##// END OF EJS Templates
debugbackupbundle: introduce command to interact with strip backups...
Pulkit Goyal -
r44898:89323f85 default draft
parent child Browse files
Show More
@@ -0,0 +1,39 b''
1 $ cat >> $HGRCPATH << EOF
2 > [extensions]
3 > strip=
4 > EOF
5
6 Setup repo
7
8 $ hg init repo
9 $ cd repo
10
11 Test backups list and recover
12
13 $ hg debugbackupbundle
14 no backup changesets found
15
16 $ mkcommit() {
17 > echo "$1" > "$1"
18 > hg add "$1"
19 > hg ci -l $1
20 > }
21 $ mkcommit a
22 $ mkcommit b
23 $ hg strip .
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d2ae7f538514-2953539b-backup.hg (glob)
26 $ hg debugbackupbundle
27 Recover changesets using: hg debugbackupbundle --recover <changeset hash>
28
29 Available backup changesets:
30 * (glob)
31 d2ae7f538514 b
32
33 $ hg debugbackupbundle --recover d2ae7f538514
34 Unbundling d2ae7f538514
35 adding changesets
36 adding manifests
37 adding file changes
38 added 1 changesets with 1 changes to 1 files
39 new changesets d2ae7f538514 (1 drafts)
@@ -1,4346 +1,4480 b''
1 # debugcommands.py - command processing for debug* commands
1 # debugcommands.py - command processing for debug* commands
2 #
2 #
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import codecs
10 import codecs
11 import collections
11 import collections
12 import difflib
12 import difflib
13 import errno
13 import errno
14 import glob
14 import operator
15 import operator
15 import os
16 import os
16 import platform
17 import platform
17 import random
18 import random
18 import re
19 import re
19 import socket
20 import socket
20 import ssl
21 import ssl
21 import stat
22 import stat
22 import string
23 import string
23 import subprocess
24 import subprocess
24 import sys
25 import sys
25 import time
26 import time
26
27
27 from .i18n import _
28 from .i18n import _
28 from .node import (
29 from .node import (
29 bin,
30 bin,
30 hex,
31 hex,
31 nullid,
32 nullid,
32 nullrev,
33 nullrev,
33 short,
34 short,
34 )
35 )
35 from .pycompat import (
36 from .pycompat import (
36 getattr,
37 getattr,
37 open,
38 open,
38 )
39 )
39 from . import (
40 from . import (
40 bundle2,
41 bundle2,
42 bundlerepo,
41 changegroup,
43 changegroup,
42 cmdutil,
44 cmdutil,
43 color,
45 color,
44 context,
46 context,
45 copies,
47 copies,
46 dagparser,
48 dagparser,
47 encoding,
49 encoding,
48 error,
50 error,
49 exchange,
51 exchange,
50 extensions,
52 extensions,
51 filemerge,
53 filemerge,
52 filesetlang,
54 filesetlang,
53 formatter,
55 formatter,
54 hg,
56 hg,
55 httppeer,
57 httppeer,
56 localrepo,
58 localrepo,
57 lock as lockmod,
59 lock as lockmod,
58 logcmdutil,
60 logcmdutil,
59 merge as mergemod,
61 merge as mergemod,
60 obsolete,
62 obsolete,
61 obsutil,
63 obsutil,
62 pathutil,
64 pathutil,
63 phases,
65 phases,
64 policy,
66 policy,
65 pvec,
67 pvec,
66 pycompat,
68 pycompat,
67 registrar,
69 registrar,
68 repair,
70 repair,
69 revlog,
71 revlog,
70 revset,
72 revset,
71 revsetlang,
73 revsetlang,
72 scmutil,
74 scmutil,
73 setdiscovery,
75 setdiscovery,
74 simplemerge,
76 simplemerge,
75 sshpeer,
77 sshpeer,
76 sslutil,
78 sslutil,
77 streamclone,
79 streamclone,
78 tags as tagsmod,
80 tags as tagsmod,
79 templater,
81 templater,
80 treediscovery,
82 treediscovery,
81 upgrade,
83 upgrade,
82 url as urlmod,
84 url as urlmod,
83 util,
85 util,
84 vfs as vfsmod,
86 vfs as vfsmod,
85 wireprotoframing,
87 wireprotoframing,
86 wireprotoserver,
88 wireprotoserver,
87 wireprotov2peer,
89 wireprotov2peer,
88 )
90 )
89 from .utils import (
91 from .utils import (
90 cborutil,
92 cborutil,
91 compression,
93 compression,
92 dateutil,
94 dateutil,
93 procutil,
95 procutil,
94 stringutil,
96 stringutil,
95 )
97 )
96
98
97 from .revlogutils import (
99 from .revlogutils import (
98 deltas as deltautil,
100 deltas as deltautil,
99 nodemap,
101 nodemap,
100 )
102 )
101
103
102 release = lockmod.release
104 release = lockmod.release
103
105
104 command = registrar.command()
106 command = registrar.command()
105
107
106
108
107 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
109 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
108 def debugancestor(ui, repo, *args):
110 def debugancestor(ui, repo, *args):
109 """find the ancestor revision of two revisions in a given index"""
111 """find the ancestor revision of two revisions in a given index"""
110 if len(args) == 3:
112 if len(args) == 3:
111 index, rev1, rev2 = args
113 index, rev1, rev2 = args
112 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
114 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
113 lookup = r.lookup
115 lookup = r.lookup
114 elif len(args) == 2:
116 elif len(args) == 2:
115 if not repo:
117 if not repo:
116 raise error.Abort(
118 raise error.Abort(
117 _(b'there is no Mercurial repository here (.hg not found)')
119 _(b'there is no Mercurial repository here (.hg not found)')
118 )
120 )
119 rev1, rev2 = args
121 rev1, rev2 = args
120 r = repo.changelog
122 r = repo.changelog
121 lookup = repo.lookup
123 lookup = repo.lookup
122 else:
124 else:
123 raise error.Abort(_(b'either two or three arguments required'))
125 raise error.Abort(_(b'either two or three arguments required'))
124 a = r.ancestor(lookup(rev1), lookup(rev2))
126 a = r.ancestor(lookup(rev1), lookup(rev2))
125 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
127 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
126
128
127
129
128 @command(b'debugapplystreamclonebundle', [], b'FILE')
130 @command(b'debugapplystreamclonebundle', [], b'FILE')
129 def debugapplystreamclonebundle(ui, repo, fname):
131 def debugapplystreamclonebundle(ui, repo, fname):
130 """apply a stream clone bundle file"""
132 """apply a stream clone bundle file"""
131 f = hg.openpath(ui, fname)
133 f = hg.openpath(ui, fname)
132 gen = exchange.readbundle(ui, f, fname)
134 gen = exchange.readbundle(ui, f, fname)
133 gen.apply(repo)
135 gen.apply(repo)
134
136
135
137
136 @command(
138 @command(
137 b'debugbuilddag',
139 b'debugbuilddag',
138 [
140 [
139 (
141 (
140 b'm',
142 b'm',
141 b'mergeable-file',
143 b'mergeable-file',
142 None,
144 None,
143 _(b'add single file mergeable changes'),
145 _(b'add single file mergeable changes'),
144 ),
146 ),
145 (
147 (
146 b'o',
148 b'o',
147 b'overwritten-file',
149 b'overwritten-file',
148 None,
150 None,
149 _(b'add single file all revs overwrite'),
151 _(b'add single file all revs overwrite'),
150 ),
152 ),
151 (b'n', b'new-file', None, _(b'add new file at each rev')),
153 (b'n', b'new-file', None, _(b'add new file at each rev')),
152 ],
154 ],
153 _(b'[OPTION]... [TEXT]'),
155 _(b'[OPTION]... [TEXT]'),
154 )
156 )
155 def debugbuilddag(
157 def debugbuilddag(
156 ui,
158 ui,
157 repo,
159 repo,
158 text=None,
160 text=None,
159 mergeable_file=False,
161 mergeable_file=False,
160 overwritten_file=False,
162 overwritten_file=False,
161 new_file=False,
163 new_file=False,
162 ):
164 ):
163 """builds a repo with a given DAG from scratch in the current empty repo
165 """builds a repo with a given DAG from scratch in the current empty repo
164
166
165 The description of the DAG is read from stdin if not given on the
167 The description of the DAG is read from stdin if not given on the
166 command line.
168 command line.
167
169
168 Elements:
170 Elements:
169
171
170 - "+n" is a linear run of n nodes based on the current default parent
172 - "+n" is a linear run of n nodes based on the current default parent
171 - "." is a single node based on the current default parent
173 - "." is a single node based on the current default parent
172 - "$" resets the default parent to null (implied at the start);
174 - "$" resets the default parent to null (implied at the start);
173 otherwise the default parent is always the last node created
175 otherwise the default parent is always the last node created
174 - "<p" sets the default parent to the backref p
176 - "<p" sets the default parent to the backref p
175 - "*p" is a fork at parent p, which is a backref
177 - "*p" is a fork at parent p, which is a backref
176 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
178 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
177 - "/p2" is a merge of the preceding node and p2
179 - "/p2" is a merge of the preceding node and p2
178 - ":tag" defines a local tag for the preceding node
180 - ":tag" defines a local tag for the preceding node
179 - "@branch" sets the named branch for subsequent nodes
181 - "@branch" sets the named branch for subsequent nodes
180 - "#...\\n" is a comment up to the end of the line
182 - "#...\\n" is a comment up to the end of the line
181
183
182 Whitespace between the above elements is ignored.
184 Whitespace between the above elements is ignored.
183
185
184 A backref is either
186 A backref is either
185
187
186 - a number n, which references the node curr-n, where curr is the current
188 - a number n, which references the node curr-n, where curr is the current
187 node, or
189 node, or
188 - the name of a local tag you placed earlier using ":tag", or
190 - the name of a local tag you placed earlier using ":tag", or
189 - empty to denote the default parent.
191 - empty to denote the default parent.
190
192
191 All string valued-elements are either strictly alphanumeric, or must
193 All string valued-elements are either strictly alphanumeric, or must
192 be enclosed in double quotes ("..."), with "\\" as escape character.
194 be enclosed in double quotes ("..."), with "\\" as escape character.
193 """
195 """
194
196
195 if text is None:
197 if text is None:
196 ui.status(_(b"reading DAG from stdin\n"))
198 ui.status(_(b"reading DAG from stdin\n"))
197 text = ui.fin.read()
199 text = ui.fin.read()
198
200
199 cl = repo.changelog
201 cl = repo.changelog
200 if len(cl) > 0:
202 if len(cl) > 0:
201 raise error.Abort(_(b'repository is not empty'))
203 raise error.Abort(_(b'repository is not empty'))
202
204
203 # determine number of revs in DAG
205 # determine number of revs in DAG
204 total = 0
206 total = 0
205 for type, data in dagparser.parsedag(text):
207 for type, data in dagparser.parsedag(text):
206 if type == b'n':
208 if type == b'n':
207 total += 1
209 total += 1
208
210
209 if mergeable_file:
211 if mergeable_file:
210 linesperrev = 2
212 linesperrev = 2
211 # make a file with k lines per rev
213 # make a file with k lines per rev
212 initialmergedlines = [
214 initialmergedlines = [
213 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
215 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
214 ]
216 ]
215 initialmergedlines.append(b"")
217 initialmergedlines.append(b"")
216
218
217 tags = []
219 tags = []
218 progress = ui.makeprogress(
220 progress = ui.makeprogress(
219 _(b'building'), unit=_(b'revisions'), total=total
221 _(b'building'), unit=_(b'revisions'), total=total
220 )
222 )
221 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
223 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
222 at = -1
224 at = -1
223 atbranch = b'default'
225 atbranch = b'default'
224 nodeids = []
226 nodeids = []
225 id = 0
227 id = 0
226 progress.update(id)
228 progress.update(id)
227 for type, data in dagparser.parsedag(text):
229 for type, data in dagparser.parsedag(text):
228 if type == b'n':
230 if type == b'n':
229 ui.note((b'node %s\n' % pycompat.bytestr(data)))
231 ui.note((b'node %s\n' % pycompat.bytestr(data)))
230 id, ps = data
232 id, ps = data
231
233
232 files = []
234 files = []
233 filecontent = {}
235 filecontent = {}
234
236
235 p2 = None
237 p2 = None
236 if mergeable_file:
238 if mergeable_file:
237 fn = b"mf"
239 fn = b"mf"
238 p1 = repo[ps[0]]
240 p1 = repo[ps[0]]
239 if len(ps) > 1:
241 if len(ps) > 1:
240 p2 = repo[ps[1]]
242 p2 = repo[ps[1]]
241 pa = p1.ancestor(p2)
243 pa = p1.ancestor(p2)
242 base, local, other = [
244 base, local, other = [
243 x[fn].data() for x in (pa, p1, p2)
245 x[fn].data() for x in (pa, p1, p2)
244 ]
246 ]
245 m3 = simplemerge.Merge3Text(base, local, other)
247 m3 = simplemerge.Merge3Text(base, local, other)
246 ml = [l.strip() for l in m3.merge_lines()]
248 ml = [l.strip() for l in m3.merge_lines()]
247 ml.append(b"")
249 ml.append(b"")
248 elif at > 0:
250 elif at > 0:
249 ml = p1[fn].data().split(b"\n")
251 ml = p1[fn].data().split(b"\n")
250 else:
252 else:
251 ml = initialmergedlines
253 ml = initialmergedlines
252 ml[id * linesperrev] += b" r%i" % id
254 ml[id * linesperrev] += b" r%i" % id
253 mergedtext = b"\n".join(ml)
255 mergedtext = b"\n".join(ml)
254 files.append(fn)
256 files.append(fn)
255 filecontent[fn] = mergedtext
257 filecontent[fn] = mergedtext
256
258
257 if overwritten_file:
259 if overwritten_file:
258 fn = b"of"
260 fn = b"of"
259 files.append(fn)
261 files.append(fn)
260 filecontent[fn] = b"r%i\n" % id
262 filecontent[fn] = b"r%i\n" % id
261
263
262 if new_file:
264 if new_file:
263 fn = b"nf%i" % id
265 fn = b"nf%i" % id
264 files.append(fn)
266 files.append(fn)
265 filecontent[fn] = b"r%i\n" % id
267 filecontent[fn] = b"r%i\n" % id
266 if len(ps) > 1:
268 if len(ps) > 1:
267 if not p2:
269 if not p2:
268 p2 = repo[ps[1]]
270 p2 = repo[ps[1]]
269 for fn in p2:
271 for fn in p2:
270 if fn.startswith(b"nf"):
272 if fn.startswith(b"nf"):
271 files.append(fn)
273 files.append(fn)
272 filecontent[fn] = p2[fn].data()
274 filecontent[fn] = p2[fn].data()
273
275
274 def fctxfn(repo, cx, path):
276 def fctxfn(repo, cx, path):
275 if path in filecontent:
277 if path in filecontent:
276 return context.memfilectx(
278 return context.memfilectx(
277 repo, cx, path, filecontent[path]
279 repo, cx, path, filecontent[path]
278 )
280 )
279 return None
281 return None
280
282
281 if len(ps) == 0 or ps[0] < 0:
283 if len(ps) == 0 or ps[0] < 0:
282 pars = [None, None]
284 pars = [None, None]
283 elif len(ps) == 1:
285 elif len(ps) == 1:
284 pars = [nodeids[ps[0]], None]
286 pars = [nodeids[ps[0]], None]
285 else:
287 else:
286 pars = [nodeids[p] for p in ps]
288 pars = [nodeids[p] for p in ps]
287 cx = context.memctx(
289 cx = context.memctx(
288 repo,
290 repo,
289 pars,
291 pars,
290 b"r%i" % id,
292 b"r%i" % id,
291 files,
293 files,
292 fctxfn,
294 fctxfn,
293 date=(id, 0),
295 date=(id, 0),
294 user=b"debugbuilddag",
296 user=b"debugbuilddag",
295 extra={b'branch': atbranch},
297 extra={b'branch': atbranch},
296 )
298 )
297 nodeid = repo.commitctx(cx)
299 nodeid = repo.commitctx(cx)
298 nodeids.append(nodeid)
300 nodeids.append(nodeid)
299 at = id
301 at = id
300 elif type == b'l':
302 elif type == b'l':
301 id, name = data
303 id, name = data
302 ui.note((b'tag %s\n' % name))
304 ui.note((b'tag %s\n' % name))
303 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
305 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
304 elif type == b'a':
306 elif type == b'a':
305 ui.note((b'branch %s\n' % data))
307 ui.note((b'branch %s\n' % data))
306 atbranch = data
308 atbranch = data
307 progress.update(id)
309 progress.update(id)
308
310
309 if tags:
311 if tags:
310 repo.vfs.write(b"localtags", b"".join(tags))
312 repo.vfs.write(b"localtags", b"".join(tags))
311
313
312
314
313 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
315 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
314 indent_string = b' ' * indent
316 indent_string = b' ' * indent
315 if all:
317 if all:
316 ui.writenoi18n(
318 ui.writenoi18n(
317 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
319 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
318 % indent_string
320 % indent_string
319 )
321 )
320
322
321 def showchunks(named):
323 def showchunks(named):
322 ui.write(b"\n%s%s\n" % (indent_string, named))
324 ui.write(b"\n%s%s\n" % (indent_string, named))
323 for deltadata in gen.deltaiter():
325 for deltadata in gen.deltaiter():
324 node, p1, p2, cs, deltabase, delta, flags = deltadata
326 node, p1, p2, cs, deltabase, delta, flags = deltadata
325 ui.write(
327 ui.write(
326 b"%s%s %s %s %s %s %d\n"
328 b"%s%s %s %s %s %s %d\n"
327 % (
329 % (
328 indent_string,
330 indent_string,
329 hex(node),
331 hex(node),
330 hex(p1),
332 hex(p1),
331 hex(p2),
333 hex(p2),
332 hex(cs),
334 hex(cs),
333 hex(deltabase),
335 hex(deltabase),
334 len(delta),
336 len(delta),
335 )
337 )
336 )
338 )
337
339
338 gen.changelogheader()
340 gen.changelogheader()
339 showchunks(b"changelog")
341 showchunks(b"changelog")
340 gen.manifestheader()
342 gen.manifestheader()
341 showchunks(b"manifest")
343 showchunks(b"manifest")
342 for chunkdata in iter(gen.filelogheader, {}):
344 for chunkdata in iter(gen.filelogheader, {}):
343 fname = chunkdata[b'filename']
345 fname = chunkdata[b'filename']
344 showchunks(fname)
346 showchunks(fname)
345 else:
347 else:
346 if isinstance(gen, bundle2.unbundle20):
348 if isinstance(gen, bundle2.unbundle20):
347 raise error.Abort(_(b'use debugbundle2 for this file'))
349 raise error.Abort(_(b'use debugbundle2 for this file'))
348 gen.changelogheader()
350 gen.changelogheader()
349 for deltadata in gen.deltaiter():
351 for deltadata in gen.deltaiter():
350 node, p1, p2, cs, deltabase, delta, flags = deltadata
352 node, p1, p2, cs, deltabase, delta, flags = deltadata
351 ui.write(b"%s%s\n" % (indent_string, hex(node)))
353 ui.write(b"%s%s\n" % (indent_string, hex(node)))
352
354
353
355
354 def _debugobsmarkers(ui, part, indent=0, **opts):
356 def _debugobsmarkers(ui, part, indent=0, **opts):
355 """display version and markers contained in 'data'"""
357 """display version and markers contained in 'data'"""
356 opts = pycompat.byteskwargs(opts)
358 opts = pycompat.byteskwargs(opts)
357 data = part.read()
359 data = part.read()
358 indent_string = b' ' * indent
360 indent_string = b' ' * indent
359 try:
361 try:
360 version, markers = obsolete._readmarkers(data)
362 version, markers = obsolete._readmarkers(data)
361 except error.UnknownVersion as exc:
363 except error.UnknownVersion as exc:
362 msg = b"%sunsupported version: %s (%d bytes)\n"
364 msg = b"%sunsupported version: %s (%d bytes)\n"
363 msg %= indent_string, exc.version, len(data)
365 msg %= indent_string, exc.version, len(data)
364 ui.write(msg)
366 ui.write(msg)
365 else:
367 else:
366 msg = b"%sversion: %d (%d bytes)\n"
368 msg = b"%sversion: %d (%d bytes)\n"
367 msg %= indent_string, version, len(data)
369 msg %= indent_string, version, len(data)
368 ui.write(msg)
370 ui.write(msg)
369 fm = ui.formatter(b'debugobsolete', opts)
371 fm = ui.formatter(b'debugobsolete', opts)
370 for rawmarker in sorted(markers):
372 for rawmarker in sorted(markers):
371 m = obsutil.marker(None, rawmarker)
373 m = obsutil.marker(None, rawmarker)
372 fm.startitem()
374 fm.startitem()
373 fm.plain(indent_string)
375 fm.plain(indent_string)
374 cmdutil.showmarker(fm, m)
376 cmdutil.showmarker(fm, m)
375 fm.end()
377 fm.end()
376
378
377
379
378 def _debugphaseheads(ui, data, indent=0):
380 def _debugphaseheads(ui, data, indent=0):
379 """display version and markers contained in 'data'"""
381 """display version and markers contained in 'data'"""
380 indent_string = b' ' * indent
382 indent_string = b' ' * indent
381 headsbyphase = phases.binarydecode(data)
383 headsbyphase = phases.binarydecode(data)
382 for phase in phases.allphases:
384 for phase in phases.allphases:
383 for head in headsbyphase[phase]:
385 for head in headsbyphase[phase]:
384 ui.write(indent_string)
386 ui.write(indent_string)
385 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
387 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
386
388
387
389
388 def _quasirepr(thing):
390 def _quasirepr(thing):
389 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
391 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
390 return b'{%s}' % (
392 return b'{%s}' % (
391 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
393 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
392 )
394 )
393 return pycompat.bytestr(repr(thing))
395 return pycompat.bytestr(repr(thing))
394
396
395
397
396 def _debugbundle2(ui, gen, all=None, **opts):
398 def _debugbundle2(ui, gen, all=None, **opts):
397 """lists the contents of a bundle2"""
399 """lists the contents of a bundle2"""
398 if not isinstance(gen, bundle2.unbundle20):
400 if not isinstance(gen, bundle2.unbundle20):
399 raise error.Abort(_(b'not a bundle2 file'))
401 raise error.Abort(_(b'not a bundle2 file'))
400 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
402 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
401 parttypes = opts.get('part_type', [])
403 parttypes = opts.get('part_type', [])
402 for part in gen.iterparts():
404 for part in gen.iterparts():
403 if parttypes and part.type not in parttypes:
405 if parttypes and part.type not in parttypes:
404 continue
406 continue
405 msg = b'%s -- %s (mandatory: %r)\n'
407 msg = b'%s -- %s (mandatory: %r)\n'
406 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
408 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
407 if part.type == b'changegroup':
409 if part.type == b'changegroup':
408 version = part.params.get(b'version', b'01')
410 version = part.params.get(b'version', b'01')
409 cg = changegroup.getunbundler(version, part, b'UN')
411 cg = changegroup.getunbundler(version, part, b'UN')
410 if not ui.quiet:
412 if not ui.quiet:
411 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
413 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
412 if part.type == b'obsmarkers':
414 if part.type == b'obsmarkers':
413 if not ui.quiet:
415 if not ui.quiet:
414 _debugobsmarkers(ui, part, indent=4, **opts)
416 _debugobsmarkers(ui, part, indent=4, **opts)
415 if part.type == b'phase-heads':
417 if part.type == b'phase-heads':
416 if not ui.quiet:
418 if not ui.quiet:
417 _debugphaseheads(ui, part, indent=4)
419 _debugphaseheads(ui, part, indent=4)
418
420
419
421
420 @command(
422 @command(
421 b'debugbundle',
423 b'debugbundle',
422 [
424 [
423 (b'a', b'all', None, _(b'show all details')),
425 (b'a', b'all', None, _(b'show all details')),
424 (b'', b'part-type', [], _(b'show only the named part type')),
426 (b'', b'part-type', [], _(b'show only the named part type')),
425 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
427 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
426 ],
428 ],
427 _(b'FILE'),
429 _(b'FILE'),
428 norepo=True,
430 norepo=True,
429 )
431 )
430 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
432 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
431 """lists the contents of a bundle"""
433 """lists the contents of a bundle"""
432 with hg.openpath(ui, bundlepath) as f:
434 with hg.openpath(ui, bundlepath) as f:
433 if spec:
435 if spec:
434 spec = exchange.getbundlespec(ui, f)
436 spec = exchange.getbundlespec(ui, f)
435 ui.write(b'%s\n' % spec)
437 ui.write(b'%s\n' % spec)
436 return
438 return
437
439
438 gen = exchange.readbundle(ui, f, bundlepath)
440 gen = exchange.readbundle(ui, f, bundlepath)
439 if isinstance(gen, bundle2.unbundle20):
441 if isinstance(gen, bundle2.unbundle20):
440 return _debugbundle2(ui, gen, all=all, **opts)
442 return _debugbundle2(ui, gen, all=all, **opts)
441 _debugchangegroup(ui, gen, all=all, **opts)
443 _debugchangegroup(ui, gen, all=all, **opts)
442
444
443
445
444 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
446 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
445 def debugcapabilities(ui, path, **opts):
447 def debugcapabilities(ui, path, **opts):
446 """lists the capabilities of a remote peer"""
448 """lists the capabilities of a remote peer"""
447 opts = pycompat.byteskwargs(opts)
449 opts = pycompat.byteskwargs(opts)
448 peer = hg.peer(ui, opts, path)
450 peer = hg.peer(ui, opts, path)
449 caps = peer.capabilities()
451 caps = peer.capabilities()
450 ui.writenoi18n(b'Main capabilities:\n')
452 ui.writenoi18n(b'Main capabilities:\n')
451 for c in sorted(caps):
453 for c in sorted(caps):
452 ui.write(b' %s\n' % c)
454 ui.write(b' %s\n' % c)
453 b2caps = bundle2.bundle2caps(peer)
455 b2caps = bundle2.bundle2caps(peer)
454 if b2caps:
456 if b2caps:
455 ui.writenoi18n(b'Bundle2 capabilities:\n')
457 ui.writenoi18n(b'Bundle2 capabilities:\n')
456 for key, values in sorted(pycompat.iteritems(b2caps)):
458 for key, values in sorted(pycompat.iteritems(b2caps)):
457 ui.write(b' %s\n' % key)
459 ui.write(b' %s\n' % key)
458 for v in values:
460 for v in values:
459 ui.write(b' %s\n' % v)
461 ui.write(b' %s\n' % v)
460
462
461
463
462 @command(b'debugcheckstate', [], b'')
464 @command(b'debugcheckstate', [], b'')
463 def debugcheckstate(ui, repo):
465 def debugcheckstate(ui, repo):
464 """validate the correctness of the current dirstate"""
466 """validate the correctness of the current dirstate"""
465 parent1, parent2 = repo.dirstate.parents()
467 parent1, parent2 = repo.dirstate.parents()
466 m1 = repo[parent1].manifest()
468 m1 = repo[parent1].manifest()
467 m2 = repo[parent2].manifest()
469 m2 = repo[parent2].manifest()
468 errors = 0
470 errors = 0
469 for f in repo.dirstate:
471 for f in repo.dirstate:
470 state = repo.dirstate[f]
472 state = repo.dirstate[f]
471 if state in b"nr" and f not in m1:
473 if state in b"nr" and f not in m1:
472 ui.warn(_(b"%s in state %s, but not in manifest1\n") % (f, state))
474 ui.warn(_(b"%s in state %s, but not in manifest1\n") % (f, state))
473 errors += 1
475 errors += 1
474 if state in b"a" and f in m1:
476 if state in b"a" and f in m1:
475 ui.warn(_(b"%s in state %s, but also in manifest1\n") % (f, state))
477 ui.warn(_(b"%s in state %s, but also in manifest1\n") % (f, state))
476 errors += 1
478 errors += 1
477 if state in b"m" and f not in m1 and f not in m2:
479 if state in b"m" and f not in m1 and f not in m2:
478 ui.warn(
480 ui.warn(
479 _(b"%s in state %s, but not in either manifest\n") % (f, state)
481 _(b"%s in state %s, but not in either manifest\n") % (f, state)
480 )
482 )
481 errors += 1
483 errors += 1
482 for f in m1:
484 for f in m1:
483 state = repo.dirstate[f]
485 state = repo.dirstate[f]
484 if state not in b"nrm":
486 if state not in b"nrm":
485 ui.warn(_(b"%s in manifest1, but listed as state %s") % (f, state))
487 ui.warn(_(b"%s in manifest1, but listed as state %s") % (f, state))
486 errors += 1
488 errors += 1
487 if errors:
489 if errors:
488 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
490 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
489 raise error.Abort(errstr)
491 raise error.Abort(errstr)
490
492
491
493
492 @command(
494 @command(
493 b'debugcolor',
495 b'debugcolor',
494 [(b'', b'style', None, _(b'show all configured styles'))],
496 [(b'', b'style', None, _(b'show all configured styles'))],
495 b'hg debugcolor',
497 b'hg debugcolor',
496 )
498 )
497 def debugcolor(ui, repo, **opts):
499 def debugcolor(ui, repo, **opts):
498 """show available color, effects or style"""
500 """show available color, effects or style"""
499 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
501 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
500 if opts.get('style'):
502 if opts.get('style'):
501 return _debugdisplaystyle(ui)
503 return _debugdisplaystyle(ui)
502 else:
504 else:
503 return _debugdisplaycolor(ui)
505 return _debugdisplaycolor(ui)
504
506
505
507
506 def _debugdisplaycolor(ui):
508 def _debugdisplaycolor(ui):
507 ui = ui.copy()
509 ui = ui.copy()
508 ui._styles.clear()
510 ui._styles.clear()
509 for effect in color._activeeffects(ui).keys():
511 for effect in color._activeeffects(ui).keys():
510 ui._styles[effect] = effect
512 ui._styles[effect] = effect
511 if ui._terminfoparams:
513 if ui._terminfoparams:
512 for k, v in ui.configitems(b'color'):
514 for k, v in ui.configitems(b'color'):
513 if k.startswith(b'color.'):
515 if k.startswith(b'color.'):
514 ui._styles[k] = k[6:]
516 ui._styles[k] = k[6:]
515 elif k.startswith(b'terminfo.'):
517 elif k.startswith(b'terminfo.'):
516 ui._styles[k] = k[9:]
518 ui._styles[k] = k[9:]
517 ui.write(_(b'available colors:\n'))
519 ui.write(_(b'available colors:\n'))
518 # sort label with a '_' after the other to group '_background' entry.
520 # sort label with a '_' after the other to group '_background' entry.
519 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
521 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
520 for colorname, label in items:
522 for colorname, label in items:
521 ui.write(b'%s\n' % colorname, label=label)
523 ui.write(b'%s\n' % colorname, label=label)
522
524
523
525
524 def _debugdisplaystyle(ui):
526 def _debugdisplaystyle(ui):
525 ui.write(_(b'available style:\n'))
527 ui.write(_(b'available style:\n'))
526 if not ui._styles:
528 if not ui._styles:
527 return
529 return
528 width = max(len(s) for s in ui._styles)
530 width = max(len(s) for s in ui._styles)
529 for label, effects in sorted(ui._styles.items()):
531 for label, effects in sorted(ui._styles.items()):
530 ui.write(b'%s' % label, label=label)
532 ui.write(b'%s' % label, label=label)
531 if effects:
533 if effects:
532 # 50
534 # 50
533 ui.write(b': ')
535 ui.write(b': ')
534 ui.write(b' ' * (max(0, width - len(label))))
536 ui.write(b' ' * (max(0, width - len(label))))
535 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
537 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
536 ui.write(b'\n')
538 ui.write(b'\n')
537
539
538
540
539 @command(b'debugcreatestreamclonebundle', [], b'FILE')
541 @command(b'debugcreatestreamclonebundle', [], b'FILE')
540 def debugcreatestreamclonebundle(ui, repo, fname):
542 def debugcreatestreamclonebundle(ui, repo, fname):
541 """create a stream clone bundle file
543 """create a stream clone bundle file
542
544
543 Stream bundles are special bundles that are essentially archives of
545 Stream bundles are special bundles that are essentially archives of
544 revlog files. They are commonly used for cloning very quickly.
546 revlog files. They are commonly used for cloning very quickly.
545 """
547 """
546 # TODO we may want to turn this into an abort when this functionality
548 # TODO we may want to turn this into an abort when this functionality
547 # is moved into `hg bundle`.
549 # is moved into `hg bundle`.
548 if phases.hassecret(repo):
550 if phases.hassecret(repo):
549 ui.warn(
551 ui.warn(
550 _(
552 _(
551 b'(warning: stream clone bundle will contain secret '
553 b'(warning: stream clone bundle will contain secret '
552 b'revisions)\n'
554 b'revisions)\n'
553 )
555 )
554 )
556 )
555
557
556 requirements, gen = streamclone.generatebundlev1(repo)
558 requirements, gen = streamclone.generatebundlev1(repo)
557 changegroup.writechunks(ui, gen, fname)
559 changegroup.writechunks(ui, gen, fname)
558
560
559 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
561 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
560
562
561
563
562 @command(
564 @command(
563 b'debugdag',
565 b'debugdag',
564 [
566 [
565 (b't', b'tags', None, _(b'use tags as labels')),
567 (b't', b'tags', None, _(b'use tags as labels')),
566 (b'b', b'branches', None, _(b'annotate with branch names')),
568 (b'b', b'branches', None, _(b'annotate with branch names')),
567 (b'', b'dots', None, _(b'use dots for runs')),
569 (b'', b'dots', None, _(b'use dots for runs')),
568 (b's', b'spaces', None, _(b'separate elements by spaces')),
570 (b's', b'spaces', None, _(b'separate elements by spaces')),
569 ],
571 ],
570 _(b'[OPTION]... [FILE [REV]...]'),
572 _(b'[OPTION]... [FILE [REV]...]'),
571 optionalrepo=True,
573 optionalrepo=True,
572 )
574 )
573 def debugdag(ui, repo, file_=None, *revs, **opts):
575 def debugdag(ui, repo, file_=None, *revs, **opts):
574 """format the changelog or an index DAG as a concise textual description
576 """format the changelog or an index DAG as a concise textual description
575
577
576 If you pass a revlog index, the revlog's DAG is emitted. If you list
578 If you pass a revlog index, the revlog's DAG is emitted. If you list
577 revision numbers, they get labeled in the output as rN.
579 revision numbers, they get labeled in the output as rN.
578
580
579 Otherwise, the changelog DAG of the current repo is emitted.
581 Otherwise, the changelog DAG of the current repo is emitted.
580 """
582 """
581 spaces = opts.get('spaces')
583 spaces = opts.get('spaces')
582 dots = opts.get('dots')
584 dots = opts.get('dots')
583 if file_:
585 if file_:
584 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
586 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
585 revs = set((int(r) for r in revs))
587 revs = set((int(r) for r in revs))
586
588
587 def events():
589 def events():
588 for r in rlog:
590 for r in rlog:
589 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
591 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
590 if r in revs:
592 if r in revs:
591 yield b'l', (r, b"r%i" % r)
593 yield b'l', (r, b"r%i" % r)
592
594
593 elif repo:
595 elif repo:
594 cl = repo.changelog
596 cl = repo.changelog
595 tags = opts.get('tags')
597 tags = opts.get('tags')
596 branches = opts.get('branches')
598 branches = opts.get('branches')
597 if tags:
599 if tags:
598 labels = {}
600 labels = {}
599 for l, n in repo.tags().items():
601 for l, n in repo.tags().items():
600 labels.setdefault(cl.rev(n), []).append(l)
602 labels.setdefault(cl.rev(n), []).append(l)
601
603
602 def events():
604 def events():
603 b = b"default"
605 b = b"default"
604 for r in cl:
606 for r in cl:
605 if branches:
607 if branches:
606 newb = cl.read(cl.node(r))[5][b'branch']
608 newb = cl.read(cl.node(r))[5][b'branch']
607 if newb != b:
609 if newb != b:
608 yield b'a', newb
610 yield b'a', newb
609 b = newb
611 b = newb
610 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
612 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
611 if tags:
613 if tags:
612 ls = labels.get(r)
614 ls = labels.get(r)
613 if ls:
615 if ls:
614 for l in ls:
616 for l in ls:
615 yield b'l', (r, l)
617 yield b'l', (r, l)
616
618
617 else:
619 else:
618 raise error.Abort(_(b'need repo for changelog dag'))
620 raise error.Abort(_(b'need repo for changelog dag'))
619
621
620 for line in dagparser.dagtextlines(
622 for line in dagparser.dagtextlines(
621 events(),
623 events(),
622 addspaces=spaces,
624 addspaces=spaces,
623 wraplabels=True,
625 wraplabels=True,
624 wrapannotations=True,
626 wrapannotations=True,
625 wrapnonlinear=dots,
627 wrapnonlinear=dots,
626 usedots=dots,
628 usedots=dots,
627 maxlinewidth=70,
629 maxlinewidth=70,
628 ):
630 ):
629 ui.write(line)
631 ui.write(line)
630 ui.write(b"\n")
632 ui.write(b"\n")
631
633
632
634
633 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
635 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
634 def debugdata(ui, repo, file_, rev=None, **opts):
636 def debugdata(ui, repo, file_, rev=None, **opts):
635 """dump the contents of a data file revision"""
637 """dump the contents of a data file revision"""
636 opts = pycompat.byteskwargs(opts)
638 opts = pycompat.byteskwargs(opts)
637 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
639 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
638 if rev is not None:
640 if rev is not None:
639 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
641 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
640 file_, rev = None, file_
642 file_, rev = None, file_
641 elif rev is None:
643 elif rev is None:
642 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
644 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
643 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
645 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
644 try:
646 try:
645 ui.write(r.rawdata(r.lookup(rev)))
647 ui.write(r.rawdata(r.lookup(rev)))
646 except KeyError:
648 except KeyError:
647 raise error.Abort(_(b'invalid revision identifier %s') % rev)
649 raise error.Abort(_(b'invalid revision identifier %s') % rev)
648
650
649
651
650 @command(
652 @command(
651 b'debugdate',
653 b'debugdate',
652 [(b'e', b'extended', None, _(b'try extended date formats'))],
654 [(b'e', b'extended', None, _(b'try extended date formats'))],
653 _(b'[-e] DATE [RANGE]'),
655 _(b'[-e] DATE [RANGE]'),
654 norepo=True,
656 norepo=True,
655 optionalrepo=True,
657 optionalrepo=True,
656 )
658 )
657 def debugdate(ui, date, range=None, **opts):
659 def debugdate(ui, date, range=None, **opts):
658 """parse and display a date"""
660 """parse and display a date"""
659 if opts["extended"]:
661 if opts["extended"]:
660 d = dateutil.parsedate(date, dateutil.extendeddateformats)
662 d = dateutil.parsedate(date, dateutil.extendeddateformats)
661 else:
663 else:
662 d = dateutil.parsedate(date)
664 d = dateutil.parsedate(date)
663 ui.writenoi18n(b"internal: %d %d\n" % d)
665 ui.writenoi18n(b"internal: %d %d\n" % d)
664 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
666 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
665 if range:
667 if range:
666 m = dateutil.matchdate(range)
668 m = dateutil.matchdate(range)
667 ui.writenoi18n(b"match: %s\n" % m(d[0]))
669 ui.writenoi18n(b"match: %s\n" % m(d[0]))
668
670
669
671
670 @command(
672 @command(
671 b'debugdeltachain',
673 b'debugdeltachain',
672 cmdutil.debugrevlogopts + cmdutil.formatteropts,
674 cmdutil.debugrevlogopts + cmdutil.formatteropts,
673 _(b'-c|-m|FILE'),
675 _(b'-c|-m|FILE'),
674 optionalrepo=True,
676 optionalrepo=True,
675 )
677 )
676 def debugdeltachain(ui, repo, file_=None, **opts):
678 def debugdeltachain(ui, repo, file_=None, **opts):
677 """dump information about delta chains in a revlog
679 """dump information about delta chains in a revlog
678
680
679 Output can be templatized. Available template keywords are:
681 Output can be templatized. Available template keywords are:
680
682
681 :``rev``: revision number
683 :``rev``: revision number
682 :``chainid``: delta chain identifier (numbered by unique base)
684 :``chainid``: delta chain identifier (numbered by unique base)
683 :``chainlen``: delta chain length to this revision
685 :``chainlen``: delta chain length to this revision
684 :``prevrev``: previous revision in delta chain
686 :``prevrev``: previous revision in delta chain
685 :``deltatype``: role of delta / how it was computed
687 :``deltatype``: role of delta / how it was computed
686 :``compsize``: compressed size of revision
688 :``compsize``: compressed size of revision
687 :``uncompsize``: uncompressed size of revision
689 :``uncompsize``: uncompressed size of revision
688 :``chainsize``: total size of compressed revisions in chain
690 :``chainsize``: total size of compressed revisions in chain
689 :``chainratio``: total chain size divided by uncompressed revision size
691 :``chainratio``: total chain size divided by uncompressed revision size
690 (new delta chains typically start at ratio 2.00)
692 (new delta chains typically start at ratio 2.00)
691 :``lindist``: linear distance from base revision in delta chain to end
693 :``lindist``: linear distance from base revision in delta chain to end
692 of this revision
694 of this revision
693 :``extradist``: total size of revisions not part of this delta chain from
695 :``extradist``: total size of revisions not part of this delta chain from
694 base of delta chain to end of this revision; a measurement
696 base of delta chain to end of this revision; a measurement
695 of how much extra data we need to read/seek across to read
697 of how much extra data we need to read/seek across to read
696 the delta chain for this revision
698 the delta chain for this revision
697 :``extraratio``: extradist divided by chainsize; another representation of
699 :``extraratio``: extradist divided by chainsize; another representation of
698 how much unrelated data is needed to load this delta chain
700 how much unrelated data is needed to load this delta chain
699
701
700 If the repository is configured to use the sparse read, additional keywords
702 If the repository is configured to use the sparse read, additional keywords
701 are available:
703 are available:
702
704
703 :``readsize``: total size of data read from the disk for a revision
705 :``readsize``: total size of data read from the disk for a revision
704 (sum of the sizes of all the blocks)
706 (sum of the sizes of all the blocks)
705 :``largestblock``: size of the largest block of data read from the disk
707 :``largestblock``: size of the largest block of data read from the disk
706 :``readdensity``: density of useful bytes in the data read from the disk
708 :``readdensity``: density of useful bytes in the data read from the disk
707 :``srchunks``: in how many data hunks the whole revision would be read
709 :``srchunks``: in how many data hunks the whole revision would be read
708
710
709 The sparse read can be enabled with experimental.sparse-read = True
711 The sparse read can be enabled with experimental.sparse-read = True
710 """
712 """
711 opts = pycompat.byteskwargs(opts)
713 opts = pycompat.byteskwargs(opts)
712 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
714 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
713 index = r.index
715 index = r.index
714 start = r.start
716 start = r.start
715 length = r.length
717 length = r.length
716 generaldelta = r.version & revlog.FLAG_GENERALDELTA
718 generaldelta = r.version & revlog.FLAG_GENERALDELTA
717 withsparseread = getattr(r, '_withsparseread', False)
719 withsparseread = getattr(r, '_withsparseread', False)
718
720
719 def revinfo(rev):
721 def revinfo(rev):
720 e = index[rev]
722 e = index[rev]
721 compsize = e[1]
723 compsize = e[1]
722 uncompsize = e[2]
724 uncompsize = e[2]
723 chainsize = 0
725 chainsize = 0
724
726
725 if generaldelta:
727 if generaldelta:
726 if e[3] == e[5]:
728 if e[3] == e[5]:
727 deltatype = b'p1'
729 deltatype = b'p1'
728 elif e[3] == e[6]:
730 elif e[3] == e[6]:
729 deltatype = b'p2'
731 deltatype = b'p2'
730 elif e[3] == rev - 1:
732 elif e[3] == rev - 1:
731 deltatype = b'prev'
733 deltatype = b'prev'
732 elif e[3] == rev:
734 elif e[3] == rev:
733 deltatype = b'base'
735 deltatype = b'base'
734 else:
736 else:
735 deltatype = b'other'
737 deltatype = b'other'
736 else:
738 else:
737 if e[3] == rev:
739 if e[3] == rev:
738 deltatype = b'base'
740 deltatype = b'base'
739 else:
741 else:
740 deltatype = b'prev'
742 deltatype = b'prev'
741
743
742 chain = r._deltachain(rev)[0]
744 chain = r._deltachain(rev)[0]
743 for iterrev in chain:
745 for iterrev in chain:
744 e = index[iterrev]
746 e = index[iterrev]
745 chainsize += e[1]
747 chainsize += e[1]
746
748
747 return compsize, uncompsize, deltatype, chain, chainsize
749 return compsize, uncompsize, deltatype, chain, chainsize
748
750
749 fm = ui.formatter(b'debugdeltachain', opts)
751 fm = ui.formatter(b'debugdeltachain', opts)
750
752
751 fm.plain(
753 fm.plain(
752 b' rev chain# chainlen prev delta '
754 b' rev chain# chainlen prev delta '
753 b'size rawsize chainsize ratio lindist extradist '
755 b'size rawsize chainsize ratio lindist extradist '
754 b'extraratio'
756 b'extraratio'
755 )
757 )
756 if withsparseread:
758 if withsparseread:
757 fm.plain(b' readsize largestblk rddensity srchunks')
759 fm.plain(b' readsize largestblk rddensity srchunks')
758 fm.plain(b'\n')
760 fm.plain(b'\n')
759
761
760 chainbases = {}
762 chainbases = {}
761 for rev in r:
763 for rev in r:
762 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
764 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
763 chainbase = chain[0]
765 chainbase = chain[0]
764 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
766 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
765 basestart = start(chainbase)
767 basestart = start(chainbase)
766 revstart = start(rev)
768 revstart = start(rev)
767 lineardist = revstart + comp - basestart
769 lineardist = revstart + comp - basestart
768 extradist = lineardist - chainsize
770 extradist = lineardist - chainsize
769 try:
771 try:
770 prevrev = chain[-2]
772 prevrev = chain[-2]
771 except IndexError:
773 except IndexError:
772 prevrev = -1
774 prevrev = -1
773
775
774 if uncomp != 0:
776 if uncomp != 0:
775 chainratio = float(chainsize) / float(uncomp)
777 chainratio = float(chainsize) / float(uncomp)
776 else:
778 else:
777 chainratio = chainsize
779 chainratio = chainsize
778
780
779 if chainsize != 0:
781 if chainsize != 0:
780 extraratio = float(extradist) / float(chainsize)
782 extraratio = float(extradist) / float(chainsize)
781 else:
783 else:
782 extraratio = extradist
784 extraratio = extradist
783
785
784 fm.startitem()
786 fm.startitem()
785 fm.write(
787 fm.write(
786 b'rev chainid chainlen prevrev deltatype compsize '
788 b'rev chainid chainlen prevrev deltatype compsize '
787 b'uncompsize chainsize chainratio lindist extradist '
789 b'uncompsize chainsize chainratio lindist extradist '
788 b'extraratio',
790 b'extraratio',
789 b'%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
791 b'%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
790 rev,
792 rev,
791 chainid,
793 chainid,
792 len(chain),
794 len(chain),
793 prevrev,
795 prevrev,
794 deltatype,
796 deltatype,
795 comp,
797 comp,
796 uncomp,
798 uncomp,
797 chainsize,
799 chainsize,
798 chainratio,
800 chainratio,
799 lineardist,
801 lineardist,
800 extradist,
802 extradist,
801 extraratio,
803 extraratio,
802 rev=rev,
804 rev=rev,
803 chainid=chainid,
805 chainid=chainid,
804 chainlen=len(chain),
806 chainlen=len(chain),
805 prevrev=prevrev,
807 prevrev=prevrev,
806 deltatype=deltatype,
808 deltatype=deltatype,
807 compsize=comp,
809 compsize=comp,
808 uncompsize=uncomp,
810 uncompsize=uncomp,
809 chainsize=chainsize,
811 chainsize=chainsize,
810 chainratio=chainratio,
812 chainratio=chainratio,
811 lindist=lineardist,
813 lindist=lineardist,
812 extradist=extradist,
814 extradist=extradist,
813 extraratio=extraratio,
815 extraratio=extraratio,
814 )
816 )
815 if withsparseread:
817 if withsparseread:
816 readsize = 0
818 readsize = 0
817 largestblock = 0
819 largestblock = 0
818 srchunks = 0
820 srchunks = 0
819
821
820 for revschunk in deltautil.slicechunk(r, chain):
822 for revschunk in deltautil.slicechunk(r, chain):
821 srchunks += 1
823 srchunks += 1
822 blkend = start(revschunk[-1]) + length(revschunk[-1])
824 blkend = start(revschunk[-1]) + length(revschunk[-1])
823 blksize = blkend - start(revschunk[0])
825 blksize = blkend - start(revschunk[0])
824
826
825 readsize += blksize
827 readsize += blksize
826 if largestblock < blksize:
828 if largestblock < blksize:
827 largestblock = blksize
829 largestblock = blksize
828
830
829 if readsize:
831 if readsize:
830 readdensity = float(chainsize) / float(readsize)
832 readdensity = float(chainsize) / float(readsize)
831 else:
833 else:
832 readdensity = 1
834 readdensity = 1
833
835
834 fm.write(
836 fm.write(
835 b'readsize largestblock readdensity srchunks',
837 b'readsize largestblock readdensity srchunks',
836 b' %10d %10d %9.5f %8d',
838 b' %10d %10d %9.5f %8d',
837 readsize,
839 readsize,
838 largestblock,
840 largestblock,
839 readdensity,
841 readdensity,
840 srchunks,
842 srchunks,
841 readsize=readsize,
843 readsize=readsize,
842 largestblock=largestblock,
844 largestblock=largestblock,
843 readdensity=readdensity,
845 readdensity=readdensity,
844 srchunks=srchunks,
846 srchunks=srchunks,
845 )
847 )
846
848
847 fm.plain(b'\n')
849 fm.plain(b'\n')
848
850
849 fm.end()
851 fm.end()
850
852
851
853
852 @command(
854 @command(
853 b'debugdirstate|debugstate',
855 b'debugdirstate|debugstate',
854 [
856 [
855 (
857 (
856 b'',
858 b'',
857 b'nodates',
859 b'nodates',
858 None,
860 None,
859 _(b'do not display the saved mtime (DEPRECATED)'),
861 _(b'do not display the saved mtime (DEPRECATED)'),
860 ),
862 ),
861 (b'', b'dates', True, _(b'display the saved mtime')),
863 (b'', b'dates', True, _(b'display the saved mtime')),
862 (b'', b'datesort', None, _(b'sort by saved mtime')),
864 (b'', b'datesort', None, _(b'sort by saved mtime')),
863 ],
865 ],
864 _(b'[OPTION]...'),
866 _(b'[OPTION]...'),
865 )
867 )
866 def debugstate(ui, repo, **opts):
868 def debugstate(ui, repo, **opts):
867 """show the contents of the current dirstate"""
869 """show the contents of the current dirstate"""
868
870
869 nodates = not opts['dates']
871 nodates = not opts['dates']
870 if opts.get('nodates') is not None:
872 if opts.get('nodates') is not None:
871 nodates = True
873 nodates = True
872 datesort = opts.get('datesort')
874 datesort = opts.get('datesort')
873
875
874 if datesort:
876 if datesort:
875 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
877 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
876 else:
878 else:
877 keyfunc = None # sort by filename
879 keyfunc = None # sort by filename
878 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
880 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
879 if ent[3] == -1:
881 if ent[3] == -1:
880 timestr = b'unset '
882 timestr = b'unset '
881 elif nodates:
883 elif nodates:
882 timestr = b'set '
884 timestr = b'set '
883 else:
885 else:
884 timestr = time.strftime(
886 timestr = time.strftime(
885 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
887 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
886 )
888 )
887 timestr = encoding.strtolocal(timestr)
889 timestr = encoding.strtolocal(timestr)
888 if ent[1] & 0o20000:
890 if ent[1] & 0o20000:
889 mode = b'lnk'
891 mode = b'lnk'
890 else:
892 else:
891 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
893 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
892 ui.write(b"%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
894 ui.write(b"%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
893 for f in repo.dirstate.copies():
895 for f in repo.dirstate.copies():
894 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
896 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
895
897
896
898
897 @command(
899 @command(
898 b'debugdiscovery',
900 b'debugdiscovery',
899 [
901 [
900 (b'', b'old', None, _(b'use old-style discovery')),
902 (b'', b'old', None, _(b'use old-style discovery')),
901 (
903 (
902 b'',
904 b'',
903 b'nonheads',
905 b'nonheads',
904 None,
906 None,
905 _(b'use old-style discovery with non-heads included'),
907 _(b'use old-style discovery with non-heads included'),
906 ),
908 ),
907 (b'', b'rev', [], b'restrict discovery to this set of revs'),
909 (b'', b'rev', [], b'restrict discovery to this set of revs'),
908 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
910 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
909 ]
911 ]
910 + cmdutil.remoteopts,
912 + cmdutil.remoteopts,
911 _(b'[--rev REV] [OTHER]'),
913 _(b'[--rev REV] [OTHER]'),
912 )
914 )
913 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
915 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
914 """runs the changeset discovery protocol in isolation"""
916 """runs the changeset discovery protocol in isolation"""
915 opts = pycompat.byteskwargs(opts)
917 opts = pycompat.byteskwargs(opts)
916 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
918 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
917 remote = hg.peer(repo, opts, remoteurl)
919 remote = hg.peer(repo, opts, remoteurl)
918 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
920 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
919
921
920 # make sure tests are repeatable
922 # make sure tests are repeatable
921 random.seed(int(opts[b'seed']))
923 random.seed(int(opts[b'seed']))
922
924
923 if opts.get(b'old'):
925 if opts.get(b'old'):
924
926
925 def doit(pushedrevs, remoteheads, remote=remote):
927 def doit(pushedrevs, remoteheads, remote=remote):
926 if not util.safehasattr(remote, b'branches'):
928 if not util.safehasattr(remote, b'branches'):
927 # enable in-client legacy support
929 # enable in-client legacy support
928 remote = localrepo.locallegacypeer(remote.local())
930 remote = localrepo.locallegacypeer(remote.local())
929 common, _in, hds = treediscovery.findcommonincoming(
931 common, _in, hds = treediscovery.findcommonincoming(
930 repo, remote, force=True
932 repo, remote, force=True
931 )
933 )
932 common = set(common)
934 common = set(common)
933 if not opts.get(b'nonheads'):
935 if not opts.get(b'nonheads'):
934 ui.writenoi18n(
936 ui.writenoi18n(
935 b"unpruned common: %s\n"
937 b"unpruned common: %s\n"
936 % b" ".join(sorted(short(n) for n in common))
938 % b" ".join(sorted(short(n) for n in common))
937 )
939 )
938
940
939 clnode = repo.changelog.node
941 clnode = repo.changelog.node
940 common = repo.revs(b'heads(::%ln)', common)
942 common = repo.revs(b'heads(::%ln)', common)
941 common = {clnode(r) for r in common}
943 common = {clnode(r) for r in common}
942 return common, hds
944 return common, hds
943
945
944 else:
946 else:
945
947
946 def doit(pushedrevs, remoteheads, remote=remote):
948 def doit(pushedrevs, remoteheads, remote=remote):
947 nodes = None
949 nodes = None
948 if pushedrevs:
950 if pushedrevs:
949 revs = scmutil.revrange(repo, pushedrevs)
951 revs = scmutil.revrange(repo, pushedrevs)
950 nodes = [repo[r].node() for r in revs]
952 nodes = [repo[r].node() for r in revs]
951 common, any, hds = setdiscovery.findcommonheads(
953 common, any, hds = setdiscovery.findcommonheads(
952 ui, repo, remote, ancestorsof=nodes
954 ui, repo, remote, ancestorsof=nodes
953 )
955 )
954 return common, hds
956 return common, hds
955
957
956 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
958 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
957 localrevs = opts[b'rev']
959 localrevs = opts[b'rev']
958 with util.timedcm('debug-discovery') as t:
960 with util.timedcm('debug-discovery') as t:
959 common, hds = doit(localrevs, remoterevs)
961 common, hds = doit(localrevs, remoterevs)
960
962
961 # compute all statistics
963 # compute all statistics
962 common = set(common)
964 common = set(common)
963 rheads = set(hds)
965 rheads = set(hds)
964 lheads = set(repo.heads())
966 lheads = set(repo.heads())
965
967
966 data = {}
968 data = {}
967 data[b'elapsed'] = t.elapsed
969 data[b'elapsed'] = t.elapsed
968 data[b'nb-common'] = len(common)
970 data[b'nb-common'] = len(common)
969 data[b'nb-common-local'] = len(common & lheads)
971 data[b'nb-common-local'] = len(common & lheads)
970 data[b'nb-common-remote'] = len(common & rheads)
972 data[b'nb-common-remote'] = len(common & rheads)
971 data[b'nb-common-both'] = len(common & rheads & lheads)
973 data[b'nb-common-both'] = len(common & rheads & lheads)
972 data[b'nb-local'] = len(lheads)
974 data[b'nb-local'] = len(lheads)
973 data[b'nb-local-missing'] = data[b'nb-local'] - data[b'nb-common-local']
975 data[b'nb-local-missing'] = data[b'nb-local'] - data[b'nb-common-local']
974 data[b'nb-remote'] = len(rheads)
976 data[b'nb-remote'] = len(rheads)
975 data[b'nb-remote-unknown'] = data[b'nb-remote'] - data[b'nb-common-remote']
977 data[b'nb-remote-unknown'] = data[b'nb-remote'] - data[b'nb-common-remote']
976 data[b'nb-revs'] = len(repo.revs(b'all()'))
978 data[b'nb-revs'] = len(repo.revs(b'all()'))
977 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
979 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
978 data[b'nb-revs-missing'] = data[b'nb-revs'] - data[b'nb-revs-common']
980 data[b'nb-revs-missing'] = data[b'nb-revs'] - data[b'nb-revs-common']
979
981
980 # display discovery summary
982 # display discovery summary
981 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
983 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
982 ui.writenoi18n(b"heads summary:\n")
984 ui.writenoi18n(b"heads summary:\n")
983 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
985 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
984 ui.writenoi18n(b" also local heads: %(nb-common-local)9d\n" % data)
986 ui.writenoi18n(b" also local heads: %(nb-common-local)9d\n" % data)
985 ui.writenoi18n(b" also remote heads: %(nb-common-remote)9d\n" % data)
987 ui.writenoi18n(b" also remote heads: %(nb-common-remote)9d\n" % data)
986 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
988 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
987 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
989 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
988 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
990 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
989 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
991 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
990 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
992 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
991 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
993 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
992 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
994 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
993 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
995 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
994 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
996 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
995 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
997 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
996
998
997 if ui.verbose:
999 if ui.verbose:
998 ui.writenoi18n(
1000 ui.writenoi18n(
999 b"common heads: %s\n" % b" ".join(sorted(short(n) for n in common))
1001 b"common heads: %s\n" % b" ".join(sorted(short(n) for n in common))
1000 )
1002 )
1001
1003
1002
1004
1003 _chunksize = 4 << 10
1005 _chunksize = 4 << 10
1004
1006
1005
1007
1006 @command(
1008 @command(
1007 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1009 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1008 )
1010 )
1009 def debugdownload(ui, repo, url, output=None, **opts):
1011 def debugdownload(ui, repo, url, output=None, **opts):
1010 """download a resource using Mercurial logic and config
1012 """download a resource using Mercurial logic and config
1011 """
1013 """
1012 fh = urlmod.open(ui, url, output)
1014 fh = urlmod.open(ui, url, output)
1013
1015
1014 dest = ui
1016 dest = ui
1015 if output:
1017 if output:
1016 dest = open(output, b"wb", _chunksize)
1018 dest = open(output, b"wb", _chunksize)
1017 try:
1019 try:
1018 data = fh.read(_chunksize)
1020 data = fh.read(_chunksize)
1019 while data:
1021 while data:
1020 dest.write(data)
1022 dest.write(data)
1021 data = fh.read(_chunksize)
1023 data = fh.read(_chunksize)
1022 finally:
1024 finally:
1023 if output:
1025 if output:
1024 dest.close()
1026 dest.close()
1025
1027
1026
1028
1027 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1029 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1028 def debugextensions(ui, repo, **opts):
1030 def debugextensions(ui, repo, **opts):
1029 '''show information about active extensions'''
1031 '''show information about active extensions'''
1030 opts = pycompat.byteskwargs(opts)
1032 opts = pycompat.byteskwargs(opts)
1031 exts = extensions.extensions(ui)
1033 exts = extensions.extensions(ui)
1032 hgver = util.version()
1034 hgver = util.version()
1033 fm = ui.formatter(b'debugextensions', opts)
1035 fm = ui.formatter(b'debugextensions', opts)
1034 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1036 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1035 isinternal = extensions.ismoduleinternal(extmod)
1037 isinternal = extensions.ismoduleinternal(extmod)
1036 extsource = None
1038 extsource = None
1037
1039
1038 if util.safehasattr(extmod, '__file__'):
1040 if util.safehasattr(extmod, '__file__'):
1039 extsource = pycompat.fsencode(extmod.__file__)
1041 extsource = pycompat.fsencode(extmod.__file__)
1040 elif getattr(sys, 'oxidized', False):
1042 elif getattr(sys, 'oxidized', False):
1041 extsource = pycompat.sysexecutable
1043 extsource = pycompat.sysexecutable
1042 if isinternal:
1044 if isinternal:
1043 exttestedwith = [] # never expose magic string to users
1045 exttestedwith = [] # never expose magic string to users
1044 else:
1046 else:
1045 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1047 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1046 extbuglink = getattr(extmod, 'buglink', None)
1048 extbuglink = getattr(extmod, 'buglink', None)
1047
1049
1048 fm.startitem()
1050 fm.startitem()
1049
1051
1050 if ui.quiet or ui.verbose:
1052 if ui.quiet or ui.verbose:
1051 fm.write(b'name', b'%s\n', extname)
1053 fm.write(b'name', b'%s\n', extname)
1052 else:
1054 else:
1053 fm.write(b'name', b'%s', extname)
1055 fm.write(b'name', b'%s', extname)
1054 if isinternal or hgver in exttestedwith:
1056 if isinternal or hgver in exttestedwith:
1055 fm.plain(b'\n')
1057 fm.plain(b'\n')
1056 elif not exttestedwith:
1058 elif not exttestedwith:
1057 fm.plain(_(b' (untested!)\n'))
1059 fm.plain(_(b' (untested!)\n'))
1058 else:
1060 else:
1059 lasttestedversion = exttestedwith[-1]
1061 lasttestedversion = exttestedwith[-1]
1060 fm.plain(b' (%s!)\n' % lasttestedversion)
1062 fm.plain(b' (%s!)\n' % lasttestedversion)
1061
1063
1062 fm.condwrite(
1064 fm.condwrite(
1063 ui.verbose and extsource,
1065 ui.verbose and extsource,
1064 b'source',
1066 b'source',
1065 _(b' location: %s\n'),
1067 _(b' location: %s\n'),
1066 extsource or b"",
1068 extsource or b"",
1067 )
1069 )
1068
1070
1069 if ui.verbose:
1071 if ui.verbose:
1070 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1072 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1071 fm.data(bundled=isinternal)
1073 fm.data(bundled=isinternal)
1072
1074
1073 fm.condwrite(
1075 fm.condwrite(
1074 ui.verbose and exttestedwith,
1076 ui.verbose and exttestedwith,
1075 b'testedwith',
1077 b'testedwith',
1076 _(b' tested with: %s\n'),
1078 _(b' tested with: %s\n'),
1077 fm.formatlist(exttestedwith, name=b'ver'),
1079 fm.formatlist(exttestedwith, name=b'ver'),
1078 )
1080 )
1079
1081
1080 fm.condwrite(
1082 fm.condwrite(
1081 ui.verbose and extbuglink,
1083 ui.verbose and extbuglink,
1082 b'buglink',
1084 b'buglink',
1083 _(b' bug reporting: %s\n'),
1085 _(b' bug reporting: %s\n'),
1084 extbuglink or b"",
1086 extbuglink or b"",
1085 )
1087 )
1086
1088
1087 fm.end()
1089 fm.end()
1088
1090
1089
1091
1090 @command(
1092 @command(
1091 b'debugfileset',
1093 b'debugfileset',
1092 [
1094 [
1093 (
1095 (
1094 b'r',
1096 b'r',
1095 b'rev',
1097 b'rev',
1096 b'',
1098 b'',
1097 _(b'apply the filespec on this revision'),
1099 _(b'apply the filespec on this revision'),
1098 _(b'REV'),
1100 _(b'REV'),
1099 ),
1101 ),
1100 (
1102 (
1101 b'',
1103 b'',
1102 b'all-files',
1104 b'all-files',
1103 False,
1105 False,
1104 _(b'test files from all revisions and working directory'),
1106 _(b'test files from all revisions and working directory'),
1105 ),
1107 ),
1106 (
1108 (
1107 b's',
1109 b's',
1108 b'show-matcher',
1110 b'show-matcher',
1109 None,
1111 None,
1110 _(b'print internal representation of matcher'),
1112 _(b'print internal representation of matcher'),
1111 ),
1113 ),
1112 (
1114 (
1113 b'p',
1115 b'p',
1114 b'show-stage',
1116 b'show-stage',
1115 [],
1117 [],
1116 _(b'print parsed tree at the given stage'),
1118 _(b'print parsed tree at the given stage'),
1117 _(b'NAME'),
1119 _(b'NAME'),
1118 ),
1120 ),
1119 ],
1121 ],
1120 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1122 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1121 )
1123 )
1122 def debugfileset(ui, repo, expr, **opts):
1124 def debugfileset(ui, repo, expr, **opts):
1123 '''parse and apply a fileset specification'''
1125 '''parse and apply a fileset specification'''
1124 from . import fileset
1126 from . import fileset
1125
1127
1126 fileset.symbols # force import of fileset so we have predicates to optimize
1128 fileset.symbols # force import of fileset so we have predicates to optimize
1127 opts = pycompat.byteskwargs(opts)
1129 opts = pycompat.byteskwargs(opts)
1128 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1130 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1129
1131
1130 stages = [
1132 stages = [
1131 (b'parsed', pycompat.identity),
1133 (b'parsed', pycompat.identity),
1132 (b'analyzed', filesetlang.analyze),
1134 (b'analyzed', filesetlang.analyze),
1133 (b'optimized', filesetlang.optimize),
1135 (b'optimized', filesetlang.optimize),
1134 ]
1136 ]
1135 stagenames = set(n for n, f in stages)
1137 stagenames = set(n for n, f in stages)
1136
1138
1137 showalways = set()
1139 showalways = set()
1138 if ui.verbose and not opts[b'show_stage']:
1140 if ui.verbose and not opts[b'show_stage']:
1139 # show parsed tree by --verbose (deprecated)
1141 # show parsed tree by --verbose (deprecated)
1140 showalways.add(b'parsed')
1142 showalways.add(b'parsed')
1141 if opts[b'show_stage'] == [b'all']:
1143 if opts[b'show_stage'] == [b'all']:
1142 showalways.update(stagenames)
1144 showalways.update(stagenames)
1143 else:
1145 else:
1144 for n in opts[b'show_stage']:
1146 for n in opts[b'show_stage']:
1145 if n not in stagenames:
1147 if n not in stagenames:
1146 raise error.Abort(_(b'invalid stage name: %s') % n)
1148 raise error.Abort(_(b'invalid stage name: %s') % n)
1147 showalways.update(opts[b'show_stage'])
1149 showalways.update(opts[b'show_stage'])
1148
1150
1149 tree = filesetlang.parse(expr)
1151 tree = filesetlang.parse(expr)
1150 for n, f in stages:
1152 for n, f in stages:
1151 tree = f(tree)
1153 tree = f(tree)
1152 if n in showalways:
1154 if n in showalways:
1153 if opts[b'show_stage'] or n != b'parsed':
1155 if opts[b'show_stage'] or n != b'parsed':
1154 ui.write(b"* %s:\n" % n)
1156 ui.write(b"* %s:\n" % n)
1155 ui.write(filesetlang.prettyformat(tree), b"\n")
1157 ui.write(filesetlang.prettyformat(tree), b"\n")
1156
1158
1157 files = set()
1159 files = set()
1158 if opts[b'all_files']:
1160 if opts[b'all_files']:
1159 for r in repo:
1161 for r in repo:
1160 c = repo[r]
1162 c = repo[r]
1161 files.update(c.files())
1163 files.update(c.files())
1162 files.update(c.substate)
1164 files.update(c.substate)
1163 if opts[b'all_files'] or ctx.rev() is None:
1165 if opts[b'all_files'] or ctx.rev() is None:
1164 wctx = repo[None]
1166 wctx = repo[None]
1165 files.update(
1167 files.update(
1166 repo.dirstate.walk(
1168 repo.dirstate.walk(
1167 scmutil.matchall(repo),
1169 scmutil.matchall(repo),
1168 subrepos=list(wctx.substate),
1170 subrepos=list(wctx.substate),
1169 unknown=True,
1171 unknown=True,
1170 ignored=True,
1172 ignored=True,
1171 )
1173 )
1172 )
1174 )
1173 files.update(wctx.substate)
1175 files.update(wctx.substate)
1174 else:
1176 else:
1175 files.update(ctx.files())
1177 files.update(ctx.files())
1176 files.update(ctx.substate)
1178 files.update(ctx.substate)
1177
1179
1178 m = ctx.matchfileset(repo.getcwd(), expr)
1180 m = ctx.matchfileset(repo.getcwd(), expr)
1179 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1181 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1180 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1182 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1181 for f in sorted(files):
1183 for f in sorted(files):
1182 if not m(f):
1184 if not m(f):
1183 continue
1185 continue
1184 ui.write(b"%s\n" % f)
1186 ui.write(b"%s\n" % f)
1185
1187
1186
1188
1187 @command(b'debugformat', [] + cmdutil.formatteropts)
1189 @command(b'debugformat', [] + cmdutil.formatteropts)
1188 def debugformat(ui, repo, **opts):
1190 def debugformat(ui, repo, **opts):
1189 """display format information about the current repository
1191 """display format information about the current repository
1190
1192
1191 Use --verbose to get extra information about current config value and
1193 Use --verbose to get extra information about current config value and
1192 Mercurial default."""
1194 Mercurial default."""
1193 opts = pycompat.byteskwargs(opts)
1195 opts = pycompat.byteskwargs(opts)
1194 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1196 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1195 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1197 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1196
1198
1197 def makeformatname(name):
1199 def makeformatname(name):
1198 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1200 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1199
1201
1200 fm = ui.formatter(b'debugformat', opts)
1202 fm = ui.formatter(b'debugformat', opts)
1201 if fm.isplain():
1203 if fm.isplain():
1202
1204
1203 def formatvalue(value):
1205 def formatvalue(value):
1204 if util.safehasattr(value, b'startswith'):
1206 if util.safehasattr(value, b'startswith'):
1205 return value
1207 return value
1206 if value:
1208 if value:
1207 return b'yes'
1209 return b'yes'
1208 else:
1210 else:
1209 return b'no'
1211 return b'no'
1210
1212
1211 else:
1213 else:
1212 formatvalue = pycompat.identity
1214 formatvalue = pycompat.identity
1213
1215
1214 fm.plain(b'format-variant')
1216 fm.plain(b'format-variant')
1215 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1217 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1216 fm.plain(b' repo')
1218 fm.plain(b' repo')
1217 if ui.verbose:
1219 if ui.verbose:
1218 fm.plain(b' config default')
1220 fm.plain(b' config default')
1219 fm.plain(b'\n')
1221 fm.plain(b'\n')
1220 for fv in upgrade.allformatvariant:
1222 for fv in upgrade.allformatvariant:
1221 fm.startitem()
1223 fm.startitem()
1222 repovalue = fv.fromrepo(repo)
1224 repovalue = fv.fromrepo(repo)
1223 configvalue = fv.fromconfig(repo)
1225 configvalue = fv.fromconfig(repo)
1224
1226
1225 if repovalue != configvalue:
1227 if repovalue != configvalue:
1226 namelabel = b'formatvariant.name.mismatchconfig'
1228 namelabel = b'formatvariant.name.mismatchconfig'
1227 repolabel = b'formatvariant.repo.mismatchconfig'
1229 repolabel = b'formatvariant.repo.mismatchconfig'
1228 elif repovalue != fv.default:
1230 elif repovalue != fv.default:
1229 namelabel = b'formatvariant.name.mismatchdefault'
1231 namelabel = b'formatvariant.name.mismatchdefault'
1230 repolabel = b'formatvariant.repo.mismatchdefault'
1232 repolabel = b'formatvariant.repo.mismatchdefault'
1231 else:
1233 else:
1232 namelabel = b'formatvariant.name.uptodate'
1234 namelabel = b'formatvariant.name.uptodate'
1233 repolabel = b'formatvariant.repo.uptodate'
1235 repolabel = b'formatvariant.repo.uptodate'
1234
1236
1235 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1237 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1236 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1238 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1237 if fv.default != configvalue:
1239 if fv.default != configvalue:
1238 configlabel = b'formatvariant.config.special'
1240 configlabel = b'formatvariant.config.special'
1239 else:
1241 else:
1240 configlabel = b'formatvariant.config.default'
1242 configlabel = b'formatvariant.config.default'
1241 fm.condwrite(
1243 fm.condwrite(
1242 ui.verbose,
1244 ui.verbose,
1243 b'config',
1245 b'config',
1244 b' %6s',
1246 b' %6s',
1245 formatvalue(configvalue),
1247 formatvalue(configvalue),
1246 label=configlabel,
1248 label=configlabel,
1247 )
1249 )
1248 fm.condwrite(
1250 fm.condwrite(
1249 ui.verbose,
1251 ui.verbose,
1250 b'default',
1252 b'default',
1251 b' %7s',
1253 b' %7s',
1252 formatvalue(fv.default),
1254 formatvalue(fv.default),
1253 label=b'formatvariant.default',
1255 label=b'formatvariant.default',
1254 )
1256 )
1255 fm.plain(b'\n')
1257 fm.plain(b'\n')
1256 fm.end()
1258 fm.end()
1257
1259
1258
1260
1259 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1261 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1260 def debugfsinfo(ui, path=b"."):
1262 def debugfsinfo(ui, path=b"."):
1261 """show information detected about current filesystem"""
1263 """show information detected about current filesystem"""
1262 ui.writenoi18n(b'path: %s\n' % path)
1264 ui.writenoi18n(b'path: %s\n' % path)
1263 ui.writenoi18n(
1265 ui.writenoi18n(
1264 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1266 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1265 )
1267 )
1266 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1268 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1267 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1269 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1268 ui.writenoi18n(
1270 ui.writenoi18n(
1269 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1271 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1270 )
1272 )
1271 ui.writenoi18n(
1273 ui.writenoi18n(
1272 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1274 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1273 )
1275 )
1274 casesensitive = b'(unknown)'
1276 casesensitive = b'(unknown)'
1275 try:
1277 try:
1276 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1278 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1277 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1279 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1278 except OSError:
1280 except OSError:
1279 pass
1281 pass
1280 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1282 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1281
1283
1282
1284
1283 @command(
1285 @command(
1284 b'debuggetbundle',
1286 b'debuggetbundle',
1285 [
1287 [
1286 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1288 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1287 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1289 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1288 (
1290 (
1289 b't',
1291 b't',
1290 b'type',
1292 b'type',
1291 b'bzip2',
1293 b'bzip2',
1292 _(b'bundle compression type to use'),
1294 _(b'bundle compression type to use'),
1293 _(b'TYPE'),
1295 _(b'TYPE'),
1294 ),
1296 ),
1295 ],
1297 ],
1296 _(b'REPO FILE [-H|-C ID]...'),
1298 _(b'REPO FILE [-H|-C ID]...'),
1297 norepo=True,
1299 norepo=True,
1298 )
1300 )
1299 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1301 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1300 """retrieves a bundle from a repo
1302 """retrieves a bundle from a repo
1301
1303
1302 Every ID must be a full-length hex node id string. Saves the bundle to the
1304 Every ID must be a full-length hex node id string. Saves the bundle to the
1303 given file.
1305 given file.
1304 """
1306 """
1305 opts = pycompat.byteskwargs(opts)
1307 opts = pycompat.byteskwargs(opts)
1306 repo = hg.peer(ui, opts, repopath)
1308 repo = hg.peer(ui, opts, repopath)
1307 if not repo.capable(b'getbundle'):
1309 if not repo.capable(b'getbundle'):
1308 raise error.Abort(b"getbundle() not supported by target repository")
1310 raise error.Abort(b"getbundle() not supported by target repository")
1309 args = {}
1311 args = {}
1310 if common:
1312 if common:
1311 args['common'] = [bin(s) for s in common]
1313 args['common'] = [bin(s) for s in common]
1312 if head:
1314 if head:
1313 args['heads'] = [bin(s) for s in head]
1315 args['heads'] = [bin(s) for s in head]
1314 # TODO: get desired bundlecaps from command line.
1316 # TODO: get desired bundlecaps from command line.
1315 args['bundlecaps'] = None
1317 args['bundlecaps'] = None
1316 bundle = repo.getbundle(b'debug', **args)
1318 bundle = repo.getbundle(b'debug', **args)
1317
1319
1318 bundletype = opts.get(b'type', b'bzip2').lower()
1320 bundletype = opts.get(b'type', b'bzip2').lower()
1319 btypes = {
1321 btypes = {
1320 b'none': b'HG10UN',
1322 b'none': b'HG10UN',
1321 b'bzip2': b'HG10BZ',
1323 b'bzip2': b'HG10BZ',
1322 b'gzip': b'HG10GZ',
1324 b'gzip': b'HG10GZ',
1323 b'bundle2': b'HG20',
1325 b'bundle2': b'HG20',
1324 }
1326 }
1325 bundletype = btypes.get(bundletype)
1327 bundletype = btypes.get(bundletype)
1326 if bundletype not in bundle2.bundletypes:
1328 if bundletype not in bundle2.bundletypes:
1327 raise error.Abort(_(b'unknown bundle type specified with --type'))
1329 raise error.Abort(_(b'unknown bundle type specified with --type'))
1328 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1330 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1329
1331
1330
1332
1331 @command(b'debugignore', [], b'[FILE]')
1333 @command(b'debugignore', [], b'[FILE]')
1332 def debugignore(ui, repo, *files, **opts):
1334 def debugignore(ui, repo, *files, **opts):
1333 """display the combined ignore pattern and information about ignored files
1335 """display the combined ignore pattern and information about ignored files
1334
1336
1335 With no argument display the combined ignore pattern.
1337 With no argument display the combined ignore pattern.
1336
1338
1337 Given space separated file names, shows if the given file is ignored and
1339 Given space separated file names, shows if the given file is ignored and
1338 if so, show the ignore rule (file and line number) that matched it.
1340 if so, show the ignore rule (file and line number) that matched it.
1339 """
1341 """
1340 ignore = repo.dirstate._ignore
1342 ignore = repo.dirstate._ignore
1341 if not files:
1343 if not files:
1342 # Show all the patterns
1344 # Show all the patterns
1343 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1345 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1344 else:
1346 else:
1345 m = scmutil.match(repo[None], pats=files)
1347 m = scmutil.match(repo[None], pats=files)
1346 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1348 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1347 for f in m.files():
1349 for f in m.files():
1348 nf = util.normpath(f)
1350 nf = util.normpath(f)
1349 ignored = None
1351 ignored = None
1350 ignoredata = None
1352 ignoredata = None
1351 if nf != b'.':
1353 if nf != b'.':
1352 if ignore(nf):
1354 if ignore(nf):
1353 ignored = nf
1355 ignored = nf
1354 ignoredata = repo.dirstate._ignorefileandline(nf)
1356 ignoredata = repo.dirstate._ignorefileandline(nf)
1355 else:
1357 else:
1356 for p in pathutil.finddirs(nf):
1358 for p in pathutil.finddirs(nf):
1357 if ignore(p):
1359 if ignore(p):
1358 ignored = p
1360 ignored = p
1359 ignoredata = repo.dirstate._ignorefileandline(p)
1361 ignoredata = repo.dirstate._ignorefileandline(p)
1360 break
1362 break
1361 if ignored:
1363 if ignored:
1362 if ignored == nf:
1364 if ignored == nf:
1363 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1365 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1364 else:
1366 else:
1365 ui.write(
1367 ui.write(
1366 _(
1368 _(
1367 b"%s is ignored because of "
1369 b"%s is ignored because of "
1368 b"containing directory %s\n"
1370 b"containing directory %s\n"
1369 )
1371 )
1370 % (uipathfn(f), ignored)
1372 % (uipathfn(f), ignored)
1371 )
1373 )
1372 ignorefile, lineno, line = ignoredata
1374 ignorefile, lineno, line = ignoredata
1373 ui.write(
1375 ui.write(
1374 _(b"(ignore rule in %s, line %d: '%s')\n")
1376 _(b"(ignore rule in %s, line %d: '%s')\n")
1375 % (ignorefile, lineno, line)
1377 % (ignorefile, lineno, line)
1376 )
1378 )
1377 else:
1379 else:
1378 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1380 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1379
1381
1380
1382
1381 @command(
1383 @command(
1382 b'debugindex',
1384 b'debugindex',
1383 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1385 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1384 _(b'-c|-m|FILE'),
1386 _(b'-c|-m|FILE'),
1385 )
1387 )
1386 def debugindex(ui, repo, file_=None, **opts):
1388 def debugindex(ui, repo, file_=None, **opts):
1387 """dump index data for a storage primitive"""
1389 """dump index data for a storage primitive"""
1388 opts = pycompat.byteskwargs(opts)
1390 opts = pycompat.byteskwargs(opts)
1389 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1391 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1390
1392
1391 if ui.debugflag:
1393 if ui.debugflag:
1392 shortfn = hex
1394 shortfn = hex
1393 else:
1395 else:
1394 shortfn = short
1396 shortfn = short
1395
1397
1396 idlen = 12
1398 idlen = 12
1397 for i in store:
1399 for i in store:
1398 idlen = len(shortfn(store.node(i)))
1400 idlen = len(shortfn(store.node(i)))
1399 break
1401 break
1400
1402
1401 fm = ui.formatter(b'debugindex', opts)
1403 fm = ui.formatter(b'debugindex', opts)
1402 fm.plain(
1404 fm.plain(
1403 b' rev linkrev %s %s p2\n'
1405 b' rev linkrev %s %s p2\n'
1404 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1406 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1405 )
1407 )
1406
1408
1407 for rev in store:
1409 for rev in store:
1408 node = store.node(rev)
1410 node = store.node(rev)
1409 parents = store.parents(node)
1411 parents = store.parents(node)
1410
1412
1411 fm.startitem()
1413 fm.startitem()
1412 fm.write(b'rev', b'%6d ', rev)
1414 fm.write(b'rev', b'%6d ', rev)
1413 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1415 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1414 fm.write(b'node', b'%s ', shortfn(node))
1416 fm.write(b'node', b'%s ', shortfn(node))
1415 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1417 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1416 fm.write(b'p2', b'%s', shortfn(parents[1]))
1418 fm.write(b'p2', b'%s', shortfn(parents[1]))
1417 fm.plain(b'\n')
1419 fm.plain(b'\n')
1418
1420
1419 fm.end()
1421 fm.end()
1420
1422
1421
1423
1422 @command(
1424 @command(
1423 b'debugindexdot',
1425 b'debugindexdot',
1424 cmdutil.debugrevlogopts,
1426 cmdutil.debugrevlogopts,
1425 _(b'-c|-m|FILE'),
1427 _(b'-c|-m|FILE'),
1426 optionalrepo=True,
1428 optionalrepo=True,
1427 )
1429 )
1428 def debugindexdot(ui, repo, file_=None, **opts):
1430 def debugindexdot(ui, repo, file_=None, **opts):
1429 """dump an index DAG as a graphviz dot file"""
1431 """dump an index DAG as a graphviz dot file"""
1430 opts = pycompat.byteskwargs(opts)
1432 opts = pycompat.byteskwargs(opts)
1431 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1433 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1432 ui.writenoi18n(b"digraph G {\n")
1434 ui.writenoi18n(b"digraph G {\n")
1433 for i in r:
1435 for i in r:
1434 node = r.node(i)
1436 node = r.node(i)
1435 pp = r.parents(node)
1437 pp = r.parents(node)
1436 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1438 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1437 if pp[1] != nullid:
1439 if pp[1] != nullid:
1438 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1440 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1439 ui.write(b"}\n")
1441 ui.write(b"}\n")
1440
1442
1441
1443
1442 @command(b'debugindexstats', [])
1444 @command(b'debugindexstats', [])
1443 def debugindexstats(ui, repo):
1445 def debugindexstats(ui, repo):
1444 """show stats related to the changelog index"""
1446 """show stats related to the changelog index"""
1445 repo.changelog.shortest(nullid, 1)
1447 repo.changelog.shortest(nullid, 1)
1446 index = repo.changelog.index
1448 index = repo.changelog.index
1447 if not util.safehasattr(index, b'stats'):
1449 if not util.safehasattr(index, b'stats'):
1448 raise error.Abort(_(b'debugindexstats only works with native code'))
1450 raise error.Abort(_(b'debugindexstats only works with native code'))
1449 for k, v in sorted(index.stats().items()):
1451 for k, v in sorted(index.stats().items()):
1450 ui.write(b'%s: %d\n' % (k, v))
1452 ui.write(b'%s: %d\n' % (k, v))
1451
1453
1452
1454
1453 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1455 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1454 def debuginstall(ui, **opts):
1456 def debuginstall(ui, **opts):
1455 '''test Mercurial installation
1457 '''test Mercurial installation
1456
1458
1457 Returns 0 on success.
1459 Returns 0 on success.
1458 '''
1460 '''
1459 opts = pycompat.byteskwargs(opts)
1461 opts = pycompat.byteskwargs(opts)
1460
1462
1461 problems = 0
1463 problems = 0
1462
1464
1463 fm = ui.formatter(b'debuginstall', opts)
1465 fm = ui.formatter(b'debuginstall', opts)
1464 fm.startitem()
1466 fm.startitem()
1465
1467
1466 # encoding
1468 # encoding
1467 fm.write(b'encoding', _(b"checking encoding (%s)...\n"), encoding.encoding)
1469 fm.write(b'encoding', _(b"checking encoding (%s)...\n"), encoding.encoding)
1468 err = None
1470 err = None
1469 try:
1471 try:
1470 codecs.lookup(pycompat.sysstr(encoding.encoding))
1472 codecs.lookup(pycompat.sysstr(encoding.encoding))
1471 except LookupError as inst:
1473 except LookupError as inst:
1472 err = stringutil.forcebytestr(inst)
1474 err = stringutil.forcebytestr(inst)
1473 problems += 1
1475 problems += 1
1474 fm.condwrite(
1476 fm.condwrite(
1475 err,
1477 err,
1476 b'encodingerror',
1478 b'encodingerror',
1477 _(b" %s\n (check that your locale is properly set)\n"),
1479 _(b" %s\n (check that your locale is properly set)\n"),
1478 err,
1480 err,
1479 )
1481 )
1480
1482
1481 # Python
1483 # Python
1482 pythonlib = None
1484 pythonlib = None
1483 if util.safehasattr(os, '__file__'):
1485 if util.safehasattr(os, '__file__'):
1484 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1486 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1485 elif getattr(sys, 'oxidized', False):
1487 elif getattr(sys, 'oxidized', False):
1486 pythonlib = pycompat.sysexecutable
1488 pythonlib = pycompat.sysexecutable
1487
1489
1488 fm.write(
1490 fm.write(
1489 b'pythonexe',
1491 b'pythonexe',
1490 _(b"checking Python executable (%s)\n"),
1492 _(b"checking Python executable (%s)\n"),
1491 pycompat.sysexecutable or _(b"unknown"),
1493 pycompat.sysexecutable or _(b"unknown"),
1492 )
1494 )
1493 fm.write(
1495 fm.write(
1494 b'pythonimplementation',
1496 b'pythonimplementation',
1495 _(b"checking Python implementation (%s)\n"),
1497 _(b"checking Python implementation (%s)\n"),
1496 pycompat.sysbytes(platform.python_implementation()),
1498 pycompat.sysbytes(platform.python_implementation()),
1497 )
1499 )
1498 fm.write(
1500 fm.write(
1499 b'pythonver',
1501 b'pythonver',
1500 _(b"checking Python version (%s)\n"),
1502 _(b"checking Python version (%s)\n"),
1501 (b"%d.%d.%d" % sys.version_info[:3]),
1503 (b"%d.%d.%d" % sys.version_info[:3]),
1502 )
1504 )
1503 fm.write(
1505 fm.write(
1504 b'pythonlib',
1506 b'pythonlib',
1505 _(b"checking Python lib (%s)...\n"),
1507 _(b"checking Python lib (%s)...\n"),
1506 pythonlib or _(b"unknown"),
1508 pythonlib or _(b"unknown"),
1507 )
1509 )
1508
1510
1509 security = set(sslutil.supportedprotocols)
1511 security = set(sslutil.supportedprotocols)
1510 if sslutil.hassni:
1512 if sslutil.hassni:
1511 security.add(b'sni')
1513 security.add(b'sni')
1512
1514
1513 fm.write(
1515 fm.write(
1514 b'pythonsecurity',
1516 b'pythonsecurity',
1515 _(b"checking Python security support (%s)\n"),
1517 _(b"checking Python security support (%s)\n"),
1516 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1518 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1517 )
1519 )
1518
1520
1519 # These are warnings, not errors. So don't increment problem count. This
1521 # These are warnings, not errors. So don't increment problem count. This
1520 # may change in the future.
1522 # may change in the future.
1521 if b'tls1.2' not in security:
1523 if b'tls1.2' not in security:
1522 fm.plain(
1524 fm.plain(
1523 _(
1525 _(
1524 b' TLS 1.2 not supported by Python install; '
1526 b' TLS 1.2 not supported by Python install; '
1525 b'network connections lack modern security\n'
1527 b'network connections lack modern security\n'
1526 )
1528 )
1527 )
1529 )
1528 if b'sni' not in security:
1530 if b'sni' not in security:
1529 fm.plain(
1531 fm.plain(
1530 _(
1532 _(
1531 b' SNI not supported by Python install; may have '
1533 b' SNI not supported by Python install; may have '
1532 b'connectivity issues with some servers\n'
1534 b'connectivity issues with some servers\n'
1533 )
1535 )
1534 )
1536 )
1535
1537
1536 # TODO print CA cert info
1538 # TODO print CA cert info
1537
1539
1538 # hg version
1540 # hg version
1539 hgver = util.version()
1541 hgver = util.version()
1540 fm.write(
1542 fm.write(
1541 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1543 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1542 )
1544 )
1543 fm.write(
1545 fm.write(
1544 b'hgverextra',
1546 b'hgverextra',
1545 _(b"checking Mercurial custom build (%s)\n"),
1547 _(b"checking Mercurial custom build (%s)\n"),
1546 b'+'.join(hgver.split(b'+')[1:]),
1548 b'+'.join(hgver.split(b'+')[1:]),
1547 )
1549 )
1548
1550
1549 # compiled modules
1551 # compiled modules
1550 hgmodules = None
1552 hgmodules = None
1551 if util.safehasattr(sys.modules[__name__], '__file__'):
1553 if util.safehasattr(sys.modules[__name__], '__file__'):
1552 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1554 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1553 elif getattr(sys, 'oxidized', False):
1555 elif getattr(sys, 'oxidized', False):
1554 hgmodules = pycompat.sysexecutable
1556 hgmodules = pycompat.sysexecutable
1555
1557
1556 fm.write(
1558 fm.write(
1557 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1559 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1558 )
1560 )
1559 fm.write(
1561 fm.write(
1560 b'hgmodules',
1562 b'hgmodules',
1561 _(b"checking installed modules (%s)...\n"),
1563 _(b"checking installed modules (%s)...\n"),
1562 hgmodules or _(b"unknown"),
1564 hgmodules or _(b"unknown"),
1563 )
1565 )
1564
1566
1565 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1567 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1566 rustext = rustandc # for now, that's the only case
1568 rustext = rustandc # for now, that's the only case
1567 cext = policy.policy in (b'c', b'allow') or rustandc
1569 cext = policy.policy in (b'c', b'allow') or rustandc
1568 nopure = cext or rustext
1570 nopure = cext or rustext
1569 if nopure:
1571 if nopure:
1570 err = None
1572 err = None
1571 try:
1573 try:
1572 if cext:
1574 if cext:
1573 from .cext import ( # pytype: disable=import-error
1575 from .cext import ( # pytype: disable=import-error
1574 base85,
1576 base85,
1575 bdiff,
1577 bdiff,
1576 mpatch,
1578 mpatch,
1577 osutil,
1579 osutil,
1578 )
1580 )
1579
1581
1580 # quiet pyflakes
1582 # quiet pyflakes
1581 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1583 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1582 if rustext:
1584 if rustext:
1583 from .rustext import ( # pytype: disable=import-error
1585 from .rustext import ( # pytype: disable=import-error
1584 ancestor,
1586 ancestor,
1585 dirstate,
1587 dirstate,
1586 )
1588 )
1587
1589
1588 dir(ancestor), dir(dirstate) # quiet pyflakes
1590 dir(ancestor), dir(dirstate) # quiet pyflakes
1589 except Exception as inst:
1591 except Exception as inst:
1590 err = stringutil.forcebytestr(inst)
1592 err = stringutil.forcebytestr(inst)
1591 problems += 1
1593 problems += 1
1592 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1594 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1593
1595
1594 compengines = util.compengines._engines.values()
1596 compengines = util.compengines._engines.values()
1595 fm.write(
1597 fm.write(
1596 b'compengines',
1598 b'compengines',
1597 _(b'checking registered compression engines (%s)\n'),
1599 _(b'checking registered compression engines (%s)\n'),
1598 fm.formatlist(
1600 fm.formatlist(
1599 sorted(e.name() for e in compengines),
1601 sorted(e.name() for e in compengines),
1600 name=b'compengine',
1602 name=b'compengine',
1601 fmt=b'%s',
1603 fmt=b'%s',
1602 sep=b', ',
1604 sep=b', ',
1603 ),
1605 ),
1604 )
1606 )
1605 fm.write(
1607 fm.write(
1606 b'compenginesavail',
1608 b'compenginesavail',
1607 _(b'checking available compression engines (%s)\n'),
1609 _(b'checking available compression engines (%s)\n'),
1608 fm.formatlist(
1610 fm.formatlist(
1609 sorted(e.name() for e in compengines if e.available()),
1611 sorted(e.name() for e in compengines if e.available()),
1610 name=b'compengine',
1612 name=b'compengine',
1611 fmt=b'%s',
1613 fmt=b'%s',
1612 sep=b', ',
1614 sep=b', ',
1613 ),
1615 ),
1614 )
1616 )
1615 wirecompengines = compression.compengines.supportedwireengines(
1617 wirecompengines = compression.compengines.supportedwireengines(
1616 compression.SERVERROLE
1618 compression.SERVERROLE
1617 )
1619 )
1618 fm.write(
1620 fm.write(
1619 b'compenginesserver',
1621 b'compenginesserver',
1620 _(
1622 _(
1621 b'checking available compression engines '
1623 b'checking available compression engines '
1622 b'for wire protocol (%s)\n'
1624 b'for wire protocol (%s)\n'
1623 ),
1625 ),
1624 fm.formatlist(
1626 fm.formatlist(
1625 [e.name() for e in wirecompengines if e.wireprotosupport()],
1627 [e.name() for e in wirecompengines if e.wireprotosupport()],
1626 name=b'compengine',
1628 name=b'compengine',
1627 fmt=b'%s',
1629 fmt=b'%s',
1628 sep=b', ',
1630 sep=b', ',
1629 ),
1631 ),
1630 )
1632 )
1631 re2 = b'missing'
1633 re2 = b'missing'
1632 if util._re2:
1634 if util._re2:
1633 re2 = b'available'
1635 re2 = b'available'
1634 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1636 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1635 fm.data(re2=bool(util._re2))
1637 fm.data(re2=bool(util._re2))
1636
1638
1637 # templates
1639 # templates
1638 p = templater.templatepaths()
1640 p = templater.templatepaths()
1639 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1641 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1640 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1642 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1641 if p:
1643 if p:
1642 m = templater.templatepath(b"map-cmdline.default")
1644 m = templater.templatepath(b"map-cmdline.default")
1643 if m:
1645 if m:
1644 # template found, check if it is working
1646 # template found, check if it is working
1645 err = None
1647 err = None
1646 try:
1648 try:
1647 templater.templater.frommapfile(m)
1649 templater.templater.frommapfile(m)
1648 except Exception as inst:
1650 except Exception as inst:
1649 err = stringutil.forcebytestr(inst)
1651 err = stringutil.forcebytestr(inst)
1650 p = None
1652 p = None
1651 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1653 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1652 else:
1654 else:
1653 p = None
1655 p = None
1654 fm.condwrite(
1656 fm.condwrite(
1655 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1657 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1656 )
1658 )
1657 fm.condwrite(
1659 fm.condwrite(
1658 not m,
1660 not m,
1659 b'defaulttemplatenotfound',
1661 b'defaulttemplatenotfound',
1660 _(b" template '%s' not found\n"),
1662 _(b" template '%s' not found\n"),
1661 b"default",
1663 b"default",
1662 )
1664 )
1663 if not p:
1665 if not p:
1664 problems += 1
1666 problems += 1
1665 fm.condwrite(
1667 fm.condwrite(
1666 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1668 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1667 )
1669 )
1668
1670
1669 # editor
1671 # editor
1670 editor = ui.geteditor()
1672 editor = ui.geteditor()
1671 editor = util.expandpath(editor)
1673 editor = util.expandpath(editor)
1672 editorbin = procutil.shellsplit(editor)[0]
1674 editorbin = procutil.shellsplit(editor)[0]
1673 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1675 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1674 cmdpath = procutil.findexe(editorbin)
1676 cmdpath = procutil.findexe(editorbin)
1675 fm.condwrite(
1677 fm.condwrite(
1676 not cmdpath and editor == b'vi',
1678 not cmdpath and editor == b'vi',
1677 b'vinotfound',
1679 b'vinotfound',
1678 _(
1680 _(
1679 b" No commit editor set and can't find %s in PATH\n"
1681 b" No commit editor set and can't find %s in PATH\n"
1680 b" (specify a commit editor in your configuration"
1682 b" (specify a commit editor in your configuration"
1681 b" file)\n"
1683 b" file)\n"
1682 ),
1684 ),
1683 not cmdpath and editor == b'vi' and editorbin,
1685 not cmdpath and editor == b'vi' and editorbin,
1684 )
1686 )
1685 fm.condwrite(
1687 fm.condwrite(
1686 not cmdpath and editor != b'vi',
1688 not cmdpath and editor != b'vi',
1687 b'editornotfound',
1689 b'editornotfound',
1688 _(
1690 _(
1689 b" Can't find editor '%s' in PATH\n"
1691 b" Can't find editor '%s' in PATH\n"
1690 b" (specify a commit editor in your configuration"
1692 b" (specify a commit editor in your configuration"
1691 b" file)\n"
1693 b" file)\n"
1692 ),
1694 ),
1693 not cmdpath and editorbin,
1695 not cmdpath and editorbin,
1694 )
1696 )
1695 if not cmdpath and editor != b'vi':
1697 if not cmdpath and editor != b'vi':
1696 problems += 1
1698 problems += 1
1697
1699
1698 # check username
1700 # check username
1699 username = None
1701 username = None
1700 err = None
1702 err = None
1701 try:
1703 try:
1702 username = ui.username()
1704 username = ui.username()
1703 except error.Abort as e:
1705 except error.Abort as e:
1704 err = stringutil.forcebytestr(e)
1706 err = stringutil.forcebytestr(e)
1705 problems += 1
1707 problems += 1
1706
1708
1707 fm.condwrite(
1709 fm.condwrite(
1708 username, b'username', _(b"checking username (%s)\n"), username
1710 username, b'username', _(b"checking username (%s)\n"), username
1709 )
1711 )
1710 fm.condwrite(
1712 fm.condwrite(
1711 err,
1713 err,
1712 b'usernameerror',
1714 b'usernameerror',
1713 _(
1715 _(
1714 b"checking username...\n %s\n"
1716 b"checking username...\n %s\n"
1715 b" (specify a username in your configuration file)\n"
1717 b" (specify a username in your configuration file)\n"
1716 ),
1718 ),
1717 err,
1719 err,
1718 )
1720 )
1719
1721
1720 for name, mod in extensions.extensions():
1722 for name, mod in extensions.extensions():
1721 handler = getattr(mod, 'debuginstall', None)
1723 handler = getattr(mod, 'debuginstall', None)
1722 if handler is not None:
1724 if handler is not None:
1723 problems += handler(ui, fm)
1725 problems += handler(ui, fm)
1724
1726
1725 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1727 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1726 if not problems:
1728 if not problems:
1727 fm.data(problems=problems)
1729 fm.data(problems=problems)
1728 fm.condwrite(
1730 fm.condwrite(
1729 problems,
1731 problems,
1730 b'problems',
1732 b'problems',
1731 _(b"%d problems detected, please check your install!\n"),
1733 _(b"%d problems detected, please check your install!\n"),
1732 problems,
1734 problems,
1733 )
1735 )
1734 fm.end()
1736 fm.end()
1735
1737
1736 return problems
1738 return problems
1737
1739
1738
1740
1739 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1741 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1740 def debugknown(ui, repopath, *ids, **opts):
1742 def debugknown(ui, repopath, *ids, **opts):
1741 """test whether node ids are known to a repo
1743 """test whether node ids are known to a repo
1742
1744
1743 Every ID must be a full-length hex node id string. Returns a list of 0s
1745 Every ID must be a full-length hex node id string. Returns a list of 0s
1744 and 1s indicating unknown/known.
1746 and 1s indicating unknown/known.
1745 """
1747 """
1746 opts = pycompat.byteskwargs(opts)
1748 opts = pycompat.byteskwargs(opts)
1747 repo = hg.peer(ui, opts, repopath)
1749 repo = hg.peer(ui, opts, repopath)
1748 if not repo.capable(b'known'):
1750 if not repo.capable(b'known'):
1749 raise error.Abort(b"known() not supported by target repository")
1751 raise error.Abort(b"known() not supported by target repository")
1750 flags = repo.known([bin(s) for s in ids])
1752 flags = repo.known([bin(s) for s in ids])
1751 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1753 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1752
1754
1753
1755
1754 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1756 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1755 def debuglabelcomplete(ui, repo, *args):
1757 def debuglabelcomplete(ui, repo, *args):
1756 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1758 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1757 debugnamecomplete(ui, repo, *args)
1759 debugnamecomplete(ui, repo, *args)
1758
1760
1759
1761
1760 @command(
1762 @command(
1761 b'debuglocks',
1763 b'debuglocks',
1762 [
1764 [
1763 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1765 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1764 (
1766 (
1765 b'W',
1767 b'W',
1766 b'force-wlock',
1768 b'force-wlock',
1767 None,
1769 None,
1768 _(b'free the working state lock (DANGEROUS)'),
1770 _(b'free the working state lock (DANGEROUS)'),
1769 ),
1771 ),
1770 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1772 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1771 (
1773 (
1772 b'S',
1774 b'S',
1773 b'set-wlock',
1775 b'set-wlock',
1774 None,
1776 None,
1775 _(b'set the working state lock until stopped'),
1777 _(b'set the working state lock until stopped'),
1776 ),
1778 ),
1777 ],
1779 ],
1778 _(b'[OPTION]...'),
1780 _(b'[OPTION]...'),
1779 )
1781 )
1780 def debuglocks(ui, repo, **opts):
1782 def debuglocks(ui, repo, **opts):
1781 """show or modify state of locks
1783 """show or modify state of locks
1782
1784
1783 By default, this command will show which locks are held. This
1785 By default, this command will show which locks are held. This
1784 includes the user and process holding the lock, the amount of time
1786 includes the user and process holding the lock, the amount of time
1785 the lock has been held, and the machine name where the process is
1787 the lock has been held, and the machine name where the process is
1786 running if it's not local.
1788 running if it's not local.
1787
1789
1788 Locks protect the integrity of Mercurial's data, so should be
1790 Locks protect the integrity of Mercurial's data, so should be
1789 treated with care. System crashes or other interruptions may cause
1791 treated with care. System crashes or other interruptions may cause
1790 locks to not be properly released, though Mercurial will usually
1792 locks to not be properly released, though Mercurial will usually
1791 detect and remove such stale locks automatically.
1793 detect and remove such stale locks automatically.
1792
1794
1793 However, detecting stale locks may not always be possible (for
1795 However, detecting stale locks may not always be possible (for
1794 instance, on a shared filesystem). Removing locks may also be
1796 instance, on a shared filesystem). Removing locks may also be
1795 blocked by filesystem permissions.
1797 blocked by filesystem permissions.
1796
1798
1797 Setting a lock will prevent other commands from changing the data.
1799 Setting a lock will prevent other commands from changing the data.
1798 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1800 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1799 The set locks are removed when the command exits.
1801 The set locks are removed when the command exits.
1800
1802
1801 Returns 0 if no locks are held.
1803 Returns 0 if no locks are held.
1802
1804
1803 """
1805 """
1804
1806
1805 if opts.get('force_lock'):
1807 if opts.get('force_lock'):
1806 repo.svfs.unlink(b'lock')
1808 repo.svfs.unlink(b'lock')
1807 if opts.get('force_wlock'):
1809 if opts.get('force_wlock'):
1808 repo.vfs.unlink(b'wlock')
1810 repo.vfs.unlink(b'wlock')
1809 if opts.get('force_lock') or opts.get('force_wlock'):
1811 if opts.get('force_lock') or opts.get('force_wlock'):
1810 return 0
1812 return 0
1811
1813
1812 locks = []
1814 locks = []
1813 try:
1815 try:
1814 if opts.get('set_wlock'):
1816 if opts.get('set_wlock'):
1815 try:
1817 try:
1816 locks.append(repo.wlock(False))
1818 locks.append(repo.wlock(False))
1817 except error.LockHeld:
1819 except error.LockHeld:
1818 raise error.Abort(_(b'wlock is already held'))
1820 raise error.Abort(_(b'wlock is already held'))
1819 if opts.get('set_lock'):
1821 if opts.get('set_lock'):
1820 try:
1822 try:
1821 locks.append(repo.lock(False))
1823 locks.append(repo.lock(False))
1822 except error.LockHeld:
1824 except error.LockHeld:
1823 raise error.Abort(_(b'lock is already held'))
1825 raise error.Abort(_(b'lock is already held'))
1824 if len(locks):
1826 if len(locks):
1825 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1827 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1826 return 0
1828 return 0
1827 finally:
1829 finally:
1828 release(*locks)
1830 release(*locks)
1829
1831
1830 now = time.time()
1832 now = time.time()
1831 held = 0
1833 held = 0
1832
1834
1833 def report(vfs, name, method):
1835 def report(vfs, name, method):
1834 # this causes stale locks to get reaped for more accurate reporting
1836 # this causes stale locks to get reaped for more accurate reporting
1835 try:
1837 try:
1836 l = method(False)
1838 l = method(False)
1837 except error.LockHeld:
1839 except error.LockHeld:
1838 l = None
1840 l = None
1839
1841
1840 if l:
1842 if l:
1841 l.release()
1843 l.release()
1842 else:
1844 else:
1843 try:
1845 try:
1844 st = vfs.lstat(name)
1846 st = vfs.lstat(name)
1845 age = now - st[stat.ST_MTIME]
1847 age = now - st[stat.ST_MTIME]
1846 user = util.username(st.st_uid)
1848 user = util.username(st.st_uid)
1847 locker = vfs.readlock(name)
1849 locker = vfs.readlock(name)
1848 if b":" in locker:
1850 if b":" in locker:
1849 host, pid = locker.split(b':')
1851 host, pid = locker.split(b':')
1850 if host == socket.gethostname():
1852 if host == socket.gethostname():
1851 locker = b'user %s, process %s' % (user or b'None', pid)
1853 locker = b'user %s, process %s' % (user or b'None', pid)
1852 else:
1854 else:
1853 locker = b'user %s, process %s, host %s' % (
1855 locker = b'user %s, process %s, host %s' % (
1854 user or b'None',
1856 user or b'None',
1855 pid,
1857 pid,
1856 host,
1858 host,
1857 )
1859 )
1858 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1860 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1859 return 1
1861 return 1
1860 except OSError as e:
1862 except OSError as e:
1861 if e.errno != errno.ENOENT:
1863 if e.errno != errno.ENOENT:
1862 raise
1864 raise
1863
1865
1864 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1866 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1865 return 0
1867 return 0
1866
1868
1867 held += report(repo.svfs, b"lock", repo.lock)
1869 held += report(repo.svfs, b"lock", repo.lock)
1868 held += report(repo.vfs, b"wlock", repo.wlock)
1870 held += report(repo.vfs, b"wlock", repo.wlock)
1869
1871
1870 return held
1872 return held
1871
1873
1872
1874
1873 @command(
1875 @command(
1874 b'debugmanifestfulltextcache',
1876 b'debugmanifestfulltextcache',
1875 [
1877 [
1876 (b'', b'clear', False, _(b'clear the cache')),
1878 (b'', b'clear', False, _(b'clear the cache')),
1877 (
1879 (
1878 b'a',
1880 b'a',
1879 b'add',
1881 b'add',
1880 [],
1882 [],
1881 _(b'add the given manifest nodes to the cache'),
1883 _(b'add the given manifest nodes to the cache'),
1882 _(b'NODE'),
1884 _(b'NODE'),
1883 ),
1885 ),
1884 ],
1886 ],
1885 b'',
1887 b'',
1886 )
1888 )
1887 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1889 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1888 """show, clear or amend the contents of the manifest fulltext cache"""
1890 """show, clear or amend the contents of the manifest fulltext cache"""
1889
1891
1890 def getcache():
1892 def getcache():
1891 r = repo.manifestlog.getstorage(b'')
1893 r = repo.manifestlog.getstorage(b'')
1892 try:
1894 try:
1893 return r._fulltextcache
1895 return r._fulltextcache
1894 except AttributeError:
1896 except AttributeError:
1895 msg = _(
1897 msg = _(
1896 b"Current revlog implementation doesn't appear to have a "
1898 b"Current revlog implementation doesn't appear to have a "
1897 b"manifest fulltext cache\n"
1899 b"manifest fulltext cache\n"
1898 )
1900 )
1899 raise error.Abort(msg)
1901 raise error.Abort(msg)
1900
1902
1901 if opts.get('clear'):
1903 if opts.get('clear'):
1902 with repo.wlock():
1904 with repo.wlock():
1903 cache = getcache()
1905 cache = getcache()
1904 cache.clear(clear_persisted_data=True)
1906 cache.clear(clear_persisted_data=True)
1905 return
1907 return
1906
1908
1907 if add:
1909 if add:
1908 with repo.wlock():
1910 with repo.wlock():
1909 m = repo.manifestlog
1911 m = repo.manifestlog
1910 store = m.getstorage(b'')
1912 store = m.getstorage(b'')
1911 for n in add:
1913 for n in add:
1912 try:
1914 try:
1913 manifest = m[store.lookup(n)]
1915 manifest = m[store.lookup(n)]
1914 except error.LookupError as e:
1916 except error.LookupError as e:
1915 raise error.Abort(e, hint=b"Check your manifest node id")
1917 raise error.Abort(e, hint=b"Check your manifest node id")
1916 manifest.read() # stores revisision in cache too
1918 manifest.read() # stores revisision in cache too
1917 return
1919 return
1918
1920
1919 cache = getcache()
1921 cache = getcache()
1920 if not len(cache):
1922 if not len(cache):
1921 ui.write(_(b'cache empty\n'))
1923 ui.write(_(b'cache empty\n'))
1922 else:
1924 else:
1923 ui.write(
1925 ui.write(
1924 _(
1926 _(
1925 b'cache contains %d manifest entries, in order of most to '
1927 b'cache contains %d manifest entries, in order of most to '
1926 b'least recent:\n'
1928 b'least recent:\n'
1927 )
1929 )
1928 % (len(cache),)
1930 % (len(cache),)
1929 )
1931 )
1930 totalsize = 0
1932 totalsize = 0
1931 for nodeid in cache:
1933 for nodeid in cache:
1932 # Use cache.get to not update the LRU order
1934 # Use cache.get to not update the LRU order
1933 data = cache.peek(nodeid)
1935 data = cache.peek(nodeid)
1934 size = len(data)
1936 size = len(data)
1935 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1937 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1936 ui.write(
1938 ui.write(
1937 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1939 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1938 )
1940 )
1939 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1941 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1940 ui.write(
1942 ui.write(
1941 _(b'total cache data size %s, on-disk %s\n')
1943 _(b'total cache data size %s, on-disk %s\n')
1942 % (util.bytecount(totalsize), util.bytecount(ondisk))
1944 % (util.bytecount(totalsize), util.bytecount(ondisk))
1943 )
1945 )
1944
1946
1945
1947
1946 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
1948 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
1947 def debugmergestate(ui, repo, *args, **opts):
1949 def debugmergestate(ui, repo, *args, **opts):
1948 """print merge state
1950 """print merge state
1949
1951
1950 Use --verbose to print out information about whether v1 or v2 merge state
1952 Use --verbose to print out information about whether v1 or v2 merge state
1951 was chosen."""
1953 was chosen."""
1952
1954
1953 if ui.verbose:
1955 if ui.verbose:
1954 ms = mergemod.mergestate(repo)
1956 ms = mergemod.mergestate(repo)
1955
1957
1956 # sort so that reasonable information is on top
1958 # sort so that reasonable information is on top
1957 v1records = ms._readrecordsv1()
1959 v1records = ms._readrecordsv1()
1958 v2records = ms._readrecordsv2()
1960 v2records = ms._readrecordsv2()
1959
1961
1960 if not v1records and not v2records:
1962 if not v1records and not v2records:
1961 pass
1963 pass
1962 elif not v2records:
1964 elif not v2records:
1963 ui.writenoi18n(b'no version 2 merge state\n')
1965 ui.writenoi18n(b'no version 2 merge state\n')
1964 elif ms._v1v2match(v1records, v2records):
1966 elif ms._v1v2match(v1records, v2records):
1965 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
1967 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
1966 else:
1968 else:
1967 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
1969 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
1968
1970
1969 opts = pycompat.byteskwargs(opts)
1971 opts = pycompat.byteskwargs(opts)
1970 if not opts[b'template']:
1972 if not opts[b'template']:
1971 opts[b'template'] = (
1973 opts[b'template'] = (
1972 b'{if(commits, "", "no merge state found\n")}'
1974 b'{if(commits, "", "no merge state found\n")}'
1973 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
1975 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
1974 b'{files % "file: {path} (state \\"{state}\\")\n'
1976 b'{files % "file: {path} (state \\"{state}\\")\n'
1975 b'{if(local_path, "'
1977 b'{if(local_path, "'
1976 b' local path: {local_path} (hash {local_key}, flags \\"{local_flags}\\")\n'
1978 b' local path: {local_path} (hash {local_key}, flags \\"{local_flags}\\")\n'
1977 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
1979 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
1978 b' other path: {other_path} (node {other_node})\n'
1980 b' other path: {other_path} (node {other_node})\n'
1979 b'")}'
1981 b'")}'
1980 b'{if(rename_side, "'
1982 b'{if(rename_side, "'
1981 b' rename side: {rename_side}\n'
1983 b' rename side: {rename_side}\n'
1982 b' renamed path: {renamed_path}\n'
1984 b' renamed path: {renamed_path}\n'
1983 b'")}'
1985 b'")}'
1984 b'{extras % " extra: {key} = {value}\n"}'
1986 b'{extras % " extra: {key} = {value}\n"}'
1985 b'"}'
1987 b'"}'
1986 )
1988 )
1987
1989
1988 ms = mergemod.mergestate.read(repo)
1990 ms = mergemod.mergestate.read(repo)
1989
1991
1990 fm = ui.formatter(b'debugmergestate', opts)
1992 fm = ui.formatter(b'debugmergestate', opts)
1991 fm.startitem()
1993 fm.startitem()
1992
1994
1993 fm_commits = fm.nested(b'commits')
1995 fm_commits = fm.nested(b'commits')
1994 if ms.active():
1996 if ms.active():
1995 for name, node, label_index in (
1997 for name, node, label_index in (
1996 (b'local', ms.local, 0),
1998 (b'local', ms.local, 0),
1997 (b'other', ms.other, 1),
1999 (b'other', ms.other, 1),
1998 ):
2000 ):
1999 fm_commits.startitem()
2001 fm_commits.startitem()
2000 fm_commits.data(name=name)
2002 fm_commits.data(name=name)
2001 fm_commits.data(node=hex(node))
2003 fm_commits.data(node=hex(node))
2002 if ms._labels and len(ms._labels) > label_index:
2004 if ms._labels and len(ms._labels) > label_index:
2003 fm_commits.data(label=ms._labels[label_index])
2005 fm_commits.data(label=ms._labels[label_index])
2004 fm_commits.end()
2006 fm_commits.end()
2005
2007
2006 fm_files = fm.nested(b'files')
2008 fm_files = fm.nested(b'files')
2007 if ms.active():
2009 if ms.active():
2008 for f in ms:
2010 for f in ms:
2009 fm_files.startitem()
2011 fm_files.startitem()
2010 fm_files.data(path=f)
2012 fm_files.data(path=f)
2011 state = ms._state[f]
2013 state = ms._state[f]
2012 fm_files.data(state=state[0])
2014 fm_files.data(state=state[0])
2013 if state[0] in (
2015 if state[0] in (
2014 mergemod.MERGE_RECORD_UNRESOLVED,
2016 mergemod.MERGE_RECORD_UNRESOLVED,
2015 mergemod.MERGE_RECORD_RESOLVED,
2017 mergemod.MERGE_RECORD_RESOLVED,
2016 ):
2018 ):
2017 fm_files.data(local_key=state[1])
2019 fm_files.data(local_key=state[1])
2018 fm_files.data(local_path=state[2])
2020 fm_files.data(local_path=state[2])
2019 fm_files.data(ancestor_path=state[3])
2021 fm_files.data(ancestor_path=state[3])
2020 fm_files.data(ancestor_node=state[4])
2022 fm_files.data(ancestor_node=state[4])
2021 fm_files.data(other_path=state[5])
2023 fm_files.data(other_path=state[5])
2022 fm_files.data(other_node=state[6])
2024 fm_files.data(other_node=state[6])
2023 fm_files.data(local_flags=state[7])
2025 fm_files.data(local_flags=state[7])
2024 elif state[0] in (
2026 elif state[0] in (
2025 mergemod.MERGE_RECORD_UNRESOLVED_PATH,
2027 mergemod.MERGE_RECORD_UNRESOLVED_PATH,
2026 mergemod.MERGE_RECORD_RESOLVED_PATH,
2028 mergemod.MERGE_RECORD_RESOLVED_PATH,
2027 ):
2029 ):
2028 fm_files.data(renamed_path=state[1])
2030 fm_files.data(renamed_path=state[1])
2029 fm_files.data(rename_side=state[2])
2031 fm_files.data(rename_side=state[2])
2030 fm_extras = fm_files.nested(b'extras')
2032 fm_extras = fm_files.nested(b'extras')
2031 for k, v in ms.extras(f).items():
2033 for k, v in ms.extras(f).items():
2032 fm_extras.startitem()
2034 fm_extras.startitem()
2033 fm_extras.data(key=k)
2035 fm_extras.data(key=k)
2034 fm_extras.data(value=v)
2036 fm_extras.data(value=v)
2035 fm_extras.end()
2037 fm_extras.end()
2036
2038
2037 fm_files.end()
2039 fm_files.end()
2038
2040
2039 fm.end()
2041 fm.end()
2040
2042
2041
2043
2042 @command(b'debugnamecomplete', [], _(b'NAME...'))
2044 @command(b'debugnamecomplete', [], _(b'NAME...'))
2043 def debugnamecomplete(ui, repo, *args):
2045 def debugnamecomplete(ui, repo, *args):
2044 '''complete "names" - tags, open branch names, bookmark names'''
2046 '''complete "names" - tags, open branch names, bookmark names'''
2045
2047
2046 names = set()
2048 names = set()
2047 # since we previously only listed open branches, we will handle that
2049 # since we previously only listed open branches, we will handle that
2048 # specially (after this for loop)
2050 # specially (after this for loop)
2049 for name, ns in pycompat.iteritems(repo.names):
2051 for name, ns in pycompat.iteritems(repo.names):
2050 if name != b'branches':
2052 if name != b'branches':
2051 names.update(ns.listnames(repo))
2053 names.update(ns.listnames(repo))
2052 names.update(
2054 names.update(
2053 tag
2055 tag
2054 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2056 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2055 if not closed
2057 if not closed
2056 )
2058 )
2057 completions = set()
2059 completions = set()
2058 if not args:
2060 if not args:
2059 args = [b'']
2061 args = [b'']
2060 for a in args:
2062 for a in args:
2061 completions.update(n for n in names if n.startswith(a))
2063 completions.update(n for n in names if n.startswith(a))
2062 ui.write(b'\n'.join(sorted(completions)))
2064 ui.write(b'\n'.join(sorted(completions)))
2063 ui.write(b'\n')
2065 ui.write(b'\n')
2064
2066
2065
2067
2066 @command(
2068 @command(
2067 b'debugnodemap',
2069 b'debugnodemap',
2068 [
2070 [
2069 (
2071 (
2070 b'',
2072 b'',
2071 b'dump-new',
2073 b'dump-new',
2072 False,
2074 False,
2073 _(b'write a (new) persistent binary nodemap on stdin'),
2075 _(b'write a (new) persistent binary nodemap on stdin'),
2074 ),
2076 ),
2075 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
2077 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
2076 (
2078 (
2077 b'',
2079 b'',
2078 b'check',
2080 b'check',
2079 False,
2081 False,
2080 _(b'check that the data on disk data are correct.'),
2082 _(b'check that the data on disk data are correct.'),
2081 ),
2083 ),
2082 (
2084 (
2083 b'',
2085 b'',
2084 b'metadata',
2086 b'metadata',
2085 False,
2087 False,
2086 _(b'display the on disk meta data for the nodemap'),
2088 _(b'display the on disk meta data for the nodemap'),
2087 ),
2089 ),
2088 ],
2090 ],
2089 )
2091 )
2090 def debugnodemap(ui, repo, **opts):
2092 def debugnodemap(ui, repo, **opts):
2091 """write and inspect on disk nodemap
2093 """write and inspect on disk nodemap
2092 """
2094 """
2093 if opts['dump_new']:
2095 if opts['dump_new']:
2094 unfi = repo.unfiltered()
2096 unfi = repo.unfiltered()
2095 cl = unfi.changelog
2097 cl = unfi.changelog
2096 data = nodemap.persistent_data(cl.index)
2098 data = nodemap.persistent_data(cl.index)
2097 ui.write(data)
2099 ui.write(data)
2098 elif opts['dump_disk']:
2100 elif opts['dump_disk']:
2099 unfi = repo.unfiltered()
2101 unfi = repo.unfiltered()
2100 cl = unfi.changelog
2102 cl = unfi.changelog
2101 nm_data = nodemap.persisted_data(cl)
2103 nm_data = nodemap.persisted_data(cl)
2102 if nm_data is not None:
2104 if nm_data is not None:
2103 docket, data = nm_data
2105 docket, data = nm_data
2104 ui.write(data[:])
2106 ui.write(data[:])
2105 elif opts['check']:
2107 elif opts['check']:
2106 unfi = repo.unfiltered()
2108 unfi = repo.unfiltered()
2107 cl = unfi.changelog
2109 cl = unfi.changelog
2108 nm_data = nodemap.persisted_data(cl)
2110 nm_data = nodemap.persisted_data(cl)
2109 if nm_data is not None:
2111 if nm_data is not None:
2110 docket, data = nm_data
2112 docket, data = nm_data
2111 return nodemap.check_data(ui, cl.index, data)
2113 return nodemap.check_data(ui, cl.index, data)
2112 elif opts['metadata']:
2114 elif opts['metadata']:
2113 unfi = repo.unfiltered()
2115 unfi = repo.unfiltered()
2114 cl = unfi.changelog
2116 cl = unfi.changelog
2115 nm_data = nodemap.persisted_data(cl)
2117 nm_data = nodemap.persisted_data(cl)
2116 if nm_data is not None:
2118 if nm_data is not None:
2117 docket, data = nm_data
2119 docket, data = nm_data
2118 ui.write((b"uid: %s\n") % docket.uid)
2120 ui.write((b"uid: %s\n") % docket.uid)
2119 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2121 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2120 ui.write((b"data-length: %d\n") % docket.data_length)
2122 ui.write((b"data-length: %d\n") % docket.data_length)
2121 ui.write((b"data-unused: %d\n") % docket.data_unused)
2123 ui.write((b"data-unused: %d\n") % docket.data_unused)
2122
2124
2123
2125
2124 @command(
2126 @command(
2125 b'debugobsolete',
2127 b'debugobsolete',
2126 [
2128 [
2127 (b'', b'flags', 0, _(b'markers flag')),
2129 (b'', b'flags', 0, _(b'markers flag')),
2128 (
2130 (
2129 b'',
2131 b'',
2130 b'record-parents',
2132 b'record-parents',
2131 False,
2133 False,
2132 _(b'record parent information for the precursor'),
2134 _(b'record parent information for the precursor'),
2133 ),
2135 ),
2134 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2136 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2135 (
2137 (
2136 b'',
2138 b'',
2137 b'exclusive',
2139 b'exclusive',
2138 False,
2140 False,
2139 _(b'restrict display to markers only relevant to REV'),
2141 _(b'restrict display to markers only relevant to REV'),
2140 ),
2142 ),
2141 (b'', b'index', False, _(b'display index of the marker')),
2143 (b'', b'index', False, _(b'display index of the marker')),
2142 (b'', b'delete', [], _(b'delete markers specified by indices')),
2144 (b'', b'delete', [], _(b'delete markers specified by indices')),
2143 ]
2145 ]
2144 + cmdutil.commitopts2
2146 + cmdutil.commitopts2
2145 + cmdutil.formatteropts,
2147 + cmdutil.formatteropts,
2146 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2148 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2147 )
2149 )
2148 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2150 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2149 """create arbitrary obsolete marker
2151 """create arbitrary obsolete marker
2150
2152
2151 With no arguments, displays the list of obsolescence markers."""
2153 With no arguments, displays the list of obsolescence markers."""
2152
2154
2153 opts = pycompat.byteskwargs(opts)
2155 opts = pycompat.byteskwargs(opts)
2154
2156
2155 def parsenodeid(s):
2157 def parsenodeid(s):
2156 try:
2158 try:
2157 # We do not use revsingle/revrange functions here to accept
2159 # We do not use revsingle/revrange functions here to accept
2158 # arbitrary node identifiers, possibly not present in the
2160 # arbitrary node identifiers, possibly not present in the
2159 # local repository.
2161 # local repository.
2160 n = bin(s)
2162 n = bin(s)
2161 if len(n) != len(nullid):
2163 if len(n) != len(nullid):
2162 raise TypeError()
2164 raise TypeError()
2163 return n
2165 return n
2164 except TypeError:
2166 except TypeError:
2165 raise error.Abort(
2167 raise error.Abort(
2166 b'changeset references must be full hexadecimal '
2168 b'changeset references must be full hexadecimal '
2167 b'node identifiers'
2169 b'node identifiers'
2168 )
2170 )
2169
2171
2170 if opts.get(b'delete'):
2172 if opts.get(b'delete'):
2171 indices = []
2173 indices = []
2172 for v in opts.get(b'delete'):
2174 for v in opts.get(b'delete'):
2173 try:
2175 try:
2174 indices.append(int(v))
2176 indices.append(int(v))
2175 except ValueError:
2177 except ValueError:
2176 raise error.Abort(
2178 raise error.Abort(
2177 _(b'invalid index value: %r') % v,
2179 _(b'invalid index value: %r') % v,
2178 hint=_(b'use integers for indices'),
2180 hint=_(b'use integers for indices'),
2179 )
2181 )
2180
2182
2181 if repo.currenttransaction():
2183 if repo.currenttransaction():
2182 raise error.Abort(
2184 raise error.Abort(
2183 _(b'cannot delete obsmarkers in the middle of transaction.')
2185 _(b'cannot delete obsmarkers in the middle of transaction.')
2184 )
2186 )
2185
2187
2186 with repo.lock():
2188 with repo.lock():
2187 n = repair.deleteobsmarkers(repo.obsstore, indices)
2189 n = repair.deleteobsmarkers(repo.obsstore, indices)
2188 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2190 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2189
2191
2190 return
2192 return
2191
2193
2192 if precursor is not None:
2194 if precursor is not None:
2193 if opts[b'rev']:
2195 if opts[b'rev']:
2194 raise error.Abort(b'cannot select revision when creating marker')
2196 raise error.Abort(b'cannot select revision when creating marker')
2195 metadata = {}
2197 metadata = {}
2196 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2198 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2197 succs = tuple(parsenodeid(succ) for succ in successors)
2199 succs = tuple(parsenodeid(succ) for succ in successors)
2198 l = repo.lock()
2200 l = repo.lock()
2199 try:
2201 try:
2200 tr = repo.transaction(b'debugobsolete')
2202 tr = repo.transaction(b'debugobsolete')
2201 try:
2203 try:
2202 date = opts.get(b'date')
2204 date = opts.get(b'date')
2203 if date:
2205 if date:
2204 date = dateutil.parsedate(date)
2206 date = dateutil.parsedate(date)
2205 else:
2207 else:
2206 date = None
2208 date = None
2207 prec = parsenodeid(precursor)
2209 prec = parsenodeid(precursor)
2208 parents = None
2210 parents = None
2209 if opts[b'record_parents']:
2211 if opts[b'record_parents']:
2210 if prec not in repo.unfiltered():
2212 if prec not in repo.unfiltered():
2211 raise error.Abort(
2213 raise error.Abort(
2212 b'cannot used --record-parents on '
2214 b'cannot used --record-parents on '
2213 b'unknown changesets'
2215 b'unknown changesets'
2214 )
2216 )
2215 parents = repo.unfiltered()[prec].parents()
2217 parents = repo.unfiltered()[prec].parents()
2216 parents = tuple(p.node() for p in parents)
2218 parents = tuple(p.node() for p in parents)
2217 repo.obsstore.create(
2219 repo.obsstore.create(
2218 tr,
2220 tr,
2219 prec,
2221 prec,
2220 succs,
2222 succs,
2221 opts[b'flags'],
2223 opts[b'flags'],
2222 parents=parents,
2224 parents=parents,
2223 date=date,
2225 date=date,
2224 metadata=metadata,
2226 metadata=metadata,
2225 ui=ui,
2227 ui=ui,
2226 )
2228 )
2227 tr.close()
2229 tr.close()
2228 except ValueError as exc:
2230 except ValueError as exc:
2229 raise error.Abort(
2231 raise error.Abort(
2230 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2232 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2231 )
2233 )
2232 finally:
2234 finally:
2233 tr.release()
2235 tr.release()
2234 finally:
2236 finally:
2235 l.release()
2237 l.release()
2236 else:
2238 else:
2237 if opts[b'rev']:
2239 if opts[b'rev']:
2238 revs = scmutil.revrange(repo, opts[b'rev'])
2240 revs = scmutil.revrange(repo, opts[b'rev'])
2239 nodes = [repo[r].node() for r in revs]
2241 nodes = [repo[r].node() for r in revs]
2240 markers = list(
2242 markers = list(
2241 obsutil.getmarkers(
2243 obsutil.getmarkers(
2242 repo, nodes=nodes, exclusive=opts[b'exclusive']
2244 repo, nodes=nodes, exclusive=opts[b'exclusive']
2243 )
2245 )
2244 )
2246 )
2245 markers.sort(key=lambda x: x._data)
2247 markers.sort(key=lambda x: x._data)
2246 else:
2248 else:
2247 markers = obsutil.getmarkers(repo)
2249 markers = obsutil.getmarkers(repo)
2248
2250
2249 markerstoiter = markers
2251 markerstoiter = markers
2250 isrelevant = lambda m: True
2252 isrelevant = lambda m: True
2251 if opts.get(b'rev') and opts.get(b'index'):
2253 if opts.get(b'rev') and opts.get(b'index'):
2252 markerstoiter = obsutil.getmarkers(repo)
2254 markerstoiter = obsutil.getmarkers(repo)
2253 markerset = set(markers)
2255 markerset = set(markers)
2254 isrelevant = lambda m: m in markerset
2256 isrelevant = lambda m: m in markerset
2255
2257
2256 fm = ui.formatter(b'debugobsolete', opts)
2258 fm = ui.formatter(b'debugobsolete', opts)
2257 for i, m in enumerate(markerstoiter):
2259 for i, m in enumerate(markerstoiter):
2258 if not isrelevant(m):
2260 if not isrelevant(m):
2259 # marker can be irrelevant when we're iterating over a set
2261 # marker can be irrelevant when we're iterating over a set
2260 # of markers (markerstoiter) which is bigger than the set
2262 # of markers (markerstoiter) which is bigger than the set
2261 # of markers we want to display (markers)
2263 # of markers we want to display (markers)
2262 # this can happen if both --index and --rev options are
2264 # this can happen if both --index and --rev options are
2263 # provided and thus we need to iterate over all of the markers
2265 # provided and thus we need to iterate over all of the markers
2264 # to get the correct indices, but only display the ones that
2266 # to get the correct indices, but only display the ones that
2265 # are relevant to --rev value
2267 # are relevant to --rev value
2266 continue
2268 continue
2267 fm.startitem()
2269 fm.startitem()
2268 ind = i if opts.get(b'index') else None
2270 ind = i if opts.get(b'index') else None
2269 cmdutil.showmarker(fm, m, index=ind)
2271 cmdutil.showmarker(fm, m, index=ind)
2270 fm.end()
2272 fm.end()
2271
2273
2272
2274
2273 @command(
2275 @command(
2274 b'debugp1copies',
2276 b'debugp1copies',
2275 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2277 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2276 _(b'[-r REV]'),
2278 _(b'[-r REV]'),
2277 )
2279 )
2278 def debugp1copies(ui, repo, **opts):
2280 def debugp1copies(ui, repo, **opts):
2279 """dump copy information compared to p1"""
2281 """dump copy information compared to p1"""
2280
2282
2281 opts = pycompat.byteskwargs(opts)
2283 opts = pycompat.byteskwargs(opts)
2282 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2284 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2283 for dst, src in ctx.p1copies().items():
2285 for dst, src in ctx.p1copies().items():
2284 ui.write(b'%s -> %s\n' % (src, dst))
2286 ui.write(b'%s -> %s\n' % (src, dst))
2285
2287
2286
2288
2287 @command(
2289 @command(
2288 b'debugp2copies',
2290 b'debugp2copies',
2289 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2291 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2290 _(b'[-r REV]'),
2292 _(b'[-r REV]'),
2291 )
2293 )
2292 def debugp1copies(ui, repo, **opts):
2294 def debugp1copies(ui, repo, **opts):
2293 """dump copy information compared to p2"""
2295 """dump copy information compared to p2"""
2294
2296
2295 opts = pycompat.byteskwargs(opts)
2297 opts = pycompat.byteskwargs(opts)
2296 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2298 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2297 for dst, src in ctx.p2copies().items():
2299 for dst, src in ctx.p2copies().items():
2298 ui.write(b'%s -> %s\n' % (src, dst))
2300 ui.write(b'%s -> %s\n' % (src, dst))
2299
2301
2300
2302
2301 @command(
2303 @command(
2302 b'debugpathcomplete',
2304 b'debugpathcomplete',
2303 [
2305 [
2304 (b'f', b'full', None, _(b'complete an entire path')),
2306 (b'f', b'full', None, _(b'complete an entire path')),
2305 (b'n', b'normal', None, _(b'show only normal files')),
2307 (b'n', b'normal', None, _(b'show only normal files')),
2306 (b'a', b'added', None, _(b'show only added files')),
2308 (b'a', b'added', None, _(b'show only added files')),
2307 (b'r', b'removed', None, _(b'show only removed files')),
2309 (b'r', b'removed', None, _(b'show only removed files')),
2308 ],
2310 ],
2309 _(b'FILESPEC...'),
2311 _(b'FILESPEC...'),
2310 )
2312 )
2311 def debugpathcomplete(ui, repo, *specs, **opts):
2313 def debugpathcomplete(ui, repo, *specs, **opts):
2312 '''complete part or all of a tracked path
2314 '''complete part or all of a tracked path
2313
2315
2314 This command supports shells that offer path name completion. It
2316 This command supports shells that offer path name completion. It
2315 currently completes only files already known to the dirstate.
2317 currently completes only files already known to the dirstate.
2316
2318
2317 Completion extends only to the next path segment unless
2319 Completion extends only to the next path segment unless
2318 --full is specified, in which case entire paths are used.'''
2320 --full is specified, in which case entire paths are used.'''
2319
2321
2320 def complete(path, acceptable):
2322 def complete(path, acceptable):
2321 dirstate = repo.dirstate
2323 dirstate = repo.dirstate
2322 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2324 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2323 rootdir = repo.root + pycompat.ossep
2325 rootdir = repo.root + pycompat.ossep
2324 if spec != repo.root and not spec.startswith(rootdir):
2326 if spec != repo.root and not spec.startswith(rootdir):
2325 return [], []
2327 return [], []
2326 if os.path.isdir(spec):
2328 if os.path.isdir(spec):
2327 spec += b'/'
2329 spec += b'/'
2328 spec = spec[len(rootdir) :]
2330 spec = spec[len(rootdir) :]
2329 fixpaths = pycompat.ossep != b'/'
2331 fixpaths = pycompat.ossep != b'/'
2330 if fixpaths:
2332 if fixpaths:
2331 spec = spec.replace(pycompat.ossep, b'/')
2333 spec = spec.replace(pycompat.ossep, b'/')
2332 speclen = len(spec)
2334 speclen = len(spec)
2333 fullpaths = opts['full']
2335 fullpaths = opts['full']
2334 files, dirs = set(), set()
2336 files, dirs = set(), set()
2335 adddir, addfile = dirs.add, files.add
2337 adddir, addfile = dirs.add, files.add
2336 for f, st in pycompat.iteritems(dirstate):
2338 for f, st in pycompat.iteritems(dirstate):
2337 if f.startswith(spec) and st[0] in acceptable:
2339 if f.startswith(spec) and st[0] in acceptable:
2338 if fixpaths:
2340 if fixpaths:
2339 f = f.replace(b'/', pycompat.ossep)
2341 f = f.replace(b'/', pycompat.ossep)
2340 if fullpaths:
2342 if fullpaths:
2341 addfile(f)
2343 addfile(f)
2342 continue
2344 continue
2343 s = f.find(pycompat.ossep, speclen)
2345 s = f.find(pycompat.ossep, speclen)
2344 if s >= 0:
2346 if s >= 0:
2345 adddir(f[:s])
2347 adddir(f[:s])
2346 else:
2348 else:
2347 addfile(f)
2349 addfile(f)
2348 return files, dirs
2350 return files, dirs
2349
2351
2350 acceptable = b''
2352 acceptable = b''
2351 if opts['normal']:
2353 if opts['normal']:
2352 acceptable += b'nm'
2354 acceptable += b'nm'
2353 if opts['added']:
2355 if opts['added']:
2354 acceptable += b'a'
2356 acceptable += b'a'
2355 if opts['removed']:
2357 if opts['removed']:
2356 acceptable += b'r'
2358 acceptable += b'r'
2357 cwd = repo.getcwd()
2359 cwd = repo.getcwd()
2358 if not specs:
2360 if not specs:
2359 specs = [b'.']
2361 specs = [b'.']
2360
2362
2361 files, dirs = set(), set()
2363 files, dirs = set(), set()
2362 for spec in specs:
2364 for spec in specs:
2363 f, d = complete(spec, acceptable or b'nmar')
2365 f, d = complete(spec, acceptable or b'nmar')
2364 files.update(f)
2366 files.update(f)
2365 dirs.update(d)
2367 dirs.update(d)
2366 files.update(dirs)
2368 files.update(dirs)
2367 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2369 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2368 ui.write(b'\n')
2370 ui.write(b'\n')
2369
2371
2370
2372
2371 @command(
2373 @command(
2372 b'debugpathcopies',
2374 b'debugpathcopies',
2373 cmdutil.walkopts,
2375 cmdutil.walkopts,
2374 b'hg debugpathcopies REV1 REV2 [FILE]',
2376 b'hg debugpathcopies REV1 REV2 [FILE]',
2375 inferrepo=True,
2377 inferrepo=True,
2376 )
2378 )
2377 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2379 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2378 """show copies between two revisions"""
2380 """show copies between two revisions"""
2379 ctx1 = scmutil.revsingle(repo, rev1)
2381 ctx1 = scmutil.revsingle(repo, rev1)
2380 ctx2 = scmutil.revsingle(repo, rev2)
2382 ctx2 = scmutil.revsingle(repo, rev2)
2381 m = scmutil.match(ctx1, pats, opts)
2383 m = scmutil.match(ctx1, pats, opts)
2382 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2384 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2383 ui.write(b'%s -> %s\n' % (src, dst))
2385 ui.write(b'%s -> %s\n' % (src, dst))
2384
2386
2385
2387
2386 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2388 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2387 def debugpeer(ui, path):
2389 def debugpeer(ui, path):
2388 """establish a connection to a peer repository"""
2390 """establish a connection to a peer repository"""
2389 # Always enable peer request logging. Requires --debug to display
2391 # Always enable peer request logging. Requires --debug to display
2390 # though.
2392 # though.
2391 overrides = {
2393 overrides = {
2392 (b'devel', b'debug.peer-request'): True,
2394 (b'devel', b'debug.peer-request'): True,
2393 }
2395 }
2394
2396
2395 with ui.configoverride(overrides):
2397 with ui.configoverride(overrides):
2396 peer = hg.peer(ui, {}, path)
2398 peer = hg.peer(ui, {}, path)
2397
2399
2398 local = peer.local() is not None
2400 local = peer.local() is not None
2399 canpush = peer.canpush()
2401 canpush = peer.canpush()
2400
2402
2401 ui.write(_(b'url: %s\n') % peer.url())
2403 ui.write(_(b'url: %s\n') % peer.url())
2402 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2404 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2403 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2405 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2404
2406
2405
2407
2406 @command(
2408 @command(
2407 b'debugpickmergetool',
2409 b'debugpickmergetool',
2408 [
2410 [
2409 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2411 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2410 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2412 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2411 ]
2413 ]
2412 + cmdutil.walkopts
2414 + cmdutil.walkopts
2413 + cmdutil.mergetoolopts,
2415 + cmdutil.mergetoolopts,
2414 _(b'[PATTERN]...'),
2416 _(b'[PATTERN]...'),
2415 inferrepo=True,
2417 inferrepo=True,
2416 )
2418 )
2417 def debugpickmergetool(ui, repo, *pats, **opts):
2419 def debugpickmergetool(ui, repo, *pats, **opts):
2418 """examine which merge tool is chosen for specified file
2420 """examine which merge tool is chosen for specified file
2419
2421
2420 As described in :hg:`help merge-tools`, Mercurial examines
2422 As described in :hg:`help merge-tools`, Mercurial examines
2421 configurations below in this order to decide which merge tool is
2423 configurations below in this order to decide which merge tool is
2422 chosen for specified file.
2424 chosen for specified file.
2423
2425
2424 1. ``--tool`` option
2426 1. ``--tool`` option
2425 2. ``HGMERGE`` environment variable
2427 2. ``HGMERGE`` environment variable
2426 3. configurations in ``merge-patterns`` section
2428 3. configurations in ``merge-patterns`` section
2427 4. configuration of ``ui.merge``
2429 4. configuration of ``ui.merge``
2428 5. configurations in ``merge-tools`` section
2430 5. configurations in ``merge-tools`` section
2429 6. ``hgmerge`` tool (for historical reason only)
2431 6. ``hgmerge`` tool (for historical reason only)
2430 7. default tool for fallback (``:merge`` or ``:prompt``)
2432 7. default tool for fallback (``:merge`` or ``:prompt``)
2431
2433
2432 This command writes out examination result in the style below::
2434 This command writes out examination result in the style below::
2433
2435
2434 FILE = MERGETOOL
2436 FILE = MERGETOOL
2435
2437
2436 By default, all files known in the first parent context of the
2438 By default, all files known in the first parent context of the
2437 working directory are examined. Use file patterns and/or -I/-X
2439 working directory are examined. Use file patterns and/or -I/-X
2438 options to limit target files. -r/--rev is also useful to examine
2440 options to limit target files. -r/--rev is also useful to examine
2439 files in another context without actual updating to it.
2441 files in another context without actual updating to it.
2440
2442
2441 With --debug, this command shows warning messages while matching
2443 With --debug, this command shows warning messages while matching
2442 against ``merge-patterns`` and so on, too. It is recommended to
2444 against ``merge-patterns`` and so on, too. It is recommended to
2443 use this option with explicit file patterns and/or -I/-X options,
2445 use this option with explicit file patterns and/or -I/-X options,
2444 because this option increases amount of output per file according
2446 because this option increases amount of output per file according
2445 to configurations in hgrc.
2447 to configurations in hgrc.
2446
2448
2447 With -v/--verbose, this command shows configurations below at
2449 With -v/--verbose, this command shows configurations below at
2448 first (only if specified).
2450 first (only if specified).
2449
2451
2450 - ``--tool`` option
2452 - ``--tool`` option
2451 - ``HGMERGE`` environment variable
2453 - ``HGMERGE`` environment variable
2452 - configuration of ``ui.merge``
2454 - configuration of ``ui.merge``
2453
2455
2454 If merge tool is chosen before matching against
2456 If merge tool is chosen before matching against
2455 ``merge-patterns``, this command can't show any helpful
2457 ``merge-patterns``, this command can't show any helpful
2456 information, even with --debug. In such case, information above is
2458 information, even with --debug. In such case, information above is
2457 useful to know why a merge tool is chosen.
2459 useful to know why a merge tool is chosen.
2458 """
2460 """
2459 opts = pycompat.byteskwargs(opts)
2461 opts = pycompat.byteskwargs(opts)
2460 overrides = {}
2462 overrides = {}
2461 if opts[b'tool']:
2463 if opts[b'tool']:
2462 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2464 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2463 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2465 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2464
2466
2465 with ui.configoverride(overrides, b'debugmergepatterns'):
2467 with ui.configoverride(overrides, b'debugmergepatterns'):
2466 hgmerge = encoding.environ.get(b"HGMERGE")
2468 hgmerge = encoding.environ.get(b"HGMERGE")
2467 if hgmerge is not None:
2469 if hgmerge is not None:
2468 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2470 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2469 uimerge = ui.config(b"ui", b"merge")
2471 uimerge = ui.config(b"ui", b"merge")
2470 if uimerge:
2472 if uimerge:
2471 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2473 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2472
2474
2473 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2475 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2474 m = scmutil.match(ctx, pats, opts)
2476 m = scmutil.match(ctx, pats, opts)
2475 changedelete = opts[b'changedelete']
2477 changedelete = opts[b'changedelete']
2476 for path in ctx.walk(m):
2478 for path in ctx.walk(m):
2477 fctx = ctx[path]
2479 fctx = ctx[path]
2478 try:
2480 try:
2479 if not ui.debugflag:
2481 if not ui.debugflag:
2480 ui.pushbuffer(error=True)
2482 ui.pushbuffer(error=True)
2481 tool, toolpath = filemerge._picktool(
2483 tool, toolpath = filemerge._picktool(
2482 repo,
2484 repo,
2483 ui,
2485 ui,
2484 path,
2486 path,
2485 fctx.isbinary(),
2487 fctx.isbinary(),
2486 b'l' in fctx.flags(),
2488 b'l' in fctx.flags(),
2487 changedelete,
2489 changedelete,
2488 )
2490 )
2489 finally:
2491 finally:
2490 if not ui.debugflag:
2492 if not ui.debugflag:
2491 ui.popbuffer()
2493 ui.popbuffer()
2492 ui.write(b'%s = %s\n' % (path, tool))
2494 ui.write(b'%s = %s\n' % (path, tool))
2493
2495
2494
2496
2495 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2497 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2496 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2498 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2497 '''access the pushkey key/value protocol
2499 '''access the pushkey key/value protocol
2498
2500
2499 With two args, list the keys in the given namespace.
2501 With two args, list the keys in the given namespace.
2500
2502
2501 With five args, set a key to new if it currently is set to old.
2503 With five args, set a key to new if it currently is set to old.
2502 Reports success or failure.
2504 Reports success or failure.
2503 '''
2505 '''
2504
2506
2505 target = hg.peer(ui, {}, repopath)
2507 target = hg.peer(ui, {}, repopath)
2506 if keyinfo:
2508 if keyinfo:
2507 key, old, new = keyinfo
2509 key, old, new = keyinfo
2508 with target.commandexecutor() as e:
2510 with target.commandexecutor() as e:
2509 r = e.callcommand(
2511 r = e.callcommand(
2510 b'pushkey',
2512 b'pushkey',
2511 {
2513 {
2512 b'namespace': namespace,
2514 b'namespace': namespace,
2513 b'key': key,
2515 b'key': key,
2514 b'old': old,
2516 b'old': old,
2515 b'new': new,
2517 b'new': new,
2516 },
2518 },
2517 ).result()
2519 ).result()
2518
2520
2519 ui.status(pycompat.bytestr(r) + b'\n')
2521 ui.status(pycompat.bytestr(r) + b'\n')
2520 return not r
2522 return not r
2521 else:
2523 else:
2522 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2524 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2523 ui.write(
2525 ui.write(
2524 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2526 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2525 )
2527 )
2526
2528
2527
2529
2528 @command(b'debugpvec', [], _(b'A B'))
2530 @command(b'debugpvec', [], _(b'A B'))
2529 def debugpvec(ui, repo, a, b=None):
2531 def debugpvec(ui, repo, a, b=None):
2530 ca = scmutil.revsingle(repo, a)
2532 ca = scmutil.revsingle(repo, a)
2531 cb = scmutil.revsingle(repo, b)
2533 cb = scmutil.revsingle(repo, b)
2532 pa = pvec.ctxpvec(ca)
2534 pa = pvec.ctxpvec(ca)
2533 pb = pvec.ctxpvec(cb)
2535 pb = pvec.ctxpvec(cb)
2534 if pa == pb:
2536 if pa == pb:
2535 rel = b"="
2537 rel = b"="
2536 elif pa > pb:
2538 elif pa > pb:
2537 rel = b">"
2539 rel = b">"
2538 elif pa < pb:
2540 elif pa < pb:
2539 rel = b"<"
2541 rel = b"<"
2540 elif pa | pb:
2542 elif pa | pb:
2541 rel = b"|"
2543 rel = b"|"
2542 ui.write(_(b"a: %s\n") % pa)
2544 ui.write(_(b"a: %s\n") % pa)
2543 ui.write(_(b"b: %s\n") % pb)
2545 ui.write(_(b"b: %s\n") % pb)
2544 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2546 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2545 ui.write(
2547 ui.write(
2546 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2548 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2547 % (
2549 % (
2548 abs(pa._depth - pb._depth),
2550 abs(pa._depth - pb._depth),
2549 pvec._hamming(pa._vec, pb._vec),
2551 pvec._hamming(pa._vec, pb._vec),
2550 pa.distance(pb),
2552 pa.distance(pb),
2551 rel,
2553 rel,
2552 )
2554 )
2553 )
2555 )
2554
2556
2555
2557
2556 @command(
2558 @command(
2557 b'debugrebuilddirstate|debugrebuildstate',
2559 b'debugrebuilddirstate|debugrebuildstate',
2558 [
2560 [
2559 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2561 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2560 (
2562 (
2561 b'',
2563 b'',
2562 b'minimal',
2564 b'minimal',
2563 None,
2565 None,
2564 _(
2566 _(
2565 b'only rebuild files that are inconsistent with '
2567 b'only rebuild files that are inconsistent with '
2566 b'the working copy parent'
2568 b'the working copy parent'
2567 ),
2569 ),
2568 ),
2570 ),
2569 ],
2571 ],
2570 _(b'[-r REV]'),
2572 _(b'[-r REV]'),
2571 )
2573 )
2572 def debugrebuilddirstate(ui, repo, rev, **opts):
2574 def debugrebuilddirstate(ui, repo, rev, **opts):
2573 """rebuild the dirstate as it would look like for the given revision
2575 """rebuild the dirstate as it would look like for the given revision
2574
2576
2575 If no revision is specified the first current parent will be used.
2577 If no revision is specified the first current parent will be used.
2576
2578
2577 The dirstate will be set to the files of the given revision.
2579 The dirstate will be set to the files of the given revision.
2578 The actual working directory content or existing dirstate
2580 The actual working directory content or existing dirstate
2579 information such as adds or removes is not considered.
2581 information such as adds or removes is not considered.
2580
2582
2581 ``minimal`` will only rebuild the dirstate status for files that claim to be
2583 ``minimal`` will only rebuild the dirstate status for files that claim to be
2582 tracked but are not in the parent manifest, or that exist in the parent
2584 tracked but are not in the parent manifest, or that exist in the parent
2583 manifest but are not in the dirstate. It will not change adds, removes, or
2585 manifest but are not in the dirstate. It will not change adds, removes, or
2584 modified files that are in the working copy parent.
2586 modified files that are in the working copy parent.
2585
2587
2586 One use of this command is to make the next :hg:`status` invocation
2588 One use of this command is to make the next :hg:`status` invocation
2587 check the actual file content.
2589 check the actual file content.
2588 """
2590 """
2589 ctx = scmutil.revsingle(repo, rev)
2591 ctx = scmutil.revsingle(repo, rev)
2590 with repo.wlock():
2592 with repo.wlock():
2591 dirstate = repo.dirstate
2593 dirstate = repo.dirstate
2592 changedfiles = None
2594 changedfiles = None
2593 # See command doc for what minimal does.
2595 # See command doc for what minimal does.
2594 if opts.get('minimal'):
2596 if opts.get('minimal'):
2595 manifestfiles = set(ctx.manifest().keys())
2597 manifestfiles = set(ctx.manifest().keys())
2596 dirstatefiles = set(dirstate)
2598 dirstatefiles = set(dirstate)
2597 manifestonly = manifestfiles - dirstatefiles
2599 manifestonly = manifestfiles - dirstatefiles
2598 dsonly = dirstatefiles - manifestfiles
2600 dsonly = dirstatefiles - manifestfiles
2599 dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
2601 dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
2600 changedfiles = manifestonly | dsnotadded
2602 changedfiles = manifestonly | dsnotadded
2601
2603
2602 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2604 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2603
2605
2604
2606
2605 @command(b'debugrebuildfncache', [], b'')
2607 @command(b'debugrebuildfncache', [], b'')
2606 def debugrebuildfncache(ui, repo):
2608 def debugrebuildfncache(ui, repo):
2607 """rebuild the fncache file"""
2609 """rebuild the fncache file"""
2608 repair.rebuildfncache(ui, repo)
2610 repair.rebuildfncache(ui, repo)
2609
2611
2610
2612
2611 @command(
2613 @command(
2612 b'debugrename',
2614 b'debugrename',
2613 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2615 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2614 _(b'[-r REV] [FILE]...'),
2616 _(b'[-r REV] [FILE]...'),
2615 )
2617 )
2616 def debugrename(ui, repo, *pats, **opts):
2618 def debugrename(ui, repo, *pats, **opts):
2617 """dump rename information"""
2619 """dump rename information"""
2618
2620
2619 opts = pycompat.byteskwargs(opts)
2621 opts = pycompat.byteskwargs(opts)
2620 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2622 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2621 m = scmutil.match(ctx, pats, opts)
2623 m = scmutil.match(ctx, pats, opts)
2622 for abs in ctx.walk(m):
2624 for abs in ctx.walk(m):
2623 fctx = ctx[abs]
2625 fctx = ctx[abs]
2624 o = fctx.filelog().renamed(fctx.filenode())
2626 o = fctx.filelog().renamed(fctx.filenode())
2625 rel = repo.pathto(abs)
2627 rel = repo.pathto(abs)
2626 if o:
2628 if o:
2627 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2629 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2628 else:
2630 else:
2629 ui.write(_(b"%s not renamed\n") % rel)
2631 ui.write(_(b"%s not renamed\n") % rel)
2630
2632
2631
2633
2632 @command(
2634 @command(
2633 b'debugrevlog',
2635 b'debugrevlog',
2634 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2636 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2635 _(b'-c|-m|FILE'),
2637 _(b'-c|-m|FILE'),
2636 optionalrepo=True,
2638 optionalrepo=True,
2637 )
2639 )
2638 def debugrevlog(ui, repo, file_=None, **opts):
2640 def debugrevlog(ui, repo, file_=None, **opts):
2639 """show data and statistics about a revlog"""
2641 """show data and statistics about a revlog"""
2640 opts = pycompat.byteskwargs(opts)
2642 opts = pycompat.byteskwargs(opts)
2641 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2643 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2642
2644
2643 if opts.get(b"dump"):
2645 if opts.get(b"dump"):
2644 numrevs = len(r)
2646 numrevs = len(r)
2645 ui.write(
2647 ui.write(
2646 (
2648 (
2647 b"# rev p1rev p2rev start end deltastart base p1 p2"
2649 b"# rev p1rev p2rev start end deltastart base p1 p2"
2648 b" rawsize totalsize compression heads chainlen\n"
2650 b" rawsize totalsize compression heads chainlen\n"
2649 )
2651 )
2650 )
2652 )
2651 ts = 0
2653 ts = 0
2652 heads = set()
2654 heads = set()
2653
2655
2654 for rev in pycompat.xrange(numrevs):
2656 for rev in pycompat.xrange(numrevs):
2655 dbase = r.deltaparent(rev)
2657 dbase = r.deltaparent(rev)
2656 if dbase == -1:
2658 if dbase == -1:
2657 dbase = rev
2659 dbase = rev
2658 cbase = r.chainbase(rev)
2660 cbase = r.chainbase(rev)
2659 clen = r.chainlen(rev)
2661 clen = r.chainlen(rev)
2660 p1, p2 = r.parentrevs(rev)
2662 p1, p2 = r.parentrevs(rev)
2661 rs = r.rawsize(rev)
2663 rs = r.rawsize(rev)
2662 ts = ts + rs
2664 ts = ts + rs
2663 heads -= set(r.parentrevs(rev))
2665 heads -= set(r.parentrevs(rev))
2664 heads.add(rev)
2666 heads.add(rev)
2665 try:
2667 try:
2666 compression = ts / r.end(rev)
2668 compression = ts / r.end(rev)
2667 except ZeroDivisionError:
2669 except ZeroDivisionError:
2668 compression = 0
2670 compression = 0
2669 ui.write(
2671 ui.write(
2670 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2672 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2671 b"%11d %5d %8d\n"
2673 b"%11d %5d %8d\n"
2672 % (
2674 % (
2673 rev,
2675 rev,
2674 p1,
2676 p1,
2675 p2,
2677 p2,
2676 r.start(rev),
2678 r.start(rev),
2677 r.end(rev),
2679 r.end(rev),
2678 r.start(dbase),
2680 r.start(dbase),
2679 r.start(cbase),
2681 r.start(cbase),
2680 r.start(p1),
2682 r.start(p1),
2681 r.start(p2),
2683 r.start(p2),
2682 rs,
2684 rs,
2683 ts,
2685 ts,
2684 compression,
2686 compression,
2685 len(heads),
2687 len(heads),
2686 clen,
2688 clen,
2687 )
2689 )
2688 )
2690 )
2689 return 0
2691 return 0
2690
2692
2691 v = r.version
2693 v = r.version
2692 format = v & 0xFFFF
2694 format = v & 0xFFFF
2693 flags = []
2695 flags = []
2694 gdelta = False
2696 gdelta = False
2695 if v & revlog.FLAG_INLINE_DATA:
2697 if v & revlog.FLAG_INLINE_DATA:
2696 flags.append(b'inline')
2698 flags.append(b'inline')
2697 if v & revlog.FLAG_GENERALDELTA:
2699 if v & revlog.FLAG_GENERALDELTA:
2698 gdelta = True
2700 gdelta = True
2699 flags.append(b'generaldelta')
2701 flags.append(b'generaldelta')
2700 if not flags:
2702 if not flags:
2701 flags = [b'(none)']
2703 flags = [b'(none)']
2702
2704
2703 ### tracks merge vs single parent
2705 ### tracks merge vs single parent
2704 nummerges = 0
2706 nummerges = 0
2705
2707
2706 ### tracks ways the "delta" are build
2708 ### tracks ways the "delta" are build
2707 # nodelta
2709 # nodelta
2708 numempty = 0
2710 numempty = 0
2709 numemptytext = 0
2711 numemptytext = 0
2710 numemptydelta = 0
2712 numemptydelta = 0
2711 # full file content
2713 # full file content
2712 numfull = 0
2714 numfull = 0
2713 # intermediate snapshot against a prior snapshot
2715 # intermediate snapshot against a prior snapshot
2714 numsemi = 0
2716 numsemi = 0
2715 # snapshot count per depth
2717 # snapshot count per depth
2716 numsnapdepth = collections.defaultdict(lambda: 0)
2718 numsnapdepth = collections.defaultdict(lambda: 0)
2717 # delta against previous revision
2719 # delta against previous revision
2718 numprev = 0
2720 numprev = 0
2719 # delta against first or second parent (not prev)
2721 # delta against first or second parent (not prev)
2720 nump1 = 0
2722 nump1 = 0
2721 nump2 = 0
2723 nump2 = 0
2722 # delta against neither prev nor parents
2724 # delta against neither prev nor parents
2723 numother = 0
2725 numother = 0
2724 # delta against prev that are also first or second parent
2726 # delta against prev that are also first or second parent
2725 # (details of `numprev`)
2727 # (details of `numprev`)
2726 nump1prev = 0
2728 nump1prev = 0
2727 nump2prev = 0
2729 nump2prev = 0
2728
2730
2729 # data about delta chain of each revs
2731 # data about delta chain of each revs
2730 chainlengths = []
2732 chainlengths = []
2731 chainbases = []
2733 chainbases = []
2732 chainspans = []
2734 chainspans = []
2733
2735
2734 # data about each revision
2736 # data about each revision
2735 datasize = [None, 0, 0]
2737 datasize = [None, 0, 0]
2736 fullsize = [None, 0, 0]
2738 fullsize = [None, 0, 0]
2737 semisize = [None, 0, 0]
2739 semisize = [None, 0, 0]
2738 # snapshot count per depth
2740 # snapshot count per depth
2739 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2741 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2740 deltasize = [None, 0, 0]
2742 deltasize = [None, 0, 0]
2741 chunktypecounts = {}
2743 chunktypecounts = {}
2742 chunktypesizes = {}
2744 chunktypesizes = {}
2743
2745
2744 def addsize(size, l):
2746 def addsize(size, l):
2745 if l[0] is None or size < l[0]:
2747 if l[0] is None or size < l[0]:
2746 l[0] = size
2748 l[0] = size
2747 if size > l[1]:
2749 if size > l[1]:
2748 l[1] = size
2750 l[1] = size
2749 l[2] += size
2751 l[2] += size
2750
2752
2751 numrevs = len(r)
2753 numrevs = len(r)
2752 for rev in pycompat.xrange(numrevs):
2754 for rev in pycompat.xrange(numrevs):
2753 p1, p2 = r.parentrevs(rev)
2755 p1, p2 = r.parentrevs(rev)
2754 delta = r.deltaparent(rev)
2756 delta = r.deltaparent(rev)
2755 if format > 0:
2757 if format > 0:
2756 addsize(r.rawsize(rev), datasize)
2758 addsize(r.rawsize(rev), datasize)
2757 if p2 != nullrev:
2759 if p2 != nullrev:
2758 nummerges += 1
2760 nummerges += 1
2759 size = r.length(rev)
2761 size = r.length(rev)
2760 if delta == nullrev:
2762 if delta == nullrev:
2761 chainlengths.append(0)
2763 chainlengths.append(0)
2762 chainbases.append(r.start(rev))
2764 chainbases.append(r.start(rev))
2763 chainspans.append(size)
2765 chainspans.append(size)
2764 if size == 0:
2766 if size == 0:
2765 numempty += 1
2767 numempty += 1
2766 numemptytext += 1
2768 numemptytext += 1
2767 else:
2769 else:
2768 numfull += 1
2770 numfull += 1
2769 numsnapdepth[0] += 1
2771 numsnapdepth[0] += 1
2770 addsize(size, fullsize)
2772 addsize(size, fullsize)
2771 addsize(size, snapsizedepth[0])
2773 addsize(size, snapsizedepth[0])
2772 else:
2774 else:
2773 chainlengths.append(chainlengths[delta] + 1)
2775 chainlengths.append(chainlengths[delta] + 1)
2774 baseaddr = chainbases[delta]
2776 baseaddr = chainbases[delta]
2775 revaddr = r.start(rev)
2777 revaddr = r.start(rev)
2776 chainbases.append(baseaddr)
2778 chainbases.append(baseaddr)
2777 chainspans.append((revaddr - baseaddr) + size)
2779 chainspans.append((revaddr - baseaddr) + size)
2778 if size == 0:
2780 if size == 0:
2779 numempty += 1
2781 numempty += 1
2780 numemptydelta += 1
2782 numemptydelta += 1
2781 elif r.issnapshot(rev):
2783 elif r.issnapshot(rev):
2782 addsize(size, semisize)
2784 addsize(size, semisize)
2783 numsemi += 1
2785 numsemi += 1
2784 depth = r.snapshotdepth(rev)
2786 depth = r.snapshotdepth(rev)
2785 numsnapdepth[depth] += 1
2787 numsnapdepth[depth] += 1
2786 addsize(size, snapsizedepth[depth])
2788 addsize(size, snapsizedepth[depth])
2787 else:
2789 else:
2788 addsize(size, deltasize)
2790 addsize(size, deltasize)
2789 if delta == rev - 1:
2791 if delta == rev - 1:
2790 numprev += 1
2792 numprev += 1
2791 if delta == p1:
2793 if delta == p1:
2792 nump1prev += 1
2794 nump1prev += 1
2793 elif delta == p2:
2795 elif delta == p2:
2794 nump2prev += 1
2796 nump2prev += 1
2795 elif delta == p1:
2797 elif delta == p1:
2796 nump1 += 1
2798 nump1 += 1
2797 elif delta == p2:
2799 elif delta == p2:
2798 nump2 += 1
2800 nump2 += 1
2799 elif delta != nullrev:
2801 elif delta != nullrev:
2800 numother += 1
2802 numother += 1
2801
2803
2802 # Obtain data on the raw chunks in the revlog.
2804 # Obtain data on the raw chunks in the revlog.
2803 if util.safehasattr(r, b'_getsegmentforrevs'):
2805 if util.safehasattr(r, b'_getsegmentforrevs'):
2804 segment = r._getsegmentforrevs(rev, rev)[1]
2806 segment = r._getsegmentforrevs(rev, rev)[1]
2805 else:
2807 else:
2806 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2808 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2807 if segment:
2809 if segment:
2808 chunktype = bytes(segment[0:1])
2810 chunktype = bytes(segment[0:1])
2809 else:
2811 else:
2810 chunktype = b'empty'
2812 chunktype = b'empty'
2811
2813
2812 if chunktype not in chunktypecounts:
2814 if chunktype not in chunktypecounts:
2813 chunktypecounts[chunktype] = 0
2815 chunktypecounts[chunktype] = 0
2814 chunktypesizes[chunktype] = 0
2816 chunktypesizes[chunktype] = 0
2815
2817
2816 chunktypecounts[chunktype] += 1
2818 chunktypecounts[chunktype] += 1
2817 chunktypesizes[chunktype] += size
2819 chunktypesizes[chunktype] += size
2818
2820
2819 # Adjust size min value for empty cases
2821 # Adjust size min value for empty cases
2820 for size in (datasize, fullsize, semisize, deltasize):
2822 for size in (datasize, fullsize, semisize, deltasize):
2821 if size[0] is None:
2823 if size[0] is None:
2822 size[0] = 0
2824 size[0] = 0
2823
2825
2824 numdeltas = numrevs - numfull - numempty - numsemi
2826 numdeltas = numrevs - numfull - numempty - numsemi
2825 numoprev = numprev - nump1prev - nump2prev
2827 numoprev = numprev - nump1prev - nump2prev
2826 totalrawsize = datasize[2]
2828 totalrawsize = datasize[2]
2827 datasize[2] /= numrevs
2829 datasize[2] /= numrevs
2828 fulltotal = fullsize[2]
2830 fulltotal = fullsize[2]
2829 if numfull == 0:
2831 if numfull == 0:
2830 fullsize[2] = 0
2832 fullsize[2] = 0
2831 else:
2833 else:
2832 fullsize[2] /= numfull
2834 fullsize[2] /= numfull
2833 semitotal = semisize[2]
2835 semitotal = semisize[2]
2834 snaptotal = {}
2836 snaptotal = {}
2835 if numsemi > 0:
2837 if numsemi > 0:
2836 semisize[2] /= numsemi
2838 semisize[2] /= numsemi
2837 for depth in snapsizedepth:
2839 for depth in snapsizedepth:
2838 snaptotal[depth] = snapsizedepth[depth][2]
2840 snaptotal[depth] = snapsizedepth[depth][2]
2839 snapsizedepth[depth][2] /= numsnapdepth[depth]
2841 snapsizedepth[depth][2] /= numsnapdepth[depth]
2840
2842
2841 deltatotal = deltasize[2]
2843 deltatotal = deltasize[2]
2842 if numdeltas > 0:
2844 if numdeltas > 0:
2843 deltasize[2] /= numdeltas
2845 deltasize[2] /= numdeltas
2844 totalsize = fulltotal + semitotal + deltatotal
2846 totalsize = fulltotal + semitotal + deltatotal
2845 avgchainlen = sum(chainlengths) / numrevs
2847 avgchainlen = sum(chainlengths) / numrevs
2846 maxchainlen = max(chainlengths)
2848 maxchainlen = max(chainlengths)
2847 maxchainspan = max(chainspans)
2849 maxchainspan = max(chainspans)
2848 compratio = 1
2850 compratio = 1
2849 if totalsize:
2851 if totalsize:
2850 compratio = totalrawsize / totalsize
2852 compratio = totalrawsize / totalsize
2851
2853
2852 basedfmtstr = b'%%%dd\n'
2854 basedfmtstr = b'%%%dd\n'
2853 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2855 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2854
2856
2855 def dfmtstr(max):
2857 def dfmtstr(max):
2856 return basedfmtstr % len(str(max))
2858 return basedfmtstr % len(str(max))
2857
2859
2858 def pcfmtstr(max, padding=0):
2860 def pcfmtstr(max, padding=0):
2859 return basepcfmtstr % (len(str(max)), b' ' * padding)
2861 return basepcfmtstr % (len(str(max)), b' ' * padding)
2860
2862
2861 def pcfmt(value, total):
2863 def pcfmt(value, total):
2862 if total:
2864 if total:
2863 return (value, 100 * float(value) / total)
2865 return (value, 100 * float(value) / total)
2864 else:
2866 else:
2865 return value, 100.0
2867 return value, 100.0
2866
2868
2867 ui.writenoi18n(b'format : %d\n' % format)
2869 ui.writenoi18n(b'format : %d\n' % format)
2868 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2870 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2869
2871
2870 ui.write(b'\n')
2872 ui.write(b'\n')
2871 fmt = pcfmtstr(totalsize)
2873 fmt = pcfmtstr(totalsize)
2872 fmt2 = dfmtstr(totalsize)
2874 fmt2 = dfmtstr(totalsize)
2873 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2875 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2874 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2876 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2875 ui.writenoi18n(
2877 ui.writenoi18n(
2876 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2878 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2877 )
2879 )
2878 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2880 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2879 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2881 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2880 ui.writenoi18n(
2882 ui.writenoi18n(
2881 b' text : '
2883 b' text : '
2882 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2884 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2883 )
2885 )
2884 ui.writenoi18n(
2886 ui.writenoi18n(
2885 b' delta : '
2887 b' delta : '
2886 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2888 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2887 )
2889 )
2888 ui.writenoi18n(
2890 ui.writenoi18n(
2889 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2891 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2890 )
2892 )
2891 for depth in sorted(numsnapdepth):
2893 for depth in sorted(numsnapdepth):
2892 ui.write(
2894 ui.write(
2893 (b' lvl-%-3d : ' % depth)
2895 (b' lvl-%-3d : ' % depth)
2894 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2896 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2895 )
2897 )
2896 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2898 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2897 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2899 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2898 ui.writenoi18n(
2900 ui.writenoi18n(
2899 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2901 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2900 )
2902 )
2901 for depth in sorted(numsnapdepth):
2903 for depth in sorted(numsnapdepth):
2902 ui.write(
2904 ui.write(
2903 (b' lvl-%-3d : ' % depth)
2905 (b' lvl-%-3d : ' % depth)
2904 + fmt % pcfmt(snaptotal[depth], totalsize)
2906 + fmt % pcfmt(snaptotal[depth], totalsize)
2905 )
2907 )
2906 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2908 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2907
2909
2908 def fmtchunktype(chunktype):
2910 def fmtchunktype(chunktype):
2909 if chunktype == b'empty':
2911 if chunktype == b'empty':
2910 return b' %s : ' % chunktype
2912 return b' %s : ' % chunktype
2911 elif chunktype in pycompat.bytestr(string.ascii_letters):
2913 elif chunktype in pycompat.bytestr(string.ascii_letters):
2912 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2914 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2913 else:
2915 else:
2914 return b' 0x%s : ' % hex(chunktype)
2916 return b' 0x%s : ' % hex(chunktype)
2915
2917
2916 ui.write(b'\n')
2918 ui.write(b'\n')
2917 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2919 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2918 for chunktype in sorted(chunktypecounts):
2920 for chunktype in sorted(chunktypecounts):
2919 ui.write(fmtchunktype(chunktype))
2921 ui.write(fmtchunktype(chunktype))
2920 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2922 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2921 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2923 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2922 for chunktype in sorted(chunktypecounts):
2924 for chunktype in sorted(chunktypecounts):
2923 ui.write(fmtchunktype(chunktype))
2925 ui.write(fmtchunktype(chunktype))
2924 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2926 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2925
2927
2926 ui.write(b'\n')
2928 ui.write(b'\n')
2927 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2929 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2928 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2930 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2929 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2931 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2930 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2932 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2931 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2933 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2932
2934
2933 if format > 0:
2935 if format > 0:
2934 ui.write(b'\n')
2936 ui.write(b'\n')
2935 ui.writenoi18n(
2937 ui.writenoi18n(
2936 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2938 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2937 % tuple(datasize)
2939 % tuple(datasize)
2938 )
2940 )
2939 ui.writenoi18n(
2941 ui.writenoi18n(
2940 b'full revision size (min/max/avg) : %d / %d / %d\n'
2942 b'full revision size (min/max/avg) : %d / %d / %d\n'
2941 % tuple(fullsize)
2943 % tuple(fullsize)
2942 )
2944 )
2943 ui.writenoi18n(
2945 ui.writenoi18n(
2944 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2946 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2945 % tuple(semisize)
2947 % tuple(semisize)
2946 )
2948 )
2947 for depth in sorted(snapsizedepth):
2949 for depth in sorted(snapsizedepth):
2948 if depth == 0:
2950 if depth == 0:
2949 continue
2951 continue
2950 ui.writenoi18n(
2952 ui.writenoi18n(
2951 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2953 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2952 % ((depth,) + tuple(snapsizedepth[depth]))
2954 % ((depth,) + tuple(snapsizedepth[depth]))
2953 )
2955 )
2954 ui.writenoi18n(
2956 ui.writenoi18n(
2955 b'delta size (min/max/avg) : %d / %d / %d\n'
2957 b'delta size (min/max/avg) : %d / %d / %d\n'
2956 % tuple(deltasize)
2958 % tuple(deltasize)
2957 )
2959 )
2958
2960
2959 if numdeltas > 0:
2961 if numdeltas > 0:
2960 ui.write(b'\n')
2962 ui.write(b'\n')
2961 fmt = pcfmtstr(numdeltas)
2963 fmt = pcfmtstr(numdeltas)
2962 fmt2 = pcfmtstr(numdeltas, 4)
2964 fmt2 = pcfmtstr(numdeltas, 4)
2963 ui.writenoi18n(
2965 ui.writenoi18n(
2964 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2966 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2965 )
2967 )
2966 if numprev > 0:
2968 if numprev > 0:
2967 ui.writenoi18n(
2969 ui.writenoi18n(
2968 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2970 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2969 )
2971 )
2970 ui.writenoi18n(
2972 ui.writenoi18n(
2971 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2973 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2972 )
2974 )
2973 ui.writenoi18n(
2975 ui.writenoi18n(
2974 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2976 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2975 )
2977 )
2976 if gdelta:
2978 if gdelta:
2977 ui.writenoi18n(
2979 ui.writenoi18n(
2978 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
2980 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
2979 )
2981 )
2980 ui.writenoi18n(
2982 ui.writenoi18n(
2981 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
2983 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
2982 )
2984 )
2983 ui.writenoi18n(
2985 ui.writenoi18n(
2984 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
2986 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
2985 )
2987 )
2986
2988
2987
2989
2988 @command(
2990 @command(
2989 b'debugrevlogindex',
2991 b'debugrevlogindex',
2990 cmdutil.debugrevlogopts
2992 cmdutil.debugrevlogopts
2991 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
2993 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
2992 _(b'[-f FORMAT] -c|-m|FILE'),
2994 _(b'[-f FORMAT] -c|-m|FILE'),
2993 optionalrepo=True,
2995 optionalrepo=True,
2994 )
2996 )
2995 def debugrevlogindex(ui, repo, file_=None, **opts):
2997 def debugrevlogindex(ui, repo, file_=None, **opts):
2996 """dump the contents of a revlog index"""
2998 """dump the contents of a revlog index"""
2997 opts = pycompat.byteskwargs(opts)
2999 opts = pycompat.byteskwargs(opts)
2998 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
3000 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
2999 format = opts.get(b'format', 0)
3001 format = opts.get(b'format', 0)
3000 if format not in (0, 1):
3002 if format not in (0, 1):
3001 raise error.Abort(_(b"unknown format %d") % format)
3003 raise error.Abort(_(b"unknown format %d") % format)
3002
3004
3003 if ui.debugflag:
3005 if ui.debugflag:
3004 shortfn = hex
3006 shortfn = hex
3005 else:
3007 else:
3006 shortfn = short
3008 shortfn = short
3007
3009
3008 # There might not be anything in r, so have a sane default
3010 # There might not be anything in r, so have a sane default
3009 idlen = 12
3011 idlen = 12
3010 for i in r:
3012 for i in r:
3011 idlen = len(shortfn(r.node(i)))
3013 idlen = len(shortfn(r.node(i)))
3012 break
3014 break
3013
3015
3014 if format == 0:
3016 if format == 0:
3015 if ui.verbose:
3017 if ui.verbose:
3016 ui.writenoi18n(
3018 ui.writenoi18n(
3017 b" rev offset length linkrev %s %s p2\n"
3019 b" rev offset length linkrev %s %s p2\n"
3018 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3020 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3019 )
3021 )
3020 else:
3022 else:
3021 ui.writenoi18n(
3023 ui.writenoi18n(
3022 b" rev linkrev %s %s p2\n"
3024 b" rev linkrev %s %s p2\n"
3023 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3025 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3024 )
3026 )
3025 elif format == 1:
3027 elif format == 1:
3026 if ui.verbose:
3028 if ui.verbose:
3027 ui.writenoi18n(
3029 ui.writenoi18n(
3028 (
3030 (
3029 b" rev flag offset length size link p1"
3031 b" rev flag offset length size link p1"
3030 b" p2 %s\n"
3032 b" p2 %s\n"
3031 )
3033 )
3032 % b"nodeid".rjust(idlen)
3034 % b"nodeid".rjust(idlen)
3033 )
3035 )
3034 else:
3036 else:
3035 ui.writenoi18n(
3037 ui.writenoi18n(
3036 b" rev flag size link p1 p2 %s\n"
3038 b" rev flag size link p1 p2 %s\n"
3037 % b"nodeid".rjust(idlen)
3039 % b"nodeid".rjust(idlen)
3038 )
3040 )
3039
3041
3040 for i in r:
3042 for i in r:
3041 node = r.node(i)
3043 node = r.node(i)
3042 if format == 0:
3044 if format == 0:
3043 try:
3045 try:
3044 pp = r.parents(node)
3046 pp = r.parents(node)
3045 except Exception:
3047 except Exception:
3046 pp = [nullid, nullid]
3048 pp = [nullid, nullid]
3047 if ui.verbose:
3049 if ui.verbose:
3048 ui.write(
3050 ui.write(
3049 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3051 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3050 % (
3052 % (
3051 i,
3053 i,
3052 r.start(i),
3054 r.start(i),
3053 r.length(i),
3055 r.length(i),
3054 r.linkrev(i),
3056 r.linkrev(i),
3055 shortfn(node),
3057 shortfn(node),
3056 shortfn(pp[0]),
3058 shortfn(pp[0]),
3057 shortfn(pp[1]),
3059 shortfn(pp[1]),
3058 )
3060 )
3059 )
3061 )
3060 else:
3062 else:
3061 ui.write(
3063 ui.write(
3062 b"% 6d % 7d %s %s %s\n"
3064 b"% 6d % 7d %s %s %s\n"
3063 % (
3065 % (
3064 i,
3066 i,
3065 r.linkrev(i),
3067 r.linkrev(i),
3066 shortfn(node),
3068 shortfn(node),
3067 shortfn(pp[0]),
3069 shortfn(pp[0]),
3068 shortfn(pp[1]),
3070 shortfn(pp[1]),
3069 )
3071 )
3070 )
3072 )
3071 elif format == 1:
3073 elif format == 1:
3072 pr = r.parentrevs(i)
3074 pr = r.parentrevs(i)
3073 if ui.verbose:
3075 if ui.verbose:
3074 ui.write(
3076 ui.write(
3075 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3077 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3076 % (
3078 % (
3077 i,
3079 i,
3078 r.flags(i),
3080 r.flags(i),
3079 r.start(i),
3081 r.start(i),
3080 r.length(i),
3082 r.length(i),
3081 r.rawsize(i),
3083 r.rawsize(i),
3082 r.linkrev(i),
3084 r.linkrev(i),
3083 pr[0],
3085 pr[0],
3084 pr[1],
3086 pr[1],
3085 shortfn(node),
3087 shortfn(node),
3086 )
3088 )
3087 )
3089 )
3088 else:
3090 else:
3089 ui.write(
3091 ui.write(
3090 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3092 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3091 % (
3093 % (
3092 i,
3094 i,
3093 r.flags(i),
3095 r.flags(i),
3094 r.rawsize(i),
3096 r.rawsize(i),
3095 r.linkrev(i),
3097 r.linkrev(i),
3096 pr[0],
3098 pr[0],
3097 pr[1],
3099 pr[1],
3098 shortfn(node),
3100 shortfn(node),
3099 )
3101 )
3100 )
3102 )
3101
3103
3102
3104
3103 @command(
3105 @command(
3104 b'debugrevspec',
3106 b'debugrevspec',
3105 [
3107 [
3106 (
3108 (
3107 b'',
3109 b'',
3108 b'optimize',
3110 b'optimize',
3109 None,
3111 None,
3110 _(b'print parsed tree after optimizing (DEPRECATED)'),
3112 _(b'print parsed tree after optimizing (DEPRECATED)'),
3111 ),
3113 ),
3112 (
3114 (
3113 b'',
3115 b'',
3114 b'show-revs',
3116 b'show-revs',
3115 True,
3117 True,
3116 _(b'print list of result revisions (default)'),
3118 _(b'print list of result revisions (default)'),
3117 ),
3119 ),
3118 (
3120 (
3119 b's',
3121 b's',
3120 b'show-set',
3122 b'show-set',
3121 None,
3123 None,
3122 _(b'print internal representation of result set'),
3124 _(b'print internal representation of result set'),
3123 ),
3125 ),
3124 (
3126 (
3125 b'p',
3127 b'p',
3126 b'show-stage',
3128 b'show-stage',
3127 [],
3129 [],
3128 _(b'print parsed tree at the given stage'),
3130 _(b'print parsed tree at the given stage'),
3129 _(b'NAME'),
3131 _(b'NAME'),
3130 ),
3132 ),
3131 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3133 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3132 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3134 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3133 ],
3135 ],
3134 b'REVSPEC',
3136 b'REVSPEC',
3135 )
3137 )
3136 def debugrevspec(ui, repo, expr, **opts):
3138 def debugrevspec(ui, repo, expr, **opts):
3137 """parse and apply a revision specification
3139 """parse and apply a revision specification
3138
3140
3139 Use -p/--show-stage option to print the parsed tree at the given stages.
3141 Use -p/--show-stage option to print the parsed tree at the given stages.
3140 Use -p all to print tree at every stage.
3142 Use -p all to print tree at every stage.
3141
3143
3142 Use --no-show-revs option with -s or -p to print only the set
3144 Use --no-show-revs option with -s or -p to print only the set
3143 representation or the parsed tree respectively.
3145 representation or the parsed tree respectively.
3144
3146
3145 Use --verify-optimized to compare the optimized result with the unoptimized
3147 Use --verify-optimized to compare the optimized result with the unoptimized
3146 one. Returns 1 if the optimized result differs.
3148 one. Returns 1 if the optimized result differs.
3147 """
3149 """
3148 opts = pycompat.byteskwargs(opts)
3150 opts = pycompat.byteskwargs(opts)
3149 aliases = ui.configitems(b'revsetalias')
3151 aliases = ui.configitems(b'revsetalias')
3150 stages = [
3152 stages = [
3151 (b'parsed', lambda tree: tree),
3153 (b'parsed', lambda tree: tree),
3152 (
3154 (
3153 b'expanded',
3155 b'expanded',
3154 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3156 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3155 ),
3157 ),
3156 (b'concatenated', revsetlang.foldconcat),
3158 (b'concatenated', revsetlang.foldconcat),
3157 (b'analyzed', revsetlang.analyze),
3159 (b'analyzed', revsetlang.analyze),
3158 (b'optimized', revsetlang.optimize),
3160 (b'optimized', revsetlang.optimize),
3159 ]
3161 ]
3160 if opts[b'no_optimized']:
3162 if opts[b'no_optimized']:
3161 stages = stages[:-1]
3163 stages = stages[:-1]
3162 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3164 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3163 raise error.Abort(
3165 raise error.Abort(
3164 _(b'cannot use --verify-optimized with --no-optimized')
3166 _(b'cannot use --verify-optimized with --no-optimized')
3165 )
3167 )
3166 stagenames = set(n for n, f in stages)
3168 stagenames = set(n for n, f in stages)
3167
3169
3168 showalways = set()
3170 showalways = set()
3169 showchanged = set()
3171 showchanged = set()
3170 if ui.verbose and not opts[b'show_stage']:
3172 if ui.verbose and not opts[b'show_stage']:
3171 # show parsed tree by --verbose (deprecated)
3173 # show parsed tree by --verbose (deprecated)
3172 showalways.add(b'parsed')
3174 showalways.add(b'parsed')
3173 showchanged.update([b'expanded', b'concatenated'])
3175 showchanged.update([b'expanded', b'concatenated'])
3174 if opts[b'optimize']:
3176 if opts[b'optimize']:
3175 showalways.add(b'optimized')
3177 showalways.add(b'optimized')
3176 if opts[b'show_stage'] and opts[b'optimize']:
3178 if opts[b'show_stage'] and opts[b'optimize']:
3177 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3179 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3178 if opts[b'show_stage'] == [b'all']:
3180 if opts[b'show_stage'] == [b'all']:
3179 showalways.update(stagenames)
3181 showalways.update(stagenames)
3180 else:
3182 else:
3181 for n in opts[b'show_stage']:
3183 for n in opts[b'show_stage']:
3182 if n not in stagenames:
3184 if n not in stagenames:
3183 raise error.Abort(_(b'invalid stage name: %s') % n)
3185 raise error.Abort(_(b'invalid stage name: %s') % n)
3184 showalways.update(opts[b'show_stage'])
3186 showalways.update(opts[b'show_stage'])
3185
3187
3186 treebystage = {}
3188 treebystage = {}
3187 printedtree = None
3189 printedtree = None
3188 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3190 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3189 for n, f in stages:
3191 for n, f in stages:
3190 treebystage[n] = tree = f(tree)
3192 treebystage[n] = tree = f(tree)
3191 if n in showalways or (n in showchanged and tree != printedtree):
3193 if n in showalways or (n in showchanged and tree != printedtree):
3192 if opts[b'show_stage'] or n != b'parsed':
3194 if opts[b'show_stage'] or n != b'parsed':
3193 ui.write(b"* %s:\n" % n)
3195 ui.write(b"* %s:\n" % n)
3194 ui.write(revsetlang.prettyformat(tree), b"\n")
3196 ui.write(revsetlang.prettyformat(tree), b"\n")
3195 printedtree = tree
3197 printedtree = tree
3196
3198
3197 if opts[b'verify_optimized']:
3199 if opts[b'verify_optimized']:
3198 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3200 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3199 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3201 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3200 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3202 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3201 ui.writenoi18n(
3203 ui.writenoi18n(
3202 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3204 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3203 )
3205 )
3204 ui.writenoi18n(
3206 ui.writenoi18n(
3205 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3207 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3206 )
3208 )
3207 arevs = list(arevs)
3209 arevs = list(arevs)
3208 brevs = list(brevs)
3210 brevs = list(brevs)
3209 if arevs == brevs:
3211 if arevs == brevs:
3210 return 0
3212 return 0
3211 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3213 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3212 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3214 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3213 sm = difflib.SequenceMatcher(None, arevs, brevs)
3215 sm = difflib.SequenceMatcher(None, arevs, brevs)
3214 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3216 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3215 if tag in ('delete', 'replace'):
3217 if tag in ('delete', 'replace'):
3216 for c in arevs[alo:ahi]:
3218 for c in arevs[alo:ahi]:
3217 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3219 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3218 if tag in ('insert', 'replace'):
3220 if tag in ('insert', 'replace'):
3219 for c in brevs[blo:bhi]:
3221 for c in brevs[blo:bhi]:
3220 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3222 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3221 if tag == 'equal':
3223 if tag == 'equal':
3222 for c in arevs[alo:ahi]:
3224 for c in arevs[alo:ahi]:
3223 ui.write(b' %d\n' % c)
3225 ui.write(b' %d\n' % c)
3224 return 1
3226 return 1
3225
3227
3226 func = revset.makematcher(tree)
3228 func = revset.makematcher(tree)
3227 revs = func(repo)
3229 revs = func(repo)
3228 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3230 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3229 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3231 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3230 if not opts[b'show_revs']:
3232 if not opts[b'show_revs']:
3231 return
3233 return
3232 for c in revs:
3234 for c in revs:
3233 ui.write(b"%d\n" % c)
3235 ui.write(b"%d\n" % c)
3234
3236
3235
3237
3236 @command(
3238 @command(
3237 b'debugserve',
3239 b'debugserve',
3238 [
3240 [
3239 (
3241 (
3240 b'',
3242 b'',
3241 b'sshstdio',
3243 b'sshstdio',
3242 False,
3244 False,
3243 _(b'run an SSH server bound to process handles'),
3245 _(b'run an SSH server bound to process handles'),
3244 ),
3246 ),
3245 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3247 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3246 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3248 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3247 ],
3249 ],
3248 b'',
3250 b'',
3249 )
3251 )
3250 def debugserve(ui, repo, **opts):
3252 def debugserve(ui, repo, **opts):
3251 """run a server with advanced settings
3253 """run a server with advanced settings
3252
3254
3253 This command is similar to :hg:`serve`. It exists partially as a
3255 This command is similar to :hg:`serve`. It exists partially as a
3254 workaround to the fact that ``hg serve --stdio`` must have specific
3256 workaround to the fact that ``hg serve --stdio`` must have specific
3255 arguments for security reasons.
3257 arguments for security reasons.
3256 """
3258 """
3257 opts = pycompat.byteskwargs(opts)
3259 opts = pycompat.byteskwargs(opts)
3258
3260
3259 if not opts[b'sshstdio']:
3261 if not opts[b'sshstdio']:
3260 raise error.Abort(_(b'only --sshstdio is currently supported'))
3262 raise error.Abort(_(b'only --sshstdio is currently supported'))
3261
3263
3262 logfh = None
3264 logfh = None
3263
3265
3264 if opts[b'logiofd'] and opts[b'logiofile']:
3266 if opts[b'logiofd'] and opts[b'logiofile']:
3265 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3267 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3266
3268
3267 if opts[b'logiofd']:
3269 if opts[b'logiofd']:
3268 # Ideally we would be line buffered. But line buffering in binary
3270 # Ideally we would be line buffered. But line buffering in binary
3269 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3271 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3270 # buffering could have performance impacts. But since this isn't
3272 # buffering could have performance impacts. But since this isn't
3271 # performance critical code, it should be fine.
3273 # performance critical code, it should be fine.
3272 try:
3274 try:
3273 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3275 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3274 except OSError as e:
3276 except OSError as e:
3275 if e.errno != errno.ESPIPE:
3277 if e.errno != errno.ESPIPE:
3276 raise
3278 raise
3277 # can't seek a pipe, so `ab` mode fails on py3
3279 # can't seek a pipe, so `ab` mode fails on py3
3278 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3280 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3279 elif opts[b'logiofile']:
3281 elif opts[b'logiofile']:
3280 logfh = open(opts[b'logiofile'], b'ab', 0)
3282 logfh = open(opts[b'logiofile'], b'ab', 0)
3281
3283
3282 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3284 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3283 s.serve_forever()
3285 s.serve_forever()
3284
3286
3285
3287
3286 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3288 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3287 def debugsetparents(ui, repo, rev1, rev2=None):
3289 def debugsetparents(ui, repo, rev1, rev2=None):
3288 """manually set the parents of the current working directory
3290 """manually set the parents of the current working directory
3289
3291
3290 This is useful for writing repository conversion tools, but should
3292 This is useful for writing repository conversion tools, but should
3291 be used with care. For example, neither the working directory nor the
3293 be used with care. For example, neither the working directory nor the
3292 dirstate is updated, so file status may be incorrect after running this
3294 dirstate is updated, so file status may be incorrect after running this
3293 command.
3295 command.
3294
3296
3295 Returns 0 on success.
3297 Returns 0 on success.
3296 """
3298 """
3297
3299
3298 node1 = scmutil.revsingle(repo, rev1).node()
3300 node1 = scmutil.revsingle(repo, rev1).node()
3299 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3301 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3300
3302
3301 with repo.wlock():
3303 with repo.wlock():
3302 repo.setparents(node1, node2)
3304 repo.setparents(node1, node2)
3303
3305
3304
3306
3305 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3307 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3306 def debugsidedata(ui, repo, file_, rev=None, **opts):
3308 def debugsidedata(ui, repo, file_, rev=None, **opts):
3307 """dump the side data for a cl/manifest/file revision
3309 """dump the side data for a cl/manifest/file revision
3308
3310
3309 Use --verbose to dump the sidedata content."""
3311 Use --verbose to dump the sidedata content."""
3310 opts = pycompat.byteskwargs(opts)
3312 opts = pycompat.byteskwargs(opts)
3311 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3313 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3312 if rev is not None:
3314 if rev is not None:
3313 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3315 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3314 file_, rev = None, file_
3316 file_, rev = None, file_
3315 elif rev is None:
3317 elif rev is None:
3316 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3318 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3317 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3319 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3318 r = getattr(r, '_revlog', r)
3320 r = getattr(r, '_revlog', r)
3319 try:
3321 try:
3320 sidedata = r.sidedata(r.lookup(rev))
3322 sidedata = r.sidedata(r.lookup(rev))
3321 except KeyError:
3323 except KeyError:
3322 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3324 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3323 if sidedata:
3325 if sidedata:
3324 sidedata = list(sidedata.items())
3326 sidedata = list(sidedata.items())
3325 sidedata.sort()
3327 sidedata.sort()
3326 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3328 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3327 for key, value in sidedata:
3329 for key, value in sidedata:
3328 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3330 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3329 if ui.verbose:
3331 if ui.verbose:
3330 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3332 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3331
3333
3332
3334
3333 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3335 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3334 def debugssl(ui, repo, source=None, **opts):
3336 def debugssl(ui, repo, source=None, **opts):
3335 '''test a secure connection to a server
3337 '''test a secure connection to a server
3336
3338
3337 This builds the certificate chain for the server on Windows, installing the
3339 This builds the certificate chain for the server on Windows, installing the
3338 missing intermediates and trusted root via Windows Update if necessary. It
3340 missing intermediates and trusted root via Windows Update if necessary. It
3339 does nothing on other platforms.
3341 does nothing on other platforms.
3340
3342
3341 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3343 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3342 that server is used. See :hg:`help urls` for more information.
3344 that server is used. See :hg:`help urls` for more information.
3343
3345
3344 If the update succeeds, retry the original operation. Otherwise, the cause
3346 If the update succeeds, retry the original operation. Otherwise, the cause
3345 of the SSL error is likely another issue.
3347 of the SSL error is likely another issue.
3346 '''
3348 '''
3347 if not pycompat.iswindows:
3349 if not pycompat.iswindows:
3348 raise error.Abort(
3350 raise error.Abort(
3349 _(b'certificate chain building is only possible on Windows')
3351 _(b'certificate chain building is only possible on Windows')
3350 )
3352 )
3351
3353
3352 if not source:
3354 if not source:
3353 if not repo:
3355 if not repo:
3354 raise error.Abort(
3356 raise error.Abort(
3355 _(
3357 _(
3356 b"there is no Mercurial repository here, and no "
3358 b"there is no Mercurial repository here, and no "
3357 b"server specified"
3359 b"server specified"
3358 )
3360 )
3359 )
3361 )
3360 source = b"default"
3362 source = b"default"
3361
3363
3362 source, branches = hg.parseurl(ui.expandpath(source))
3364 source, branches = hg.parseurl(ui.expandpath(source))
3363 url = util.url(source)
3365 url = util.url(source)
3364
3366
3365 defaultport = {b'https': 443, b'ssh': 22}
3367 defaultport = {b'https': 443, b'ssh': 22}
3366 if url.scheme in defaultport:
3368 if url.scheme in defaultport:
3367 try:
3369 try:
3368 addr = (url.host, int(url.port or defaultport[url.scheme]))
3370 addr = (url.host, int(url.port or defaultport[url.scheme]))
3369 except ValueError:
3371 except ValueError:
3370 raise error.Abort(_(b"malformed port number in URL"))
3372 raise error.Abort(_(b"malformed port number in URL"))
3371 else:
3373 else:
3372 raise error.Abort(_(b"only https and ssh connections are supported"))
3374 raise error.Abort(_(b"only https and ssh connections are supported"))
3373
3375
3374 from . import win32
3376 from . import win32
3375
3377
3376 s = ssl.wrap_socket(
3378 s = ssl.wrap_socket(
3377 socket.socket(),
3379 socket.socket(),
3378 ssl_version=ssl.PROTOCOL_TLS,
3380 ssl_version=ssl.PROTOCOL_TLS,
3379 cert_reqs=ssl.CERT_NONE,
3381 cert_reqs=ssl.CERT_NONE,
3380 ca_certs=None,
3382 ca_certs=None,
3381 )
3383 )
3382
3384
3383 try:
3385 try:
3384 s.connect(addr)
3386 s.connect(addr)
3385 cert = s.getpeercert(True)
3387 cert = s.getpeercert(True)
3386
3388
3387 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3389 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3388
3390
3389 complete = win32.checkcertificatechain(cert, build=False)
3391 complete = win32.checkcertificatechain(cert, build=False)
3390
3392
3391 if not complete:
3393 if not complete:
3392 ui.status(_(b'certificate chain is incomplete, updating... '))
3394 ui.status(_(b'certificate chain is incomplete, updating... '))
3393
3395
3394 if not win32.checkcertificatechain(cert):
3396 if not win32.checkcertificatechain(cert):
3395 ui.status(_(b'failed.\n'))
3397 ui.status(_(b'failed.\n'))
3396 else:
3398 else:
3397 ui.status(_(b'done.\n'))
3399 ui.status(_(b'done.\n'))
3398 else:
3400 else:
3399 ui.status(_(b'full certificate chain is available\n'))
3401 ui.status(_(b'full certificate chain is available\n'))
3400 finally:
3402 finally:
3401 s.close()
3403 s.close()
3402
3404
3403
3405
3404 @command(
3406 @command(
3407 b"debugbackupbundle",
3408 [
3409 (
3410 b"",
3411 b"recover",
3412 b"",
3413 b"brings the specified changeset back into the repository",
3414 )
3415 ]
3416 + cmdutil.logopts,
3417 _(b"hg debugbackupbundle [--recover HASH]"),
3418 )
3419 def debugbackupbundle(ui, repo, *pats, **opts):
3420 """lists the changesets available in backup bundles
3421
3422 Without any arguments, this command prints a list of the changesets in each
3423 backup bundle.
3424
3425 --recover takes a changeset hash and unbundles the first bundle that
3426 contains that hash, which puts that changeset back in your repository.
3427
3428 --verbose will print the entire commit message and the bundle path for that
3429 backup.
3430 """
3431 backups = filter(
3432 os.path.isfile, glob.glob(repo.vfs.join("strip-backup") + "/*.hg")
3433 )
3434 backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
3435
3436 opts["bundle"] = ""
3437 opts["force"] = None
3438 limit = logcmdutil.getlimit(opts)
3439
3440 def display(other, chlist, displayer):
3441 if opts.get("newest_first"):
3442 chlist.reverse()
3443 count = 0
3444 for n in chlist:
3445 if limit is not None and count >= limit:
3446 break
3447 parents = [True for p in other.changelog.parents(n) if p != nullid]
3448 if opts.get("no_merges") and len(parents) == 2:
3449 continue
3450 count += 1
3451 displayer.show(other[n])
3452
3453 recovernode = opts.get("recover")
3454 if recovernode:
3455 if scmutil.isrevsymbol(repo, recovernode):
3456 ui.warn(_("%s already exists in the repo\n") % recovernode)
3457 return
3458 elif backups:
3459 msg = _(
3460 "Recover changesets using: hg debugbackupbundle --recover "
3461 "<changeset hash>\n\nAvailable backup changesets:"
3462 )
3463 ui.status(msg, label="status.removed")
3464 else:
3465 ui.status(_("no backup changesets found\n"))
3466 return
3467
3468 for backup in backups:
3469 # Much of this is copied from the hg incoming logic
3470 source = ui.expandpath(os.path.relpath(backup, encoding.getcwd()))
3471 source, branches = hg.parseurl(source, opts.get("branch"))
3472 try:
3473 other = hg.peer(repo, opts, source)
3474 except error.LookupError as ex:
3475 msg = _("\nwarning: unable to open bundle %s") % source
3476 hint = _("\n(missing parent rev %s)\n") % short(ex.name)
3477 ui.warn(msg, hint=hint)
3478 continue
3479 revs, checkout = hg.addbranchrevs(
3480 repo, other, branches, opts.get("rev")
3481 )
3482
3483 if revs:
3484 revs = [other.lookup(rev) for rev in revs]
3485
3486 quiet = ui.quiet
3487 try:
3488 ui.quiet = True
3489 other, chlist, cleanupfn = bundlerepo.getremotechanges(
3490 ui, repo, other, revs, opts["bundle"], opts["force"]
3491 )
3492 except error.LookupError:
3493 continue
3494 finally:
3495 ui.quiet = quiet
3496
3497 try:
3498 if not chlist:
3499 continue
3500 if recovernode:
3501 with repo.lock(), repo.transaction("unbundle") as tr:
3502 if scmutil.isrevsymbol(other, recovernode):
3503 ui.status(_("Unbundling %s\n") % (recovernode))
3504 f = hg.openpath(ui, source)
3505 gen = exchange.readbundle(ui, f, source)
3506 if isinstance(gen, bundle2.unbundle20):
3507 bundle2.applybundle(
3508 repo,
3509 gen,
3510 tr,
3511 source="unbundle",
3512 url="bundle:" + source,
3513 )
3514 else:
3515 gen.apply(repo, "unbundle", "bundle:" + source)
3516 break
3517 else:
3518 backupdate = time.strftime(
3519 "%a %H:%M, %Y-%m-%d",
3520 time.localtime(os.path.getmtime(source)),
3521 )
3522 ui.status("\n%s\n" % (backupdate.ljust(50)))
3523 if ui.verbose:
3524 ui.status("%s%s\n" % ("bundle:".ljust(13), source))
3525 else:
3526 opts[
3527 "template"
3528 ] = "{label('status.modified', node|short)} {desc|firstline}\n"
3529 displayer = logcmdutil.changesetdisplayer(
3530 ui, other, opts, False
3531 )
3532 display(other, chlist, displayer)
3533 displayer.close()
3534 finally:
3535 cleanupfn()
3536
3537
3538 @command(
3405 b'debugsub',
3539 b'debugsub',
3406 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3540 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3407 _(b'[-r REV] [REV]'),
3541 _(b'[-r REV] [REV]'),
3408 )
3542 )
3409 def debugsub(ui, repo, rev=None):
3543 def debugsub(ui, repo, rev=None):
3410 ctx = scmutil.revsingle(repo, rev, None)
3544 ctx = scmutil.revsingle(repo, rev, None)
3411 for k, v in sorted(ctx.substate.items()):
3545 for k, v in sorted(ctx.substate.items()):
3412 ui.writenoi18n(b'path %s\n' % k)
3546 ui.writenoi18n(b'path %s\n' % k)
3413 ui.writenoi18n(b' source %s\n' % v[0])
3547 ui.writenoi18n(b' source %s\n' % v[0])
3414 ui.writenoi18n(b' revision %s\n' % v[1])
3548 ui.writenoi18n(b' revision %s\n' % v[1])
3415
3549
3416
3550
3417 @command(
3551 @command(
3418 b'debugsuccessorssets',
3552 b'debugsuccessorssets',
3419 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3553 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3420 _(b'[REV]'),
3554 _(b'[REV]'),
3421 )
3555 )
3422 def debugsuccessorssets(ui, repo, *revs, **opts):
3556 def debugsuccessorssets(ui, repo, *revs, **opts):
3423 """show set of successors for revision
3557 """show set of successors for revision
3424
3558
3425 A successors set of changeset A is a consistent group of revisions that
3559 A successors set of changeset A is a consistent group of revisions that
3426 succeed A. It contains non-obsolete changesets only unless closests
3560 succeed A. It contains non-obsolete changesets only unless closests
3427 successors set is set.
3561 successors set is set.
3428
3562
3429 In most cases a changeset A has a single successors set containing a single
3563 In most cases a changeset A has a single successors set containing a single
3430 successor (changeset A replaced by A').
3564 successor (changeset A replaced by A').
3431
3565
3432 A changeset that is made obsolete with no successors are called "pruned".
3566 A changeset that is made obsolete with no successors are called "pruned".
3433 Such changesets have no successors sets at all.
3567 Such changesets have no successors sets at all.
3434
3568
3435 A changeset that has been "split" will have a successors set containing
3569 A changeset that has been "split" will have a successors set containing
3436 more than one successor.
3570 more than one successor.
3437
3571
3438 A changeset that has been rewritten in multiple different ways is called
3572 A changeset that has been rewritten in multiple different ways is called
3439 "divergent". Such changesets have multiple successor sets (each of which
3573 "divergent". Such changesets have multiple successor sets (each of which
3440 may also be split, i.e. have multiple successors).
3574 may also be split, i.e. have multiple successors).
3441
3575
3442 Results are displayed as follows::
3576 Results are displayed as follows::
3443
3577
3444 <rev1>
3578 <rev1>
3445 <successors-1A>
3579 <successors-1A>
3446 <rev2>
3580 <rev2>
3447 <successors-2A>
3581 <successors-2A>
3448 <successors-2B1> <successors-2B2> <successors-2B3>
3582 <successors-2B1> <successors-2B2> <successors-2B3>
3449
3583
3450 Here rev2 has two possible (i.e. divergent) successors sets. The first
3584 Here rev2 has two possible (i.e. divergent) successors sets. The first
3451 holds one element, whereas the second holds three (i.e. the changeset has
3585 holds one element, whereas the second holds three (i.e. the changeset has
3452 been split).
3586 been split).
3453 """
3587 """
3454 # passed to successorssets caching computation from one call to another
3588 # passed to successorssets caching computation from one call to another
3455 cache = {}
3589 cache = {}
3456 ctx2str = bytes
3590 ctx2str = bytes
3457 node2str = short
3591 node2str = short
3458 for rev in scmutil.revrange(repo, revs):
3592 for rev in scmutil.revrange(repo, revs):
3459 ctx = repo[rev]
3593 ctx = repo[rev]
3460 ui.write(b'%s\n' % ctx2str(ctx))
3594 ui.write(b'%s\n' % ctx2str(ctx))
3461 for succsset in obsutil.successorssets(
3595 for succsset in obsutil.successorssets(
3462 repo, ctx.node(), closest=opts['closest'], cache=cache
3596 repo, ctx.node(), closest=opts['closest'], cache=cache
3463 ):
3597 ):
3464 if succsset:
3598 if succsset:
3465 ui.write(b' ')
3599 ui.write(b' ')
3466 ui.write(node2str(succsset[0]))
3600 ui.write(node2str(succsset[0]))
3467 for node in succsset[1:]:
3601 for node in succsset[1:]:
3468 ui.write(b' ')
3602 ui.write(b' ')
3469 ui.write(node2str(node))
3603 ui.write(node2str(node))
3470 ui.write(b'\n')
3604 ui.write(b'\n')
3471
3605
3472
3606
3473 @command(b'debugtagscache', [])
3607 @command(b'debugtagscache', [])
3474 def debugtagscache(ui, repo):
3608 def debugtagscache(ui, repo):
3475 """display the contents of .hg/cache/hgtagsfnodes1"""
3609 """display the contents of .hg/cache/hgtagsfnodes1"""
3476 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3610 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3477 for r in repo:
3611 for r in repo:
3478 node = repo[r].node()
3612 node = repo[r].node()
3479 tagsnode = cache.getfnode(node, computemissing=False)
3613 tagsnode = cache.getfnode(node, computemissing=False)
3480 tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
3614 tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
3481 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
3615 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
3482
3616
3483
3617
3484 @command(
3618 @command(
3485 b'debugtemplate',
3619 b'debugtemplate',
3486 [
3620 [
3487 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3621 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3488 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3622 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3489 ],
3623 ],
3490 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3624 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3491 optionalrepo=True,
3625 optionalrepo=True,
3492 )
3626 )
3493 def debugtemplate(ui, repo, tmpl, **opts):
3627 def debugtemplate(ui, repo, tmpl, **opts):
3494 """parse and apply a template
3628 """parse and apply a template
3495
3629
3496 If -r/--rev is given, the template is processed as a log template and
3630 If -r/--rev is given, the template is processed as a log template and
3497 applied to the given changesets. Otherwise, it is processed as a generic
3631 applied to the given changesets. Otherwise, it is processed as a generic
3498 template.
3632 template.
3499
3633
3500 Use --verbose to print the parsed tree.
3634 Use --verbose to print the parsed tree.
3501 """
3635 """
3502 revs = None
3636 revs = None
3503 if opts['rev']:
3637 if opts['rev']:
3504 if repo is None:
3638 if repo is None:
3505 raise error.RepoError(
3639 raise error.RepoError(
3506 _(b'there is no Mercurial repository here (.hg not found)')
3640 _(b'there is no Mercurial repository here (.hg not found)')
3507 )
3641 )
3508 revs = scmutil.revrange(repo, opts['rev'])
3642 revs = scmutil.revrange(repo, opts['rev'])
3509
3643
3510 props = {}
3644 props = {}
3511 for d in opts['define']:
3645 for d in opts['define']:
3512 try:
3646 try:
3513 k, v = (e.strip() for e in d.split(b'=', 1))
3647 k, v = (e.strip() for e in d.split(b'=', 1))
3514 if not k or k == b'ui':
3648 if not k or k == b'ui':
3515 raise ValueError
3649 raise ValueError
3516 props[k] = v
3650 props[k] = v
3517 except ValueError:
3651 except ValueError:
3518 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3652 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3519
3653
3520 if ui.verbose:
3654 if ui.verbose:
3521 aliases = ui.configitems(b'templatealias')
3655 aliases = ui.configitems(b'templatealias')
3522 tree = templater.parse(tmpl)
3656 tree = templater.parse(tmpl)
3523 ui.note(templater.prettyformat(tree), b'\n')
3657 ui.note(templater.prettyformat(tree), b'\n')
3524 newtree = templater.expandaliases(tree, aliases)
3658 newtree = templater.expandaliases(tree, aliases)
3525 if newtree != tree:
3659 if newtree != tree:
3526 ui.notenoi18n(
3660 ui.notenoi18n(
3527 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3661 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3528 )
3662 )
3529
3663
3530 if revs is None:
3664 if revs is None:
3531 tres = formatter.templateresources(ui, repo)
3665 tres = formatter.templateresources(ui, repo)
3532 t = formatter.maketemplater(ui, tmpl, resources=tres)
3666 t = formatter.maketemplater(ui, tmpl, resources=tres)
3533 if ui.verbose:
3667 if ui.verbose:
3534 kwds, funcs = t.symbolsuseddefault()
3668 kwds, funcs = t.symbolsuseddefault()
3535 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3669 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3536 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3670 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3537 ui.write(t.renderdefault(props))
3671 ui.write(t.renderdefault(props))
3538 else:
3672 else:
3539 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3673 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3540 if ui.verbose:
3674 if ui.verbose:
3541 kwds, funcs = displayer.t.symbolsuseddefault()
3675 kwds, funcs = displayer.t.symbolsuseddefault()
3542 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3676 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3543 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3677 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3544 for r in revs:
3678 for r in revs:
3545 displayer.show(repo[r], **pycompat.strkwargs(props))
3679 displayer.show(repo[r], **pycompat.strkwargs(props))
3546 displayer.close()
3680 displayer.close()
3547
3681
3548
3682
3549 @command(
3683 @command(
3550 b'debuguigetpass',
3684 b'debuguigetpass',
3551 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3685 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3552 _(b'[-p TEXT]'),
3686 _(b'[-p TEXT]'),
3553 norepo=True,
3687 norepo=True,
3554 )
3688 )
3555 def debuguigetpass(ui, prompt=b''):
3689 def debuguigetpass(ui, prompt=b''):
3556 """show prompt to type password"""
3690 """show prompt to type password"""
3557 r = ui.getpass(prompt)
3691 r = ui.getpass(prompt)
3558 ui.writenoi18n(b'respose: %s\n' % r)
3692 ui.writenoi18n(b'respose: %s\n' % r)
3559
3693
3560
3694
3561 @command(
3695 @command(
3562 b'debuguiprompt',
3696 b'debuguiprompt',
3563 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3697 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3564 _(b'[-p TEXT]'),
3698 _(b'[-p TEXT]'),
3565 norepo=True,
3699 norepo=True,
3566 )
3700 )
3567 def debuguiprompt(ui, prompt=b''):
3701 def debuguiprompt(ui, prompt=b''):
3568 """show plain prompt"""
3702 """show plain prompt"""
3569 r = ui.prompt(prompt)
3703 r = ui.prompt(prompt)
3570 ui.writenoi18n(b'response: %s\n' % r)
3704 ui.writenoi18n(b'response: %s\n' % r)
3571
3705
3572
3706
3573 @command(b'debugupdatecaches', [])
3707 @command(b'debugupdatecaches', [])
3574 def debugupdatecaches(ui, repo, *pats, **opts):
3708 def debugupdatecaches(ui, repo, *pats, **opts):
3575 """warm all known caches in the repository"""
3709 """warm all known caches in the repository"""
3576 with repo.wlock(), repo.lock():
3710 with repo.wlock(), repo.lock():
3577 repo.updatecaches(full=True)
3711 repo.updatecaches(full=True)
3578
3712
3579
3713
3580 @command(
3714 @command(
3581 b'debugupgraderepo',
3715 b'debugupgraderepo',
3582 [
3716 [
3583 (
3717 (
3584 b'o',
3718 b'o',
3585 b'optimize',
3719 b'optimize',
3586 [],
3720 [],
3587 _(b'extra optimization to perform'),
3721 _(b'extra optimization to perform'),
3588 _(b'NAME'),
3722 _(b'NAME'),
3589 ),
3723 ),
3590 (b'', b'run', False, _(b'performs an upgrade')),
3724 (b'', b'run', False, _(b'performs an upgrade')),
3591 (b'', b'backup', True, _(b'keep the old repository content around')),
3725 (b'', b'backup', True, _(b'keep the old repository content around')),
3592 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3726 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3593 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3727 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3594 ],
3728 ],
3595 )
3729 )
3596 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3730 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3597 """upgrade a repository to use different features
3731 """upgrade a repository to use different features
3598
3732
3599 If no arguments are specified, the repository is evaluated for upgrade
3733 If no arguments are specified, the repository is evaluated for upgrade
3600 and a list of problems and potential optimizations is printed.
3734 and a list of problems and potential optimizations is printed.
3601
3735
3602 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3736 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3603 can be influenced via additional arguments. More details will be provided
3737 can be influenced via additional arguments. More details will be provided
3604 by the command output when run without ``--run``.
3738 by the command output when run without ``--run``.
3605
3739
3606 During the upgrade, the repository will be locked and no writes will be
3740 During the upgrade, the repository will be locked and no writes will be
3607 allowed.
3741 allowed.
3608
3742
3609 At the end of the upgrade, the repository may not be readable while new
3743 At the end of the upgrade, the repository may not be readable while new
3610 repository data is swapped in. This window will be as long as it takes to
3744 repository data is swapped in. This window will be as long as it takes to
3611 rename some directories inside the ``.hg`` directory. On most machines, this
3745 rename some directories inside the ``.hg`` directory. On most machines, this
3612 should complete almost instantaneously and the chances of a consumer being
3746 should complete almost instantaneously and the chances of a consumer being
3613 unable to access the repository should be low.
3747 unable to access the repository should be low.
3614
3748
3615 By default, all revlog will be upgraded. You can restrict this using flag
3749 By default, all revlog will be upgraded. You can restrict this using flag
3616 such as `--manifest`:
3750 such as `--manifest`:
3617
3751
3618 * `--manifest`: only optimize the manifest
3752 * `--manifest`: only optimize the manifest
3619 * `--no-manifest`: optimize all revlog but the manifest
3753 * `--no-manifest`: optimize all revlog but the manifest
3620 * `--changelog`: optimize the changelog only
3754 * `--changelog`: optimize the changelog only
3621 * `--no-changelog --no-manifest`: optimize filelogs only
3755 * `--no-changelog --no-manifest`: optimize filelogs only
3622 """
3756 """
3623 return upgrade.upgraderepo(
3757 return upgrade.upgraderepo(
3624 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3758 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3625 )
3759 )
3626
3760
3627
3761
3628 @command(
3762 @command(
3629 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3763 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3630 )
3764 )
3631 def debugwalk(ui, repo, *pats, **opts):
3765 def debugwalk(ui, repo, *pats, **opts):
3632 """show how files match on given patterns"""
3766 """show how files match on given patterns"""
3633 opts = pycompat.byteskwargs(opts)
3767 opts = pycompat.byteskwargs(opts)
3634 m = scmutil.match(repo[None], pats, opts)
3768 m = scmutil.match(repo[None], pats, opts)
3635 if ui.verbose:
3769 if ui.verbose:
3636 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3770 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3637 items = list(repo[None].walk(m))
3771 items = list(repo[None].walk(m))
3638 if not items:
3772 if not items:
3639 return
3773 return
3640 f = lambda fn: fn
3774 f = lambda fn: fn
3641 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3775 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3642 f = lambda fn: util.normpath(fn)
3776 f = lambda fn: util.normpath(fn)
3643 fmt = b'f %%-%ds %%-%ds %%s' % (
3777 fmt = b'f %%-%ds %%-%ds %%s' % (
3644 max([len(abs) for abs in items]),
3778 max([len(abs) for abs in items]),
3645 max([len(repo.pathto(abs)) for abs in items]),
3779 max([len(repo.pathto(abs)) for abs in items]),
3646 )
3780 )
3647 for abs in items:
3781 for abs in items:
3648 line = fmt % (
3782 line = fmt % (
3649 abs,
3783 abs,
3650 f(repo.pathto(abs)),
3784 f(repo.pathto(abs)),
3651 m.exact(abs) and b'exact' or b'',
3785 m.exact(abs) and b'exact' or b'',
3652 )
3786 )
3653 ui.write(b"%s\n" % line.rstrip())
3787 ui.write(b"%s\n" % line.rstrip())
3654
3788
3655
3789
3656 @command(b'debugwhyunstable', [], _(b'REV'))
3790 @command(b'debugwhyunstable', [], _(b'REV'))
3657 def debugwhyunstable(ui, repo, rev):
3791 def debugwhyunstable(ui, repo, rev):
3658 """explain instabilities of a changeset"""
3792 """explain instabilities of a changeset"""
3659 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3793 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3660 dnodes = b''
3794 dnodes = b''
3661 if entry.get(b'divergentnodes'):
3795 if entry.get(b'divergentnodes'):
3662 dnodes = (
3796 dnodes = (
3663 b' '.join(
3797 b' '.join(
3664 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3798 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3665 for ctx in entry[b'divergentnodes']
3799 for ctx in entry[b'divergentnodes']
3666 )
3800 )
3667 + b' '
3801 + b' '
3668 )
3802 )
3669 ui.write(
3803 ui.write(
3670 b'%s: %s%s %s\n'
3804 b'%s: %s%s %s\n'
3671 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3805 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3672 )
3806 )
3673
3807
3674
3808
3675 @command(
3809 @command(
3676 b'debugwireargs',
3810 b'debugwireargs',
3677 [
3811 [
3678 (b'', b'three', b'', b'three'),
3812 (b'', b'three', b'', b'three'),
3679 (b'', b'four', b'', b'four'),
3813 (b'', b'four', b'', b'four'),
3680 (b'', b'five', b'', b'five'),
3814 (b'', b'five', b'', b'five'),
3681 ]
3815 ]
3682 + cmdutil.remoteopts,
3816 + cmdutil.remoteopts,
3683 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3817 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3684 norepo=True,
3818 norepo=True,
3685 )
3819 )
3686 def debugwireargs(ui, repopath, *vals, **opts):
3820 def debugwireargs(ui, repopath, *vals, **opts):
3687 opts = pycompat.byteskwargs(opts)
3821 opts = pycompat.byteskwargs(opts)
3688 repo = hg.peer(ui, opts, repopath)
3822 repo = hg.peer(ui, opts, repopath)
3689 for opt in cmdutil.remoteopts:
3823 for opt in cmdutil.remoteopts:
3690 del opts[opt[1]]
3824 del opts[opt[1]]
3691 args = {}
3825 args = {}
3692 for k, v in pycompat.iteritems(opts):
3826 for k, v in pycompat.iteritems(opts):
3693 if v:
3827 if v:
3694 args[k] = v
3828 args[k] = v
3695 args = pycompat.strkwargs(args)
3829 args = pycompat.strkwargs(args)
3696 # run twice to check that we don't mess up the stream for the next command
3830 # run twice to check that we don't mess up the stream for the next command
3697 res1 = repo.debugwireargs(*vals, **args)
3831 res1 = repo.debugwireargs(*vals, **args)
3698 res2 = repo.debugwireargs(*vals, **args)
3832 res2 = repo.debugwireargs(*vals, **args)
3699 ui.write(b"%s\n" % res1)
3833 ui.write(b"%s\n" % res1)
3700 if res1 != res2:
3834 if res1 != res2:
3701 ui.warn(b"%s\n" % res2)
3835 ui.warn(b"%s\n" % res2)
3702
3836
3703
3837
3704 def _parsewirelangblocks(fh):
3838 def _parsewirelangblocks(fh):
3705 activeaction = None
3839 activeaction = None
3706 blocklines = []
3840 blocklines = []
3707 lastindent = 0
3841 lastindent = 0
3708
3842
3709 for line in fh:
3843 for line in fh:
3710 line = line.rstrip()
3844 line = line.rstrip()
3711 if not line:
3845 if not line:
3712 continue
3846 continue
3713
3847
3714 if line.startswith(b'#'):
3848 if line.startswith(b'#'):
3715 continue
3849 continue
3716
3850
3717 if not line.startswith(b' '):
3851 if not line.startswith(b' '):
3718 # New block. Flush previous one.
3852 # New block. Flush previous one.
3719 if activeaction:
3853 if activeaction:
3720 yield activeaction, blocklines
3854 yield activeaction, blocklines
3721
3855
3722 activeaction = line
3856 activeaction = line
3723 blocklines = []
3857 blocklines = []
3724 lastindent = 0
3858 lastindent = 0
3725 continue
3859 continue
3726
3860
3727 # Else we start with an indent.
3861 # Else we start with an indent.
3728
3862
3729 if not activeaction:
3863 if not activeaction:
3730 raise error.Abort(_(b'indented line outside of block'))
3864 raise error.Abort(_(b'indented line outside of block'))
3731
3865
3732 indent = len(line) - len(line.lstrip())
3866 indent = len(line) - len(line.lstrip())
3733
3867
3734 # If this line is indented more than the last line, concatenate it.
3868 # If this line is indented more than the last line, concatenate it.
3735 if indent > lastindent and blocklines:
3869 if indent > lastindent and blocklines:
3736 blocklines[-1] += line.lstrip()
3870 blocklines[-1] += line.lstrip()
3737 else:
3871 else:
3738 blocklines.append(line)
3872 blocklines.append(line)
3739 lastindent = indent
3873 lastindent = indent
3740
3874
3741 # Flush last block.
3875 # Flush last block.
3742 if activeaction:
3876 if activeaction:
3743 yield activeaction, blocklines
3877 yield activeaction, blocklines
3744
3878
3745
3879
3746 @command(
3880 @command(
3747 b'debugwireproto',
3881 b'debugwireproto',
3748 [
3882 [
3749 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3883 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3750 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3884 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3751 (
3885 (
3752 b'',
3886 b'',
3753 b'noreadstderr',
3887 b'noreadstderr',
3754 False,
3888 False,
3755 _(b'do not read from stderr of the remote'),
3889 _(b'do not read from stderr of the remote'),
3756 ),
3890 ),
3757 (
3891 (
3758 b'',
3892 b'',
3759 b'nologhandshake',
3893 b'nologhandshake',
3760 False,
3894 False,
3761 _(b'do not log I/O related to the peer handshake'),
3895 _(b'do not log I/O related to the peer handshake'),
3762 ),
3896 ),
3763 ]
3897 ]
3764 + cmdutil.remoteopts,
3898 + cmdutil.remoteopts,
3765 _(b'[PATH]'),
3899 _(b'[PATH]'),
3766 optionalrepo=True,
3900 optionalrepo=True,
3767 )
3901 )
3768 def debugwireproto(ui, repo, path=None, **opts):
3902 def debugwireproto(ui, repo, path=None, **opts):
3769 """send wire protocol commands to a server
3903 """send wire protocol commands to a server
3770
3904
3771 This command can be used to issue wire protocol commands to remote
3905 This command can be used to issue wire protocol commands to remote
3772 peers and to debug the raw data being exchanged.
3906 peers and to debug the raw data being exchanged.
3773
3907
3774 ``--localssh`` will start an SSH server against the current repository
3908 ``--localssh`` will start an SSH server against the current repository
3775 and connect to that. By default, the connection will perform a handshake
3909 and connect to that. By default, the connection will perform a handshake
3776 and establish an appropriate peer instance.
3910 and establish an appropriate peer instance.
3777
3911
3778 ``--peer`` can be used to bypass the handshake protocol and construct a
3912 ``--peer`` can be used to bypass the handshake protocol and construct a
3779 peer instance using the specified class type. Valid values are ``raw``,
3913 peer instance using the specified class type. Valid values are ``raw``,
3780 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3914 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3781 raw data payloads and don't support higher-level command actions.
3915 raw data payloads and don't support higher-level command actions.
3782
3916
3783 ``--noreadstderr`` can be used to disable automatic reading from stderr
3917 ``--noreadstderr`` can be used to disable automatic reading from stderr
3784 of the peer (for SSH connections only). Disabling automatic reading of
3918 of the peer (for SSH connections only). Disabling automatic reading of
3785 stderr is useful for making output more deterministic.
3919 stderr is useful for making output more deterministic.
3786
3920
3787 Commands are issued via a mini language which is specified via stdin.
3921 Commands are issued via a mini language which is specified via stdin.
3788 The language consists of individual actions to perform. An action is
3922 The language consists of individual actions to perform. An action is
3789 defined by a block. A block is defined as a line with no leading
3923 defined by a block. A block is defined as a line with no leading
3790 space followed by 0 or more lines with leading space. Blocks are
3924 space followed by 0 or more lines with leading space. Blocks are
3791 effectively a high-level command with additional metadata.
3925 effectively a high-level command with additional metadata.
3792
3926
3793 Lines beginning with ``#`` are ignored.
3927 Lines beginning with ``#`` are ignored.
3794
3928
3795 The following sections denote available actions.
3929 The following sections denote available actions.
3796
3930
3797 raw
3931 raw
3798 ---
3932 ---
3799
3933
3800 Send raw data to the server.
3934 Send raw data to the server.
3801
3935
3802 The block payload contains the raw data to send as one atomic send
3936 The block payload contains the raw data to send as one atomic send
3803 operation. The data may not actually be delivered in a single system
3937 operation. The data may not actually be delivered in a single system
3804 call: it depends on the abilities of the transport being used.
3938 call: it depends on the abilities of the transport being used.
3805
3939
3806 Each line in the block is de-indented and concatenated. Then, that
3940 Each line in the block is de-indented and concatenated. Then, that
3807 value is evaluated as a Python b'' literal. This allows the use of
3941 value is evaluated as a Python b'' literal. This allows the use of
3808 backslash escaping, etc.
3942 backslash escaping, etc.
3809
3943
3810 raw+
3944 raw+
3811 ----
3945 ----
3812
3946
3813 Behaves like ``raw`` except flushes output afterwards.
3947 Behaves like ``raw`` except flushes output afterwards.
3814
3948
3815 command <X>
3949 command <X>
3816 -----------
3950 -----------
3817
3951
3818 Send a request to run a named command, whose name follows the ``command``
3952 Send a request to run a named command, whose name follows the ``command``
3819 string.
3953 string.
3820
3954
3821 Arguments to the command are defined as lines in this block. The format of
3955 Arguments to the command are defined as lines in this block. The format of
3822 each line is ``<key> <value>``. e.g.::
3956 each line is ``<key> <value>``. e.g.::
3823
3957
3824 command listkeys
3958 command listkeys
3825 namespace bookmarks
3959 namespace bookmarks
3826
3960
3827 If the value begins with ``eval:``, it will be interpreted as a Python
3961 If the value begins with ``eval:``, it will be interpreted as a Python
3828 literal expression. Otherwise values are interpreted as Python b'' literals.
3962 literal expression. Otherwise values are interpreted as Python b'' literals.
3829 This allows sending complex types and encoding special byte sequences via
3963 This allows sending complex types and encoding special byte sequences via
3830 backslash escaping.
3964 backslash escaping.
3831
3965
3832 The following arguments have special meaning:
3966 The following arguments have special meaning:
3833
3967
3834 ``PUSHFILE``
3968 ``PUSHFILE``
3835 When defined, the *push* mechanism of the peer will be used instead
3969 When defined, the *push* mechanism of the peer will be used instead
3836 of the static request-response mechanism and the content of the
3970 of the static request-response mechanism and the content of the
3837 file specified in the value of this argument will be sent as the
3971 file specified in the value of this argument will be sent as the
3838 command payload.
3972 command payload.
3839
3973
3840 This can be used to submit a local bundle file to the remote.
3974 This can be used to submit a local bundle file to the remote.
3841
3975
3842 batchbegin
3976 batchbegin
3843 ----------
3977 ----------
3844
3978
3845 Instruct the peer to begin a batched send.
3979 Instruct the peer to begin a batched send.
3846
3980
3847 All ``command`` blocks are queued for execution until the next
3981 All ``command`` blocks are queued for execution until the next
3848 ``batchsubmit`` block.
3982 ``batchsubmit`` block.
3849
3983
3850 batchsubmit
3984 batchsubmit
3851 -----------
3985 -----------
3852
3986
3853 Submit previously queued ``command`` blocks as a batch request.
3987 Submit previously queued ``command`` blocks as a batch request.
3854
3988
3855 This action MUST be paired with a ``batchbegin`` action.
3989 This action MUST be paired with a ``batchbegin`` action.
3856
3990
3857 httprequest <method> <path>
3991 httprequest <method> <path>
3858 ---------------------------
3992 ---------------------------
3859
3993
3860 (HTTP peer only)
3994 (HTTP peer only)
3861
3995
3862 Send an HTTP request to the peer.
3996 Send an HTTP request to the peer.
3863
3997
3864 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
3998 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
3865
3999
3866 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
4000 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
3867 headers to add to the request. e.g. ``Accept: foo``.
4001 headers to add to the request. e.g. ``Accept: foo``.
3868
4002
3869 The following arguments are special:
4003 The following arguments are special:
3870
4004
3871 ``BODYFILE``
4005 ``BODYFILE``
3872 The content of the file defined as the value to this argument will be
4006 The content of the file defined as the value to this argument will be
3873 transferred verbatim as the HTTP request body.
4007 transferred verbatim as the HTTP request body.
3874
4008
3875 ``frame <type> <flags> <payload>``
4009 ``frame <type> <flags> <payload>``
3876 Send a unified protocol frame as part of the request body.
4010 Send a unified protocol frame as part of the request body.
3877
4011
3878 All frames will be collected and sent as the body to the HTTP
4012 All frames will be collected and sent as the body to the HTTP
3879 request.
4013 request.
3880
4014
3881 close
4015 close
3882 -----
4016 -----
3883
4017
3884 Close the connection to the server.
4018 Close the connection to the server.
3885
4019
3886 flush
4020 flush
3887 -----
4021 -----
3888
4022
3889 Flush data written to the server.
4023 Flush data written to the server.
3890
4024
3891 readavailable
4025 readavailable
3892 -------------
4026 -------------
3893
4027
3894 Close the write end of the connection and read all available data from
4028 Close the write end of the connection and read all available data from
3895 the server.
4029 the server.
3896
4030
3897 If the connection to the server encompasses multiple pipes, we poll both
4031 If the connection to the server encompasses multiple pipes, we poll both
3898 pipes and read available data.
4032 pipes and read available data.
3899
4033
3900 readline
4034 readline
3901 --------
4035 --------
3902
4036
3903 Read a line of output from the server. If there are multiple output
4037 Read a line of output from the server. If there are multiple output
3904 pipes, reads only the main pipe.
4038 pipes, reads only the main pipe.
3905
4039
3906 ereadline
4040 ereadline
3907 ---------
4041 ---------
3908
4042
3909 Like ``readline``, but read from the stderr pipe, if available.
4043 Like ``readline``, but read from the stderr pipe, if available.
3910
4044
3911 read <X>
4045 read <X>
3912 --------
4046 --------
3913
4047
3914 ``read()`` N bytes from the server's main output pipe.
4048 ``read()`` N bytes from the server's main output pipe.
3915
4049
3916 eread <X>
4050 eread <X>
3917 ---------
4051 ---------
3918
4052
3919 ``read()`` N bytes from the server's stderr pipe, if available.
4053 ``read()`` N bytes from the server's stderr pipe, if available.
3920
4054
3921 Specifying Unified Frame-Based Protocol Frames
4055 Specifying Unified Frame-Based Protocol Frames
3922 ----------------------------------------------
4056 ----------------------------------------------
3923
4057
3924 It is possible to emit a *Unified Frame-Based Protocol* by using special
4058 It is possible to emit a *Unified Frame-Based Protocol* by using special
3925 syntax.
4059 syntax.
3926
4060
3927 A frame is composed as a type, flags, and payload. These can be parsed
4061 A frame is composed as a type, flags, and payload. These can be parsed
3928 from a string of the form:
4062 from a string of the form:
3929
4063
3930 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
4064 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3931
4065
3932 ``request-id`` and ``stream-id`` are integers defining the request and
4066 ``request-id`` and ``stream-id`` are integers defining the request and
3933 stream identifiers.
4067 stream identifiers.
3934
4068
3935 ``type`` can be an integer value for the frame type or the string name
4069 ``type`` can be an integer value for the frame type or the string name
3936 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
4070 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3937 ``command-name``.
4071 ``command-name``.
3938
4072
3939 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
4073 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3940 components. Each component (and there can be just one) can be an integer
4074 components. Each component (and there can be just one) can be an integer
3941 or a flag name for stream flags or frame flags, respectively. Values are
4075 or a flag name for stream flags or frame flags, respectively. Values are
3942 resolved to integers and then bitwise OR'd together.
4076 resolved to integers and then bitwise OR'd together.
3943
4077
3944 ``payload`` represents the raw frame payload. If it begins with
4078 ``payload`` represents the raw frame payload. If it begins with
3945 ``cbor:``, the following string is evaluated as Python code and the
4079 ``cbor:``, the following string is evaluated as Python code and the
3946 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
4080 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3947 as a Python byte string literal.
4081 as a Python byte string literal.
3948 """
4082 """
3949 opts = pycompat.byteskwargs(opts)
4083 opts = pycompat.byteskwargs(opts)
3950
4084
3951 if opts[b'localssh'] and not repo:
4085 if opts[b'localssh'] and not repo:
3952 raise error.Abort(_(b'--localssh requires a repository'))
4086 raise error.Abort(_(b'--localssh requires a repository'))
3953
4087
3954 if opts[b'peer'] and opts[b'peer'] not in (
4088 if opts[b'peer'] and opts[b'peer'] not in (
3955 b'raw',
4089 b'raw',
3956 b'http2',
4090 b'http2',
3957 b'ssh1',
4091 b'ssh1',
3958 b'ssh2',
4092 b'ssh2',
3959 ):
4093 ):
3960 raise error.Abort(
4094 raise error.Abort(
3961 _(b'invalid value for --peer'),
4095 _(b'invalid value for --peer'),
3962 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
4096 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
3963 )
4097 )
3964
4098
3965 if path and opts[b'localssh']:
4099 if path and opts[b'localssh']:
3966 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
4100 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
3967
4101
3968 if ui.interactive():
4102 if ui.interactive():
3969 ui.write(_(b'(waiting for commands on stdin)\n'))
4103 ui.write(_(b'(waiting for commands on stdin)\n'))
3970
4104
3971 blocks = list(_parsewirelangblocks(ui.fin))
4105 blocks = list(_parsewirelangblocks(ui.fin))
3972
4106
3973 proc = None
4107 proc = None
3974 stdin = None
4108 stdin = None
3975 stdout = None
4109 stdout = None
3976 stderr = None
4110 stderr = None
3977 opener = None
4111 opener = None
3978
4112
3979 if opts[b'localssh']:
4113 if opts[b'localssh']:
3980 # We start the SSH server in its own process so there is process
4114 # We start the SSH server in its own process so there is process
3981 # separation. This prevents a whole class of potential bugs around
4115 # separation. This prevents a whole class of potential bugs around
3982 # shared state from interfering with server operation.
4116 # shared state from interfering with server operation.
3983 args = procutil.hgcmd() + [
4117 args = procutil.hgcmd() + [
3984 b'-R',
4118 b'-R',
3985 repo.root,
4119 repo.root,
3986 b'debugserve',
4120 b'debugserve',
3987 b'--sshstdio',
4121 b'--sshstdio',
3988 ]
4122 ]
3989 proc = subprocess.Popen(
4123 proc = subprocess.Popen(
3990 pycompat.rapply(procutil.tonativestr, args),
4124 pycompat.rapply(procutil.tonativestr, args),
3991 stdin=subprocess.PIPE,
4125 stdin=subprocess.PIPE,
3992 stdout=subprocess.PIPE,
4126 stdout=subprocess.PIPE,
3993 stderr=subprocess.PIPE,
4127 stderr=subprocess.PIPE,
3994 bufsize=0,
4128 bufsize=0,
3995 )
4129 )
3996
4130
3997 stdin = proc.stdin
4131 stdin = proc.stdin
3998 stdout = proc.stdout
4132 stdout = proc.stdout
3999 stderr = proc.stderr
4133 stderr = proc.stderr
4000
4134
4001 # We turn the pipes into observers so we can log I/O.
4135 # We turn the pipes into observers so we can log I/O.
4002 if ui.verbose or opts[b'peer'] == b'raw':
4136 if ui.verbose or opts[b'peer'] == b'raw':
4003 stdin = util.makeloggingfileobject(
4137 stdin = util.makeloggingfileobject(
4004 ui, proc.stdin, b'i', logdata=True
4138 ui, proc.stdin, b'i', logdata=True
4005 )
4139 )
4006 stdout = util.makeloggingfileobject(
4140 stdout = util.makeloggingfileobject(
4007 ui, proc.stdout, b'o', logdata=True
4141 ui, proc.stdout, b'o', logdata=True
4008 )
4142 )
4009 stderr = util.makeloggingfileobject(
4143 stderr = util.makeloggingfileobject(
4010 ui, proc.stderr, b'e', logdata=True
4144 ui, proc.stderr, b'e', logdata=True
4011 )
4145 )
4012
4146
4013 # --localssh also implies the peer connection settings.
4147 # --localssh also implies the peer connection settings.
4014
4148
4015 url = b'ssh://localserver'
4149 url = b'ssh://localserver'
4016 autoreadstderr = not opts[b'noreadstderr']
4150 autoreadstderr = not opts[b'noreadstderr']
4017
4151
4018 if opts[b'peer'] == b'ssh1':
4152 if opts[b'peer'] == b'ssh1':
4019 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4153 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4020 peer = sshpeer.sshv1peer(
4154 peer = sshpeer.sshv1peer(
4021 ui,
4155 ui,
4022 url,
4156 url,
4023 proc,
4157 proc,
4024 stdin,
4158 stdin,
4025 stdout,
4159 stdout,
4026 stderr,
4160 stderr,
4027 None,
4161 None,
4028 autoreadstderr=autoreadstderr,
4162 autoreadstderr=autoreadstderr,
4029 )
4163 )
4030 elif opts[b'peer'] == b'ssh2':
4164 elif opts[b'peer'] == b'ssh2':
4031 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
4165 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
4032 peer = sshpeer.sshv2peer(
4166 peer = sshpeer.sshv2peer(
4033 ui,
4167 ui,
4034 url,
4168 url,
4035 proc,
4169 proc,
4036 stdin,
4170 stdin,
4037 stdout,
4171 stdout,
4038 stderr,
4172 stderr,
4039 None,
4173 None,
4040 autoreadstderr=autoreadstderr,
4174 autoreadstderr=autoreadstderr,
4041 )
4175 )
4042 elif opts[b'peer'] == b'raw':
4176 elif opts[b'peer'] == b'raw':
4043 ui.write(_(b'using raw connection to peer\n'))
4177 ui.write(_(b'using raw connection to peer\n'))
4044 peer = None
4178 peer = None
4045 else:
4179 else:
4046 ui.write(_(b'creating ssh peer from handshake results\n'))
4180 ui.write(_(b'creating ssh peer from handshake results\n'))
4047 peer = sshpeer.makepeer(
4181 peer = sshpeer.makepeer(
4048 ui,
4182 ui,
4049 url,
4183 url,
4050 proc,
4184 proc,
4051 stdin,
4185 stdin,
4052 stdout,
4186 stdout,
4053 stderr,
4187 stderr,
4054 autoreadstderr=autoreadstderr,
4188 autoreadstderr=autoreadstderr,
4055 )
4189 )
4056
4190
4057 elif path:
4191 elif path:
4058 # We bypass hg.peer() so we can proxy the sockets.
4192 # We bypass hg.peer() so we can proxy the sockets.
4059 # TODO consider not doing this because we skip
4193 # TODO consider not doing this because we skip
4060 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4194 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4061 u = util.url(path)
4195 u = util.url(path)
4062 if u.scheme != b'http':
4196 if u.scheme != b'http':
4063 raise error.Abort(_(b'only http:// paths are currently supported'))
4197 raise error.Abort(_(b'only http:// paths are currently supported'))
4064
4198
4065 url, authinfo = u.authinfo()
4199 url, authinfo = u.authinfo()
4066 openerargs = {
4200 openerargs = {
4067 'useragent': b'Mercurial debugwireproto',
4201 'useragent': b'Mercurial debugwireproto',
4068 }
4202 }
4069
4203
4070 # Turn pipes/sockets into observers so we can log I/O.
4204 # Turn pipes/sockets into observers so we can log I/O.
4071 if ui.verbose:
4205 if ui.verbose:
4072 openerargs.update(
4206 openerargs.update(
4073 {
4207 {
4074 'loggingfh': ui,
4208 'loggingfh': ui,
4075 'loggingname': b's',
4209 'loggingname': b's',
4076 'loggingopts': {'logdata': True, 'logdataapis': False,},
4210 'loggingopts': {'logdata': True, 'logdataapis': False,},
4077 }
4211 }
4078 )
4212 )
4079
4213
4080 if ui.debugflag:
4214 if ui.debugflag:
4081 openerargs['loggingopts']['logdataapis'] = True
4215 openerargs['loggingopts']['logdataapis'] = True
4082
4216
4083 # Don't send default headers when in raw mode. This allows us to
4217 # Don't send default headers when in raw mode. This allows us to
4084 # bypass most of the behavior of our URL handling code so we can
4218 # bypass most of the behavior of our URL handling code so we can
4085 # have near complete control over what's sent on the wire.
4219 # have near complete control over what's sent on the wire.
4086 if opts[b'peer'] == b'raw':
4220 if opts[b'peer'] == b'raw':
4087 openerargs['sendaccept'] = False
4221 openerargs['sendaccept'] = False
4088
4222
4089 opener = urlmod.opener(ui, authinfo, **openerargs)
4223 opener = urlmod.opener(ui, authinfo, **openerargs)
4090
4224
4091 if opts[b'peer'] == b'http2':
4225 if opts[b'peer'] == b'http2':
4092 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4226 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4093 # We go through makepeer() because we need an API descriptor for
4227 # We go through makepeer() because we need an API descriptor for
4094 # the peer instance to be useful.
4228 # the peer instance to be useful.
4095 with ui.configoverride(
4229 with ui.configoverride(
4096 {(b'experimental', b'httppeer.advertise-v2'): True}
4230 {(b'experimental', b'httppeer.advertise-v2'): True}
4097 ):
4231 ):
4098 if opts[b'nologhandshake']:
4232 if opts[b'nologhandshake']:
4099 ui.pushbuffer()
4233 ui.pushbuffer()
4100
4234
4101 peer = httppeer.makepeer(ui, path, opener=opener)
4235 peer = httppeer.makepeer(ui, path, opener=opener)
4102
4236
4103 if opts[b'nologhandshake']:
4237 if opts[b'nologhandshake']:
4104 ui.popbuffer()
4238 ui.popbuffer()
4105
4239
4106 if not isinstance(peer, httppeer.httpv2peer):
4240 if not isinstance(peer, httppeer.httpv2peer):
4107 raise error.Abort(
4241 raise error.Abort(
4108 _(
4242 _(
4109 b'could not instantiate HTTP peer for '
4243 b'could not instantiate HTTP peer for '
4110 b'wire protocol version 2'
4244 b'wire protocol version 2'
4111 ),
4245 ),
4112 hint=_(
4246 hint=_(
4113 b'the server may not have the feature '
4247 b'the server may not have the feature '
4114 b'enabled or is not allowing this '
4248 b'enabled or is not allowing this '
4115 b'client version'
4249 b'client version'
4116 ),
4250 ),
4117 )
4251 )
4118
4252
4119 elif opts[b'peer'] == b'raw':
4253 elif opts[b'peer'] == b'raw':
4120 ui.write(_(b'using raw connection to peer\n'))
4254 ui.write(_(b'using raw connection to peer\n'))
4121 peer = None
4255 peer = None
4122 elif opts[b'peer']:
4256 elif opts[b'peer']:
4123 raise error.Abort(
4257 raise error.Abort(
4124 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4258 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4125 )
4259 )
4126 else:
4260 else:
4127 peer = httppeer.makepeer(ui, path, opener=opener)
4261 peer = httppeer.makepeer(ui, path, opener=opener)
4128
4262
4129 # We /could/ populate stdin/stdout with sock.makefile()...
4263 # We /could/ populate stdin/stdout with sock.makefile()...
4130 else:
4264 else:
4131 raise error.Abort(_(b'unsupported connection configuration'))
4265 raise error.Abort(_(b'unsupported connection configuration'))
4132
4266
4133 batchedcommands = None
4267 batchedcommands = None
4134
4268
4135 # Now perform actions based on the parsed wire language instructions.
4269 # Now perform actions based on the parsed wire language instructions.
4136 for action, lines in blocks:
4270 for action, lines in blocks:
4137 if action in (b'raw', b'raw+'):
4271 if action in (b'raw', b'raw+'):
4138 if not stdin:
4272 if not stdin:
4139 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4273 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4140
4274
4141 # Concatenate the data together.
4275 # Concatenate the data together.
4142 data = b''.join(l.lstrip() for l in lines)
4276 data = b''.join(l.lstrip() for l in lines)
4143 data = stringutil.unescapestr(data)
4277 data = stringutil.unescapestr(data)
4144 stdin.write(data)
4278 stdin.write(data)
4145
4279
4146 if action == b'raw+':
4280 if action == b'raw+':
4147 stdin.flush()
4281 stdin.flush()
4148 elif action == b'flush':
4282 elif action == b'flush':
4149 if not stdin:
4283 if not stdin:
4150 raise error.Abort(_(b'cannot call flush on this peer'))
4284 raise error.Abort(_(b'cannot call flush on this peer'))
4151 stdin.flush()
4285 stdin.flush()
4152 elif action.startswith(b'command'):
4286 elif action.startswith(b'command'):
4153 if not peer:
4287 if not peer:
4154 raise error.Abort(
4288 raise error.Abort(
4155 _(
4289 _(
4156 b'cannot send commands unless peer instance '
4290 b'cannot send commands unless peer instance '
4157 b'is available'
4291 b'is available'
4158 )
4292 )
4159 )
4293 )
4160
4294
4161 command = action.split(b' ', 1)[1]
4295 command = action.split(b' ', 1)[1]
4162
4296
4163 args = {}
4297 args = {}
4164 for line in lines:
4298 for line in lines:
4165 # We need to allow empty values.
4299 # We need to allow empty values.
4166 fields = line.lstrip().split(b' ', 1)
4300 fields = line.lstrip().split(b' ', 1)
4167 if len(fields) == 1:
4301 if len(fields) == 1:
4168 key = fields[0]
4302 key = fields[0]
4169 value = b''
4303 value = b''
4170 else:
4304 else:
4171 key, value = fields
4305 key, value = fields
4172
4306
4173 if value.startswith(b'eval:'):
4307 if value.startswith(b'eval:'):
4174 value = stringutil.evalpythonliteral(value[5:])
4308 value = stringutil.evalpythonliteral(value[5:])
4175 else:
4309 else:
4176 value = stringutil.unescapestr(value)
4310 value = stringutil.unescapestr(value)
4177
4311
4178 args[key] = value
4312 args[key] = value
4179
4313
4180 if batchedcommands is not None:
4314 if batchedcommands is not None:
4181 batchedcommands.append((command, args))
4315 batchedcommands.append((command, args))
4182 continue
4316 continue
4183
4317
4184 ui.status(_(b'sending %s command\n') % command)
4318 ui.status(_(b'sending %s command\n') % command)
4185
4319
4186 if b'PUSHFILE' in args:
4320 if b'PUSHFILE' in args:
4187 with open(args[b'PUSHFILE'], 'rb') as fh:
4321 with open(args[b'PUSHFILE'], 'rb') as fh:
4188 del args[b'PUSHFILE']
4322 del args[b'PUSHFILE']
4189 res, output = peer._callpush(
4323 res, output = peer._callpush(
4190 command, fh, **pycompat.strkwargs(args)
4324 command, fh, **pycompat.strkwargs(args)
4191 )
4325 )
4192 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4326 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4193 ui.status(
4327 ui.status(
4194 _(b'remote output: %s\n') % stringutil.escapestr(output)
4328 _(b'remote output: %s\n') % stringutil.escapestr(output)
4195 )
4329 )
4196 else:
4330 else:
4197 with peer.commandexecutor() as e:
4331 with peer.commandexecutor() as e:
4198 res = e.callcommand(command, args).result()
4332 res = e.callcommand(command, args).result()
4199
4333
4200 if isinstance(res, wireprotov2peer.commandresponse):
4334 if isinstance(res, wireprotov2peer.commandresponse):
4201 val = res.objects()
4335 val = res.objects()
4202 ui.status(
4336 ui.status(
4203 _(b'response: %s\n')
4337 _(b'response: %s\n')
4204 % stringutil.pprint(val, bprefix=True, indent=2)
4338 % stringutil.pprint(val, bprefix=True, indent=2)
4205 )
4339 )
4206 else:
4340 else:
4207 ui.status(
4341 ui.status(
4208 _(b'response: %s\n')
4342 _(b'response: %s\n')
4209 % stringutil.pprint(res, bprefix=True, indent=2)
4343 % stringutil.pprint(res, bprefix=True, indent=2)
4210 )
4344 )
4211
4345
4212 elif action == b'batchbegin':
4346 elif action == b'batchbegin':
4213 if batchedcommands is not None:
4347 if batchedcommands is not None:
4214 raise error.Abort(_(b'nested batchbegin not allowed'))
4348 raise error.Abort(_(b'nested batchbegin not allowed'))
4215
4349
4216 batchedcommands = []
4350 batchedcommands = []
4217 elif action == b'batchsubmit':
4351 elif action == b'batchsubmit':
4218 # There is a batching API we could go through. But it would be
4352 # There is a batching API we could go through. But it would be
4219 # difficult to normalize requests into function calls. It is easier
4353 # difficult to normalize requests into function calls. It is easier
4220 # to bypass this layer and normalize to commands + args.
4354 # to bypass this layer and normalize to commands + args.
4221 ui.status(
4355 ui.status(
4222 _(b'sending batch with %d sub-commands\n')
4356 _(b'sending batch with %d sub-commands\n')
4223 % len(batchedcommands)
4357 % len(batchedcommands)
4224 )
4358 )
4225 assert peer is not None
4359 assert peer is not None
4226 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4360 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4227 ui.status(
4361 ui.status(
4228 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4362 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4229 )
4363 )
4230
4364
4231 batchedcommands = None
4365 batchedcommands = None
4232
4366
4233 elif action.startswith(b'httprequest '):
4367 elif action.startswith(b'httprequest '):
4234 if not opener:
4368 if not opener:
4235 raise error.Abort(
4369 raise error.Abort(
4236 _(b'cannot use httprequest without an HTTP peer')
4370 _(b'cannot use httprequest without an HTTP peer')
4237 )
4371 )
4238
4372
4239 request = action.split(b' ', 2)
4373 request = action.split(b' ', 2)
4240 if len(request) != 3:
4374 if len(request) != 3:
4241 raise error.Abort(
4375 raise error.Abort(
4242 _(
4376 _(
4243 b'invalid httprequest: expected format is '
4377 b'invalid httprequest: expected format is '
4244 b'"httprequest <method> <path>'
4378 b'"httprequest <method> <path>'
4245 )
4379 )
4246 )
4380 )
4247
4381
4248 method, httppath = request[1:]
4382 method, httppath = request[1:]
4249 headers = {}
4383 headers = {}
4250 body = None
4384 body = None
4251 frames = []
4385 frames = []
4252 for line in lines:
4386 for line in lines:
4253 line = line.lstrip()
4387 line = line.lstrip()
4254 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4388 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4255 if m:
4389 if m:
4256 # Headers need to use native strings.
4390 # Headers need to use native strings.
4257 key = pycompat.strurl(m.group(1))
4391 key = pycompat.strurl(m.group(1))
4258 value = pycompat.strurl(m.group(2))
4392 value = pycompat.strurl(m.group(2))
4259 headers[key] = value
4393 headers[key] = value
4260 continue
4394 continue
4261
4395
4262 if line.startswith(b'BODYFILE '):
4396 if line.startswith(b'BODYFILE '):
4263 with open(line.split(b' ', 1), b'rb') as fh:
4397 with open(line.split(b' ', 1), b'rb') as fh:
4264 body = fh.read()
4398 body = fh.read()
4265 elif line.startswith(b'frame '):
4399 elif line.startswith(b'frame '):
4266 frame = wireprotoframing.makeframefromhumanstring(
4400 frame = wireprotoframing.makeframefromhumanstring(
4267 line[len(b'frame ') :]
4401 line[len(b'frame ') :]
4268 )
4402 )
4269
4403
4270 frames.append(frame)
4404 frames.append(frame)
4271 else:
4405 else:
4272 raise error.Abort(
4406 raise error.Abort(
4273 _(b'unknown argument to httprequest: %s') % line
4407 _(b'unknown argument to httprequest: %s') % line
4274 )
4408 )
4275
4409
4276 url = path + httppath
4410 url = path + httppath
4277
4411
4278 if frames:
4412 if frames:
4279 body = b''.join(bytes(f) for f in frames)
4413 body = b''.join(bytes(f) for f in frames)
4280
4414
4281 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4415 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4282
4416
4283 # urllib.Request insists on using has_data() as a proxy for
4417 # urllib.Request insists on using has_data() as a proxy for
4284 # determining the request method. Override that to use our
4418 # determining the request method. Override that to use our
4285 # explicitly requested method.
4419 # explicitly requested method.
4286 req.get_method = lambda: pycompat.sysstr(method)
4420 req.get_method = lambda: pycompat.sysstr(method)
4287
4421
4288 try:
4422 try:
4289 res = opener.open(req)
4423 res = opener.open(req)
4290 body = res.read()
4424 body = res.read()
4291 except util.urlerr.urlerror as e:
4425 except util.urlerr.urlerror as e:
4292 # read() method must be called, but only exists in Python 2
4426 # read() method must be called, but only exists in Python 2
4293 getattr(e, 'read', lambda: None)()
4427 getattr(e, 'read', lambda: None)()
4294 continue
4428 continue
4295
4429
4296 ct = res.headers.get('Content-Type')
4430 ct = res.headers.get('Content-Type')
4297 if ct == 'application/mercurial-cbor':
4431 if ct == 'application/mercurial-cbor':
4298 ui.write(
4432 ui.write(
4299 _(b'cbor> %s\n')
4433 _(b'cbor> %s\n')
4300 % stringutil.pprint(
4434 % stringutil.pprint(
4301 cborutil.decodeall(body), bprefix=True, indent=2
4435 cborutil.decodeall(body), bprefix=True, indent=2
4302 )
4436 )
4303 )
4437 )
4304
4438
4305 elif action == b'close':
4439 elif action == b'close':
4306 assert peer is not None
4440 assert peer is not None
4307 peer.close()
4441 peer.close()
4308 elif action == b'readavailable':
4442 elif action == b'readavailable':
4309 if not stdout or not stderr:
4443 if not stdout or not stderr:
4310 raise error.Abort(
4444 raise error.Abort(
4311 _(b'readavailable not available on this peer')
4445 _(b'readavailable not available on this peer')
4312 )
4446 )
4313
4447
4314 stdin.close()
4448 stdin.close()
4315 stdout.read()
4449 stdout.read()
4316 stderr.read()
4450 stderr.read()
4317
4451
4318 elif action == b'readline':
4452 elif action == b'readline':
4319 if not stdout:
4453 if not stdout:
4320 raise error.Abort(_(b'readline not available on this peer'))
4454 raise error.Abort(_(b'readline not available on this peer'))
4321 stdout.readline()
4455 stdout.readline()
4322 elif action == b'ereadline':
4456 elif action == b'ereadline':
4323 if not stderr:
4457 if not stderr:
4324 raise error.Abort(_(b'ereadline not available on this peer'))
4458 raise error.Abort(_(b'ereadline not available on this peer'))
4325 stderr.readline()
4459 stderr.readline()
4326 elif action.startswith(b'read '):
4460 elif action.startswith(b'read '):
4327 count = int(action.split(b' ', 1)[1])
4461 count = int(action.split(b' ', 1)[1])
4328 if not stdout:
4462 if not stdout:
4329 raise error.Abort(_(b'read not available on this peer'))
4463 raise error.Abort(_(b'read not available on this peer'))
4330 stdout.read(count)
4464 stdout.read(count)
4331 elif action.startswith(b'eread '):
4465 elif action.startswith(b'eread '):
4332 count = int(action.split(b' ', 1)[1])
4466 count = int(action.split(b' ', 1)[1])
4333 if not stderr:
4467 if not stderr:
4334 raise error.Abort(_(b'eread not available on this peer'))
4468 raise error.Abort(_(b'eread not available on this peer'))
4335 stderr.read(count)
4469 stderr.read(count)
4336 else:
4470 else:
4337 raise error.Abort(_(b'unknown action: %s') % action)
4471 raise error.Abort(_(b'unknown action: %s') % action)
4338
4472
4339 if batchedcommands is not None:
4473 if batchedcommands is not None:
4340 raise error.Abort(_(b'unclosed "batchbegin" request'))
4474 raise error.Abort(_(b'unclosed "batchbegin" request'))
4341
4475
4342 if peer:
4476 if peer:
4343 peer.close()
4477 peer.close()
4344
4478
4345 if proc:
4479 if proc:
4346 proc.kill()
4480 proc.kill()
@@ -1,429 +1,431 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 abort
4 add
4 add
5 addremove
5 addremove
6 annotate
6 annotate
7 archive
7 archive
8 backout
8 backout
9 bisect
9 bisect
10 bookmarks
10 bookmarks
11 branch
11 branch
12 branches
12 branches
13 bundle
13 bundle
14 cat
14 cat
15 clone
15 clone
16 commit
16 commit
17 config
17 config
18 continue
18 continue
19 copy
19 copy
20 diff
20 diff
21 export
21 export
22 files
22 files
23 forget
23 forget
24 graft
24 graft
25 grep
25 grep
26 heads
26 heads
27 help
27 help
28 identify
28 identify
29 import
29 import
30 incoming
30 incoming
31 init
31 init
32 locate
32 locate
33 log
33 log
34 manifest
34 manifest
35 merge
35 merge
36 outgoing
36 outgoing
37 parents
37 parents
38 paths
38 paths
39 phase
39 phase
40 pull
40 pull
41 push
41 push
42 recover
42 recover
43 remove
43 remove
44 rename
44 rename
45 resolve
45 resolve
46 revert
46 revert
47 rollback
47 rollback
48 root
48 root
49 serve
49 serve
50 shelve
50 shelve
51 status
51 status
52 summary
52 summary
53 tag
53 tag
54 tags
54 tags
55 tip
55 tip
56 unbundle
56 unbundle
57 unshelve
57 unshelve
58 update
58 update
59 verify
59 verify
60 version
60 version
61
61
62 Show all commands that start with "a"
62 Show all commands that start with "a"
63 $ hg debugcomplete a
63 $ hg debugcomplete a
64 abort
64 abort
65 add
65 add
66 addremove
66 addremove
67 annotate
67 annotate
68 archive
68 archive
69
69
70 Do not show debug commands if there are other candidates
70 Do not show debug commands if there are other candidates
71 $ hg debugcomplete d
71 $ hg debugcomplete d
72 diff
72 diff
73
73
74 Show debug commands if there are no other candidates
74 Show debug commands if there are no other candidates
75 $ hg debugcomplete debug
75 $ hg debugcomplete debug
76 debugancestor
76 debugancestor
77 debugapplystreamclonebundle
77 debugapplystreamclonebundle
78 debugbackupbundle
78 debugbuilddag
79 debugbuilddag
79 debugbundle
80 debugbundle
80 debugcapabilities
81 debugcapabilities
81 debugcheckstate
82 debugcheckstate
82 debugcolor
83 debugcolor
83 debugcommands
84 debugcommands
84 debugcomplete
85 debugcomplete
85 debugconfig
86 debugconfig
86 debugcreatestreamclonebundle
87 debugcreatestreamclonebundle
87 debugdag
88 debugdag
88 debugdata
89 debugdata
89 debugdate
90 debugdate
90 debugdeltachain
91 debugdeltachain
91 debugdirstate
92 debugdirstate
92 debugdiscovery
93 debugdiscovery
93 debugdownload
94 debugdownload
94 debugextensions
95 debugextensions
95 debugfileset
96 debugfileset
96 debugformat
97 debugformat
97 debugfsinfo
98 debugfsinfo
98 debuggetbundle
99 debuggetbundle
99 debugignore
100 debugignore
100 debugindex
101 debugindex
101 debugindexdot
102 debugindexdot
102 debugindexstats
103 debugindexstats
103 debuginstall
104 debuginstall
104 debugknown
105 debugknown
105 debuglabelcomplete
106 debuglabelcomplete
106 debuglocks
107 debuglocks
107 debugmanifestfulltextcache
108 debugmanifestfulltextcache
108 debugmergestate
109 debugmergestate
109 debugnamecomplete
110 debugnamecomplete
110 debugnodemap
111 debugnodemap
111 debugobsolete
112 debugobsolete
112 debugp1copies
113 debugp1copies
113 debugp2copies
114 debugp2copies
114 debugpathcomplete
115 debugpathcomplete
115 debugpathcopies
116 debugpathcopies
116 debugpeer
117 debugpeer
117 debugpickmergetool
118 debugpickmergetool
118 debugpushkey
119 debugpushkey
119 debugpvec
120 debugpvec
120 debugrebuilddirstate
121 debugrebuilddirstate
121 debugrebuildfncache
122 debugrebuildfncache
122 debugrename
123 debugrename
123 debugrevlog
124 debugrevlog
124 debugrevlogindex
125 debugrevlogindex
125 debugrevspec
126 debugrevspec
126 debugserve
127 debugserve
127 debugsetparents
128 debugsetparents
128 debugsidedata
129 debugsidedata
129 debugssl
130 debugssl
130 debugsub
131 debugsub
131 debugsuccessorssets
132 debugsuccessorssets
132 debugtagscache
133 debugtagscache
133 debugtemplate
134 debugtemplate
134 debuguigetpass
135 debuguigetpass
135 debuguiprompt
136 debuguiprompt
136 debugupdatecaches
137 debugupdatecaches
137 debugupgraderepo
138 debugupgraderepo
138 debugwalk
139 debugwalk
139 debugwhyunstable
140 debugwhyunstable
140 debugwireargs
141 debugwireargs
141 debugwireproto
142 debugwireproto
142
143
143 Do not show the alias of a debug command if there are other candidates
144 Do not show the alias of a debug command if there are other candidates
144 (this should hide rawcommit)
145 (this should hide rawcommit)
145 $ hg debugcomplete r
146 $ hg debugcomplete r
146 recover
147 recover
147 remove
148 remove
148 rename
149 rename
149 resolve
150 resolve
150 revert
151 revert
151 rollback
152 rollback
152 root
153 root
153 Show the alias of a debug command if there are no other candidates
154 Show the alias of a debug command if there are no other candidates
154 $ hg debugcomplete rawc
155 $ hg debugcomplete rawc
155
156
156
157
157 Show the global options
158 Show the global options
158 $ hg debugcomplete --options | sort
159 $ hg debugcomplete --options | sort
159 --color
160 --color
160 --config
161 --config
161 --cwd
162 --cwd
162 --debug
163 --debug
163 --debugger
164 --debugger
164 --encoding
165 --encoding
165 --encodingmode
166 --encodingmode
166 --help
167 --help
167 --hidden
168 --hidden
168 --noninteractive
169 --noninteractive
169 --pager
170 --pager
170 --profile
171 --profile
171 --quiet
172 --quiet
172 --repository
173 --repository
173 --time
174 --time
174 --traceback
175 --traceback
175 --verbose
176 --verbose
176 --version
177 --version
177 -R
178 -R
178 -h
179 -h
179 -q
180 -q
180 -v
181 -v
181 -y
182 -y
182
183
183 Show the options for the "serve" command
184 Show the options for the "serve" command
184 $ hg debugcomplete --options serve | sort
185 $ hg debugcomplete --options serve | sort
185 --accesslog
186 --accesslog
186 --address
187 --address
187 --certificate
188 --certificate
188 --cmdserver
189 --cmdserver
189 --color
190 --color
190 --config
191 --config
191 --cwd
192 --cwd
192 --daemon
193 --daemon
193 --daemon-postexec
194 --daemon-postexec
194 --debug
195 --debug
195 --debugger
196 --debugger
196 --encoding
197 --encoding
197 --encodingmode
198 --encodingmode
198 --errorlog
199 --errorlog
199 --help
200 --help
200 --hidden
201 --hidden
201 --ipv6
202 --ipv6
202 --name
203 --name
203 --noninteractive
204 --noninteractive
204 --pager
205 --pager
205 --pid-file
206 --pid-file
206 --port
207 --port
207 --prefix
208 --prefix
208 --print-url
209 --print-url
209 --profile
210 --profile
210 --quiet
211 --quiet
211 --repository
212 --repository
212 --stdio
213 --stdio
213 --style
214 --style
214 --subrepos
215 --subrepos
215 --templates
216 --templates
216 --time
217 --time
217 --traceback
218 --traceback
218 --verbose
219 --verbose
219 --version
220 --version
220 --web-conf
221 --web-conf
221 -6
222 -6
222 -A
223 -A
223 -E
224 -E
224 -R
225 -R
225 -S
226 -S
226 -a
227 -a
227 -d
228 -d
228 -h
229 -h
229 -n
230 -n
230 -p
231 -p
231 -q
232 -q
232 -t
233 -t
233 -v
234 -v
234 -y
235 -y
235
236
236 Show an error if we use --options with an ambiguous abbreviation
237 Show an error if we use --options with an ambiguous abbreviation
237 $ hg debugcomplete --options s
238 $ hg debugcomplete --options s
238 hg: command 's' is ambiguous:
239 hg: command 's' is ambiguous:
239 serve shelve showconfig status summary
240 serve shelve showconfig status summary
240 [255]
241 [255]
241
242
242 Show all commands + options
243 Show all commands + options
243 $ hg debugcommands
244 $ hg debugcommands
244 abort: dry-run
245 abort: dry-run
245 add: include, exclude, subrepos, dry-run
246 add: include, exclude, subrepos, dry-run
246 addremove: similarity, subrepos, include, exclude, dry-run
247 addremove: similarity, subrepos, include, exclude, dry-run
247 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
248 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
248 archive: no-decode, prefix, rev, type, subrepos, include, exclude
249 archive: no-decode, prefix, rev, type, subrepos, include, exclude
249 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
250 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
250 bisect: reset, good, bad, skip, extend, command, noupdate
251 bisect: reset, good, bad, skip, extend, command, noupdate
251 bookmarks: force, rev, delete, rename, inactive, list, template
252 bookmarks: force, rev, delete, rename, inactive, list, template
252 branch: force, clean, rev
253 branch: force, clean, rev
253 branches: active, closed, rev, template
254 branches: active, closed, rev, template
254 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
255 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
255 cat: output, rev, decode, include, exclude, template
256 cat: output, rev, decode, include, exclude, template
256 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
257 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
257 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
258 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
258 config: untrusted, edit, local, global, template
259 config: untrusted, edit, local, global, template
259 continue: dry-run
260 continue: dry-run
260 copy: forget, after, at-rev, force, include, exclude, dry-run
261 copy: forget, after, at-rev, force, include, exclude, dry-run
261 debugancestor:
262 debugancestor:
262 debugapplystreamclonebundle:
263 debugapplystreamclonebundle:
264 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
263 debugbuilddag: mergeable-file, overwritten-file, new-file
265 debugbuilddag: mergeable-file, overwritten-file, new-file
264 debugbundle: all, part-type, spec
266 debugbundle: all, part-type, spec
265 debugcapabilities:
267 debugcapabilities:
266 debugcheckstate:
268 debugcheckstate:
267 debugcolor: style
269 debugcolor: style
268 debugcommands:
270 debugcommands:
269 debugcomplete: options
271 debugcomplete: options
270 debugcreatestreamclonebundle:
272 debugcreatestreamclonebundle:
271 debugdag: tags, branches, dots, spaces
273 debugdag: tags, branches, dots, spaces
272 debugdata: changelog, manifest, dir
274 debugdata: changelog, manifest, dir
273 debugdate: extended
275 debugdate: extended
274 debugdeltachain: changelog, manifest, dir, template
276 debugdeltachain: changelog, manifest, dir, template
275 debugdirstate: nodates, dates, datesort
277 debugdirstate: nodates, dates, datesort
276 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
278 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
277 debugdownload: output
279 debugdownload: output
278 debugextensions: template
280 debugextensions: template
279 debugfileset: rev, all-files, show-matcher, show-stage
281 debugfileset: rev, all-files, show-matcher, show-stage
280 debugformat: template
282 debugformat: template
281 debugfsinfo:
283 debugfsinfo:
282 debuggetbundle: head, common, type
284 debuggetbundle: head, common, type
283 debugignore:
285 debugignore:
284 debugindex: changelog, manifest, dir, template
286 debugindex: changelog, manifest, dir, template
285 debugindexdot: changelog, manifest, dir
287 debugindexdot: changelog, manifest, dir
286 debugindexstats:
288 debugindexstats:
287 debuginstall: template
289 debuginstall: template
288 debugknown:
290 debugknown:
289 debuglabelcomplete:
291 debuglabelcomplete:
290 debuglocks: force-lock, force-wlock, set-lock, set-wlock
292 debuglocks: force-lock, force-wlock, set-lock, set-wlock
291 debugmanifestfulltextcache: clear, add
293 debugmanifestfulltextcache: clear, add
292 debugmergestate: style, template
294 debugmergestate: style, template
293 debugnamecomplete:
295 debugnamecomplete:
294 debugnodemap: dump-new, dump-disk, check, metadata
296 debugnodemap: dump-new, dump-disk, check, metadata
295 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
297 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
296 debugp1copies: rev
298 debugp1copies: rev
297 debugp2copies: rev
299 debugp2copies: rev
298 debugpathcomplete: full, normal, added, removed
300 debugpathcomplete: full, normal, added, removed
299 debugpathcopies: include, exclude
301 debugpathcopies: include, exclude
300 debugpeer:
302 debugpeer:
301 debugpickmergetool: rev, changedelete, include, exclude, tool
303 debugpickmergetool: rev, changedelete, include, exclude, tool
302 debugpushkey:
304 debugpushkey:
303 debugpvec:
305 debugpvec:
304 debugrebuilddirstate: rev, minimal
306 debugrebuilddirstate: rev, minimal
305 debugrebuildfncache:
307 debugrebuildfncache:
306 debugrename: rev
308 debugrename: rev
307 debugrevlog: changelog, manifest, dir, dump
309 debugrevlog: changelog, manifest, dir, dump
308 debugrevlogindex: changelog, manifest, dir, format
310 debugrevlogindex: changelog, manifest, dir, format
309 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
311 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
310 debugserve: sshstdio, logiofd, logiofile
312 debugserve: sshstdio, logiofd, logiofile
311 debugsetparents:
313 debugsetparents:
312 debugsidedata: changelog, manifest, dir
314 debugsidedata: changelog, manifest, dir
313 debugssl:
315 debugssl:
314 debugsub: rev
316 debugsub: rev
315 debugsuccessorssets: closest
317 debugsuccessorssets: closest
316 debugtagscache:
318 debugtagscache:
317 debugtemplate: rev, define
319 debugtemplate: rev, define
318 debuguigetpass: prompt
320 debuguigetpass: prompt
319 debuguiprompt: prompt
321 debuguiprompt: prompt
320 debugupdatecaches:
322 debugupdatecaches:
321 debugupgraderepo: optimize, run, backup, changelog, manifest
323 debugupgraderepo: optimize, run, backup, changelog, manifest
322 debugwalk: include, exclude
324 debugwalk: include, exclude
323 debugwhyunstable:
325 debugwhyunstable:
324 debugwireargs: three, four, five, ssh, remotecmd, insecure
326 debugwireargs: three, four, five, ssh, remotecmd, insecure
325 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
327 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
326 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
328 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
327 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
329 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
328 files: rev, print0, include, exclude, template, subrepos
330 files: rev, print0, include, exclude, template, subrepos
329 forget: interactive, include, exclude, dry-run
331 forget: interactive, include, exclude, dry-run
330 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
332 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
331 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
333 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
332 heads: rev, topo, active, closed, style, template
334 heads: rev, topo, active, closed, style, template
333 help: extension, command, keyword, system
335 help: extension, command, keyword, system
334 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
336 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
335 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
337 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
336 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
338 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
337 init: ssh, remotecmd, insecure
339 init: ssh, remotecmd, insecure
338 locate: rev, print0, fullpath, include, exclude
340 locate: rev, print0, fullpath, include, exclude
339 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
341 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
340 manifest: rev, all, template
342 manifest: rev, all, template
341 merge: force, rev, preview, abort, tool
343 merge: force, rev, preview, abort, tool
342 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
344 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
343 parents: rev, style, template
345 parents: rev, style, template
344 paths: template
346 paths: template
345 phase: public, draft, secret, force, rev
347 phase: public, draft, secret, force, rev
346 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
348 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
347 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
349 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
348 recover: verify
350 recover: verify
349 remove: after, force, subrepos, include, exclude, dry-run
351 remove: after, force, subrepos, include, exclude, dry-run
350 rename: after, force, include, exclude, dry-run
352 rename: after, force, include, exclude, dry-run
351 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
353 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
352 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
354 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
353 rollback: dry-run, force
355 rollback: dry-run, force
354 root: template
356 root: template
355 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
357 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
356 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
358 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
357 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
359 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
358 summary: remote
360 summary: remote
359 tag: force, local, rev, remove, edit, message, date, user
361 tag: force, local, rev, remove, edit, message, date, user
360 tags: template
362 tags: template
361 tip: patch, git, style, template
363 tip: patch, git, style, template
362 unbundle: update
364 unbundle: update
363 unshelve: abort, continue, interactive, keep, name, tool, date
365 unshelve: abort, continue, interactive, keep, name, tool, date
364 update: clean, check, merge, date, rev, tool
366 update: clean, check, merge, date, rev, tool
365 verify: full
367 verify: full
366 version: template
368 version: template
367
369
368 $ hg init a
370 $ hg init a
369 $ cd a
371 $ cd a
370 $ echo fee > fee
372 $ echo fee > fee
371 $ hg ci -q -Amfee
373 $ hg ci -q -Amfee
372 $ hg tag fee
374 $ hg tag fee
373 $ mkdir fie
375 $ mkdir fie
374 $ echo dead > fie/dead
376 $ echo dead > fie/dead
375 $ echo live > fie/live
377 $ echo live > fie/live
376 $ hg bookmark fo
378 $ hg bookmark fo
377 $ hg branch -q fie
379 $ hg branch -q fie
378 $ hg ci -q -Amfie
380 $ hg ci -q -Amfie
379 $ echo fo > fo
381 $ echo fo > fo
380 $ hg branch -qf default
382 $ hg branch -qf default
381 $ hg ci -q -Amfo
383 $ hg ci -q -Amfo
382 $ echo Fum > Fum
384 $ echo Fum > Fum
383 $ hg ci -q -AmFum
385 $ hg ci -q -AmFum
384 $ hg bookmark Fum
386 $ hg bookmark Fum
385
387
386 Test debugpathcomplete
388 Test debugpathcomplete
387
389
388 $ hg debugpathcomplete f
390 $ hg debugpathcomplete f
389 fee
391 fee
390 fie
392 fie
391 fo
393 fo
392 $ hg debugpathcomplete -f f
394 $ hg debugpathcomplete -f f
393 fee
395 fee
394 fie/dead
396 fie/dead
395 fie/live
397 fie/live
396 fo
398 fo
397
399
398 $ hg rm Fum
400 $ hg rm Fum
399 $ hg debugpathcomplete -r F
401 $ hg debugpathcomplete -r F
400 Fum
402 Fum
401
403
402 Test debugnamecomplete
404 Test debugnamecomplete
403
405
404 $ hg debugnamecomplete
406 $ hg debugnamecomplete
405 Fum
407 Fum
406 default
408 default
407 fee
409 fee
408 fie
410 fie
409 fo
411 fo
410 tip
412 tip
411 $ hg debugnamecomplete f
413 $ hg debugnamecomplete f
412 fee
414 fee
413 fie
415 fie
414 fo
416 fo
415
417
416 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
418 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
417 used for completions in some shells.
419 used for completions in some shells.
418
420
419 $ hg debuglabelcomplete
421 $ hg debuglabelcomplete
420 Fum
422 Fum
421 default
423 default
422 fee
424 fee
423 fie
425 fie
424 fo
426 fo
425 tip
427 tip
426 $ hg debuglabelcomplete f
428 $ hg debuglabelcomplete f
427 fee
429 fee
428 fie
430 fie
429 fo
431 fo
@@ -1,3903 +1,3905 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 Extra extensions will be printed in help output in a non-reliable order since
47 Extra extensions will be printed in help output in a non-reliable order since
48 the extension is unknown.
48 the extension is unknown.
49 #if no-extraextensions
49 #if no-extraextensions
50
50
51 $ hg help
51 $ hg help
52 Mercurial Distributed SCM
52 Mercurial Distributed SCM
53
53
54 list of commands:
54 list of commands:
55
55
56 Repository creation:
56 Repository creation:
57
57
58 clone make a copy of an existing repository
58 clone make a copy of an existing repository
59 init create a new repository in the given directory
59 init create a new repository in the given directory
60
60
61 Remote repository management:
61 Remote repository management:
62
62
63 incoming show new changesets found in source
63 incoming show new changesets found in source
64 outgoing show changesets not found in the destination
64 outgoing show changesets not found in the destination
65 paths show aliases for remote repositories
65 paths show aliases for remote repositories
66 pull pull changes from the specified source
66 pull pull changes from the specified source
67 push push changes to the specified destination
67 push push changes to the specified destination
68 serve start stand-alone webserver
68 serve start stand-alone webserver
69
69
70 Change creation:
70 Change creation:
71
71
72 commit commit the specified files or all outstanding changes
72 commit commit the specified files or all outstanding changes
73
73
74 Change manipulation:
74 Change manipulation:
75
75
76 backout reverse effect of earlier changeset
76 backout reverse effect of earlier changeset
77 graft copy changes from other branches onto the current branch
77 graft copy changes from other branches onto the current branch
78 merge merge another revision into working directory
78 merge merge another revision into working directory
79
79
80 Change organization:
80 Change organization:
81
81
82 bookmarks create a new bookmark or list existing bookmarks
82 bookmarks create a new bookmark or list existing bookmarks
83 branch set or show the current branch name
83 branch set or show the current branch name
84 branches list repository named branches
84 branches list repository named branches
85 phase set or show the current phase name
85 phase set or show the current phase name
86 tag add one or more tags for the current or given revision
86 tag add one or more tags for the current or given revision
87 tags list repository tags
87 tags list repository tags
88
88
89 File content management:
89 File content management:
90
90
91 annotate show changeset information by line for each file
91 annotate show changeset information by line for each file
92 cat output the current or given revision of files
92 cat output the current or given revision of files
93 copy mark files as copied for the next commit
93 copy mark files as copied for the next commit
94 diff diff repository (or selected files)
94 diff diff repository (or selected files)
95 grep search for a pattern in specified files
95 grep search for a pattern in specified files
96
96
97 Change navigation:
97 Change navigation:
98
98
99 bisect subdivision search of changesets
99 bisect subdivision search of changesets
100 heads show branch heads
100 heads show branch heads
101 identify identify the working directory or specified revision
101 identify identify the working directory or specified revision
102 log show revision history of entire repository or files
102 log show revision history of entire repository or files
103
103
104 Working directory management:
104 Working directory management:
105
105
106 add add the specified files on the next commit
106 add add the specified files on the next commit
107 addremove add all new files, delete all missing files
107 addremove add all new files, delete all missing files
108 files list tracked files
108 files list tracked files
109 forget forget the specified files on the next commit
109 forget forget the specified files on the next commit
110 remove remove the specified files on the next commit
110 remove remove the specified files on the next commit
111 rename rename files; equivalent of copy + remove
111 rename rename files; equivalent of copy + remove
112 resolve redo merges or set/view the merge status of files
112 resolve redo merges or set/view the merge status of files
113 revert restore files to their checkout state
113 revert restore files to their checkout state
114 root print the root (top) of the current working directory
114 root print the root (top) of the current working directory
115 shelve save and set aside changes from the working directory
115 shelve save and set aside changes from the working directory
116 status show changed files in the working directory
116 status show changed files in the working directory
117 summary summarize working directory state
117 summary summarize working directory state
118 unshelve restore a shelved change to the working directory
118 unshelve restore a shelved change to the working directory
119 update update working directory (or switch revisions)
119 update update working directory (or switch revisions)
120
120
121 Change import/export:
121 Change import/export:
122
122
123 archive create an unversioned archive of a repository revision
123 archive create an unversioned archive of a repository revision
124 bundle create a bundle file
124 bundle create a bundle file
125 export dump the header and diffs for one or more changesets
125 export dump the header and diffs for one or more changesets
126 import import an ordered set of patches
126 import import an ordered set of patches
127 unbundle apply one or more bundle files
127 unbundle apply one or more bundle files
128
128
129 Repository maintenance:
129 Repository maintenance:
130
130
131 manifest output the current or given revision of the project manifest
131 manifest output the current or given revision of the project manifest
132 recover roll back an interrupted transaction
132 recover roll back an interrupted transaction
133 verify verify the integrity of the repository
133 verify verify the integrity of the repository
134
134
135 Help:
135 Help:
136
136
137 config show combined config settings from all hgrc files
137 config show combined config settings from all hgrc files
138 help show help for a given topic or a help overview
138 help show help for a given topic or a help overview
139 version output version and copyright information
139 version output version and copyright information
140
140
141 additional help topics:
141 additional help topics:
142
142
143 Mercurial identifiers:
143 Mercurial identifiers:
144
144
145 filesets Specifying File Sets
145 filesets Specifying File Sets
146 hgignore Syntax for Mercurial Ignore Files
146 hgignore Syntax for Mercurial Ignore Files
147 patterns File Name Patterns
147 patterns File Name Patterns
148 revisions Specifying Revisions
148 revisions Specifying Revisions
149 urls URL Paths
149 urls URL Paths
150
150
151 Mercurial output:
151 Mercurial output:
152
152
153 color Colorizing Outputs
153 color Colorizing Outputs
154 dates Date Formats
154 dates Date Formats
155 diffs Diff Formats
155 diffs Diff Formats
156 templating Template Usage
156 templating Template Usage
157
157
158 Mercurial configuration:
158 Mercurial configuration:
159
159
160 config Configuration Files
160 config Configuration Files
161 environment Environment Variables
161 environment Environment Variables
162 extensions Using Additional Features
162 extensions Using Additional Features
163 flags Command-line flags
163 flags Command-line flags
164 hgweb Configuring hgweb
164 hgweb Configuring hgweb
165 merge-tools Merge Tools
165 merge-tools Merge Tools
166 pager Pager Support
166 pager Pager Support
167
167
168 Concepts:
168 Concepts:
169
169
170 bundlespec Bundle File Formats
170 bundlespec Bundle File Formats
171 glossary Glossary
171 glossary Glossary
172 phases Working with Phases
172 phases Working with Phases
173 subrepos Subrepositories
173 subrepos Subrepositories
174
174
175 Miscellaneous:
175 Miscellaneous:
176
176
177 deprecated Deprecated Features
177 deprecated Deprecated Features
178 internals Technical implementation topics
178 internals Technical implementation topics
179 scripting Using Mercurial from scripts and automation
179 scripting Using Mercurial from scripts and automation
180
180
181 (use 'hg help -v' to show built-in aliases and global options)
181 (use 'hg help -v' to show built-in aliases and global options)
182
182
183 $ hg -q help
183 $ hg -q help
184 Repository creation:
184 Repository creation:
185
185
186 clone make a copy of an existing repository
186 clone make a copy of an existing repository
187 init create a new repository in the given directory
187 init create a new repository in the given directory
188
188
189 Remote repository management:
189 Remote repository management:
190
190
191 incoming show new changesets found in source
191 incoming show new changesets found in source
192 outgoing show changesets not found in the destination
192 outgoing show changesets not found in the destination
193 paths show aliases for remote repositories
193 paths show aliases for remote repositories
194 pull pull changes from the specified source
194 pull pull changes from the specified source
195 push push changes to the specified destination
195 push push changes to the specified destination
196 serve start stand-alone webserver
196 serve start stand-alone webserver
197
197
198 Change creation:
198 Change creation:
199
199
200 commit commit the specified files or all outstanding changes
200 commit commit the specified files or all outstanding changes
201
201
202 Change manipulation:
202 Change manipulation:
203
203
204 backout reverse effect of earlier changeset
204 backout reverse effect of earlier changeset
205 graft copy changes from other branches onto the current branch
205 graft copy changes from other branches onto the current branch
206 merge merge another revision into working directory
206 merge merge another revision into working directory
207
207
208 Change organization:
208 Change organization:
209
209
210 bookmarks create a new bookmark or list existing bookmarks
210 bookmarks create a new bookmark or list existing bookmarks
211 branch set or show the current branch name
211 branch set or show the current branch name
212 branches list repository named branches
212 branches list repository named branches
213 phase set or show the current phase name
213 phase set or show the current phase name
214 tag add one or more tags for the current or given revision
214 tag add one or more tags for the current or given revision
215 tags list repository tags
215 tags list repository tags
216
216
217 File content management:
217 File content management:
218
218
219 annotate show changeset information by line for each file
219 annotate show changeset information by line for each file
220 cat output the current or given revision of files
220 cat output the current or given revision of files
221 copy mark files as copied for the next commit
221 copy mark files as copied for the next commit
222 diff diff repository (or selected files)
222 diff diff repository (or selected files)
223 grep search for a pattern in specified files
223 grep search for a pattern in specified files
224
224
225 Change navigation:
225 Change navigation:
226
226
227 bisect subdivision search of changesets
227 bisect subdivision search of changesets
228 heads show branch heads
228 heads show branch heads
229 identify identify the working directory or specified revision
229 identify identify the working directory or specified revision
230 log show revision history of entire repository or files
230 log show revision history of entire repository or files
231
231
232 Working directory management:
232 Working directory management:
233
233
234 add add the specified files on the next commit
234 add add the specified files on the next commit
235 addremove add all new files, delete all missing files
235 addremove add all new files, delete all missing files
236 files list tracked files
236 files list tracked files
237 forget forget the specified files on the next commit
237 forget forget the specified files on the next commit
238 remove remove the specified files on the next commit
238 remove remove the specified files on the next commit
239 rename rename files; equivalent of copy + remove
239 rename rename files; equivalent of copy + remove
240 resolve redo merges or set/view the merge status of files
240 resolve redo merges or set/view the merge status of files
241 revert restore files to their checkout state
241 revert restore files to their checkout state
242 root print the root (top) of the current working directory
242 root print the root (top) of the current working directory
243 shelve save and set aside changes from the working directory
243 shelve save and set aside changes from the working directory
244 status show changed files in the working directory
244 status show changed files in the working directory
245 summary summarize working directory state
245 summary summarize working directory state
246 unshelve restore a shelved change to the working directory
246 unshelve restore a shelved change to the working directory
247 update update working directory (or switch revisions)
247 update update working directory (or switch revisions)
248
248
249 Change import/export:
249 Change import/export:
250
250
251 archive create an unversioned archive of a repository revision
251 archive create an unversioned archive of a repository revision
252 bundle create a bundle file
252 bundle create a bundle file
253 export dump the header and diffs for one or more changesets
253 export dump the header and diffs for one or more changesets
254 import import an ordered set of patches
254 import import an ordered set of patches
255 unbundle apply one or more bundle files
255 unbundle apply one or more bundle files
256
256
257 Repository maintenance:
257 Repository maintenance:
258
258
259 manifest output the current or given revision of the project manifest
259 manifest output the current or given revision of the project manifest
260 recover roll back an interrupted transaction
260 recover roll back an interrupted transaction
261 verify verify the integrity of the repository
261 verify verify the integrity of the repository
262
262
263 Help:
263 Help:
264
264
265 config show combined config settings from all hgrc files
265 config show combined config settings from all hgrc files
266 help show help for a given topic or a help overview
266 help show help for a given topic or a help overview
267 version output version and copyright information
267 version output version and copyright information
268
268
269 additional help topics:
269 additional help topics:
270
270
271 Mercurial identifiers:
271 Mercurial identifiers:
272
272
273 filesets Specifying File Sets
273 filesets Specifying File Sets
274 hgignore Syntax for Mercurial Ignore Files
274 hgignore Syntax for Mercurial Ignore Files
275 patterns File Name Patterns
275 patterns File Name Patterns
276 revisions Specifying Revisions
276 revisions Specifying Revisions
277 urls URL Paths
277 urls URL Paths
278
278
279 Mercurial output:
279 Mercurial output:
280
280
281 color Colorizing Outputs
281 color Colorizing Outputs
282 dates Date Formats
282 dates Date Formats
283 diffs Diff Formats
283 diffs Diff Formats
284 templating Template Usage
284 templating Template Usage
285
285
286 Mercurial configuration:
286 Mercurial configuration:
287
287
288 config Configuration Files
288 config Configuration Files
289 environment Environment Variables
289 environment Environment Variables
290 extensions Using Additional Features
290 extensions Using Additional Features
291 flags Command-line flags
291 flags Command-line flags
292 hgweb Configuring hgweb
292 hgweb Configuring hgweb
293 merge-tools Merge Tools
293 merge-tools Merge Tools
294 pager Pager Support
294 pager Pager Support
295
295
296 Concepts:
296 Concepts:
297
297
298 bundlespec Bundle File Formats
298 bundlespec Bundle File Formats
299 glossary Glossary
299 glossary Glossary
300 phases Working with Phases
300 phases Working with Phases
301 subrepos Subrepositories
301 subrepos Subrepositories
302
302
303 Miscellaneous:
303 Miscellaneous:
304
304
305 deprecated Deprecated Features
305 deprecated Deprecated Features
306 internals Technical implementation topics
306 internals Technical implementation topics
307 scripting Using Mercurial from scripts and automation
307 scripting Using Mercurial from scripts and automation
308
308
309 Test extension help:
309 Test extension help:
310 $ hg help extensions --config extensions.rebase= --config extensions.children=
310 $ hg help extensions --config extensions.rebase= --config extensions.children=
311 Using Additional Features
311 Using Additional Features
312 """""""""""""""""""""""""
312 """""""""""""""""""""""""
313
313
314 Mercurial has the ability to add new features through the use of
314 Mercurial has the ability to add new features through the use of
315 extensions. Extensions may add new commands, add options to existing
315 extensions. Extensions may add new commands, add options to existing
316 commands, change the default behavior of commands, or implement hooks.
316 commands, change the default behavior of commands, or implement hooks.
317
317
318 To enable the "foo" extension, either shipped with Mercurial or in the
318 To enable the "foo" extension, either shipped with Mercurial or in the
319 Python search path, create an entry for it in your configuration file,
319 Python search path, create an entry for it in your configuration file,
320 like this:
320 like this:
321
321
322 [extensions]
322 [extensions]
323 foo =
323 foo =
324
324
325 You may also specify the full path to an extension:
325 You may also specify the full path to an extension:
326
326
327 [extensions]
327 [extensions]
328 myfeature = ~/.hgext/myfeature.py
328 myfeature = ~/.hgext/myfeature.py
329
329
330 See 'hg help config' for more information on configuration files.
330 See 'hg help config' for more information on configuration files.
331
331
332 Extensions are not loaded by default for a variety of reasons: they can
332 Extensions are not loaded by default for a variety of reasons: they can
333 increase startup overhead; they may be meant for advanced usage only; they
333 increase startup overhead; they may be meant for advanced usage only; they
334 may provide potentially dangerous abilities (such as letting you destroy
334 may provide potentially dangerous abilities (such as letting you destroy
335 or modify history); they might not be ready for prime time; or they may
335 or modify history); they might not be ready for prime time; or they may
336 alter some usual behaviors of stock Mercurial. It is thus up to the user
336 alter some usual behaviors of stock Mercurial. It is thus up to the user
337 to activate extensions as needed.
337 to activate extensions as needed.
338
338
339 To explicitly disable an extension enabled in a configuration file of
339 To explicitly disable an extension enabled in a configuration file of
340 broader scope, prepend its path with !:
340 broader scope, prepend its path with !:
341
341
342 [extensions]
342 [extensions]
343 # disabling extension bar residing in /path/to/extension/bar.py
343 # disabling extension bar residing in /path/to/extension/bar.py
344 bar = !/path/to/extension/bar.py
344 bar = !/path/to/extension/bar.py
345 # ditto, but no path was supplied for extension baz
345 # ditto, but no path was supplied for extension baz
346 baz = !
346 baz = !
347
347
348 enabled extensions:
348 enabled extensions:
349
349
350 children command to display child changesets (DEPRECATED)
350 children command to display child changesets (DEPRECATED)
351 rebase command to move sets of revisions to a different ancestor
351 rebase command to move sets of revisions to a different ancestor
352
352
353 disabled extensions:
353 disabled extensions:
354
354
355 acl hooks for controlling repository access
355 acl hooks for controlling repository access
356 blackbox log repository events to a blackbox for debugging
356 blackbox log repository events to a blackbox for debugging
357 bugzilla hooks for integrating with the Bugzilla bug tracker
357 bugzilla hooks for integrating with the Bugzilla bug tracker
358 censor erase file content at a given revision
358 censor erase file content at a given revision
359 churn command to display statistics about repository history
359 churn command to display statistics about repository history
360 clonebundles advertise pre-generated bundles to seed clones
360 clonebundles advertise pre-generated bundles to seed clones
361 closehead close arbitrary heads without checking them out first
361 closehead close arbitrary heads without checking them out first
362 convert import revisions from foreign VCS repositories into
362 convert import revisions from foreign VCS repositories into
363 Mercurial
363 Mercurial
364 eol automatically manage newlines in repository files
364 eol automatically manage newlines in repository files
365 extdiff command to allow external programs to compare revisions
365 extdiff command to allow external programs to compare revisions
366 factotum http authentication with factotum
366 factotum http authentication with factotum
367 fastexport export repositories as git fast-import stream
367 fastexport export repositories as git fast-import stream
368 githelp try mapping git commands to Mercurial commands
368 githelp try mapping git commands to Mercurial commands
369 gpg commands to sign and verify changesets
369 gpg commands to sign and verify changesets
370 hgk browse the repository in a graphical way
370 hgk browse the repository in a graphical way
371 highlight syntax highlighting for hgweb (requires Pygments)
371 highlight syntax highlighting for hgweb (requires Pygments)
372 histedit interactive history editing
372 histedit interactive history editing
373 keyword expand keywords in tracked files
373 keyword expand keywords in tracked files
374 largefiles track large binary files
374 largefiles track large binary files
375 mq manage a stack of patches
375 mq manage a stack of patches
376 notify hooks for sending email push notifications
376 notify hooks for sending email push notifications
377 patchbomb command to send changesets as (a series of) patch emails
377 patchbomb command to send changesets as (a series of) patch emails
378 purge command to delete untracked files from the working
378 purge command to delete untracked files from the working
379 directory
379 directory
380 relink recreates hardlinks between repository clones
380 relink recreates hardlinks between repository clones
381 schemes extend schemes with shortcuts to repository swarms
381 schemes extend schemes with shortcuts to repository swarms
382 share share a common history between several working directories
382 share share a common history between several working directories
383 strip strip changesets and their descendants from history
383 strip strip changesets and their descendants from history
384 transplant command to transplant changesets from another branch
384 transplant command to transplant changesets from another branch
385 win32mbcs allow the use of MBCS paths with problematic encodings
385 win32mbcs allow the use of MBCS paths with problematic encodings
386 zeroconf discover and advertise repositories on the local network
386 zeroconf discover and advertise repositories on the local network
387
387
388 #endif
388 #endif
389
389
390 Verify that deprecated extensions are included if --verbose:
390 Verify that deprecated extensions are included if --verbose:
391
391
392 $ hg -v help extensions | grep children
392 $ hg -v help extensions | grep children
393 children command to display child changesets (DEPRECATED)
393 children command to display child changesets (DEPRECATED)
394
394
395 Verify that extension keywords appear in help templates
395 Verify that extension keywords appear in help templates
396
396
397 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
397 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
398
398
399 Test short command list with verbose option
399 Test short command list with verbose option
400
400
401 $ hg -v help shortlist
401 $ hg -v help shortlist
402 Mercurial Distributed SCM
402 Mercurial Distributed SCM
403
403
404 basic commands:
404 basic commands:
405
405
406 abort abort an unfinished operation (EXPERIMENTAL)
406 abort abort an unfinished operation (EXPERIMENTAL)
407 add add the specified files on the next commit
407 add add the specified files on the next commit
408 annotate, blame
408 annotate, blame
409 show changeset information by line for each file
409 show changeset information by line for each file
410 clone make a copy of an existing repository
410 clone make a copy of an existing repository
411 commit, ci commit the specified files or all outstanding changes
411 commit, ci commit the specified files or all outstanding changes
412 continue resumes an interrupted operation (EXPERIMENTAL)
412 continue resumes an interrupted operation (EXPERIMENTAL)
413 diff diff repository (or selected files)
413 diff diff repository (or selected files)
414 export dump the header and diffs for one or more changesets
414 export dump the header and diffs for one or more changesets
415 forget forget the specified files on the next commit
415 forget forget the specified files on the next commit
416 init create a new repository in the given directory
416 init create a new repository in the given directory
417 log, history show revision history of entire repository or files
417 log, history show revision history of entire repository or files
418 merge merge another revision into working directory
418 merge merge another revision into working directory
419 pull pull changes from the specified source
419 pull pull changes from the specified source
420 push push changes to the specified destination
420 push push changes to the specified destination
421 remove, rm remove the specified files on the next commit
421 remove, rm remove the specified files on the next commit
422 serve start stand-alone webserver
422 serve start stand-alone webserver
423 status, st show changed files in the working directory
423 status, st show changed files in the working directory
424 summary, sum summarize working directory state
424 summary, sum summarize working directory state
425 update, up, checkout, co
425 update, up, checkout, co
426 update working directory (or switch revisions)
426 update working directory (or switch revisions)
427
427
428 global options ([+] can be repeated):
428 global options ([+] can be repeated):
429
429
430 -R --repository REPO repository root directory or name of overlay bundle
430 -R --repository REPO repository root directory or name of overlay bundle
431 file
431 file
432 --cwd DIR change working directory
432 --cwd DIR change working directory
433 -y --noninteractive do not prompt, automatically pick the first choice for
433 -y --noninteractive do not prompt, automatically pick the first choice for
434 all prompts
434 all prompts
435 -q --quiet suppress output
435 -q --quiet suppress output
436 -v --verbose enable additional output
436 -v --verbose enable additional output
437 --color TYPE when to colorize (boolean, always, auto, never, or
437 --color TYPE when to colorize (boolean, always, auto, never, or
438 debug)
438 debug)
439 --config CONFIG [+] set/override config option (use 'section.name=value')
439 --config CONFIG [+] set/override config option (use 'section.name=value')
440 --debug enable debugging output
440 --debug enable debugging output
441 --debugger start debugger
441 --debugger start debugger
442 --encoding ENCODE set the charset encoding (default: ascii)
442 --encoding ENCODE set the charset encoding (default: ascii)
443 --encodingmode MODE set the charset encoding mode (default: strict)
443 --encodingmode MODE set the charset encoding mode (default: strict)
444 --traceback always print a traceback on exception
444 --traceback always print a traceback on exception
445 --time time how long the command takes
445 --time time how long the command takes
446 --profile print command execution profile
446 --profile print command execution profile
447 --version output version information and exit
447 --version output version information and exit
448 -h --help display help and exit
448 -h --help display help and exit
449 --hidden consider hidden changesets
449 --hidden consider hidden changesets
450 --pager TYPE when to paginate (boolean, always, auto, or never)
450 --pager TYPE when to paginate (boolean, always, auto, or never)
451 (default: auto)
451 (default: auto)
452
452
453 (use 'hg help' for the full list of commands)
453 (use 'hg help' for the full list of commands)
454
454
455 $ hg add -h
455 $ hg add -h
456 hg add [OPTION]... [FILE]...
456 hg add [OPTION]... [FILE]...
457
457
458 add the specified files on the next commit
458 add the specified files on the next commit
459
459
460 Schedule files to be version controlled and added to the repository.
460 Schedule files to be version controlled and added to the repository.
461
461
462 The files will be added to the repository at the next commit. To undo an
462 The files will be added to the repository at the next commit. To undo an
463 add before that, see 'hg forget'.
463 add before that, see 'hg forget'.
464
464
465 If no names are given, add all files to the repository (except files
465 If no names are given, add all files to the repository (except files
466 matching ".hgignore").
466 matching ".hgignore").
467
467
468 Returns 0 if all files are successfully added.
468 Returns 0 if all files are successfully added.
469
469
470 options ([+] can be repeated):
470 options ([+] can be repeated):
471
471
472 -I --include PATTERN [+] include names matching the given patterns
472 -I --include PATTERN [+] include names matching the given patterns
473 -X --exclude PATTERN [+] exclude names matching the given patterns
473 -X --exclude PATTERN [+] exclude names matching the given patterns
474 -S --subrepos recurse into subrepositories
474 -S --subrepos recurse into subrepositories
475 -n --dry-run do not perform actions, just print output
475 -n --dry-run do not perform actions, just print output
476
476
477 (some details hidden, use --verbose to show complete help)
477 (some details hidden, use --verbose to show complete help)
478
478
479 Verbose help for add
479 Verbose help for add
480
480
481 $ hg add -hv
481 $ hg add -hv
482 hg add [OPTION]... [FILE]...
482 hg add [OPTION]... [FILE]...
483
483
484 add the specified files on the next commit
484 add the specified files on the next commit
485
485
486 Schedule files to be version controlled and added to the repository.
486 Schedule files to be version controlled and added to the repository.
487
487
488 The files will be added to the repository at the next commit. To undo an
488 The files will be added to the repository at the next commit. To undo an
489 add before that, see 'hg forget'.
489 add before that, see 'hg forget'.
490
490
491 If no names are given, add all files to the repository (except files
491 If no names are given, add all files to the repository (except files
492 matching ".hgignore").
492 matching ".hgignore").
493
493
494 Examples:
494 Examples:
495
495
496 - New (unknown) files are added automatically by 'hg add':
496 - New (unknown) files are added automatically by 'hg add':
497
497
498 $ ls
498 $ ls
499 foo.c
499 foo.c
500 $ hg status
500 $ hg status
501 ? foo.c
501 ? foo.c
502 $ hg add
502 $ hg add
503 adding foo.c
503 adding foo.c
504 $ hg status
504 $ hg status
505 A foo.c
505 A foo.c
506
506
507 - Specific files to be added can be specified:
507 - Specific files to be added can be specified:
508
508
509 $ ls
509 $ ls
510 bar.c foo.c
510 bar.c foo.c
511 $ hg status
511 $ hg status
512 ? bar.c
512 ? bar.c
513 ? foo.c
513 ? foo.c
514 $ hg add bar.c
514 $ hg add bar.c
515 $ hg status
515 $ hg status
516 A bar.c
516 A bar.c
517 ? foo.c
517 ? foo.c
518
518
519 Returns 0 if all files are successfully added.
519 Returns 0 if all files are successfully added.
520
520
521 options ([+] can be repeated):
521 options ([+] can be repeated):
522
522
523 -I --include PATTERN [+] include names matching the given patterns
523 -I --include PATTERN [+] include names matching the given patterns
524 -X --exclude PATTERN [+] exclude names matching the given patterns
524 -X --exclude PATTERN [+] exclude names matching the given patterns
525 -S --subrepos recurse into subrepositories
525 -S --subrepos recurse into subrepositories
526 -n --dry-run do not perform actions, just print output
526 -n --dry-run do not perform actions, just print output
527
527
528 global options ([+] can be repeated):
528 global options ([+] can be repeated):
529
529
530 -R --repository REPO repository root directory or name of overlay bundle
530 -R --repository REPO repository root directory or name of overlay bundle
531 file
531 file
532 --cwd DIR change working directory
532 --cwd DIR change working directory
533 -y --noninteractive do not prompt, automatically pick the first choice for
533 -y --noninteractive do not prompt, automatically pick the first choice for
534 all prompts
534 all prompts
535 -q --quiet suppress output
535 -q --quiet suppress output
536 -v --verbose enable additional output
536 -v --verbose enable additional output
537 --color TYPE when to colorize (boolean, always, auto, never, or
537 --color TYPE when to colorize (boolean, always, auto, never, or
538 debug)
538 debug)
539 --config CONFIG [+] set/override config option (use 'section.name=value')
539 --config CONFIG [+] set/override config option (use 'section.name=value')
540 --debug enable debugging output
540 --debug enable debugging output
541 --debugger start debugger
541 --debugger start debugger
542 --encoding ENCODE set the charset encoding (default: ascii)
542 --encoding ENCODE set the charset encoding (default: ascii)
543 --encodingmode MODE set the charset encoding mode (default: strict)
543 --encodingmode MODE set the charset encoding mode (default: strict)
544 --traceback always print a traceback on exception
544 --traceback always print a traceback on exception
545 --time time how long the command takes
545 --time time how long the command takes
546 --profile print command execution profile
546 --profile print command execution profile
547 --version output version information and exit
547 --version output version information and exit
548 -h --help display help and exit
548 -h --help display help and exit
549 --hidden consider hidden changesets
549 --hidden consider hidden changesets
550 --pager TYPE when to paginate (boolean, always, auto, or never)
550 --pager TYPE when to paginate (boolean, always, auto, or never)
551 (default: auto)
551 (default: auto)
552
552
553 Test the textwidth config option
553 Test the textwidth config option
554
554
555 $ hg root -h --config ui.textwidth=50
555 $ hg root -h --config ui.textwidth=50
556 hg root
556 hg root
557
557
558 print the root (top) of the current working
558 print the root (top) of the current working
559 directory
559 directory
560
560
561 Print the root directory of the current
561 Print the root directory of the current
562 repository.
562 repository.
563
563
564 Returns 0 on success.
564 Returns 0 on success.
565
565
566 options:
566 options:
567
567
568 -T --template TEMPLATE display with template
568 -T --template TEMPLATE display with template
569
569
570 (some details hidden, use --verbose to show
570 (some details hidden, use --verbose to show
571 complete help)
571 complete help)
572
572
573 Test help option with version option
573 Test help option with version option
574
574
575 $ hg add -h --version
575 $ hg add -h --version
576 Mercurial Distributed SCM (version *) (glob)
576 Mercurial Distributed SCM (version *) (glob)
577 (see https://mercurial-scm.org for more information)
577 (see https://mercurial-scm.org for more information)
578
578
579 Copyright (C) 2005-* Matt Mackall and others (glob)
579 Copyright (C) 2005-* Matt Mackall and others (glob)
580 This is free software; see the source for copying conditions. There is NO
580 This is free software; see the source for copying conditions. There is NO
581 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
581 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
582
582
583 $ hg add --skjdfks
583 $ hg add --skjdfks
584 hg add: option --skjdfks not recognized
584 hg add: option --skjdfks not recognized
585 hg add [OPTION]... [FILE]...
585 hg add [OPTION]... [FILE]...
586
586
587 add the specified files on the next commit
587 add the specified files on the next commit
588
588
589 options ([+] can be repeated):
589 options ([+] can be repeated):
590
590
591 -I --include PATTERN [+] include names matching the given patterns
591 -I --include PATTERN [+] include names matching the given patterns
592 -X --exclude PATTERN [+] exclude names matching the given patterns
592 -X --exclude PATTERN [+] exclude names matching the given patterns
593 -S --subrepos recurse into subrepositories
593 -S --subrepos recurse into subrepositories
594 -n --dry-run do not perform actions, just print output
594 -n --dry-run do not perform actions, just print output
595
595
596 (use 'hg add -h' to show more help)
596 (use 'hg add -h' to show more help)
597 [255]
597 [255]
598
598
599 Test ambiguous command help
599 Test ambiguous command help
600
600
601 $ hg help ad
601 $ hg help ad
602 list of commands:
602 list of commands:
603
603
604 add add the specified files on the next commit
604 add add the specified files on the next commit
605 addremove add all new files, delete all missing files
605 addremove add all new files, delete all missing files
606
606
607 (use 'hg help -v ad' to show built-in aliases and global options)
607 (use 'hg help -v ad' to show built-in aliases and global options)
608
608
609 Test command without options
609 Test command without options
610
610
611 $ hg help verify
611 $ hg help verify
612 hg verify
612 hg verify
613
613
614 verify the integrity of the repository
614 verify the integrity of the repository
615
615
616 Verify the integrity of the current repository.
616 Verify the integrity of the current repository.
617
617
618 This will perform an extensive check of the repository's integrity,
618 This will perform an extensive check of the repository's integrity,
619 validating the hashes and checksums of each entry in the changelog,
619 validating the hashes and checksums of each entry in the changelog,
620 manifest, and tracked files, as well as the integrity of their crosslinks
620 manifest, and tracked files, as well as the integrity of their crosslinks
621 and indices.
621 and indices.
622
622
623 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
623 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
624 information about recovery from corruption of the repository.
624 information about recovery from corruption of the repository.
625
625
626 Returns 0 on success, 1 if errors are encountered.
626 Returns 0 on success, 1 if errors are encountered.
627
627
628 options:
628 options:
629
629
630 (some details hidden, use --verbose to show complete help)
630 (some details hidden, use --verbose to show complete help)
631
631
632 $ hg help diff
632 $ hg help diff
633 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
633 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
634
634
635 diff repository (or selected files)
635 diff repository (or selected files)
636
636
637 Show differences between revisions for the specified files.
637 Show differences between revisions for the specified files.
638
638
639 Differences between files are shown using the unified diff format.
639 Differences between files are shown using the unified diff format.
640
640
641 Note:
641 Note:
642 'hg diff' may generate unexpected results for merges, as it will
642 'hg diff' may generate unexpected results for merges, as it will
643 default to comparing against the working directory's first parent
643 default to comparing against the working directory's first parent
644 changeset if no revisions are specified.
644 changeset if no revisions are specified.
645
645
646 When two revision arguments are given, then changes are shown between
646 When two revision arguments are given, then changes are shown between
647 those revisions. If only one revision is specified then that revision is
647 those revisions. If only one revision is specified then that revision is
648 compared to the working directory, and, when no revisions are specified,
648 compared to the working directory, and, when no revisions are specified,
649 the working directory files are compared to its first parent.
649 the working directory files are compared to its first parent.
650
650
651 Alternatively you can specify -c/--change with a revision to see the
651 Alternatively you can specify -c/--change with a revision to see the
652 changes in that changeset relative to its first parent.
652 changes in that changeset relative to its first parent.
653
653
654 Without the -a/--text option, diff will avoid generating diffs of files it
654 Without the -a/--text option, diff will avoid generating diffs of files it
655 detects as binary. With -a, diff will generate a diff anyway, probably
655 detects as binary. With -a, diff will generate a diff anyway, probably
656 with undesirable results.
656 with undesirable results.
657
657
658 Use the -g/--git option to generate diffs in the git extended diff format.
658 Use the -g/--git option to generate diffs in the git extended diff format.
659 For more information, read 'hg help diffs'.
659 For more information, read 'hg help diffs'.
660
660
661 Returns 0 on success.
661 Returns 0 on success.
662
662
663 options ([+] can be repeated):
663 options ([+] can be repeated):
664
664
665 -r --rev REV [+] revision
665 -r --rev REV [+] revision
666 -c --change REV change made by revision
666 -c --change REV change made by revision
667 -a --text treat all files as text
667 -a --text treat all files as text
668 -g --git use git extended diff format
668 -g --git use git extended diff format
669 --binary generate binary diffs in git mode (default)
669 --binary generate binary diffs in git mode (default)
670 --nodates omit dates from diff headers
670 --nodates omit dates from diff headers
671 --noprefix omit a/ and b/ prefixes from filenames
671 --noprefix omit a/ and b/ prefixes from filenames
672 -p --show-function show which function each change is in
672 -p --show-function show which function each change is in
673 --reverse produce a diff that undoes the changes
673 --reverse produce a diff that undoes the changes
674 -w --ignore-all-space ignore white space when comparing lines
674 -w --ignore-all-space ignore white space when comparing lines
675 -b --ignore-space-change ignore changes in the amount of white space
675 -b --ignore-space-change ignore changes in the amount of white space
676 -B --ignore-blank-lines ignore changes whose lines are all blank
676 -B --ignore-blank-lines ignore changes whose lines are all blank
677 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
677 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
678 -U --unified NUM number of lines of context to show
678 -U --unified NUM number of lines of context to show
679 --stat output diffstat-style summary of changes
679 --stat output diffstat-style summary of changes
680 --root DIR produce diffs relative to subdirectory
680 --root DIR produce diffs relative to subdirectory
681 -I --include PATTERN [+] include names matching the given patterns
681 -I --include PATTERN [+] include names matching the given patterns
682 -X --exclude PATTERN [+] exclude names matching the given patterns
682 -X --exclude PATTERN [+] exclude names matching the given patterns
683 -S --subrepos recurse into subrepositories
683 -S --subrepos recurse into subrepositories
684
684
685 (some details hidden, use --verbose to show complete help)
685 (some details hidden, use --verbose to show complete help)
686
686
687 $ hg help status
687 $ hg help status
688 hg status [OPTION]... [FILE]...
688 hg status [OPTION]... [FILE]...
689
689
690 aliases: st
690 aliases: st
691
691
692 show changed files in the working directory
692 show changed files in the working directory
693
693
694 Show status of files in the repository. If names are given, only files
694 Show status of files in the repository. If names are given, only files
695 that match are shown. Files that are clean or ignored or the source of a
695 that match are shown. Files that are clean or ignored or the source of a
696 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
696 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
697 -C/--copies or -A/--all are given. Unless options described with "show
697 -C/--copies or -A/--all are given. Unless options described with "show
698 only ..." are given, the options -mardu are used.
698 only ..." are given, the options -mardu are used.
699
699
700 Option -q/--quiet hides untracked (unknown and ignored) files unless
700 Option -q/--quiet hides untracked (unknown and ignored) files unless
701 explicitly requested with -u/--unknown or -i/--ignored.
701 explicitly requested with -u/--unknown or -i/--ignored.
702
702
703 Note:
703 Note:
704 'hg status' may appear to disagree with diff if permissions have
704 'hg status' may appear to disagree with diff if permissions have
705 changed or a merge has occurred. The standard diff format does not
705 changed or a merge has occurred. The standard diff format does not
706 report permission changes and diff only reports changes relative to one
706 report permission changes and diff only reports changes relative to one
707 merge parent.
707 merge parent.
708
708
709 If one revision is given, it is used as the base revision. If two
709 If one revision is given, it is used as the base revision. If two
710 revisions are given, the differences between them are shown. The --change
710 revisions are given, the differences between them are shown. The --change
711 option can also be used as a shortcut to list the changed files of a
711 option can also be used as a shortcut to list the changed files of a
712 revision from its first parent.
712 revision from its first parent.
713
713
714 The codes used to show the status of files are:
714 The codes used to show the status of files are:
715
715
716 M = modified
716 M = modified
717 A = added
717 A = added
718 R = removed
718 R = removed
719 C = clean
719 C = clean
720 ! = missing (deleted by non-hg command, but still tracked)
720 ! = missing (deleted by non-hg command, but still tracked)
721 ? = not tracked
721 ? = not tracked
722 I = ignored
722 I = ignored
723 = origin of the previous file (with --copies)
723 = origin of the previous file (with --copies)
724
724
725 Returns 0 on success.
725 Returns 0 on success.
726
726
727 options ([+] can be repeated):
727 options ([+] can be repeated):
728
728
729 -A --all show status of all files
729 -A --all show status of all files
730 -m --modified show only modified files
730 -m --modified show only modified files
731 -a --added show only added files
731 -a --added show only added files
732 -r --removed show only removed files
732 -r --removed show only removed files
733 -d --deleted show only deleted (but tracked) files
733 -d --deleted show only deleted (but tracked) files
734 -c --clean show only files without changes
734 -c --clean show only files without changes
735 -u --unknown show only unknown (not tracked) files
735 -u --unknown show only unknown (not tracked) files
736 -i --ignored show only ignored files
736 -i --ignored show only ignored files
737 -n --no-status hide status prefix
737 -n --no-status hide status prefix
738 -C --copies show source of copied files
738 -C --copies show source of copied files
739 -0 --print0 end filenames with NUL, for use with xargs
739 -0 --print0 end filenames with NUL, for use with xargs
740 --rev REV [+] show difference from revision
740 --rev REV [+] show difference from revision
741 --change REV list the changed files of a revision
741 --change REV list the changed files of a revision
742 -I --include PATTERN [+] include names matching the given patterns
742 -I --include PATTERN [+] include names matching the given patterns
743 -X --exclude PATTERN [+] exclude names matching the given patterns
743 -X --exclude PATTERN [+] exclude names matching the given patterns
744 -S --subrepos recurse into subrepositories
744 -S --subrepos recurse into subrepositories
745 -T --template TEMPLATE display with template
745 -T --template TEMPLATE display with template
746
746
747 (some details hidden, use --verbose to show complete help)
747 (some details hidden, use --verbose to show complete help)
748
748
749 $ hg -q help status
749 $ hg -q help status
750 hg status [OPTION]... [FILE]...
750 hg status [OPTION]... [FILE]...
751
751
752 show changed files in the working directory
752 show changed files in the working directory
753
753
754 $ hg help foo
754 $ hg help foo
755 abort: no such help topic: foo
755 abort: no such help topic: foo
756 (try 'hg help --keyword foo')
756 (try 'hg help --keyword foo')
757 [255]
757 [255]
758
758
759 $ hg skjdfks
759 $ hg skjdfks
760 hg: unknown command 'skjdfks'
760 hg: unknown command 'skjdfks'
761 (use 'hg help' for a list of commands)
761 (use 'hg help' for a list of commands)
762 [255]
762 [255]
763
763
764 Typoed command gives suggestion
764 Typoed command gives suggestion
765 $ hg puls
765 $ hg puls
766 hg: unknown command 'puls'
766 hg: unknown command 'puls'
767 (did you mean one of pull, push?)
767 (did you mean one of pull, push?)
768 [255]
768 [255]
769
769
770 Not enabled extension gets suggested
770 Not enabled extension gets suggested
771
771
772 $ hg rebase
772 $ hg rebase
773 hg: unknown command 'rebase'
773 hg: unknown command 'rebase'
774 'rebase' is provided by the following extension:
774 'rebase' is provided by the following extension:
775
775
776 rebase command to move sets of revisions to a different ancestor
776 rebase command to move sets of revisions to a different ancestor
777
777
778 (use 'hg help extensions' for information on enabling extensions)
778 (use 'hg help extensions' for information on enabling extensions)
779 [255]
779 [255]
780
780
781 Disabled extension gets suggested
781 Disabled extension gets suggested
782 $ hg --config extensions.rebase=! rebase
782 $ hg --config extensions.rebase=! rebase
783 hg: unknown command 'rebase'
783 hg: unknown command 'rebase'
784 'rebase' is provided by the following extension:
784 'rebase' is provided by the following extension:
785
785
786 rebase command to move sets of revisions to a different ancestor
786 rebase command to move sets of revisions to a different ancestor
787
787
788 (use 'hg help extensions' for information on enabling extensions)
788 (use 'hg help extensions' for information on enabling extensions)
789 [255]
789 [255]
790
790
791 Checking that help adapts based on the config:
791 Checking that help adapts based on the config:
792
792
793 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
793 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
794 -g --[no-]git use git extended diff format (default: on from
794 -g --[no-]git use git extended diff format (default: on from
795 config)
795 config)
796
796
797 Make sure that we don't run afoul of the help system thinking that
797 Make sure that we don't run afoul of the help system thinking that
798 this is a section and erroring out weirdly.
798 this is a section and erroring out weirdly.
799
799
800 $ hg .log
800 $ hg .log
801 hg: unknown command '.log'
801 hg: unknown command '.log'
802 (did you mean log?)
802 (did you mean log?)
803 [255]
803 [255]
804
804
805 $ hg log.
805 $ hg log.
806 hg: unknown command 'log.'
806 hg: unknown command 'log.'
807 (did you mean log?)
807 (did you mean log?)
808 [255]
808 [255]
809 $ hg pu.lh
809 $ hg pu.lh
810 hg: unknown command 'pu.lh'
810 hg: unknown command 'pu.lh'
811 (did you mean one of pull, push?)
811 (did you mean one of pull, push?)
812 [255]
812 [255]
813
813
814 $ cat > helpext.py <<EOF
814 $ cat > helpext.py <<EOF
815 > import os
815 > import os
816 > from mercurial import commands, fancyopts, registrar
816 > from mercurial import commands, fancyopts, registrar
817 >
817 >
818 > def func(arg):
818 > def func(arg):
819 > return '%sfoo' % arg
819 > return '%sfoo' % arg
820 > class customopt(fancyopts.customopt):
820 > class customopt(fancyopts.customopt):
821 > def newstate(self, oldstate, newparam, abort):
821 > def newstate(self, oldstate, newparam, abort):
822 > return '%sbar' % oldstate
822 > return '%sbar' % oldstate
823 > cmdtable = {}
823 > cmdtable = {}
824 > command = registrar.command(cmdtable)
824 > command = registrar.command(cmdtable)
825 >
825 >
826 > @command(b'nohelp',
826 > @command(b'nohelp',
827 > [(b'', b'longdesc', 3, b'x'*67),
827 > [(b'', b'longdesc', 3, b'x'*67),
828 > (b'n', b'', None, b'normal desc'),
828 > (b'n', b'', None, b'normal desc'),
829 > (b'', b'newline', b'', b'line1\nline2'),
829 > (b'', b'newline', b'', b'line1\nline2'),
830 > (b'', b'default-off', False, b'enable X'),
830 > (b'', b'default-off', False, b'enable X'),
831 > (b'', b'default-on', True, b'enable Y'),
831 > (b'', b'default-on', True, b'enable Y'),
832 > (b'', b'callableopt', func, b'adds foo'),
832 > (b'', b'callableopt', func, b'adds foo'),
833 > (b'', b'customopt', customopt(''), b'adds bar'),
833 > (b'', b'customopt', customopt(''), b'adds bar'),
834 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
834 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
835 > b'hg nohelp',
835 > b'hg nohelp',
836 > norepo=True)
836 > norepo=True)
837 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
837 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
838 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
838 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
839 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
839 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
840 > def nohelp(ui, *args, **kwargs):
840 > def nohelp(ui, *args, **kwargs):
841 > pass
841 > pass
842 >
842 >
843 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
843 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
844 > def hashelp(ui, *args, **kwargs):
844 > def hashelp(ui, *args, **kwargs):
845 > """Extension command's help"""
845 > """Extension command's help"""
846 >
846 >
847 > def uisetup(ui):
847 > def uisetup(ui):
848 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
848 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
849 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
849 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
850 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
850 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
851 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
851 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
852 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
852 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
853 >
853 >
854 > EOF
854 > EOF
855 $ echo '[extensions]' >> $HGRCPATH
855 $ echo '[extensions]' >> $HGRCPATH
856 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
856 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
857
857
858 Test for aliases
858 Test for aliases
859
859
860 $ hg help | grep hgalias
860 $ hg help | grep hgalias
861 hgalias My doc
861 hgalias My doc
862
862
863 $ hg help hgalias
863 $ hg help hgalias
864 hg hgalias [--remote]
864 hg hgalias [--remote]
865
865
866 alias for: hg summary
866 alias for: hg summary
867
867
868 My doc
868 My doc
869
869
870 defined by: helpext
870 defined by: helpext
871
871
872 options:
872 options:
873
873
874 --remote check for push and pull
874 --remote check for push and pull
875
875
876 (some details hidden, use --verbose to show complete help)
876 (some details hidden, use --verbose to show complete help)
877 $ hg help hgaliasnodoc
877 $ hg help hgaliasnodoc
878 hg hgaliasnodoc [--remote]
878 hg hgaliasnodoc [--remote]
879
879
880 alias for: hg summary
880 alias for: hg summary
881
881
882 summarize working directory state
882 summarize working directory state
883
883
884 This generates a brief summary of the working directory state, including
884 This generates a brief summary of the working directory state, including
885 parents, branch, commit status, phase and available updates.
885 parents, branch, commit status, phase and available updates.
886
886
887 With the --remote option, this will check the default paths for incoming
887 With the --remote option, this will check the default paths for incoming
888 and outgoing changes. This can be time-consuming.
888 and outgoing changes. This can be time-consuming.
889
889
890 Returns 0 on success.
890 Returns 0 on success.
891
891
892 defined by: helpext
892 defined by: helpext
893
893
894 options:
894 options:
895
895
896 --remote check for push and pull
896 --remote check for push and pull
897
897
898 (some details hidden, use --verbose to show complete help)
898 (some details hidden, use --verbose to show complete help)
899
899
900 $ hg help shellalias
900 $ hg help shellalias
901 hg shellalias
901 hg shellalias
902
902
903 shell alias for: echo hi
903 shell alias for: echo hi
904
904
905 (no help text available)
905 (no help text available)
906
906
907 defined by: helpext
907 defined by: helpext
908
908
909 (some details hidden, use --verbose to show complete help)
909 (some details hidden, use --verbose to show complete help)
910
910
911 Test command with no help text
911 Test command with no help text
912
912
913 $ hg help nohelp
913 $ hg help nohelp
914 hg nohelp
914 hg nohelp
915
915
916 (no help text available)
916 (no help text available)
917
917
918 options:
918 options:
919
919
920 --longdesc VALUE
920 --longdesc VALUE
921 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
921 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
922 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
922 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
923 -n -- normal desc
923 -n -- normal desc
924 --newline VALUE line1 line2
924 --newline VALUE line1 line2
925 --default-off enable X
925 --default-off enable X
926 --[no-]default-on enable Y (default: on)
926 --[no-]default-on enable Y (default: on)
927 --callableopt VALUE adds foo
927 --callableopt VALUE adds foo
928 --customopt VALUE adds bar
928 --customopt VALUE adds bar
929 --customopt-withdefault VALUE adds bar (default: foo)
929 --customopt-withdefault VALUE adds bar (default: foo)
930
930
931 (some details hidden, use --verbose to show complete help)
931 (some details hidden, use --verbose to show complete help)
932
932
933 Test that default list of commands includes extension commands that have help,
933 Test that default list of commands includes extension commands that have help,
934 but not those that don't, except in verbose mode, when a keyword is passed, or
934 but not those that don't, except in verbose mode, when a keyword is passed, or
935 when help about the extension is requested.
935 when help about the extension is requested.
936
936
937 #if no-extraextensions
937 #if no-extraextensions
938
938
939 $ hg help | grep hashelp
939 $ hg help | grep hashelp
940 hashelp Extension command's help
940 hashelp Extension command's help
941 $ hg help | grep nohelp
941 $ hg help | grep nohelp
942 [1]
942 [1]
943 $ hg help -v | grep nohelp
943 $ hg help -v | grep nohelp
944 nohelp (no help text available)
944 nohelp (no help text available)
945
945
946 $ hg help -k nohelp
946 $ hg help -k nohelp
947 Commands:
947 Commands:
948
948
949 nohelp hg nohelp
949 nohelp hg nohelp
950
950
951 Extension Commands:
951 Extension Commands:
952
952
953 nohelp (no help text available)
953 nohelp (no help text available)
954
954
955 $ hg help helpext
955 $ hg help helpext
956 helpext extension - no help text available
956 helpext extension - no help text available
957
957
958 list of commands:
958 list of commands:
959
959
960 hashelp Extension command's help
960 hashelp Extension command's help
961 nohelp (no help text available)
961 nohelp (no help text available)
962
962
963 (use 'hg help -v helpext' to show built-in aliases and global options)
963 (use 'hg help -v helpext' to show built-in aliases and global options)
964
964
965 #endif
965 #endif
966
966
967 Test list of internal help commands
967 Test list of internal help commands
968
968
969 $ hg help debug
969 $ hg help debug
970 debug commands (internal and unsupported):
970 debug commands (internal and unsupported):
971
971
972 debugancestor
972 debugancestor
973 find the ancestor revision of two revisions in a given index
973 find the ancestor revision of two revisions in a given index
974 debugapplystreamclonebundle
974 debugapplystreamclonebundle
975 apply a stream clone bundle file
975 apply a stream clone bundle file
976 debugbackupbundle
977 lists the changesets available in backup bundles
976 debugbuilddag
978 debugbuilddag
977 builds a repo with a given DAG from scratch in the current
979 builds a repo with a given DAG from scratch in the current
978 empty repo
980 empty repo
979 debugbundle lists the contents of a bundle
981 debugbundle lists the contents of a bundle
980 debugcapabilities
982 debugcapabilities
981 lists the capabilities of a remote peer
983 lists the capabilities of a remote peer
982 debugcheckstate
984 debugcheckstate
983 validate the correctness of the current dirstate
985 validate the correctness of the current dirstate
984 debugcolor show available color, effects or style
986 debugcolor show available color, effects or style
985 debugcommands
987 debugcommands
986 list all available commands and options
988 list all available commands and options
987 debugcomplete
989 debugcomplete
988 returns the completion list associated with the given command
990 returns the completion list associated with the given command
989 debugcreatestreamclonebundle
991 debugcreatestreamclonebundle
990 create a stream clone bundle file
992 create a stream clone bundle file
991 debugdag format the changelog or an index DAG as a concise textual
993 debugdag format the changelog or an index DAG as a concise textual
992 description
994 description
993 debugdata dump the contents of a data file revision
995 debugdata dump the contents of a data file revision
994 debugdate parse and display a date
996 debugdate parse and display a date
995 debugdeltachain
997 debugdeltachain
996 dump information about delta chains in a revlog
998 dump information about delta chains in a revlog
997 debugdirstate
999 debugdirstate
998 show the contents of the current dirstate
1000 show the contents of the current dirstate
999 debugdiscovery
1001 debugdiscovery
1000 runs the changeset discovery protocol in isolation
1002 runs the changeset discovery protocol in isolation
1001 debugdownload
1003 debugdownload
1002 download a resource using Mercurial logic and config
1004 download a resource using Mercurial logic and config
1003 debugextensions
1005 debugextensions
1004 show information about active extensions
1006 show information about active extensions
1005 debugfileset parse and apply a fileset specification
1007 debugfileset parse and apply a fileset specification
1006 debugformat display format information about the current repository
1008 debugformat display format information about the current repository
1007 debugfsinfo show information detected about current filesystem
1009 debugfsinfo show information detected about current filesystem
1008 debuggetbundle
1010 debuggetbundle
1009 retrieves a bundle from a repo
1011 retrieves a bundle from a repo
1010 debugignore display the combined ignore pattern and information about
1012 debugignore display the combined ignore pattern and information about
1011 ignored files
1013 ignored files
1012 debugindex dump index data for a storage primitive
1014 debugindex dump index data for a storage primitive
1013 debugindexdot
1015 debugindexdot
1014 dump an index DAG as a graphviz dot file
1016 dump an index DAG as a graphviz dot file
1015 debugindexstats
1017 debugindexstats
1016 show stats related to the changelog index
1018 show stats related to the changelog index
1017 debuginstall test Mercurial installation
1019 debuginstall test Mercurial installation
1018 debugknown test whether node ids are known to a repo
1020 debugknown test whether node ids are known to a repo
1019 debuglocks show or modify state of locks
1021 debuglocks show or modify state of locks
1020 debugmanifestfulltextcache
1022 debugmanifestfulltextcache
1021 show, clear or amend the contents of the manifest fulltext
1023 show, clear or amend the contents of the manifest fulltext
1022 cache
1024 cache
1023 debugmergestate
1025 debugmergestate
1024 print merge state
1026 print merge state
1025 debugnamecomplete
1027 debugnamecomplete
1026 complete "names" - tags, open branch names, bookmark names
1028 complete "names" - tags, open branch names, bookmark names
1027 debugnodemap write and inspect on disk nodemap
1029 debugnodemap write and inspect on disk nodemap
1028 debugobsolete
1030 debugobsolete
1029 create arbitrary obsolete marker
1031 create arbitrary obsolete marker
1030 debugoptADV (no help text available)
1032 debugoptADV (no help text available)
1031 debugoptDEP (no help text available)
1033 debugoptDEP (no help text available)
1032 debugoptEXP (no help text available)
1034 debugoptEXP (no help text available)
1033 debugp1copies
1035 debugp1copies
1034 dump copy information compared to p1
1036 dump copy information compared to p1
1035 debugp2copies
1037 debugp2copies
1036 dump copy information compared to p2
1038 dump copy information compared to p2
1037 debugpathcomplete
1039 debugpathcomplete
1038 complete part or all of a tracked path
1040 complete part or all of a tracked path
1039 debugpathcopies
1041 debugpathcopies
1040 show copies between two revisions
1042 show copies between two revisions
1041 debugpeer establish a connection to a peer repository
1043 debugpeer establish a connection to a peer repository
1042 debugpickmergetool
1044 debugpickmergetool
1043 examine which merge tool is chosen for specified file
1045 examine which merge tool is chosen for specified file
1044 debugpushkey access the pushkey key/value protocol
1046 debugpushkey access the pushkey key/value protocol
1045 debugpvec (no help text available)
1047 debugpvec (no help text available)
1046 debugrebuilddirstate
1048 debugrebuilddirstate
1047 rebuild the dirstate as it would look like for the given
1049 rebuild the dirstate as it would look like for the given
1048 revision
1050 revision
1049 debugrebuildfncache
1051 debugrebuildfncache
1050 rebuild the fncache file
1052 rebuild the fncache file
1051 debugrename dump rename information
1053 debugrename dump rename information
1052 debugrevlog show data and statistics about a revlog
1054 debugrevlog show data and statistics about a revlog
1053 debugrevlogindex
1055 debugrevlogindex
1054 dump the contents of a revlog index
1056 dump the contents of a revlog index
1055 debugrevspec parse and apply a revision specification
1057 debugrevspec parse and apply a revision specification
1056 debugserve run a server with advanced settings
1058 debugserve run a server with advanced settings
1057 debugsetparents
1059 debugsetparents
1058 manually set the parents of the current working directory
1060 manually set the parents of the current working directory
1059 debugsidedata
1061 debugsidedata
1060 dump the side data for a cl/manifest/file revision
1062 dump the side data for a cl/manifest/file revision
1061 debugssl test a secure connection to a server
1063 debugssl test a secure connection to a server
1062 debugsub (no help text available)
1064 debugsub (no help text available)
1063 debugsuccessorssets
1065 debugsuccessorssets
1064 show set of successors for revision
1066 show set of successors for revision
1065 debugtagscache
1067 debugtagscache
1066 display the contents of .hg/cache/hgtagsfnodes1
1068 display the contents of .hg/cache/hgtagsfnodes1
1067 debugtemplate
1069 debugtemplate
1068 parse and apply a template
1070 parse and apply a template
1069 debuguigetpass
1071 debuguigetpass
1070 show prompt to type password
1072 show prompt to type password
1071 debuguiprompt
1073 debuguiprompt
1072 show plain prompt
1074 show plain prompt
1073 debugupdatecaches
1075 debugupdatecaches
1074 warm all known caches in the repository
1076 warm all known caches in the repository
1075 debugupgraderepo
1077 debugupgraderepo
1076 upgrade a repository to use different features
1078 upgrade a repository to use different features
1077 debugwalk show how files match on given patterns
1079 debugwalk show how files match on given patterns
1078 debugwhyunstable
1080 debugwhyunstable
1079 explain instabilities of a changeset
1081 explain instabilities of a changeset
1080 debugwireargs
1082 debugwireargs
1081 (no help text available)
1083 (no help text available)
1082 debugwireproto
1084 debugwireproto
1083 send wire protocol commands to a server
1085 send wire protocol commands to a server
1084
1086
1085 (use 'hg help -v debug' to show built-in aliases and global options)
1087 (use 'hg help -v debug' to show built-in aliases and global options)
1086
1088
1087 internals topic renders index of available sub-topics
1089 internals topic renders index of available sub-topics
1088
1090
1089 $ hg help internals
1091 $ hg help internals
1090 Technical implementation topics
1092 Technical implementation topics
1091 """""""""""""""""""""""""""""""
1093 """""""""""""""""""""""""""""""
1092
1094
1093 To access a subtopic, use "hg help internals.{subtopic-name}"
1095 To access a subtopic, use "hg help internals.{subtopic-name}"
1094
1096
1095 bundle2 Bundle2
1097 bundle2 Bundle2
1096 bundles Bundles
1098 bundles Bundles
1097 cbor CBOR
1099 cbor CBOR
1098 censor Censor
1100 censor Censor
1099 changegroups Changegroups
1101 changegroups Changegroups
1100 config Config Registrar
1102 config Config Registrar
1101 extensions Extension API
1103 extensions Extension API
1102 mergestate Mergestate
1104 mergestate Mergestate
1103 requirements Repository Requirements
1105 requirements Repository Requirements
1104 revlogs Revision Logs
1106 revlogs Revision Logs
1105 wireprotocol Wire Protocol
1107 wireprotocol Wire Protocol
1106 wireprotocolrpc
1108 wireprotocolrpc
1107 Wire Protocol RPC
1109 Wire Protocol RPC
1108 wireprotocolv2
1110 wireprotocolv2
1109 Wire Protocol Version 2
1111 Wire Protocol Version 2
1110
1112
1111 sub-topics can be accessed
1113 sub-topics can be accessed
1112
1114
1113 $ hg help internals.changegroups
1115 $ hg help internals.changegroups
1114 Changegroups
1116 Changegroups
1115 """"""""""""
1117 """"""""""""
1116
1118
1117 Changegroups are representations of repository revlog data, specifically
1119 Changegroups are representations of repository revlog data, specifically
1118 the changelog data, root/flat manifest data, treemanifest data, and
1120 the changelog data, root/flat manifest data, treemanifest data, and
1119 filelogs.
1121 filelogs.
1120
1122
1121 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1123 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1122 level, versions "1" and "2" are almost exactly the same, with the only
1124 level, versions "1" and "2" are almost exactly the same, with the only
1123 difference being an additional item in the *delta header*. Version "3"
1125 difference being an additional item in the *delta header*. Version "3"
1124 adds support for storage flags in the *delta header* and optionally
1126 adds support for storage flags in the *delta header* and optionally
1125 exchanging treemanifests (enabled by setting an option on the
1127 exchanging treemanifests (enabled by setting an option on the
1126 "changegroup" part in the bundle2).
1128 "changegroup" part in the bundle2).
1127
1129
1128 Changegroups when not exchanging treemanifests consist of 3 logical
1130 Changegroups when not exchanging treemanifests consist of 3 logical
1129 segments:
1131 segments:
1130
1132
1131 +---------------------------------+
1133 +---------------------------------+
1132 | | | |
1134 | | | |
1133 | changeset | manifest | filelogs |
1135 | changeset | manifest | filelogs |
1134 | | | |
1136 | | | |
1135 | | | |
1137 | | | |
1136 +---------------------------------+
1138 +---------------------------------+
1137
1139
1138 When exchanging treemanifests, there are 4 logical segments:
1140 When exchanging treemanifests, there are 4 logical segments:
1139
1141
1140 +-------------------------------------------------+
1142 +-------------------------------------------------+
1141 | | | | |
1143 | | | | |
1142 | changeset | root | treemanifests | filelogs |
1144 | changeset | root | treemanifests | filelogs |
1143 | | manifest | | |
1145 | | manifest | | |
1144 | | | | |
1146 | | | | |
1145 +-------------------------------------------------+
1147 +-------------------------------------------------+
1146
1148
1147 The principle building block of each segment is a *chunk*. A *chunk* is a
1149 The principle building block of each segment is a *chunk*. A *chunk* is a
1148 framed piece of data:
1150 framed piece of data:
1149
1151
1150 +---------------------------------------+
1152 +---------------------------------------+
1151 | | |
1153 | | |
1152 | length | data |
1154 | length | data |
1153 | (4 bytes) | (<length - 4> bytes) |
1155 | (4 bytes) | (<length - 4> bytes) |
1154 | | |
1156 | | |
1155 +---------------------------------------+
1157 +---------------------------------------+
1156
1158
1157 All integers are big-endian signed integers. Each chunk starts with a
1159 All integers are big-endian signed integers. Each chunk starts with a
1158 32-bit integer indicating the length of the entire chunk (including the
1160 32-bit integer indicating the length of the entire chunk (including the
1159 length field itself).
1161 length field itself).
1160
1162
1161 There is a special case chunk that has a value of 0 for the length
1163 There is a special case chunk that has a value of 0 for the length
1162 ("0x00000000"). We call this an *empty chunk*.
1164 ("0x00000000"). We call this an *empty chunk*.
1163
1165
1164 Delta Groups
1166 Delta Groups
1165 ============
1167 ============
1166
1168
1167 A *delta group* expresses the content of a revlog as a series of deltas,
1169 A *delta group* expresses the content of a revlog as a series of deltas,
1168 or patches against previous revisions.
1170 or patches against previous revisions.
1169
1171
1170 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1172 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1171 to signal the end of the delta group:
1173 to signal the end of the delta group:
1172
1174
1173 +------------------------------------------------------------------------+
1175 +------------------------------------------------------------------------+
1174 | | | | | |
1176 | | | | | |
1175 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1177 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1176 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1178 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1177 | | | | | |
1179 | | | | | |
1178 +------------------------------------------------------------------------+
1180 +------------------------------------------------------------------------+
1179
1181
1180 Each *chunk*'s data consists of the following:
1182 Each *chunk*'s data consists of the following:
1181
1183
1182 +---------------------------------------+
1184 +---------------------------------------+
1183 | | |
1185 | | |
1184 | delta header | delta data |
1186 | delta header | delta data |
1185 | (various by version) | (various) |
1187 | (various by version) | (various) |
1186 | | |
1188 | | |
1187 +---------------------------------------+
1189 +---------------------------------------+
1188
1190
1189 The *delta data* is a series of *delta*s that describe a diff from an
1191 The *delta data* is a series of *delta*s that describe a diff from an
1190 existing entry (either that the recipient already has, or previously
1192 existing entry (either that the recipient already has, or previously
1191 specified in the bundle/changegroup).
1193 specified in the bundle/changegroup).
1192
1194
1193 The *delta header* is different between versions "1", "2", and "3" of the
1195 The *delta header* is different between versions "1", "2", and "3" of the
1194 changegroup format.
1196 changegroup format.
1195
1197
1196 Version 1 (headerlen=80):
1198 Version 1 (headerlen=80):
1197
1199
1198 +------------------------------------------------------+
1200 +------------------------------------------------------+
1199 | | | | |
1201 | | | | |
1200 | node | p1 node | p2 node | link node |
1202 | node | p1 node | p2 node | link node |
1201 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1203 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1202 | | | | |
1204 | | | | |
1203 +------------------------------------------------------+
1205 +------------------------------------------------------+
1204
1206
1205 Version 2 (headerlen=100):
1207 Version 2 (headerlen=100):
1206
1208
1207 +------------------------------------------------------------------+
1209 +------------------------------------------------------------------+
1208 | | | | | |
1210 | | | | | |
1209 | node | p1 node | p2 node | base node | link node |
1211 | node | p1 node | p2 node | base node | link node |
1210 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1212 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1211 | | | | | |
1213 | | | | | |
1212 +------------------------------------------------------------------+
1214 +------------------------------------------------------------------+
1213
1215
1214 Version 3 (headerlen=102):
1216 Version 3 (headerlen=102):
1215
1217
1216 +------------------------------------------------------------------------------+
1218 +------------------------------------------------------------------------------+
1217 | | | | | | |
1219 | | | | | | |
1218 | node | p1 node | p2 node | base node | link node | flags |
1220 | node | p1 node | p2 node | base node | link node | flags |
1219 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1221 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1220 | | | | | | |
1222 | | | | | | |
1221 +------------------------------------------------------------------------------+
1223 +------------------------------------------------------------------------------+
1222
1224
1223 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1225 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1224 contain a series of *delta*s, densely packed (no separators). These deltas
1226 contain a series of *delta*s, densely packed (no separators). These deltas
1225 describe a diff from an existing entry (either that the recipient already
1227 describe a diff from an existing entry (either that the recipient already
1226 has, or previously specified in the bundle/changegroup). The format is
1228 has, or previously specified in the bundle/changegroup). The format is
1227 described more fully in "hg help internals.bdiff", but briefly:
1229 described more fully in "hg help internals.bdiff", but briefly:
1228
1230
1229 +---------------------------------------------------------------+
1231 +---------------------------------------------------------------+
1230 | | | | |
1232 | | | | |
1231 | start offset | end offset | new length | content |
1233 | start offset | end offset | new length | content |
1232 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1234 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1233 | | | | |
1235 | | | | |
1234 +---------------------------------------------------------------+
1236 +---------------------------------------------------------------+
1235
1237
1236 Please note that the length field in the delta data does *not* include
1238 Please note that the length field in the delta data does *not* include
1237 itself.
1239 itself.
1238
1240
1239 In version 1, the delta is always applied against the previous node from
1241 In version 1, the delta is always applied against the previous node from
1240 the changegroup or the first parent if this is the first entry in the
1242 the changegroup or the first parent if this is the first entry in the
1241 changegroup.
1243 changegroup.
1242
1244
1243 In version 2 and up, the delta base node is encoded in the entry in the
1245 In version 2 and up, the delta base node is encoded in the entry in the
1244 changegroup. This allows the delta to be expressed against any parent,
1246 changegroup. This allows the delta to be expressed against any parent,
1245 which can result in smaller deltas and more efficient encoding of data.
1247 which can result in smaller deltas and more efficient encoding of data.
1246
1248
1247 The *flags* field holds bitwise flags affecting the processing of revision
1249 The *flags* field holds bitwise flags affecting the processing of revision
1248 data. The following flags are defined:
1250 data. The following flags are defined:
1249
1251
1250 32768
1252 32768
1251 Censored revision. The revision's fulltext has been replaced by censor
1253 Censored revision. The revision's fulltext has been replaced by censor
1252 metadata. May only occur on file revisions.
1254 metadata. May only occur on file revisions.
1253
1255
1254 16384
1256 16384
1255 Ellipsis revision. Revision hash does not match data (likely due to
1257 Ellipsis revision. Revision hash does not match data (likely due to
1256 rewritten parents).
1258 rewritten parents).
1257
1259
1258 8192
1260 8192
1259 Externally stored. The revision fulltext contains "key:value" "\n"
1261 Externally stored. The revision fulltext contains "key:value" "\n"
1260 delimited metadata defining an object stored elsewhere. Used by the LFS
1262 delimited metadata defining an object stored elsewhere. Used by the LFS
1261 extension.
1263 extension.
1262
1264
1263 For historical reasons, the integer values are identical to revlog version
1265 For historical reasons, the integer values are identical to revlog version
1264 1 per-revision storage flags and correspond to bits being set in this
1266 1 per-revision storage flags and correspond to bits being set in this
1265 2-byte field. Bits were allocated starting from the most-significant bit,
1267 2-byte field. Bits were allocated starting from the most-significant bit,
1266 hence the reverse ordering and allocation of these flags.
1268 hence the reverse ordering and allocation of these flags.
1267
1269
1268 Changeset Segment
1270 Changeset Segment
1269 =================
1271 =================
1270
1272
1271 The *changeset segment* consists of a single *delta group* holding
1273 The *changeset segment* consists of a single *delta group* holding
1272 changelog data. The *empty chunk* at the end of the *delta group* denotes
1274 changelog data. The *empty chunk* at the end of the *delta group* denotes
1273 the boundary to the *manifest segment*.
1275 the boundary to the *manifest segment*.
1274
1276
1275 Manifest Segment
1277 Manifest Segment
1276 ================
1278 ================
1277
1279
1278 The *manifest segment* consists of a single *delta group* holding manifest
1280 The *manifest segment* consists of a single *delta group* holding manifest
1279 data. If treemanifests are in use, it contains only the manifest for the
1281 data. If treemanifests are in use, it contains only the manifest for the
1280 root directory of the repository. Otherwise, it contains the entire
1282 root directory of the repository. Otherwise, it contains the entire
1281 manifest data. The *empty chunk* at the end of the *delta group* denotes
1283 manifest data. The *empty chunk* at the end of the *delta group* denotes
1282 the boundary to the next segment (either the *treemanifests segment* or
1284 the boundary to the next segment (either the *treemanifests segment* or
1283 the *filelogs segment*, depending on version and the request options).
1285 the *filelogs segment*, depending on version and the request options).
1284
1286
1285 Treemanifests Segment
1287 Treemanifests Segment
1286 ---------------------
1288 ---------------------
1287
1289
1288 The *treemanifests segment* only exists in changegroup version "3", and
1290 The *treemanifests segment* only exists in changegroup version "3", and
1289 only if the 'treemanifest' param is part of the bundle2 changegroup part
1291 only if the 'treemanifest' param is part of the bundle2 changegroup part
1290 (it is not possible to use changegroup version 3 outside of bundle2).
1292 (it is not possible to use changegroup version 3 outside of bundle2).
1291 Aside from the filenames in the *treemanifests segment* containing a
1293 Aside from the filenames in the *treemanifests segment* containing a
1292 trailing "/" character, it behaves identically to the *filelogs segment*
1294 trailing "/" character, it behaves identically to the *filelogs segment*
1293 (see below). The final sub-segment is followed by an *empty chunk*
1295 (see below). The final sub-segment is followed by an *empty chunk*
1294 (logically, a sub-segment with filename size 0). This denotes the boundary
1296 (logically, a sub-segment with filename size 0). This denotes the boundary
1295 to the *filelogs segment*.
1297 to the *filelogs segment*.
1296
1298
1297 Filelogs Segment
1299 Filelogs Segment
1298 ================
1300 ================
1299
1301
1300 The *filelogs segment* consists of multiple sub-segments, each
1302 The *filelogs segment* consists of multiple sub-segments, each
1301 corresponding to an individual file whose data is being described:
1303 corresponding to an individual file whose data is being described:
1302
1304
1303 +--------------------------------------------------+
1305 +--------------------------------------------------+
1304 | | | | | |
1306 | | | | | |
1305 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1307 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1306 | | | | | (4 bytes) |
1308 | | | | | (4 bytes) |
1307 | | | | | |
1309 | | | | | |
1308 +--------------------------------------------------+
1310 +--------------------------------------------------+
1309
1311
1310 The final filelog sub-segment is followed by an *empty chunk* (logically,
1312 The final filelog sub-segment is followed by an *empty chunk* (logically,
1311 a sub-segment with filename size 0). This denotes the end of the segment
1313 a sub-segment with filename size 0). This denotes the end of the segment
1312 and of the overall changegroup.
1314 and of the overall changegroup.
1313
1315
1314 Each filelog sub-segment consists of the following:
1316 Each filelog sub-segment consists of the following:
1315
1317
1316 +------------------------------------------------------+
1318 +------------------------------------------------------+
1317 | | | |
1319 | | | |
1318 | filename length | filename | delta group |
1320 | filename length | filename | delta group |
1319 | (4 bytes) | (<length - 4> bytes) | (various) |
1321 | (4 bytes) | (<length - 4> bytes) | (various) |
1320 | | | |
1322 | | | |
1321 +------------------------------------------------------+
1323 +------------------------------------------------------+
1322
1324
1323 That is, a *chunk* consisting of the filename (not terminated or padded)
1325 That is, a *chunk* consisting of the filename (not terminated or padded)
1324 followed by N chunks constituting the *delta group* for this file. The
1326 followed by N chunks constituting the *delta group* for this file. The
1325 *empty chunk* at the end of each *delta group* denotes the boundary to the
1327 *empty chunk* at the end of each *delta group* denotes the boundary to the
1326 next filelog sub-segment.
1328 next filelog sub-segment.
1327
1329
1328 non-existent subtopics print an error
1330 non-existent subtopics print an error
1329
1331
1330 $ hg help internals.foo
1332 $ hg help internals.foo
1331 abort: no such help topic: internals.foo
1333 abort: no such help topic: internals.foo
1332 (try 'hg help --keyword foo')
1334 (try 'hg help --keyword foo')
1333 [255]
1335 [255]
1334
1336
1335 test advanced, deprecated and experimental options are hidden in command help
1337 test advanced, deprecated and experimental options are hidden in command help
1336 $ hg help debugoptADV
1338 $ hg help debugoptADV
1337 hg debugoptADV
1339 hg debugoptADV
1338
1340
1339 (no help text available)
1341 (no help text available)
1340
1342
1341 options:
1343 options:
1342
1344
1343 (some details hidden, use --verbose to show complete help)
1345 (some details hidden, use --verbose to show complete help)
1344 $ hg help debugoptDEP
1346 $ hg help debugoptDEP
1345 hg debugoptDEP
1347 hg debugoptDEP
1346
1348
1347 (no help text available)
1349 (no help text available)
1348
1350
1349 options:
1351 options:
1350
1352
1351 (some details hidden, use --verbose to show complete help)
1353 (some details hidden, use --verbose to show complete help)
1352
1354
1353 $ hg help debugoptEXP
1355 $ hg help debugoptEXP
1354 hg debugoptEXP
1356 hg debugoptEXP
1355
1357
1356 (no help text available)
1358 (no help text available)
1357
1359
1358 options:
1360 options:
1359
1361
1360 (some details hidden, use --verbose to show complete help)
1362 (some details hidden, use --verbose to show complete help)
1361
1363
1362 test advanced, deprecated and experimental options are shown with -v
1364 test advanced, deprecated and experimental options are shown with -v
1363 $ hg help -v debugoptADV | grep aopt
1365 $ hg help -v debugoptADV | grep aopt
1364 --aopt option is (ADVANCED)
1366 --aopt option is (ADVANCED)
1365 $ hg help -v debugoptDEP | grep dopt
1367 $ hg help -v debugoptDEP | grep dopt
1366 --dopt option is (DEPRECATED)
1368 --dopt option is (DEPRECATED)
1367 $ hg help -v debugoptEXP | grep eopt
1369 $ hg help -v debugoptEXP | grep eopt
1368 --eopt option is (EXPERIMENTAL)
1370 --eopt option is (EXPERIMENTAL)
1369
1371
1370 #if gettext
1372 #if gettext
1371 test deprecated option is hidden with translation with untranslated description
1373 test deprecated option is hidden with translation with untranslated description
1372 (use many globy for not failing on changed transaction)
1374 (use many globy for not failing on changed transaction)
1373 $ LANGUAGE=sv hg help debugoptDEP
1375 $ LANGUAGE=sv hg help debugoptDEP
1374 hg debugoptDEP
1376 hg debugoptDEP
1375
1377
1376 (*) (glob)
1378 (*) (glob)
1377
1379
1378 options:
1380 options:
1379
1381
1380 (some details hidden, use --verbose to show complete help)
1382 (some details hidden, use --verbose to show complete help)
1381 #endif
1383 #endif
1382
1384
1383 Test commands that collide with topics (issue4240)
1385 Test commands that collide with topics (issue4240)
1384
1386
1385 $ hg config -hq
1387 $ hg config -hq
1386 hg config [-u] [NAME]...
1388 hg config [-u] [NAME]...
1387
1389
1388 show combined config settings from all hgrc files
1390 show combined config settings from all hgrc files
1389 $ hg showconfig -hq
1391 $ hg showconfig -hq
1390 hg config [-u] [NAME]...
1392 hg config [-u] [NAME]...
1391
1393
1392 show combined config settings from all hgrc files
1394 show combined config settings from all hgrc files
1393
1395
1394 Test a help topic
1396 Test a help topic
1395
1397
1396 $ hg help dates
1398 $ hg help dates
1397 Date Formats
1399 Date Formats
1398 """"""""""""
1400 """"""""""""
1399
1401
1400 Some commands allow the user to specify a date, e.g.:
1402 Some commands allow the user to specify a date, e.g.:
1401
1403
1402 - backout, commit, import, tag: Specify the commit date.
1404 - backout, commit, import, tag: Specify the commit date.
1403 - log, revert, update: Select revision(s) by date.
1405 - log, revert, update: Select revision(s) by date.
1404
1406
1405 Many date formats are valid. Here are some examples:
1407 Many date formats are valid. Here are some examples:
1406
1408
1407 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1409 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1408 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1410 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1409 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1411 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1410 - "Dec 6" (midnight)
1412 - "Dec 6" (midnight)
1411 - "13:18" (today assumed)
1413 - "13:18" (today assumed)
1412 - "3:39" (3:39AM assumed)
1414 - "3:39" (3:39AM assumed)
1413 - "3:39pm" (15:39)
1415 - "3:39pm" (15:39)
1414 - "2006-12-06 13:18:29" (ISO 8601 format)
1416 - "2006-12-06 13:18:29" (ISO 8601 format)
1415 - "2006-12-6 13:18"
1417 - "2006-12-6 13:18"
1416 - "2006-12-6"
1418 - "2006-12-6"
1417 - "12-6"
1419 - "12-6"
1418 - "12/6"
1420 - "12/6"
1419 - "12/6/6" (Dec 6 2006)
1421 - "12/6/6" (Dec 6 2006)
1420 - "today" (midnight)
1422 - "today" (midnight)
1421 - "yesterday" (midnight)
1423 - "yesterday" (midnight)
1422 - "now" - right now
1424 - "now" - right now
1423
1425
1424 Lastly, there is Mercurial's internal format:
1426 Lastly, there is Mercurial's internal format:
1425
1427
1426 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1428 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1427
1429
1428 This is the internal representation format for dates. The first number is
1430 This is the internal representation format for dates. The first number is
1429 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1431 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1430 is the offset of the local timezone, in seconds west of UTC (negative if
1432 is the offset of the local timezone, in seconds west of UTC (negative if
1431 the timezone is east of UTC).
1433 the timezone is east of UTC).
1432
1434
1433 The log command also accepts date ranges:
1435 The log command also accepts date ranges:
1434
1436
1435 - "<DATE" - at or before a given date/time
1437 - "<DATE" - at or before a given date/time
1436 - ">DATE" - on or after a given date/time
1438 - ">DATE" - on or after a given date/time
1437 - "DATE to DATE" - a date range, inclusive
1439 - "DATE to DATE" - a date range, inclusive
1438 - "-DAYS" - within a given number of days of today
1440 - "-DAYS" - within a given number of days of today
1439
1441
1440 Test repeated config section name
1442 Test repeated config section name
1441
1443
1442 $ hg help config.host
1444 $ hg help config.host
1443 "http_proxy.host"
1445 "http_proxy.host"
1444 Host name and (optional) port of the proxy server, for example
1446 Host name and (optional) port of the proxy server, for example
1445 "myproxy:8000".
1447 "myproxy:8000".
1446
1448
1447 "smtp.host"
1449 "smtp.host"
1448 Host name of mail server, e.g. "mail.example.com".
1450 Host name of mail server, e.g. "mail.example.com".
1449
1451
1450
1452
1451 Test section name with dot
1453 Test section name with dot
1452
1454
1453 $ hg help config.ui.username
1455 $ hg help config.ui.username
1454 "ui.username"
1456 "ui.username"
1455 The committer of a changeset created when running "commit". Typically
1457 The committer of a changeset created when running "commit". Typically
1456 a person's name and email address, e.g. "Fred Widget
1458 a person's name and email address, e.g. "Fred Widget
1457 <fred@example.com>". Environment variables in the username are
1459 <fred@example.com>". Environment variables in the username are
1458 expanded.
1460 expanded.
1459
1461
1460 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1462 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1461 empty, e.g. if the system admin set "username =" in the system hgrc,
1463 empty, e.g. if the system admin set "username =" in the system hgrc,
1462 it has to be specified manually or in a different hgrc file)
1464 it has to be specified manually or in a different hgrc file)
1463
1465
1464
1466
1465 $ hg help config.annotate.git
1467 $ hg help config.annotate.git
1466 abort: help section not found: config.annotate.git
1468 abort: help section not found: config.annotate.git
1467 [255]
1469 [255]
1468
1470
1469 $ hg help config.update.check
1471 $ hg help config.update.check
1470 "commands.update.check"
1472 "commands.update.check"
1471 Determines what level of checking 'hg update' will perform before
1473 Determines what level of checking 'hg update' will perform before
1472 moving to a destination revision. Valid values are "abort", "none",
1474 moving to a destination revision. Valid values are "abort", "none",
1473 "linear", and "noconflict". "abort" always fails if the working
1475 "linear", and "noconflict". "abort" always fails if the working
1474 directory has uncommitted changes. "none" performs no checking, and
1476 directory has uncommitted changes. "none" performs no checking, and
1475 may result in a merge with uncommitted changes. "linear" allows any
1477 may result in a merge with uncommitted changes. "linear" allows any
1476 update as long as it follows a straight line in the revision history,
1478 update as long as it follows a straight line in the revision history,
1477 and may trigger a merge with uncommitted changes. "noconflict" will
1479 and may trigger a merge with uncommitted changes. "noconflict" will
1478 allow any update which would not trigger a merge with uncommitted
1480 allow any update which would not trigger a merge with uncommitted
1479 changes, if any are present. (default: "linear")
1481 changes, if any are present. (default: "linear")
1480
1482
1481
1483
1482 $ hg help config.commands.update.check
1484 $ hg help config.commands.update.check
1483 "commands.update.check"
1485 "commands.update.check"
1484 Determines what level of checking 'hg update' will perform before
1486 Determines what level of checking 'hg update' will perform before
1485 moving to a destination revision. Valid values are "abort", "none",
1487 moving to a destination revision. Valid values are "abort", "none",
1486 "linear", and "noconflict". "abort" always fails if the working
1488 "linear", and "noconflict". "abort" always fails if the working
1487 directory has uncommitted changes. "none" performs no checking, and
1489 directory has uncommitted changes. "none" performs no checking, and
1488 may result in a merge with uncommitted changes. "linear" allows any
1490 may result in a merge with uncommitted changes. "linear" allows any
1489 update as long as it follows a straight line in the revision history,
1491 update as long as it follows a straight line in the revision history,
1490 and may trigger a merge with uncommitted changes. "noconflict" will
1492 and may trigger a merge with uncommitted changes. "noconflict" will
1491 allow any update which would not trigger a merge with uncommitted
1493 allow any update which would not trigger a merge with uncommitted
1492 changes, if any are present. (default: "linear")
1494 changes, if any are present. (default: "linear")
1493
1495
1494
1496
1495 $ hg help config.ommands.update.check
1497 $ hg help config.ommands.update.check
1496 abort: help section not found: config.ommands.update.check
1498 abort: help section not found: config.ommands.update.check
1497 [255]
1499 [255]
1498
1500
1499 Unrelated trailing paragraphs shouldn't be included
1501 Unrelated trailing paragraphs shouldn't be included
1500
1502
1501 $ hg help config.extramsg | grep '^$'
1503 $ hg help config.extramsg | grep '^$'
1502
1504
1503
1505
1504 Test capitalized section name
1506 Test capitalized section name
1505
1507
1506 $ hg help scripting.HGPLAIN > /dev/null
1508 $ hg help scripting.HGPLAIN > /dev/null
1507
1509
1508 Help subsection:
1510 Help subsection:
1509
1511
1510 $ hg help config.charsets |grep "Email example:" > /dev/null
1512 $ hg help config.charsets |grep "Email example:" > /dev/null
1511 [1]
1513 [1]
1512
1514
1513 Show nested definitions
1515 Show nested definitions
1514 ("profiling.type"[break]"ls"[break]"stat"[break])
1516 ("profiling.type"[break]"ls"[break]"stat"[break])
1515
1517
1516 $ hg help config.type | egrep '^$'|wc -l
1518 $ hg help config.type | egrep '^$'|wc -l
1517 \s*3 (re)
1519 \s*3 (re)
1518
1520
1519 $ hg help config.profiling.type.ls
1521 $ hg help config.profiling.type.ls
1520 "profiling.type.ls"
1522 "profiling.type.ls"
1521 Use Python's built-in instrumenting profiler. This profiler works on
1523 Use Python's built-in instrumenting profiler. This profiler works on
1522 all platforms, but each line number it reports is the first line of
1524 all platforms, but each line number it reports is the first line of
1523 a function. This restriction makes it difficult to identify the
1525 a function. This restriction makes it difficult to identify the
1524 expensive parts of a non-trivial function.
1526 expensive parts of a non-trivial function.
1525
1527
1526
1528
1527 Separate sections from subsections
1529 Separate sections from subsections
1528
1530
1529 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1531 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1530 "format"
1532 "format"
1531 --------
1533 --------
1532
1534
1533 "usegeneraldelta"
1535 "usegeneraldelta"
1534
1536
1535 "dotencode"
1537 "dotencode"
1536
1538
1537 "usefncache"
1539 "usefncache"
1538
1540
1539 "usestore"
1541 "usestore"
1540
1542
1541 "sparse-revlog"
1543 "sparse-revlog"
1542
1544
1543 "revlog-compression"
1545 "revlog-compression"
1544
1546
1545 "bookmarks-in-store"
1547 "bookmarks-in-store"
1546
1548
1547 "profiling"
1549 "profiling"
1548 -----------
1550 -----------
1549
1551
1550 "format"
1552 "format"
1551
1553
1552 "progress"
1554 "progress"
1553 ----------
1555 ----------
1554
1556
1555 "format"
1557 "format"
1556
1558
1557
1559
1558 Last item in help config.*:
1560 Last item in help config.*:
1559
1561
1560 $ hg help config.`hg help config|grep '^ "'| \
1562 $ hg help config.`hg help config|grep '^ "'| \
1561 > tail -1|sed 's![ "]*!!g'`| \
1563 > tail -1|sed 's![ "]*!!g'`| \
1562 > grep 'hg help -c config' > /dev/null
1564 > grep 'hg help -c config' > /dev/null
1563 [1]
1565 [1]
1564
1566
1565 note to use help -c for general hg help config:
1567 note to use help -c for general hg help config:
1566
1568
1567 $ hg help config |grep 'hg help -c config' > /dev/null
1569 $ hg help config |grep 'hg help -c config' > /dev/null
1568
1570
1569 Test templating help
1571 Test templating help
1570
1572
1571 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1573 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1572 desc String. The text of the changeset description.
1574 desc String. The text of the changeset description.
1573 diffstat String. Statistics of changes with the following format:
1575 diffstat String. Statistics of changes with the following format:
1574 firstline Any text. Returns the first line of text.
1576 firstline Any text. Returns the first line of text.
1575 nonempty Any text. Returns '(none)' if the string is empty.
1577 nonempty Any text. Returns '(none)' if the string is empty.
1576
1578
1577 Test deprecated items
1579 Test deprecated items
1578
1580
1579 $ hg help -v templating | grep currentbookmark
1581 $ hg help -v templating | grep currentbookmark
1580 currentbookmark
1582 currentbookmark
1581 $ hg help templating | (grep currentbookmark || true)
1583 $ hg help templating | (grep currentbookmark || true)
1582
1584
1583 Test help hooks
1585 Test help hooks
1584
1586
1585 $ cat > helphook1.py <<EOF
1587 $ cat > helphook1.py <<EOF
1586 > from mercurial import help
1588 > from mercurial import help
1587 >
1589 >
1588 > def rewrite(ui, topic, doc):
1590 > def rewrite(ui, topic, doc):
1589 > return doc + b'\nhelphook1\n'
1591 > return doc + b'\nhelphook1\n'
1590 >
1592 >
1591 > def extsetup(ui):
1593 > def extsetup(ui):
1592 > help.addtopichook(b'revisions', rewrite)
1594 > help.addtopichook(b'revisions', rewrite)
1593 > EOF
1595 > EOF
1594 $ cat > helphook2.py <<EOF
1596 $ cat > helphook2.py <<EOF
1595 > from mercurial import help
1597 > from mercurial import help
1596 >
1598 >
1597 > def rewrite(ui, topic, doc):
1599 > def rewrite(ui, topic, doc):
1598 > return doc + b'\nhelphook2\n'
1600 > return doc + b'\nhelphook2\n'
1599 >
1601 >
1600 > def extsetup(ui):
1602 > def extsetup(ui):
1601 > help.addtopichook(b'revisions', rewrite)
1603 > help.addtopichook(b'revisions', rewrite)
1602 > EOF
1604 > EOF
1603 $ echo '[extensions]' >> $HGRCPATH
1605 $ echo '[extensions]' >> $HGRCPATH
1604 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1606 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1605 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1607 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1606 $ hg help revsets | grep helphook
1608 $ hg help revsets | grep helphook
1607 helphook1
1609 helphook1
1608 helphook2
1610 helphook2
1609
1611
1610 help -c should only show debug --debug
1612 help -c should only show debug --debug
1611
1613
1612 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1614 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1613 [1]
1615 [1]
1614
1616
1615 help -c should only show deprecated for -v
1617 help -c should only show deprecated for -v
1616
1618
1617 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1619 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1618 [1]
1620 [1]
1619
1621
1620 Test -s / --system
1622 Test -s / --system
1621
1623
1622 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1624 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1623 > wc -l | sed -e 's/ //g'
1625 > wc -l | sed -e 's/ //g'
1624 0
1626 0
1625 $ hg help config.files --system unix | grep 'USER' | \
1627 $ hg help config.files --system unix | grep 'USER' | \
1626 > wc -l | sed -e 's/ //g'
1628 > wc -l | sed -e 's/ //g'
1627 0
1629 0
1628
1630
1629 Test -e / -c / -k combinations
1631 Test -e / -c / -k combinations
1630
1632
1631 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1633 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1632 Commands:
1634 Commands:
1633 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1635 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1634 Extensions:
1636 Extensions:
1635 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1637 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1636 Topics:
1638 Topics:
1637 Commands:
1639 Commands:
1638 Extensions:
1640 Extensions:
1639 Extension Commands:
1641 Extension Commands:
1640 $ hg help -c schemes
1642 $ hg help -c schemes
1641 abort: no such help topic: schemes
1643 abort: no such help topic: schemes
1642 (try 'hg help --keyword schemes')
1644 (try 'hg help --keyword schemes')
1643 [255]
1645 [255]
1644 $ hg help -e schemes |head -1
1646 $ hg help -e schemes |head -1
1645 schemes extension - extend schemes with shortcuts to repository swarms
1647 schemes extension - extend schemes with shortcuts to repository swarms
1646 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1648 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1647 Commands:
1649 Commands:
1648 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1650 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1649 Extensions:
1651 Extensions:
1650 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1652 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1651 Extensions:
1653 Extensions:
1652 Commands:
1654 Commands:
1653 $ hg help -c commit > /dev/null
1655 $ hg help -c commit > /dev/null
1654 $ hg help -e -c commit > /dev/null
1656 $ hg help -e -c commit > /dev/null
1655 $ hg help -e commit
1657 $ hg help -e commit
1656 abort: no such help topic: commit
1658 abort: no such help topic: commit
1657 (try 'hg help --keyword commit')
1659 (try 'hg help --keyword commit')
1658 [255]
1660 [255]
1659
1661
1660 Test keyword search help
1662 Test keyword search help
1661
1663
1662 $ cat > prefixedname.py <<EOF
1664 $ cat > prefixedname.py <<EOF
1663 > '''matched against word "clone"
1665 > '''matched against word "clone"
1664 > '''
1666 > '''
1665 > EOF
1667 > EOF
1666 $ echo '[extensions]' >> $HGRCPATH
1668 $ echo '[extensions]' >> $HGRCPATH
1667 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1669 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1668 $ hg help -k clone
1670 $ hg help -k clone
1669 Topics:
1671 Topics:
1670
1672
1671 config Configuration Files
1673 config Configuration Files
1672 extensions Using Additional Features
1674 extensions Using Additional Features
1673 glossary Glossary
1675 glossary Glossary
1674 phases Working with Phases
1676 phases Working with Phases
1675 subrepos Subrepositories
1677 subrepos Subrepositories
1676 urls URL Paths
1678 urls URL Paths
1677
1679
1678 Commands:
1680 Commands:
1679
1681
1680 bookmarks create a new bookmark or list existing bookmarks
1682 bookmarks create a new bookmark or list existing bookmarks
1681 clone make a copy of an existing repository
1683 clone make a copy of an existing repository
1682 paths show aliases for remote repositories
1684 paths show aliases for remote repositories
1683 pull pull changes from the specified source
1685 pull pull changes from the specified source
1684 update update working directory (or switch revisions)
1686 update update working directory (or switch revisions)
1685
1687
1686 Extensions:
1688 Extensions:
1687
1689
1688 clonebundles advertise pre-generated bundles to seed clones
1690 clonebundles advertise pre-generated bundles to seed clones
1689 narrow create clones which fetch history data for subset of files
1691 narrow create clones which fetch history data for subset of files
1690 (EXPERIMENTAL)
1692 (EXPERIMENTAL)
1691 prefixedname matched against word "clone"
1693 prefixedname matched against word "clone"
1692 relink recreates hardlinks between repository clones
1694 relink recreates hardlinks between repository clones
1693
1695
1694 Extension Commands:
1696 Extension Commands:
1695
1697
1696 qclone clone main and patch repository at same time
1698 qclone clone main and patch repository at same time
1697
1699
1698 Test unfound topic
1700 Test unfound topic
1699
1701
1700 $ hg help nonexistingtopicthatwillneverexisteverever
1702 $ hg help nonexistingtopicthatwillneverexisteverever
1701 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1703 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1702 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1704 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1703 [255]
1705 [255]
1704
1706
1705 Test unfound keyword
1707 Test unfound keyword
1706
1708
1707 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1709 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1708 abort: no matches
1710 abort: no matches
1709 (try 'hg help' for a list of topics)
1711 (try 'hg help' for a list of topics)
1710 [255]
1712 [255]
1711
1713
1712 Test omit indicating for help
1714 Test omit indicating for help
1713
1715
1714 $ cat > addverboseitems.py <<EOF
1716 $ cat > addverboseitems.py <<EOF
1715 > r'''extension to test omit indicating.
1717 > r'''extension to test omit indicating.
1716 >
1718 >
1717 > This paragraph is never omitted (for extension)
1719 > This paragraph is never omitted (for extension)
1718 >
1720 >
1719 > .. container:: verbose
1721 > .. container:: verbose
1720 >
1722 >
1721 > This paragraph is omitted,
1723 > This paragraph is omitted,
1722 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1724 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1723 >
1725 >
1724 > This paragraph is never omitted, too (for extension)
1726 > This paragraph is never omitted, too (for extension)
1725 > '''
1727 > '''
1726 > from __future__ import absolute_import
1728 > from __future__ import absolute_import
1727 > from mercurial import commands, help
1729 > from mercurial import commands, help
1728 > testtopic = br"""This paragraph is never omitted (for topic).
1730 > testtopic = br"""This paragraph is never omitted (for topic).
1729 >
1731 >
1730 > .. container:: verbose
1732 > .. container:: verbose
1731 >
1733 >
1732 > This paragraph is omitted,
1734 > This paragraph is omitted,
1733 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1735 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1734 >
1736 >
1735 > This paragraph is never omitted, too (for topic)
1737 > This paragraph is never omitted, too (for topic)
1736 > """
1738 > """
1737 > def extsetup(ui):
1739 > def extsetup(ui):
1738 > help.helptable.append(([b"topic-containing-verbose"],
1740 > help.helptable.append(([b"topic-containing-verbose"],
1739 > b"This is the topic to test omit indicating.",
1741 > b"This is the topic to test omit indicating.",
1740 > lambda ui: testtopic))
1742 > lambda ui: testtopic))
1741 > EOF
1743 > EOF
1742 $ echo '[extensions]' >> $HGRCPATH
1744 $ echo '[extensions]' >> $HGRCPATH
1743 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1745 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1744 $ hg help addverboseitems
1746 $ hg help addverboseitems
1745 addverboseitems extension - extension to test omit indicating.
1747 addverboseitems extension - extension to test omit indicating.
1746
1748
1747 This paragraph is never omitted (for extension)
1749 This paragraph is never omitted (for extension)
1748
1750
1749 This paragraph is never omitted, too (for extension)
1751 This paragraph is never omitted, too (for extension)
1750
1752
1751 (some details hidden, use --verbose to show complete help)
1753 (some details hidden, use --verbose to show complete help)
1752
1754
1753 no commands defined
1755 no commands defined
1754 $ hg help -v addverboseitems
1756 $ hg help -v addverboseitems
1755 addverboseitems extension - extension to test omit indicating.
1757 addverboseitems extension - extension to test omit indicating.
1756
1758
1757 This paragraph is never omitted (for extension)
1759 This paragraph is never omitted (for extension)
1758
1760
1759 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1761 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1760 extension)
1762 extension)
1761
1763
1762 This paragraph is never omitted, too (for extension)
1764 This paragraph is never omitted, too (for extension)
1763
1765
1764 no commands defined
1766 no commands defined
1765 $ hg help topic-containing-verbose
1767 $ hg help topic-containing-verbose
1766 This is the topic to test omit indicating.
1768 This is the topic to test omit indicating.
1767 """"""""""""""""""""""""""""""""""""""""""
1769 """"""""""""""""""""""""""""""""""""""""""
1768
1770
1769 This paragraph is never omitted (for topic).
1771 This paragraph is never omitted (for topic).
1770
1772
1771 This paragraph is never omitted, too (for topic)
1773 This paragraph is never omitted, too (for topic)
1772
1774
1773 (some details hidden, use --verbose to show complete help)
1775 (some details hidden, use --verbose to show complete help)
1774 $ hg help -v topic-containing-verbose
1776 $ hg help -v topic-containing-verbose
1775 This is the topic to test omit indicating.
1777 This is the topic to test omit indicating.
1776 """"""""""""""""""""""""""""""""""""""""""
1778 """"""""""""""""""""""""""""""""""""""""""
1777
1779
1778 This paragraph is never omitted (for topic).
1780 This paragraph is never omitted (for topic).
1779
1781
1780 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1782 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1781 topic)
1783 topic)
1782
1784
1783 This paragraph is never omitted, too (for topic)
1785 This paragraph is never omitted, too (for topic)
1784
1786
1785 Test section lookup
1787 Test section lookup
1786
1788
1787 $ hg help revset.merge
1789 $ hg help revset.merge
1788 "merge()"
1790 "merge()"
1789 Changeset is a merge changeset.
1791 Changeset is a merge changeset.
1790
1792
1791 $ hg help glossary.dag
1793 $ hg help glossary.dag
1792 DAG
1794 DAG
1793 The repository of changesets of a distributed version control system
1795 The repository of changesets of a distributed version control system
1794 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1796 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1795 of nodes and edges, where nodes correspond to changesets and edges
1797 of nodes and edges, where nodes correspond to changesets and edges
1796 imply a parent -> child relation. This graph can be visualized by
1798 imply a parent -> child relation. This graph can be visualized by
1797 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1799 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1798 limited by the requirement for children to have at most two parents.
1800 limited by the requirement for children to have at most two parents.
1799
1801
1800
1802
1801 $ hg help hgrc.paths
1803 $ hg help hgrc.paths
1802 "paths"
1804 "paths"
1803 -------
1805 -------
1804
1806
1805 Assigns symbolic names and behavior to repositories.
1807 Assigns symbolic names and behavior to repositories.
1806
1808
1807 Options are symbolic names defining the URL or directory that is the
1809 Options are symbolic names defining the URL or directory that is the
1808 location of the repository. Example:
1810 location of the repository. Example:
1809
1811
1810 [paths]
1812 [paths]
1811 my_server = https://example.com/my_repo
1813 my_server = https://example.com/my_repo
1812 local_path = /home/me/repo
1814 local_path = /home/me/repo
1813
1815
1814 These symbolic names can be used from the command line. To pull from
1816 These symbolic names can be used from the command line. To pull from
1815 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1817 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1816 local_path'.
1818 local_path'.
1817
1819
1818 Options containing colons (":") denote sub-options that can influence
1820 Options containing colons (":") denote sub-options that can influence
1819 behavior for that specific path. Example:
1821 behavior for that specific path. Example:
1820
1822
1821 [paths]
1823 [paths]
1822 my_server = https://example.com/my_path
1824 my_server = https://example.com/my_path
1823 my_server:pushurl = ssh://example.com/my_path
1825 my_server:pushurl = ssh://example.com/my_path
1824
1826
1825 The following sub-options can be defined:
1827 The following sub-options can be defined:
1826
1828
1827 "pushurl"
1829 "pushurl"
1828 The URL to use for push operations. If not defined, the location
1830 The URL to use for push operations. If not defined, the location
1829 defined by the path's main entry is used.
1831 defined by the path's main entry is used.
1830
1832
1831 "pushrev"
1833 "pushrev"
1832 A revset defining which revisions to push by default.
1834 A revset defining which revisions to push by default.
1833
1835
1834 When 'hg push' is executed without a "-r" argument, the revset defined
1836 When 'hg push' is executed without a "-r" argument, the revset defined
1835 by this sub-option is evaluated to determine what to push.
1837 by this sub-option is evaluated to determine what to push.
1836
1838
1837 For example, a value of "." will push the working directory's revision
1839 For example, a value of "." will push the working directory's revision
1838 by default.
1840 by default.
1839
1841
1840 Revsets specifying bookmarks will not result in the bookmark being
1842 Revsets specifying bookmarks will not result in the bookmark being
1841 pushed.
1843 pushed.
1842
1844
1843 The following special named paths exist:
1845 The following special named paths exist:
1844
1846
1845 "default"
1847 "default"
1846 The URL or directory to use when no source or remote is specified.
1848 The URL or directory to use when no source or remote is specified.
1847
1849
1848 'hg clone' will automatically define this path to the location the
1850 'hg clone' will automatically define this path to the location the
1849 repository was cloned from.
1851 repository was cloned from.
1850
1852
1851 "default-push"
1853 "default-push"
1852 (deprecated) The URL or directory for the default 'hg push' location.
1854 (deprecated) The URL or directory for the default 'hg push' location.
1853 "default:pushurl" should be used instead.
1855 "default:pushurl" should be used instead.
1854
1856
1855 $ hg help glossary.mcguffin
1857 $ hg help glossary.mcguffin
1856 abort: help section not found: glossary.mcguffin
1858 abort: help section not found: glossary.mcguffin
1857 [255]
1859 [255]
1858
1860
1859 $ hg help glossary.mc.guffin
1861 $ hg help glossary.mc.guffin
1860 abort: help section not found: glossary.mc.guffin
1862 abort: help section not found: glossary.mc.guffin
1861 [255]
1863 [255]
1862
1864
1863 $ hg help template.files
1865 $ hg help template.files
1864 files List of strings. All files modified, added, or removed by
1866 files List of strings. All files modified, added, or removed by
1865 this changeset.
1867 this changeset.
1866 files(pattern)
1868 files(pattern)
1867 All files of the current changeset matching the pattern. See
1869 All files of the current changeset matching the pattern. See
1868 'hg help patterns'.
1870 'hg help patterns'.
1869
1871
1870 Test section lookup by translated message
1872 Test section lookup by translated message
1871
1873
1872 str.lower() instead of encoding.lower(str) on translated message might
1874 str.lower() instead of encoding.lower(str) on translated message might
1873 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1875 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1874 as the second or later byte of multi-byte character.
1876 as the second or later byte of multi-byte character.
1875
1877
1876 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1878 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1877 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1879 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1878 replacement makes message meaningless.
1880 replacement makes message meaningless.
1879
1881
1880 This tests that section lookup by translated string isn't broken by
1882 This tests that section lookup by translated string isn't broken by
1881 such str.lower().
1883 such str.lower().
1882
1884
1883 $ "$PYTHON" <<EOF
1885 $ "$PYTHON" <<EOF
1884 > def escape(s):
1886 > def escape(s):
1885 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1887 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1886 > # translation of "record" in ja_JP.cp932
1888 > # translation of "record" in ja_JP.cp932
1887 > upper = b"\x8bL\x98^"
1889 > upper = b"\x8bL\x98^"
1888 > # str.lower()-ed section name should be treated as different one
1890 > # str.lower()-ed section name should be treated as different one
1889 > lower = b"\x8bl\x98^"
1891 > lower = b"\x8bl\x98^"
1890 > with open('ambiguous.py', 'wb') as fp:
1892 > with open('ambiguous.py', 'wb') as fp:
1891 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1893 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1892 > u'''summary of extension
1894 > u'''summary of extension
1893 >
1895 >
1894 > %s
1896 > %s
1895 > ----
1897 > ----
1896 >
1898 >
1897 > Upper name should show only this message
1899 > Upper name should show only this message
1898 >
1900 >
1899 > %s
1901 > %s
1900 > ----
1902 > ----
1901 >
1903 >
1902 > Lower name should show only this message
1904 > Lower name should show only this message
1903 >
1905 >
1904 > subsequent section
1906 > subsequent section
1905 > ------------------
1907 > ------------------
1906 >
1908 >
1907 > This should be hidden at 'hg help ambiguous' with section name.
1909 > This should be hidden at 'hg help ambiguous' with section name.
1908 > '''
1910 > '''
1909 > """ % (escape(upper), escape(lower)))
1911 > """ % (escape(upper), escape(lower)))
1910 > EOF
1912 > EOF
1911
1913
1912 $ cat >> $HGRCPATH <<EOF
1914 $ cat >> $HGRCPATH <<EOF
1913 > [extensions]
1915 > [extensions]
1914 > ambiguous = ./ambiguous.py
1916 > ambiguous = ./ambiguous.py
1915 > EOF
1917 > EOF
1916
1918
1917 $ "$PYTHON" <<EOF | sh
1919 $ "$PYTHON" <<EOF | sh
1918 > from mercurial import pycompat
1920 > from mercurial import pycompat
1919 > upper = b"\x8bL\x98^"
1921 > upper = b"\x8bL\x98^"
1920 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1922 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1921 > EOF
1923 > EOF
1922 \x8bL\x98^ (esc)
1924 \x8bL\x98^ (esc)
1923 ----
1925 ----
1924
1926
1925 Upper name should show only this message
1927 Upper name should show only this message
1926
1928
1927
1929
1928 $ "$PYTHON" <<EOF | sh
1930 $ "$PYTHON" <<EOF | sh
1929 > from mercurial import pycompat
1931 > from mercurial import pycompat
1930 > lower = b"\x8bl\x98^"
1932 > lower = b"\x8bl\x98^"
1931 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1933 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1932 > EOF
1934 > EOF
1933 \x8bl\x98^ (esc)
1935 \x8bl\x98^ (esc)
1934 ----
1936 ----
1935
1937
1936 Lower name should show only this message
1938 Lower name should show only this message
1937
1939
1938
1940
1939 $ cat >> $HGRCPATH <<EOF
1941 $ cat >> $HGRCPATH <<EOF
1940 > [extensions]
1942 > [extensions]
1941 > ambiguous = !
1943 > ambiguous = !
1942 > EOF
1944 > EOF
1943
1945
1944 Show help content of disabled extensions
1946 Show help content of disabled extensions
1945
1947
1946 $ cat >> $HGRCPATH <<EOF
1948 $ cat >> $HGRCPATH <<EOF
1947 > [extensions]
1949 > [extensions]
1948 > ambiguous = !./ambiguous.py
1950 > ambiguous = !./ambiguous.py
1949 > EOF
1951 > EOF
1950 $ hg help -e ambiguous
1952 $ hg help -e ambiguous
1951 ambiguous extension - (no help text available)
1953 ambiguous extension - (no help text available)
1952
1954
1953 (use 'hg help extensions' for information on enabling extensions)
1955 (use 'hg help extensions' for information on enabling extensions)
1954
1956
1955 Test dynamic list of merge tools only shows up once
1957 Test dynamic list of merge tools only shows up once
1956 $ hg help merge-tools
1958 $ hg help merge-tools
1957 Merge Tools
1959 Merge Tools
1958 """""""""""
1960 """""""""""
1959
1961
1960 To merge files Mercurial uses merge tools.
1962 To merge files Mercurial uses merge tools.
1961
1963
1962 A merge tool combines two different versions of a file into a merged file.
1964 A merge tool combines two different versions of a file into a merged file.
1963 Merge tools are given the two files and the greatest common ancestor of
1965 Merge tools are given the two files and the greatest common ancestor of
1964 the two file versions, so they can determine the changes made on both
1966 the two file versions, so they can determine the changes made on both
1965 branches.
1967 branches.
1966
1968
1967 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1969 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1968 backout' and in several extensions.
1970 backout' and in several extensions.
1969
1971
1970 Usually, the merge tool tries to automatically reconcile the files by
1972 Usually, the merge tool tries to automatically reconcile the files by
1971 combining all non-overlapping changes that occurred separately in the two
1973 combining all non-overlapping changes that occurred separately in the two
1972 different evolutions of the same initial base file. Furthermore, some
1974 different evolutions of the same initial base file. Furthermore, some
1973 interactive merge programs make it easier to manually resolve conflicting
1975 interactive merge programs make it easier to manually resolve conflicting
1974 merges, either in a graphical way, or by inserting some conflict markers.
1976 merges, either in a graphical way, or by inserting some conflict markers.
1975 Mercurial does not include any interactive merge programs but relies on
1977 Mercurial does not include any interactive merge programs but relies on
1976 external tools for that.
1978 external tools for that.
1977
1979
1978 Available merge tools
1980 Available merge tools
1979 =====================
1981 =====================
1980
1982
1981 External merge tools and their properties are configured in the merge-
1983 External merge tools and their properties are configured in the merge-
1982 tools configuration section - see hgrc(5) - but they can often just be
1984 tools configuration section - see hgrc(5) - but they can often just be
1983 named by their executable.
1985 named by their executable.
1984
1986
1985 A merge tool is generally usable if its executable can be found on the
1987 A merge tool is generally usable if its executable can be found on the
1986 system and if it can handle the merge. The executable is found if it is an
1988 system and if it can handle the merge. The executable is found if it is an
1987 absolute or relative executable path or the name of an application in the
1989 absolute or relative executable path or the name of an application in the
1988 executable search path. The tool is assumed to be able to handle the merge
1990 executable search path. The tool is assumed to be able to handle the merge
1989 if it can handle symlinks if the file is a symlink, if it can handle
1991 if it can handle symlinks if the file is a symlink, if it can handle
1990 binary files if the file is binary, and if a GUI is available if the tool
1992 binary files if the file is binary, and if a GUI is available if the tool
1991 requires a GUI.
1993 requires a GUI.
1992
1994
1993 There are some internal merge tools which can be used. The internal merge
1995 There are some internal merge tools which can be used. The internal merge
1994 tools are:
1996 tools are:
1995
1997
1996 ":dump"
1998 ":dump"
1997 Creates three versions of the files to merge, containing the contents of
1999 Creates three versions of the files to merge, containing the contents of
1998 local, other and base. These files can then be used to perform a merge
2000 local, other and base. These files can then be used to perform a merge
1999 manually. If the file to be merged is named "a.txt", these files will
2001 manually. If the file to be merged is named "a.txt", these files will
2000 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2002 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2001 they will be placed in the same directory as "a.txt".
2003 they will be placed in the same directory as "a.txt".
2002
2004
2003 This implies premerge. Therefore, files aren't dumped, if premerge runs
2005 This implies premerge. Therefore, files aren't dumped, if premerge runs
2004 successfully. Use :forcedump to forcibly write files out.
2006 successfully. Use :forcedump to forcibly write files out.
2005
2007
2006 (actual capabilities: binary, symlink)
2008 (actual capabilities: binary, symlink)
2007
2009
2008 ":fail"
2010 ":fail"
2009 Rather than attempting to merge files that were modified on both
2011 Rather than attempting to merge files that were modified on both
2010 branches, it marks them as unresolved. The resolve command must be used
2012 branches, it marks them as unresolved. The resolve command must be used
2011 to resolve these conflicts.
2013 to resolve these conflicts.
2012
2014
2013 (actual capabilities: binary, symlink)
2015 (actual capabilities: binary, symlink)
2014
2016
2015 ":forcedump"
2017 ":forcedump"
2016 Creates three versions of the files as same as :dump, but omits
2018 Creates three versions of the files as same as :dump, but omits
2017 premerge.
2019 premerge.
2018
2020
2019 (actual capabilities: binary, symlink)
2021 (actual capabilities: binary, symlink)
2020
2022
2021 ":local"
2023 ":local"
2022 Uses the local 'p1()' version of files as the merged version.
2024 Uses the local 'p1()' version of files as the merged version.
2023
2025
2024 (actual capabilities: binary, symlink)
2026 (actual capabilities: binary, symlink)
2025
2027
2026 ":merge"
2028 ":merge"
2027 Uses the internal non-interactive simple merge algorithm for merging
2029 Uses the internal non-interactive simple merge algorithm for merging
2028 files. It will fail if there are any conflicts and leave markers in the
2030 files. It will fail if there are any conflicts and leave markers in the
2029 partially merged file. Markers will have two sections, one for each side
2031 partially merged file. Markers will have two sections, one for each side
2030 of merge.
2032 of merge.
2031
2033
2032 ":merge-local"
2034 ":merge-local"
2033 Like :merge, but resolve all conflicts non-interactively in favor of the
2035 Like :merge, but resolve all conflicts non-interactively in favor of the
2034 local 'p1()' changes.
2036 local 'p1()' changes.
2035
2037
2036 ":merge-other"
2038 ":merge-other"
2037 Like :merge, but resolve all conflicts non-interactively in favor of the
2039 Like :merge, but resolve all conflicts non-interactively in favor of the
2038 other 'p2()' changes.
2040 other 'p2()' changes.
2039
2041
2040 ":merge3"
2042 ":merge3"
2041 Uses the internal non-interactive simple merge algorithm for merging
2043 Uses the internal non-interactive simple merge algorithm for merging
2042 files. It will fail if there are any conflicts and leave markers in the
2044 files. It will fail if there are any conflicts and leave markers in the
2043 partially merged file. Marker will have three sections, one from each
2045 partially merged file. Marker will have three sections, one from each
2044 side of the merge and one for the base content.
2046 side of the merge and one for the base content.
2045
2047
2046 ":other"
2048 ":other"
2047 Uses the other 'p2()' version of files as the merged version.
2049 Uses the other 'p2()' version of files as the merged version.
2048
2050
2049 (actual capabilities: binary, symlink)
2051 (actual capabilities: binary, symlink)
2050
2052
2051 ":prompt"
2053 ":prompt"
2052 Asks the user which of the local 'p1()' or the other 'p2()' version to
2054 Asks the user which of the local 'p1()' or the other 'p2()' version to
2053 keep as the merged version.
2055 keep as the merged version.
2054
2056
2055 (actual capabilities: binary, symlink)
2057 (actual capabilities: binary, symlink)
2056
2058
2057 ":tagmerge"
2059 ":tagmerge"
2058 Uses the internal tag merge algorithm (experimental).
2060 Uses the internal tag merge algorithm (experimental).
2059
2061
2060 ":union"
2062 ":union"
2061 Uses the internal non-interactive simple merge algorithm for merging
2063 Uses the internal non-interactive simple merge algorithm for merging
2062 files. It will use both left and right sides for conflict regions. No
2064 files. It will use both left and right sides for conflict regions. No
2063 markers are inserted.
2065 markers are inserted.
2064
2066
2065 Internal tools are always available and do not require a GUI but will by
2067 Internal tools are always available and do not require a GUI but will by
2066 default not handle symlinks or binary files. See next section for detail
2068 default not handle symlinks or binary files. See next section for detail
2067 about "actual capabilities" described above.
2069 about "actual capabilities" described above.
2068
2070
2069 Choosing a merge tool
2071 Choosing a merge tool
2070 =====================
2072 =====================
2071
2073
2072 Mercurial uses these rules when deciding which merge tool to use:
2074 Mercurial uses these rules when deciding which merge tool to use:
2073
2075
2074 1. If a tool has been specified with the --tool option to merge or
2076 1. If a tool has been specified with the --tool option to merge or
2075 resolve, it is used. If it is the name of a tool in the merge-tools
2077 resolve, it is used. If it is the name of a tool in the merge-tools
2076 configuration, its configuration is used. Otherwise the specified tool
2078 configuration, its configuration is used. Otherwise the specified tool
2077 must be executable by the shell.
2079 must be executable by the shell.
2078 2. If the "HGMERGE" environment variable is present, its value is used and
2080 2. If the "HGMERGE" environment variable is present, its value is used and
2079 must be executable by the shell.
2081 must be executable by the shell.
2080 3. If the filename of the file to be merged matches any of the patterns in
2082 3. If the filename of the file to be merged matches any of the patterns in
2081 the merge-patterns configuration section, the first usable merge tool
2083 the merge-patterns configuration section, the first usable merge tool
2082 corresponding to a matching pattern is used.
2084 corresponding to a matching pattern is used.
2083 4. If ui.merge is set it will be considered next. If the value is not the
2085 4. If ui.merge is set it will be considered next. If the value is not the
2084 name of a configured tool, the specified value is used and must be
2086 name of a configured tool, the specified value is used and must be
2085 executable by the shell. Otherwise the named tool is used if it is
2087 executable by the shell. Otherwise the named tool is used if it is
2086 usable.
2088 usable.
2087 5. If any usable merge tools are present in the merge-tools configuration
2089 5. If any usable merge tools are present in the merge-tools configuration
2088 section, the one with the highest priority is used.
2090 section, the one with the highest priority is used.
2089 6. If a program named "hgmerge" can be found on the system, it is used -
2091 6. If a program named "hgmerge" can be found on the system, it is used -
2090 but it will by default not be used for symlinks and binary files.
2092 but it will by default not be used for symlinks and binary files.
2091 7. If the file to be merged is not binary and is not a symlink, then
2093 7. If the file to be merged is not binary and is not a symlink, then
2092 internal ":merge" is used.
2094 internal ":merge" is used.
2093 8. Otherwise, ":prompt" is used.
2095 8. Otherwise, ":prompt" is used.
2094
2096
2095 For historical reason, Mercurial treats merge tools as below while
2097 For historical reason, Mercurial treats merge tools as below while
2096 examining rules above.
2098 examining rules above.
2097
2099
2098 step specified via binary symlink
2100 step specified via binary symlink
2099 ----------------------------------
2101 ----------------------------------
2100 1. --tool o/o o/o
2102 1. --tool o/o o/o
2101 2. HGMERGE o/o o/o
2103 2. HGMERGE o/o o/o
2102 3. merge-patterns o/o(*) x/?(*)
2104 3. merge-patterns o/o(*) x/?(*)
2103 4. ui.merge x/?(*) x/?(*)
2105 4. ui.merge x/?(*) x/?(*)
2104
2106
2105 Each capability column indicates Mercurial behavior for internal/external
2107 Each capability column indicates Mercurial behavior for internal/external
2106 merge tools at examining each rule.
2108 merge tools at examining each rule.
2107
2109
2108 - "o": "assume that a tool has capability"
2110 - "o": "assume that a tool has capability"
2109 - "x": "assume that a tool does not have capability"
2111 - "x": "assume that a tool does not have capability"
2110 - "?": "check actual capability of a tool"
2112 - "?": "check actual capability of a tool"
2111
2113
2112 If "merge.strict-capability-check" configuration is true, Mercurial checks
2114 If "merge.strict-capability-check" configuration is true, Mercurial checks
2113 capabilities of merge tools strictly in (*) cases above (= each capability
2115 capabilities of merge tools strictly in (*) cases above (= each capability
2114 column becomes "?/?"). It is false by default for backward compatibility.
2116 column becomes "?/?"). It is false by default for backward compatibility.
2115
2117
2116 Note:
2118 Note:
2117 After selecting a merge program, Mercurial will by default attempt to
2119 After selecting a merge program, Mercurial will by default attempt to
2118 merge the files using a simple merge algorithm first. Only if it
2120 merge the files using a simple merge algorithm first. Only if it
2119 doesn't succeed because of conflicting changes will Mercurial actually
2121 doesn't succeed because of conflicting changes will Mercurial actually
2120 execute the merge program. Whether to use the simple merge algorithm
2122 execute the merge program. Whether to use the simple merge algorithm
2121 first can be controlled by the premerge setting of the merge tool.
2123 first can be controlled by the premerge setting of the merge tool.
2122 Premerge is enabled by default unless the file is binary or a symlink.
2124 Premerge is enabled by default unless the file is binary or a symlink.
2123
2125
2124 See the merge-tools and ui sections of hgrc(5) for details on the
2126 See the merge-tools and ui sections of hgrc(5) for details on the
2125 configuration of merge tools.
2127 configuration of merge tools.
2126
2128
2127 Compression engines listed in `hg help bundlespec`
2129 Compression engines listed in `hg help bundlespec`
2128
2130
2129 $ hg help bundlespec | grep gzip
2131 $ hg help bundlespec | grep gzip
2130 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2132 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2131 An algorithm that produces smaller bundles than "gzip".
2133 An algorithm that produces smaller bundles than "gzip".
2132 This engine will likely produce smaller bundles than "gzip" but will be
2134 This engine will likely produce smaller bundles than "gzip" but will be
2133 "gzip"
2135 "gzip"
2134 better compression than "gzip". It also frequently yields better (?)
2136 better compression than "gzip". It also frequently yields better (?)
2135
2137
2136 Test usage of section marks in help documents
2138 Test usage of section marks in help documents
2137
2139
2138 $ cd "$TESTDIR"/../doc
2140 $ cd "$TESTDIR"/../doc
2139 $ "$PYTHON" check-seclevel.py
2141 $ "$PYTHON" check-seclevel.py
2140 $ cd $TESTTMP
2142 $ cd $TESTTMP
2141
2143
2142 #if serve
2144 #if serve
2143
2145
2144 Test the help pages in hgweb.
2146 Test the help pages in hgweb.
2145
2147
2146 Dish up an empty repo; serve it cold.
2148 Dish up an empty repo; serve it cold.
2147
2149
2148 $ hg init "$TESTTMP/test"
2150 $ hg init "$TESTTMP/test"
2149 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2151 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2150 $ cat hg.pid >> $DAEMON_PIDS
2152 $ cat hg.pid >> $DAEMON_PIDS
2151
2153
2152 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2154 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2153 200 Script output follows
2155 200 Script output follows
2154
2156
2155 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2157 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2156 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2158 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2157 <head>
2159 <head>
2158 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2160 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2159 <meta name="robots" content="index, nofollow" />
2161 <meta name="robots" content="index, nofollow" />
2160 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2162 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2161 <script type="text/javascript" src="/static/mercurial.js"></script>
2163 <script type="text/javascript" src="/static/mercurial.js"></script>
2162
2164
2163 <title>Help: Index</title>
2165 <title>Help: Index</title>
2164 </head>
2166 </head>
2165 <body>
2167 <body>
2166
2168
2167 <div class="container">
2169 <div class="container">
2168 <div class="menu">
2170 <div class="menu">
2169 <div class="logo">
2171 <div class="logo">
2170 <a href="https://mercurial-scm.org/">
2172 <a href="https://mercurial-scm.org/">
2171 <img src="/static/hglogo.png" alt="mercurial" /></a>
2173 <img src="/static/hglogo.png" alt="mercurial" /></a>
2172 </div>
2174 </div>
2173 <ul>
2175 <ul>
2174 <li><a href="/shortlog">log</a></li>
2176 <li><a href="/shortlog">log</a></li>
2175 <li><a href="/graph">graph</a></li>
2177 <li><a href="/graph">graph</a></li>
2176 <li><a href="/tags">tags</a></li>
2178 <li><a href="/tags">tags</a></li>
2177 <li><a href="/bookmarks">bookmarks</a></li>
2179 <li><a href="/bookmarks">bookmarks</a></li>
2178 <li><a href="/branches">branches</a></li>
2180 <li><a href="/branches">branches</a></li>
2179 </ul>
2181 </ul>
2180 <ul>
2182 <ul>
2181 <li class="active">help</li>
2183 <li class="active">help</li>
2182 </ul>
2184 </ul>
2183 </div>
2185 </div>
2184
2186
2185 <div class="main">
2187 <div class="main">
2186 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2188 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2187
2189
2188 <form class="search" action="/log">
2190 <form class="search" action="/log">
2189
2191
2190 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2192 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2191 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2193 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2192 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2194 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2193 </form>
2195 </form>
2194 <table class="bigtable">
2196 <table class="bigtable">
2195 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2197 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2196
2198
2197 <tr><td>
2199 <tr><td>
2198 <a href="/help/bundlespec">
2200 <a href="/help/bundlespec">
2199 bundlespec
2201 bundlespec
2200 </a>
2202 </a>
2201 </td><td>
2203 </td><td>
2202 Bundle File Formats
2204 Bundle File Formats
2203 </td></tr>
2205 </td></tr>
2204 <tr><td>
2206 <tr><td>
2205 <a href="/help/color">
2207 <a href="/help/color">
2206 color
2208 color
2207 </a>
2209 </a>
2208 </td><td>
2210 </td><td>
2209 Colorizing Outputs
2211 Colorizing Outputs
2210 </td></tr>
2212 </td></tr>
2211 <tr><td>
2213 <tr><td>
2212 <a href="/help/config">
2214 <a href="/help/config">
2213 config
2215 config
2214 </a>
2216 </a>
2215 </td><td>
2217 </td><td>
2216 Configuration Files
2218 Configuration Files
2217 </td></tr>
2219 </td></tr>
2218 <tr><td>
2220 <tr><td>
2219 <a href="/help/dates">
2221 <a href="/help/dates">
2220 dates
2222 dates
2221 </a>
2223 </a>
2222 </td><td>
2224 </td><td>
2223 Date Formats
2225 Date Formats
2224 </td></tr>
2226 </td></tr>
2225 <tr><td>
2227 <tr><td>
2226 <a href="/help/deprecated">
2228 <a href="/help/deprecated">
2227 deprecated
2229 deprecated
2228 </a>
2230 </a>
2229 </td><td>
2231 </td><td>
2230 Deprecated Features
2232 Deprecated Features
2231 </td></tr>
2233 </td></tr>
2232 <tr><td>
2234 <tr><td>
2233 <a href="/help/diffs">
2235 <a href="/help/diffs">
2234 diffs
2236 diffs
2235 </a>
2237 </a>
2236 </td><td>
2238 </td><td>
2237 Diff Formats
2239 Diff Formats
2238 </td></tr>
2240 </td></tr>
2239 <tr><td>
2241 <tr><td>
2240 <a href="/help/environment">
2242 <a href="/help/environment">
2241 environment
2243 environment
2242 </a>
2244 </a>
2243 </td><td>
2245 </td><td>
2244 Environment Variables
2246 Environment Variables
2245 </td></tr>
2247 </td></tr>
2246 <tr><td>
2248 <tr><td>
2247 <a href="/help/extensions">
2249 <a href="/help/extensions">
2248 extensions
2250 extensions
2249 </a>
2251 </a>
2250 </td><td>
2252 </td><td>
2251 Using Additional Features
2253 Using Additional Features
2252 </td></tr>
2254 </td></tr>
2253 <tr><td>
2255 <tr><td>
2254 <a href="/help/filesets">
2256 <a href="/help/filesets">
2255 filesets
2257 filesets
2256 </a>
2258 </a>
2257 </td><td>
2259 </td><td>
2258 Specifying File Sets
2260 Specifying File Sets
2259 </td></tr>
2261 </td></tr>
2260 <tr><td>
2262 <tr><td>
2261 <a href="/help/flags">
2263 <a href="/help/flags">
2262 flags
2264 flags
2263 </a>
2265 </a>
2264 </td><td>
2266 </td><td>
2265 Command-line flags
2267 Command-line flags
2266 </td></tr>
2268 </td></tr>
2267 <tr><td>
2269 <tr><td>
2268 <a href="/help/glossary">
2270 <a href="/help/glossary">
2269 glossary
2271 glossary
2270 </a>
2272 </a>
2271 </td><td>
2273 </td><td>
2272 Glossary
2274 Glossary
2273 </td></tr>
2275 </td></tr>
2274 <tr><td>
2276 <tr><td>
2275 <a href="/help/hgignore">
2277 <a href="/help/hgignore">
2276 hgignore
2278 hgignore
2277 </a>
2279 </a>
2278 </td><td>
2280 </td><td>
2279 Syntax for Mercurial Ignore Files
2281 Syntax for Mercurial Ignore Files
2280 </td></tr>
2282 </td></tr>
2281 <tr><td>
2283 <tr><td>
2282 <a href="/help/hgweb">
2284 <a href="/help/hgweb">
2283 hgweb
2285 hgweb
2284 </a>
2286 </a>
2285 </td><td>
2287 </td><td>
2286 Configuring hgweb
2288 Configuring hgweb
2287 </td></tr>
2289 </td></tr>
2288 <tr><td>
2290 <tr><td>
2289 <a href="/help/internals">
2291 <a href="/help/internals">
2290 internals
2292 internals
2291 </a>
2293 </a>
2292 </td><td>
2294 </td><td>
2293 Technical implementation topics
2295 Technical implementation topics
2294 </td></tr>
2296 </td></tr>
2295 <tr><td>
2297 <tr><td>
2296 <a href="/help/merge-tools">
2298 <a href="/help/merge-tools">
2297 merge-tools
2299 merge-tools
2298 </a>
2300 </a>
2299 </td><td>
2301 </td><td>
2300 Merge Tools
2302 Merge Tools
2301 </td></tr>
2303 </td></tr>
2302 <tr><td>
2304 <tr><td>
2303 <a href="/help/pager">
2305 <a href="/help/pager">
2304 pager
2306 pager
2305 </a>
2307 </a>
2306 </td><td>
2308 </td><td>
2307 Pager Support
2309 Pager Support
2308 </td></tr>
2310 </td></tr>
2309 <tr><td>
2311 <tr><td>
2310 <a href="/help/patterns">
2312 <a href="/help/patterns">
2311 patterns
2313 patterns
2312 </a>
2314 </a>
2313 </td><td>
2315 </td><td>
2314 File Name Patterns
2316 File Name Patterns
2315 </td></tr>
2317 </td></tr>
2316 <tr><td>
2318 <tr><td>
2317 <a href="/help/phases">
2319 <a href="/help/phases">
2318 phases
2320 phases
2319 </a>
2321 </a>
2320 </td><td>
2322 </td><td>
2321 Working with Phases
2323 Working with Phases
2322 </td></tr>
2324 </td></tr>
2323 <tr><td>
2325 <tr><td>
2324 <a href="/help/revisions">
2326 <a href="/help/revisions">
2325 revisions
2327 revisions
2326 </a>
2328 </a>
2327 </td><td>
2329 </td><td>
2328 Specifying Revisions
2330 Specifying Revisions
2329 </td></tr>
2331 </td></tr>
2330 <tr><td>
2332 <tr><td>
2331 <a href="/help/scripting">
2333 <a href="/help/scripting">
2332 scripting
2334 scripting
2333 </a>
2335 </a>
2334 </td><td>
2336 </td><td>
2335 Using Mercurial from scripts and automation
2337 Using Mercurial from scripts and automation
2336 </td></tr>
2338 </td></tr>
2337 <tr><td>
2339 <tr><td>
2338 <a href="/help/subrepos">
2340 <a href="/help/subrepos">
2339 subrepos
2341 subrepos
2340 </a>
2342 </a>
2341 </td><td>
2343 </td><td>
2342 Subrepositories
2344 Subrepositories
2343 </td></tr>
2345 </td></tr>
2344 <tr><td>
2346 <tr><td>
2345 <a href="/help/templating">
2347 <a href="/help/templating">
2346 templating
2348 templating
2347 </a>
2349 </a>
2348 </td><td>
2350 </td><td>
2349 Template Usage
2351 Template Usage
2350 </td></tr>
2352 </td></tr>
2351 <tr><td>
2353 <tr><td>
2352 <a href="/help/urls">
2354 <a href="/help/urls">
2353 urls
2355 urls
2354 </a>
2356 </a>
2355 </td><td>
2357 </td><td>
2356 URL Paths
2358 URL Paths
2357 </td></tr>
2359 </td></tr>
2358 <tr><td>
2360 <tr><td>
2359 <a href="/help/topic-containing-verbose">
2361 <a href="/help/topic-containing-verbose">
2360 topic-containing-verbose
2362 topic-containing-verbose
2361 </a>
2363 </a>
2362 </td><td>
2364 </td><td>
2363 This is the topic to test omit indicating.
2365 This is the topic to test omit indicating.
2364 </td></tr>
2366 </td></tr>
2365
2367
2366
2368
2367 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2369 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2368
2370
2369 <tr><td>
2371 <tr><td>
2370 <a href="/help/abort">
2372 <a href="/help/abort">
2371 abort
2373 abort
2372 </a>
2374 </a>
2373 </td><td>
2375 </td><td>
2374 abort an unfinished operation (EXPERIMENTAL)
2376 abort an unfinished operation (EXPERIMENTAL)
2375 </td></tr>
2377 </td></tr>
2376 <tr><td>
2378 <tr><td>
2377 <a href="/help/add">
2379 <a href="/help/add">
2378 add
2380 add
2379 </a>
2381 </a>
2380 </td><td>
2382 </td><td>
2381 add the specified files on the next commit
2383 add the specified files on the next commit
2382 </td></tr>
2384 </td></tr>
2383 <tr><td>
2385 <tr><td>
2384 <a href="/help/annotate">
2386 <a href="/help/annotate">
2385 annotate
2387 annotate
2386 </a>
2388 </a>
2387 </td><td>
2389 </td><td>
2388 show changeset information by line for each file
2390 show changeset information by line for each file
2389 </td></tr>
2391 </td></tr>
2390 <tr><td>
2392 <tr><td>
2391 <a href="/help/clone">
2393 <a href="/help/clone">
2392 clone
2394 clone
2393 </a>
2395 </a>
2394 </td><td>
2396 </td><td>
2395 make a copy of an existing repository
2397 make a copy of an existing repository
2396 </td></tr>
2398 </td></tr>
2397 <tr><td>
2399 <tr><td>
2398 <a href="/help/commit">
2400 <a href="/help/commit">
2399 commit
2401 commit
2400 </a>
2402 </a>
2401 </td><td>
2403 </td><td>
2402 commit the specified files or all outstanding changes
2404 commit the specified files or all outstanding changes
2403 </td></tr>
2405 </td></tr>
2404 <tr><td>
2406 <tr><td>
2405 <a href="/help/continue">
2407 <a href="/help/continue">
2406 continue
2408 continue
2407 </a>
2409 </a>
2408 </td><td>
2410 </td><td>
2409 resumes an interrupted operation (EXPERIMENTAL)
2411 resumes an interrupted operation (EXPERIMENTAL)
2410 </td></tr>
2412 </td></tr>
2411 <tr><td>
2413 <tr><td>
2412 <a href="/help/diff">
2414 <a href="/help/diff">
2413 diff
2415 diff
2414 </a>
2416 </a>
2415 </td><td>
2417 </td><td>
2416 diff repository (or selected files)
2418 diff repository (or selected files)
2417 </td></tr>
2419 </td></tr>
2418 <tr><td>
2420 <tr><td>
2419 <a href="/help/export">
2421 <a href="/help/export">
2420 export
2422 export
2421 </a>
2423 </a>
2422 </td><td>
2424 </td><td>
2423 dump the header and diffs for one or more changesets
2425 dump the header and diffs for one or more changesets
2424 </td></tr>
2426 </td></tr>
2425 <tr><td>
2427 <tr><td>
2426 <a href="/help/forget">
2428 <a href="/help/forget">
2427 forget
2429 forget
2428 </a>
2430 </a>
2429 </td><td>
2431 </td><td>
2430 forget the specified files on the next commit
2432 forget the specified files on the next commit
2431 </td></tr>
2433 </td></tr>
2432 <tr><td>
2434 <tr><td>
2433 <a href="/help/init">
2435 <a href="/help/init">
2434 init
2436 init
2435 </a>
2437 </a>
2436 </td><td>
2438 </td><td>
2437 create a new repository in the given directory
2439 create a new repository in the given directory
2438 </td></tr>
2440 </td></tr>
2439 <tr><td>
2441 <tr><td>
2440 <a href="/help/log">
2442 <a href="/help/log">
2441 log
2443 log
2442 </a>
2444 </a>
2443 </td><td>
2445 </td><td>
2444 show revision history of entire repository or files
2446 show revision history of entire repository or files
2445 </td></tr>
2447 </td></tr>
2446 <tr><td>
2448 <tr><td>
2447 <a href="/help/merge">
2449 <a href="/help/merge">
2448 merge
2450 merge
2449 </a>
2451 </a>
2450 </td><td>
2452 </td><td>
2451 merge another revision into working directory
2453 merge another revision into working directory
2452 </td></tr>
2454 </td></tr>
2453 <tr><td>
2455 <tr><td>
2454 <a href="/help/pull">
2456 <a href="/help/pull">
2455 pull
2457 pull
2456 </a>
2458 </a>
2457 </td><td>
2459 </td><td>
2458 pull changes from the specified source
2460 pull changes from the specified source
2459 </td></tr>
2461 </td></tr>
2460 <tr><td>
2462 <tr><td>
2461 <a href="/help/push">
2463 <a href="/help/push">
2462 push
2464 push
2463 </a>
2465 </a>
2464 </td><td>
2466 </td><td>
2465 push changes to the specified destination
2467 push changes to the specified destination
2466 </td></tr>
2468 </td></tr>
2467 <tr><td>
2469 <tr><td>
2468 <a href="/help/remove">
2470 <a href="/help/remove">
2469 remove
2471 remove
2470 </a>
2472 </a>
2471 </td><td>
2473 </td><td>
2472 remove the specified files on the next commit
2474 remove the specified files on the next commit
2473 </td></tr>
2475 </td></tr>
2474 <tr><td>
2476 <tr><td>
2475 <a href="/help/serve">
2477 <a href="/help/serve">
2476 serve
2478 serve
2477 </a>
2479 </a>
2478 </td><td>
2480 </td><td>
2479 start stand-alone webserver
2481 start stand-alone webserver
2480 </td></tr>
2482 </td></tr>
2481 <tr><td>
2483 <tr><td>
2482 <a href="/help/status">
2484 <a href="/help/status">
2483 status
2485 status
2484 </a>
2486 </a>
2485 </td><td>
2487 </td><td>
2486 show changed files in the working directory
2488 show changed files in the working directory
2487 </td></tr>
2489 </td></tr>
2488 <tr><td>
2490 <tr><td>
2489 <a href="/help/summary">
2491 <a href="/help/summary">
2490 summary
2492 summary
2491 </a>
2493 </a>
2492 </td><td>
2494 </td><td>
2493 summarize working directory state
2495 summarize working directory state
2494 </td></tr>
2496 </td></tr>
2495 <tr><td>
2497 <tr><td>
2496 <a href="/help/update">
2498 <a href="/help/update">
2497 update
2499 update
2498 </a>
2500 </a>
2499 </td><td>
2501 </td><td>
2500 update working directory (or switch revisions)
2502 update working directory (or switch revisions)
2501 </td></tr>
2503 </td></tr>
2502
2504
2503
2505
2504
2506
2505 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2507 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2506
2508
2507 <tr><td>
2509 <tr><td>
2508 <a href="/help/addremove">
2510 <a href="/help/addremove">
2509 addremove
2511 addremove
2510 </a>
2512 </a>
2511 </td><td>
2513 </td><td>
2512 add all new files, delete all missing files
2514 add all new files, delete all missing files
2513 </td></tr>
2515 </td></tr>
2514 <tr><td>
2516 <tr><td>
2515 <a href="/help/archive">
2517 <a href="/help/archive">
2516 archive
2518 archive
2517 </a>
2519 </a>
2518 </td><td>
2520 </td><td>
2519 create an unversioned archive of a repository revision
2521 create an unversioned archive of a repository revision
2520 </td></tr>
2522 </td></tr>
2521 <tr><td>
2523 <tr><td>
2522 <a href="/help/backout">
2524 <a href="/help/backout">
2523 backout
2525 backout
2524 </a>
2526 </a>
2525 </td><td>
2527 </td><td>
2526 reverse effect of earlier changeset
2528 reverse effect of earlier changeset
2527 </td></tr>
2529 </td></tr>
2528 <tr><td>
2530 <tr><td>
2529 <a href="/help/bisect">
2531 <a href="/help/bisect">
2530 bisect
2532 bisect
2531 </a>
2533 </a>
2532 </td><td>
2534 </td><td>
2533 subdivision search of changesets
2535 subdivision search of changesets
2534 </td></tr>
2536 </td></tr>
2535 <tr><td>
2537 <tr><td>
2536 <a href="/help/bookmarks">
2538 <a href="/help/bookmarks">
2537 bookmarks
2539 bookmarks
2538 </a>
2540 </a>
2539 </td><td>
2541 </td><td>
2540 create a new bookmark or list existing bookmarks
2542 create a new bookmark or list existing bookmarks
2541 </td></tr>
2543 </td></tr>
2542 <tr><td>
2544 <tr><td>
2543 <a href="/help/branch">
2545 <a href="/help/branch">
2544 branch
2546 branch
2545 </a>
2547 </a>
2546 </td><td>
2548 </td><td>
2547 set or show the current branch name
2549 set or show the current branch name
2548 </td></tr>
2550 </td></tr>
2549 <tr><td>
2551 <tr><td>
2550 <a href="/help/branches">
2552 <a href="/help/branches">
2551 branches
2553 branches
2552 </a>
2554 </a>
2553 </td><td>
2555 </td><td>
2554 list repository named branches
2556 list repository named branches
2555 </td></tr>
2557 </td></tr>
2556 <tr><td>
2558 <tr><td>
2557 <a href="/help/bundle">
2559 <a href="/help/bundle">
2558 bundle
2560 bundle
2559 </a>
2561 </a>
2560 </td><td>
2562 </td><td>
2561 create a bundle file
2563 create a bundle file
2562 </td></tr>
2564 </td></tr>
2563 <tr><td>
2565 <tr><td>
2564 <a href="/help/cat">
2566 <a href="/help/cat">
2565 cat
2567 cat
2566 </a>
2568 </a>
2567 </td><td>
2569 </td><td>
2568 output the current or given revision of files
2570 output the current or given revision of files
2569 </td></tr>
2571 </td></tr>
2570 <tr><td>
2572 <tr><td>
2571 <a href="/help/config">
2573 <a href="/help/config">
2572 config
2574 config
2573 </a>
2575 </a>
2574 </td><td>
2576 </td><td>
2575 show combined config settings from all hgrc files
2577 show combined config settings from all hgrc files
2576 </td></tr>
2578 </td></tr>
2577 <tr><td>
2579 <tr><td>
2578 <a href="/help/copy">
2580 <a href="/help/copy">
2579 copy
2581 copy
2580 </a>
2582 </a>
2581 </td><td>
2583 </td><td>
2582 mark files as copied for the next commit
2584 mark files as copied for the next commit
2583 </td></tr>
2585 </td></tr>
2584 <tr><td>
2586 <tr><td>
2585 <a href="/help/files">
2587 <a href="/help/files">
2586 files
2588 files
2587 </a>
2589 </a>
2588 </td><td>
2590 </td><td>
2589 list tracked files
2591 list tracked files
2590 </td></tr>
2592 </td></tr>
2591 <tr><td>
2593 <tr><td>
2592 <a href="/help/graft">
2594 <a href="/help/graft">
2593 graft
2595 graft
2594 </a>
2596 </a>
2595 </td><td>
2597 </td><td>
2596 copy changes from other branches onto the current branch
2598 copy changes from other branches onto the current branch
2597 </td></tr>
2599 </td></tr>
2598 <tr><td>
2600 <tr><td>
2599 <a href="/help/grep">
2601 <a href="/help/grep">
2600 grep
2602 grep
2601 </a>
2603 </a>
2602 </td><td>
2604 </td><td>
2603 search for a pattern in specified files
2605 search for a pattern in specified files
2604 </td></tr>
2606 </td></tr>
2605 <tr><td>
2607 <tr><td>
2606 <a href="/help/hashelp">
2608 <a href="/help/hashelp">
2607 hashelp
2609 hashelp
2608 </a>
2610 </a>
2609 </td><td>
2611 </td><td>
2610 Extension command's help
2612 Extension command's help
2611 </td></tr>
2613 </td></tr>
2612 <tr><td>
2614 <tr><td>
2613 <a href="/help/heads">
2615 <a href="/help/heads">
2614 heads
2616 heads
2615 </a>
2617 </a>
2616 </td><td>
2618 </td><td>
2617 show branch heads
2619 show branch heads
2618 </td></tr>
2620 </td></tr>
2619 <tr><td>
2621 <tr><td>
2620 <a href="/help/help">
2622 <a href="/help/help">
2621 help
2623 help
2622 </a>
2624 </a>
2623 </td><td>
2625 </td><td>
2624 show help for a given topic or a help overview
2626 show help for a given topic or a help overview
2625 </td></tr>
2627 </td></tr>
2626 <tr><td>
2628 <tr><td>
2627 <a href="/help/hgalias">
2629 <a href="/help/hgalias">
2628 hgalias
2630 hgalias
2629 </a>
2631 </a>
2630 </td><td>
2632 </td><td>
2631 My doc
2633 My doc
2632 </td></tr>
2634 </td></tr>
2633 <tr><td>
2635 <tr><td>
2634 <a href="/help/hgaliasnodoc">
2636 <a href="/help/hgaliasnodoc">
2635 hgaliasnodoc
2637 hgaliasnodoc
2636 </a>
2638 </a>
2637 </td><td>
2639 </td><td>
2638 summarize working directory state
2640 summarize working directory state
2639 </td></tr>
2641 </td></tr>
2640 <tr><td>
2642 <tr><td>
2641 <a href="/help/identify">
2643 <a href="/help/identify">
2642 identify
2644 identify
2643 </a>
2645 </a>
2644 </td><td>
2646 </td><td>
2645 identify the working directory or specified revision
2647 identify the working directory or specified revision
2646 </td></tr>
2648 </td></tr>
2647 <tr><td>
2649 <tr><td>
2648 <a href="/help/import">
2650 <a href="/help/import">
2649 import
2651 import
2650 </a>
2652 </a>
2651 </td><td>
2653 </td><td>
2652 import an ordered set of patches
2654 import an ordered set of patches
2653 </td></tr>
2655 </td></tr>
2654 <tr><td>
2656 <tr><td>
2655 <a href="/help/incoming">
2657 <a href="/help/incoming">
2656 incoming
2658 incoming
2657 </a>
2659 </a>
2658 </td><td>
2660 </td><td>
2659 show new changesets found in source
2661 show new changesets found in source
2660 </td></tr>
2662 </td></tr>
2661 <tr><td>
2663 <tr><td>
2662 <a href="/help/manifest">
2664 <a href="/help/manifest">
2663 manifest
2665 manifest
2664 </a>
2666 </a>
2665 </td><td>
2667 </td><td>
2666 output the current or given revision of the project manifest
2668 output the current or given revision of the project manifest
2667 </td></tr>
2669 </td></tr>
2668 <tr><td>
2670 <tr><td>
2669 <a href="/help/nohelp">
2671 <a href="/help/nohelp">
2670 nohelp
2672 nohelp
2671 </a>
2673 </a>
2672 </td><td>
2674 </td><td>
2673 (no help text available)
2675 (no help text available)
2674 </td></tr>
2676 </td></tr>
2675 <tr><td>
2677 <tr><td>
2676 <a href="/help/outgoing">
2678 <a href="/help/outgoing">
2677 outgoing
2679 outgoing
2678 </a>
2680 </a>
2679 </td><td>
2681 </td><td>
2680 show changesets not found in the destination
2682 show changesets not found in the destination
2681 </td></tr>
2683 </td></tr>
2682 <tr><td>
2684 <tr><td>
2683 <a href="/help/paths">
2685 <a href="/help/paths">
2684 paths
2686 paths
2685 </a>
2687 </a>
2686 </td><td>
2688 </td><td>
2687 show aliases for remote repositories
2689 show aliases for remote repositories
2688 </td></tr>
2690 </td></tr>
2689 <tr><td>
2691 <tr><td>
2690 <a href="/help/phase">
2692 <a href="/help/phase">
2691 phase
2693 phase
2692 </a>
2694 </a>
2693 </td><td>
2695 </td><td>
2694 set or show the current phase name
2696 set or show the current phase name
2695 </td></tr>
2697 </td></tr>
2696 <tr><td>
2698 <tr><td>
2697 <a href="/help/recover">
2699 <a href="/help/recover">
2698 recover
2700 recover
2699 </a>
2701 </a>
2700 </td><td>
2702 </td><td>
2701 roll back an interrupted transaction
2703 roll back an interrupted transaction
2702 </td></tr>
2704 </td></tr>
2703 <tr><td>
2705 <tr><td>
2704 <a href="/help/rename">
2706 <a href="/help/rename">
2705 rename
2707 rename
2706 </a>
2708 </a>
2707 </td><td>
2709 </td><td>
2708 rename files; equivalent of copy + remove
2710 rename files; equivalent of copy + remove
2709 </td></tr>
2711 </td></tr>
2710 <tr><td>
2712 <tr><td>
2711 <a href="/help/resolve">
2713 <a href="/help/resolve">
2712 resolve
2714 resolve
2713 </a>
2715 </a>
2714 </td><td>
2716 </td><td>
2715 redo merges or set/view the merge status of files
2717 redo merges or set/view the merge status of files
2716 </td></tr>
2718 </td></tr>
2717 <tr><td>
2719 <tr><td>
2718 <a href="/help/revert">
2720 <a href="/help/revert">
2719 revert
2721 revert
2720 </a>
2722 </a>
2721 </td><td>
2723 </td><td>
2722 restore files to their checkout state
2724 restore files to their checkout state
2723 </td></tr>
2725 </td></tr>
2724 <tr><td>
2726 <tr><td>
2725 <a href="/help/root">
2727 <a href="/help/root">
2726 root
2728 root
2727 </a>
2729 </a>
2728 </td><td>
2730 </td><td>
2729 print the root (top) of the current working directory
2731 print the root (top) of the current working directory
2730 </td></tr>
2732 </td></tr>
2731 <tr><td>
2733 <tr><td>
2732 <a href="/help/shellalias">
2734 <a href="/help/shellalias">
2733 shellalias
2735 shellalias
2734 </a>
2736 </a>
2735 </td><td>
2737 </td><td>
2736 (no help text available)
2738 (no help text available)
2737 </td></tr>
2739 </td></tr>
2738 <tr><td>
2740 <tr><td>
2739 <a href="/help/shelve">
2741 <a href="/help/shelve">
2740 shelve
2742 shelve
2741 </a>
2743 </a>
2742 </td><td>
2744 </td><td>
2743 save and set aside changes from the working directory
2745 save and set aside changes from the working directory
2744 </td></tr>
2746 </td></tr>
2745 <tr><td>
2747 <tr><td>
2746 <a href="/help/tag">
2748 <a href="/help/tag">
2747 tag
2749 tag
2748 </a>
2750 </a>
2749 </td><td>
2751 </td><td>
2750 add one or more tags for the current or given revision
2752 add one or more tags for the current or given revision
2751 </td></tr>
2753 </td></tr>
2752 <tr><td>
2754 <tr><td>
2753 <a href="/help/tags">
2755 <a href="/help/tags">
2754 tags
2756 tags
2755 </a>
2757 </a>
2756 </td><td>
2758 </td><td>
2757 list repository tags
2759 list repository tags
2758 </td></tr>
2760 </td></tr>
2759 <tr><td>
2761 <tr><td>
2760 <a href="/help/unbundle">
2762 <a href="/help/unbundle">
2761 unbundle
2763 unbundle
2762 </a>
2764 </a>
2763 </td><td>
2765 </td><td>
2764 apply one or more bundle files
2766 apply one or more bundle files
2765 </td></tr>
2767 </td></tr>
2766 <tr><td>
2768 <tr><td>
2767 <a href="/help/unshelve">
2769 <a href="/help/unshelve">
2768 unshelve
2770 unshelve
2769 </a>
2771 </a>
2770 </td><td>
2772 </td><td>
2771 restore a shelved change to the working directory
2773 restore a shelved change to the working directory
2772 </td></tr>
2774 </td></tr>
2773 <tr><td>
2775 <tr><td>
2774 <a href="/help/verify">
2776 <a href="/help/verify">
2775 verify
2777 verify
2776 </a>
2778 </a>
2777 </td><td>
2779 </td><td>
2778 verify the integrity of the repository
2780 verify the integrity of the repository
2779 </td></tr>
2781 </td></tr>
2780 <tr><td>
2782 <tr><td>
2781 <a href="/help/version">
2783 <a href="/help/version">
2782 version
2784 version
2783 </a>
2785 </a>
2784 </td><td>
2786 </td><td>
2785 output version and copyright information
2787 output version and copyright information
2786 </td></tr>
2788 </td></tr>
2787
2789
2788
2790
2789 </table>
2791 </table>
2790 </div>
2792 </div>
2791 </div>
2793 </div>
2792
2794
2793
2795
2794
2796
2795 </body>
2797 </body>
2796 </html>
2798 </html>
2797
2799
2798
2800
2799 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2801 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2800 200 Script output follows
2802 200 Script output follows
2801
2803
2802 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2804 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2803 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2805 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2804 <head>
2806 <head>
2805 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2807 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2806 <meta name="robots" content="index, nofollow" />
2808 <meta name="robots" content="index, nofollow" />
2807 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2809 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2808 <script type="text/javascript" src="/static/mercurial.js"></script>
2810 <script type="text/javascript" src="/static/mercurial.js"></script>
2809
2811
2810 <title>Help: add</title>
2812 <title>Help: add</title>
2811 </head>
2813 </head>
2812 <body>
2814 <body>
2813
2815
2814 <div class="container">
2816 <div class="container">
2815 <div class="menu">
2817 <div class="menu">
2816 <div class="logo">
2818 <div class="logo">
2817 <a href="https://mercurial-scm.org/">
2819 <a href="https://mercurial-scm.org/">
2818 <img src="/static/hglogo.png" alt="mercurial" /></a>
2820 <img src="/static/hglogo.png" alt="mercurial" /></a>
2819 </div>
2821 </div>
2820 <ul>
2822 <ul>
2821 <li><a href="/shortlog">log</a></li>
2823 <li><a href="/shortlog">log</a></li>
2822 <li><a href="/graph">graph</a></li>
2824 <li><a href="/graph">graph</a></li>
2823 <li><a href="/tags">tags</a></li>
2825 <li><a href="/tags">tags</a></li>
2824 <li><a href="/bookmarks">bookmarks</a></li>
2826 <li><a href="/bookmarks">bookmarks</a></li>
2825 <li><a href="/branches">branches</a></li>
2827 <li><a href="/branches">branches</a></li>
2826 </ul>
2828 </ul>
2827 <ul>
2829 <ul>
2828 <li class="active"><a href="/help">help</a></li>
2830 <li class="active"><a href="/help">help</a></li>
2829 </ul>
2831 </ul>
2830 </div>
2832 </div>
2831
2833
2832 <div class="main">
2834 <div class="main">
2833 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2835 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2834 <h3>Help: add</h3>
2836 <h3>Help: add</h3>
2835
2837
2836 <form class="search" action="/log">
2838 <form class="search" action="/log">
2837
2839
2838 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2840 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2839 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2841 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2840 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2842 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2841 </form>
2843 </form>
2842 <div id="doc">
2844 <div id="doc">
2843 <p>
2845 <p>
2844 hg add [OPTION]... [FILE]...
2846 hg add [OPTION]... [FILE]...
2845 </p>
2847 </p>
2846 <p>
2848 <p>
2847 add the specified files on the next commit
2849 add the specified files on the next commit
2848 </p>
2850 </p>
2849 <p>
2851 <p>
2850 Schedule files to be version controlled and added to the
2852 Schedule files to be version controlled and added to the
2851 repository.
2853 repository.
2852 </p>
2854 </p>
2853 <p>
2855 <p>
2854 The files will be added to the repository at the next commit. To
2856 The files will be added to the repository at the next commit. To
2855 undo an add before that, see 'hg forget'.
2857 undo an add before that, see 'hg forget'.
2856 </p>
2858 </p>
2857 <p>
2859 <p>
2858 If no names are given, add all files to the repository (except
2860 If no names are given, add all files to the repository (except
2859 files matching &quot;.hgignore&quot;).
2861 files matching &quot;.hgignore&quot;).
2860 </p>
2862 </p>
2861 <p>
2863 <p>
2862 Examples:
2864 Examples:
2863 </p>
2865 </p>
2864 <ul>
2866 <ul>
2865 <li> New (unknown) files are added automatically by 'hg add':
2867 <li> New (unknown) files are added automatically by 'hg add':
2866 <pre>
2868 <pre>
2867 \$ ls (re)
2869 \$ ls (re)
2868 foo.c
2870 foo.c
2869 \$ hg status (re)
2871 \$ hg status (re)
2870 ? foo.c
2872 ? foo.c
2871 \$ hg add (re)
2873 \$ hg add (re)
2872 adding foo.c
2874 adding foo.c
2873 \$ hg status (re)
2875 \$ hg status (re)
2874 A foo.c
2876 A foo.c
2875 </pre>
2877 </pre>
2876 <li> Specific files to be added can be specified:
2878 <li> Specific files to be added can be specified:
2877 <pre>
2879 <pre>
2878 \$ ls (re)
2880 \$ ls (re)
2879 bar.c foo.c
2881 bar.c foo.c
2880 \$ hg status (re)
2882 \$ hg status (re)
2881 ? bar.c
2883 ? bar.c
2882 ? foo.c
2884 ? foo.c
2883 \$ hg add bar.c (re)
2885 \$ hg add bar.c (re)
2884 \$ hg status (re)
2886 \$ hg status (re)
2885 A bar.c
2887 A bar.c
2886 ? foo.c
2888 ? foo.c
2887 </pre>
2889 </pre>
2888 </ul>
2890 </ul>
2889 <p>
2891 <p>
2890 Returns 0 if all files are successfully added.
2892 Returns 0 if all files are successfully added.
2891 </p>
2893 </p>
2892 <p>
2894 <p>
2893 options ([+] can be repeated):
2895 options ([+] can be repeated):
2894 </p>
2896 </p>
2895 <table>
2897 <table>
2896 <tr><td>-I</td>
2898 <tr><td>-I</td>
2897 <td>--include PATTERN [+]</td>
2899 <td>--include PATTERN [+]</td>
2898 <td>include names matching the given patterns</td></tr>
2900 <td>include names matching the given patterns</td></tr>
2899 <tr><td>-X</td>
2901 <tr><td>-X</td>
2900 <td>--exclude PATTERN [+]</td>
2902 <td>--exclude PATTERN [+]</td>
2901 <td>exclude names matching the given patterns</td></tr>
2903 <td>exclude names matching the given patterns</td></tr>
2902 <tr><td>-S</td>
2904 <tr><td>-S</td>
2903 <td>--subrepos</td>
2905 <td>--subrepos</td>
2904 <td>recurse into subrepositories</td></tr>
2906 <td>recurse into subrepositories</td></tr>
2905 <tr><td>-n</td>
2907 <tr><td>-n</td>
2906 <td>--dry-run</td>
2908 <td>--dry-run</td>
2907 <td>do not perform actions, just print output</td></tr>
2909 <td>do not perform actions, just print output</td></tr>
2908 </table>
2910 </table>
2909 <p>
2911 <p>
2910 global options ([+] can be repeated):
2912 global options ([+] can be repeated):
2911 </p>
2913 </p>
2912 <table>
2914 <table>
2913 <tr><td>-R</td>
2915 <tr><td>-R</td>
2914 <td>--repository REPO</td>
2916 <td>--repository REPO</td>
2915 <td>repository root directory or name of overlay bundle file</td></tr>
2917 <td>repository root directory or name of overlay bundle file</td></tr>
2916 <tr><td></td>
2918 <tr><td></td>
2917 <td>--cwd DIR</td>
2919 <td>--cwd DIR</td>
2918 <td>change working directory</td></tr>
2920 <td>change working directory</td></tr>
2919 <tr><td>-y</td>
2921 <tr><td>-y</td>
2920 <td>--noninteractive</td>
2922 <td>--noninteractive</td>
2921 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2923 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2922 <tr><td>-q</td>
2924 <tr><td>-q</td>
2923 <td>--quiet</td>
2925 <td>--quiet</td>
2924 <td>suppress output</td></tr>
2926 <td>suppress output</td></tr>
2925 <tr><td>-v</td>
2927 <tr><td>-v</td>
2926 <td>--verbose</td>
2928 <td>--verbose</td>
2927 <td>enable additional output</td></tr>
2929 <td>enable additional output</td></tr>
2928 <tr><td></td>
2930 <tr><td></td>
2929 <td>--color TYPE</td>
2931 <td>--color TYPE</td>
2930 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2932 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2931 <tr><td></td>
2933 <tr><td></td>
2932 <td>--config CONFIG [+]</td>
2934 <td>--config CONFIG [+]</td>
2933 <td>set/override config option (use 'section.name=value')</td></tr>
2935 <td>set/override config option (use 'section.name=value')</td></tr>
2934 <tr><td></td>
2936 <tr><td></td>
2935 <td>--debug</td>
2937 <td>--debug</td>
2936 <td>enable debugging output</td></tr>
2938 <td>enable debugging output</td></tr>
2937 <tr><td></td>
2939 <tr><td></td>
2938 <td>--debugger</td>
2940 <td>--debugger</td>
2939 <td>start debugger</td></tr>
2941 <td>start debugger</td></tr>
2940 <tr><td></td>
2942 <tr><td></td>
2941 <td>--encoding ENCODE</td>
2943 <td>--encoding ENCODE</td>
2942 <td>set the charset encoding (default: ascii)</td></tr>
2944 <td>set the charset encoding (default: ascii)</td></tr>
2943 <tr><td></td>
2945 <tr><td></td>
2944 <td>--encodingmode MODE</td>
2946 <td>--encodingmode MODE</td>
2945 <td>set the charset encoding mode (default: strict)</td></tr>
2947 <td>set the charset encoding mode (default: strict)</td></tr>
2946 <tr><td></td>
2948 <tr><td></td>
2947 <td>--traceback</td>
2949 <td>--traceback</td>
2948 <td>always print a traceback on exception</td></tr>
2950 <td>always print a traceback on exception</td></tr>
2949 <tr><td></td>
2951 <tr><td></td>
2950 <td>--time</td>
2952 <td>--time</td>
2951 <td>time how long the command takes</td></tr>
2953 <td>time how long the command takes</td></tr>
2952 <tr><td></td>
2954 <tr><td></td>
2953 <td>--profile</td>
2955 <td>--profile</td>
2954 <td>print command execution profile</td></tr>
2956 <td>print command execution profile</td></tr>
2955 <tr><td></td>
2957 <tr><td></td>
2956 <td>--version</td>
2958 <td>--version</td>
2957 <td>output version information and exit</td></tr>
2959 <td>output version information and exit</td></tr>
2958 <tr><td>-h</td>
2960 <tr><td>-h</td>
2959 <td>--help</td>
2961 <td>--help</td>
2960 <td>display help and exit</td></tr>
2962 <td>display help and exit</td></tr>
2961 <tr><td></td>
2963 <tr><td></td>
2962 <td>--hidden</td>
2964 <td>--hidden</td>
2963 <td>consider hidden changesets</td></tr>
2965 <td>consider hidden changesets</td></tr>
2964 <tr><td></td>
2966 <tr><td></td>
2965 <td>--pager TYPE</td>
2967 <td>--pager TYPE</td>
2966 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2968 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2967 </table>
2969 </table>
2968
2970
2969 </div>
2971 </div>
2970 </div>
2972 </div>
2971 </div>
2973 </div>
2972
2974
2973
2975
2974
2976
2975 </body>
2977 </body>
2976 </html>
2978 </html>
2977
2979
2978
2980
2979 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2981 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2980 200 Script output follows
2982 200 Script output follows
2981
2983
2982 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2984 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2983 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2985 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2984 <head>
2986 <head>
2985 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2987 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2986 <meta name="robots" content="index, nofollow" />
2988 <meta name="robots" content="index, nofollow" />
2987 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2989 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2988 <script type="text/javascript" src="/static/mercurial.js"></script>
2990 <script type="text/javascript" src="/static/mercurial.js"></script>
2989
2991
2990 <title>Help: remove</title>
2992 <title>Help: remove</title>
2991 </head>
2993 </head>
2992 <body>
2994 <body>
2993
2995
2994 <div class="container">
2996 <div class="container">
2995 <div class="menu">
2997 <div class="menu">
2996 <div class="logo">
2998 <div class="logo">
2997 <a href="https://mercurial-scm.org/">
2999 <a href="https://mercurial-scm.org/">
2998 <img src="/static/hglogo.png" alt="mercurial" /></a>
3000 <img src="/static/hglogo.png" alt="mercurial" /></a>
2999 </div>
3001 </div>
3000 <ul>
3002 <ul>
3001 <li><a href="/shortlog">log</a></li>
3003 <li><a href="/shortlog">log</a></li>
3002 <li><a href="/graph">graph</a></li>
3004 <li><a href="/graph">graph</a></li>
3003 <li><a href="/tags">tags</a></li>
3005 <li><a href="/tags">tags</a></li>
3004 <li><a href="/bookmarks">bookmarks</a></li>
3006 <li><a href="/bookmarks">bookmarks</a></li>
3005 <li><a href="/branches">branches</a></li>
3007 <li><a href="/branches">branches</a></li>
3006 </ul>
3008 </ul>
3007 <ul>
3009 <ul>
3008 <li class="active"><a href="/help">help</a></li>
3010 <li class="active"><a href="/help">help</a></li>
3009 </ul>
3011 </ul>
3010 </div>
3012 </div>
3011
3013
3012 <div class="main">
3014 <div class="main">
3013 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3015 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3014 <h3>Help: remove</h3>
3016 <h3>Help: remove</h3>
3015
3017
3016 <form class="search" action="/log">
3018 <form class="search" action="/log">
3017
3019
3018 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3020 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3019 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3021 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3020 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3022 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3021 </form>
3023 </form>
3022 <div id="doc">
3024 <div id="doc">
3023 <p>
3025 <p>
3024 hg remove [OPTION]... FILE...
3026 hg remove [OPTION]... FILE...
3025 </p>
3027 </p>
3026 <p>
3028 <p>
3027 aliases: rm
3029 aliases: rm
3028 </p>
3030 </p>
3029 <p>
3031 <p>
3030 remove the specified files on the next commit
3032 remove the specified files on the next commit
3031 </p>
3033 </p>
3032 <p>
3034 <p>
3033 Schedule the indicated files for removal from the current branch.
3035 Schedule the indicated files for removal from the current branch.
3034 </p>
3036 </p>
3035 <p>
3037 <p>
3036 This command schedules the files to be removed at the next commit.
3038 This command schedules the files to be removed at the next commit.
3037 To undo a remove before that, see 'hg revert'. To undo added
3039 To undo a remove before that, see 'hg revert'. To undo added
3038 files, see 'hg forget'.
3040 files, see 'hg forget'.
3039 </p>
3041 </p>
3040 <p>
3042 <p>
3041 -A/--after can be used to remove only files that have already
3043 -A/--after can be used to remove only files that have already
3042 been deleted, -f/--force can be used to force deletion, and -Af
3044 been deleted, -f/--force can be used to force deletion, and -Af
3043 can be used to remove files from the next revision without
3045 can be used to remove files from the next revision without
3044 deleting them from the working directory.
3046 deleting them from the working directory.
3045 </p>
3047 </p>
3046 <p>
3048 <p>
3047 The following table details the behavior of remove for different
3049 The following table details the behavior of remove for different
3048 file states (columns) and option combinations (rows). The file
3050 file states (columns) and option combinations (rows). The file
3049 states are Added [A], Clean [C], Modified [M] and Missing [!]
3051 states are Added [A], Clean [C], Modified [M] and Missing [!]
3050 (as reported by 'hg status'). The actions are Warn, Remove
3052 (as reported by 'hg status'). The actions are Warn, Remove
3051 (from branch) and Delete (from disk):
3053 (from branch) and Delete (from disk):
3052 </p>
3054 </p>
3053 <table>
3055 <table>
3054 <tr><td>opt/state</td>
3056 <tr><td>opt/state</td>
3055 <td>A</td>
3057 <td>A</td>
3056 <td>C</td>
3058 <td>C</td>
3057 <td>M</td>
3059 <td>M</td>
3058 <td>!</td></tr>
3060 <td>!</td></tr>
3059 <tr><td>none</td>
3061 <tr><td>none</td>
3060 <td>W</td>
3062 <td>W</td>
3061 <td>RD</td>
3063 <td>RD</td>
3062 <td>W</td>
3064 <td>W</td>
3063 <td>R</td></tr>
3065 <td>R</td></tr>
3064 <tr><td>-f</td>
3066 <tr><td>-f</td>
3065 <td>R</td>
3067 <td>R</td>
3066 <td>RD</td>
3068 <td>RD</td>
3067 <td>RD</td>
3069 <td>RD</td>
3068 <td>R</td></tr>
3070 <td>R</td></tr>
3069 <tr><td>-A</td>
3071 <tr><td>-A</td>
3070 <td>W</td>
3072 <td>W</td>
3071 <td>W</td>
3073 <td>W</td>
3072 <td>W</td>
3074 <td>W</td>
3073 <td>R</td></tr>
3075 <td>R</td></tr>
3074 <tr><td>-Af</td>
3076 <tr><td>-Af</td>
3075 <td>R</td>
3077 <td>R</td>
3076 <td>R</td>
3078 <td>R</td>
3077 <td>R</td>
3079 <td>R</td>
3078 <td>R</td></tr>
3080 <td>R</td></tr>
3079 </table>
3081 </table>
3080 <p>
3082 <p>
3081 <b>Note:</b>
3083 <b>Note:</b>
3082 </p>
3084 </p>
3083 <p>
3085 <p>
3084 'hg remove' never deletes files in Added [A] state from the
3086 'hg remove' never deletes files in Added [A] state from the
3085 working directory, not even if &quot;--force&quot; is specified.
3087 working directory, not even if &quot;--force&quot; is specified.
3086 </p>
3088 </p>
3087 <p>
3089 <p>
3088 Returns 0 on success, 1 if any warnings encountered.
3090 Returns 0 on success, 1 if any warnings encountered.
3089 </p>
3091 </p>
3090 <p>
3092 <p>
3091 options ([+] can be repeated):
3093 options ([+] can be repeated):
3092 </p>
3094 </p>
3093 <table>
3095 <table>
3094 <tr><td>-A</td>
3096 <tr><td>-A</td>
3095 <td>--after</td>
3097 <td>--after</td>
3096 <td>record delete for missing files</td></tr>
3098 <td>record delete for missing files</td></tr>
3097 <tr><td>-f</td>
3099 <tr><td>-f</td>
3098 <td>--force</td>
3100 <td>--force</td>
3099 <td>forget added files, delete modified files</td></tr>
3101 <td>forget added files, delete modified files</td></tr>
3100 <tr><td>-S</td>
3102 <tr><td>-S</td>
3101 <td>--subrepos</td>
3103 <td>--subrepos</td>
3102 <td>recurse into subrepositories</td></tr>
3104 <td>recurse into subrepositories</td></tr>
3103 <tr><td>-I</td>
3105 <tr><td>-I</td>
3104 <td>--include PATTERN [+]</td>
3106 <td>--include PATTERN [+]</td>
3105 <td>include names matching the given patterns</td></tr>
3107 <td>include names matching the given patterns</td></tr>
3106 <tr><td>-X</td>
3108 <tr><td>-X</td>
3107 <td>--exclude PATTERN [+]</td>
3109 <td>--exclude PATTERN [+]</td>
3108 <td>exclude names matching the given patterns</td></tr>
3110 <td>exclude names matching the given patterns</td></tr>
3109 <tr><td>-n</td>
3111 <tr><td>-n</td>
3110 <td>--dry-run</td>
3112 <td>--dry-run</td>
3111 <td>do not perform actions, just print output</td></tr>
3113 <td>do not perform actions, just print output</td></tr>
3112 </table>
3114 </table>
3113 <p>
3115 <p>
3114 global options ([+] can be repeated):
3116 global options ([+] can be repeated):
3115 </p>
3117 </p>
3116 <table>
3118 <table>
3117 <tr><td>-R</td>
3119 <tr><td>-R</td>
3118 <td>--repository REPO</td>
3120 <td>--repository REPO</td>
3119 <td>repository root directory or name of overlay bundle file</td></tr>
3121 <td>repository root directory or name of overlay bundle file</td></tr>
3120 <tr><td></td>
3122 <tr><td></td>
3121 <td>--cwd DIR</td>
3123 <td>--cwd DIR</td>
3122 <td>change working directory</td></tr>
3124 <td>change working directory</td></tr>
3123 <tr><td>-y</td>
3125 <tr><td>-y</td>
3124 <td>--noninteractive</td>
3126 <td>--noninteractive</td>
3125 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3127 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3126 <tr><td>-q</td>
3128 <tr><td>-q</td>
3127 <td>--quiet</td>
3129 <td>--quiet</td>
3128 <td>suppress output</td></tr>
3130 <td>suppress output</td></tr>
3129 <tr><td>-v</td>
3131 <tr><td>-v</td>
3130 <td>--verbose</td>
3132 <td>--verbose</td>
3131 <td>enable additional output</td></tr>
3133 <td>enable additional output</td></tr>
3132 <tr><td></td>
3134 <tr><td></td>
3133 <td>--color TYPE</td>
3135 <td>--color TYPE</td>
3134 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3136 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3135 <tr><td></td>
3137 <tr><td></td>
3136 <td>--config CONFIG [+]</td>
3138 <td>--config CONFIG [+]</td>
3137 <td>set/override config option (use 'section.name=value')</td></tr>
3139 <td>set/override config option (use 'section.name=value')</td></tr>
3138 <tr><td></td>
3140 <tr><td></td>
3139 <td>--debug</td>
3141 <td>--debug</td>
3140 <td>enable debugging output</td></tr>
3142 <td>enable debugging output</td></tr>
3141 <tr><td></td>
3143 <tr><td></td>
3142 <td>--debugger</td>
3144 <td>--debugger</td>
3143 <td>start debugger</td></tr>
3145 <td>start debugger</td></tr>
3144 <tr><td></td>
3146 <tr><td></td>
3145 <td>--encoding ENCODE</td>
3147 <td>--encoding ENCODE</td>
3146 <td>set the charset encoding (default: ascii)</td></tr>
3148 <td>set the charset encoding (default: ascii)</td></tr>
3147 <tr><td></td>
3149 <tr><td></td>
3148 <td>--encodingmode MODE</td>
3150 <td>--encodingmode MODE</td>
3149 <td>set the charset encoding mode (default: strict)</td></tr>
3151 <td>set the charset encoding mode (default: strict)</td></tr>
3150 <tr><td></td>
3152 <tr><td></td>
3151 <td>--traceback</td>
3153 <td>--traceback</td>
3152 <td>always print a traceback on exception</td></tr>
3154 <td>always print a traceback on exception</td></tr>
3153 <tr><td></td>
3155 <tr><td></td>
3154 <td>--time</td>
3156 <td>--time</td>
3155 <td>time how long the command takes</td></tr>
3157 <td>time how long the command takes</td></tr>
3156 <tr><td></td>
3158 <tr><td></td>
3157 <td>--profile</td>
3159 <td>--profile</td>
3158 <td>print command execution profile</td></tr>
3160 <td>print command execution profile</td></tr>
3159 <tr><td></td>
3161 <tr><td></td>
3160 <td>--version</td>
3162 <td>--version</td>
3161 <td>output version information and exit</td></tr>
3163 <td>output version information and exit</td></tr>
3162 <tr><td>-h</td>
3164 <tr><td>-h</td>
3163 <td>--help</td>
3165 <td>--help</td>
3164 <td>display help and exit</td></tr>
3166 <td>display help and exit</td></tr>
3165 <tr><td></td>
3167 <tr><td></td>
3166 <td>--hidden</td>
3168 <td>--hidden</td>
3167 <td>consider hidden changesets</td></tr>
3169 <td>consider hidden changesets</td></tr>
3168 <tr><td></td>
3170 <tr><td></td>
3169 <td>--pager TYPE</td>
3171 <td>--pager TYPE</td>
3170 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3172 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3171 </table>
3173 </table>
3172
3174
3173 </div>
3175 </div>
3174 </div>
3176 </div>
3175 </div>
3177 </div>
3176
3178
3177
3179
3178
3180
3179 </body>
3181 </body>
3180 </html>
3182 </html>
3181
3183
3182
3184
3183 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3185 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3184 200 Script output follows
3186 200 Script output follows
3185
3187
3186 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3188 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3187 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3189 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3188 <head>
3190 <head>
3189 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3191 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3190 <meta name="robots" content="index, nofollow" />
3192 <meta name="robots" content="index, nofollow" />
3191 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3193 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3192 <script type="text/javascript" src="/static/mercurial.js"></script>
3194 <script type="text/javascript" src="/static/mercurial.js"></script>
3193
3195
3194 <title>Help: dates</title>
3196 <title>Help: dates</title>
3195 </head>
3197 </head>
3196 <body>
3198 <body>
3197
3199
3198 <div class="container">
3200 <div class="container">
3199 <div class="menu">
3201 <div class="menu">
3200 <div class="logo">
3202 <div class="logo">
3201 <a href="https://mercurial-scm.org/">
3203 <a href="https://mercurial-scm.org/">
3202 <img src="/static/hglogo.png" alt="mercurial" /></a>
3204 <img src="/static/hglogo.png" alt="mercurial" /></a>
3203 </div>
3205 </div>
3204 <ul>
3206 <ul>
3205 <li><a href="/shortlog">log</a></li>
3207 <li><a href="/shortlog">log</a></li>
3206 <li><a href="/graph">graph</a></li>
3208 <li><a href="/graph">graph</a></li>
3207 <li><a href="/tags">tags</a></li>
3209 <li><a href="/tags">tags</a></li>
3208 <li><a href="/bookmarks">bookmarks</a></li>
3210 <li><a href="/bookmarks">bookmarks</a></li>
3209 <li><a href="/branches">branches</a></li>
3211 <li><a href="/branches">branches</a></li>
3210 </ul>
3212 </ul>
3211 <ul>
3213 <ul>
3212 <li class="active"><a href="/help">help</a></li>
3214 <li class="active"><a href="/help">help</a></li>
3213 </ul>
3215 </ul>
3214 </div>
3216 </div>
3215
3217
3216 <div class="main">
3218 <div class="main">
3217 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3219 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3218 <h3>Help: dates</h3>
3220 <h3>Help: dates</h3>
3219
3221
3220 <form class="search" action="/log">
3222 <form class="search" action="/log">
3221
3223
3222 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3224 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3223 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3225 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3224 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3226 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3225 </form>
3227 </form>
3226 <div id="doc">
3228 <div id="doc">
3227 <h1>Date Formats</h1>
3229 <h1>Date Formats</h1>
3228 <p>
3230 <p>
3229 Some commands allow the user to specify a date, e.g.:
3231 Some commands allow the user to specify a date, e.g.:
3230 </p>
3232 </p>
3231 <ul>
3233 <ul>
3232 <li> backout, commit, import, tag: Specify the commit date.
3234 <li> backout, commit, import, tag: Specify the commit date.
3233 <li> log, revert, update: Select revision(s) by date.
3235 <li> log, revert, update: Select revision(s) by date.
3234 </ul>
3236 </ul>
3235 <p>
3237 <p>
3236 Many date formats are valid. Here are some examples:
3238 Many date formats are valid. Here are some examples:
3237 </p>
3239 </p>
3238 <ul>
3240 <ul>
3239 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3241 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3240 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3242 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3241 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3243 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3242 <li> &quot;Dec 6&quot; (midnight)
3244 <li> &quot;Dec 6&quot; (midnight)
3243 <li> &quot;13:18&quot; (today assumed)
3245 <li> &quot;13:18&quot; (today assumed)
3244 <li> &quot;3:39&quot; (3:39AM assumed)
3246 <li> &quot;3:39&quot; (3:39AM assumed)
3245 <li> &quot;3:39pm&quot; (15:39)
3247 <li> &quot;3:39pm&quot; (15:39)
3246 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3248 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3247 <li> &quot;2006-12-6 13:18&quot;
3249 <li> &quot;2006-12-6 13:18&quot;
3248 <li> &quot;2006-12-6&quot;
3250 <li> &quot;2006-12-6&quot;
3249 <li> &quot;12-6&quot;
3251 <li> &quot;12-6&quot;
3250 <li> &quot;12/6&quot;
3252 <li> &quot;12/6&quot;
3251 <li> &quot;12/6/6&quot; (Dec 6 2006)
3253 <li> &quot;12/6/6&quot; (Dec 6 2006)
3252 <li> &quot;today&quot; (midnight)
3254 <li> &quot;today&quot; (midnight)
3253 <li> &quot;yesterday&quot; (midnight)
3255 <li> &quot;yesterday&quot; (midnight)
3254 <li> &quot;now&quot; - right now
3256 <li> &quot;now&quot; - right now
3255 </ul>
3257 </ul>
3256 <p>
3258 <p>
3257 Lastly, there is Mercurial's internal format:
3259 Lastly, there is Mercurial's internal format:
3258 </p>
3260 </p>
3259 <ul>
3261 <ul>
3260 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3262 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3261 </ul>
3263 </ul>
3262 <p>
3264 <p>
3263 This is the internal representation format for dates. The first number
3265 This is the internal representation format for dates. The first number
3264 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3266 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3265 second is the offset of the local timezone, in seconds west of UTC
3267 second is the offset of the local timezone, in seconds west of UTC
3266 (negative if the timezone is east of UTC).
3268 (negative if the timezone is east of UTC).
3267 </p>
3269 </p>
3268 <p>
3270 <p>
3269 The log command also accepts date ranges:
3271 The log command also accepts date ranges:
3270 </p>
3272 </p>
3271 <ul>
3273 <ul>
3272 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3274 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3273 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3275 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3274 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3276 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3275 <li> &quot;-DAYS&quot; - within a given number of days of today
3277 <li> &quot;-DAYS&quot; - within a given number of days of today
3276 </ul>
3278 </ul>
3277
3279
3278 </div>
3280 </div>
3279 </div>
3281 </div>
3280 </div>
3282 </div>
3281
3283
3282
3284
3283
3285
3284 </body>
3286 </body>
3285 </html>
3287 </html>
3286
3288
3287
3289
3288 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3290 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3289 200 Script output follows
3291 200 Script output follows
3290
3292
3291 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3293 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3292 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3294 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3293 <head>
3295 <head>
3294 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3296 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3295 <meta name="robots" content="index, nofollow" />
3297 <meta name="robots" content="index, nofollow" />
3296 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3298 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3297 <script type="text/javascript" src="/static/mercurial.js"></script>
3299 <script type="text/javascript" src="/static/mercurial.js"></script>
3298
3300
3299 <title>Help: pager</title>
3301 <title>Help: pager</title>
3300 </head>
3302 </head>
3301 <body>
3303 <body>
3302
3304
3303 <div class="container">
3305 <div class="container">
3304 <div class="menu">
3306 <div class="menu">
3305 <div class="logo">
3307 <div class="logo">
3306 <a href="https://mercurial-scm.org/">
3308 <a href="https://mercurial-scm.org/">
3307 <img src="/static/hglogo.png" alt="mercurial" /></a>
3309 <img src="/static/hglogo.png" alt="mercurial" /></a>
3308 </div>
3310 </div>
3309 <ul>
3311 <ul>
3310 <li><a href="/shortlog">log</a></li>
3312 <li><a href="/shortlog">log</a></li>
3311 <li><a href="/graph">graph</a></li>
3313 <li><a href="/graph">graph</a></li>
3312 <li><a href="/tags">tags</a></li>
3314 <li><a href="/tags">tags</a></li>
3313 <li><a href="/bookmarks">bookmarks</a></li>
3315 <li><a href="/bookmarks">bookmarks</a></li>
3314 <li><a href="/branches">branches</a></li>
3316 <li><a href="/branches">branches</a></li>
3315 </ul>
3317 </ul>
3316 <ul>
3318 <ul>
3317 <li class="active"><a href="/help">help</a></li>
3319 <li class="active"><a href="/help">help</a></li>
3318 </ul>
3320 </ul>
3319 </div>
3321 </div>
3320
3322
3321 <div class="main">
3323 <div class="main">
3322 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3324 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3323 <h3>Help: pager</h3>
3325 <h3>Help: pager</h3>
3324
3326
3325 <form class="search" action="/log">
3327 <form class="search" action="/log">
3326
3328
3327 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3329 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3328 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3330 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3329 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3331 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3330 </form>
3332 </form>
3331 <div id="doc">
3333 <div id="doc">
3332 <h1>Pager Support</h1>
3334 <h1>Pager Support</h1>
3333 <p>
3335 <p>
3334 Some Mercurial commands can produce a lot of output, and Mercurial will
3336 Some Mercurial commands can produce a lot of output, and Mercurial will
3335 attempt to use a pager to make those commands more pleasant.
3337 attempt to use a pager to make those commands more pleasant.
3336 </p>
3338 </p>
3337 <p>
3339 <p>
3338 To set the pager that should be used, set the application variable:
3340 To set the pager that should be used, set the application variable:
3339 </p>
3341 </p>
3340 <pre>
3342 <pre>
3341 [pager]
3343 [pager]
3342 pager = less -FRX
3344 pager = less -FRX
3343 </pre>
3345 </pre>
3344 <p>
3346 <p>
3345 If no pager is set in the user or repository configuration, Mercurial uses the
3347 If no pager is set in the user or repository configuration, Mercurial uses the
3346 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3348 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3347 or system configuration is used. If none of these are set, a default pager will
3349 or system configuration is used. If none of these are set, a default pager will
3348 be used, typically 'less' on Unix and 'more' on Windows.
3350 be used, typically 'less' on Unix and 'more' on Windows.
3349 </p>
3351 </p>
3350 <p>
3352 <p>
3351 You can disable the pager for certain commands by adding them to the
3353 You can disable the pager for certain commands by adding them to the
3352 pager.ignore list:
3354 pager.ignore list:
3353 </p>
3355 </p>
3354 <pre>
3356 <pre>
3355 [pager]
3357 [pager]
3356 ignore = version, help, update
3358 ignore = version, help, update
3357 </pre>
3359 </pre>
3358 <p>
3360 <p>
3359 To ignore global commands like 'hg version' or 'hg help', you have
3361 To ignore global commands like 'hg version' or 'hg help', you have
3360 to specify them in your user configuration file.
3362 to specify them in your user configuration file.
3361 </p>
3363 </p>
3362 <p>
3364 <p>
3363 To control whether the pager is used at all for an individual command,
3365 To control whether the pager is used at all for an individual command,
3364 you can use --pager=&lt;value&gt;:
3366 you can use --pager=&lt;value&gt;:
3365 </p>
3367 </p>
3366 <ul>
3368 <ul>
3367 <li> use as needed: 'auto'.
3369 <li> use as needed: 'auto'.
3368 <li> require the pager: 'yes' or 'on'.
3370 <li> require the pager: 'yes' or 'on'.
3369 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3371 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3370 </ul>
3372 </ul>
3371 <p>
3373 <p>
3372 To globally turn off all attempts to use a pager, set:
3374 To globally turn off all attempts to use a pager, set:
3373 </p>
3375 </p>
3374 <pre>
3376 <pre>
3375 [ui]
3377 [ui]
3376 paginate = never
3378 paginate = never
3377 </pre>
3379 </pre>
3378 <p>
3380 <p>
3379 which will prevent the pager from running.
3381 which will prevent the pager from running.
3380 </p>
3382 </p>
3381
3383
3382 </div>
3384 </div>
3383 </div>
3385 </div>
3384 </div>
3386 </div>
3385
3387
3386
3388
3387
3389
3388 </body>
3390 </body>
3389 </html>
3391 </html>
3390
3392
3391
3393
3392 Sub-topic indexes rendered properly
3394 Sub-topic indexes rendered properly
3393
3395
3394 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3396 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3395 200 Script output follows
3397 200 Script output follows
3396
3398
3397 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3399 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3398 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3400 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3399 <head>
3401 <head>
3400 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3402 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3401 <meta name="robots" content="index, nofollow" />
3403 <meta name="robots" content="index, nofollow" />
3402 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3404 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3403 <script type="text/javascript" src="/static/mercurial.js"></script>
3405 <script type="text/javascript" src="/static/mercurial.js"></script>
3404
3406
3405 <title>Help: internals</title>
3407 <title>Help: internals</title>
3406 </head>
3408 </head>
3407 <body>
3409 <body>
3408
3410
3409 <div class="container">
3411 <div class="container">
3410 <div class="menu">
3412 <div class="menu">
3411 <div class="logo">
3413 <div class="logo">
3412 <a href="https://mercurial-scm.org/">
3414 <a href="https://mercurial-scm.org/">
3413 <img src="/static/hglogo.png" alt="mercurial" /></a>
3415 <img src="/static/hglogo.png" alt="mercurial" /></a>
3414 </div>
3416 </div>
3415 <ul>
3417 <ul>
3416 <li><a href="/shortlog">log</a></li>
3418 <li><a href="/shortlog">log</a></li>
3417 <li><a href="/graph">graph</a></li>
3419 <li><a href="/graph">graph</a></li>
3418 <li><a href="/tags">tags</a></li>
3420 <li><a href="/tags">tags</a></li>
3419 <li><a href="/bookmarks">bookmarks</a></li>
3421 <li><a href="/bookmarks">bookmarks</a></li>
3420 <li><a href="/branches">branches</a></li>
3422 <li><a href="/branches">branches</a></li>
3421 </ul>
3423 </ul>
3422 <ul>
3424 <ul>
3423 <li><a href="/help">help</a></li>
3425 <li><a href="/help">help</a></li>
3424 </ul>
3426 </ul>
3425 </div>
3427 </div>
3426
3428
3427 <div class="main">
3429 <div class="main">
3428 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3430 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3429
3431
3430 <form class="search" action="/log">
3432 <form class="search" action="/log">
3431
3433
3432 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3434 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3433 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3435 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3434 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3436 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3435 </form>
3437 </form>
3436 <table class="bigtable">
3438 <table class="bigtable">
3437 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3439 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3438
3440
3439 <tr><td>
3441 <tr><td>
3440 <a href="/help/internals.bundle2">
3442 <a href="/help/internals.bundle2">
3441 bundle2
3443 bundle2
3442 </a>
3444 </a>
3443 </td><td>
3445 </td><td>
3444 Bundle2
3446 Bundle2
3445 </td></tr>
3447 </td></tr>
3446 <tr><td>
3448 <tr><td>
3447 <a href="/help/internals.bundles">
3449 <a href="/help/internals.bundles">
3448 bundles
3450 bundles
3449 </a>
3451 </a>
3450 </td><td>
3452 </td><td>
3451 Bundles
3453 Bundles
3452 </td></tr>
3454 </td></tr>
3453 <tr><td>
3455 <tr><td>
3454 <a href="/help/internals.cbor">
3456 <a href="/help/internals.cbor">
3455 cbor
3457 cbor
3456 </a>
3458 </a>
3457 </td><td>
3459 </td><td>
3458 CBOR
3460 CBOR
3459 </td></tr>
3461 </td></tr>
3460 <tr><td>
3462 <tr><td>
3461 <a href="/help/internals.censor">
3463 <a href="/help/internals.censor">
3462 censor
3464 censor
3463 </a>
3465 </a>
3464 </td><td>
3466 </td><td>
3465 Censor
3467 Censor
3466 </td></tr>
3468 </td></tr>
3467 <tr><td>
3469 <tr><td>
3468 <a href="/help/internals.changegroups">
3470 <a href="/help/internals.changegroups">
3469 changegroups
3471 changegroups
3470 </a>
3472 </a>
3471 </td><td>
3473 </td><td>
3472 Changegroups
3474 Changegroups
3473 </td></tr>
3475 </td></tr>
3474 <tr><td>
3476 <tr><td>
3475 <a href="/help/internals.config">
3477 <a href="/help/internals.config">
3476 config
3478 config
3477 </a>
3479 </a>
3478 </td><td>
3480 </td><td>
3479 Config Registrar
3481 Config Registrar
3480 </td></tr>
3482 </td></tr>
3481 <tr><td>
3483 <tr><td>
3482 <a href="/help/internals.extensions">
3484 <a href="/help/internals.extensions">
3483 extensions
3485 extensions
3484 </a>
3486 </a>
3485 </td><td>
3487 </td><td>
3486 Extension API
3488 Extension API
3487 </td></tr>
3489 </td></tr>
3488 <tr><td>
3490 <tr><td>
3489 <a href="/help/internals.mergestate">
3491 <a href="/help/internals.mergestate">
3490 mergestate
3492 mergestate
3491 </a>
3493 </a>
3492 </td><td>
3494 </td><td>
3493 Mergestate
3495 Mergestate
3494 </td></tr>
3496 </td></tr>
3495 <tr><td>
3497 <tr><td>
3496 <a href="/help/internals.requirements">
3498 <a href="/help/internals.requirements">
3497 requirements
3499 requirements
3498 </a>
3500 </a>
3499 </td><td>
3501 </td><td>
3500 Repository Requirements
3502 Repository Requirements
3501 </td></tr>
3503 </td></tr>
3502 <tr><td>
3504 <tr><td>
3503 <a href="/help/internals.revlogs">
3505 <a href="/help/internals.revlogs">
3504 revlogs
3506 revlogs
3505 </a>
3507 </a>
3506 </td><td>
3508 </td><td>
3507 Revision Logs
3509 Revision Logs
3508 </td></tr>
3510 </td></tr>
3509 <tr><td>
3511 <tr><td>
3510 <a href="/help/internals.wireprotocol">
3512 <a href="/help/internals.wireprotocol">
3511 wireprotocol
3513 wireprotocol
3512 </a>
3514 </a>
3513 </td><td>
3515 </td><td>
3514 Wire Protocol
3516 Wire Protocol
3515 </td></tr>
3517 </td></tr>
3516 <tr><td>
3518 <tr><td>
3517 <a href="/help/internals.wireprotocolrpc">
3519 <a href="/help/internals.wireprotocolrpc">
3518 wireprotocolrpc
3520 wireprotocolrpc
3519 </a>
3521 </a>
3520 </td><td>
3522 </td><td>
3521 Wire Protocol RPC
3523 Wire Protocol RPC
3522 </td></tr>
3524 </td></tr>
3523 <tr><td>
3525 <tr><td>
3524 <a href="/help/internals.wireprotocolv2">
3526 <a href="/help/internals.wireprotocolv2">
3525 wireprotocolv2
3527 wireprotocolv2
3526 </a>
3528 </a>
3527 </td><td>
3529 </td><td>
3528 Wire Protocol Version 2
3530 Wire Protocol Version 2
3529 </td></tr>
3531 </td></tr>
3530
3532
3531
3533
3532
3534
3533
3535
3534
3536
3535 </table>
3537 </table>
3536 </div>
3538 </div>
3537 </div>
3539 </div>
3538
3540
3539
3541
3540
3542
3541 </body>
3543 </body>
3542 </html>
3544 </html>
3543
3545
3544
3546
3545 Sub-topic topics rendered properly
3547 Sub-topic topics rendered properly
3546
3548
3547 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3549 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3548 200 Script output follows
3550 200 Script output follows
3549
3551
3550 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3552 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3551 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3553 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3552 <head>
3554 <head>
3553 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3555 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3554 <meta name="robots" content="index, nofollow" />
3556 <meta name="robots" content="index, nofollow" />
3555 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3557 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3556 <script type="text/javascript" src="/static/mercurial.js"></script>
3558 <script type="text/javascript" src="/static/mercurial.js"></script>
3557
3559
3558 <title>Help: internals.changegroups</title>
3560 <title>Help: internals.changegroups</title>
3559 </head>
3561 </head>
3560 <body>
3562 <body>
3561
3563
3562 <div class="container">
3564 <div class="container">
3563 <div class="menu">
3565 <div class="menu">
3564 <div class="logo">
3566 <div class="logo">
3565 <a href="https://mercurial-scm.org/">
3567 <a href="https://mercurial-scm.org/">
3566 <img src="/static/hglogo.png" alt="mercurial" /></a>
3568 <img src="/static/hglogo.png" alt="mercurial" /></a>
3567 </div>
3569 </div>
3568 <ul>
3570 <ul>
3569 <li><a href="/shortlog">log</a></li>
3571 <li><a href="/shortlog">log</a></li>
3570 <li><a href="/graph">graph</a></li>
3572 <li><a href="/graph">graph</a></li>
3571 <li><a href="/tags">tags</a></li>
3573 <li><a href="/tags">tags</a></li>
3572 <li><a href="/bookmarks">bookmarks</a></li>
3574 <li><a href="/bookmarks">bookmarks</a></li>
3573 <li><a href="/branches">branches</a></li>
3575 <li><a href="/branches">branches</a></li>
3574 </ul>
3576 </ul>
3575 <ul>
3577 <ul>
3576 <li class="active"><a href="/help">help</a></li>
3578 <li class="active"><a href="/help">help</a></li>
3577 </ul>
3579 </ul>
3578 </div>
3580 </div>
3579
3581
3580 <div class="main">
3582 <div class="main">
3581 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3583 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3582 <h3>Help: internals.changegroups</h3>
3584 <h3>Help: internals.changegroups</h3>
3583
3585
3584 <form class="search" action="/log">
3586 <form class="search" action="/log">
3585
3587
3586 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3588 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3587 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3589 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3588 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3590 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3589 </form>
3591 </form>
3590 <div id="doc">
3592 <div id="doc">
3591 <h1>Changegroups</h1>
3593 <h1>Changegroups</h1>
3592 <p>
3594 <p>
3593 Changegroups are representations of repository revlog data, specifically
3595 Changegroups are representations of repository revlog data, specifically
3594 the changelog data, root/flat manifest data, treemanifest data, and
3596 the changelog data, root/flat manifest data, treemanifest data, and
3595 filelogs.
3597 filelogs.
3596 </p>
3598 </p>
3597 <p>
3599 <p>
3598 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3600 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3599 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3601 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3600 only difference being an additional item in the *delta header*. Version
3602 only difference being an additional item in the *delta header*. Version
3601 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3603 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3602 exchanging treemanifests (enabled by setting an option on the
3604 exchanging treemanifests (enabled by setting an option on the
3603 &quot;changegroup&quot; part in the bundle2).
3605 &quot;changegroup&quot; part in the bundle2).
3604 </p>
3606 </p>
3605 <p>
3607 <p>
3606 Changegroups when not exchanging treemanifests consist of 3 logical
3608 Changegroups when not exchanging treemanifests consist of 3 logical
3607 segments:
3609 segments:
3608 </p>
3610 </p>
3609 <pre>
3611 <pre>
3610 +---------------------------------+
3612 +---------------------------------+
3611 | | | |
3613 | | | |
3612 | changeset | manifest | filelogs |
3614 | changeset | manifest | filelogs |
3613 | | | |
3615 | | | |
3614 | | | |
3616 | | | |
3615 +---------------------------------+
3617 +---------------------------------+
3616 </pre>
3618 </pre>
3617 <p>
3619 <p>
3618 When exchanging treemanifests, there are 4 logical segments:
3620 When exchanging treemanifests, there are 4 logical segments:
3619 </p>
3621 </p>
3620 <pre>
3622 <pre>
3621 +-------------------------------------------------+
3623 +-------------------------------------------------+
3622 | | | | |
3624 | | | | |
3623 | changeset | root | treemanifests | filelogs |
3625 | changeset | root | treemanifests | filelogs |
3624 | | manifest | | |
3626 | | manifest | | |
3625 | | | | |
3627 | | | | |
3626 +-------------------------------------------------+
3628 +-------------------------------------------------+
3627 </pre>
3629 </pre>
3628 <p>
3630 <p>
3629 The principle building block of each segment is a *chunk*. A *chunk*
3631 The principle building block of each segment is a *chunk*. A *chunk*
3630 is a framed piece of data:
3632 is a framed piece of data:
3631 </p>
3633 </p>
3632 <pre>
3634 <pre>
3633 +---------------------------------------+
3635 +---------------------------------------+
3634 | | |
3636 | | |
3635 | length | data |
3637 | length | data |
3636 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3638 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3637 | | |
3639 | | |
3638 +---------------------------------------+
3640 +---------------------------------------+
3639 </pre>
3641 </pre>
3640 <p>
3642 <p>
3641 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3643 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3642 integer indicating the length of the entire chunk (including the length field
3644 integer indicating the length of the entire chunk (including the length field
3643 itself).
3645 itself).
3644 </p>
3646 </p>
3645 <p>
3647 <p>
3646 There is a special case chunk that has a value of 0 for the length
3648 There is a special case chunk that has a value of 0 for the length
3647 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3649 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3648 </p>
3650 </p>
3649 <h2>Delta Groups</h2>
3651 <h2>Delta Groups</h2>
3650 <p>
3652 <p>
3651 A *delta group* expresses the content of a revlog as a series of deltas,
3653 A *delta group* expresses the content of a revlog as a series of deltas,
3652 or patches against previous revisions.
3654 or patches against previous revisions.
3653 </p>
3655 </p>
3654 <p>
3656 <p>
3655 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3657 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3656 to signal the end of the delta group:
3658 to signal the end of the delta group:
3657 </p>
3659 </p>
3658 <pre>
3660 <pre>
3659 +------------------------------------------------------------------------+
3661 +------------------------------------------------------------------------+
3660 | | | | | |
3662 | | | | | |
3661 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3663 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3662 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3664 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3663 | | | | | |
3665 | | | | | |
3664 +------------------------------------------------------------------------+
3666 +------------------------------------------------------------------------+
3665 </pre>
3667 </pre>
3666 <p>
3668 <p>
3667 Each *chunk*'s data consists of the following:
3669 Each *chunk*'s data consists of the following:
3668 </p>
3670 </p>
3669 <pre>
3671 <pre>
3670 +---------------------------------------+
3672 +---------------------------------------+
3671 | | |
3673 | | |
3672 | delta header | delta data |
3674 | delta header | delta data |
3673 | (various by version) | (various) |
3675 | (various by version) | (various) |
3674 | | |
3676 | | |
3675 +---------------------------------------+
3677 +---------------------------------------+
3676 </pre>
3678 </pre>
3677 <p>
3679 <p>
3678 The *delta data* is a series of *delta*s that describe a diff from an existing
3680 The *delta data* is a series of *delta*s that describe a diff from an existing
3679 entry (either that the recipient already has, or previously specified in the
3681 entry (either that the recipient already has, or previously specified in the
3680 bundle/changegroup).
3682 bundle/changegroup).
3681 </p>
3683 </p>
3682 <p>
3684 <p>
3683 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3685 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3684 &quot;3&quot; of the changegroup format.
3686 &quot;3&quot; of the changegroup format.
3685 </p>
3687 </p>
3686 <p>
3688 <p>
3687 Version 1 (headerlen=80):
3689 Version 1 (headerlen=80):
3688 </p>
3690 </p>
3689 <pre>
3691 <pre>
3690 +------------------------------------------------------+
3692 +------------------------------------------------------+
3691 | | | | |
3693 | | | | |
3692 | node | p1 node | p2 node | link node |
3694 | node | p1 node | p2 node | link node |
3693 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3695 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3694 | | | | |
3696 | | | | |
3695 +------------------------------------------------------+
3697 +------------------------------------------------------+
3696 </pre>
3698 </pre>
3697 <p>
3699 <p>
3698 Version 2 (headerlen=100):
3700 Version 2 (headerlen=100):
3699 </p>
3701 </p>
3700 <pre>
3702 <pre>
3701 +------------------------------------------------------------------+
3703 +------------------------------------------------------------------+
3702 | | | | | |
3704 | | | | | |
3703 | node | p1 node | p2 node | base node | link node |
3705 | node | p1 node | p2 node | base node | link node |
3704 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3706 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3705 | | | | | |
3707 | | | | | |
3706 +------------------------------------------------------------------+
3708 +------------------------------------------------------------------+
3707 </pre>
3709 </pre>
3708 <p>
3710 <p>
3709 Version 3 (headerlen=102):
3711 Version 3 (headerlen=102):
3710 </p>
3712 </p>
3711 <pre>
3713 <pre>
3712 +------------------------------------------------------------------------------+
3714 +------------------------------------------------------------------------------+
3713 | | | | | | |
3715 | | | | | | |
3714 | node | p1 node | p2 node | base node | link node | flags |
3716 | node | p1 node | p2 node | base node | link node | flags |
3715 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3717 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3716 | | | | | | |
3718 | | | | | | |
3717 +------------------------------------------------------------------------------+
3719 +------------------------------------------------------------------------------+
3718 </pre>
3720 </pre>
3719 <p>
3721 <p>
3720 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3722 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3721 series of *delta*s, densely packed (no separators). These deltas describe a diff
3723 series of *delta*s, densely packed (no separators). These deltas describe a diff
3722 from an existing entry (either that the recipient already has, or previously
3724 from an existing entry (either that the recipient already has, or previously
3723 specified in the bundle/changegroup). The format is described more fully in
3725 specified in the bundle/changegroup). The format is described more fully in
3724 &quot;hg help internals.bdiff&quot;, but briefly:
3726 &quot;hg help internals.bdiff&quot;, but briefly:
3725 </p>
3727 </p>
3726 <pre>
3728 <pre>
3727 +---------------------------------------------------------------+
3729 +---------------------------------------------------------------+
3728 | | | | |
3730 | | | | |
3729 | start offset | end offset | new length | content |
3731 | start offset | end offset | new length | content |
3730 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3732 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3731 | | | | |
3733 | | | | |
3732 +---------------------------------------------------------------+
3734 +---------------------------------------------------------------+
3733 </pre>
3735 </pre>
3734 <p>
3736 <p>
3735 Please note that the length field in the delta data does *not* include itself.
3737 Please note that the length field in the delta data does *not* include itself.
3736 </p>
3738 </p>
3737 <p>
3739 <p>
3738 In version 1, the delta is always applied against the previous node from
3740 In version 1, the delta is always applied against the previous node from
3739 the changegroup or the first parent if this is the first entry in the
3741 the changegroup or the first parent if this is the first entry in the
3740 changegroup.
3742 changegroup.
3741 </p>
3743 </p>
3742 <p>
3744 <p>
3743 In version 2 and up, the delta base node is encoded in the entry in the
3745 In version 2 and up, the delta base node is encoded in the entry in the
3744 changegroup. This allows the delta to be expressed against any parent,
3746 changegroup. This allows the delta to be expressed against any parent,
3745 which can result in smaller deltas and more efficient encoding of data.
3747 which can result in smaller deltas and more efficient encoding of data.
3746 </p>
3748 </p>
3747 <p>
3749 <p>
3748 The *flags* field holds bitwise flags affecting the processing of revision
3750 The *flags* field holds bitwise flags affecting the processing of revision
3749 data. The following flags are defined:
3751 data. The following flags are defined:
3750 </p>
3752 </p>
3751 <dl>
3753 <dl>
3752 <dt>32768
3754 <dt>32768
3753 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3755 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3754 <dt>16384
3756 <dt>16384
3755 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3757 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3756 <dt>8192
3758 <dt>8192
3757 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3759 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3758 </dl>
3760 </dl>
3759 <p>
3761 <p>
3760 For historical reasons, the integer values are identical to revlog version 1
3762 For historical reasons, the integer values are identical to revlog version 1
3761 per-revision storage flags and correspond to bits being set in this 2-byte
3763 per-revision storage flags and correspond to bits being set in this 2-byte
3762 field. Bits were allocated starting from the most-significant bit, hence the
3764 field. Bits were allocated starting from the most-significant bit, hence the
3763 reverse ordering and allocation of these flags.
3765 reverse ordering and allocation of these flags.
3764 </p>
3766 </p>
3765 <h2>Changeset Segment</h2>
3767 <h2>Changeset Segment</h2>
3766 <p>
3768 <p>
3767 The *changeset segment* consists of a single *delta group* holding
3769 The *changeset segment* consists of a single *delta group* holding
3768 changelog data. The *empty chunk* at the end of the *delta group* denotes
3770 changelog data. The *empty chunk* at the end of the *delta group* denotes
3769 the boundary to the *manifest segment*.
3771 the boundary to the *manifest segment*.
3770 </p>
3772 </p>
3771 <h2>Manifest Segment</h2>
3773 <h2>Manifest Segment</h2>
3772 <p>
3774 <p>
3773 The *manifest segment* consists of a single *delta group* holding manifest
3775 The *manifest segment* consists of a single *delta group* holding manifest
3774 data. If treemanifests are in use, it contains only the manifest for the
3776 data. If treemanifests are in use, it contains only the manifest for the
3775 root directory of the repository. Otherwise, it contains the entire
3777 root directory of the repository. Otherwise, it contains the entire
3776 manifest data. The *empty chunk* at the end of the *delta group* denotes
3778 manifest data. The *empty chunk* at the end of the *delta group* denotes
3777 the boundary to the next segment (either the *treemanifests segment* or the
3779 the boundary to the next segment (either the *treemanifests segment* or the
3778 *filelogs segment*, depending on version and the request options).
3780 *filelogs segment*, depending on version and the request options).
3779 </p>
3781 </p>
3780 <h3>Treemanifests Segment</h3>
3782 <h3>Treemanifests Segment</h3>
3781 <p>
3783 <p>
3782 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3784 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3783 only if the 'treemanifest' param is part of the bundle2 changegroup part
3785 only if the 'treemanifest' param is part of the bundle2 changegroup part
3784 (it is not possible to use changegroup version 3 outside of bundle2).
3786 (it is not possible to use changegroup version 3 outside of bundle2).
3785 Aside from the filenames in the *treemanifests segment* containing a
3787 Aside from the filenames in the *treemanifests segment* containing a
3786 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3788 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3787 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3789 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3788 a sub-segment with filename size 0). This denotes the boundary to the
3790 a sub-segment with filename size 0). This denotes the boundary to the
3789 *filelogs segment*.
3791 *filelogs segment*.
3790 </p>
3792 </p>
3791 <h2>Filelogs Segment</h2>
3793 <h2>Filelogs Segment</h2>
3792 <p>
3794 <p>
3793 The *filelogs segment* consists of multiple sub-segments, each
3795 The *filelogs segment* consists of multiple sub-segments, each
3794 corresponding to an individual file whose data is being described:
3796 corresponding to an individual file whose data is being described:
3795 </p>
3797 </p>
3796 <pre>
3798 <pre>
3797 +--------------------------------------------------+
3799 +--------------------------------------------------+
3798 | | | | | |
3800 | | | | | |
3799 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3801 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3800 | | | | | (4 bytes) |
3802 | | | | | (4 bytes) |
3801 | | | | | |
3803 | | | | | |
3802 +--------------------------------------------------+
3804 +--------------------------------------------------+
3803 </pre>
3805 </pre>
3804 <p>
3806 <p>
3805 The final filelog sub-segment is followed by an *empty chunk* (logically,
3807 The final filelog sub-segment is followed by an *empty chunk* (logically,
3806 a sub-segment with filename size 0). This denotes the end of the segment
3808 a sub-segment with filename size 0). This denotes the end of the segment
3807 and of the overall changegroup.
3809 and of the overall changegroup.
3808 </p>
3810 </p>
3809 <p>
3811 <p>
3810 Each filelog sub-segment consists of the following:
3812 Each filelog sub-segment consists of the following:
3811 </p>
3813 </p>
3812 <pre>
3814 <pre>
3813 +------------------------------------------------------+
3815 +------------------------------------------------------+
3814 | | | |
3816 | | | |
3815 | filename length | filename | delta group |
3817 | filename length | filename | delta group |
3816 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3818 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3817 | | | |
3819 | | | |
3818 +------------------------------------------------------+
3820 +------------------------------------------------------+
3819 </pre>
3821 </pre>
3820 <p>
3822 <p>
3821 That is, a *chunk* consisting of the filename (not terminated or padded)
3823 That is, a *chunk* consisting of the filename (not terminated or padded)
3822 followed by N chunks constituting the *delta group* for this file. The
3824 followed by N chunks constituting the *delta group* for this file. The
3823 *empty chunk* at the end of each *delta group* denotes the boundary to the
3825 *empty chunk* at the end of each *delta group* denotes the boundary to the
3824 next filelog sub-segment.
3826 next filelog sub-segment.
3825 </p>
3827 </p>
3826
3828
3827 </div>
3829 </div>
3828 </div>
3830 </div>
3829 </div>
3831 </div>
3830
3832
3831
3833
3832
3834
3833 </body>
3835 </body>
3834 </html>
3836 </html>
3835
3837
3836
3838
3837 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3839 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3838 404 Not Found
3840 404 Not Found
3839
3841
3840 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3842 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3841 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3843 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3842 <head>
3844 <head>
3843 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3845 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3844 <meta name="robots" content="index, nofollow" />
3846 <meta name="robots" content="index, nofollow" />
3845 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3847 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3846 <script type="text/javascript" src="/static/mercurial.js"></script>
3848 <script type="text/javascript" src="/static/mercurial.js"></script>
3847
3849
3848 <title>test: error</title>
3850 <title>test: error</title>
3849 </head>
3851 </head>
3850 <body>
3852 <body>
3851
3853
3852 <div class="container">
3854 <div class="container">
3853 <div class="menu">
3855 <div class="menu">
3854 <div class="logo">
3856 <div class="logo">
3855 <a href="https://mercurial-scm.org/">
3857 <a href="https://mercurial-scm.org/">
3856 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3858 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3857 </div>
3859 </div>
3858 <ul>
3860 <ul>
3859 <li><a href="/shortlog">log</a></li>
3861 <li><a href="/shortlog">log</a></li>
3860 <li><a href="/graph">graph</a></li>
3862 <li><a href="/graph">graph</a></li>
3861 <li><a href="/tags">tags</a></li>
3863 <li><a href="/tags">tags</a></li>
3862 <li><a href="/bookmarks">bookmarks</a></li>
3864 <li><a href="/bookmarks">bookmarks</a></li>
3863 <li><a href="/branches">branches</a></li>
3865 <li><a href="/branches">branches</a></li>
3864 </ul>
3866 </ul>
3865 <ul>
3867 <ul>
3866 <li><a href="/help">help</a></li>
3868 <li><a href="/help">help</a></li>
3867 </ul>
3869 </ul>
3868 </div>
3870 </div>
3869
3871
3870 <div class="main">
3872 <div class="main">
3871
3873
3872 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3874 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3873 <h3>error</h3>
3875 <h3>error</h3>
3874
3876
3875
3877
3876 <form class="search" action="/log">
3878 <form class="search" action="/log">
3877
3879
3878 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3880 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3879 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3881 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3880 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3882 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3881 </form>
3883 </form>
3882
3884
3883 <div class="description">
3885 <div class="description">
3884 <p>
3886 <p>
3885 An error occurred while processing your request:
3887 An error occurred while processing your request:
3886 </p>
3888 </p>
3887 <p>
3889 <p>
3888 Not Found
3890 Not Found
3889 </p>
3891 </p>
3890 </div>
3892 </div>
3891 </div>
3893 </div>
3892 </div>
3894 </div>
3893
3895
3894
3896
3895
3897
3896 </body>
3898 </body>
3897 </html>
3899 </html>
3898
3900
3899 [1]
3901 [1]
3900
3902
3901 $ killdaemons.py
3903 $ killdaemons.py
3902
3904
3903 #endif
3905 #endif
General Comments 0
You need to be logged in to leave comments. Login now