##// END OF EJS Templates
debugcommands: introduce new debugrequirements command...
Pulkit Goyal -
r45667:4a28f5e8 default
parent child Browse files
Show More
@@ -1,4505 +1,4512
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 glob
15 import operator
15 import operator
16 import os
16 import os
17 import platform
17 import platform
18 import random
18 import random
19 import re
19 import re
20 import socket
20 import socket
21 import ssl
21 import ssl
22 import stat
22 import stat
23 import string
23 import string
24 import subprocess
24 import subprocess
25 import sys
25 import sys
26 import time
26 import time
27
27
28 from .i18n import _
28 from .i18n import _
29 from .node import (
29 from .node import (
30 bin,
30 bin,
31 hex,
31 hex,
32 nullid,
32 nullid,
33 nullrev,
33 nullrev,
34 short,
34 short,
35 )
35 )
36 from .pycompat import (
36 from .pycompat import (
37 getattr,
37 getattr,
38 open,
38 open,
39 )
39 )
40 from . import (
40 from . import (
41 bundle2,
41 bundle2,
42 bundlerepo,
42 bundlerepo,
43 changegroup,
43 changegroup,
44 cmdutil,
44 cmdutil,
45 color,
45 color,
46 context,
46 context,
47 copies,
47 copies,
48 dagparser,
48 dagparser,
49 encoding,
49 encoding,
50 error,
50 error,
51 exchange,
51 exchange,
52 extensions,
52 extensions,
53 filemerge,
53 filemerge,
54 filesetlang,
54 filesetlang,
55 formatter,
55 formatter,
56 hg,
56 hg,
57 httppeer,
57 httppeer,
58 localrepo,
58 localrepo,
59 lock as lockmod,
59 lock as lockmod,
60 logcmdutil,
60 logcmdutil,
61 mergestate as mergestatemod,
61 mergestate as mergestatemod,
62 obsolete,
62 obsolete,
63 obsutil,
63 obsutil,
64 pathutil,
64 pathutil,
65 phases,
65 phases,
66 policy,
66 policy,
67 pvec,
67 pvec,
68 pycompat,
68 pycompat,
69 registrar,
69 registrar,
70 repair,
70 repair,
71 revlog,
71 revlog,
72 revset,
72 revset,
73 revsetlang,
73 revsetlang,
74 scmutil,
74 scmutil,
75 setdiscovery,
75 setdiscovery,
76 simplemerge,
76 simplemerge,
77 sshpeer,
77 sshpeer,
78 sslutil,
78 sslutil,
79 streamclone,
79 streamclone,
80 tags as tagsmod,
80 tags as tagsmod,
81 templater,
81 templater,
82 treediscovery,
82 treediscovery,
83 upgrade,
83 upgrade,
84 url as urlmod,
84 url as urlmod,
85 util,
85 util,
86 vfs as vfsmod,
86 vfs as vfsmod,
87 wireprotoframing,
87 wireprotoframing,
88 wireprotoserver,
88 wireprotoserver,
89 wireprotov2peer,
89 wireprotov2peer,
90 )
90 )
91 from .utils import (
91 from .utils import (
92 cborutil,
92 cborutil,
93 compression,
93 compression,
94 dateutil,
94 dateutil,
95 procutil,
95 procutil,
96 stringutil,
96 stringutil,
97 )
97 )
98
98
99 from .revlogutils import (
99 from .revlogutils import (
100 deltas as deltautil,
100 deltas as deltautil,
101 nodemap,
101 nodemap,
102 )
102 )
103
103
104 release = lockmod.release
104 release = lockmod.release
105
105
106 command = registrar.command()
106 command = registrar.command()
107
107
108
108
109 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
109 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
110 def debugancestor(ui, repo, *args):
110 def debugancestor(ui, repo, *args):
111 """find the ancestor revision of two revisions in a given index"""
111 """find the ancestor revision of two revisions in a given index"""
112 if len(args) == 3:
112 if len(args) == 3:
113 index, rev1, rev2 = args
113 index, rev1, rev2 = args
114 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
114 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
115 lookup = r.lookup
115 lookup = r.lookup
116 elif len(args) == 2:
116 elif len(args) == 2:
117 if not repo:
117 if not repo:
118 raise error.Abort(
118 raise error.Abort(
119 _(b'there is no Mercurial repository here (.hg not found)')
119 _(b'there is no Mercurial repository here (.hg not found)')
120 )
120 )
121 rev1, rev2 = args
121 rev1, rev2 = args
122 r = repo.changelog
122 r = repo.changelog
123 lookup = repo.lookup
123 lookup = repo.lookup
124 else:
124 else:
125 raise error.Abort(_(b'either two or three arguments required'))
125 raise error.Abort(_(b'either two or three arguments required'))
126 a = r.ancestor(lookup(rev1), lookup(rev2))
126 a = r.ancestor(lookup(rev1), lookup(rev2))
127 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
127 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
128
128
129
129
130 @command(b'debugapplystreamclonebundle', [], b'FILE')
130 @command(b'debugapplystreamclonebundle', [], b'FILE')
131 def debugapplystreamclonebundle(ui, repo, fname):
131 def debugapplystreamclonebundle(ui, repo, fname):
132 """apply a stream clone bundle file"""
132 """apply a stream clone bundle file"""
133 f = hg.openpath(ui, fname)
133 f = hg.openpath(ui, fname)
134 gen = exchange.readbundle(ui, f, fname)
134 gen = exchange.readbundle(ui, f, fname)
135 gen.apply(repo)
135 gen.apply(repo)
136
136
137
137
138 @command(
138 @command(
139 b'debugbuilddag',
139 b'debugbuilddag',
140 [
140 [
141 (
141 (
142 b'm',
142 b'm',
143 b'mergeable-file',
143 b'mergeable-file',
144 None,
144 None,
145 _(b'add single file mergeable changes'),
145 _(b'add single file mergeable changes'),
146 ),
146 ),
147 (
147 (
148 b'o',
148 b'o',
149 b'overwritten-file',
149 b'overwritten-file',
150 None,
150 None,
151 _(b'add single file all revs overwrite'),
151 _(b'add single file all revs overwrite'),
152 ),
152 ),
153 (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')),
154 ],
154 ],
155 _(b'[OPTION]... [TEXT]'),
155 _(b'[OPTION]... [TEXT]'),
156 )
156 )
157 def debugbuilddag(
157 def debugbuilddag(
158 ui,
158 ui,
159 repo,
159 repo,
160 text=None,
160 text=None,
161 mergeable_file=False,
161 mergeable_file=False,
162 overwritten_file=False,
162 overwritten_file=False,
163 new_file=False,
163 new_file=False,
164 ):
164 ):
165 """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
166
166
167 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
168 command line.
168 command line.
169
169
170 Elements:
170 Elements:
171
171
172 - "+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
173 - "." is a single node based on the current default parent
173 - "." is a single node based on the current default parent
174 - "$" resets the default parent to null (implied at the start);
174 - "$" resets the default parent to null (implied at the start);
175 otherwise the default parent is always the last node created
175 otherwise the default parent is always the last node created
176 - "<p" sets the default parent to the backref p
176 - "<p" sets the default parent to the backref p
177 - "*p" is a fork at parent p, which is a backref
177 - "*p" is a fork at parent p, which is a backref
178 - "*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
179 - "/p2" is a merge of the preceding node and p2
179 - "/p2" is a merge of the preceding node and p2
180 - ":tag" defines a local tag for the preceding node
180 - ":tag" defines a local tag for the preceding node
181 - "@branch" sets the named branch for subsequent nodes
181 - "@branch" sets the named branch for subsequent nodes
182 - "#...\\n" is a comment up to the end of the line
182 - "#...\\n" is a comment up to the end of the line
183
183
184 Whitespace between the above elements is ignored.
184 Whitespace between the above elements is ignored.
185
185
186 A backref is either
186 A backref is either
187
187
188 - 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
189 node, or
189 node, or
190 - 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
191 - empty to denote the default parent.
191 - empty to denote the default parent.
192
192
193 All string valued-elements are either strictly alphanumeric, or must
193 All string valued-elements are either strictly alphanumeric, or must
194 be enclosed in double quotes ("..."), with "\\" as escape character.
194 be enclosed in double quotes ("..."), with "\\" as escape character.
195 """
195 """
196
196
197 if text is None:
197 if text is None:
198 ui.status(_(b"reading DAG from stdin\n"))
198 ui.status(_(b"reading DAG from stdin\n"))
199 text = ui.fin.read()
199 text = ui.fin.read()
200
200
201 cl = repo.changelog
201 cl = repo.changelog
202 if len(cl) > 0:
202 if len(cl) > 0:
203 raise error.Abort(_(b'repository is not empty'))
203 raise error.Abort(_(b'repository is not empty'))
204
204
205 # determine number of revs in DAG
205 # determine number of revs in DAG
206 total = 0
206 total = 0
207 for type, data in dagparser.parsedag(text):
207 for type, data in dagparser.parsedag(text):
208 if type == b'n':
208 if type == b'n':
209 total += 1
209 total += 1
210
210
211 if mergeable_file:
211 if mergeable_file:
212 linesperrev = 2
212 linesperrev = 2
213 # make a file with k lines per rev
213 # make a file with k lines per rev
214 initialmergedlines = [
214 initialmergedlines = [
215 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
215 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
216 ]
216 ]
217 initialmergedlines.append(b"")
217 initialmergedlines.append(b"")
218
218
219 tags = []
219 tags = []
220 progress = ui.makeprogress(
220 progress = ui.makeprogress(
221 _(b'building'), unit=_(b'revisions'), total=total
221 _(b'building'), unit=_(b'revisions'), total=total
222 )
222 )
223 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
223 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
224 at = -1
224 at = -1
225 atbranch = b'default'
225 atbranch = b'default'
226 nodeids = []
226 nodeids = []
227 id = 0
227 id = 0
228 progress.update(id)
228 progress.update(id)
229 for type, data in dagparser.parsedag(text):
229 for type, data in dagparser.parsedag(text):
230 if type == b'n':
230 if type == b'n':
231 ui.note((b'node %s\n' % pycompat.bytestr(data)))
231 ui.note((b'node %s\n' % pycompat.bytestr(data)))
232 id, ps = data
232 id, ps = data
233
233
234 files = []
234 files = []
235 filecontent = {}
235 filecontent = {}
236
236
237 p2 = None
237 p2 = None
238 if mergeable_file:
238 if mergeable_file:
239 fn = b"mf"
239 fn = b"mf"
240 p1 = repo[ps[0]]
240 p1 = repo[ps[0]]
241 if len(ps) > 1:
241 if len(ps) > 1:
242 p2 = repo[ps[1]]
242 p2 = repo[ps[1]]
243 pa = p1.ancestor(p2)
243 pa = p1.ancestor(p2)
244 base, local, other = [
244 base, local, other = [
245 x[fn].data() for x in (pa, p1, p2)
245 x[fn].data() for x in (pa, p1, p2)
246 ]
246 ]
247 m3 = simplemerge.Merge3Text(base, local, other)
247 m3 = simplemerge.Merge3Text(base, local, other)
248 ml = [l.strip() for l in m3.merge_lines()]
248 ml = [l.strip() for l in m3.merge_lines()]
249 ml.append(b"")
249 ml.append(b"")
250 elif at > 0:
250 elif at > 0:
251 ml = p1[fn].data().split(b"\n")
251 ml = p1[fn].data().split(b"\n")
252 else:
252 else:
253 ml = initialmergedlines
253 ml = initialmergedlines
254 ml[id * linesperrev] += b" r%i" % id
254 ml[id * linesperrev] += b" r%i" % id
255 mergedtext = b"\n".join(ml)
255 mergedtext = b"\n".join(ml)
256 files.append(fn)
256 files.append(fn)
257 filecontent[fn] = mergedtext
257 filecontent[fn] = mergedtext
258
258
259 if overwritten_file:
259 if overwritten_file:
260 fn = b"of"
260 fn = b"of"
261 files.append(fn)
261 files.append(fn)
262 filecontent[fn] = b"r%i\n" % id
262 filecontent[fn] = b"r%i\n" % id
263
263
264 if new_file:
264 if new_file:
265 fn = b"nf%i" % id
265 fn = b"nf%i" % id
266 files.append(fn)
266 files.append(fn)
267 filecontent[fn] = b"r%i\n" % id
267 filecontent[fn] = b"r%i\n" % id
268 if len(ps) > 1:
268 if len(ps) > 1:
269 if not p2:
269 if not p2:
270 p2 = repo[ps[1]]
270 p2 = repo[ps[1]]
271 for fn in p2:
271 for fn in p2:
272 if fn.startswith(b"nf"):
272 if fn.startswith(b"nf"):
273 files.append(fn)
273 files.append(fn)
274 filecontent[fn] = p2[fn].data()
274 filecontent[fn] = p2[fn].data()
275
275
276 def fctxfn(repo, cx, path):
276 def fctxfn(repo, cx, path):
277 if path in filecontent:
277 if path in filecontent:
278 return context.memfilectx(
278 return context.memfilectx(
279 repo, cx, path, filecontent[path]
279 repo, cx, path, filecontent[path]
280 )
280 )
281 return None
281 return None
282
282
283 if len(ps) == 0 or ps[0] < 0:
283 if len(ps) == 0 or ps[0] < 0:
284 pars = [None, None]
284 pars = [None, None]
285 elif len(ps) == 1:
285 elif len(ps) == 1:
286 pars = [nodeids[ps[0]], None]
286 pars = [nodeids[ps[0]], None]
287 else:
287 else:
288 pars = [nodeids[p] for p in ps]
288 pars = [nodeids[p] for p in ps]
289 cx = context.memctx(
289 cx = context.memctx(
290 repo,
290 repo,
291 pars,
291 pars,
292 b"r%i" % id,
292 b"r%i" % id,
293 files,
293 files,
294 fctxfn,
294 fctxfn,
295 date=(id, 0),
295 date=(id, 0),
296 user=b"debugbuilddag",
296 user=b"debugbuilddag",
297 extra={b'branch': atbranch},
297 extra={b'branch': atbranch},
298 )
298 )
299 nodeid = repo.commitctx(cx)
299 nodeid = repo.commitctx(cx)
300 nodeids.append(nodeid)
300 nodeids.append(nodeid)
301 at = id
301 at = id
302 elif type == b'l':
302 elif type == b'l':
303 id, name = data
303 id, name = data
304 ui.note((b'tag %s\n' % name))
304 ui.note((b'tag %s\n' % name))
305 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))
306 elif type == b'a':
306 elif type == b'a':
307 ui.note((b'branch %s\n' % data))
307 ui.note((b'branch %s\n' % data))
308 atbranch = data
308 atbranch = data
309 progress.update(id)
309 progress.update(id)
310
310
311 if tags:
311 if tags:
312 repo.vfs.write(b"localtags", b"".join(tags))
312 repo.vfs.write(b"localtags", b"".join(tags))
313
313
314
314
315 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
315 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
316 indent_string = b' ' * indent
316 indent_string = b' ' * indent
317 if all:
317 if all:
318 ui.writenoi18n(
318 ui.writenoi18n(
319 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
319 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
320 % indent_string
320 % indent_string
321 )
321 )
322
322
323 def showchunks(named):
323 def showchunks(named):
324 ui.write(b"\n%s%s\n" % (indent_string, named))
324 ui.write(b"\n%s%s\n" % (indent_string, named))
325 for deltadata in gen.deltaiter():
325 for deltadata in gen.deltaiter():
326 node, p1, p2, cs, deltabase, delta, flags = deltadata
326 node, p1, p2, cs, deltabase, delta, flags = deltadata
327 ui.write(
327 ui.write(
328 b"%s%s %s %s %s %s %d\n"
328 b"%s%s %s %s %s %s %d\n"
329 % (
329 % (
330 indent_string,
330 indent_string,
331 hex(node),
331 hex(node),
332 hex(p1),
332 hex(p1),
333 hex(p2),
333 hex(p2),
334 hex(cs),
334 hex(cs),
335 hex(deltabase),
335 hex(deltabase),
336 len(delta),
336 len(delta),
337 )
337 )
338 )
338 )
339
339
340 gen.changelogheader()
340 gen.changelogheader()
341 showchunks(b"changelog")
341 showchunks(b"changelog")
342 gen.manifestheader()
342 gen.manifestheader()
343 showchunks(b"manifest")
343 showchunks(b"manifest")
344 for chunkdata in iter(gen.filelogheader, {}):
344 for chunkdata in iter(gen.filelogheader, {}):
345 fname = chunkdata[b'filename']
345 fname = chunkdata[b'filename']
346 showchunks(fname)
346 showchunks(fname)
347 else:
347 else:
348 if isinstance(gen, bundle2.unbundle20):
348 if isinstance(gen, bundle2.unbundle20):
349 raise error.Abort(_(b'use debugbundle2 for this file'))
349 raise error.Abort(_(b'use debugbundle2 for this file'))
350 gen.changelogheader()
350 gen.changelogheader()
351 for deltadata in gen.deltaiter():
351 for deltadata in gen.deltaiter():
352 node, p1, p2, cs, deltabase, delta, flags = deltadata
352 node, p1, p2, cs, deltabase, delta, flags = deltadata
353 ui.write(b"%s%s\n" % (indent_string, hex(node)))
353 ui.write(b"%s%s\n" % (indent_string, hex(node)))
354
354
355
355
356 def _debugobsmarkers(ui, part, indent=0, **opts):
356 def _debugobsmarkers(ui, part, indent=0, **opts):
357 """display version and markers contained in 'data'"""
357 """display version and markers contained in 'data'"""
358 opts = pycompat.byteskwargs(opts)
358 opts = pycompat.byteskwargs(opts)
359 data = part.read()
359 data = part.read()
360 indent_string = b' ' * indent
360 indent_string = b' ' * indent
361 try:
361 try:
362 version, markers = obsolete._readmarkers(data)
362 version, markers = obsolete._readmarkers(data)
363 except error.UnknownVersion as exc:
363 except error.UnknownVersion as exc:
364 msg = b"%sunsupported version: %s (%d bytes)\n"
364 msg = b"%sunsupported version: %s (%d bytes)\n"
365 msg %= indent_string, exc.version, len(data)
365 msg %= indent_string, exc.version, len(data)
366 ui.write(msg)
366 ui.write(msg)
367 else:
367 else:
368 msg = b"%sversion: %d (%d bytes)\n"
368 msg = b"%sversion: %d (%d bytes)\n"
369 msg %= indent_string, version, len(data)
369 msg %= indent_string, version, len(data)
370 ui.write(msg)
370 ui.write(msg)
371 fm = ui.formatter(b'debugobsolete', opts)
371 fm = ui.formatter(b'debugobsolete', opts)
372 for rawmarker in sorted(markers):
372 for rawmarker in sorted(markers):
373 m = obsutil.marker(None, rawmarker)
373 m = obsutil.marker(None, rawmarker)
374 fm.startitem()
374 fm.startitem()
375 fm.plain(indent_string)
375 fm.plain(indent_string)
376 cmdutil.showmarker(fm, m)
376 cmdutil.showmarker(fm, m)
377 fm.end()
377 fm.end()
378
378
379
379
380 def _debugphaseheads(ui, data, indent=0):
380 def _debugphaseheads(ui, data, indent=0):
381 """display version and markers contained in 'data'"""
381 """display version and markers contained in 'data'"""
382 indent_string = b' ' * indent
382 indent_string = b' ' * indent
383 headsbyphase = phases.binarydecode(data)
383 headsbyphase = phases.binarydecode(data)
384 for phase in phases.allphases:
384 for phase in phases.allphases:
385 for head in headsbyphase[phase]:
385 for head in headsbyphase[phase]:
386 ui.write(indent_string)
386 ui.write(indent_string)
387 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
387 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
388
388
389
389
390 def _quasirepr(thing):
390 def _quasirepr(thing):
391 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
391 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
392 return b'{%s}' % (
392 return b'{%s}' % (
393 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))
394 )
394 )
395 return pycompat.bytestr(repr(thing))
395 return pycompat.bytestr(repr(thing))
396
396
397
397
398 def _debugbundle2(ui, gen, all=None, **opts):
398 def _debugbundle2(ui, gen, all=None, **opts):
399 """lists the contents of a bundle2"""
399 """lists the contents of a bundle2"""
400 if not isinstance(gen, bundle2.unbundle20):
400 if not isinstance(gen, bundle2.unbundle20):
401 raise error.Abort(_(b'not a bundle2 file'))
401 raise error.Abort(_(b'not a bundle2 file'))
402 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
402 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
403 parttypes = opts.get('part_type', [])
403 parttypes = opts.get('part_type', [])
404 for part in gen.iterparts():
404 for part in gen.iterparts():
405 if parttypes and part.type not in parttypes:
405 if parttypes and part.type not in parttypes:
406 continue
406 continue
407 msg = b'%s -- %s (mandatory: %r)\n'
407 msg = b'%s -- %s (mandatory: %r)\n'
408 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
408 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
409 if part.type == b'changegroup':
409 if part.type == b'changegroup':
410 version = part.params.get(b'version', b'01')
410 version = part.params.get(b'version', b'01')
411 cg = changegroup.getunbundler(version, part, b'UN')
411 cg = changegroup.getunbundler(version, part, b'UN')
412 if not ui.quiet:
412 if not ui.quiet:
413 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
413 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
414 if part.type == b'obsmarkers':
414 if part.type == b'obsmarkers':
415 if not ui.quiet:
415 if not ui.quiet:
416 _debugobsmarkers(ui, part, indent=4, **opts)
416 _debugobsmarkers(ui, part, indent=4, **opts)
417 if part.type == b'phase-heads':
417 if part.type == b'phase-heads':
418 if not ui.quiet:
418 if not ui.quiet:
419 _debugphaseheads(ui, part, indent=4)
419 _debugphaseheads(ui, part, indent=4)
420
420
421
421
422 @command(
422 @command(
423 b'debugbundle',
423 b'debugbundle',
424 [
424 [
425 (b'a', b'all', None, _(b'show all details')),
425 (b'a', b'all', None, _(b'show all details')),
426 (b'', b'part-type', [], _(b'show only the named part type')),
426 (b'', b'part-type', [], _(b'show only the named part type')),
427 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
427 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
428 ],
428 ],
429 _(b'FILE'),
429 _(b'FILE'),
430 norepo=True,
430 norepo=True,
431 )
431 )
432 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
432 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
433 """lists the contents of a bundle"""
433 """lists the contents of a bundle"""
434 with hg.openpath(ui, bundlepath) as f:
434 with hg.openpath(ui, bundlepath) as f:
435 if spec:
435 if spec:
436 spec = exchange.getbundlespec(ui, f)
436 spec = exchange.getbundlespec(ui, f)
437 ui.write(b'%s\n' % spec)
437 ui.write(b'%s\n' % spec)
438 return
438 return
439
439
440 gen = exchange.readbundle(ui, f, bundlepath)
440 gen = exchange.readbundle(ui, f, bundlepath)
441 if isinstance(gen, bundle2.unbundle20):
441 if isinstance(gen, bundle2.unbundle20):
442 return _debugbundle2(ui, gen, all=all, **opts)
442 return _debugbundle2(ui, gen, all=all, **opts)
443 _debugchangegroup(ui, gen, all=all, **opts)
443 _debugchangegroup(ui, gen, all=all, **opts)
444
444
445
445
446 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
446 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
447 def debugcapabilities(ui, path, **opts):
447 def debugcapabilities(ui, path, **opts):
448 """lists the capabilities of a remote peer"""
448 """lists the capabilities of a remote peer"""
449 opts = pycompat.byteskwargs(opts)
449 opts = pycompat.byteskwargs(opts)
450 peer = hg.peer(ui, opts, path)
450 peer = hg.peer(ui, opts, path)
451 caps = peer.capabilities()
451 caps = peer.capabilities()
452 ui.writenoi18n(b'Main capabilities:\n')
452 ui.writenoi18n(b'Main capabilities:\n')
453 for c in sorted(caps):
453 for c in sorted(caps):
454 ui.write(b' %s\n' % c)
454 ui.write(b' %s\n' % c)
455 b2caps = bundle2.bundle2caps(peer)
455 b2caps = bundle2.bundle2caps(peer)
456 if b2caps:
456 if b2caps:
457 ui.writenoi18n(b'Bundle2 capabilities:\n')
457 ui.writenoi18n(b'Bundle2 capabilities:\n')
458 for key, values in sorted(pycompat.iteritems(b2caps)):
458 for key, values in sorted(pycompat.iteritems(b2caps)):
459 ui.write(b' %s\n' % key)
459 ui.write(b' %s\n' % key)
460 for v in values:
460 for v in values:
461 ui.write(b' %s\n' % v)
461 ui.write(b' %s\n' % v)
462
462
463
463
464 @command(b'debugcheckstate', [], b'')
464 @command(b'debugcheckstate', [], b'')
465 def debugcheckstate(ui, repo):
465 def debugcheckstate(ui, repo):
466 """validate the correctness of the current dirstate"""
466 """validate the correctness of the current dirstate"""
467 parent1, parent2 = repo.dirstate.parents()
467 parent1, parent2 = repo.dirstate.parents()
468 m1 = repo[parent1].manifest()
468 m1 = repo[parent1].manifest()
469 m2 = repo[parent2].manifest()
469 m2 = repo[parent2].manifest()
470 errors = 0
470 errors = 0
471 for f in repo.dirstate:
471 for f in repo.dirstate:
472 state = repo.dirstate[f]
472 state = repo.dirstate[f]
473 if state in b"nr" and f not in m1:
473 if state in b"nr" and f not in m1:
474 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))
475 errors += 1
475 errors += 1
476 if state in b"a" and f in m1:
476 if state in b"a" and f in m1:
477 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))
478 errors += 1
478 errors += 1
479 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:
480 ui.warn(
480 ui.warn(
481 _(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)
482 )
482 )
483 errors += 1
483 errors += 1
484 for f in m1:
484 for f in m1:
485 state = repo.dirstate[f]
485 state = repo.dirstate[f]
486 if state not in b"nrm":
486 if state not in b"nrm":
487 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))
488 errors += 1
488 errors += 1
489 if errors:
489 if errors:
490 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
490 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
491 raise error.Abort(errstr)
491 raise error.Abort(errstr)
492
492
493
493
494 @command(
494 @command(
495 b'debugcolor',
495 b'debugcolor',
496 [(b'', b'style', None, _(b'show all configured styles'))],
496 [(b'', b'style', None, _(b'show all configured styles'))],
497 b'hg debugcolor',
497 b'hg debugcolor',
498 )
498 )
499 def debugcolor(ui, repo, **opts):
499 def debugcolor(ui, repo, **opts):
500 """show available color, effects or style"""
500 """show available color, effects or style"""
501 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
501 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
502 if opts.get('style'):
502 if opts.get('style'):
503 return _debugdisplaystyle(ui)
503 return _debugdisplaystyle(ui)
504 else:
504 else:
505 return _debugdisplaycolor(ui)
505 return _debugdisplaycolor(ui)
506
506
507
507
508 def _debugdisplaycolor(ui):
508 def _debugdisplaycolor(ui):
509 ui = ui.copy()
509 ui = ui.copy()
510 ui._styles.clear()
510 ui._styles.clear()
511 for effect in color._activeeffects(ui).keys():
511 for effect in color._activeeffects(ui).keys():
512 ui._styles[effect] = effect
512 ui._styles[effect] = effect
513 if ui._terminfoparams:
513 if ui._terminfoparams:
514 for k, v in ui.configitems(b'color'):
514 for k, v in ui.configitems(b'color'):
515 if k.startswith(b'color.'):
515 if k.startswith(b'color.'):
516 ui._styles[k] = k[6:]
516 ui._styles[k] = k[6:]
517 elif k.startswith(b'terminfo.'):
517 elif k.startswith(b'terminfo.'):
518 ui._styles[k] = k[9:]
518 ui._styles[k] = k[9:]
519 ui.write(_(b'available colors:\n'))
519 ui.write(_(b'available colors:\n'))
520 # sort label with a '_' after the other to group '_background' entry.
520 # sort label with a '_' after the other to group '_background' entry.
521 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]))
522 for colorname, label in items:
522 for colorname, label in items:
523 ui.write(b'%s\n' % colorname, label=label)
523 ui.write(b'%s\n' % colorname, label=label)
524
524
525
525
526 def _debugdisplaystyle(ui):
526 def _debugdisplaystyle(ui):
527 ui.write(_(b'available style:\n'))
527 ui.write(_(b'available style:\n'))
528 if not ui._styles:
528 if not ui._styles:
529 return
529 return
530 width = max(len(s) for s in ui._styles)
530 width = max(len(s) for s in ui._styles)
531 for label, effects in sorted(ui._styles.items()):
531 for label, effects in sorted(ui._styles.items()):
532 ui.write(b'%s' % label, label=label)
532 ui.write(b'%s' % label, label=label)
533 if effects:
533 if effects:
534 # 50
534 # 50
535 ui.write(b': ')
535 ui.write(b': ')
536 ui.write(b' ' * (max(0, width - len(label))))
536 ui.write(b' ' * (max(0, width - len(label))))
537 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()))
538 ui.write(b'\n')
538 ui.write(b'\n')
539
539
540
540
541 @command(b'debugcreatestreamclonebundle', [], b'FILE')
541 @command(b'debugcreatestreamclonebundle', [], b'FILE')
542 def debugcreatestreamclonebundle(ui, repo, fname):
542 def debugcreatestreamclonebundle(ui, repo, fname):
543 """create a stream clone bundle file
543 """create a stream clone bundle file
544
544
545 Stream bundles are special bundles that are essentially archives of
545 Stream bundles are special bundles that are essentially archives of
546 revlog files. They are commonly used for cloning very quickly.
546 revlog files. They are commonly used for cloning very quickly.
547 """
547 """
548 # 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
549 # is moved into `hg bundle`.
549 # is moved into `hg bundle`.
550 if phases.hassecret(repo):
550 if phases.hassecret(repo):
551 ui.warn(
551 ui.warn(
552 _(
552 _(
553 b'(warning: stream clone bundle will contain secret '
553 b'(warning: stream clone bundle will contain secret '
554 b'revisions)\n'
554 b'revisions)\n'
555 )
555 )
556 )
556 )
557
557
558 requirements, gen = streamclone.generatebundlev1(repo)
558 requirements, gen = streamclone.generatebundlev1(repo)
559 changegroup.writechunks(ui, gen, fname)
559 changegroup.writechunks(ui, gen, fname)
560
560
561 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
561 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
562
562
563
563
564 @command(
564 @command(
565 b'debugdag',
565 b'debugdag',
566 [
566 [
567 (b't', b'tags', None, _(b'use tags as labels')),
567 (b't', b'tags', None, _(b'use tags as labels')),
568 (b'b', b'branches', None, _(b'annotate with branch names')),
568 (b'b', b'branches', None, _(b'annotate with branch names')),
569 (b'', b'dots', None, _(b'use dots for runs')),
569 (b'', b'dots', None, _(b'use dots for runs')),
570 (b's', b'spaces', None, _(b'separate elements by spaces')),
570 (b's', b'spaces', None, _(b'separate elements by spaces')),
571 ],
571 ],
572 _(b'[OPTION]... [FILE [REV]...]'),
572 _(b'[OPTION]... [FILE [REV]...]'),
573 optionalrepo=True,
573 optionalrepo=True,
574 )
574 )
575 def debugdag(ui, repo, file_=None, *revs, **opts):
575 def debugdag(ui, repo, file_=None, *revs, **opts):
576 """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
577
577
578 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
579 revision numbers, they get labeled in the output as rN.
579 revision numbers, they get labeled in the output as rN.
580
580
581 Otherwise, the changelog DAG of the current repo is emitted.
581 Otherwise, the changelog DAG of the current repo is emitted.
582 """
582 """
583 spaces = opts.get('spaces')
583 spaces = opts.get('spaces')
584 dots = opts.get('dots')
584 dots = opts.get('dots')
585 if file_:
585 if file_:
586 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
586 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
587 revs = {int(r) for r in revs}
587 revs = {int(r) for r in revs}
588
588
589 def events():
589 def events():
590 for r in rlog:
590 for r in rlog:
591 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))
592 if r in revs:
592 if r in revs:
593 yield b'l', (r, b"r%i" % r)
593 yield b'l', (r, b"r%i" % r)
594
594
595 elif repo:
595 elif repo:
596 cl = repo.changelog
596 cl = repo.changelog
597 tags = opts.get('tags')
597 tags = opts.get('tags')
598 branches = opts.get('branches')
598 branches = opts.get('branches')
599 if tags:
599 if tags:
600 labels = {}
600 labels = {}
601 for l, n in repo.tags().items():
601 for l, n in repo.tags().items():
602 labels.setdefault(cl.rev(n), []).append(l)
602 labels.setdefault(cl.rev(n), []).append(l)
603
603
604 def events():
604 def events():
605 b = b"default"
605 b = b"default"
606 for r in cl:
606 for r in cl:
607 if branches:
607 if branches:
608 newb = cl.read(cl.node(r))[5][b'branch']
608 newb = cl.read(cl.node(r))[5][b'branch']
609 if newb != b:
609 if newb != b:
610 yield b'a', newb
610 yield b'a', newb
611 b = newb
611 b = newb
612 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))
613 if tags:
613 if tags:
614 ls = labels.get(r)
614 ls = labels.get(r)
615 if ls:
615 if ls:
616 for l in ls:
616 for l in ls:
617 yield b'l', (r, l)
617 yield b'l', (r, l)
618
618
619 else:
619 else:
620 raise error.Abort(_(b'need repo for changelog dag'))
620 raise error.Abort(_(b'need repo for changelog dag'))
621
621
622 for line in dagparser.dagtextlines(
622 for line in dagparser.dagtextlines(
623 events(),
623 events(),
624 addspaces=spaces,
624 addspaces=spaces,
625 wraplabels=True,
625 wraplabels=True,
626 wrapannotations=True,
626 wrapannotations=True,
627 wrapnonlinear=dots,
627 wrapnonlinear=dots,
628 usedots=dots,
628 usedots=dots,
629 maxlinewidth=70,
629 maxlinewidth=70,
630 ):
630 ):
631 ui.write(line)
631 ui.write(line)
632 ui.write(b"\n")
632 ui.write(b"\n")
633
633
634
634
635 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
635 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
636 def debugdata(ui, repo, file_, rev=None, **opts):
636 def debugdata(ui, repo, file_, rev=None, **opts):
637 """dump the contents of a data file revision"""
637 """dump the contents of a data file revision"""
638 opts = pycompat.byteskwargs(opts)
638 opts = pycompat.byteskwargs(opts)
639 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'):
640 if rev is not None:
640 if rev is not None:
641 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
641 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
642 file_, rev = None, file_
642 file_, rev = None, file_
643 elif rev is None:
643 elif rev is None:
644 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
644 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
645 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
645 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
646 try:
646 try:
647 ui.write(r.rawdata(r.lookup(rev)))
647 ui.write(r.rawdata(r.lookup(rev)))
648 except KeyError:
648 except KeyError:
649 raise error.Abort(_(b'invalid revision identifier %s') % rev)
649 raise error.Abort(_(b'invalid revision identifier %s') % rev)
650
650
651
651
652 @command(
652 @command(
653 b'debugdate',
653 b'debugdate',
654 [(b'e', b'extended', None, _(b'try extended date formats'))],
654 [(b'e', b'extended', None, _(b'try extended date formats'))],
655 _(b'[-e] DATE [RANGE]'),
655 _(b'[-e] DATE [RANGE]'),
656 norepo=True,
656 norepo=True,
657 optionalrepo=True,
657 optionalrepo=True,
658 )
658 )
659 def debugdate(ui, date, range=None, **opts):
659 def debugdate(ui, date, range=None, **opts):
660 """parse and display a date"""
660 """parse and display a date"""
661 if opts["extended"]:
661 if opts["extended"]:
662 d = dateutil.parsedate(date, dateutil.extendeddateformats)
662 d = dateutil.parsedate(date, dateutil.extendeddateformats)
663 else:
663 else:
664 d = dateutil.parsedate(date)
664 d = dateutil.parsedate(date)
665 ui.writenoi18n(b"internal: %d %d\n" % d)
665 ui.writenoi18n(b"internal: %d %d\n" % d)
666 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
666 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
667 if range:
667 if range:
668 m = dateutil.matchdate(range)
668 m = dateutil.matchdate(range)
669 ui.writenoi18n(b"match: %s\n" % m(d[0]))
669 ui.writenoi18n(b"match: %s\n" % m(d[0]))
670
670
671
671
672 @command(
672 @command(
673 b'debugdeltachain',
673 b'debugdeltachain',
674 cmdutil.debugrevlogopts + cmdutil.formatteropts,
674 cmdutil.debugrevlogopts + cmdutil.formatteropts,
675 _(b'-c|-m|FILE'),
675 _(b'-c|-m|FILE'),
676 optionalrepo=True,
676 optionalrepo=True,
677 )
677 )
678 def debugdeltachain(ui, repo, file_=None, **opts):
678 def debugdeltachain(ui, repo, file_=None, **opts):
679 """dump information about delta chains in a revlog
679 """dump information about delta chains in a revlog
680
680
681 Output can be templatized. Available template keywords are:
681 Output can be templatized. Available template keywords are:
682
682
683 :``rev``: revision number
683 :``rev``: revision number
684 :``chainid``: delta chain identifier (numbered by unique base)
684 :``chainid``: delta chain identifier (numbered by unique base)
685 :``chainlen``: delta chain length to this revision
685 :``chainlen``: delta chain length to this revision
686 :``prevrev``: previous revision in delta chain
686 :``prevrev``: previous revision in delta chain
687 :``deltatype``: role of delta / how it was computed
687 :``deltatype``: role of delta / how it was computed
688 :``compsize``: compressed size of revision
688 :``compsize``: compressed size of revision
689 :``uncompsize``: uncompressed size of revision
689 :``uncompsize``: uncompressed size of revision
690 :``chainsize``: total size of compressed revisions in chain
690 :``chainsize``: total size of compressed revisions in chain
691 :``chainratio``: total chain size divided by uncompressed revision size
691 :``chainratio``: total chain size divided by uncompressed revision size
692 (new delta chains typically start at ratio 2.00)
692 (new delta chains typically start at ratio 2.00)
693 :``lindist``: linear distance from base revision in delta chain to end
693 :``lindist``: linear distance from base revision in delta chain to end
694 of this revision
694 of this revision
695 :``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
696 base of delta chain to end of this revision; a measurement
696 base of delta chain to end of this revision; a measurement
697 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
698 the delta chain for this revision
698 the delta chain for this revision
699 :``extraratio``: extradist divided by chainsize; another representation of
699 :``extraratio``: extradist divided by chainsize; another representation of
700 how much unrelated data is needed to load this delta chain
700 how much unrelated data is needed to load this delta chain
701
701
702 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
703 are available:
703 are available:
704
704
705 :``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
706 (sum of the sizes of all the blocks)
706 (sum of the sizes of all the blocks)
707 :``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
708 :``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
709 :``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
710
710
711 The sparse read can be enabled with experimental.sparse-read = True
711 The sparse read can be enabled with experimental.sparse-read = True
712 """
712 """
713 opts = pycompat.byteskwargs(opts)
713 opts = pycompat.byteskwargs(opts)
714 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
714 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
715 index = r.index
715 index = r.index
716 start = r.start
716 start = r.start
717 length = r.length
717 length = r.length
718 generaldelta = r.version & revlog.FLAG_GENERALDELTA
718 generaldelta = r.version & revlog.FLAG_GENERALDELTA
719 withsparseread = getattr(r, '_withsparseread', False)
719 withsparseread = getattr(r, '_withsparseread', False)
720
720
721 def revinfo(rev):
721 def revinfo(rev):
722 e = index[rev]
722 e = index[rev]
723 compsize = e[1]
723 compsize = e[1]
724 uncompsize = e[2]
724 uncompsize = e[2]
725 chainsize = 0
725 chainsize = 0
726
726
727 if generaldelta:
727 if generaldelta:
728 if e[3] == e[5]:
728 if e[3] == e[5]:
729 deltatype = b'p1'
729 deltatype = b'p1'
730 elif e[3] == e[6]:
730 elif e[3] == e[6]:
731 deltatype = b'p2'
731 deltatype = b'p2'
732 elif e[3] == rev - 1:
732 elif e[3] == rev - 1:
733 deltatype = b'prev'
733 deltatype = b'prev'
734 elif e[3] == rev:
734 elif e[3] == rev:
735 deltatype = b'base'
735 deltatype = b'base'
736 else:
736 else:
737 deltatype = b'other'
737 deltatype = b'other'
738 else:
738 else:
739 if e[3] == rev:
739 if e[3] == rev:
740 deltatype = b'base'
740 deltatype = b'base'
741 else:
741 else:
742 deltatype = b'prev'
742 deltatype = b'prev'
743
743
744 chain = r._deltachain(rev)[0]
744 chain = r._deltachain(rev)[0]
745 for iterrev in chain:
745 for iterrev in chain:
746 e = index[iterrev]
746 e = index[iterrev]
747 chainsize += e[1]
747 chainsize += e[1]
748
748
749 return compsize, uncompsize, deltatype, chain, chainsize
749 return compsize, uncompsize, deltatype, chain, chainsize
750
750
751 fm = ui.formatter(b'debugdeltachain', opts)
751 fm = ui.formatter(b'debugdeltachain', opts)
752
752
753 fm.plain(
753 fm.plain(
754 b' rev chain# chainlen prev delta '
754 b' rev chain# chainlen prev delta '
755 b'size rawsize chainsize ratio lindist extradist '
755 b'size rawsize chainsize ratio lindist extradist '
756 b'extraratio'
756 b'extraratio'
757 )
757 )
758 if withsparseread:
758 if withsparseread:
759 fm.plain(b' readsize largestblk rddensity srchunks')
759 fm.plain(b' readsize largestblk rddensity srchunks')
760 fm.plain(b'\n')
760 fm.plain(b'\n')
761
761
762 chainbases = {}
762 chainbases = {}
763 for rev in r:
763 for rev in r:
764 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
764 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
765 chainbase = chain[0]
765 chainbase = chain[0]
766 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
766 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
767 basestart = start(chainbase)
767 basestart = start(chainbase)
768 revstart = start(rev)
768 revstart = start(rev)
769 lineardist = revstart + comp - basestart
769 lineardist = revstart + comp - basestart
770 extradist = lineardist - chainsize
770 extradist = lineardist - chainsize
771 try:
771 try:
772 prevrev = chain[-2]
772 prevrev = chain[-2]
773 except IndexError:
773 except IndexError:
774 prevrev = -1
774 prevrev = -1
775
775
776 if uncomp != 0:
776 if uncomp != 0:
777 chainratio = float(chainsize) / float(uncomp)
777 chainratio = float(chainsize) / float(uncomp)
778 else:
778 else:
779 chainratio = chainsize
779 chainratio = chainsize
780
780
781 if chainsize != 0:
781 if chainsize != 0:
782 extraratio = float(extradist) / float(chainsize)
782 extraratio = float(extradist) / float(chainsize)
783 else:
783 else:
784 extraratio = extradist
784 extraratio = extradist
785
785
786 fm.startitem()
786 fm.startitem()
787 fm.write(
787 fm.write(
788 b'rev chainid chainlen prevrev deltatype compsize '
788 b'rev chainid chainlen prevrev deltatype compsize '
789 b'uncompsize chainsize chainratio lindist extradist '
789 b'uncompsize chainsize chainratio lindist extradist '
790 b'extraratio',
790 b'extraratio',
791 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',
792 rev,
792 rev,
793 chainid,
793 chainid,
794 len(chain),
794 len(chain),
795 prevrev,
795 prevrev,
796 deltatype,
796 deltatype,
797 comp,
797 comp,
798 uncomp,
798 uncomp,
799 chainsize,
799 chainsize,
800 chainratio,
800 chainratio,
801 lineardist,
801 lineardist,
802 extradist,
802 extradist,
803 extraratio,
803 extraratio,
804 rev=rev,
804 rev=rev,
805 chainid=chainid,
805 chainid=chainid,
806 chainlen=len(chain),
806 chainlen=len(chain),
807 prevrev=prevrev,
807 prevrev=prevrev,
808 deltatype=deltatype,
808 deltatype=deltatype,
809 compsize=comp,
809 compsize=comp,
810 uncompsize=uncomp,
810 uncompsize=uncomp,
811 chainsize=chainsize,
811 chainsize=chainsize,
812 chainratio=chainratio,
812 chainratio=chainratio,
813 lindist=lineardist,
813 lindist=lineardist,
814 extradist=extradist,
814 extradist=extradist,
815 extraratio=extraratio,
815 extraratio=extraratio,
816 )
816 )
817 if withsparseread:
817 if withsparseread:
818 readsize = 0
818 readsize = 0
819 largestblock = 0
819 largestblock = 0
820 srchunks = 0
820 srchunks = 0
821
821
822 for revschunk in deltautil.slicechunk(r, chain):
822 for revschunk in deltautil.slicechunk(r, chain):
823 srchunks += 1
823 srchunks += 1
824 blkend = start(revschunk[-1]) + length(revschunk[-1])
824 blkend = start(revschunk[-1]) + length(revschunk[-1])
825 blksize = blkend - start(revschunk[0])
825 blksize = blkend - start(revschunk[0])
826
826
827 readsize += blksize
827 readsize += blksize
828 if largestblock < blksize:
828 if largestblock < blksize:
829 largestblock = blksize
829 largestblock = blksize
830
830
831 if readsize:
831 if readsize:
832 readdensity = float(chainsize) / float(readsize)
832 readdensity = float(chainsize) / float(readsize)
833 else:
833 else:
834 readdensity = 1
834 readdensity = 1
835
835
836 fm.write(
836 fm.write(
837 b'readsize largestblock readdensity srchunks',
837 b'readsize largestblock readdensity srchunks',
838 b' %10d %10d %9.5f %8d',
838 b' %10d %10d %9.5f %8d',
839 readsize,
839 readsize,
840 largestblock,
840 largestblock,
841 readdensity,
841 readdensity,
842 srchunks,
842 srchunks,
843 readsize=readsize,
843 readsize=readsize,
844 largestblock=largestblock,
844 largestblock=largestblock,
845 readdensity=readdensity,
845 readdensity=readdensity,
846 srchunks=srchunks,
846 srchunks=srchunks,
847 )
847 )
848
848
849 fm.plain(b'\n')
849 fm.plain(b'\n')
850
850
851 fm.end()
851 fm.end()
852
852
853
853
854 @command(
854 @command(
855 b'debugdirstate|debugstate',
855 b'debugdirstate|debugstate',
856 [
856 [
857 (
857 (
858 b'',
858 b'',
859 b'nodates',
859 b'nodates',
860 None,
860 None,
861 _(b'do not display the saved mtime (DEPRECATED)'),
861 _(b'do not display the saved mtime (DEPRECATED)'),
862 ),
862 ),
863 (b'', b'dates', True, _(b'display the saved mtime')),
863 (b'', b'dates', True, _(b'display the saved mtime')),
864 (b'', b'datesort', None, _(b'sort by saved mtime')),
864 (b'', b'datesort', None, _(b'sort by saved mtime')),
865 ],
865 ],
866 _(b'[OPTION]...'),
866 _(b'[OPTION]...'),
867 )
867 )
868 def debugstate(ui, repo, **opts):
868 def debugstate(ui, repo, **opts):
869 """show the contents of the current dirstate"""
869 """show the contents of the current dirstate"""
870
870
871 nodates = not opts['dates']
871 nodates = not opts['dates']
872 if opts.get('nodates') is not None:
872 if opts.get('nodates') is not None:
873 nodates = True
873 nodates = True
874 datesort = opts.get('datesort')
874 datesort = opts.get('datesort')
875
875
876 if datesort:
876 if datesort:
877 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
878 else:
878 else:
879 keyfunc = None # sort by filename
879 keyfunc = None # sort by filename
880 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
880 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
881 if ent[3] == -1:
881 if ent[3] == -1:
882 timestr = b'unset '
882 timestr = b'unset '
883 elif nodates:
883 elif nodates:
884 timestr = b'set '
884 timestr = b'set '
885 else:
885 else:
886 timestr = time.strftime(
886 timestr = time.strftime(
887 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
887 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
888 )
888 )
889 timestr = encoding.strtolocal(timestr)
889 timestr = encoding.strtolocal(timestr)
890 if ent[1] & 0o20000:
890 if ent[1] & 0o20000:
891 mode = b'lnk'
891 mode = b'lnk'
892 else:
892 else:
893 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
893 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
894 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_))
895 for f in repo.dirstate.copies():
895 for f in repo.dirstate.copies():
896 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))
897
897
898
898
899 @command(
899 @command(
900 b'debugdiscovery',
900 b'debugdiscovery',
901 [
901 [
902 (b'', b'old', None, _(b'use old-style discovery')),
902 (b'', b'old', None, _(b'use old-style discovery')),
903 (
903 (
904 b'',
904 b'',
905 b'nonheads',
905 b'nonheads',
906 None,
906 None,
907 _(b'use old-style discovery with non-heads included'),
907 _(b'use old-style discovery with non-heads included'),
908 ),
908 ),
909 (b'', b'rev', [], b'restrict discovery to this set of revs'),
909 (b'', b'rev', [], b'restrict discovery to this set of revs'),
910 (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'),
911 ]
911 ]
912 + cmdutil.remoteopts,
912 + cmdutil.remoteopts,
913 _(b'[--rev REV] [OTHER]'),
913 _(b'[--rev REV] [OTHER]'),
914 )
914 )
915 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
915 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
916 """runs the changeset discovery protocol in isolation"""
916 """runs the changeset discovery protocol in isolation"""
917 opts = pycompat.byteskwargs(opts)
917 opts = pycompat.byteskwargs(opts)
918 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
918 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
919 remote = hg.peer(repo, opts, remoteurl)
919 remote = hg.peer(repo, opts, remoteurl)
920 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
920 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
921
921
922 # make sure tests are repeatable
922 # make sure tests are repeatable
923 random.seed(int(opts[b'seed']))
923 random.seed(int(opts[b'seed']))
924
924
925 if opts.get(b'old'):
925 if opts.get(b'old'):
926
926
927 def doit(pushedrevs, remoteheads, remote=remote):
927 def doit(pushedrevs, remoteheads, remote=remote):
928 if not util.safehasattr(remote, b'branches'):
928 if not util.safehasattr(remote, b'branches'):
929 # enable in-client legacy support
929 # enable in-client legacy support
930 remote = localrepo.locallegacypeer(remote.local())
930 remote = localrepo.locallegacypeer(remote.local())
931 common, _in, hds = treediscovery.findcommonincoming(
931 common, _in, hds = treediscovery.findcommonincoming(
932 repo, remote, force=True
932 repo, remote, force=True
933 )
933 )
934 common = set(common)
934 common = set(common)
935 if not opts.get(b'nonheads'):
935 if not opts.get(b'nonheads'):
936 ui.writenoi18n(
936 ui.writenoi18n(
937 b"unpruned common: %s\n"
937 b"unpruned common: %s\n"
938 % b" ".join(sorted(short(n) for n in common))
938 % b" ".join(sorted(short(n) for n in common))
939 )
939 )
940
940
941 clnode = repo.changelog.node
941 clnode = repo.changelog.node
942 common = repo.revs(b'heads(::%ln)', common)
942 common = repo.revs(b'heads(::%ln)', common)
943 common = {clnode(r) for r in common}
943 common = {clnode(r) for r in common}
944 return common, hds
944 return common, hds
945
945
946 else:
946 else:
947
947
948 def doit(pushedrevs, remoteheads, remote=remote):
948 def doit(pushedrevs, remoteheads, remote=remote):
949 nodes = None
949 nodes = None
950 if pushedrevs:
950 if pushedrevs:
951 revs = scmutil.revrange(repo, pushedrevs)
951 revs = scmutil.revrange(repo, pushedrevs)
952 nodes = [repo[r].node() for r in revs]
952 nodes = [repo[r].node() for r in revs]
953 common, any, hds = setdiscovery.findcommonheads(
953 common, any, hds = setdiscovery.findcommonheads(
954 ui, repo, remote, ancestorsof=nodes
954 ui, repo, remote, ancestorsof=nodes
955 )
955 )
956 return common, hds
956 return common, hds
957
957
958 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
958 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
959 localrevs = opts[b'rev']
959 localrevs = opts[b'rev']
960 with util.timedcm('debug-discovery') as t:
960 with util.timedcm('debug-discovery') as t:
961 common, hds = doit(localrevs, remoterevs)
961 common, hds = doit(localrevs, remoterevs)
962
962
963 # compute all statistics
963 # compute all statistics
964 common = set(common)
964 common = set(common)
965 rheads = set(hds)
965 rheads = set(hds)
966 lheads = set(repo.heads())
966 lheads = set(repo.heads())
967
967
968 data = {}
968 data = {}
969 data[b'elapsed'] = t.elapsed
969 data[b'elapsed'] = t.elapsed
970 data[b'nb-common'] = len(common)
970 data[b'nb-common'] = len(common)
971 data[b'nb-common-local'] = len(common & lheads)
971 data[b'nb-common-local'] = len(common & lheads)
972 data[b'nb-common-remote'] = len(common & rheads)
972 data[b'nb-common-remote'] = len(common & rheads)
973 data[b'nb-common-both'] = len(common & rheads & lheads)
973 data[b'nb-common-both'] = len(common & rheads & lheads)
974 data[b'nb-local'] = len(lheads)
974 data[b'nb-local'] = len(lheads)
975 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']
976 data[b'nb-remote'] = len(rheads)
976 data[b'nb-remote'] = len(rheads)
977 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']
978 data[b'nb-revs'] = len(repo.revs(b'all()'))
978 data[b'nb-revs'] = len(repo.revs(b'all()'))
979 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
979 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
980 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']
981
981
982 # display discovery summary
982 # display discovery summary
983 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
983 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
984 ui.writenoi18n(b"heads summary:\n")
984 ui.writenoi18n(b"heads summary:\n")
985 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
985 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
986 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)
987 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)
988 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
988 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
989 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
989 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
990 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
990 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
991 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
991 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
992 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
992 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
993 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
993 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
994 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
994 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
995 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
995 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
996 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
996 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
997 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
997 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
998
998
999 if ui.verbose:
999 if ui.verbose:
1000 ui.writenoi18n(
1000 ui.writenoi18n(
1001 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))
1002 )
1002 )
1003
1003
1004
1004
1005 _chunksize = 4 << 10
1005 _chunksize = 4 << 10
1006
1006
1007
1007
1008 @command(
1008 @command(
1009 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1009 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1010 )
1010 )
1011 def debugdownload(ui, repo, url, output=None, **opts):
1011 def debugdownload(ui, repo, url, output=None, **opts):
1012 """download a resource using Mercurial logic and config
1012 """download a resource using Mercurial logic and config
1013 """
1013 """
1014 fh = urlmod.open(ui, url, output)
1014 fh = urlmod.open(ui, url, output)
1015
1015
1016 dest = ui
1016 dest = ui
1017 if output:
1017 if output:
1018 dest = open(output, b"wb", _chunksize)
1018 dest = open(output, b"wb", _chunksize)
1019 try:
1019 try:
1020 data = fh.read(_chunksize)
1020 data = fh.read(_chunksize)
1021 while data:
1021 while data:
1022 dest.write(data)
1022 dest.write(data)
1023 data = fh.read(_chunksize)
1023 data = fh.read(_chunksize)
1024 finally:
1024 finally:
1025 if output:
1025 if output:
1026 dest.close()
1026 dest.close()
1027
1027
1028
1028
1029 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1029 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1030 def debugextensions(ui, repo, **opts):
1030 def debugextensions(ui, repo, **opts):
1031 '''show information about active extensions'''
1031 '''show information about active extensions'''
1032 opts = pycompat.byteskwargs(opts)
1032 opts = pycompat.byteskwargs(opts)
1033 exts = extensions.extensions(ui)
1033 exts = extensions.extensions(ui)
1034 hgver = util.version()
1034 hgver = util.version()
1035 fm = ui.formatter(b'debugextensions', opts)
1035 fm = ui.formatter(b'debugextensions', opts)
1036 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1036 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1037 isinternal = extensions.ismoduleinternal(extmod)
1037 isinternal = extensions.ismoduleinternal(extmod)
1038 extsource = None
1038 extsource = None
1039
1039
1040 if util.safehasattr(extmod, '__file__'):
1040 if util.safehasattr(extmod, '__file__'):
1041 extsource = pycompat.fsencode(extmod.__file__)
1041 extsource = pycompat.fsencode(extmod.__file__)
1042 elif getattr(sys, 'oxidized', False):
1042 elif getattr(sys, 'oxidized', False):
1043 extsource = pycompat.sysexecutable
1043 extsource = pycompat.sysexecutable
1044 if isinternal:
1044 if isinternal:
1045 exttestedwith = [] # never expose magic string to users
1045 exttestedwith = [] # never expose magic string to users
1046 else:
1046 else:
1047 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1047 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1048 extbuglink = getattr(extmod, 'buglink', None)
1048 extbuglink = getattr(extmod, 'buglink', None)
1049
1049
1050 fm.startitem()
1050 fm.startitem()
1051
1051
1052 if ui.quiet or ui.verbose:
1052 if ui.quiet or ui.verbose:
1053 fm.write(b'name', b'%s\n', extname)
1053 fm.write(b'name', b'%s\n', extname)
1054 else:
1054 else:
1055 fm.write(b'name', b'%s', extname)
1055 fm.write(b'name', b'%s', extname)
1056 if isinternal or hgver in exttestedwith:
1056 if isinternal or hgver in exttestedwith:
1057 fm.plain(b'\n')
1057 fm.plain(b'\n')
1058 elif not exttestedwith:
1058 elif not exttestedwith:
1059 fm.plain(_(b' (untested!)\n'))
1059 fm.plain(_(b' (untested!)\n'))
1060 else:
1060 else:
1061 lasttestedversion = exttestedwith[-1]
1061 lasttestedversion = exttestedwith[-1]
1062 fm.plain(b' (%s!)\n' % lasttestedversion)
1062 fm.plain(b' (%s!)\n' % lasttestedversion)
1063
1063
1064 fm.condwrite(
1064 fm.condwrite(
1065 ui.verbose and extsource,
1065 ui.verbose and extsource,
1066 b'source',
1066 b'source',
1067 _(b' location: %s\n'),
1067 _(b' location: %s\n'),
1068 extsource or b"",
1068 extsource or b"",
1069 )
1069 )
1070
1070
1071 if ui.verbose:
1071 if ui.verbose:
1072 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1072 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1073 fm.data(bundled=isinternal)
1073 fm.data(bundled=isinternal)
1074
1074
1075 fm.condwrite(
1075 fm.condwrite(
1076 ui.verbose and exttestedwith,
1076 ui.verbose and exttestedwith,
1077 b'testedwith',
1077 b'testedwith',
1078 _(b' tested with: %s\n'),
1078 _(b' tested with: %s\n'),
1079 fm.formatlist(exttestedwith, name=b'ver'),
1079 fm.formatlist(exttestedwith, name=b'ver'),
1080 )
1080 )
1081
1081
1082 fm.condwrite(
1082 fm.condwrite(
1083 ui.verbose and extbuglink,
1083 ui.verbose and extbuglink,
1084 b'buglink',
1084 b'buglink',
1085 _(b' bug reporting: %s\n'),
1085 _(b' bug reporting: %s\n'),
1086 extbuglink or b"",
1086 extbuglink or b"",
1087 )
1087 )
1088
1088
1089 fm.end()
1089 fm.end()
1090
1090
1091
1091
1092 @command(
1092 @command(
1093 b'debugfileset',
1093 b'debugfileset',
1094 [
1094 [
1095 (
1095 (
1096 b'r',
1096 b'r',
1097 b'rev',
1097 b'rev',
1098 b'',
1098 b'',
1099 _(b'apply the filespec on this revision'),
1099 _(b'apply the filespec on this revision'),
1100 _(b'REV'),
1100 _(b'REV'),
1101 ),
1101 ),
1102 (
1102 (
1103 b'',
1103 b'',
1104 b'all-files',
1104 b'all-files',
1105 False,
1105 False,
1106 _(b'test files from all revisions and working directory'),
1106 _(b'test files from all revisions and working directory'),
1107 ),
1107 ),
1108 (
1108 (
1109 b's',
1109 b's',
1110 b'show-matcher',
1110 b'show-matcher',
1111 None,
1111 None,
1112 _(b'print internal representation of matcher'),
1112 _(b'print internal representation of matcher'),
1113 ),
1113 ),
1114 (
1114 (
1115 b'p',
1115 b'p',
1116 b'show-stage',
1116 b'show-stage',
1117 [],
1117 [],
1118 _(b'print parsed tree at the given stage'),
1118 _(b'print parsed tree at the given stage'),
1119 _(b'NAME'),
1119 _(b'NAME'),
1120 ),
1120 ),
1121 ],
1121 ],
1122 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1122 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1123 )
1123 )
1124 def debugfileset(ui, repo, expr, **opts):
1124 def debugfileset(ui, repo, expr, **opts):
1125 '''parse and apply a fileset specification'''
1125 '''parse and apply a fileset specification'''
1126 from . import fileset
1126 from . import fileset
1127
1127
1128 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
1129 opts = pycompat.byteskwargs(opts)
1129 opts = pycompat.byteskwargs(opts)
1130 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1130 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1131
1131
1132 stages = [
1132 stages = [
1133 (b'parsed', pycompat.identity),
1133 (b'parsed', pycompat.identity),
1134 (b'analyzed', filesetlang.analyze),
1134 (b'analyzed', filesetlang.analyze),
1135 (b'optimized', filesetlang.optimize),
1135 (b'optimized', filesetlang.optimize),
1136 ]
1136 ]
1137 stagenames = {n for n, f in stages}
1137 stagenames = {n for n, f in stages}
1138
1138
1139 showalways = set()
1139 showalways = set()
1140 if ui.verbose and not opts[b'show_stage']:
1140 if ui.verbose and not opts[b'show_stage']:
1141 # show parsed tree by --verbose (deprecated)
1141 # show parsed tree by --verbose (deprecated)
1142 showalways.add(b'parsed')
1142 showalways.add(b'parsed')
1143 if opts[b'show_stage'] == [b'all']:
1143 if opts[b'show_stage'] == [b'all']:
1144 showalways.update(stagenames)
1144 showalways.update(stagenames)
1145 else:
1145 else:
1146 for n in opts[b'show_stage']:
1146 for n in opts[b'show_stage']:
1147 if n not in stagenames:
1147 if n not in stagenames:
1148 raise error.Abort(_(b'invalid stage name: %s') % n)
1148 raise error.Abort(_(b'invalid stage name: %s') % n)
1149 showalways.update(opts[b'show_stage'])
1149 showalways.update(opts[b'show_stage'])
1150
1150
1151 tree = filesetlang.parse(expr)
1151 tree = filesetlang.parse(expr)
1152 for n, f in stages:
1152 for n, f in stages:
1153 tree = f(tree)
1153 tree = f(tree)
1154 if n in showalways:
1154 if n in showalways:
1155 if opts[b'show_stage'] or n != b'parsed':
1155 if opts[b'show_stage'] or n != b'parsed':
1156 ui.write(b"* %s:\n" % n)
1156 ui.write(b"* %s:\n" % n)
1157 ui.write(filesetlang.prettyformat(tree), b"\n")
1157 ui.write(filesetlang.prettyformat(tree), b"\n")
1158
1158
1159 files = set()
1159 files = set()
1160 if opts[b'all_files']:
1160 if opts[b'all_files']:
1161 for r in repo:
1161 for r in repo:
1162 c = repo[r]
1162 c = repo[r]
1163 files.update(c.files())
1163 files.update(c.files())
1164 files.update(c.substate)
1164 files.update(c.substate)
1165 if opts[b'all_files'] or ctx.rev() is None:
1165 if opts[b'all_files'] or ctx.rev() is None:
1166 wctx = repo[None]
1166 wctx = repo[None]
1167 files.update(
1167 files.update(
1168 repo.dirstate.walk(
1168 repo.dirstate.walk(
1169 scmutil.matchall(repo),
1169 scmutil.matchall(repo),
1170 subrepos=list(wctx.substate),
1170 subrepos=list(wctx.substate),
1171 unknown=True,
1171 unknown=True,
1172 ignored=True,
1172 ignored=True,
1173 )
1173 )
1174 )
1174 )
1175 files.update(wctx.substate)
1175 files.update(wctx.substate)
1176 else:
1176 else:
1177 files.update(ctx.files())
1177 files.update(ctx.files())
1178 files.update(ctx.substate)
1178 files.update(ctx.substate)
1179
1179
1180 m = ctx.matchfileset(repo.getcwd(), expr)
1180 m = ctx.matchfileset(repo.getcwd(), expr)
1181 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):
1182 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1182 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1183 for f in sorted(files):
1183 for f in sorted(files):
1184 if not m(f):
1184 if not m(f):
1185 continue
1185 continue
1186 ui.write(b"%s\n" % f)
1186 ui.write(b"%s\n" % f)
1187
1187
1188
1188
1189 @command(b'debugformat', [] + cmdutil.formatteropts)
1189 @command(b'debugformat', [] + cmdutil.formatteropts)
1190 def debugformat(ui, repo, **opts):
1190 def debugformat(ui, repo, **opts):
1191 """display format information about the current repository
1191 """display format information about the current repository
1192
1192
1193 Use --verbose to get extra information about current config value and
1193 Use --verbose to get extra information about current config value and
1194 Mercurial default."""
1194 Mercurial default."""
1195 opts = pycompat.byteskwargs(opts)
1195 opts = pycompat.byteskwargs(opts)
1196 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1196 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1197 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1197 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1198
1198
1199 def makeformatname(name):
1199 def makeformatname(name):
1200 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1200 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1201
1201
1202 fm = ui.formatter(b'debugformat', opts)
1202 fm = ui.formatter(b'debugformat', opts)
1203 if fm.isplain():
1203 if fm.isplain():
1204
1204
1205 def formatvalue(value):
1205 def formatvalue(value):
1206 if util.safehasattr(value, b'startswith'):
1206 if util.safehasattr(value, b'startswith'):
1207 return value
1207 return value
1208 if value:
1208 if value:
1209 return b'yes'
1209 return b'yes'
1210 else:
1210 else:
1211 return b'no'
1211 return b'no'
1212
1212
1213 else:
1213 else:
1214 formatvalue = pycompat.identity
1214 formatvalue = pycompat.identity
1215
1215
1216 fm.plain(b'format-variant')
1216 fm.plain(b'format-variant')
1217 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1217 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1218 fm.plain(b' repo')
1218 fm.plain(b' repo')
1219 if ui.verbose:
1219 if ui.verbose:
1220 fm.plain(b' config default')
1220 fm.plain(b' config default')
1221 fm.plain(b'\n')
1221 fm.plain(b'\n')
1222 for fv in upgrade.allformatvariant:
1222 for fv in upgrade.allformatvariant:
1223 fm.startitem()
1223 fm.startitem()
1224 repovalue = fv.fromrepo(repo)
1224 repovalue = fv.fromrepo(repo)
1225 configvalue = fv.fromconfig(repo)
1225 configvalue = fv.fromconfig(repo)
1226
1226
1227 if repovalue != configvalue:
1227 if repovalue != configvalue:
1228 namelabel = b'formatvariant.name.mismatchconfig'
1228 namelabel = b'formatvariant.name.mismatchconfig'
1229 repolabel = b'formatvariant.repo.mismatchconfig'
1229 repolabel = b'formatvariant.repo.mismatchconfig'
1230 elif repovalue != fv.default:
1230 elif repovalue != fv.default:
1231 namelabel = b'formatvariant.name.mismatchdefault'
1231 namelabel = b'formatvariant.name.mismatchdefault'
1232 repolabel = b'formatvariant.repo.mismatchdefault'
1232 repolabel = b'formatvariant.repo.mismatchdefault'
1233 else:
1233 else:
1234 namelabel = b'formatvariant.name.uptodate'
1234 namelabel = b'formatvariant.name.uptodate'
1235 repolabel = b'formatvariant.repo.uptodate'
1235 repolabel = b'formatvariant.repo.uptodate'
1236
1236
1237 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1237 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1238 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1238 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1239 if fv.default != configvalue:
1239 if fv.default != configvalue:
1240 configlabel = b'formatvariant.config.special'
1240 configlabel = b'formatvariant.config.special'
1241 else:
1241 else:
1242 configlabel = b'formatvariant.config.default'
1242 configlabel = b'formatvariant.config.default'
1243 fm.condwrite(
1243 fm.condwrite(
1244 ui.verbose,
1244 ui.verbose,
1245 b'config',
1245 b'config',
1246 b' %6s',
1246 b' %6s',
1247 formatvalue(configvalue),
1247 formatvalue(configvalue),
1248 label=configlabel,
1248 label=configlabel,
1249 )
1249 )
1250 fm.condwrite(
1250 fm.condwrite(
1251 ui.verbose,
1251 ui.verbose,
1252 b'default',
1252 b'default',
1253 b' %7s',
1253 b' %7s',
1254 formatvalue(fv.default),
1254 formatvalue(fv.default),
1255 label=b'formatvariant.default',
1255 label=b'formatvariant.default',
1256 )
1256 )
1257 fm.plain(b'\n')
1257 fm.plain(b'\n')
1258 fm.end()
1258 fm.end()
1259
1259
1260
1260
1261 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1261 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1262 def debugfsinfo(ui, path=b"."):
1262 def debugfsinfo(ui, path=b"."):
1263 """show information detected about current filesystem"""
1263 """show information detected about current filesystem"""
1264 ui.writenoi18n(b'path: %s\n' % path)
1264 ui.writenoi18n(b'path: %s\n' % path)
1265 ui.writenoi18n(
1265 ui.writenoi18n(
1266 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1266 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1267 )
1267 )
1268 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'))
1269 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)'))
1270 ui.writenoi18n(
1270 ui.writenoi18n(
1271 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')
1272 )
1272 )
1273 ui.writenoi18n(
1273 ui.writenoi18n(
1274 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')
1275 )
1275 )
1276 casesensitive = b'(unknown)'
1276 casesensitive = b'(unknown)'
1277 try:
1277 try:
1278 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1278 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1279 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1279 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1280 except OSError:
1280 except OSError:
1281 pass
1281 pass
1282 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1282 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1283
1283
1284
1284
1285 @command(
1285 @command(
1286 b'debuggetbundle',
1286 b'debuggetbundle',
1287 [
1287 [
1288 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1288 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1289 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1289 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1290 (
1290 (
1291 b't',
1291 b't',
1292 b'type',
1292 b'type',
1293 b'bzip2',
1293 b'bzip2',
1294 _(b'bundle compression type to use'),
1294 _(b'bundle compression type to use'),
1295 _(b'TYPE'),
1295 _(b'TYPE'),
1296 ),
1296 ),
1297 ],
1297 ],
1298 _(b'REPO FILE [-H|-C ID]...'),
1298 _(b'REPO FILE [-H|-C ID]...'),
1299 norepo=True,
1299 norepo=True,
1300 )
1300 )
1301 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1301 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1302 """retrieves a bundle from a repo
1302 """retrieves a bundle from a repo
1303
1303
1304 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
1305 given file.
1305 given file.
1306 """
1306 """
1307 opts = pycompat.byteskwargs(opts)
1307 opts = pycompat.byteskwargs(opts)
1308 repo = hg.peer(ui, opts, repopath)
1308 repo = hg.peer(ui, opts, repopath)
1309 if not repo.capable(b'getbundle'):
1309 if not repo.capable(b'getbundle'):
1310 raise error.Abort(b"getbundle() not supported by target repository")
1310 raise error.Abort(b"getbundle() not supported by target repository")
1311 args = {}
1311 args = {}
1312 if common:
1312 if common:
1313 args['common'] = [bin(s) for s in common]
1313 args['common'] = [bin(s) for s in common]
1314 if head:
1314 if head:
1315 args['heads'] = [bin(s) for s in head]
1315 args['heads'] = [bin(s) for s in head]
1316 # TODO: get desired bundlecaps from command line.
1316 # TODO: get desired bundlecaps from command line.
1317 args['bundlecaps'] = None
1317 args['bundlecaps'] = None
1318 bundle = repo.getbundle(b'debug', **args)
1318 bundle = repo.getbundle(b'debug', **args)
1319
1319
1320 bundletype = opts.get(b'type', b'bzip2').lower()
1320 bundletype = opts.get(b'type', b'bzip2').lower()
1321 btypes = {
1321 btypes = {
1322 b'none': b'HG10UN',
1322 b'none': b'HG10UN',
1323 b'bzip2': b'HG10BZ',
1323 b'bzip2': b'HG10BZ',
1324 b'gzip': b'HG10GZ',
1324 b'gzip': b'HG10GZ',
1325 b'bundle2': b'HG20',
1325 b'bundle2': b'HG20',
1326 }
1326 }
1327 bundletype = btypes.get(bundletype)
1327 bundletype = btypes.get(bundletype)
1328 if bundletype not in bundle2.bundletypes:
1328 if bundletype not in bundle2.bundletypes:
1329 raise error.Abort(_(b'unknown bundle type specified with --type'))
1329 raise error.Abort(_(b'unknown bundle type specified with --type'))
1330 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1330 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1331
1331
1332
1332
1333 @command(b'debugignore', [], b'[FILE]')
1333 @command(b'debugignore', [], b'[FILE]')
1334 def debugignore(ui, repo, *files, **opts):
1334 def debugignore(ui, repo, *files, **opts):
1335 """display the combined ignore pattern and information about ignored files
1335 """display the combined ignore pattern and information about ignored files
1336
1336
1337 With no argument display the combined ignore pattern.
1337 With no argument display the combined ignore pattern.
1338
1338
1339 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
1340 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.
1341 """
1341 """
1342 ignore = repo.dirstate._ignore
1342 ignore = repo.dirstate._ignore
1343 if not files:
1343 if not files:
1344 # Show all the patterns
1344 # Show all the patterns
1345 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1345 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1346 else:
1346 else:
1347 m = scmutil.match(repo[None], pats=files)
1347 m = scmutil.match(repo[None], pats=files)
1348 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1348 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1349 for f in m.files():
1349 for f in m.files():
1350 nf = util.normpath(f)
1350 nf = util.normpath(f)
1351 ignored = None
1351 ignored = None
1352 ignoredata = None
1352 ignoredata = None
1353 if nf != b'.':
1353 if nf != b'.':
1354 if ignore(nf):
1354 if ignore(nf):
1355 ignored = nf
1355 ignored = nf
1356 ignoredata = repo.dirstate._ignorefileandline(nf)
1356 ignoredata = repo.dirstate._ignorefileandline(nf)
1357 else:
1357 else:
1358 for p in pathutil.finddirs(nf):
1358 for p in pathutil.finddirs(nf):
1359 if ignore(p):
1359 if ignore(p):
1360 ignored = p
1360 ignored = p
1361 ignoredata = repo.dirstate._ignorefileandline(p)
1361 ignoredata = repo.dirstate._ignorefileandline(p)
1362 break
1362 break
1363 if ignored:
1363 if ignored:
1364 if ignored == nf:
1364 if ignored == nf:
1365 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1365 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1366 else:
1366 else:
1367 ui.write(
1367 ui.write(
1368 _(
1368 _(
1369 b"%s is ignored because of "
1369 b"%s is ignored because of "
1370 b"containing directory %s\n"
1370 b"containing directory %s\n"
1371 )
1371 )
1372 % (uipathfn(f), ignored)
1372 % (uipathfn(f), ignored)
1373 )
1373 )
1374 ignorefile, lineno, line = ignoredata
1374 ignorefile, lineno, line = ignoredata
1375 ui.write(
1375 ui.write(
1376 _(b"(ignore rule in %s, line %d: '%s')\n")
1376 _(b"(ignore rule in %s, line %d: '%s')\n")
1377 % (ignorefile, lineno, line)
1377 % (ignorefile, lineno, line)
1378 )
1378 )
1379 else:
1379 else:
1380 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1380 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1381
1381
1382
1382
1383 @command(
1383 @command(
1384 b'debugindex',
1384 b'debugindex',
1385 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1385 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1386 _(b'-c|-m|FILE'),
1386 _(b'-c|-m|FILE'),
1387 )
1387 )
1388 def debugindex(ui, repo, file_=None, **opts):
1388 def debugindex(ui, repo, file_=None, **opts):
1389 """dump index data for a storage primitive"""
1389 """dump index data for a storage primitive"""
1390 opts = pycompat.byteskwargs(opts)
1390 opts = pycompat.byteskwargs(opts)
1391 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1391 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1392
1392
1393 if ui.debugflag:
1393 if ui.debugflag:
1394 shortfn = hex
1394 shortfn = hex
1395 else:
1395 else:
1396 shortfn = short
1396 shortfn = short
1397
1397
1398 idlen = 12
1398 idlen = 12
1399 for i in store:
1399 for i in store:
1400 idlen = len(shortfn(store.node(i)))
1400 idlen = len(shortfn(store.node(i)))
1401 break
1401 break
1402
1402
1403 fm = ui.formatter(b'debugindex', opts)
1403 fm = ui.formatter(b'debugindex', opts)
1404 fm.plain(
1404 fm.plain(
1405 b' rev linkrev %s %s p2\n'
1405 b' rev linkrev %s %s p2\n'
1406 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1406 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1407 )
1407 )
1408
1408
1409 for rev in store:
1409 for rev in store:
1410 node = store.node(rev)
1410 node = store.node(rev)
1411 parents = store.parents(node)
1411 parents = store.parents(node)
1412
1412
1413 fm.startitem()
1413 fm.startitem()
1414 fm.write(b'rev', b'%6d ', rev)
1414 fm.write(b'rev', b'%6d ', rev)
1415 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1415 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1416 fm.write(b'node', b'%s ', shortfn(node))
1416 fm.write(b'node', b'%s ', shortfn(node))
1417 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1417 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1418 fm.write(b'p2', b'%s', shortfn(parents[1]))
1418 fm.write(b'p2', b'%s', shortfn(parents[1]))
1419 fm.plain(b'\n')
1419 fm.plain(b'\n')
1420
1420
1421 fm.end()
1421 fm.end()
1422
1422
1423
1423
1424 @command(
1424 @command(
1425 b'debugindexdot',
1425 b'debugindexdot',
1426 cmdutil.debugrevlogopts,
1426 cmdutil.debugrevlogopts,
1427 _(b'-c|-m|FILE'),
1427 _(b'-c|-m|FILE'),
1428 optionalrepo=True,
1428 optionalrepo=True,
1429 )
1429 )
1430 def debugindexdot(ui, repo, file_=None, **opts):
1430 def debugindexdot(ui, repo, file_=None, **opts):
1431 """dump an index DAG as a graphviz dot file"""
1431 """dump an index DAG as a graphviz dot file"""
1432 opts = pycompat.byteskwargs(opts)
1432 opts = pycompat.byteskwargs(opts)
1433 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1433 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1434 ui.writenoi18n(b"digraph G {\n")
1434 ui.writenoi18n(b"digraph G {\n")
1435 for i in r:
1435 for i in r:
1436 node = r.node(i)
1436 node = r.node(i)
1437 pp = r.parents(node)
1437 pp = r.parents(node)
1438 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))
1439 if pp[1] != nullid:
1439 if pp[1] != nullid:
1440 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))
1441 ui.write(b"}\n")
1441 ui.write(b"}\n")
1442
1442
1443
1443
1444 @command(b'debugindexstats', [])
1444 @command(b'debugindexstats', [])
1445 def debugindexstats(ui, repo):
1445 def debugindexstats(ui, repo):
1446 """show stats related to the changelog index"""
1446 """show stats related to the changelog index"""
1447 repo.changelog.shortest(nullid, 1)
1447 repo.changelog.shortest(nullid, 1)
1448 index = repo.changelog.index
1448 index = repo.changelog.index
1449 if not util.safehasattr(index, b'stats'):
1449 if not util.safehasattr(index, b'stats'):
1450 raise error.Abort(_(b'debugindexstats only works with native code'))
1450 raise error.Abort(_(b'debugindexstats only works with native code'))
1451 for k, v in sorted(index.stats().items()):
1451 for k, v in sorted(index.stats().items()):
1452 ui.write(b'%s: %d\n' % (k, v))
1452 ui.write(b'%s: %d\n' % (k, v))
1453
1453
1454
1454
1455 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1455 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1456 def debuginstall(ui, **opts):
1456 def debuginstall(ui, **opts):
1457 '''test Mercurial installation
1457 '''test Mercurial installation
1458
1458
1459 Returns 0 on success.
1459 Returns 0 on success.
1460 '''
1460 '''
1461 opts = pycompat.byteskwargs(opts)
1461 opts = pycompat.byteskwargs(opts)
1462
1462
1463 problems = 0
1463 problems = 0
1464
1464
1465 fm = ui.formatter(b'debuginstall', opts)
1465 fm = ui.formatter(b'debuginstall', opts)
1466 fm.startitem()
1466 fm.startitem()
1467
1467
1468 # encoding might be unknown or wrong. don't translate these messages.
1468 # encoding might be unknown or wrong. don't translate these messages.
1469 fm.write(b'encoding', b"checking encoding (%s)...\n", encoding.encoding)
1469 fm.write(b'encoding', b"checking encoding (%s)...\n", encoding.encoding)
1470 err = None
1470 err = None
1471 try:
1471 try:
1472 codecs.lookup(pycompat.sysstr(encoding.encoding))
1472 codecs.lookup(pycompat.sysstr(encoding.encoding))
1473 except LookupError as inst:
1473 except LookupError as inst:
1474 err = stringutil.forcebytestr(inst)
1474 err = stringutil.forcebytestr(inst)
1475 problems += 1
1475 problems += 1
1476 fm.condwrite(
1476 fm.condwrite(
1477 err,
1477 err,
1478 b'encodingerror',
1478 b'encodingerror',
1479 b" %s\n (check that your locale is properly set)\n",
1479 b" %s\n (check that your locale is properly set)\n",
1480 err,
1480 err,
1481 )
1481 )
1482
1482
1483 # Python
1483 # Python
1484 pythonlib = None
1484 pythonlib = None
1485 if util.safehasattr(os, '__file__'):
1485 if util.safehasattr(os, '__file__'):
1486 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1486 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1487 elif getattr(sys, 'oxidized', False):
1487 elif getattr(sys, 'oxidized', False):
1488 pythonlib = pycompat.sysexecutable
1488 pythonlib = pycompat.sysexecutable
1489
1489
1490 fm.write(
1490 fm.write(
1491 b'pythonexe',
1491 b'pythonexe',
1492 _(b"checking Python executable (%s)\n"),
1492 _(b"checking Python executable (%s)\n"),
1493 pycompat.sysexecutable or _(b"unknown"),
1493 pycompat.sysexecutable or _(b"unknown"),
1494 )
1494 )
1495 fm.write(
1495 fm.write(
1496 b'pythonimplementation',
1496 b'pythonimplementation',
1497 _(b"checking Python implementation (%s)\n"),
1497 _(b"checking Python implementation (%s)\n"),
1498 pycompat.sysbytes(platform.python_implementation()),
1498 pycompat.sysbytes(platform.python_implementation()),
1499 )
1499 )
1500 fm.write(
1500 fm.write(
1501 b'pythonver',
1501 b'pythonver',
1502 _(b"checking Python version (%s)\n"),
1502 _(b"checking Python version (%s)\n"),
1503 (b"%d.%d.%d" % sys.version_info[:3]),
1503 (b"%d.%d.%d" % sys.version_info[:3]),
1504 )
1504 )
1505 fm.write(
1505 fm.write(
1506 b'pythonlib',
1506 b'pythonlib',
1507 _(b"checking Python lib (%s)...\n"),
1507 _(b"checking Python lib (%s)...\n"),
1508 pythonlib or _(b"unknown"),
1508 pythonlib or _(b"unknown"),
1509 )
1509 )
1510
1510
1511 try:
1511 try:
1512 from . import rustext
1512 from . import rustext
1513
1513
1514 rustext.__doc__ # trigger lazy import
1514 rustext.__doc__ # trigger lazy import
1515 except ImportError:
1515 except ImportError:
1516 rustext = None
1516 rustext = None
1517
1517
1518 security = set(sslutil.supportedprotocols)
1518 security = set(sslutil.supportedprotocols)
1519 if sslutil.hassni:
1519 if sslutil.hassni:
1520 security.add(b'sni')
1520 security.add(b'sni')
1521
1521
1522 fm.write(
1522 fm.write(
1523 b'pythonsecurity',
1523 b'pythonsecurity',
1524 _(b"checking Python security support (%s)\n"),
1524 _(b"checking Python security support (%s)\n"),
1525 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1525 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1526 )
1526 )
1527
1527
1528 # These are warnings, not errors. So don't increment problem count. This
1528 # These are warnings, not errors. So don't increment problem count. This
1529 # may change in the future.
1529 # may change in the future.
1530 if b'tls1.2' not in security:
1530 if b'tls1.2' not in security:
1531 fm.plain(
1531 fm.plain(
1532 _(
1532 _(
1533 b' TLS 1.2 not supported by Python install; '
1533 b' TLS 1.2 not supported by Python install; '
1534 b'network connections lack modern security\n'
1534 b'network connections lack modern security\n'
1535 )
1535 )
1536 )
1536 )
1537 if b'sni' not in security:
1537 if b'sni' not in security:
1538 fm.plain(
1538 fm.plain(
1539 _(
1539 _(
1540 b' SNI not supported by Python install; may have '
1540 b' SNI not supported by Python install; may have '
1541 b'connectivity issues with some servers\n'
1541 b'connectivity issues with some servers\n'
1542 )
1542 )
1543 )
1543 )
1544
1544
1545 fm.plain(
1545 fm.plain(
1546 _(
1546 _(
1547 b"checking Rust extensions (%s)\n"
1547 b"checking Rust extensions (%s)\n"
1548 % (b'missing' if rustext is None else b'installed')
1548 % (b'missing' if rustext is None else b'installed')
1549 ),
1549 ),
1550 )
1550 )
1551
1551
1552 # TODO print CA cert info
1552 # TODO print CA cert info
1553
1553
1554 # hg version
1554 # hg version
1555 hgver = util.version()
1555 hgver = util.version()
1556 fm.write(
1556 fm.write(
1557 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1557 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1558 )
1558 )
1559 fm.write(
1559 fm.write(
1560 b'hgverextra',
1560 b'hgverextra',
1561 _(b"checking Mercurial custom build (%s)\n"),
1561 _(b"checking Mercurial custom build (%s)\n"),
1562 b'+'.join(hgver.split(b'+')[1:]),
1562 b'+'.join(hgver.split(b'+')[1:]),
1563 )
1563 )
1564
1564
1565 # compiled modules
1565 # compiled modules
1566 hgmodules = None
1566 hgmodules = None
1567 if util.safehasattr(sys.modules[__name__], '__file__'):
1567 if util.safehasattr(sys.modules[__name__], '__file__'):
1568 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1568 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1569 elif getattr(sys, 'oxidized', False):
1569 elif getattr(sys, 'oxidized', False):
1570 hgmodules = pycompat.sysexecutable
1570 hgmodules = pycompat.sysexecutable
1571
1571
1572 fm.write(
1572 fm.write(
1573 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1573 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1574 )
1574 )
1575 fm.write(
1575 fm.write(
1576 b'hgmodules',
1576 b'hgmodules',
1577 _(b"checking installed modules (%s)...\n"),
1577 _(b"checking installed modules (%s)...\n"),
1578 hgmodules or _(b"unknown"),
1578 hgmodules or _(b"unknown"),
1579 )
1579 )
1580
1580
1581 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1581 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1582 rustext = rustandc # for now, that's the only case
1582 rustext = rustandc # for now, that's the only case
1583 cext = policy.policy in (b'c', b'allow') or rustandc
1583 cext = policy.policy in (b'c', b'allow') or rustandc
1584 nopure = cext or rustext
1584 nopure = cext or rustext
1585 if nopure:
1585 if nopure:
1586 err = None
1586 err = None
1587 try:
1587 try:
1588 if cext:
1588 if cext:
1589 from .cext import ( # pytype: disable=import-error
1589 from .cext import ( # pytype: disable=import-error
1590 base85,
1590 base85,
1591 bdiff,
1591 bdiff,
1592 mpatch,
1592 mpatch,
1593 osutil,
1593 osutil,
1594 )
1594 )
1595
1595
1596 # quiet pyflakes
1596 # quiet pyflakes
1597 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1597 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1598 if rustext:
1598 if rustext:
1599 from .rustext import ( # pytype: disable=import-error
1599 from .rustext import ( # pytype: disable=import-error
1600 ancestor,
1600 ancestor,
1601 dirstate,
1601 dirstate,
1602 )
1602 )
1603
1603
1604 dir(ancestor), dir(dirstate) # quiet pyflakes
1604 dir(ancestor), dir(dirstate) # quiet pyflakes
1605 except Exception as inst:
1605 except Exception as inst:
1606 err = stringutil.forcebytestr(inst)
1606 err = stringutil.forcebytestr(inst)
1607 problems += 1
1607 problems += 1
1608 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1608 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1609
1609
1610 compengines = util.compengines._engines.values()
1610 compengines = util.compengines._engines.values()
1611 fm.write(
1611 fm.write(
1612 b'compengines',
1612 b'compengines',
1613 _(b'checking registered compression engines (%s)\n'),
1613 _(b'checking registered compression engines (%s)\n'),
1614 fm.formatlist(
1614 fm.formatlist(
1615 sorted(e.name() for e in compengines),
1615 sorted(e.name() for e in compengines),
1616 name=b'compengine',
1616 name=b'compengine',
1617 fmt=b'%s',
1617 fmt=b'%s',
1618 sep=b', ',
1618 sep=b', ',
1619 ),
1619 ),
1620 )
1620 )
1621 fm.write(
1621 fm.write(
1622 b'compenginesavail',
1622 b'compenginesavail',
1623 _(b'checking available compression engines (%s)\n'),
1623 _(b'checking available compression engines (%s)\n'),
1624 fm.formatlist(
1624 fm.formatlist(
1625 sorted(e.name() for e in compengines if e.available()),
1625 sorted(e.name() for e in compengines if e.available()),
1626 name=b'compengine',
1626 name=b'compengine',
1627 fmt=b'%s',
1627 fmt=b'%s',
1628 sep=b', ',
1628 sep=b', ',
1629 ),
1629 ),
1630 )
1630 )
1631 wirecompengines = compression.compengines.supportedwireengines(
1631 wirecompengines = compression.compengines.supportedwireengines(
1632 compression.SERVERROLE
1632 compression.SERVERROLE
1633 )
1633 )
1634 fm.write(
1634 fm.write(
1635 b'compenginesserver',
1635 b'compenginesserver',
1636 _(
1636 _(
1637 b'checking available compression engines '
1637 b'checking available compression engines '
1638 b'for wire protocol (%s)\n'
1638 b'for wire protocol (%s)\n'
1639 ),
1639 ),
1640 fm.formatlist(
1640 fm.formatlist(
1641 [e.name() for e in wirecompengines if e.wireprotosupport()],
1641 [e.name() for e in wirecompengines if e.wireprotosupport()],
1642 name=b'compengine',
1642 name=b'compengine',
1643 fmt=b'%s',
1643 fmt=b'%s',
1644 sep=b', ',
1644 sep=b', ',
1645 ),
1645 ),
1646 )
1646 )
1647 re2 = b'missing'
1647 re2 = b'missing'
1648 if util._re2:
1648 if util._re2:
1649 re2 = b'available'
1649 re2 = b'available'
1650 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1650 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1651 fm.data(re2=bool(util._re2))
1651 fm.data(re2=bool(util._re2))
1652
1652
1653 # templates
1653 # templates
1654 p = templater.templatepaths()
1654 p = templater.templatepaths()
1655 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1655 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1656 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1656 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1657 if p:
1657 if p:
1658 m = templater.templatepath(b"map-cmdline.default")
1658 m = templater.templatepath(b"map-cmdline.default")
1659 if m:
1659 if m:
1660 # template found, check if it is working
1660 # template found, check if it is working
1661 err = None
1661 err = None
1662 try:
1662 try:
1663 templater.templater.frommapfile(m)
1663 templater.templater.frommapfile(m)
1664 except Exception as inst:
1664 except Exception as inst:
1665 err = stringutil.forcebytestr(inst)
1665 err = stringutil.forcebytestr(inst)
1666 p = None
1666 p = None
1667 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1667 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1668 else:
1668 else:
1669 p = None
1669 p = None
1670 fm.condwrite(
1670 fm.condwrite(
1671 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1671 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1672 )
1672 )
1673 fm.condwrite(
1673 fm.condwrite(
1674 not m,
1674 not m,
1675 b'defaulttemplatenotfound',
1675 b'defaulttemplatenotfound',
1676 _(b" template '%s' not found\n"),
1676 _(b" template '%s' not found\n"),
1677 b"default",
1677 b"default",
1678 )
1678 )
1679 if not p:
1679 if not p:
1680 problems += 1
1680 problems += 1
1681 fm.condwrite(
1681 fm.condwrite(
1682 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1682 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1683 )
1683 )
1684
1684
1685 # editor
1685 # editor
1686 editor = ui.geteditor()
1686 editor = ui.geteditor()
1687 editor = util.expandpath(editor)
1687 editor = util.expandpath(editor)
1688 editorbin = procutil.shellsplit(editor)[0]
1688 editorbin = procutil.shellsplit(editor)[0]
1689 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1689 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1690 cmdpath = procutil.findexe(editorbin)
1690 cmdpath = procutil.findexe(editorbin)
1691 fm.condwrite(
1691 fm.condwrite(
1692 not cmdpath and editor == b'vi',
1692 not cmdpath and editor == b'vi',
1693 b'vinotfound',
1693 b'vinotfound',
1694 _(
1694 _(
1695 b" No commit editor set and can't find %s in PATH\n"
1695 b" No commit editor set and can't find %s in PATH\n"
1696 b" (specify a commit editor in your configuration"
1696 b" (specify a commit editor in your configuration"
1697 b" file)\n"
1697 b" file)\n"
1698 ),
1698 ),
1699 not cmdpath and editor == b'vi' and editorbin,
1699 not cmdpath and editor == b'vi' and editorbin,
1700 )
1700 )
1701 fm.condwrite(
1701 fm.condwrite(
1702 not cmdpath and editor != b'vi',
1702 not cmdpath and editor != b'vi',
1703 b'editornotfound',
1703 b'editornotfound',
1704 _(
1704 _(
1705 b" Can't find editor '%s' in PATH\n"
1705 b" Can't find editor '%s' in PATH\n"
1706 b" (specify a commit editor in your configuration"
1706 b" (specify a commit editor in your configuration"
1707 b" file)\n"
1707 b" file)\n"
1708 ),
1708 ),
1709 not cmdpath and editorbin,
1709 not cmdpath and editorbin,
1710 )
1710 )
1711 if not cmdpath and editor != b'vi':
1711 if not cmdpath and editor != b'vi':
1712 problems += 1
1712 problems += 1
1713
1713
1714 # check username
1714 # check username
1715 username = None
1715 username = None
1716 err = None
1716 err = None
1717 try:
1717 try:
1718 username = ui.username()
1718 username = ui.username()
1719 except error.Abort as e:
1719 except error.Abort as e:
1720 err = stringutil.forcebytestr(e)
1720 err = stringutil.forcebytestr(e)
1721 problems += 1
1721 problems += 1
1722
1722
1723 fm.condwrite(
1723 fm.condwrite(
1724 username, b'username', _(b"checking username (%s)\n"), username
1724 username, b'username', _(b"checking username (%s)\n"), username
1725 )
1725 )
1726 fm.condwrite(
1726 fm.condwrite(
1727 err,
1727 err,
1728 b'usernameerror',
1728 b'usernameerror',
1729 _(
1729 _(
1730 b"checking username...\n %s\n"
1730 b"checking username...\n %s\n"
1731 b" (specify a username in your configuration file)\n"
1731 b" (specify a username in your configuration file)\n"
1732 ),
1732 ),
1733 err,
1733 err,
1734 )
1734 )
1735
1735
1736 for name, mod in extensions.extensions():
1736 for name, mod in extensions.extensions():
1737 handler = getattr(mod, 'debuginstall', None)
1737 handler = getattr(mod, 'debuginstall', None)
1738 if handler is not None:
1738 if handler is not None:
1739 problems += handler(ui, fm)
1739 problems += handler(ui, fm)
1740
1740
1741 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1741 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1742 if not problems:
1742 if not problems:
1743 fm.data(problems=problems)
1743 fm.data(problems=problems)
1744 fm.condwrite(
1744 fm.condwrite(
1745 problems,
1745 problems,
1746 b'problems',
1746 b'problems',
1747 _(b"%d problems detected, please check your install!\n"),
1747 _(b"%d problems detected, please check your install!\n"),
1748 problems,
1748 problems,
1749 )
1749 )
1750 fm.end()
1750 fm.end()
1751
1751
1752 return problems
1752 return problems
1753
1753
1754
1754
1755 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1755 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1756 def debugknown(ui, repopath, *ids, **opts):
1756 def debugknown(ui, repopath, *ids, **opts):
1757 """test whether node ids are known to a repo
1757 """test whether node ids are known to a repo
1758
1758
1759 Every ID must be a full-length hex node id string. Returns a list of 0s
1759 Every ID must be a full-length hex node id string. Returns a list of 0s
1760 and 1s indicating unknown/known.
1760 and 1s indicating unknown/known.
1761 """
1761 """
1762 opts = pycompat.byteskwargs(opts)
1762 opts = pycompat.byteskwargs(opts)
1763 repo = hg.peer(ui, opts, repopath)
1763 repo = hg.peer(ui, opts, repopath)
1764 if not repo.capable(b'known'):
1764 if not repo.capable(b'known'):
1765 raise error.Abort(b"known() not supported by target repository")
1765 raise error.Abort(b"known() not supported by target repository")
1766 flags = repo.known([bin(s) for s in ids])
1766 flags = repo.known([bin(s) for s in ids])
1767 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1767 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1768
1768
1769
1769
1770 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1770 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1771 def debuglabelcomplete(ui, repo, *args):
1771 def debuglabelcomplete(ui, repo, *args):
1772 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1772 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1773 debugnamecomplete(ui, repo, *args)
1773 debugnamecomplete(ui, repo, *args)
1774
1774
1775
1775
1776 @command(
1776 @command(
1777 b'debuglocks',
1777 b'debuglocks',
1778 [
1778 [
1779 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1779 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1780 (
1780 (
1781 b'W',
1781 b'W',
1782 b'force-wlock',
1782 b'force-wlock',
1783 None,
1783 None,
1784 _(b'free the working state lock (DANGEROUS)'),
1784 _(b'free the working state lock (DANGEROUS)'),
1785 ),
1785 ),
1786 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1786 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1787 (
1787 (
1788 b'S',
1788 b'S',
1789 b'set-wlock',
1789 b'set-wlock',
1790 None,
1790 None,
1791 _(b'set the working state lock until stopped'),
1791 _(b'set the working state lock until stopped'),
1792 ),
1792 ),
1793 ],
1793 ],
1794 _(b'[OPTION]...'),
1794 _(b'[OPTION]...'),
1795 )
1795 )
1796 def debuglocks(ui, repo, **opts):
1796 def debuglocks(ui, repo, **opts):
1797 """show or modify state of locks
1797 """show or modify state of locks
1798
1798
1799 By default, this command will show which locks are held. This
1799 By default, this command will show which locks are held. This
1800 includes the user and process holding the lock, the amount of time
1800 includes the user and process holding the lock, the amount of time
1801 the lock has been held, and the machine name where the process is
1801 the lock has been held, and the machine name where the process is
1802 running if it's not local.
1802 running if it's not local.
1803
1803
1804 Locks protect the integrity of Mercurial's data, so should be
1804 Locks protect the integrity of Mercurial's data, so should be
1805 treated with care. System crashes or other interruptions may cause
1805 treated with care. System crashes or other interruptions may cause
1806 locks to not be properly released, though Mercurial will usually
1806 locks to not be properly released, though Mercurial will usually
1807 detect and remove such stale locks automatically.
1807 detect and remove such stale locks automatically.
1808
1808
1809 However, detecting stale locks may not always be possible (for
1809 However, detecting stale locks may not always be possible (for
1810 instance, on a shared filesystem). Removing locks may also be
1810 instance, on a shared filesystem). Removing locks may also be
1811 blocked by filesystem permissions.
1811 blocked by filesystem permissions.
1812
1812
1813 Setting a lock will prevent other commands from changing the data.
1813 Setting a lock will prevent other commands from changing the data.
1814 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1814 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1815 The set locks are removed when the command exits.
1815 The set locks are removed when the command exits.
1816
1816
1817 Returns 0 if no locks are held.
1817 Returns 0 if no locks are held.
1818
1818
1819 """
1819 """
1820
1820
1821 if opts.get('force_lock'):
1821 if opts.get('force_lock'):
1822 repo.svfs.unlink(b'lock')
1822 repo.svfs.unlink(b'lock')
1823 if opts.get('force_wlock'):
1823 if opts.get('force_wlock'):
1824 repo.vfs.unlink(b'wlock')
1824 repo.vfs.unlink(b'wlock')
1825 if opts.get('force_lock') or opts.get('force_wlock'):
1825 if opts.get('force_lock') or opts.get('force_wlock'):
1826 return 0
1826 return 0
1827
1827
1828 locks = []
1828 locks = []
1829 try:
1829 try:
1830 if opts.get('set_wlock'):
1830 if opts.get('set_wlock'):
1831 try:
1831 try:
1832 locks.append(repo.wlock(False))
1832 locks.append(repo.wlock(False))
1833 except error.LockHeld:
1833 except error.LockHeld:
1834 raise error.Abort(_(b'wlock is already held'))
1834 raise error.Abort(_(b'wlock is already held'))
1835 if opts.get('set_lock'):
1835 if opts.get('set_lock'):
1836 try:
1836 try:
1837 locks.append(repo.lock(False))
1837 locks.append(repo.lock(False))
1838 except error.LockHeld:
1838 except error.LockHeld:
1839 raise error.Abort(_(b'lock is already held'))
1839 raise error.Abort(_(b'lock is already held'))
1840 if len(locks):
1840 if len(locks):
1841 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1841 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1842 return 0
1842 return 0
1843 finally:
1843 finally:
1844 release(*locks)
1844 release(*locks)
1845
1845
1846 now = time.time()
1846 now = time.time()
1847 held = 0
1847 held = 0
1848
1848
1849 def report(vfs, name, method):
1849 def report(vfs, name, method):
1850 # this causes stale locks to get reaped for more accurate reporting
1850 # this causes stale locks to get reaped for more accurate reporting
1851 try:
1851 try:
1852 l = method(False)
1852 l = method(False)
1853 except error.LockHeld:
1853 except error.LockHeld:
1854 l = None
1854 l = None
1855
1855
1856 if l:
1856 if l:
1857 l.release()
1857 l.release()
1858 else:
1858 else:
1859 try:
1859 try:
1860 st = vfs.lstat(name)
1860 st = vfs.lstat(name)
1861 age = now - st[stat.ST_MTIME]
1861 age = now - st[stat.ST_MTIME]
1862 user = util.username(st.st_uid)
1862 user = util.username(st.st_uid)
1863 locker = vfs.readlock(name)
1863 locker = vfs.readlock(name)
1864 if b":" in locker:
1864 if b":" in locker:
1865 host, pid = locker.split(b':')
1865 host, pid = locker.split(b':')
1866 if host == socket.gethostname():
1866 if host == socket.gethostname():
1867 locker = b'user %s, process %s' % (user or b'None', pid)
1867 locker = b'user %s, process %s' % (user or b'None', pid)
1868 else:
1868 else:
1869 locker = b'user %s, process %s, host %s' % (
1869 locker = b'user %s, process %s, host %s' % (
1870 user or b'None',
1870 user or b'None',
1871 pid,
1871 pid,
1872 host,
1872 host,
1873 )
1873 )
1874 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1874 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1875 return 1
1875 return 1
1876 except OSError as e:
1876 except OSError as e:
1877 if e.errno != errno.ENOENT:
1877 if e.errno != errno.ENOENT:
1878 raise
1878 raise
1879
1879
1880 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1880 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1881 return 0
1881 return 0
1882
1882
1883 held += report(repo.svfs, b"lock", repo.lock)
1883 held += report(repo.svfs, b"lock", repo.lock)
1884 held += report(repo.vfs, b"wlock", repo.wlock)
1884 held += report(repo.vfs, b"wlock", repo.wlock)
1885
1885
1886 return held
1886 return held
1887
1887
1888
1888
1889 @command(
1889 @command(
1890 b'debugmanifestfulltextcache',
1890 b'debugmanifestfulltextcache',
1891 [
1891 [
1892 (b'', b'clear', False, _(b'clear the cache')),
1892 (b'', b'clear', False, _(b'clear the cache')),
1893 (
1893 (
1894 b'a',
1894 b'a',
1895 b'add',
1895 b'add',
1896 [],
1896 [],
1897 _(b'add the given manifest nodes to the cache'),
1897 _(b'add the given manifest nodes to the cache'),
1898 _(b'NODE'),
1898 _(b'NODE'),
1899 ),
1899 ),
1900 ],
1900 ],
1901 b'',
1901 b'',
1902 )
1902 )
1903 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1903 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1904 """show, clear or amend the contents of the manifest fulltext cache"""
1904 """show, clear or amend the contents of the manifest fulltext cache"""
1905
1905
1906 def getcache():
1906 def getcache():
1907 r = repo.manifestlog.getstorage(b'')
1907 r = repo.manifestlog.getstorage(b'')
1908 try:
1908 try:
1909 return r._fulltextcache
1909 return r._fulltextcache
1910 except AttributeError:
1910 except AttributeError:
1911 msg = _(
1911 msg = _(
1912 b"Current revlog implementation doesn't appear to have a "
1912 b"Current revlog implementation doesn't appear to have a "
1913 b"manifest fulltext cache\n"
1913 b"manifest fulltext cache\n"
1914 )
1914 )
1915 raise error.Abort(msg)
1915 raise error.Abort(msg)
1916
1916
1917 if opts.get('clear'):
1917 if opts.get('clear'):
1918 with repo.wlock():
1918 with repo.wlock():
1919 cache = getcache()
1919 cache = getcache()
1920 cache.clear(clear_persisted_data=True)
1920 cache.clear(clear_persisted_data=True)
1921 return
1921 return
1922
1922
1923 if add:
1923 if add:
1924 with repo.wlock():
1924 with repo.wlock():
1925 m = repo.manifestlog
1925 m = repo.manifestlog
1926 store = m.getstorage(b'')
1926 store = m.getstorage(b'')
1927 for n in add:
1927 for n in add:
1928 try:
1928 try:
1929 manifest = m[store.lookup(n)]
1929 manifest = m[store.lookup(n)]
1930 except error.LookupError as e:
1930 except error.LookupError as e:
1931 raise error.Abort(e, hint=b"Check your manifest node id")
1931 raise error.Abort(e, hint=b"Check your manifest node id")
1932 manifest.read() # stores revisision in cache too
1932 manifest.read() # stores revisision in cache too
1933 return
1933 return
1934
1934
1935 cache = getcache()
1935 cache = getcache()
1936 if not len(cache):
1936 if not len(cache):
1937 ui.write(_(b'cache empty\n'))
1937 ui.write(_(b'cache empty\n'))
1938 else:
1938 else:
1939 ui.write(
1939 ui.write(
1940 _(
1940 _(
1941 b'cache contains %d manifest entries, in order of most to '
1941 b'cache contains %d manifest entries, in order of most to '
1942 b'least recent:\n'
1942 b'least recent:\n'
1943 )
1943 )
1944 % (len(cache),)
1944 % (len(cache),)
1945 )
1945 )
1946 totalsize = 0
1946 totalsize = 0
1947 for nodeid in cache:
1947 for nodeid in cache:
1948 # Use cache.get to not update the LRU order
1948 # Use cache.get to not update the LRU order
1949 data = cache.peek(nodeid)
1949 data = cache.peek(nodeid)
1950 size = len(data)
1950 size = len(data)
1951 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1951 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1952 ui.write(
1952 ui.write(
1953 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1953 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1954 )
1954 )
1955 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1955 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1956 ui.write(
1956 ui.write(
1957 _(b'total cache data size %s, on-disk %s\n')
1957 _(b'total cache data size %s, on-disk %s\n')
1958 % (util.bytecount(totalsize), util.bytecount(ondisk))
1958 % (util.bytecount(totalsize), util.bytecount(ondisk))
1959 )
1959 )
1960
1960
1961
1961
1962 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
1962 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
1963 def debugmergestate(ui, repo, *args, **opts):
1963 def debugmergestate(ui, repo, *args, **opts):
1964 """print merge state
1964 """print merge state
1965
1965
1966 Use --verbose to print out information about whether v1 or v2 merge state
1966 Use --verbose to print out information about whether v1 or v2 merge state
1967 was chosen."""
1967 was chosen."""
1968
1968
1969 if ui.verbose:
1969 if ui.verbose:
1970 ms = mergestatemod.mergestate(repo)
1970 ms = mergestatemod.mergestate(repo)
1971
1971
1972 # sort so that reasonable information is on top
1972 # sort so that reasonable information is on top
1973 v1records = ms._readrecordsv1()
1973 v1records = ms._readrecordsv1()
1974 v2records = ms._readrecordsv2()
1974 v2records = ms._readrecordsv2()
1975
1975
1976 if not v1records and not v2records:
1976 if not v1records and not v2records:
1977 pass
1977 pass
1978 elif not v2records:
1978 elif not v2records:
1979 ui.writenoi18n(b'no version 2 merge state\n')
1979 ui.writenoi18n(b'no version 2 merge state\n')
1980 elif ms._v1v2match(v1records, v2records):
1980 elif ms._v1v2match(v1records, v2records):
1981 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
1981 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
1982 else:
1982 else:
1983 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
1983 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
1984
1984
1985 opts = pycompat.byteskwargs(opts)
1985 opts = pycompat.byteskwargs(opts)
1986 if not opts[b'template']:
1986 if not opts[b'template']:
1987 opts[b'template'] = (
1987 opts[b'template'] = (
1988 b'{if(commits, "", "no merge state found\n")}'
1988 b'{if(commits, "", "no merge state found\n")}'
1989 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
1989 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
1990 b'{files % "file: {path} (state \\"{state}\\")\n'
1990 b'{files % "file: {path} (state \\"{state}\\")\n'
1991 b'{if(local_path, "'
1991 b'{if(local_path, "'
1992 b' local path: {local_path} (hash {local_key}, flags \\"{local_flags}\\")\n'
1992 b' local path: {local_path} (hash {local_key}, flags \\"{local_flags}\\")\n'
1993 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
1993 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
1994 b' other path: {other_path} (node {other_node})\n'
1994 b' other path: {other_path} (node {other_node})\n'
1995 b'")}'
1995 b'")}'
1996 b'{if(rename_side, "'
1996 b'{if(rename_side, "'
1997 b' rename side: {rename_side}\n'
1997 b' rename side: {rename_side}\n'
1998 b' renamed path: {renamed_path}\n'
1998 b' renamed path: {renamed_path}\n'
1999 b'")}'
1999 b'")}'
2000 b'{extras % " extra: {key} = {value}\n"}'
2000 b'{extras % " extra: {key} = {value}\n"}'
2001 b'"}'
2001 b'"}'
2002 )
2002 )
2003
2003
2004 ms = mergestatemod.mergestate.read(repo)
2004 ms = mergestatemod.mergestate.read(repo)
2005
2005
2006 fm = ui.formatter(b'debugmergestate', opts)
2006 fm = ui.formatter(b'debugmergestate', opts)
2007 fm.startitem()
2007 fm.startitem()
2008
2008
2009 fm_commits = fm.nested(b'commits')
2009 fm_commits = fm.nested(b'commits')
2010 if ms.active():
2010 if ms.active():
2011 for name, node, label_index in (
2011 for name, node, label_index in (
2012 (b'local', ms.local, 0),
2012 (b'local', ms.local, 0),
2013 (b'other', ms.other, 1),
2013 (b'other', ms.other, 1),
2014 ):
2014 ):
2015 fm_commits.startitem()
2015 fm_commits.startitem()
2016 fm_commits.data(name=name)
2016 fm_commits.data(name=name)
2017 fm_commits.data(node=hex(node))
2017 fm_commits.data(node=hex(node))
2018 if ms._labels and len(ms._labels) > label_index:
2018 if ms._labels and len(ms._labels) > label_index:
2019 fm_commits.data(label=ms._labels[label_index])
2019 fm_commits.data(label=ms._labels[label_index])
2020 fm_commits.end()
2020 fm_commits.end()
2021
2021
2022 fm_files = fm.nested(b'files')
2022 fm_files = fm.nested(b'files')
2023 if ms.active():
2023 if ms.active():
2024 for f in ms:
2024 for f in ms:
2025 fm_files.startitem()
2025 fm_files.startitem()
2026 fm_files.data(path=f)
2026 fm_files.data(path=f)
2027 state = ms._state[f]
2027 state = ms._state[f]
2028 fm_files.data(state=state[0])
2028 fm_files.data(state=state[0])
2029 if state[0] in (
2029 if state[0] in (
2030 mergestatemod.MERGE_RECORD_UNRESOLVED,
2030 mergestatemod.MERGE_RECORD_UNRESOLVED,
2031 mergestatemod.MERGE_RECORD_RESOLVED,
2031 mergestatemod.MERGE_RECORD_RESOLVED,
2032 ):
2032 ):
2033 fm_files.data(local_key=state[1])
2033 fm_files.data(local_key=state[1])
2034 fm_files.data(local_path=state[2])
2034 fm_files.data(local_path=state[2])
2035 fm_files.data(ancestor_path=state[3])
2035 fm_files.data(ancestor_path=state[3])
2036 fm_files.data(ancestor_node=state[4])
2036 fm_files.data(ancestor_node=state[4])
2037 fm_files.data(other_path=state[5])
2037 fm_files.data(other_path=state[5])
2038 fm_files.data(other_node=state[6])
2038 fm_files.data(other_node=state[6])
2039 fm_files.data(local_flags=state[7])
2039 fm_files.data(local_flags=state[7])
2040 elif state[0] in (
2040 elif state[0] in (
2041 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
2041 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
2042 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
2042 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
2043 ):
2043 ):
2044 fm_files.data(renamed_path=state[1])
2044 fm_files.data(renamed_path=state[1])
2045 fm_files.data(rename_side=state[2])
2045 fm_files.data(rename_side=state[2])
2046 fm_extras = fm_files.nested(b'extras')
2046 fm_extras = fm_files.nested(b'extras')
2047 for k, v in ms.extras(f).items():
2047 for k, v in ms.extras(f).items():
2048 fm_extras.startitem()
2048 fm_extras.startitem()
2049 fm_extras.data(key=k)
2049 fm_extras.data(key=k)
2050 fm_extras.data(value=v)
2050 fm_extras.data(value=v)
2051 fm_extras.end()
2051 fm_extras.end()
2052
2052
2053 fm_files.end()
2053 fm_files.end()
2054
2054
2055 fm.end()
2055 fm.end()
2056
2056
2057
2057
2058 @command(b'debugnamecomplete', [], _(b'NAME...'))
2058 @command(b'debugnamecomplete', [], _(b'NAME...'))
2059 def debugnamecomplete(ui, repo, *args):
2059 def debugnamecomplete(ui, repo, *args):
2060 '''complete "names" - tags, open branch names, bookmark names'''
2060 '''complete "names" - tags, open branch names, bookmark names'''
2061
2061
2062 names = set()
2062 names = set()
2063 # since we previously only listed open branches, we will handle that
2063 # since we previously only listed open branches, we will handle that
2064 # specially (after this for loop)
2064 # specially (after this for loop)
2065 for name, ns in pycompat.iteritems(repo.names):
2065 for name, ns in pycompat.iteritems(repo.names):
2066 if name != b'branches':
2066 if name != b'branches':
2067 names.update(ns.listnames(repo))
2067 names.update(ns.listnames(repo))
2068 names.update(
2068 names.update(
2069 tag
2069 tag
2070 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2070 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2071 if not closed
2071 if not closed
2072 )
2072 )
2073 completions = set()
2073 completions = set()
2074 if not args:
2074 if not args:
2075 args = [b'']
2075 args = [b'']
2076 for a in args:
2076 for a in args:
2077 completions.update(n for n in names if n.startswith(a))
2077 completions.update(n for n in names if n.startswith(a))
2078 ui.write(b'\n'.join(sorted(completions)))
2078 ui.write(b'\n'.join(sorted(completions)))
2079 ui.write(b'\n')
2079 ui.write(b'\n')
2080
2080
2081
2081
2082 @command(
2082 @command(
2083 b'debugnodemap',
2083 b'debugnodemap',
2084 [
2084 [
2085 (
2085 (
2086 b'',
2086 b'',
2087 b'dump-new',
2087 b'dump-new',
2088 False,
2088 False,
2089 _(b'write a (new) persistent binary nodemap on stdin'),
2089 _(b'write a (new) persistent binary nodemap on stdin'),
2090 ),
2090 ),
2091 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
2091 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
2092 (
2092 (
2093 b'',
2093 b'',
2094 b'check',
2094 b'check',
2095 False,
2095 False,
2096 _(b'check that the data on disk data are correct.'),
2096 _(b'check that the data on disk data are correct.'),
2097 ),
2097 ),
2098 (
2098 (
2099 b'',
2099 b'',
2100 b'metadata',
2100 b'metadata',
2101 False,
2101 False,
2102 _(b'display the on disk meta data for the nodemap'),
2102 _(b'display the on disk meta data for the nodemap'),
2103 ),
2103 ),
2104 ],
2104 ],
2105 )
2105 )
2106 def debugnodemap(ui, repo, **opts):
2106 def debugnodemap(ui, repo, **opts):
2107 """write and inspect on disk nodemap
2107 """write and inspect on disk nodemap
2108 """
2108 """
2109 if opts['dump_new']:
2109 if opts['dump_new']:
2110 unfi = repo.unfiltered()
2110 unfi = repo.unfiltered()
2111 cl = unfi.changelog
2111 cl = unfi.changelog
2112 if util.safehasattr(cl.index, "nodemap_data_all"):
2112 if util.safehasattr(cl.index, "nodemap_data_all"):
2113 data = cl.index.nodemap_data_all()
2113 data = cl.index.nodemap_data_all()
2114 else:
2114 else:
2115 data = nodemap.persistent_data(cl.index)
2115 data = nodemap.persistent_data(cl.index)
2116 ui.write(data)
2116 ui.write(data)
2117 elif opts['dump_disk']:
2117 elif opts['dump_disk']:
2118 unfi = repo.unfiltered()
2118 unfi = repo.unfiltered()
2119 cl = unfi.changelog
2119 cl = unfi.changelog
2120 nm_data = nodemap.persisted_data(cl)
2120 nm_data = nodemap.persisted_data(cl)
2121 if nm_data is not None:
2121 if nm_data is not None:
2122 docket, data = nm_data
2122 docket, data = nm_data
2123 ui.write(data[:])
2123 ui.write(data[:])
2124 elif opts['check']:
2124 elif opts['check']:
2125 unfi = repo.unfiltered()
2125 unfi = repo.unfiltered()
2126 cl = unfi.changelog
2126 cl = unfi.changelog
2127 nm_data = nodemap.persisted_data(cl)
2127 nm_data = nodemap.persisted_data(cl)
2128 if nm_data is not None:
2128 if nm_data is not None:
2129 docket, data = nm_data
2129 docket, data = nm_data
2130 return nodemap.check_data(ui, cl.index, data)
2130 return nodemap.check_data(ui, cl.index, data)
2131 elif opts['metadata']:
2131 elif opts['metadata']:
2132 unfi = repo.unfiltered()
2132 unfi = repo.unfiltered()
2133 cl = unfi.changelog
2133 cl = unfi.changelog
2134 nm_data = nodemap.persisted_data(cl)
2134 nm_data = nodemap.persisted_data(cl)
2135 if nm_data is not None:
2135 if nm_data is not None:
2136 docket, data = nm_data
2136 docket, data = nm_data
2137 ui.write((b"uid: %s\n") % docket.uid)
2137 ui.write((b"uid: %s\n") % docket.uid)
2138 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2138 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2139 ui.write((b"tip-node: %s\n") % hex(docket.tip_node))
2139 ui.write((b"tip-node: %s\n") % hex(docket.tip_node))
2140 ui.write((b"data-length: %d\n") % docket.data_length)
2140 ui.write((b"data-length: %d\n") % docket.data_length)
2141 ui.write((b"data-unused: %d\n") % docket.data_unused)
2141 ui.write((b"data-unused: %d\n") % docket.data_unused)
2142 unused_perc = docket.data_unused * 100.0 / docket.data_length
2142 unused_perc = docket.data_unused * 100.0 / docket.data_length
2143 ui.write((b"data-unused: %2.3f%%\n") % unused_perc)
2143 ui.write((b"data-unused: %2.3f%%\n") % unused_perc)
2144
2144
2145
2145
2146 @command(
2146 @command(
2147 b'debugobsolete',
2147 b'debugobsolete',
2148 [
2148 [
2149 (b'', b'flags', 0, _(b'markers flag')),
2149 (b'', b'flags', 0, _(b'markers flag')),
2150 (
2150 (
2151 b'',
2151 b'',
2152 b'record-parents',
2152 b'record-parents',
2153 False,
2153 False,
2154 _(b'record parent information for the precursor'),
2154 _(b'record parent information for the precursor'),
2155 ),
2155 ),
2156 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2156 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2157 (
2157 (
2158 b'',
2158 b'',
2159 b'exclusive',
2159 b'exclusive',
2160 False,
2160 False,
2161 _(b'restrict display to markers only relevant to REV'),
2161 _(b'restrict display to markers only relevant to REV'),
2162 ),
2162 ),
2163 (b'', b'index', False, _(b'display index of the marker')),
2163 (b'', b'index', False, _(b'display index of the marker')),
2164 (b'', b'delete', [], _(b'delete markers specified by indices')),
2164 (b'', b'delete', [], _(b'delete markers specified by indices')),
2165 ]
2165 ]
2166 + cmdutil.commitopts2
2166 + cmdutil.commitopts2
2167 + cmdutil.formatteropts,
2167 + cmdutil.formatteropts,
2168 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2168 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2169 )
2169 )
2170 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2170 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2171 """create arbitrary obsolete marker
2171 """create arbitrary obsolete marker
2172
2172
2173 With no arguments, displays the list of obsolescence markers."""
2173 With no arguments, displays the list of obsolescence markers."""
2174
2174
2175 opts = pycompat.byteskwargs(opts)
2175 opts = pycompat.byteskwargs(opts)
2176
2176
2177 def parsenodeid(s):
2177 def parsenodeid(s):
2178 try:
2178 try:
2179 # We do not use revsingle/revrange functions here to accept
2179 # We do not use revsingle/revrange functions here to accept
2180 # arbitrary node identifiers, possibly not present in the
2180 # arbitrary node identifiers, possibly not present in the
2181 # local repository.
2181 # local repository.
2182 n = bin(s)
2182 n = bin(s)
2183 if len(n) != len(nullid):
2183 if len(n) != len(nullid):
2184 raise TypeError()
2184 raise TypeError()
2185 return n
2185 return n
2186 except TypeError:
2186 except TypeError:
2187 raise error.Abort(
2187 raise error.Abort(
2188 b'changeset references must be full hexadecimal '
2188 b'changeset references must be full hexadecimal '
2189 b'node identifiers'
2189 b'node identifiers'
2190 )
2190 )
2191
2191
2192 if opts.get(b'delete'):
2192 if opts.get(b'delete'):
2193 indices = []
2193 indices = []
2194 for v in opts.get(b'delete'):
2194 for v in opts.get(b'delete'):
2195 try:
2195 try:
2196 indices.append(int(v))
2196 indices.append(int(v))
2197 except ValueError:
2197 except ValueError:
2198 raise error.Abort(
2198 raise error.Abort(
2199 _(b'invalid index value: %r') % v,
2199 _(b'invalid index value: %r') % v,
2200 hint=_(b'use integers for indices'),
2200 hint=_(b'use integers for indices'),
2201 )
2201 )
2202
2202
2203 if repo.currenttransaction():
2203 if repo.currenttransaction():
2204 raise error.Abort(
2204 raise error.Abort(
2205 _(b'cannot delete obsmarkers in the middle of transaction.')
2205 _(b'cannot delete obsmarkers in the middle of transaction.')
2206 )
2206 )
2207
2207
2208 with repo.lock():
2208 with repo.lock():
2209 n = repair.deleteobsmarkers(repo.obsstore, indices)
2209 n = repair.deleteobsmarkers(repo.obsstore, indices)
2210 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2210 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2211
2211
2212 return
2212 return
2213
2213
2214 if precursor is not None:
2214 if precursor is not None:
2215 if opts[b'rev']:
2215 if opts[b'rev']:
2216 raise error.Abort(b'cannot select revision when creating marker')
2216 raise error.Abort(b'cannot select revision when creating marker')
2217 metadata = {}
2217 metadata = {}
2218 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2218 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2219 succs = tuple(parsenodeid(succ) for succ in successors)
2219 succs = tuple(parsenodeid(succ) for succ in successors)
2220 l = repo.lock()
2220 l = repo.lock()
2221 try:
2221 try:
2222 tr = repo.transaction(b'debugobsolete')
2222 tr = repo.transaction(b'debugobsolete')
2223 try:
2223 try:
2224 date = opts.get(b'date')
2224 date = opts.get(b'date')
2225 if date:
2225 if date:
2226 date = dateutil.parsedate(date)
2226 date = dateutil.parsedate(date)
2227 else:
2227 else:
2228 date = None
2228 date = None
2229 prec = parsenodeid(precursor)
2229 prec = parsenodeid(precursor)
2230 parents = None
2230 parents = None
2231 if opts[b'record_parents']:
2231 if opts[b'record_parents']:
2232 if prec not in repo.unfiltered():
2232 if prec not in repo.unfiltered():
2233 raise error.Abort(
2233 raise error.Abort(
2234 b'cannot used --record-parents on '
2234 b'cannot used --record-parents on '
2235 b'unknown changesets'
2235 b'unknown changesets'
2236 )
2236 )
2237 parents = repo.unfiltered()[prec].parents()
2237 parents = repo.unfiltered()[prec].parents()
2238 parents = tuple(p.node() for p in parents)
2238 parents = tuple(p.node() for p in parents)
2239 repo.obsstore.create(
2239 repo.obsstore.create(
2240 tr,
2240 tr,
2241 prec,
2241 prec,
2242 succs,
2242 succs,
2243 opts[b'flags'],
2243 opts[b'flags'],
2244 parents=parents,
2244 parents=parents,
2245 date=date,
2245 date=date,
2246 metadata=metadata,
2246 metadata=metadata,
2247 ui=ui,
2247 ui=ui,
2248 )
2248 )
2249 tr.close()
2249 tr.close()
2250 except ValueError as exc:
2250 except ValueError as exc:
2251 raise error.Abort(
2251 raise error.Abort(
2252 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2252 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2253 )
2253 )
2254 finally:
2254 finally:
2255 tr.release()
2255 tr.release()
2256 finally:
2256 finally:
2257 l.release()
2257 l.release()
2258 else:
2258 else:
2259 if opts[b'rev']:
2259 if opts[b'rev']:
2260 revs = scmutil.revrange(repo, opts[b'rev'])
2260 revs = scmutil.revrange(repo, opts[b'rev'])
2261 nodes = [repo[r].node() for r in revs]
2261 nodes = [repo[r].node() for r in revs]
2262 markers = list(
2262 markers = list(
2263 obsutil.getmarkers(
2263 obsutil.getmarkers(
2264 repo, nodes=nodes, exclusive=opts[b'exclusive']
2264 repo, nodes=nodes, exclusive=opts[b'exclusive']
2265 )
2265 )
2266 )
2266 )
2267 markers.sort(key=lambda x: x._data)
2267 markers.sort(key=lambda x: x._data)
2268 else:
2268 else:
2269 markers = obsutil.getmarkers(repo)
2269 markers = obsutil.getmarkers(repo)
2270
2270
2271 markerstoiter = markers
2271 markerstoiter = markers
2272 isrelevant = lambda m: True
2272 isrelevant = lambda m: True
2273 if opts.get(b'rev') and opts.get(b'index'):
2273 if opts.get(b'rev') and opts.get(b'index'):
2274 markerstoiter = obsutil.getmarkers(repo)
2274 markerstoiter = obsutil.getmarkers(repo)
2275 markerset = set(markers)
2275 markerset = set(markers)
2276 isrelevant = lambda m: m in markerset
2276 isrelevant = lambda m: m in markerset
2277
2277
2278 fm = ui.formatter(b'debugobsolete', opts)
2278 fm = ui.formatter(b'debugobsolete', opts)
2279 for i, m in enumerate(markerstoiter):
2279 for i, m in enumerate(markerstoiter):
2280 if not isrelevant(m):
2280 if not isrelevant(m):
2281 # marker can be irrelevant when we're iterating over a set
2281 # marker can be irrelevant when we're iterating over a set
2282 # of markers (markerstoiter) which is bigger than the set
2282 # of markers (markerstoiter) which is bigger than the set
2283 # of markers we want to display (markers)
2283 # of markers we want to display (markers)
2284 # this can happen if both --index and --rev options are
2284 # this can happen if both --index and --rev options are
2285 # provided and thus we need to iterate over all of the markers
2285 # provided and thus we need to iterate over all of the markers
2286 # to get the correct indices, but only display the ones that
2286 # to get the correct indices, but only display the ones that
2287 # are relevant to --rev value
2287 # are relevant to --rev value
2288 continue
2288 continue
2289 fm.startitem()
2289 fm.startitem()
2290 ind = i if opts.get(b'index') else None
2290 ind = i if opts.get(b'index') else None
2291 cmdutil.showmarker(fm, m, index=ind)
2291 cmdutil.showmarker(fm, m, index=ind)
2292 fm.end()
2292 fm.end()
2293
2293
2294
2294
2295 @command(
2295 @command(
2296 b'debugp1copies',
2296 b'debugp1copies',
2297 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2297 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2298 _(b'[-r REV]'),
2298 _(b'[-r REV]'),
2299 )
2299 )
2300 def debugp1copies(ui, repo, **opts):
2300 def debugp1copies(ui, repo, **opts):
2301 """dump copy information compared to p1"""
2301 """dump copy information compared to p1"""
2302
2302
2303 opts = pycompat.byteskwargs(opts)
2303 opts = pycompat.byteskwargs(opts)
2304 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2304 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2305 for dst, src in ctx.p1copies().items():
2305 for dst, src in ctx.p1copies().items():
2306 ui.write(b'%s -> %s\n' % (src, dst))
2306 ui.write(b'%s -> %s\n' % (src, dst))
2307
2307
2308
2308
2309 @command(
2309 @command(
2310 b'debugp2copies',
2310 b'debugp2copies',
2311 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2311 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2312 _(b'[-r REV]'),
2312 _(b'[-r REV]'),
2313 )
2313 )
2314 def debugp1copies(ui, repo, **opts):
2314 def debugp1copies(ui, repo, **opts):
2315 """dump copy information compared to p2"""
2315 """dump copy information compared to p2"""
2316
2316
2317 opts = pycompat.byteskwargs(opts)
2317 opts = pycompat.byteskwargs(opts)
2318 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2318 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2319 for dst, src in ctx.p2copies().items():
2319 for dst, src in ctx.p2copies().items():
2320 ui.write(b'%s -> %s\n' % (src, dst))
2320 ui.write(b'%s -> %s\n' % (src, dst))
2321
2321
2322
2322
2323 @command(
2323 @command(
2324 b'debugpathcomplete',
2324 b'debugpathcomplete',
2325 [
2325 [
2326 (b'f', b'full', None, _(b'complete an entire path')),
2326 (b'f', b'full', None, _(b'complete an entire path')),
2327 (b'n', b'normal', None, _(b'show only normal files')),
2327 (b'n', b'normal', None, _(b'show only normal files')),
2328 (b'a', b'added', None, _(b'show only added files')),
2328 (b'a', b'added', None, _(b'show only added files')),
2329 (b'r', b'removed', None, _(b'show only removed files')),
2329 (b'r', b'removed', None, _(b'show only removed files')),
2330 ],
2330 ],
2331 _(b'FILESPEC...'),
2331 _(b'FILESPEC...'),
2332 )
2332 )
2333 def debugpathcomplete(ui, repo, *specs, **opts):
2333 def debugpathcomplete(ui, repo, *specs, **opts):
2334 '''complete part or all of a tracked path
2334 '''complete part or all of a tracked path
2335
2335
2336 This command supports shells that offer path name completion. It
2336 This command supports shells that offer path name completion. It
2337 currently completes only files already known to the dirstate.
2337 currently completes only files already known to the dirstate.
2338
2338
2339 Completion extends only to the next path segment unless
2339 Completion extends only to the next path segment unless
2340 --full is specified, in which case entire paths are used.'''
2340 --full is specified, in which case entire paths are used.'''
2341
2341
2342 def complete(path, acceptable):
2342 def complete(path, acceptable):
2343 dirstate = repo.dirstate
2343 dirstate = repo.dirstate
2344 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2344 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2345 rootdir = repo.root + pycompat.ossep
2345 rootdir = repo.root + pycompat.ossep
2346 if spec != repo.root and not spec.startswith(rootdir):
2346 if spec != repo.root and not spec.startswith(rootdir):
2347 return [], []
2347 return [], []
2348 if os.path.isdir(spec):
2348 if os.path.isdir(spec):
2349 spec += b'/'
2349 spec += b'/'
2350 spec = spec[len(rootdir) :]
2350 spec = spec[len(rootdir) :]
2351 fixpaths = pycompat.ossep != b'/'
2351 fixpaths = pycompat.ossep != b'/'
2352 if fixpaths:
2352 if fixpaths:
2353 spec = spec.replace(pycompat.ossep, b'/')
2353 spec = spec.replace(pycompat.ossep, b'/')
2354 speclen = len(spec)
2354 speclen = len(spec)
2355 fullpaths = opts['full']
2355 fullpaths = opts['full']
2356 files, dirs = set(), set()
2356 files, dirs = set(), set()
2357 adddir, addfile = dirs.add, files.add
2357 adddir, addfile = dirs.add, files.add
2358 for f, st in pycompat.iteritems(dirstate):
2358 for f, st in pycompat.iteritems(dirstate):
2359 if f.startswith(spec) and st[0] in acceptable:
2359 if f.startswith(spec) and st[0] in acceptable:
2360 if fixpaths:
2360 if fixpaths:
2361 f = f.replace(b'/', pycompat.ossep)
2361 f = f.replace(b'/', pycompat.ossep)
2362 if fullpaths:
2362 if fullpaths:
2363 addfile(f)
2363 addfile(f)
2364 continue
2364 continue
2365 s = f.find(pycompat.ossep, speclen)
2365 s = f.find(pycompat.ossep, speclen)
2366 if s >= 0:
2366 if s >= 0:
2367 adddir(f[:s])
2367 adddir(f[:s])
2368 else:
2368 else:
2369 addfile(f)
2369 addfile(f)
2370 return files, dirs
2370 return files, dirs
2371
2371
2372 acceptable = b''
2372 acceptable = b''
2373 if opts['normal']:
2373 if opts['normal']:
2374 acceptable += b'nm'
2374 acceptable += b'nm'
2375 if opts['added']:
2375 if opts['added']:
2376 acceptable += b'a'
2376 acceptable += b'a'
2377 if opts['removed']:
2377 if opts['removed']:
2378 acceptable += b'r'
2378 acceptable += b'r'
2379 cwd = repo.getcwd()
2379 cwd = repo.getcwd()
2380 if not specs:
2380 if not specs:
2381 specs = [b'.']
2381 specs = [b'.']
2382
2382
2383 files, dirs = set(), set()
2383 files, dirs = set(), set()
2384 for spec in specs:
2384 for spec in specs:
2385 f, d = complete(spec, acceptable or b'nmar')
2385 f, d = complete(spec, acceptable or b'nmar')
2386 files.update(f)
2386 files.update(f)
2387 dirs.update(d)
2387 dirs.update(d)
2388 files.update(dirs)
2388 files.update(dirs)
2389 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2389 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2390 ui.write(b'\n')
2390 ui.write(b'\n')
2391
2391
2392
2392
2393 @command(
2393 @command(
2394 b'debugpathcopies',
2394 b'debugpathcopies',
2395 cmdutil.walkopts,
2395 cmdutil.walkopts,
2396 b'hg debugpathcopies REV1 REV2 [FILE]',
2396 b'hg debugpathcopies REV1 REV2 [FILE]',
2397 inferrepo=True,
2397 inferrepo=True,
2398 )
2398 )
2399 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2399 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2400 """show copies between two revisions"""
2400 """show copies between two revisions"""
2401 ctx1 = scmutil.revsingle(repo, rev1)
2401 ctx1 = scmutil.revsingle(repo, rev1)
2402 ctx2 = scmutil.revsingle(repo, rev2)
2402 ctx2 = scmutil.revsingle(repo, rev2)
2403 m = scmutil.match(ctx1, pats, opts)
2403 m = scmutil.match(ctx1, pats, opts)
2404 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2404 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2405 ui.write(b'%s -> %s\n' % (src, dst))
2405 ui.write(b'%s -> %s\n' % (src, dst))
2406
2406
2407
2407
2408 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2408 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2409 def debugpeer(ui, path):
2409 def debugpeer(ui, path):
2410 """establish a connection to a peer repository"""
2410 """establish a connection to a peer repository"""
2411 # Always enable peer request logging. Requires --debug to display
2411 # Always enable peer request logging. Requires --debug to display
2412 # though.
2412 # though.
2413 overrides = {
2413 overrides = {
2414 (b'devel', b'debug.peer-request'): True,
2414 (b'devel', b'debug.peer-request'): True,
2415 }
2415 }
2416
2416
2417 with ui.configoverride(overrides):
2417 with ui.configoverride(overrides):
2418 peer = hg.peer(ui, {}, path)
2418 peer = hg.peer(ui, {}, path)
2419
2419
2420 local = peer.local() is not None
2420 local = peer.local() is not None
2421 canpush = peer.canpush()
2421 canpush = peer.canpush()
2422
2422
2423 ui.write(_(b'url: %s\n') % peer.url())
2423 ui.write(_(b'url: %s\n') % peer.url())
2424 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2424 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2425 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2425 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2426
2426
2427
2427
2428 @command(
2428 @command(
2429 b'debugpickmergetool',
2429 b'debugpickmergetool',
2430 [
2430 [
2431 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2431 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2432 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2432 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2433 ]
2433 ]
2434 + cmdutil.walkopts
2434 + cmdutil.walkopts
2435 + cmdutil.mergetoolopts,
2435 + cmdutil.mergetoolopts,
2436 _(b'[PATTERN]...'),
2436 _(b'[PATTERN]...'),
2437 inferrepo=True,
2437 inferrepo=True,
2438 )
2438 )
2439 def debugpickmergetool(ui, repo, *pats, **opts):
2439 def debugpickmergetool(ui, repo, *pats, **opts):
2440 """examine which merge tool is chosen for specified file
2440 """examine which merge tool is chosen for specified file
2441
2441
2442 As described in :hg:`help merge-tools`, Mercurial examines
2442 As described in :hg:`help merge-tools`, Mercurial examines
2443 configurations below in this order to decide which merge tool is
2443 configurations below in this order to decide which merge tool is
2444 chosen for specified file.
2444 chosen for specified file.
2445
2445
2446 1. ``--tool`` option
2446 1. ``--tool`` option
2447 2. ``HGMERGE`` environment variable
2447 2. ``HGMERGE`` environment variable
2448 3. configurations in ``merge-patterns`` section
2448 3. configurations in ``merge-patterns`` section
2449 4. configuration of ``ui.merge``
2449 4. configuration of ``ui.merge``
2450 5. configurations in ``merge-tools`` section
2450 5. configurations in ``merge-tools`` section
2451 6. ``hgmerge`` tool (for historical reason only)
2451 6. ``hgmerge`` tool (for historical reason only)
2452 7. default tool for fallback (``:merge`` or ``:prompt``)
2452 7. default tool for fallback (``:merge`` or ``:prompt``)
2453
2453
2454 This command writes out examination result in the style below::
2454 This command writes out examination result in the style below::
2455
2455
2456 FILE = MERGETOOL
2456 FILE = MERGETOOL
2457
2457
2458 By default, all files known in the first parent context of the
2458 By default, all files known in the first parent context of the
2459 working directory are examined. Use file patterns and/or -I/-X
2459 working directory are examined. Use file patterns and/or -I/-X
2460 options to limit target files. -r/--rev is also useful to examine
2460 options to limit target files. -r/--rev is also useful to examine
2461 files in another context without actual updating to it.
2461 files in another context without actual updating to it.
2462
2462
2463 With --debug, this command shows warning messages while matching
2463 With --debug, this command shows warning messages while matching
2464 against ``merge-patterns`` and so on, too. It is recommended to
2464 against ``merge-patterns`` and so on, too. It is recommended to
2465 use this option with explicit file patterns and/or -I/-X options,
2465 use this option with explicit file patterns and/or -I/-X options,
2466 because this option increases amount of output per file according
2466 because this option increases amount of output per file according
2467 to configurations in hgrc.
2467 to configurations in hgrc.
2468
2468
2469 With -v/--verbose, this command shows configurations below at
2469 With -v/--verbose, this command shows configurations below at
2470 first (only if specified).
2470 first (only if specified).
2471
2471
2472 - ``--tool`` option
2472 - ``--tool`` option
2473 - ``HGMERGE`` environment variable
2473 - ``HGMERGE`` environment variable
2474 - configuration of ``ui.merge``
2474 - configuration of ``ui.merge``
2475
2475
2476 If merge tool is chosen before matching against
2476 If merge tool is chosen before matching against
2477 ``merge-patterns``, this command can't show any helpful
2477 ``merge-patterns``, this command can't show any helpful
2478 information, even with --debug. In such case, information above is
2478 information, even with --debug. In such case, information above is
2479 useful to know why a merge tool is chosen.
2479 useful to know why a merge tool is chosen.
2480 """
2480 """
2481 opts = pycompat.byteskwargs(opts)
2481 opts = pycompat.byteskwargs(opts)
2482 overrides = {}
2482 overrides = {}
2483 if opts[b'tool']:
2483 if opts[b'tool']:
2484 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2484 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2485 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2485 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2486
2486
2487 with ui.configoverride(overrides, b'debugmergepatterns'):
2487 with ui.configoverride(overrides, b'debugmergepatterns'):
2488 hgmerge = encoding.environ.get(b"HGMERGE")
2488 hgmerge = encoding.environ.get(b"HGMERGE")
2489 if hgmerge is not None:
2489 if hgmerge is not None:
2490 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2490 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2491 uimerge = ui.config(b"ui", b"merge")
2491 uimerge = ui.config(b"ui", b"merge")
2492 if uimerge:
2492 if uimerge:
2493 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2493 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2494
2494
2495 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2495 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2496 m = scmutil.match(ctx, pats, opts)
2496 m = scmutil.match(ctx, pats, opts)
2497 changedelete = opts[b'changedelete']
2497 changedelete = opts[b'changedelete']
2498 for path in ctx.walk(m):
2498 for path in ctx.walk(m):
2499 fctx = ctx[path]
2499 fctx = ctx[path]
2500 try:
2500 try:
2501 if not ui.debugflag:
2501 if not ui.debugflag:
2502 ui.pushbuffer(error=True)
2502 ui.pushbuffer(error=True)
2503 tool, toolpath = filemerge._picktool(
2503 tool, toolpath = filemerge._picktool(
2504 repo,
2504 repo,
2505 ui,
2505 ui,
2506 path,
2506 path,
2507 fctx.isbinary(),
2507 fctx.isbinary(),
2508 b'l' in fctx.flags(),
2508 b'l' in fctx.flags(),
2509 changedelete,
2509 changedelete,
2510 )
2510 )
2511 finally:
2511 finally:
2512 if not ui.debugflag:
2512 if not ui.debugflag:
2513 ui.popbuffer()
2513 ui.popbuffer()
2514 ui.write(b'%s = %s\n' % (path, tool))
2514 ui.write(b'%s = %s\n' % (path, tool))
2515
2515
2516
2516
2517 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2517 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2518 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2518 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2519 '''access the pushkey key/value protocol
2519 '''access the pushkey key/value protocol
2520
2520
2521 With two args, list the keys in the given namespace.
2521 With two args, list the keys in the given namespace.
2522
2522
2523 With five args, set a key to new if it currently is set to old.
2523 With five args, set a key to new if it currently is set to old.
2524 Reports success or failure.
2524 Reports success or failure.
2525 '''
2525 '''
2526
2526
2527 target = hg.peer(ui, {}, repopath)
2527 target = hg.peer(ui, {}, repopath)
2528 if keyinfo:
2528 if keyinfo:
2529 key, old, new = keyinfo
2529 key, old, new = keyinfo
2530 with target.commandexecutor() as e:
2530 with target.commandexecutor() as e:
2531 r = e.callcommand(
2531 r = e.callcommand(
2532 b'pushkey',
2532 b'pushkey',
2533 {
2533 {
2534 b'namespace': namespace,
2534 b'namespace': namespace,
2535 b'key': key,
2535 b'key': key,
2536 b'old': old,
2536 b'old': old,
2537 b'new': new,
2537 b'new': new,
2538 },
2538 },
2539 ).result()
2539 ).result()
2540
2540
2541 ui.status(pycompat.bytestr(r) + b'\n')
2541 ui.status(pycompat.bytestr(r) + b'\n')
2542 return not r
2542 return not r
2543 else:
2543 else:
2544 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2544 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2545 ui.write(
2545 ui.write(
2546 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2546 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2547 )
2547 )
2548
2548
2549
2549
2550 @command(b'debugpvec', [], _(b'A B'))
2550 @command(b'debugpvec', [], _(b'A B'))
2551 def debugpvec(ui, repo, a, b=None):
2551 def debugpvec(ui, repo, a, b=None):
2552 ca = scmutil.revsingle(repo, a)
2552 ca = scmutil.revsingle(repo, a)
2553 cb = scmutil.revsingle(repo, b)
2553 cb = scmutil.revsingle(repo, b)
2554 pa = pvec.ctxpvec(ca)
2554 pa = pvec.ctxpvec(ca)
2555 pb = pvec.ctxpvec(cb)
2555 pb = pvec.ctxpvec(cb)
2556 if pa == pb:
2556 if pa == pb:
2557 rel = b"="
2557 rel = b"="
2558 elif pa > pb:
2558 elif pa > pb:
2559 rel = b">"
2559 rel = b">"
2560 elif pa < pb:
2560 elif pa < pb:
2561 rel = b"<"
2561 rel = b"<"
2562 elif pa | pb:
2562 elif pa | pb:
2563 rel = b"|"
2563 rel = b"|"
2564 ui.write(_(b"a: %s\n") % pa)
2564 ui.write(_(b"a: %s\n") % pa)
2565 ui.write(_(b"b: %s\n") % pb)
2565 ui.write(_(b"b: %s\n") % pb)
2566 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2566 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2567 ui.write(
2567 ui.write(
2568 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2568 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2569 % (
2569 % (
2570 abs(pa._depth - pb._depth),
2570 abs(pa._depth - pb._depth),
2571 pvec._hamming(pa._vec, pb._vec),
2571 pvec._hamming(pa._vec, pb._vec),
2572 pa.distance(pb),
2572 pa.distance(pb),
2573 rel,
2573 rel,
2574 )
2574 )
2575 )
2575 )
2576
2576
2577
2577
2578 @command(
2578 @command(
2579 b'debugrebuilddirstate|debugrebuildstate',
2579 b'debugrebuilddirstate|debugrebuildstate',
2580 [
2580 [
2581 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2581 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2582 (
2582 (
2583 b'',
2583 b'',
2584 b'minimal',
2584 b'minimal',
2585 None,
2585 None,
2586 _(
2586 _(
2587 b'only rebuild files that are inconsistent with '
2587 b'only rebuild files that are inconsistent with '
2588 b'the working copy parent'
2588 b'the working copy parent'
2589 ),
2589 ),
2590 ),
2590 ),
2591 ],
2591 ],
2592 _(b'[-r REV]'),
2592 _(b'[-r REV]'),
2593 )
2593 )
2594 def debugrebuilddirstate(ui, repo, rev, **opts):
2594 def debugrebuilddirstate(ui, repo, rev, **opts):
2595 """rebuild the dirstate as it would look like for the given revision
2595 """rebuild the dirstate as it would look like for the given revision
2596
2596
2597 If no revision is specified the first current parent will be used.
2597 If no revision is specified the first current parent will be used.
2598
2598
2599 The dirstate will be set to the files of the given revision.
2599 The dirstate will be set to the files of the given revision.
2600 The actual working directory content or existing dirstate
2600 The actual working directory content or existing dirstate
2601 information such as adds or removes is not considered.
2601 information such as adds or removes is not considered.
2602
2602
2603 ``minimal`` will only rebuild the dirstate status for files that claim to be
2603 ``minimal`` will only rebuild the dirstate status for files that claim to be
2604 tracked but are not in the parent manifest, or that exist in the parent
2604 tracked but are not in the parent manifest, or that exist in the parent
2605 manifest but are not in the dirstate. It will not change adds, removes, or
2605 manifest but are not in the dirstate. It will not change adds, removes, or
2606 modified files that are in the working copy parent.
2606 modified files that are in the working copy parent.
2607
2607
2608 One use of this command is to make the next :hg:`status` invocation
2608 One use of this command is to make the next :hg:`status` invocation
2609 check the actual file content.
2609 check the actual file content.
2610 """
2610 """
2611 ctx = scmutil.revsingle(repo, rev)
2611 ctx = scmutil.revsingle(repo, rev)
2612 with repo.wlock():
2612 with repo.wlock():
2613 dirstate = repo.dirstate
2613 dirstate = repo.dirstate
2614 changedfiles = None
2614 changedfiles = None
2615 # See command doc for what minimal does.
2615 # See command doc for what minimal does.
2616 if opts.get('minimal'):
2616 if opts.get('minimal'):
2617 manifestfiles = set(ctx.manifest().keys())
2617 manifestfiles = set(ctx.manifest().keys())
2618 dirstatefiles = set(dirstate)
2618 dirstatefiles = set(dirstate)
2619 manifestonly = manifestfiles - dirstatefiles
2619 manifestonly = manifestfiles - dirstatefiles
2620 dsonly = dirstatefiles - manifestfiles
2620 dsonly = dirstatefiles - manifestfiles
2621 dsnotadded = {f for f in dsonly if dirstate[f] != b'a'}
2621 dsnotadded = {f for f in dsonly if dirstate[f] != b'a'}
2622 changedfiles = manifestonly | dsnotadded
2622 changedfiles = manifestonly | dsnotadded
2623
2623
2624 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2624 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2625
2625
2626
2626
2627 @command(b'debugrebuildfncache', [], b'')
2627 @command(b'debugrebuildfncache', [], b'')
2628 def debugrebuildfncache(ui, repo):
2628 def debugrebuildfncache(ui, repo):
2629 """rebuild the fncache file"""
2629 """rebuild the fncache file"""
2630 repair.rebuildfncache(ui, repo)
2630 repair.rebuildfncache(ui, repo)
2631
2631
2632
2632
2633 @command(
2633 @command(
2634 b'debugrename',
2634 b'debugrename',
2635 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2635 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2636 _(b'[-r REV] [FILE]...'),
2636 _(b'[-r REV] [FILE]...'),
2637 )
2637 )
2638 def debugrename(ui, repo, *pats, **opts):
2638 def debugrename(ui, repo, *pats, **opts):
2639 """dump rename information"""
2639 """dump rename information"""
2640
2640
2641 opts = pycompat.byteskwargs(opts)
2641 opts = pycompat.byteskwargs(opts)
2642 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2642 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2643 m = scmutil.match(ctx, pats, opts)
2643 m = scmutil.match(ctx, pats, opts)
2644 for abs in ctx.walk(m):
2644 for abs in ctx.walk(m):
2645 fctx = ctx[abs]
2645 fctx = ctx[abs]
2646 o = fctx.filelog().renamed(fctx.filenode())
2646 o = fctx.filelog().renamed(fctx.filenode())
2647 rel = repo.pathto(abs)
2647 rel = repo.pathto(abs)
2648 if o:
2648 if o:
2649 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2649 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2650 else:
2650 else:
2651 ui.write(_(b"%s not renamed\n") % rel)
2651 ui.write(_(b"%s not renamed\n") % rel)
2652
2652
2653
2653
2654 @command(b'debugrequires|debugrequirements', [], b'')
2655 def debugrequirements(ui, repo):
2656 """ print the current repo requirements """
2657 for r in sorted(repo.requirements):
2658 ui.write(b"%s\n" % r)
2659
2660
2654 @command(
2661 @command(
2655 b'debugrevlog',
2662 b'debugrevlog',
2656 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2663 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2657 _(b'-c|-m|FILE'),
2664 _(b'-c|-m|FILE'),
2658 optionalrepo=True,
2665 optionalrepo=True,
2659 )
2666 )
2660 def debugrevlog(ui, repo, file_=None, **opts):
2667 def debugrevlog(ui, repo, file_=None, **opts):
2661 """show data and statistics about a revlog"""
2668 """show data and statistics about a revlog"""
2662 opts = pycompat.byteskwargs(opts)
2669 opts = pycompat.byteskwargs(opts)
2663 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2670 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2664
2671
2665 if opts.get(b"dump"):
2672 if opts.get(b"dump"):
2666 numrevs = len(r)
2673 numrevs = len(r)
2667 ui.write(
2674 ui.write(
2668 (
2675 (
2669 b"# rev p1rev p2rev start end deltastart base p1 p2"
2676 b"# rev p1rev p2rev start end deltastart base p1 p2"
2670 b" rawsize totalsize compression heads chainlen\n"
2677 b" rawsize totalsize compression heads chainlen\n"
2671 )
2678 )
2672 )
2679 )
2673 ts = 0
2680 ts = 0
2674 heads = set()
2681 heads = set()
2675
2682
2676 for rev in pycompat.xrange(numrevs):
2683 for rev in pycompat.xrange(numrevs):
2677 dbase = r.deltaparent(rev)
2684 dbase = r.deltaparent(rev)
2678 if dbase == -1:
2685 if dbase == -1:
2679 dbase = rev
2686 dbase = rev
2680 cbase = r.chainbase(rev)
2687 cbase = r.chainbase(rev)
2681 clen = r.chainlen(rev)
2688 clen = r.chainlen(rev)
2682 p1, p2 = r.parentrevs(rev)
2689 p1, p2 = r.parentrevs(rev)
2683 rs = r.rawsize(rev)
2690 rs = r.rawsize(rev)
2684 ts = ts + rs
2691 ts = ts + rs
2685 heads -= set(r.parentrevs(rev))
2692 heads -= set(r.parentrevs(rev))
2686 heads.add(rev)
2693 heads.add(rev)
2687 try:
2694 try:
2688 compression = ts / r.end(rev)
2695 compression = ts / r.end(rev)
2689 except ZeroDivisionError:
2696 except ZeroDivisionError:
2690 compression = 0
2697 compression = 0
2691 ui.write(
2698 ui.write(
2692 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2699 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2693 b"%11d %5d %8d\n"
2700 b"%11d %5d %8d\n"
2694 % (
2701 % (
2695 rev,
2702 rev,
2696 p1,
2703 p1,
2697 p2,
2704 p2,
2698 r.start(rev),
2705 r.start(rev),
2699 r.end(rev),
2706 r.end(rev),
2700 r.start(dbase),
2707 r.start(dbase),
2701 r.start(cbase),
2708 r.start(cbase),
2702 r.start(p1),
2709 r.start(p1),
2703 r.start(p2),
2710 r.start(p2),
2704 rs,
2711 rs,
2705 ts,
2712 ts,
2706 compression,
2713 compression,
2707 len(heads),
2714 len(heads),
2708 clen,
2715 clen,
2709 )
2716 )
2710 )
2717 )
2711 return 0
2718 return 0
2712
2719
2713 v = r.version
2720 v = r.version
2714 format = v & 0xFFFF
2721 format = v & 0xFFFF
2715 flags = []
2722 flags = []
2716 gdelta = False
2723 gdelta = False
2717 if v & revlog.FLAG_INLINE_DATA:
2724 if v & revlog.FLAG_INLINE_DATA:
2718 flags.append(b'inline')
2725 flags.append(b'inline')
2719 if v & revlog.FLAG_GENERALDELTA:
2726 if v & revlog.FLAG_GENERALDELTA:
2720 gdelta = True
2727 gdelta = True
2721 flags.append(b'generaldelta')
2728 flags.append(b'generaldelta')
2722 if not flags:
2729 if not flags:
2723 flags = [b'(none)']
2730 flags = [b'(none)']
2724
2731
2725 ### tracks merge vs single parent
2732 ### tracks merge vs single parent
2726 nummerges = 0
2733 nummerges = 0
2727
2734
2728 ### tracks ways the "delta" are build
2735 ### tracks ways the "delta" are build
2729 # nodelta
2736 # nodelta
2730 numempty = 0
2737 numempty = 0
2731 numemptytext = 0
2738 numemptytext = 0
2732 numemptydelta = 0
2739 numemptydelta = 0
2733 # full file content
2740 # full file content
2734 numfull = 0
2741 numfull = 0
2735 # intermediate snapshot against a prior snapshot
2742 # intermediate snapshot against a prior snapshot
2736 numsemi = 0
2743 numsemi = 0
2737 # snapshot count per depth
2744 # snapshot count per depth
2738 numsnapdepth = collections.defaultdict(lambda: 0)
2745 numsnapdepth = collections.defaultdict(lambda: 0)
2739 # delta against previous revision
2746 # delta against previous revision
2740 numprev = 0
2747 numprev = 0
2741 # delta against first or second parent (not prev)
2748 # delta against first or second parent (not prev)
2742 nump1 = 0
2749 nump1 = 0
2743 nump2 = 0
2750 nump2 = 0
2744 # delta against neither prev nor parents
2751 # delta against neither prev nor parents
2745 numother = 0
2752 numother = 0
2746 # delta against prev that are also first or second parent
2753 # delta against prev that are also first or second parent
2747 # (details of `numprev`)
2754 # (details of `numprev`)
2748 nump1prev = 0
2755 nump1prev = 0
2749 nump2prev = 0
2756 nump2prev = 0
2750
2757
2751 # data about delta chain of each revs
2758 # data about delta chain of each revs
2752 chainlengths = []
2759 chainlengths = []
2753 chainbases = []
2760 chainbases = []
2754 chainspans = []
2761 chainspans = []
2755
2762
2756 # data about each revision
2763 # data about each revision
2757 datasize = [None, 0, 0]
2764 datasize = [None, 0, 0]
2758 fullsize = [None, 0, 0]
2765 fullsize = [None, 0, 0]
2759 semisize = [None, 0, 0]
2766 semisize = [None, 0, 0]
2760 # snapshot count per depth
2767 # snapshot count per depth
2761 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2768 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2762 deltasize = [None, 0, 0]
2769 deltasize = [None, 0, 0]
2763 chunktypecounts = {}
2770 chunktypecounts = {}
2764 chunktypesizes = {}
2771 chunktypesizes = {}
2765
2772
2766 def addsize(size, l):
2773 def addsize(size, l):
2767 if l[0] is None or size < l[0]:
2774 if l[0] is None or size < l[0]:
2768 l[0] = size
2775 l[0] = size
2769 if size > l[1]:
2776 if size > l[1]:
2770 l[1] = size
2777 l[1] = size
2771 l[2] += size
2778 l[2] += size
2772
2779
2773 numrevs = len(r)
2780 numrevs = len(r)
2774 for rev in pycompat.xrange(numrevs):
2781 for rev in pycompat.xrange(numrevs):
2775 p1, p2 = r.parentrevs(rev)
2782 p1, p2 = r.parentrevs(rev)
2776 delta = r.deltaparent(rev)
2783 delta = r.deltaparent(rev)
2777 if format > 0:
2784 if format > 0:
2778 addsize(r.rawsize(rev), datasize)
2785 addsize(r.rawsize(rev), datasize)
2779 if p2 != nullrev:
2786 if p2 != nullrev:
2780 nummerges += 1
2787 nummerges += 1
2781 size = r.length(rev)
2788 size = r.length(rev)
2782 if delta == nullrev:
2789 if delta == nullrev:
2783 chainlengths.append(0)
2790 chainlengths.append(0)
2784 chainbases.append(r.start(rev))
2791 chainbases.append(r.start(rev))
2785 chainspans.append(size)
2792 chainspans.append(size)
2786 if size == 0:
2793 if size == 0:
2787 numempty += 1
2794 numempty += 1
2788 numemptytext += 1
2795 numemptytext += 1
2789 else:
2796 else:
2790 numfull += 1
2797 numfull += 1
2791 numsnapdepth[0] += 1
2798 numsnapdepth[0] += 1
2792 addsize(size, fullsize)
2799 addsize(size, fullsize)
2793 addsize(size, snapsizedepth[0])
2800 addsize(size, snapsizedepth[0])
2794 else:
2801 else:
2795 chainlengths.append(chainlengths[delta] + 1)
2802 chainlengths.append(chainlengths[delta] + 1)
2796 baseaddr = chainbases[delta]
2803 baseaddr = chainbases[delta]
2797 revaddr = r.start(rev)
2804 revaddr = r.start(rev)
2798 chainbases.append(baseaddr)
2805 chainbases.append(baseaddr)
2799 chainspans.append((revaddr - baseaddr) + size)
2806 chainspans.append((revaddr - baseaddr) + size)
2800 if size == 0:
2807 if size == 0:
2801 numempty += 1
2808 numempty += 1
2802 numemptydelta += 1
2809 numemptydelta += 1
2803 elif r.issnapshot(rev):
2810 elif r.issnapshot(rev):
2804 addsize(size, semisize)
2811 addsize(size, semisize)
2805 numsemi += 1
2812 numsemi += 1
2806 depth = r.snapshotdepth(rev)
2813 depth = r.snapshotdepth(rev)
2807 numsnapdepth[depth] += 1
2814 numsnapdepth[depth] += 1
2808 addsize(size, snapsizedepth[depth])
2815 addsize(size, snapsizedepth[depth])
2809 else:
2816 else:
2810 addsize(size, deltasize)
2817 addsize(size, deltasize)
2811 if delta == rev - 1:
2818 if delta == rev - 1:
2812 numprev += 1
2819 numprev += 1
2813 if delta == p1:
2820 if delta == p1:
2814 nump1prev += 1
2821 nump1prev += 1
2815 elif delta == p2:
2822 elif delta == p2:
2816 nump2prev += 1
2823 nump2prev += 1
2817 elif delta == p1:
2824 elif delta == p1:
2818 nump1 += 1
2825 nump1 += 1
2819 elif delta == p2:
2826 elif delta == p2:
2820 nump2 += 1
2827 nump2 += 1
2821 elif delta != nullrev:
2828 elif delta != nullrev:
2822 numother += 1
2829 numother += 1
2823
2830
2824 # Obtain data on the raw chunks in the revlog.
2831 # Obtain data on the raw chunks in the revlog.
2825 if util.safehasattr(r, b'_getsegmentforrevs'):
2832 if util.safehasattr(r, b'_getsegmentforrevs'):
2826 segment = r._getsegmentforrevs(rev, rev)[1]
2833 segment = r._getsegmentforrevs(rev, rev)[1]
2827 else:
2834 else:
2828 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2835 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2829 if segment:
2836 if segment:
2830 chunktype = bytes(segment[0:1])
2837 chunktype = bytes(segment[0:1])
2831 else:
2838 else:
2832 chunktype = b'empty'
2839 chunktype = b'empty'
2833
2840
2834 if chunktype not in chunktypecounts:
2841 if chunktype not in chunktypecounts:
2835 chunktypecounts[chunktype] = 0
2842 chunktypecounts[chunktype] = 0
2836 chunktypesizes[chunktype] = 0
2843 chunktypesizes[chunktype] = 0
2837
2844
2838 chunktypecounts[chunktype] += 1
2845 chunktypecounts[chunktype] += 1
2839 chunktypesizes[chunktype] += size
2846 chunktypesizes[chunktype] += size
2840
2847
2841 # Adjust size min value for empty cases
2848 # Adjust size min value for empty cases
2842 for size in (datasize, fullsize, semisize, deltasize):
2849 for size in (datasize, fullsize, semisize, deltasize):
2843 if size[0] is None:
2850 if size[0] is None:
2844 size[0] = 0
2851 size[0] = 0
2845
2852
2846 numdeltas = numrevs - numfull - numempty - numsemi
2853 numdeltas = numrevs - numfull - numempty - numsemi
2847 numoprev = numprev - nump1prev - nump2prev
2854 numoprev = numprev - nump1prev - nump2prev
2848 totalrawsize = datasize[2]
2855 totalrawsize = datasize[2]
2849 datasize[2] /= numrevs
2856 datasize[2] /= numrevs
2850 fulltotal = fullsize[2]
2857 fulltotal = fullsize[2]
2851 if numfull == 0:
2858 if numfull == 0:
2852 fullsize[2] = 0
2859 fullsize[2] = 0
2853 else:
2860 else:
2854 fullsize[2] /= numfull
2861 fullsize[2] /= numfull
2855 semitotal = semisize[2]
2862 semitotal = semisize[2]
2856 snaptotal = {}
2863 snaptotal = {}
2857 if numsemi > 0:
2864 if numsemi > 0:
2858 semisize[2] /= numsemi
2865 semisize[2] /= numsemi
2859 for depth in snapsizedepth:
2866 for depth in snapsizedepth:
2860 snaptotal[depth] = snapsizedepth[depth][2]
2867 snaptotal[depth] = snapsizedepth[depth][2]
2861 snapsizedepth[depth][2] /= numsnapdepth[depth]
2868 snapsizedepth[depth][2] /= numsnapdepth[depth]
2862
2869
2863 deltatotal = deltasize[2]
2870 deltatotal = deltasize[2]
2864 if numdeltas > 0:
2871 if numdeltas > 0:
2865 deltasize[2] /= numdeltas
2872 deltasize[2] /= numdeltas
2866 totalsize = fulltotal + semitotal + deltatotal
2873 totalsize = fulltotal + semitotal + deltatotal
2867 avgchainlen = sum(chainlengths) / numrevs
2874 avgchainlen = sum(chainlengths) / numrevs
2868 maxchainlen = max(chainlengths)
2875 maxchainlen = max(chainlengths)
2869 maxchainspan = max(chainspans)
2876 maxchainspan = max(chainspans)
2870 compratio = 1
2877 compratio = 1
2871 if totalsize:
2878 if totalsize:
2872 compratio = totalrawsize / totalsize
2879 compratio = totalrawsize / totalsize
2873
2880
2874 basedfmtstr = b'%%%dd\n'
2881 basedfmtstr = b'%%%dd\n'
2875 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2882 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2876
2883
2877 def dfmtstr(max):
2884 def dfmtstr(max):
2878 return basedfmtstr % len(str(max))
2885 return basedfmtstr % len(str(max))
2879
2886
2880 def pcfmtstr(max, padding=0):
2887 def pcfmtstr(max, padding=0):
2881 return basepcfmtstr % (len(str(max)), b' ' * padding)
2888 return basepcfmtstr % (len(str(max)), b' ' * padding)
2882
2889
2883 def pcfmt(value, total):
2890 def pcfmt(value, total):
2884 if total:
2891 if total:
2885 return (value, 100 * float(value) / total)
2892 return (value, 100 * float(value) / total)
2886 else:
2893 else:
2887 return value, 100.0
2894 return value, 100.0
2888
2895
2889 ui.writenoi18n(b'format : %d\n' % format)
2896 ui.writenoi18n(b'format : %d\n' % format)
2890 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2897 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2891
2898
2892 ui.write(b'\n')
2899 ui.write(b'\n')
2893 fmt = pcfmtstr(totalsize)
2900 fmt = pcfmtstr(totalsize)
2894 fmt2 = dfmtstr(totalsize)
2901 fmt2 = dfmtstr(totalsize)
2895 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2902 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2896 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2903 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2897 ui.writenoi18n(
2904 ui.writenoi18n(
2898 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2905 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2899 )
2906 )
2900 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2907 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2901 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2908 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2902 ui.writenoi18n(
2909 ui.writenoi18n(
2903 b' text : '
2910 b' text : '
2904 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2911 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2905 )
2912 )
2906 ui.writenoi18n(
2913 ui.writenoi18n(
2907 b' delta : '
2914 b' delta : '
2908 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2915 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2909 )
2916 )
2910 ui.writenoi18n(
2917 ui.writenoi18n(
2911 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2918 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2912 )
2919 )
2913 for depth in sorted(numsnapdepth):
2920 for depth in sorted(numsnapdepth):
2914 ui.write(
2921 ui.write(
2915 (b' lvl-%-3d : ' % depth)
2922 (b' lvl-%-3d : ' % depth)
2916 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2923 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2917 )
2924 )
2918 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2925 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2919 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2926 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2920 ui.writenoi18n(
2927 ui.writenoi18n(
2921 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2928 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2922 )
2929 )
2923 for depth in sorted(numsnapdepth):
2930 for depth in sorted(numsnapdepth):
2924 ui.write(
2931 ui.write(
2925 (b' lvl-%-3d : ' % depth)
2932 (b' lvl-%-3d : ' % depth)
2926 + fmt % pcfmt(snaptotal[depth], totalsize)
2933 + fmt % pcfmt(snaptotal[depth], totalsize)
2927 )
2934 )
2928 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2935 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2929
2936
2930 def fmtchunktype(chunktype):
2937 def fmtchunktype(chunktype):
2931 if chunktype == b'empty':
2938 if chunktype == b'empty':
2932 return b' %s : ' % chunktype
2939 return b' %s : ' % chunktype
2933 elif chunktype in pycompat.bytestr(string.ascii_letters):
2940 elif chunktype in pycompat.bytestr(string.ascii_letters):
2934 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2941 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2935 else:
2942 else:
2936 return b' 0x%s : ' % hex(chunktype)
2943 return b' 0x%s : ' % hex(chunktype)
2937
2944
2938 ui.write(b'\n')
2945 ui.write(b'\n')
2939 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2946 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2940 for chunktype in sorted(chunktypecounts):
2947 for chunktype in sorted(chunktypecounts):
2941 ui.write(fmtchunktype(chunktype))
2948 ui.write(fmtchunktype(chunktype))
2942 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2949 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2943 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2950 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2944 for chunktype in sorted(chunktypecounts):
2951 for chunktype in sorted(chunktypecounts):
2945 ui.write(fmtchunktype(chunktype))
2952 ui.write(fmtchunktype(chunktype))
2946 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2953 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2947
2954
2948 ui.write(b'\n')
2955 ui.write(b'\n')
2949 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2956 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2950 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2957 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2951 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2958 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2952 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2959 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2953 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2960 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2954
2961
2955 if format > 0:
2962 if format > 0:
2956 ui.write(b'\n')
2963 ui.write(b'\n')
2957 ui.writenoi18n(
2964 ui.writenoi18n(
2958 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2965 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2959 % tuple(datasize)
2966 % tuple(datasize)
2960 )
2967 )
2961 ui.writenoi18n(
2968 ui.writenoi18n(
2962 b'full revision size (min/max/avg) : %d / %d / %d\n'
2969 b'full revision size (min/max/avg) : %d / %d / %d\n'
2963 % tuple(fullsize)
2970 % tuple(fullsize)
2964 )
2971 )
2965 ui.writenoi18n(
2972 ui.writenoi18n(
2966 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2973 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2967 % tuple(semisize)
2974 % tuple(semisize)
2968 )
2975 )
2969 for depth in sorted(snapsizedepth):
2976 for depth in sorted(snapsizedepth):
2970 if depth == 0:
2977 if depth == 0:
2971 continue
2978 continue
2972 ui.writenoi18n(
2979 ui.writenoi18n(
2973 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2980 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2974 % ((depth,) + tuple(snapsizedepth[depth]))
2981 % ((depth,) + tuple(snapsizedepth[depth]))
2975 )
2982 )
2976 ui.writenoi18n(
2983 ui.writenoi18n(
2977 b'delta size (min/max/avg) : %d / %d / %d\n'
2984 b'delta size (min/max/avg) : %d / %d / %d\n'
2978 % tuple(deltasize)
2985 % tuple(deltasize)
2979 )
2986 )
2980
2987
2981 if numdeltas > 0:
2988 if numdeltas > 0:
2982 ui.write(b'\n')
2989 ui.write(b'\n')
2983 fmt = pcfmtstr(numdeltas)
2990 fmt = pcfmtstr(numdeltas)
2984 fmt2 = pcfmtstr(numdeltas, 4)
2991 fmt2 = pcfmtstr(numdeltas, 4)
2985 ui.writenoi18n(
2992 ui.writenoi18n(
2986 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2993 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2987 )
2994 )
2988 if numprev > 0:
2995 if numprev > 0:
2989 ui.writenoi18n(
2996 ui.writenoi18n(
2990 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2997 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2991 )
2998 )
2992 ui.writenoi18n(
2999 ui.writenoi18n(
2993 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
3000 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2994 )
3001 )
2995 ui.writenoi18n(
3002 ui.writenoi18n(
2996 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
3003 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2997 )
3004 )
2998 if gdelta:
3005 if gdelta:
2999 ui.writenoi18n(
3006 ui.writenoi18n(
3000 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
3007 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
3001 )
3008 )
3002 ui.writenoi18n(
3009 ui.writenoi18n(
3003 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
3010 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
3004 )
3011 )
3005 ui.writenoi18n(
3012 ui.writenoi18n(
3006 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
3013 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
3007 )
3014 )
3008
3015
3009
3016
3010 @command(
3017 @command(
3011 b'debugrevlogindex',
3018 b'debugrevlogindex',
3012 cmdutil.debugrevlogopts
3019 cmdutil.debugrevlogopts
3013 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
3020 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
3014 _(b'[-f FORMAT] -c|-m|FILE'),
3021 _(b'[-f FORMAT] -c|-m|FILE'),
3015 optionalrepo=True,
3022 optionalrepo=True,
3016 )
3023 )
3017 def debugrevlogindex(ui, repo, file_=None, **opts):
3024 def debugrevlogindex(ui, repo, file_=None, **opts):
3018 """dump the contents of a revlog index"""
3025 """dump the contents of a revlog index"""
3019 opts = pycompat.byteskwargs(opts)
3026 opts = pycompat.byteskwargs(opts)
3020 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
3027 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
3021 format = opts.get(b'format', 0)
3028 format = opts.get(b'format', 0)
3022 if format not in (0, 1):
3029 if format not in (0, 1):
3023 raise error.Abort(_(b"unknown format %d") % format)
3030 raise error.Abort(_(b"unknown format %d") % format)
3024
3031
3025 if ui.debugflag:
3032 if ui.debugflag:
3026 shortfn = hex
3033 shortfn = hex
3027 else:
3034 else:
3028 shortfn = short
3035 shortfn = short
3029
3036
3030 # There might not be anything in r, so have a sane default
3037 # There might not be anything in r, so have a sane default
3031 idlen = 12
3038 idlen = 12
3032 for i in r:
3039 for i in r:
3033 idlen = len(shortfn(r.node(i)))
3040 idlen = len(shortfn(r.node(i)))
3034 break
3041 break
3035
3042
3036 if format == 0:
3043 if format == 0:
3037 if ui.verbose:
3044 if ui.verbose:
3038 ui.writenoi18n(
3045 ui.writenoi18n(
3039 b" rev offset length linkrev %s %s p2\n"
3046 b" rev offset length linkrev %s %s p2\n"
3040 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3047 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3041 )
3048 )
3042 else:
3049 else:
3043 ui.writenoi18n(
3050 ui.writenoi18n(
3044 b" rev linkrev %s %s p2\n"
3051 b" rev linkrev %s %s p2\n"
3045 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3052 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3046 )
3053 )
3047 elif format == 1:
3054 elif format == 1:
3048 if ui.verbose:
3055 if ui.verbose:
3049 ui.writenoi18n(
3056 ui.writenoi18n(
3050 (
3057 (
3051 b" rev flag offset length size link p1"
3058 b" rev flag offset length size link p1"
3052 b" p2 %s\n"
3059 b" p2 %s\n"
3053 )
3060 )
3054 % b"nodeid".rjust(idlen)
3061 % b"nodeid".rjust(idlen)
3055 )
3062 )
3056 else:
3063 else:
3057 ui.writenoi18n(
3064 ui.writenoi18n(
3058 b" rev flag size link p1 p2 %s\n"
3065 b" rev flag size link p1 p2 %s\n"
3059 % b"nodeid".rjust(idlen)
3066 % b"nodeid".rjust(idlen)
3060 )
3067 )
3061
3068
3062 for i in r:
3069 for i in r:
3063 node = r.node(i)
3070 node = r.node(i)
3064 if format == 0:
3071 if format == 0:
3065 try:
3072 try:
3066 pp = r.parents(node)
3073 pp = r.parents(node)
3067 except Exception:
3074 except Exception:
3068 pp = [nullid, nullid]
3075 pp = [nullid, nullid]
3069 if ui.verbose:
3076 if ui.verbose:
3070 ui.write(
3077 ui.write(
3071 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3078 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3072 % (
3079 % (
3073 i,
3080 i,
3074 r.start(i),
3081 r.start(i),
3075 r.length(i),
3082 r.length(i),
3076 r.linkrev(i),
3083 r.linkrev(i),
3077 shortfn(node),
3084 shortfn(node),
3078 shortfn(pp[0]),
3085 shortfn(pp[0]),
3079 shortfn(pp[1]),
3086 shortfn(pp[1]),
3080 )
3087 )
3081 )
3088 )
3082 else:
3089 else:
3083 ui.write(
3090 ui.write(
3084 b"% 6d % 7d %s %s %s\n"
3091 b"% 6d % 7d %s %s %s\n"
3085 % (
3092 % (
3086 i,
3093 i,
3087 r.linkrev(i),
3094 r.linkrev(i),
3088 shortfn(node),
3095 shortfn(node),
3089 shortfn(pp[0]),
3096 shortfn(pp[0]),
3090 shortfn(pp[1]),
3097 shortfn(pp[1]),
3091 )
3098 )
3092 )
3099 )
3093 elif format == 1:
3100 elif format == 1:
3094 pr = r.parentrevs(i)
3101 pr = r.parentrevs(i)
3095 if ui.verbose:
3102 if ui.verbose:
3096 ui.write(
3103 ui.write(
3097 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3104 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3098 % (
3105 % (
3099 i,
3106 i,
3100 r.flags(i),
3107 r.flags(i),
3101 r.start(i),
3108 r.start(i),
3102 r.length(i),
3109 r.length(i),
3103 r.rawsize(i),
3110 r.rawsize(i),
3104 r.linkrev(i),
3111 r.linkrev(i),
3105 pr[0],
3112 pr[0],
3106 pr[1],
3113 pr[1],
3107 shortfn(node),
3114 shortfn(node),
3108 )
3115 )
3109 )
3116 )
3110 else:
3117 else:
3111 ui.write(
3118 ui.write(
3112 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3119 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3113 % (
3120 % (
3114 i,
3121 i,
3115 r.flags(i),
3122 r.flags(i),
3116 r.rawsize(i),
3123 r.rawsize(i),
3117 r.linkrev(i),
3124 r.linkrev(i),
3118 pr[0],
3125 pr[0],
3119 pr[1],
3126 pr[1],
3120 shortfn(node),
3127 shortfn(node),
3121 )
3128 )
3122 )
3129 )
3123
3130
3124
3131
3125 @command(
3132 @command(
3126 b'debugrevspec',
3133 b'debugrevspec',
3127 [
3134 [
3128 (
3135 (
3129 b'',
3136 b'',
3130 b'optimize',
3137 b'optimize',
3131 None,
3138 None,
3132 _(b'print parsed tree after optimizing (DEPRECATED)'),
3139 _(b'print parsed tree after optimizing (DEPRECATED)'),
3133 ),
3140 ),
3134 (
3141 (
3135 b'',
3142 b'',
3136 b'show-revs',
3143 b'show-revs',
3137 True,
3144 True,
3138 _(b'print list of result revisions (default)'),
3145 _(b'print list of result revisions (default)'),
3139 ),
3146 ),
3140 (
3147 (
3141 b's',
3148 b's',
3142 b'show-set',
3149 b'show-set',
3143 None,
3150 None,
3144 _(b'print internal representation of result set'),
3151 _(b'print internal representation of result set'),
3145 ),
3152 ),
3146 (
3153 (
3147 b'p',
3154 b'p',
3148 b'show-stage',
3155 b'show-stage',
3149 [],
3156 [],
3150 _(b'print parsed tree at the given stage'),
3157 _(b'print parsed tree at the given stage'),
3151 _(b'NAME'),
3158 _(b'NAME'),
3152 ),
3159 ),
3153 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3160 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3154 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3161 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3155 ],
3162 ],
3156 b'REVSPEC',
3163 b'REVSPEC',
3157 )
3164 )
3158 def debugrevspec(ui, repo, expr, **opts):
3165 def debugrevspec(ui, repo, expr, **opts):
3159 """parse and apply a revision specification
3166 """parse and apply a revision specification
3160
3167
3161 Use -p/--show-stage option to print the parsed tree at the given stages.
3168 Use -p/--show-stage option to print the parsed tree at the given stages.
3162 Use -p all to print tree at every stage.
3169 Use -p all to print tree at every stage.
3163
3170
3164 Use --no-show-revs option with -s or -p to print only the set
3171 Use --no-show-revs option with -s or -p to print only the set
3165 representation or the parsed tree respectively.
3172 representation or the parsed tree respectively.
3166
3173
3167 Use --verify-optimized to compare the optimized result with the unoptimized
3174 Use --verify-optimized to compare the optimized result with the unoptimized
3168 one. Returns 1 if the optimized result differs.
3175 one. Returns 1 if the optimized result differs.
3169 """
3176 """
3170 opts = pycompat.byteskwargs(opts)
3177 opts = pycompat.byteskwargs(opts)
3171 aliases = ui.configitems(b'revsetalias')
3178 aliases = ui.configitems(b'revsetalias')
3172 stages = [
3179 stages = [
3173 (b'parsed', lambda tree: tree),
3180 (b'parsed', lambda tree: tree),
3174 (
3181 (
3175 b'expanded',
3182 b'expanded',
3176 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3183 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3177 ),
3184 ),
3178 (b'concatenated', revsetlang.foldconcat),
3185 (b'concatenated', revsetlang.foldconcat),
3179 (b'analyzed', revsetlang.analyze),
3186 (b'analyzed', revsetlang.analyze),
3180 (b'optimized', revsetlang.optimize),
3187 (b'optimized', revsetlang.optimize),
3181 ]
3188 ]
3182 if opts[b'no_optimized']:
3189 if opts[b'no_optimized']:
3183 stages = stages[:-1]
3190 stages = stages[:-1]
3184 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3191 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3185 raise error.Abort(
3192 raise error.Abort(
3186 _(b'cannot use --verify-optimized with --no-optimized')
3193 _(b'cannot use --verify-optimized with --no-optimized')
3187 )
3194 )
3188 stagenames = {n for n, f in stages}
3195 stagenames = {n for n, f in stages}
3189
3196
3190 showalways = set()
3197 showalways = set()
3191 showchanged = set()
3198 showchanged = set()
3192 if ui.verbose and not opts[b'show_stage']:
3199 if ui.verbose and not opts[b'show_stage']:
3193 # show parsed tree by --verbose (deprecated)
3200 # show parsed tree by --verbose (deprecated)
3194 showalways.add(b'parsed')
3201 showalways.add(b'parsed')
3195 showchanged.update([b'expanded', b'concatenated'])
3202 showchanged.update([b'expanded', b'concatenated'])
3196 if opts[b'optimize']:
3203 if opts[b'optimize']:
3197 showalways.add(b'optimized')
3204 showalways.add(b'optimized')
3198 if opts[b'show_stage'] and opts[b'optimize']:
3205 if opts[b'show_stage'] and opts[b'optimize']:
3199 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3206 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3200 if opts[b'show_stage'] == [b'all']:
3207 if opts[b'show_stage'] == [b'all']:
3201 showalways.update(stagenames)
3208 showalways.update(stagenames)
3202 else:
3209 else:
3203 for n in opts[b'show_stage']:
3210 for n in opts[b'show_stage']:
3204 if n not in stagenames:
3211 if n not in stagenames:
3205 raise error.Abort(_(b'invalid stage name: %s') % n)
3212 raise error.Abort(_(b'invalid stage name: %s') % n)
3206 showalways.update(opts[b'show_stage'])
3213 showalways.update(opts[b'show_stage'])
3207
3214
3208 treebystage = {}
3215 treebystage = {}
3209 printedtree = None
3216 printedtree = None
3210 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3217 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3211 for n, f in stages:
3218 for n, f in stages:
3212 treebystage[n] = tree = f(tree)
3219 treebystage[n] = tree = f(tree)
3213 if n in showalways or (n in showchanged and tree != printedtree):
3220 if n in showalways or (n in showchanged and tree != printedtree):
3214 if opts[b'show_stage'] or n != b'parsed':
3221 if opts[b'show_stage'] or n != b'parsed':
3215 ui.write(b"* %s:\n" % n)
3222 ui.write(b"* %s:\n" % n)
3216 ui.write(revsetlang.prettyformat(tree), b"\n")
3223 ui.write(revsetlang.prettyformat(tree), b"\n")
3217 printedtree = tree
3224 printedtree = tree
3218
3225
3219 if opts[b'verify_optimized']:
3226 if opts[b'verify_optimized']:
3220 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3227 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3221 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3228 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3222 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3229 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3223 ui.writenoi18n(
3230 ui.writenoi18n(
3224 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3231 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3225 )
3232 )
3226 ui.writenoi18n(
3233 ui.writenoi18n(
3227 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3234 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3228 )
3235 )
3229 arevs = list(arevs)
3236 arevs = list(arevs)
3230 brevs = list(brevs)
3237 brevs = list(brevs)
3231 if arevs == brevs:
3238 if arevs == brevs:
3232 return 0
3239 return 0
3233 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3240 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3234 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3241 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3235 sm = difflib.SequenceMatcher(None, arevs, brevs)
3242 sm = difflib.SequenceMatcher(None, arevs, brevs)
3236 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3243 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3237 if tag in ('delete', 'replace'):
3244 if tag in ('delete', 'replace'):
3238 for c in arevs[alo:ahi]:
3245 for c in arevs[alo:ahi]:
3239 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3246 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3240 if tag in ('insert', 'replace'):
3247 if tag in ('insert', 'replace'):
3241 for c in brevs[blo:bhi]:
3248 for c in brevs[blo:bhi]:
3242 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3249 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3243 if tag == 'equal':
3250 if tag == 'equal':
3244 for c in arevs[alo:ahi]:
3251 for c in arevs[alo:ahi]:
3245 ui.write(b' %d\n' % c)
3252 ui.write(b' %d\n' % c)
3246 return 1
3253 return 1
3247
3254
3248 func = revset.makematcher(tree)
3255 func = revset.makematcher(tree)
3249 revs = func(repo)
3256 revs = func(repo)
3250 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3257 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3251 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3258 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3252 if not opts[b'show_revs']:
3259 if not opts[b'show_revs']:
3253 return
3260 return
3254 for c in revs:
3261 for c in revs:
3255 ui.write(b"%d\n" % c)
3262 ui.write(b"%d\n" % c)
3256
3263
3257
3264
3258 @command(
3265 @command(
3259 b'debugserve',
3266 b'debugserve',
3260 [
3267 [
3261 (
3268 (
3262 b'',
3269 b'',
3263 b'sshstdio',
3270 b'sshstdio',
3264 False,
3271 False,
3265 _(b'run an SSH server bound to process handles'),
3272 _(b'run an SSH server bound to process handles'),
3266 ),
3273 ),
3267 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3274 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3268 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3275 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3269 ],
3276 ],
3270 b'',
3277 b'',
3271 )
3278 )
3272 def debugserve(ui, repo, **opts):
3279 def debugserve(ui, repo, **opts):
3273 """run a server with advanced settings
3280 """run a server with advanced settings
3274
3281
3275 This command is similar to :hg:`serve`. It exists partially as a
3282 This command is similar to :hg:`serve`. It exists partially as a
3276 workaround to the fact that ``hg serve --stdio`` must have specific
3283 workaround to the fact that ``hg serve --stdio`` must have specific
3277 arguments for security reasons.
3284 arguments for security reasons.
3278 """
3285 """
3279 opts = pycompat.byteskwargs(opts)
3286 opts = pycompat.byteskwargs(opts)
3280
3287
3281 if not opts[b'sshstdio']:
3288 if not opts[b'sshstdio']:
3282 raise error.Abort(_(b'only --sshstdio is currently supported'))
3289 raise error.Abort(_(b'only --sshstdio is currently supported'))
3283
3290
3284 logfh = None
3291 logfh = None
3285
3292
3286 if opts[b'logiofd'] and opts[b'logiofile']:
3293 if opts[b'logiofd'] and opts[b'logiofile']:
3287 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3294 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3288
3295
3289 if opts[b'logiofd']:
3296 if opts[b'logiofd']:
3290 # Ideally we would be line buffered. But line buffering in binary
3297 # Ideally we would be line buffered. But line buffering in binary
3291 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3298 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3292 # buffering could have performance impacts. But since this isn't
3299 # buffering could have performance impacts. But since this isn't
3293 # performance critical code, it should be fine.
3300 # performance critical code, it should be fine.
3294 try:
3301 try:
3295 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3302 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3296 except OSError as e:
3303 except OSError as e:
3297 if e.errno != errno.ESPIPE:
3304 if e.errno != errno.ESPIPE:
3298 raise
3305 raise
3299 # can't seek a pipe, so `ab` mode fails on py3
3306 # can't seek a pipe, so `ab` mode fails on py3
3300 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3307 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3301 elif opts[b'logiofile']:
3308 elif opts[b'logiofile']:
3302 logfh = open(opts[b'logiofile'], b'ab', 0)
3309 logfh = open(opts[b'logiofile'], b'ab', 0)
3303
3310
3304 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3311 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3305 s.serve_forever()
3312 s.serve_forever()
3306
3313
3307
3314
3308 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3315 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3309 def debugsetparents(ui, repo, rev1, rev2=None):
3316 def debugsetparents(ui, repo, rev1, rev2=None):
3310 """manually set the parents of the current working directory
3317 """manually set the parents of the current working directory
3311
3318
3312 This is useful for writing repository conversion tools, but should
3319 This is useful for writing repository conversion tools, but should
3313 be used with care. For example, neither the working directory nor the
3320 be used with care. For example, neither the working directory nor the
3314 dirstate is updated, so file status may be incorrect after running this
3321 dirstate is updated, so file status may be incorrect after running this
3315 command.
3322 command.
3316
3323
3317 Returns 0 on success.
3324 Returns 0 on success.
3318 """
3325 """
3319
3326
3320 node1 = scmutil.revsingle(repo, rev1).node()
3327 node1 = scmutil.revsingle(repo, rev1).node()
3321 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3328 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3322
3329
3323 with repo.wlock():
3330 with repo.wlock():
3324 repo.setparents(node1, node2)
3331 repo.setparents(node1, node2)
3325
3332
3326
3333
3327 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3334 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3328 def debugsidedata(ui, repo, file_, rev=None, **opts):
3335 def debugsidedata(ui, repo, file_, rev=None, **opts):
3329 """dump the side data for a cl/manifest/file revision
3336 """dump the side data for a cl/manifest/file revision
3330
3337
3331 Use --verbose to dump the sidedata content."""
3338 Use --verbose to dump the sidedata content."""
3332 opts = pycompat.byteskwargs(opts)
3339 opts = pycompat.byteskwargs(opts)
3333 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3340 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3334 if rev is not None:
3341 if rev is not None:
3335 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3342 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3336 file_, rev = None, file_
3343 file_, rev = None, file_
3337 elif rev is None:
3344 elif rev is None:
3338 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3345 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3339 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3346 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3340 r = getattr(r, '_revlog', r)
3347 r = getattr(r, '_revlog', r)
3341 try:
3348 try:
3342 sidedata = r.sidedata(r.lookup(rev))
3349 sidedata = r.sidedata(r.lookup(rev))
3343 except KeyError:
3350 except KeyError:
3344 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3351 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3345 if sidedata:
3352 if sidedata:
3346 sidedata = list(sidedata.items())
3353 sidedata = list(sidedata.items())
3347 sidedata.sort()
3354 sidedata.sort()
3348 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3355 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3349 for key, value in sidedata:
3356 for key, value in sidedata:
3350 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3357 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3351 if ui.verbose:
3358 if ui.verbose:
3352 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3359 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3353
3360
3354
3361
3355 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3362 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3356 def debugssl(ui, repo, source=None, **opts):
3363 def debugssl(ui, repo, source=None, **opts):
3357 '''test a secure connection to a server
3364 '''test a secure connection to a server
3358
3365
3359 This builds the certificate chain for the server on Windows, installing the
3366 This builds the certificate chain for the server on Windows, installing the
3360 missing intermediates and trusted root via Windows Update if necessary. It
3367 missing intermediates and trusted root via Windows Update if necessary. It
3361 does nothing on other platforms.
3368 does nothing on other platforms.
3362
3369
3363 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3370 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3364 that server is used. See :hg:`help urls` for more information.
3371 that server is used. See :hg:`help urls` for more information.
3365
3372
3366 If the update succeeds, retry the original operation. Otherwise, the cause
3373 If the update succeeds, retry the original operation. Otherwise, the cause
3367 of the SSL error is likely another issue.
3374 of the SSL error is likely another issue.
3368 '''
3375 '''
3369 if not pycompat.iswindows:
3376 if not pycompat.iswindows:
3370 raise error.Abort(
3377 raise error.Abort(
3371 _(b'certificate chain building is only possible on Windows')
3378 _(b'certificate chain building is only possible on Windows')
3372 )
3379 )
3373
3380
3374 if not source:
3381 if not source:
3375 if not repo:
3382 if not repo:
3376 raise error.Abort(
3383 raise error.Abort(
3377 _(
3384 _(
3378 b"there is no Mercurial repository here, and no "
3385 b"there is no Mercurial repository here, and no "
3379 b"server specified"
3386 b"server specified"
3380 )
3387 )
3381 )
3388 )
3382 source = b"default"
3389 source = b"default"
3383
3390
3384 source, branches = hg.parseurl(ui.expandpath(source))
3391 source, branches = hg.parseurl(ui.expandpath(source))
3385 url = util.url(source)
3392 url = util.url(source)
3386
3393
3387 defaultport = {b'https': 443, b'ssh': 22}
3394 defaultport = {b'https': 443, b'ssh': 22}
3388 if url.scheme in defaultport:
3395 if url.scheme in defaultport:
3389 try:
3396 try:
3390 addr = (url.host, int(url.port or defaultport[url.scheme]))
3397 addr = (url.host, int(url.port or defaultport[url.scheme]))
3391 except ValueError:
3398 except ValueError:
3392 raise error.Abort(_(b"malformed port number in URL"))
3399 raise error.Abort(_(b"malformed port number in URL"))
3393 else:
3400 else:
3394 raise error.Abort(_(b"only https and ssh connections are supported"))
3401 raise error.Abort(_(b"only https and ssh connections are supported"))
3395
3402
3396 from . import win32
3403 from . import win32
3397
3404
3398 s = ssl.wrap_socket(
3405 s = ssl.wrap_socket(
3399 socket.socket(),
3406 socket.socket(),
3400 ssl_version=ssl.PROTOCOL_TLS,
3407 ssl_version=ssl.PROTOCOL_TLS,
3401 cert_reqs=ssl.CERT_NONE,
3408 cert_reqs=ssl.CERT_NONE,
3402 ca_certs=None,
3409 ca_certs=None,
3403 )
3410 )
3404
3411
3405 try:
3412 try:
3406 s.connect(addr)
3413 s.connect(addr)
3407 cert = s.getpeercert(True)
3414 cert = s.getpeercert(True)
3408
3415
3409 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3416 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3410
3417
3411 complete = win32.checkcertificatechain(cert, build=False)
3418 complete = win32.checkcertificatechain(cert, build=False)
3412
3419
3413 if not complete:
3420 if not complete:
3414 ui.status(_(b'certificate chain is incomplete, updating... '))
3421 ui.status(_(b'certificate chain is incomplete, updating... '))
3415
3422
3416 if not win32.checkcertificatechain(cert):
3423 if not win32.checkcertificatechain(cert):
3417 ui.status(_(b'failed.\n'))
3424 ui.status(_(b'failed.\n'))
3418 else:
3425 else:
3419 ui.status(_(b'done.\n'))
3426 ui.status(_(b'done.\n'))
3420 else:
3427 else:
3421 ui.status(_(b'full certificate chain is available\n'))
3428 ui.status(_(b'full certificate chain is available\n'))
3422 finally:
3429 finally:
3423 s.close()
3430 s.close()
3424
3431
3425
3432
3426 @command(
3433 @command(
3427 b"debugbackupbundle",
3434 b"debugbackupbundle",
3428 [
3435 [
3429 (
3436 (
3430 b"",
3437 b"",
3431 b"recover",
3438 b"recover",
3432 b"",
3439 b"",
3433 b"brings the specified changeset back into the repository",
3440 b"brings the specified changeset back into the repository",
3434 )
3441 )
3435 ]
3442 ]
3436 + cmdutil.logopts,
3443 + cmdutil.logopts,
3437 _(b"hg debugbackupbundle [--recover HASH]"),
3444 _(b"hg debugbackupbundle [--recover HASH]"),
3438 )
3445 )
3439 def debugbackupbundle(ui, repo, *pats, **opts):
3446 def debugbackupbundle(ui, repo, *pats, **opts):
3440 """lists the changesets available in backup bundles
3447 """lists the changesets available in backup bundles
3441
3448
3442 Without any arguments, this command prints a list of the changesets in each
3449 Without any arguments, this command prints a list of the changesets in each
3443 backup bundle.
3450 backup bundle.
3444
3451
3445 --recover takes a changeset hash and unbundles the first bundle that
3452 --recover takes a changeset hash and unbundles the first bundle that
3446 contains that hash, which puts that changeset back in your repository.
3453 contains that hash, which puts that changeset back in your repository.
3447
3454
3448 --verbose will print the entire commit message and the bundle path for that
3455 --verbose will print the entire commit message and the bundle path for that
3449 backup.
3456 backup.
3450 """
3457 """
3451 backups = list(
3458 backups = list(
3452 filter(
3459 filter(
3453 os.path.isfile, glob.glob(repo.vfs.join(b"strip-backup") + b"/*.hg")
3460 os.path.isfile, glob.glob(repo.vfs.join(b"strip-backup") + b"/*.hg")
3454 )
3461 )
3455 )
3462 )
3456 backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
3463 backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
3457
3464
3458 opts = pycompat.byteskwargs(opts)
3465 opts = pycompat.byteskwargs(opts)
3459 opts[b"bundle"] = b""
3466 opts[b"bundle"] = b""
3460 opts[b"force"] = None
3467 opts[b"force"] = None
3461 limit = logcmdutil.getlimit(opts)
3468 limit = logcmdutil.getlimit(opts)
3462
3469
3463 def display(other, chlist, displayer):
3470 def display(other, chlist, displayer):
3464 if opts.get(b"newest_first"):
3471 if opts.get(b"newest_first"):
3465 chlist.reverse()
3472 chlist.reverse()
3466 count = 0
3473 count = 0
3467 for n in chlist:
3474 for n in chlist:
3468 if limit is not None and count >= limit:
3475 if limit is not None and count >= limit:
3469 break
3476 break
3470 parents = [True for p in other.changelog.parents(n) if p != nullid]
3477 parents = [True for p in other.changelog.parents(n) if p != nullid]
3471 if opts.get(b"no_merges") and len(parents) == 2:
3478 if opts.get(b"no_merges") and len(parents) == 2:
3472 continue
3479 continue
3473 count += 1
3480 count += 1
3474 displayer.show(other[n])
3481 displayer.show(other[n])
3475
3482
3476 recovernode = opts.get(b"recover")
3483 recovernode = opts.get(b"recover")
3477 if recovernode:
3484 if recovernode:
3478 if scmutil.isrevsymbol(repo, recovernode):
3485 if scmutil.isrevsymbol(repo, recovernode):
3479 ui.warn(_(b"%s already exists in the repo\n") % recovernode)
3486 ui.warn(_(b"%s already exists in the repo\n") % recovernode)
3480 return
3487 return
3481 elif backups:
3488 elif backups:
3482 msg = _(
3489 msg = _(
3483 b"Recover changesets using: hg debugbackupbundle --recover "
3490 b"Recover changesets using: hg debugbackupbundle --recover "
3484 b"<changeset hash>\n\nAvailable backup changesets:"
3491 b"<changeset hash>\n\nAvailable backup changesets:"
3485 )
3492 )
3486 ui.status(msg, label=b"status.removed")
3493 ui.status(msg, label=b"status.removed")
3487 else:
3494 else:
3488 ui.status(_(b"no backup changesets found\n"))
3495 ui.status(_(b"no backup changesets found\n"))
3489 return
3496 return
3490
3497
3491 for backup in backups:
3498 for backup in backups:
3492 # Much of this is copied from the hg incoming logic
3499 # Much of this is copied from the hg incoming logic
3493 source = ui.expandpath(os.path.relpath(backup, encoding.getcwd()))
3500 source = ui.expandpath(os.path.relpath(backup, encoding.getcwd()))
3494 source, branches = hg.parseurl(source, opts.get(b"branch"))
3501 source, branches = hg.parseurl(source, opts.get(b"branch"))
3495 try:
3502 try:
3496 other = hg.peer(repo, opts, source)
3503 other = hg.peer(repo, opts, source)
3497 except error.LookupError as ex:
3504 except error.LookupError as ex:
3498 msg = _(b"\nwarning: unable to open bundle %s") % source
3505 msg = _(b"\nwarning: unable to open bundle %s") % source
3499 hint = _(b"\n(missing parent rev %s)\n") % short(ex.name)
3506 hint = _(b"\n(missing parent rev %s)\n") % short(ex.name)
3500 ui.warn(msg, hint=hint)
3507 ui.warn(msg, hint=hint)
3501 continue
3508 continue
3502 revs, checkout = hg.addbranchrevs(
3509 revs, checkout = hg.addbranchrevs(
3503 repo, other, branches, opts.get(b"rev")
3510 repo, other, branches, opts.get(b"rev")
3504 )
3511 )
3505
3512
3506 if revs:
3513 if revs:
3507 revs = [other.lookup(rev) for rev in revs]
3514 revs = [other.lookup(rev) for rev in revs]
3508
3515
3509 quiet = ui.quiet
3516 quiet = ui.quiet
3510 try:
3517 try:
3511 ui.quiet = True
3518 ui.quiet = True
3512 other, chlist, cleanupfn = bundlerepo.getremotechanges(
3519 other, chlist, cleanupfn = bundlerepo.getremotechanges(
3513 ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
3520 ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
3514 )
3521 )
3515 except error.LookupError:
3522 except error.LookupError:
3516 continue
3523 continue
3517 finally:
3524 finally:
3518 ui.quiet = quiet
3525 ui.quiet = quiet
3519
3526
3520 try:
3527 try:
3521 if not chlist:
3528 if not chlist:
3522 continue
3529 continue
3523 if recovernode:
3530 if recovernode:
3524 with repo.lock(), repo.transaction(b"unbundle") as tr:
3531 with repo.lock(), repo.transaction(b"unbundle") as tr:
3525 if scmutil.isrevsymbol(other, recovernode):
3532 if scmutil.isrevsymbol(other, recovernode):
3526 ui.status(_(b"Unbundling %s\n") % (recovernode))
3533 ui.status(_(b"Unbundling %s\n") % (recovernode))
3527 f = hg.openpath(ui, source)
3534 f = hg.openpath(ui, source)
3528 gen = exchange.readbundle(ui, f, source)
3535 gen = exchange.readbundle(ui, f, source)
3529 if isinstance(gen, bundle2.unbundle20):
3536 if isinstance(gen, bundle2.unbundle20):
3530 bundle2.applybundle(
3537 bundle2.applybundle(
3531 repo,
3538 repo,
3532 gen,
3539 gen,
3533 tr,
3540 tr,
3534 source=b"unbundle",
3541 source=b"unbundle",
3535 url=b"bundle:" + source,
3542 url=b"bundle:" + source,
3536 )
3543 )
3537 else:
3544 else:
3538 gen.apply(repo, b"unbundle", b"bundle:" + source)
3545 gen.apply(repo, b"unbundle", b"bundle:" + source)
3539 break
3546 break
3540 else:
3547 else:
3541 backupdate = encoding.strtolocal(
3548 backupdate = encoding.strtolocal(
3542 time.strftime(
3549 time.strftime(
3543 "%a %H:%M, %Y-%m-%d",
3550 "%a %H:%M, %Y-%m-%d",
3544 time.localtime(os.path.getmtime(source)),
3551 time.localtime(os.path.getmtime(source)),
3545 )
3552 )
3546 )
3553 )
3547 ui.status(b"\n%s\n" % (backupdate.ljust(50)))
3554 ui.status(b"\n%s\n" % (backupdate.ljust(50)))
3548 if ui.verbose:
3555 if ui.verbose:
3549 ui.status(b"%s%s\n" % (b"bundle:".ljust(13), source))
3556 ui.status(b"%s%s\n" % (b"bundle:".ljust(13), source))
3550 else:
3557 else:
3551 opts[
3558 opts[
3552 b"template"
3559 b"template"
3553 ] = b"{label('status.modified', node|short)} {desc|firstline}\n"
3560 ] = b"{label('status.modified', node|short)} {desc|firstline}\n"
3554 displayer = logcmdutil.changesetdisplayer(
3561 displayer = logcmdutil.changesetdisplayer(
3555 ui, other, opts, False
3562 ui, other, opts, False
3556 )
3563 )
3557 display(other, chlist, displayer)
3564 display(other, chlist, displayer)
3558 displayer.close()
3565 displayer.close()
3559 finally:
3566 finally:
3560 cleanupfn()
3567 cleanupfn()
3561
3568
3562
3569
3563 @command(
3570 @command(
3564 b'debugsub',
3571 b'debugsub',
3565 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3572 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3566 _(b'[-r REV] [REV]'),
3573 _(b'[-r REV] [REV]'),
3567 )
3574 )
3568 def debugsub(ui, repo, rev=None):
3575 def debugsub(ui, repo, rev=None):
3569 ctx = scmutil.revsingle(repo, rev, None)
3576 ctx = scmutil.revsingle(repo, rev, None)
3570 for k, v in sorted(ctx.substate.items()):
3577 for k, v in sorted(ctx.substate.items()):
3571 ui.writenoi18n(b'path %s\n' % k)
3578 ui.writenoi18n(b'path %s\n' % k)
3572 ui.writenoi18n(b' source %s\n' % v[0])
3579 ui.writenoi18n(b' source %s\n' % v[0])
3573 ui.writenoi18n(b' revision %s\n' % v[1])
3580 ui.writenoi18n(b' revision %s\n' % v[1])
3574
3581
3575
3582
3576 @command(
3583 @command(
3577 b'debugsuccessorssets',
3584 b'debugsuccessorssets',
3578 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3585 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3579 _(b'[REV]'),
3586 _(b'[REV]'),
3580 )
3587 )
3581 def debugsuccessorssets(ui, repo, *revs, **opts):
3588 def debugsuccessorssets(ui, repo, *revs, **opts):
3582 """show set of successors for revision
3589 """show set of successors for revision
3583
3590
3584 A successors set of changeset A is a consistent group of revisions that
3591 A successors set of changeset A is a consistent group of revisions that
3585 succeed A. It contains non-obsolete changesets only unless closests
3592 succeed A. It contains non-obsolete changesets only unless closests
3586 successors set is set.
3593 successors set is set.
3587
3594
3588 In most cases a changeset A has a single successors set containing a single
3595 In most cases a changeset A has a single successors set containing a single
3589 successor (changeset A replaced by A').
3596 successor (changeset A replaced by A').
3590
3597
3591 A changeset that is made obsolete with no successors are called "pruned".
3598 A changeset that is made obsolete with no successors are called "pruned".
3592 Such changesets have no successors sets at all.
3599 Such changesets have no successors sets at all.
3593
3600
3594 A changeset that has been "split" will have a successors set containing
3601 A changeset that has been "split" will have a successors set containing
3595 more than one successor.
3602 more than one successor.
3596
3603
3597 A changeset that has been rewritten in multiple different ways is called
3604 A changeset that has been rewritten in multiple different ways is called
3598 "divergent". Such changesets have multiple successor sets (each of which
3605 "divergent". Such changesets have multiple successor sets (each of which
3599 may also be split, i.e. have multiple successors).
3606 may also be split, i.e. have multiple successors).
3600
3607
3601 Results are displayed as follows::
3608 Results are displayed as follows::
3602
3609
3603 <rev1>
3610 <rev1>
3604 <successors-1A>
3611 <successors-1A>
3605 <rev2>
3612 <rev2>
3606 <successors-2A>
3613 <successors-2A>
3607 <successors-2B1> <successors-2B2> <successors-2B3>
3614 <successors-2B1> <successors-2B2> <successors-2B3>
3608
3615
3609 Here rev2 has two possible (i.e. divergent) successors sets. The first
3616 Here rev2 has two possible (i.e. divergent) successors sets. The first
3610 holds one element, whereas the second holds three (i.e. the changeset has
3617 holds one element, whereas the second holds three (i.e. the changeset has
3611 been split).
3618 been split).
3612 """
3619 """
3613 # passed to successorssets caching computation from one call to another
3620 # passed to successorssets caching computation from one call to another
3614 cache = {}
3621 cache = {}
3615 ctx2str = bytes
3622 ctx2str = bytes
3616 node2str = short
3623 node2str = short
3617 for rev in scmutil.revrange(repo, revs):
3624 for rev in scmutil.revrange(repo, revs):
3618 ctx = repo[rev]
3625 ctx = repo[rev]
3619 ui.write(b'%s\n' % ctx2str(ctx))
3626 ui.write(b'%s\n' % ctx2str(ctx))
3620 for succsset in obsutil.successorssets(
3627 for succsset in obsutil.successorssets(
3621 repo, ctx.node(), closest=opts['closest'], cache=cache
3628 repo, ctx.node(), closest=opts['closest'], cache=cache
3622 ):
3629 ):
3623 if succsset:
3630 if succsset:
3624 ui.write(b' ')
3631 ui.write(b' ')
3625 ui.write(node2str(succsset[0]))
3632 ui.write(node2str(succsset[0]))
3626 for node in succsset[1:]:
3633 for node in succsset[1:]:
3627 ui.write(b' ')
3634 ui.write(b' ')
3628 ui.write(node2str(node))
3635 ui.write(node2str(node))
3629 ui.write(b'\n')
3636 ui.write(b'\n')
3630
3637
3631
3638
3632 @command(b'debugtagscache', [])
3639 @command(b'debugtagscache', [])
3633 def debugtagscache(ui, repo):
3640 def debugtagscache(ui, repo):
3634 """display the contents of .hg/cache/hgtagsfnodes1"""
3641 """display the contents of .hg/cache/hgtagsfnodes1"""
3635 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3642 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3636 for r in repo:
3643 for r in repo:
3637 node = repo[r].node()
3644 node = repo[r].node()
3638 tagsnode = cache.getfnode(node, computemissing=False)
3645 tagsnode = cache.getfnode(node, computemissing=False)
3639 tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
3646 tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
3640 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
3647 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
3641
3648
3642
3649
3643 @command(
3650 @command(
3644 b'debugtemplate',
3651 b'debugtemplate',
3645 [
3652 [
3646 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3653 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3647 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3654 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3648 ],
3655 ],
3649 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3656 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3650 optionalrepo=True,
3657 optionalrepo=True,
3651 )
3658 )
3652 def debugtemplate(ui, repo, tmpl, **opts):
3659 def debugtemplate(ui, repo, tmpl, **opts):
3653 """parse and apply a template
3660 """parse and apply a template
3654
3661
3655 If -r/--rev is given, the template is processed as a log template and
3662 If -r/--rev is given, the template is processed as a log template and
3656 applied to the given changesets. Otherwise, it is processed as a generic
3663 applied to the given changesets. Otherwise, it is processed as a generic
3657 template.
3664 template.
3658
3665
3659 Use --verbose to print the parsed tree.
3666 Use --verbose to print the parsed tree.
3660 """
3667 """
3661 revs = None
3668 revs = None
3662 if opts['rev']:
3669 if opts['rev']:
3663 if repo is None:
3670 if repo is None:
3664 raise error.RepoError(
3671 raise error.RepoError(
3665 _(b'there is no Mercurial repository here (.hg not found)')
3672 _(b'there is no Mercurial repository here (.hg not found)')
3666 )
3673 )
3667 revs = scmutil.revrange(repo, opts['rev'])
3674 revs = scmutil.revrange(repo, opts['rev'])
3668
3675
3669 props = {}
3676 props = {}
3670 for d in opts['define']:
3677 for d in opts['define']:
3671 try:
3678 try:
3672 k, v = (e.strip() for e in d.split(b'=', 1))
3679 k, v = (e.strip() for e in d.split(b'=', 1))
3673 if not k or k == b'ui':
3680 if not k or k == b'ui':
3674 raise ValueError
3681 raise ValueError
3675 props[k] = v
3682 props[k] = v
3676 except ValueError:
3683 except ValueError:
3677 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3684 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3678
3685
3679 if ui.verbose:
3686 if ui.verbose:
3680 aliases = ui.configitems(b'templatealias')
3687 aliases = ui.configitems(b'templatealias')
3681 tree = templater.parse(tmpl)
3688 tree = templater.parse(tmpl)
3682 ui.note(templater.prettyformat(tree), b'\n')
3689 ui.note(templater.prettyformat(tree), b'\n')
3683 newtree = templater.expandaliases(tree, aliases)
3690 newtree = templater.expandaliases(tree, aliases)
3684 if newtree != tree:
3691 if newtree != tree:
3685 ui.notenoi18n(
3692 ui.notenoi18n(
3686 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3693 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3687 )
3694 )
3688
3695
3689 if revs is None:
3696 if revs is None:
3690 tres = formatter.templateresources(ui, repo)
3697 tres = formatter.templateresources(ui, repo)
3691 t = formatter.maketemplater(ui, tmpl, resources=tres)
3698 t = formatter.maketemplater(ui, tmpl, resources=tres)
3692 if ui.verbose:
3699 if ui.verbose:
3693 kwds, funcs = t.symbolsuseddefault()
3700 kwds, funcs = t.symbolsuseddefault()
3694 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3701 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3695 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3702 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3696 ui.write(t.renderdefault(props))
3703 ui.write(t.renderdefault(props))
3697 else:
3704 else:
3698 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3705 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3699 if ui.verbose:
3706 if ui.verbose:
3700 kwds, funcs = displayer.t.symbolsuseddefault()
3707 kwds, funcs = displayer.t.symbolsuseddefault()
3701 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3708 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3702 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3709 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3703 for r in revs:
3710 for r in revs:
3704 displayer.show(repo[r], **pycompat.strkwargs(props))
3711 displayer.show(repo[r], **pycompat.strkwargs(props))
3705 displayer.close()
3712 displayer.close()
3706
3713
3707
3714
3708 @command(
3715 @command(
3709 b'debuguigetpass',
3716 b'debuguigetpass',
3710 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3717 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3711 _(b'[-p TEXT]'),
3718 _(b'[-p TEXT]'),
3712 norepo=True,
3719 norepo=True,
3713 )
3720 )
3714 def debuguigetpass(ui, prompt=b''):
3721 def debuguigetpass(ui, prompt=b''):
3715 """show prompt to type password"""
3722 """show prompt to type password"""
3716 r = ui.getpass(prompt)
3723 r = ui.getpass(prompt)
3717 ui.writenoi18n(b'response: %s\n' % r)
3724 ui.writenoi18n(b'response: %s\n' % r)
3718
3725
3719
3726
3720 @command(
3727 @command(
3721 b'debuguiprompt',
3728 b'debuguiprompt',
3722 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3729 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3723 _(b'[-p TEXT]'),
3730 _(b'[-p TEXT]'),
3724 norepo=True,
3731 norepo=True,
3725 )
3732 )
3726 def debuguiprompt(ui, prompt=b''):
3733 def debuguiprompt(ui, prompt=b''):
3727 """show plain prompt"""
3734 """show plain prompt"""
3728 r = ui.prompt(prompt)
3735 r = ui.prompt(prompt)
3729 ui.writenoi18n(b'response: %s\n' % r)
3736 ui.writenoi18n(b'response: %s\n' % r)
3730
3737
3731
3738
3732 @command(b'debugupdatecaches', [])
3739 @command(b'debugupdatecaches', [])
3733 def debugupdatecaches(ui, repo, *pats, **opts):
3740 def debugupdatecaches(ui, repo, *pats, **opts):
3734 """warm all known caches in the repository"""
3741 """warm all known caches in the repository"""
3735 with repo.wlock(), repo.lock():
3742 with repo.wlock(), repo.lock():
3736 repo.updatecaches(full=True)
3743 repo.updatecaches(full=True)
3737
3744
3738
3745
3739 @command(
3746 @command(
3740 b'debugupgraderepo',
3747 b'debugupgraderepo',
3741 [
3748 [
3742 (
3749 (
3743 b'o',
3750 b'o',
3744 b'optimize',
3751 b'optimize',
3745 [],
3752 [],
3746 _(b'extra optimization to perform'),
3753 _(b'extra optimization to perform'),
3747 _(b'NAME'),
3754 _(b'NAME'),
3748 ),
3755 ),
3749 (b'', b'run', False, _(b'performs an upgrade')),
3756 (b'', b'run', False, _(b'performs an upgrade')),
3750 (b'', b'backup', True, _(b'keep the old repository content around')),
3757 (b'', b'backup', True, _(b'keep the old repository content around')),
3751 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3758 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3752 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3759 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3753 ],
3760 ],
3754 )
3761 )
3755 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3762 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3756 """upgrade a repository to use different features
3763 """upgrade a repository to use different features
3757
3764
3758 If no arguments are specified, the repository is evaluated for upgrade
3765 If no arguments are specified, the repository is evaluated for upgrade
3759 and a list of problems and potential optimizations is printed.
3766 and a list of problems and potential optimizations is printed.
3760
3767
3761 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3768 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3762 can be influenced via additional arguments. More details will be provided
3769 can be influenced via additional arguments. More details will be provided
3763 by the command output when run without ``--run``.
3770 by the command output when run without ``--run``.
3764
3771
3765 During the upgrade, the repository will be locked and no writes will be
3772 During the upgrade, the repository will be locked and no writes will be
3766 allowed.
3773 allowed.
3767
3774
3768 At the end of the upgrade, the repository may not be readable while new
3775 At the end of the upgrade, the repository may not be readable while new
3769 repository data is swapped in. This window will be as long as it takes to
3776 repository data is swapped in. This window will be as long as it takes to
3770 rename some directories inside the ``.hg`` directory. On most machines, this
3777 rename some directories inside the ``.hg`` directory. On most machines, this
3771 should complete almost instantaneously and the chances of a consumer being
3778 should complete almost instantaneously and the chances of a consumer being
3772 unable to access the repository should be low.
3779 unable to access the repository should be low.
3773
3780
3774 By default, all revlog will be upgraded. You can restrict this using flag
3781 By default, all revlog will be upgraded. You can restrict this using flag
3775 such as `--manifest`:
3782 such as `--manifest`:
3776
3783
3777 * `--manifest`: only optimize the manifest
3784 * `--manifest`: only optimize the manifest
3778 * `--no-manifest`: optimize all revlog but the manifest
3785 * `--no-manifest`: optimize all revlog but the manifest
3779 * `--changelog`: optimize the changelog only
3786 * `--changelog`: optimize the changelog only
3780 * `--no-changelog --no-manifest`: optimize filelogs only
3787 * `--no-changelog --no-manifest`: optimize filelogs only
3781 """
3788 """
3782 return upgrade.upgraderepo(
3789 return upgrade.upgraderepo(
3783 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3790 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3784 )
3791 )
3785
3792
3786
3793
3787 @command(
3794 @command(
3788 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3795 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3789 )
3796 )
3790 def debugwalk(ui, repo, *pats, **opts):
3797 def debugwalk(ui, repo, *pats, **opts):
3791 """show how files match on given patterns"""
3798 """show how files match on given patterns"""
3792 opts = pycompat.byteskwargs(opts)
3799 opts = pycompat.byteskwargs(opts)
3793 m = scmutil.match(repo[None], pats, opts)
3800 m = scmutil.match(repo[None], pats, opts)
3794 if ui.verbose:
3801 if ui.verbose:
3795 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3802 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3796 items = list(repo[None].walk(m))
3803 items = list(repo[None].walk(m))
3797 if not items:
3804 if not items:
3798 return
3805 return
3799 f = lambda fn: fn
3806 f = lambda fn: fn
3800 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3807 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3801 f = lambda fn: util.normpath(fn)
3808 f = lambda fn: util.normpath(fn)
3802 fmt = b'f %%-%ds %%-%ds %%s' % (
3809 fmt = b'f %%-%ds %%-%ds %%s' % (
3803 max([len(abs) for abs in items]),
3810 max([len(abs) for abs in items]),
3804 max([len(repo.pathto(abs)) for abs in items]),
3811 max([len(repo.pathto(abs)) for abs in items]),
3805 )
3812 )
3806 for abs in items:
3813 for abs in items:
3807 line = fmt % (
3814 line = fmt % (
3808 abs,
3815 abs,
3809 f(repo.pathto(abs)),
3816 f(repo.pathto(abs)),
3810 m.exact(abs) and b'exact' or b'',
3817 m.exact(abs) and b'exact' or b'',
3811 )
3818 )
3812 ui.write(b"%s\n" % line.rstrip())
3819 ui.write(b"%s\n" % line.rstrip())
3813
3820
3814
3821
3815 @command(b'debugwhyunstable', [], _(b'REV'))
3822 @command(b'debugwhyunstable', [], _(b'REV'))
3816 def debugwhyunstable(ui, repo, rev):
3823 def debugwhyunstable(ui, repo, rev):
3817 """explain instabilities of a changeset"""
3824 """explain instabilities of a changeset"""
3818 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3825 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3819 dnodes = b''
3826 dnodes = b''
3820 if entry.get(b'divergentnodes'):
3827 if entry.get(b'divergentnodes'):
3821 dnodes = (
3828 dnodes = (
3822 b' '.join(
3829 b' '.join(
3823 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3830 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3824 for ctx in entry[b'divergentnodes']
3831 for ctx in entry[b'divergentnodes']
3825 )
3832 )
3826 + b' '
3833 + b' '
3827 )
3834 )
3828 ui.write(
3835 ui.write(
3829 b'%s: %s%s %s\n'
3836 b'%s: %s%s %s\n'
3830 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3837 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3831 )
3838 )
3832
3839
3833
3840
3834 @command(
3841 @command(
3835 b'debugwireargs',
3842 b'debugwireargs',
3836 [
3843 [
3837 (b'', b'three', b'', b'three'),
3844 (b'', b'three', b'', b'three'),
3838 (b'', b'four', b'', b'four'),
3845 (b'', b'four', b'', b'four'),
3839 (b'', b'five', b'', b'five'),
3846 (b'', b'five', b'', b'five'),
3840 ]
3847 ]
3841 + cmdutil.remoteopts,
3848 + cmdutil.remoteopts,
3842 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3849 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3843 norepo=True,
3850 norepo=True,
3844 )
3851 )
3845 def debugwireargs(ui, repopath, *vals, **opts):
3852 def debugwireargs(ui, repopath, *vals, **opts):
3846 opts = pycompat.byteskwargs(opts)
3853 opts = pycompat.byteskwargs(opts)
3847 repo = hg.peer(ui, opts, repopath)
3854 repo = hg.peer(ui, opts, repopath)
3848 for opt in cmdutil.remoteopts:
3855 for opt in cmdutil.remoteopts:
3849 del opts[opt[1]]
3856 del opts[opt[1]]
3850 args = {}
3857 args = {}
3851 for k, v in pycompat.iteritems(opts):
3858 for k, v in pycompat.iteritems(opts):
3852 if v:
3859 if v:
3853 args[k] = v
3860 args[k] = v
3854 args = pycompat.strkwargs(args)
3861 args = pycompat.strkwargs(args)
3855 # run twice to check that we don't mess up the stream for the next command
3862 # run twice to check that we don't mess up the stream for the next command
3856 res1 = repo.debugwireargs(*vals, **args)
3863 res1 = repo.debugwireargs(*vals, **args)
3857 res2 = repo.debugwireargs(*vals, **args)
3864 res2 = repo.debugwireargs(*vals, **args)
3858 ui.write(b"%s\n" % res1)
3865 ui.write(b"%s\n" % res1)
3859 if res1 != res2:
3866 if res1 != res2:
3860 ui.warn(b"%s\n" % res2)
3867 ui.warn(b"%s\n" % res2)
3861
3868
3862
3869
3863 def _parsewirelangblocks(fh):
3870 def _parsewirelangblocks(fh):
3864 activeaction = None
3871 activeaction = None
3865 blocklines = []
3872 blocklines = []
3866 lastindent = 0
3873 lastindent = 0
3867
3874
3868 for line in fh:
3875 for line in fh:
3869 line = line.rstrip()
3876 line = line.rstrip()
3870 if not line:
3877 if not line:
3871 continue
3878 continue
3872
3879
3873 if line.startswith(b'#'):
3880 if line.startswith(b'#'):
3874 continue
3881 continue
3875
3882
3876 if not line.startswith(b' '):
3883 if not line.startswith(b' '):
3877 # New block. Flush previous one.
3884 # New block. Flush previous one.
3878 if activeaction:
3885 if activeaction:
3879 yield activeaction, blocklines
3886 yield activeaction, blocklines
3880
3887
3881 activeaction = line
3888 activeaction = line
3882 blocklines = []
3889 blocklines = []
3883 lastindent = 0
3890 lastindent = 0
3884 continue
3891 continue
3885
3892
3886 # Else we start with an indent.
3893 # Else we start with an indent.
3887
3894
3888 if not activeaction:
3895 if not activeaction:
3889 raise error.Abort(_(b'indented line outside of block'))
3896 raise error.Abort(_(b'indented line outside of block'))
3890
3897
3891 indent = len(line) - len(line.lstrip())
3898 indent = len(line) - len(line.lstrip())
3892
3899
3893 # If this line is indented more than the last line, concatenate it.
3900 # If this line is indented more than the last line, concatenate it.
3894 if indent > lastindent and blocklines:
3901 if indent > lastindent and blocklines:
3895 blocklines[-1] += line.lstrip()
3902 blocklines[-1] += line.lstrip()
3896 else:
3903 else:
3897 blocklines.append(line)
3904 blocklines.append(line)
3898 lastindent = indent
3905 lastindent = indent
3899
3906
3900 # Flush last block.
3907 # Flush last block.
3901 if activeaction:
3908 if activeaction:
3902 yield activeaction, blocklines
3909 yield activeaction, blocklines
3903
3910
3904
3911
3905 @command(
3912 @command(
3906 b'debugwireproto',
3913 b'debugwireproto',
3907 [
3914 [
3908 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3915 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3909 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3916 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3910 (
3917 (
3911 b'',
3918 b'',
3912 b'noreadstderr',
3919 b'noreadstderr',
3913 False,
3920 False,
3914 _(b'do not read from stderr of the remote'),
3921 _(b'do not read from stderr of the remote'),
3915 ),
3922 ),
3916 (
3923 (
3917 b'',
3924 b'',
3918 b'nologhandshake',
3925 b'nologhandshake',
3919 False,
3926 False,
3920 _(b'do not log I/O related to the peer handshake'),
3927 _(b'do not log I/O related to the peer handshake'),
3921 ),
3928 ),
3922 ]
3929 ]
3923 + cmdutil.remoteopts,
3930 + cmdutil.remoteopts,
3924 _(b'[PATH]'),
3931 _(b'[PATH]'),
3925 optionalrepo=True,
3932 optionalrepo=True,
3926 )
3933 )
3927 def debugwireproto(ui, repo, path=None, **opts):
3934 def debugwireproto(ui, repo, path=None, **opts):
3928 """send wire protocol commands to a server
3935 """send wire protocol commands to a server
3929
3936
3930 This command can be used to issue wire protocol commands to remote
3937 This command can be used to issue wire protocol commands to remote
3931 peers and to debug the raw data being exchanged.
3938 peers and to debug the raw data being exchanged.
3932
3939
3933 ``--localssh`` will start an SSH server against the current repository
3940 ``--localssh`` will start an SSH server against the current repository
3934 and connect to that. By default, the connection will perform a handshake
3941 and connect to that. By default, the connection will perform a handshake
3935 and establish an appropriate peer instance.
3942 and establish an appropriate peer instance.
3936
3943
3937 ``--peer`` can be used to bypass the handshake protocol and construct a
3944 ``--peer`` can be used to bypass the handshake protocol and construct a
3938 peer instance using the specified class type. Valid values are ``raw``,
3945 peer instance using the specified class type. Valid values are ``raw``,
3939 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3946 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3940 raw data payloads and don't support higher-level command actions.
3947 raw data payloads and don't support higher-level command actions.
3941
3948
3942 ``--noreadstderr`` can be used to disable automatic reading from stderr
3949 ``--noreadstderr`` can be used to disable automatic reading from stderr
3943 of the peer (for SSH connections only). Disabling automatic reading of
3950 of the peer (for SSH connections only). Disabling automatic reading of
3944 stderr is useful for making output more deterministic.
3951 stderr is useful for making output more deterministic.
3945
3952
3946 Commands are issued via a mini language which is specified via stdin.
3953 Commands are issued via a mini language which is specified via stdin.
3947 The language consists of individual actions to perform. An action is
3954 The language consists of individual actions to perform. An action is
3948 defined by a block. A block is defined as a line with no leading
3955 defined by a block. A block is defined as a line with no leading
3949 space followed by 0 or more lines with leading space. Blocks are
3956 space followed by 0 or more lines with leading space. Blocks are
3950 effectively a high-level command with additional metadata.
3957 effectively a high-level command with additional metadata.
3951
3958
3952 Lines beginning with ``#`` are ignored.
3959 Lines beginning with ``#`` are ignored.
3953
3960
3954 The following sections denote available actions.
3961 The following sections denote available actions.
3955
3962
3956 raw
3963 raw
3957 ---
3964 ---
3958
3965
3959 Send raw data to the server.
3966 Send raw data to the server.
3960
3967
3961 The block payload contains the raw data to send as one atomic send
3968 The block payload contains the raw data to send as one atomic send
3962 operation. The data may not actually be delivered in a single system
3969 operation. The data may not actually be delivered in a single system
3963 call: it depends on the abilities of the transport being used.
3970 call: it depends on the abilities of the transport being used.
3964
3971
3965 Each line in the block is de-indented and concatenated. Then, that
3972 Each line in the block is de-indented and concatenated. Then, that
3966 value is evaluated as a Python b'' literal. This allows the use of
3973 value is evaluated as a Python b'' literal. This allows the use of
3967 backslash escaping, etc.
3974 backslash escaping, etc.
3968
3975
3969 raw+
3976 raw+
3970 ----
3977 ----
3971
3978
3972 Behaves like ``raw`` except flushes output afterwards.
3979 Behaves like ``raw`` except flushes output afterwards.
3973
3980
3974 command <X>
3981 command <X>
3975 -----------
3982 -----------
3976
3983
3977 Send a request to run a named command, whose name follows the ``command``
3984 Send a request to run a named command, whose name follows the ``command``
3978 string.
3985 string.
3979
3986
3980 Arguments to the command are defined as lines in this block. The format of
3987 Arguments to the command are defined as lines in this block. The format of
3981 each line is ``<key> <value>``. e.g.::
3988 each line is ``<key> <value>``. e.g.::
3982
3989
3983 command listkeys
3990 command listkeys
3984 namespace bookmarks
3991 namespace bookmarks
3985
3992
3986 If the value begins with ``eval:``, it will be interpreted as a Python
3993 If the value begins with ``eval:``, it will be interpreted as a Python
3987 literal expression. Otherwise values are interpreted as Python b'' literals.
3994 literal expression. Otherwise values are interpreted as Python b'' literals.
3988 This allows sending complex types and encoding special byte sequences via
3995 This allows sending complex types and encoding special byte sequences via
3989 backslash escaping.
3996 backslash escaping.
3990
3997
3991 The following arguments have special meaning:
3998 The following arguments have special meaning:
3992
3999
3993 ``PUSHFILE``
4000 ``PUSHFILE``
3994 When defined, the *push* mechanism of the peer will be used instead
4001 When defined, the *push* mechanism of the peer will be used instead
3995 of the static request-response mechanism and the content of the
4002 of the static request-response mechanism and the content of the
3996 file specified in the value of this argument will be sent as the
4003 file specified in the value of this argument will be sent as the
3997 command payload.
4004 command payload.
3998
4005
3999 This can be used to submit a local bundle file to the remote.
4006 This can be used to submit a local bundle file to the remote.
4000
4007
4001 batchbegin
4008 batchbegin
4002 ----------
4009 ----------
4003
4010
4004 Instruct the peer to begin a batched send.
4011 Instruct the peer to begin a batched send.
4005
4012
4006 All ``command`` blocks are queued for execution until the next
4013 All ``command`` blocks are queued for execution until the next
4007 ``batchsubmit`` block.
4014 ``batchsubmit`` block.
4008
4015
4009 batchsubmit
4016 batchsubmit
4010 -----------
4017 -----------
4011
4018
4012 Submit previously queued ``command`` blocks as a batch request.
4019 Submit previously queued ``command`` blocks as a batch request.
4013
4020
4014 This action MUST be paired with a ``batchbegin`` action.
4021 This action MUST be paired with a ``batchbegin`` action.
4015
4022
4016 httprequest <method> <path>
4023 httprequest <method> <path>
4017 ---------------------------
4024 ---------------------------
4018
4025
4019 (HTTP peer only)
4026 (HTTP peer only)
4020
4027
4021 Send an HTTP request to the peer.
4028 Send an HTTP request to the peer.
4022
4029
4023 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
4030 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
4024
4031
4025 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
4032 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
4026 headers to add to the request. e.g. ``Accept: foo``.
4033 headers to add to the request. e.g. ``Accept: foo``.
4027
4034
4028 The following arguments are special:
4035 The following arguments are special:
4029
4036
4030 ``BODYFILE``
4037 ``BODYFILE``
4031 The content of the file defined as the value to this argument will be
4038 The content of the file defined as the value to this argument will be
4032 transferred verbatim as the HTTP request body.
4039 transferred verbatim as the HTTP request body.
4033
4040
4034 ``frame <type> <flags> <payload>``
4041 ``frame <type> <flags> <payload>``
4035 Send a unified protocol frame as part of the request body.
4042 Send a unified protocol frame as part of the request body.
4036
4043
4037 All frames will be collected and sent as the body to the HTTP
4044 All frames will be collected and sent as the body to the HTTP
4038 request.
4045 request.
4039
4046
4040 close
4047 close
4041 -----
4048 -----
4042
4049
4043 Close the connection to the server.
4050 Close the connection to the server.
4044
4051
4045 flush
4052 flush
4046 -----
4053 -----
4047
4054
4048 Flush data written to the server.
4055 Flush data written to the server.
4049
4056
4050 readavailable
4057 readavailable
4051 -------------
4058 -------------
4052
4059
4053 Close the write end of the connection and read all available data from
4060 Close the write end of the connection and read all available data from
4054 the server.
4061 the server.
4055
4062
4056 If the connection to the server encompasses multiple pipes, we poll both
4063 If the connection to the server encompasses multiple pipes, we poll both
4057 pipes and read available data.
4064 pipes and read available data.
4058
4065
4059 readline
4066 readline
4060 --------
4067 --------
4061
4068
4062 Read a line of output from the server. If there are multiple output
4069 Read a line of output from the server. If there are multiple output
4063 pipes, reads only the main pipe.
4070 pipes, reads only the main pipe.
4064
4071
4065 ereadline
4072 ereadline
4066 ---------
4073 ---------
4067
4074
4068 Like ``readline``, but read from the stderr pipe, if available.
4075 Like ``readline``, but read from the stderr pipe, if available.
4069
4076
4070 read <X>
4077 read <X>
4071 --------
4078 --------
4072
4079
4073 ``read()`` N bytes from the server's main output pipe.
4080 ``read()`` N bytes from the server's main output pipe.
4074
4081
4075 eread <X>
4082 eread <X>
4076 ---------
4083 ---------
4077
4084
4078 ``read()`` N bytes from the server's stderr pipe, if available.
4085 ``read()`` N bytes from the server's stderr pipe, if available.
4079
4086
4080 Specifying Unified Frame-Based Protocol Frames
4087 Specifying Unified Frame-Based Protocol Frames
4081 ----------------------------------------------
4088 ----------------------------------------------
4082
4089
4083 It is possible to emit a *Unified Frame-Based Protocol* by using special
4090 It is possible to emit a *Unified Frame-Based Protocol* by using special
4084 syntax.
4091 syntax.
4085
4092
4086 A frame is composed as a type, flags, and payload. These can be parsed
4093 A frame is composed as a type, flags, and payload. These can be parsed
4087 from a string of the form:
4094 from a string of the form:
4088
4095
4089 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
4096 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
4090
4097
4091 ``request-id`` and ``stream-id`` are integers defining the request and
4098 ``request-id`` and ``stream-id`` are integers defining the request and
4092 stream identifiers.
4099 stream identifiers.
4093
4100
4094 ``type`` can be an integer value for the frame type or the string name
4101 ``type`` can be an integer value for the frame type or the string name
4095 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
4102 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
4096 ``command-name``.
4103 ``command-name``.
4097
4104
4098 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
4105 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
4099 components. Each component (and there can be just one) can be an integer
4106 components. Each component (and there can be just one) can be an integer
4100 or a flag name for stream flags or frame flags, respectively. Values are
4107 or a flag name for stream flags or frame flags, respectively. Values are
4101 resolved to integers and then bitwise OR'd together.
4108 resolved to integers and then bitwise OR'd together.
4102
4109
4103 ``payload`` represents the raw frame payload. If it begins with
4110 ``payload`` represents the raw frame payload. If it begins with
4104 ``cbor:``, the following string is evaluated as Python code and the
4111 ``cbor:``, the following string is evaluated as Python code and the
4105 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
4112 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
4106 as a Python byte string literal.
4113 as a Python byte string literal.
4107 """
4114 """
4108 opts = pycompat.byteskwargs(opts)
4115 opts = pycompat.byteskwargs(opts)
4109
4116
4110 if opts[b'localssh'] and not repo:
4117 if opts[b'localssh'] and not repo:
4111 raise error.Abort(_(b'--localssh requires a repository'))
4118 raise error.Abort(_(b'--localssh requires a repository'))
4112
4119
4113 if opts[b'peer'] and opts[b'peer'] not in (
4120 if opts[b'peer'] and opts[b'peer'] not in (
4114 b'raw',
4121 b'raw',
4115 b'http2',
4122 b'http2',
4116 b'ssh1',
4123 b'ssh1',
4117 b'ssh2',
4124 b'ssh2',
4118 ):
4125 ):
4119 raise error.Abort(
4126 raise error.Abort(
4120 _(b'invalid value for --peer'),
4127 _(b'invalid value for --peer'),
4121 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
4128 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
4122 )
4129 )
4123
4130
4124 if path and opts[b'localssh']:
4131 if path and opts[b'localssh']:
4125 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
4132 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
4126
4133
4127 if ui.interactive():
4134 if ui.interactive():
4128 ui.write(_(b'(waiting for commands on stdin)\n'))
4135 ui.write(_(b'(waiting for commands on stdin)\n'))
4129
4136
4130 blocks = list(_parsewirelangblocks(ui.fin))
4137 blocks = list(_parsewirelangblocks(ui.fin))
4131
4138
4132 proc = None
4139 proc = None
4133 stdin = None
4140 stdin = None
4134 stdout = None
4141 stdout = None
4135 stderr = None
4142 stderr = None
4136 opener = None
4143 opener = None
4137
4144
4138 if opts[b'localssh']:
4145 if opts[b'localssh']:
4139 # We start the SSH server in its own process so there is process
4146 # We start the SSH server in its own process so there is process
4140 # separation. This prevents a whole class of potential bugs around
4147 # separation. This prevents a whole class of potential bugs around
4141 # shared state from interfering with server operation.
4148 # shared state from interfering with server operation.
4142 args = procutil.hgcmd() + [
4149 args = procutil.hgcmd() + [
4143 b'-R',
4150 b'-R',
4144 repo.root,
4151 repo.root,
4145 b'debugserve',
4152 b'debugserve',
4146 b'--sshstdio',
4153 b'--sshstdio',
4147 ]
4154 ]
4148 proc = subprocess.Popen(
4155 proc = subprocess.Popen(
4149 pycompat.rapply(procutil.tonativestr, args),
4156 pycompat.rapply(procutil.tonativestr, args),
4150 stdin=subprocess.PIPE,
4157 stdin=subprocess.PIPE,
4151 stdout=subprocess.PIPE,
4158 stdout=subprocess.PIPE,
4152 stderr=subprocess.PIPE,
4159 stderr=subprocess.PIPE,
4153 bufsize=0,
4160 bufsize=0,
4154 )
4161 )
4155
4162
4156 stdin = proc.stdin
4163 stdin = proc.stdin
4157 stdout = proc.stdout
4164 stdout = proc.stdout
4158 stderr = proc.stderr
4165 stderr = proc.stderr
4159
4166
4160 # We turn the pipes into observers so we can log I/O.
4167 # We turn the pipes into observers so we can log I/O.
4161 if ui.verbose or opts[b'peer'] == b'raw':
4168 if ui.verbose or opts[b'peer'] == b'raw':
4162 stdin = util.makeloggingfileobject(
4169 stdin = util.makeloggingfileobject(
4163 ui, proc.stdin, b'i', logdata=True
4170 ui, proc.stdin, b'i', logdata=True
4164 )
4171 )
4165 stdout = util.makeloggingfileobject(
4172 stdout = util.makeloggingfileobject(
4166 ui, proc.stdout, b'o', logdata=True
4173 ui, proc.stdout, b'o', logdata=True
4167 )
4174 )
4168 stderr = util.makeloggingfileobject(
4175 stderr = util.makeloggingfileobject(
4169 ui, proc.stderr, b'e', logdata=True
4176 ui, proc.stderr, b'e', logdata=True
4170 )
4177 )
4171
4178
4172 # --localssh also implies the peer connection settings.
4179 # --localssh also implies the peer connection settings.
4173
4180
4174 url = b'ssh://localserver'
4181 url = b'ssh://localserver'
4175 autoreadstderr = not opts[b'noreadstderr']
4182 autoreadstderr = not opts[b'noreadstderr']
4176
4183
4177 if opts[b'peer'] == b'ssh1':
4184 if opts[b'peer'] == b'ssh1':
4178 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4185 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4179 peer = sshpeer.sshv1peer(
4186 peer = sshpeer.sshv1peer(
4180 ui,
4187 ui,
4181 url,
4188 url,
4182 proc,
4189 proc,
4183 stdin,
4190 stdin,
4184 stdout,
4191 stdout,
4185 stderr,
4192 stderr,
4186 None,
4193 None,
4187 autoreadstderr=autoreadstderr,
4194 autoreadstderr=autoreadstderr,
4188 )
4195 )
4189 elif opts[b'peer'] == b'ssh2':
4196 elif opts[b'peer'] == b'ssh2':
4190 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
4197 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
4191 peer = sshpeer.sshv2peer(
4198 peer = sshpeer.sshv2peer(
4192 ui,
4199 ui,
4193 url,
4200 url,
4194 proc,
4201 proc,
4195 stdin,
4202 stdin,
4196 stdout,
4203 stdout,
4197 stderr,
4204 stderr,
4198 None,
4205 None,
4199 autoreadstderr=autoreadstderr,
4206 autoreadstderr=autoreadstderr,
4200 )
4207 )
4201 elif opts[b'peer'] == b'raw':
4208 elif opts[b'peer'] == b'raw':
4202 ui.write(_(b'using raw connection to peer\n'))
4209 ui.write(_(b'using raw connection to peer\n'))
4203 peer = None
4210 peer = None
4204 else:
4211 else:
4205 ui.write(_(b'creating ssh peer from handshake results\n'))
4212 ui.write(_(b'creating ssh peer from handshake results\n'))
4206 peer = sshpeer.makepeer(
4213 peer = sshpeer.makepeer(
4207 ui,
4214 ui,
4208 url,
4215 url,
4209 proc,
4216 proc,
4210 stdin,
4217 stdin,
4211 stdout,
4218 stdout,
4212 stderr,
4219 stderr,
4213 autoreadstderr=autoreadstderr,
4220 autoreadstderr=autoreadstderr,
4214 )
4221 )
4215
4222
4216 elif path:
4223 elif path:
4217 # We bypass hg.peer() so we can proxy the sockets.
4224 # We bypass hg.peer() so we can proxy the sockets.
4218 # TODO consider not doing this because we skip
4225 # TODO consider not doing this because we skip
4219 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4226 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4220 u = util.url(path)
4227 u = util.url(path)
4221 if u.scheme != b'http':
4228 if u.scheme != b'http':
4222 raise error.Abort(_(b'only http:// paths are currently supported'))
4229 raise error.Abort(_(b'only http:// paths are currently supported'))
4223
4230
4224 url, authinfo = u.authinfo()
4231 url, authinfo = u.authinfo()
4225 openerargs = {
4232 openerargs = {
4226 'useragent': b'Mercurial debugwireproto',
4233 'useragent': b'Mercurial debugwireproto',
4227 }
4234 }
4228
4235
4229 # Turn pipes/sockets into observers so we can log I/O.
4236 # Turn pipes/sockets into observers so we can log I/O.
4230 if ui.verbose:
4237 if ui.verbose:
4231 openerargs.update(
4238 openerargs.update(
4232 {
4239 {
4233 'loggingfh': ui,
4240 'loggingfh': ui,
4234 'loggingname': b's',
4241 'loggingname': b's',
4235 'loggingopts': {'logdata': True, 'logdataapis': False,},
4242 'loggingopts': {'logdata': True, 'logdataapis': False,},
4236 }
4243 }
4237 )
4244 )
4238
4245
4239 if ui.debugflag:
4246 if ui.debugflag:
4240 openerargs['loggingopts']['logdataapis'] = True
4247 openerargs['loggingopts']['logdataapis'] = True
4241
4248
4242 # Don't send default headers when in raw mode. This allows us to
4249 # Don't send default headers when in raw mode. This allows us to
4243 # bypass most of the behavior of our URL handling code so we can
4250 # bypass most of the behavior of our URL handling code so we can
4244 # have near complete control over what's sent on the wire.
4251 # have near complete control over what's sent on the wire.
4245 if opts[b'peer'] == b'raw':
4252 if opts[b'peer'] == b'raw':
4246 openerargs['sendaccept'] = False
4253 openerargs['sendaccept'] = False
4247
4254
4248 opener = urlmod.opener(ui, authinfo, **openerargs)
4255 opener = urlmod.opener(ui, authinfo, **openerargs)
4249
4256
4250 if opts[b'peer'] == b'http2':
4257 if opts[b'peer'] == b'http2':
4251 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4258 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4252 # We go through makepeer() because we need an API descriptor for
4259 # We go through makepeer() because we need an API descriptor for
4253 # the peer instance to be useful.
4260 # the peer instance to be useful.
4254 with ui.configoverride(
4261 with ui.configoverride(
4255 {(b'experimental', b'httppeer.advertise-v2'): True}
4262 {(b'experimental', b'httppeer.advertise-v2'): True}
4256 ):
4263 ):
4257 if opts[b'nologhandshake']:
4264 if opts[b'nologhandshake']:
4258 ui.pushbuffer()
4265 ui.pushbuffer()
4259
4266
4260 peer = httppeer.makepeer(ui, path, opener=opener)
4267 peer = httppeer.makepeer(ui, path, opener=opener)
4261
4268
4262 if opts[b'nologhandshake']:
4269 if opts[b'nologhandshake']:
4263 ui.popbuffer()
4270 ui.popbuffer()
4264
4271
4265 if not isinstance(peer, httppeer.httpv2peer):
4272 if not isinstance(peer, httppeer.httpv2peer):
4266 raise error.Abort(
4273 raise error.Abort(
4267 _(
4274 _(
4268 b'could not instantiate HTTP peer for '
4275 b'could not instantiate HTTP peer for '
4269 b'wire protocol version 2'
4276 b'wire protocol version 2'
4270 ),
4277 ),
4271 hint=_(
4278 hint=_(
4272 b'the server may not have the feature '
4279 b'the server may not have the feature '
4273 b'enabled or is not allowing this '
4280 b'enabled or is not allowing this '
4274 b'client version'
4281 b'client version'
4275 ),
4282 ),
4276 )
4283 )
4277
4284
4278 elif opts[b'peer'] == b'raw':
4285 elif opts[b'peer'] == b'raw':
4279 ui.write(_(b'using raw connection to peer\n'))
4286 ui.write(_(b'using raw connection to peer\n'))
4280 peer = None
4287 peer = None
4281 elif opts[b'peer']:
4288 elif opts[b'peer']:
4282 raise error.Abort(
4289 raise error.Abort(
4283 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4290 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4284 )
4291 )
4285 else:
4292 else:
4286 peer = httppeer.makepeer(ui, path, opener=opener)
4293 peer = httppeer.makepeer(ui, path, opener=opener)
4287
4294
4288 # We /could/ populate stdin/stdout with sock.makefile()...
4295 # We /could/ populate stdin/stdout with sock.makefile()...
4289 else:
4296 else:
4290 raise error.Abort(_(b'unsupported connection configuration'))
4297 raise error.Abort(_(b'unsupported connection configuration'))
4291
4298
4292 batchedcommands = None
4299 batchedcommands = None
4293
4300
4294 # Now perform actions based on the parsed wire language instructions.
4301 # Now perform actions based on the parsed wire language instructions.
4295 for action, lines in blocks:
4302 for action, lines in blocks:
4296 if action in (b'raw', b'raw+'):
4303 if action in (b'raw', b'raw+'):
4297 if not stdin:
4304 if not stdin:
4298 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4305 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4299
4306
4300 # Concatenate the data together.
4307 # Concatenate the data together.
4301 data = b''.join(l.lstrip() for l in lines)
4308 data = b''.join(l.lstrip() for l in lines)
4302 data = stringutil.unescapestr(data)
4309 data = stringutil.unescapestr(data)
4303 stdin.write(data)
4310 stdin.write(data)
4304
4311
4305 if action == b'raw+':
4312 if action == b'raw+':
4306 stdin.flush()
4313 stdin.flush()
4307 elif action == b'flush':
4314 elif action == b'flush':
4308 if not stdin:
4315 if not stdin:
4309 raise error.Abort(_(b'cannot call flush on this peer'))
4316 raise error.Abort(_(b'cannot call flush on this peer'))
4310 stdin.flush()
4317 stdin.flush()
4311 elif action.startswith(b'command'):
4318 elif action.startswith(b'command'):
4312 if not peer:
4319 if not peer:
4313 raise error.Abort(
4320 raise error.Abort(
4314 _(
4321 _(
4315 b'cannot send commands unless peer instance '
4322 b'cannot send commands unless peer instance '
4316 b'is available'
4323 b'is available'
4317 )
4324 )
4318 )
4325 )
4319
4326
4320 command = action.split(b' ', 1)[1]
4327 command = action.split(b' ', 1)[1]
4321
4328
4322 args = {}
4329 args = {}
4323 for line in lines:
4330 for line in lines:
4324 # We need to allow empty values.
4331 # We need to allow empty values.
4325 fields = line.lstrip().split(b' ', 1)
4332 fields = line.lstrip().split(b' ', 1)
4326 if len(fields) == 1:
4333 if len(fields) == 1:
4327 key = fields[0]
4334 key = fields[0]
4328 value = b''
4335 value = b''
4329 else:
4336 else:
4330 key, value = fields
4337 key, value = fields
4331
4338
4332 if value.startswith(b'eval:'):
4339 if value.startswith(b'eval:'):
4333 value = stringutil.evalpythonliteral(value[5:])
4340 value = stringutil.evalpythonliteral(value[5:])
4334 else:
4341 else:
4335 value = stringutil.unescapestr(value)
4342 value = stringutil.unescapestr(value)
4336
4343
4337 args[key] = value
4344 args[key] = value
4338
4345
4339 if batchedcommands is not None:
4346 if batchedcommands is not None:
4340 batchedcommands.append((command, args))
4347 batchedcommands.append((command, args))
4341 continue
4348 continue
4342
4349
4343 ui.status(_(b'sending %s command\n') % command)
4350 ui.status(_(b'sending %s command\n') % command)
4344
4351
4345 if b'PUSHFILE' in args:
4352 if b'PUSHFILE' in args:
4346 with open(args[b'PUSHFILE'], 'rb') as fh:
4353 with open(args[b'PUSHFILE'], 'rb') as fh:
4347 del args[b'PUSHFILE']
4354 del args[b'PUSHFILE']
4348 res, output = peer._callpush(
4355 res, output = peer._callpush(
4349 command, fh, **pycompat.strkwargs(args)
4356 command, fh, **pycompat.strkwargs(args)
4350 )
4357 )
4351 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4358 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4352 ui.status(
4359 ui.status(
4353 _(b'remote output: %s\n') % stringutil.escapestr(output)
4360 _(b'remote output: %s\n') % stringutil.escapestr(output)
4354 )
4361 )
4355 else:
4362 else:
4356 with peer.commandexecutor() as e:
4363 with peer.commandexecutor() as e:
4357 res = e.callcommand(command, args).result()
4364 res = e.callcommand(command, args).result()
4358
4365
4359 if isinstance(res, wireprotov2peer.commandresponse):
4366 if isinstance(res, wireprotov2peer.commandresponse):
4360 val = res.objects()
4367 val = res.objects()
4361 ui.status(
4368 ui.status(
4362 _(b'response: %s\n')
4369 _(b'response: %s\n')
4363 % stringutil.pprint(val, bprefix=True, indent=2)
4370 % stringutil.pprint(val, bprefix=True, indent=2)
4364 )
4371 )
4365 else:
4372 else:
4366 ui.status(
4373 ui.status(
4367 _(b'response: %s\n')
4374 _(b'response: %s\n')
4368 % stringutil.pprint(res, bprefix=True, indent=2)
4375 % stringutil.pprint(res, bprefix=True, indent=2)
4369 )
4376 )
4370
4377
4371 elif action == b'batchbegin':
4378 elif action == b'batchbegin':
4372 if batchedcommands is not None:
4379 if batchedcommands is not None:
4373 raise error.Abort(_(b'nested batchbegin not allowed'))
4380 raise error.Abort(_(b'nested batchbegin not allowed'))
4374
4381
4375 batchedcommands = []
4382 batchedcommands = []
4376 elif action == b'batchsubmit':
4383 elif action == b'batchsubmit':
4377 # There is a batching API we could go through. But it would be
4384 # There is a batching API we could go through. But it would be
4378 # difficult to normalize requests into function calls. It is easier
4385 # difficult to normalize requests into function calls. It is easier
4379 # to bypass this layer and normalize to commands + args.
4386 # to bypass this layer and normalize to commands + args.
4380 ui.status(
4387 ui.status(
4381 _(b'sending batch with %d sub-commands\n')
4388 _(b'sending batch with %d sub-commands\n')
4382 % len(batchedcommands)
4389 % len(batchedcommands)
4383 )
4390 )
4384 assert peer is not None
4391 assert peer is not None
4385 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4392 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4386 ui.status(
4393 ui.status(
4387 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4394 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4388 )
4395 )
4389
4396
4390 batchedcommands = None
4397 batchedcommands = None
4391
4398
4392 elif action.startswith(b'httprequest '):
4399 elif action.startswith(b'httprequest '):
4393 if not opener:
4400 if not opener:
4394 raise error.Abort(
4401 raise error.Abort(
4395 _(b'cannot use httprequest without an HTTP peer')
4402 _(b'cannot use httprequest without an HTTP peer')
4396 )
4403 )
4397
4404
4398 request = action.split(b' ', 2)
4405 request = action.split(b' ', 2)
4399 if len(request) != 3:
4406 if len(request) != 3:
4400 raise error.Abort(
4407 raise error.Abort(
4401 _(
4408 _(
4402 b'invalid httprequest: expected format is '
4409 b'invalid httprequest: expected format is '
4403 b'"httprequest <method> <path>'
4410 b'"httprequest <method> <path>'
4404 )
4411 )
4405 )
4412 )
4406
4413
4407 method, httppath = request[1:]
4414 method, httppath = request[1:]
4408 headers = {}
4415 headers = {}
4409 body = None
4416 body = None
4410 frames = []
4417 frames = []
4411 for line in lines:
4418 for line in lines:
4412 line = line.lstrip()
4419 line = line.lstrip()
4413 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4420 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4414 if m:
4421 if m:
4415 # Headers need to use native strings.
4422 # Headers need to use native strings.
4416 key = pycompat.strurl(m.group(1))
4423 key = pycompat.strurl(m.group(1))
4417 value = pycompat.strurl(m.group(2))
4424 value = pycompat.strurl(m.group(2))
4418 headers[key] = value
4425 headers[key] = value
4419 continue
4426 continue
4420
4427
4421 if line.startswith(b'BODYFILE '):
4428 if line.startswith(b'BODYFILE '):
4422 with open(line.split(b' ', 1), b'rb') as fh:
4429 with open(line.split(b' ', 1), b'rb') as fh:
4423 body = fh.read()
4430 body = fh.read()
4424 elif line.startswith(b'frame '):
4431 elif line.startswith(b'frame '):
4425 frame = wireprotoframing.makeframefromhumanstring(
4432 frame = wireprotoframing.makeframefromhumanstring(
4426 line[len(b'frame ') :]
4433 line[len(b'frame ') :]
4427 )
4434 )
4428
4435
4429 frames.append(frame)
4436 frames.append(frame)
4430 else:
4437 else:
4431 raise error.Abort(
4438 raise error.Abort(
4432 _(b'unknown argument to httprequest: %s') % line
4439 _(b'unknown argument to httprequest: %s') % line
4433 )
4440 )
4434
4441
4435 url = path + httppath
4442 url = path + httppath
4436
4443
4437 if frames:
4444 if frames:
4438 body = b''.join(bytes(f) for f in frames)
4445 body = b''.join(bytes(f) for f in frames)
4439
4446
4440 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4447 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4441
4448
4442 # urllib.Request insists on using has_data() as a proxy for
4449 # urllib.Request insists on using has_data() as a proxy for
4443 # determining the request method. Override that to use our
4450 # determining the request method. Override that to use our
4444 # explicitly requested method.
4451 # explicitly requested method.
4445 req.get_method = lambda: pycompat.sysstr(method)
4452 req.get_method = lambda: pycompat.sysstr(method)
4446
4453
4447 try:
4454 try:
4448 res = opener.open(req)
4455 res = opener.open(req)
4449 body = res.read()
4456 body = res.read()
4450 except util.urlerr.urlerror as e:
4457 except util.urlerr.urlerror as e:
4451 # read() method must be called, but only exists in Python 2
4458 # read() method must be called, but only exists in Python 2
4452 getattr(e, 'read', lambda: None)()
4459 getattr(e, 'read', lambda: None)()
4453 continue
4460 continue
4454
4461
4455 ct = res.headers.get('Content-Type')
4462 ct = res.headers.get('Content-Type')
4456 if ct == 'application/mercurial-cbor':
4463 if ct == 'application/mercurial-cbor':
4457 ui.write(
4464 ui.write(
4458 _(b'cbor> %s\n')
4465 _(b'cbor> %s\n')
4459 % stringutil.pprint(
4466 % stringutil.pprint(
4460 cborutil.decodeall(body), bprefix=True, indent=2
4467 cborutil.decodeall(body), bprefix=True, indent=2
4461 )
4468 )
4462 )
4469 )
4463
4470
4464 elif action == b'close':
4471 elif action == b'close':
4465 assert peer is not None
4472 assert peer is not None
4466 peer.close()
4473 peer.close()
4467 elif action == b'readavailable':
4474 elif action == b'readavailable':
4468 if not stdout or not stderr:
4475 if not stdout or not stderr:
4469 raise error.Abort(
4476 raise error.Abort(
4470 _(b'readavailable not available on this peer')
4477 _(b'readavailable not available on this peer')
4471 )
4478 )
4472
4479
4473 stdin.close()
4480 stdin.close()
4474 stdout.read()
4481 stdout.read()
4475 stderr.read()
4482 stderr.read()
4476
4483
4477 elif action == b'readline':
4484 elif action == b'readline':
4478 if not stdout:
4485 if not stdout:
4479 raise error.Abort(_(b'readline not available on this peer'))
4486 raise error.Abort(_(b'readline not available on this peer'))
4480 stdout.readline()
4487 stdout.readline()
4481 elif action == b'ereadline':
4488 elif action == b'ereadline':
4482 if not stderr:
4489 if not stderr:
4483 raise error.Abort(_(b'ereadline not available on this peer'))
4490 raise error.Abort(_(b'ereadline not available on this peer'))
4484 stderr.readline()
4491 stderr.readline()
4485 elif action.startswith(b'read '):
4492 elif action.startswith(b'read '):
4486 count = int(action.split(b' ', 1)[1])
4493 count = int(action.split(b' ', 1)[1])
4487 if not stdout:
4494 if not stdout:
4488 raise error.Abort(_(b'read not available on this peer'))
4495 raise error.Abort(_(b'read not available on this peer'))
4489 stdout.read(count)
4496 stdout.read(count)
4490 elif action.startswith(b'eread '):
4497 elif action.startswith(b'eread '):
4491 count = int(action.split(b' ', 1)[1])
4498 count = int(action.split(b' ', 1)[1])
4492 if not stderr:
4499 if not stderr:
4493 raise error.Abort(_(b'eread not available on this peer'))
4500 raise error.Abort(_(b'eread not available on this peer'))
4494 stderr.read(count)
4501 stderr.read(count)
4495 else:
4502 else:
4496 raise error.Abort(_(b'unknown action: %s') % action)
4503 raise error.Abort(_(b'unknown action: %s') % action)
4497
4504
4498 if batchedcommands is not None:
4505 if batchedcommands is not None:
4499 raise error.Abort(_(b'unclosed "batchbegin" request'))
4506 raise error.Abort(_(b'unclosed "batchbegin" request'))
4500
4507
4501 if peer:
4508 if peer:
4502 peer.close()
4509 peer.close()
4503
4510
4504 if proc:
4511 if proc:
4505 proc.kill()
4512 proc.kill()
@@ -1,431 +1,433
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 debugbackupbundle
79 debugbuilddag
79 debugbuilddag
80 debugbundle
80 debugbundle
81 debugcapabilities
81 debugcapabilities
82 debugcheckstate
82 debugcheckstate
83 debugcolor
83 debugcolor
84 debugcommands
84 debugcommands
85 debugcomplete
85 debugcomplete
86 debugconfig
86 debugconfig
87 debugcreatestreamclonebundle
87 debugcreatestreamclonebundle
88 debugdag
88 debugdag
89 debugdata
89 debugdata
90 debugdate
90 debugdate
91 debugdeltachain
91 debugdeltachain
92 debugdirstate
92 debugdirstate
93 debugdiscovery
93 debugdiscovery
94 debugdownload
94 debugdownload
95 debugextensions
95 debugextensions
96 debugfileset
96 debugfileset
97 debugformat
97 debugformat
98 debugfsinfo
98 debugfsinfo
99 debuggetbundle
99 debuggetbundle
100 debugignore
100 debugignore
101 debugindex
101 debugindex
102 debugindexdot
102 debugindexdot
103 debugindexstats
103 debugindexstats
104 debuginstall
104 debuginstall
105 debugknown
105 debugknown
106 debuglabelcomplete
106 debuglabelcomplete
107 debuglocks
107 debuglocks
108 debugmanifestfulltextcache
108 debugmanifestfulltextcache
109 debugmergestate
109 debugmergestate
110 debugnamecomplete
110 debugnamecomplete
111 debugnodemap
111 debugnodemap
112 debugobsolete
112 debugobsolete
113 debugp1copies
113 debugp1copies
114 debugp2copies
114 debugp2copies
115 debugpathcomplete
115 debugpathcomplete
116 debugpathcopies
116 debugpathcopies
117 debugpeer
117 debugpeer
118 debugpickmergetool
118 debugpickmergetool
119 debugpushkey
119 debugpushkey
120 debugpvec
120 debugpvec
121 debugrebuilddirstate
121 debugrebuilddirstate
122 debugrebuildfncache
122 debugrebuildfncache
123 debugrename
123 debugrename
124 debugrequires
124 debugrevlog
125 debugrevlog
125 debugrevlogindex
126 debugrevlogindex
126 debugrevspec
127 debugrevspec
127 debugserve
128 debugserve
128 debugsetparents
129 debugsetparents
129 debugsidedata
130 debugsidedata
130 debugssl
131 debugssl
131 debugsub
132 debugsub
132 debugsuccessorssets
133 debugsuccessorssets
133 debugtagscache
134 debugtagscache
134 debugtemplate
135 debugtemplate
135 debuguigetpass
136 debuguigetpass
136 debuguiprompt
137 debuguiprompt
137 debugupdatecaches
138 debugupdatecaches
138 debugupgraderepo
139 debugupgraderepo
139 debugwalk
140 debugwalk
140 debugwhyunstable
141 debugwhyunstable
141 debugwireargs
142 debugwireargs
142 debugwireproto
143 debugwireproto
143
144
144 Do not show the alias of a debug command if there are other candidates
145 Do not show the alias of a debug command if there are other candidates
145 (this should hide rawcommit)
146 (this should hide rawcommit)
146 $ hg debugcomplete r
147 $ hg debugcomplete r
147 recover
148 recover
148 remove
149 remove
149 rename
150 rename
150 resolve
151 resolve
151 revert
152 revert
152 rollback
153 rollback
153 root
154 root
154 Show the alias of a debug command if there are no other candidates
155 Show the alias of a debug command if there are no other candidates
155 $ hg debugcomplete rawc
156 $ hg debugcomplete rawc
156
157
157
158
158 Show the global options
159 Show the global options
159 $ hg debugcomplete --options | sort
160 $ hg debugcomplete --options | sort
160 --color
161 --color
161 --config
162 --config
162 --cwd
163 --cwd
163 --debug
164 --debug
164 --debugger
165 --debugger
165 --encoding
166 --encoding
166 --encodingmode
167 --encodingmode
167 --help
168 --help
168 --hidden
169 --hidden
169 --noninteractive
170 --noninteractive
170 --pager
171 --pager
171 --profile
172 --profile
172 --quiet
173 --quiet
173 --repository
174 --repository
174 --time
175 --time
175 --traceback
176 --traceback
176 --verbose
177 --verbose
177 --version
178 --version
178 -R
179 -R
179 -h
180 -h
180 -q
181 -q
181 -v
182 -v
182 -y
183 -y
183
184
184 Show the options for the "serve" command
185 Show the options for the "serve" command
185 $ hg debugcomplete --options serve | sort
186 $ hg debugcomplete --options serve | sort
186 --accesslog
187 --accesslog
187 --address
188 --address
188 --certificate
189 --certificate
189 --cmdserver
190 --cmdserver
190 --color
191 --color
191 --config
192 --config
192 --cwd
193 --cwd
193 --daemon
194 --daemon
194 --daemon-postexec
195 --daemon-postexec
195 --debug
196 --debug
196 --debugger
197 --debugger
197 --encoding
198 --encoding
198 --encodingmode
199 --encodingmode
199 --errorlog
200 --errorlog
200 --help
201 --help
201 --hidden
202 --hidden
202 --ipv6
203 --ipv6
203 --name
204 --name
204 --noninteractive
205 --noninteractive
205 --pager
206 --pager
206 --pid-file
207 --pid-file
207 --port
208 --port
208 --prefix
209 --prefix
209 --print-url
210 --print-url
210 --profile
211 --profile
211 --quiet
212 --quiet
212 --repository
213 --repository
213 --stdio
214 --stdio
214 --style
215 --style
215 --subrepos
216 --subrepos
216 --templates
217 --templates
217 --time
218 --time
218 --traceback
219 --traceback
219 --verbose
220 --verbose
220 --version
221 --version
221 --web-conf
222 --web-conf
222 -6
223 -6
223 -A
224 -A
224 -E
225 -E
225 -R
226 -R
226 -S
227 -S
227 -a
228 -a
228 -d
229 -d
229 -h
230 -h
230 -n
231 -n
231 -p
232 -p
232 -q
233 -q
233 -t
234 -t
234 -v
235 -v
235 -y
236 -y
236
237
237 Show an error if we use --options with an ambiguous abbreviation
238 Show an error if we use --options with an ambiguous abbreviation
238 $ hg debugcomplete --options s
239 $ hg debugcomplete --options s
239 hg: command 's' is ambiguous:
240 hg: command 's' is ambiguous:
240 serve shelve showconfig status summary
241 serve shelve showconfig status summary
241 [255]
242 [255]
242
243
243 Show all commands + options
244 Show all commands + options
244 $ hg debugcommands
245 $ hg debugcommands
245 abort: dry-run
246 abort: dry-run
246 add: include, exclude, subrepos, dry-run
247 add: include, exclude, subrepos, dry-run
247 addremove: similarity, subrepos, include, exclude, dry-run
248 addremove: similarity, subrepos, include, exclude, dry-run
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
249 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
249 archive: no-decode, prefix, rev, type, subrepos, include, exclude
250 archive: no-decode, prefix, rev, type, subrepos, include, exclude
250 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
251 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
251 bisect: reset, good, bad, skip, extend, command, noupdate
252 bisect: reset, good, bad, skip, extend, command, noupdate
252 bookmarks: force, rev, delete, rename, inactive, list, template
253 bookmarks: force, rev, delete, rename, inactive, list, template
253 branch: force, clean, rev
254 branch: force, clean, rev
254 branches: active, closed, rev, template
255 branches: active, closed, rev, template
255 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
256 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
256 cat: output, rev, decode, include, exclude, template
257 cat: output, rev, decode, include, exclude, template
257 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
258 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
258 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
259 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
259 config: untrusted, edit, local, global, template
260 config: untrusted, edit, local, global, template
260 continue: dry-run
261 continue: dry-run
261 copy: forget, after, at-rev, force, include, exclude, dry-run
262 copy: forget, after, at-rev, force, include, exclude, dry-run
262 debugancestor:
263 debugancestor:
263 debugapplystreamclonebundle:
264 debugapplystreamclonebundle:
264 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
265 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
265 debugbuilddag: mergeable-file, overwritten-file, new-file
266 debugbuilddag: mergeable-file, overwritten-file, new-file
266 debugbundle: all, part-type, spec
267 debugbundle: all, part-type, spec
267 debugcapabilities:
268 debugcapabilities:
268 debugcheckstate:
269 debugcheckstate:
269 debugcolor: style
270 debugcolor: style
270 debugcommands:
271 debugcommands:
271 debugcomplete: options
272 debugcomplete: options
272 debugcreatestreamclonebundle:
273 debugcreatestreamclonebundle:
273 debugdag: tags, branches, dots, spaces
274 debugdag: tags, branches, dots, spaces
274 debugdata: changelog, manifest, dir
275 debugdata: changelog, manifest, dir
275 debugdate: extended
276 debugdate: extended
276 debugdeltachain: changelog, manifest, dir, template
277 debugdeltachain: changelog, manifest, dir, template
277 debugdirstate: nodates, dates, datesort
278 debugdirstate: nodates, dates, datesort
278 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
279 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
279 debugdownload: output
280 debugdownload: output
280 debugextensions: template
281 debugextensions: template
281 debugfileset: rev, all-files, show-matcher, show-stage
282 debugfileset: rev, all-files, show-matcher, show-stage
282 debugformat: template
283 debugformat: template
283 debugfsinfo:
284 debugfsinfo:
284 debuggetbundle: head, common, type
285 debuggetbundle: head, common, type
285 debugignore:
286 debugignore:
286 debugindex: changelog, manifest, dir, template
287 debugindex: changelog, manifest, dir, template
287 debugindexdot: changelog, manifest, dir
288 debugindexdot: changelog, manifest, dir
288 debugindexstats:
289 debugindexstats:
289 debuginstall: template
290 debuginstall: template
290 debugknown:
291 debugknown:
291 debuglabelcomplete:
292 debuglabelcomplete:
292 debuglocks: force-lock, force-wlock, set-lock, set-wlock
293 debuglocks: force-lock, force-wlock, set-lock, set-wlock
293 debugmanifestfulltextcache: clear, add
294 debugmanifestfulltextcache: clear, add
294 debugmergestate: style, template
295 debugmergestate: style, template
295 debugnamecomplete:
296 debugnamecomplete:
296 debugnodemap: dump-new, dump-disk, check, metadata
297 debugnodemap: dump-new, dump-disk, check, metadata
297 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
298 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
298 debugp1copies: rev
299 debugp1copies: rev
299 debugp2copies: rev
300 debugp2copies: rev
300 debugpathcomplete: full, normal, added, removed
301 debugpathcomplete: full, normal, added, removed
301 debugpathcopies: include, exclude
302 debugpathcopies: include, exclude
302 debugpeer:
303 debugpeer:
303 debugpickmergetool: rev, changedelete, include, exclude, tool
304 debugpickmergetool: rev, changedelete, include, exclude, tool
304 debugpushkey:
305 debugpushkey:
305 debugpvec:
306 debugpvec:
306 debugrebuilddirstate: rev, minimal
307 debugrebuilddirstate: rev, minimal
307 debugrebuildfncache:
308 debugrebuildfncache:
308 debugrename: rev
309 debugrename: rev
310 debugrequires:
309 debugrevlog: changelog, manifest, dir, dump
311 debugrevlog: changelog, manifest, dir, dump
310 debugrevlogindex: changelog, manifest, dir, format
312 debugrevlogindex: changelog, manifest, dir, format
311 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
313 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
312 debugserve: sshstdio, logiofd, logiofile
314 debugserve: sshstdio, logiofd, logiofile
313 debugsetparents:
315 debugsetparents:
314 debugsidedata: changelog, manifest, dir
316 debugsidedata: changelog, manifest, dir
315 debugssl:
317 debugssl:
316 debugsub: rev
318 debugsub: rev
317 debugsuccessorssets: closest
319 debugsuccessorssets: closest
318 debugtagscache:
320 debugtagscache:
319 debugtemplate: rev, define
321 debugtemplate: rev, define
320 debuguigetpass: prompt
322 debuguigetpass: prompt
321 debuguiprompt: prompt
323 debuguiprompt: prompt
322 debugupdatecaches:
324 debugupdatecaches:
323 debugupgraderepo: optimize, run, backup, changelog, manifest
325 debugupgraderepo: optimize, run, backup, changelog, manifest
324 debugwalk: include, exclude
326 debugwalk: include, exclude
325 debugwhyunstable:
327 debugwhyunstable:
326 debugwireargs: three, four, five, ssh, remotecmd, insecure
328 debugwireargs: three, four, five, ssh, remotecmd, insecure
327 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
329 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
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
330 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
329 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
331 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
330 files: rev, print0, include, exclude, template, subrepos
332 files: rev, print0, include, exclude, template, subrepos
331 forget: interactive, include, exclude, dry-run
333 forget: interactive, include, exclude, dry-run
332 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
334 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
333 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
335 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
334 heads: rev, topo, active, closed, style, template
336 heads: rev, topo, active, closed, style, template
335 help: extension, command, keyword, system
337 help: extension, command, keyword, system
336 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
338 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
337 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
339 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
338 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
340 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
339 init: ssh, remotecmd, insecure
341 init: ssh, remotecmd, insecure
340 locate: rev, print0, fullpath, include, exclude
342 locate: rev, print0, fullpath, 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
343 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
342 manifest: rev, all, template
344 manifest: rev, all, template
343 merge: force, rev, preview, abort, tool
345 merge: force, rev, preview, abort, tool
344 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
346 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
345 parents: rev, style, template
347 parents: rev, style, template
346 paths: template
348 paths: template
347 phase: public, draft, secret, force, rev
349 phase: public, draft, secret, force, rev
348 pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure
350 pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure
349 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
351 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
350 recover: verify
352 recover: verify
351 remove: after, force, subrepos, include, exclude, dry-run
353 remove: after, force, subrepos, include, exclude, dry-run
352 rename: after, force, include, exclude, dry-run
354 rename: after, force, include, exclude, dry-run
353 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
355 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
354 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
356 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
355 rollback: dry-run, force
357 rollback: dry-run, force
356 root: template
358 root: template
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
359 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
358 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
360 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
359 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
361 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
360 summary: remote
362 summary: remote
361 tag: force, local, rev, remove, edit, message, date, user
363 tag: force, local, rev, remove, edit, message, date, user
362 tags: template
364 tags: template
363 tip: patch, git, style, template
365 tip: patch, git, style, template
364 unbundle: update
366 unbundle: update
365 unshelve: abort, continue, interactive, keep, name, tool, date
367 unshelve: abort, continue, interactive, keep, name, tool, date
366 update: clean, check, merge, date, rev, tool
368 update: clean, check, merge, date, rev, tool
367 verify: full
369 verify: full
368 version: template
370 version: template
369
371
370 $ hg init a
372 $ hg init a
371 $ cd a
373 $ cd a
372 $ echo fee > fee
374 $ echo fee > fee
373 $ hg ci -q -Amfee
375 $ hg ci -q -Amfee
374 $ hg tag fee
376 $ hg tag fee
375 $ mkdir fie
377 $ mkdir fie
376 $ echo dead > fie/dead
378 $ echo dead > fie/dead
377 $ echo live > fie/live
379 $ echo live > fie/live
378 $ hg bookmark fo
380 $ hg bookmark fo
379 $ hg branch -q fie
381 $ hg branch -q fie
380 $ hg ci -q -Amfie
382 $ hg ci -q -Amfie
381 $ echo fo > fo
383 $ echo fo > fo
382 $ hg branch -qf default
384 $ hg branch -qf default
383 $ hg ci -q -Amfo
385 $ hg ci -q -Amfo
384 $ echo Fum > Fum
386 $ echo Fum > Fum
385 $ hg ci -q -AmFum
387 $ hg ci -q -AmFum
386 $ hg bookmark Fum
388 $ hg bookmark Fum
387
389
388 Test debugpathcomplete
390 Test debugpathcomplete
389
391
390 $ hg debugpathcomplete f
392 $ hg debugpathcomplete f
391 fee
393 fee
392 fie
394 fie
393 fo
395 fo
394 $ hg debugpathcomplete -f f
396 $ hg debugpathcomplete -f f
395 fee
397 fee
396 fie/dead
398 fie/dead
397 fie/live
399 fie/live
398 fo
400 fo
399
401
400 $ hg rm Fum
402 $ hg rm Fum
401 $ hg debugpathcomplete -r F
403 $ hg debugpathcomplete -r F
402 Fum
404 Fum
403
405
404 Test debugnamecomplete
406 Test debugnamecomplete
405
407
406 $ hg debugnamecomplete
408 $ hg debugnamecomplete
407 Fum
409 Fum
408 default
410 default
409 fee
411 fee
410 fie
412 fie
411 fo
413 fo
412 tip
414 tip
413 $ hg debugnamecomplete f
415 $ hg debugnamecomplete f
414 fee
416 fee
415 fie
417 fie
416 fo
418 fo
417
419
418 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
420 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
419 used for completions in some shells.
421 used for completions in some shells.
420
422
421 $ hg debuglabelcomplete
423 $ hg debuglabelcomplete
422 Fum
424 Fum
423 default
425 default
424 fee
426 fee
425 fie
427 fie
426 fo
428 fo
427 tip
429 tip
428 $ hg debuglabelcomplete f
430 $ hg debuglabelcomplete f
429 fee
431 fee
430 fie
432 fie
431 fo
433 fo
@@ -1,3913 +1,3915
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
976 debugbackupbundle
977 lists the changesets available in backup bundles
977 lists the changesets available in backup bundles
978 debugbuilddag
978 debugbuilddag
979 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
980 empty repo
980 empty repo
981 debugbundle lists the contents of a bundle
981 debugbundle lists the contents of a bundle
982 debugcapabilities
982 debugcapabilities
983 lists the capabilities of a remote peer
983 lists the capabilities of a remote peer
984 debugcheckstate
984 debugcheckstate
985 validate the correctness of the current dirstate
985 validate the correctness of the current dirstate
986 debugcolor show available color, effects or style
986 debugcolor show available color, effects or style
987 debugcommands
987 debugcommands
988 list all available commands and options
988 list all available commands and options
989 debugcomplete
989 debugcomplete
990 returns the completion list associated with the given command
990 returns the completion list associated with the given command
991 debugcreatestreamclonebundle
991 debugcreatestreamclonebundle
992 create a stream clone bundle file
992 create a stream clone bundle file
993 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
994 description
994 description
995 debugdata dump the contents of a data file revision
995 debugdata dump the contents of a data file revision
996 debugdate parse and display a date
996 debugdate parse and display a date
997 debugdeltachain
997 debugdeltachain
998 dump information about delta chains in a revlog
998 dump information about delta chains in a revlog
999 debugdirstate
999 debugdirstate
1000 show the contents of the current dirstate
1000 show the contents of the current dirstate
1001 debugdiscovery
1001 debugdiscovery
1002 runs the changeset discovery protocol in isolation
1002 runs the changeset discovery protocol in isolation
1003 debugdownload
1003 debugdownload
1004 download a resource using Mercurial logic and config
1004 download a resource using Mercurial logic and config
1005 debugextensions
1005 debugextensions
1006 show information about active extensions
1006 show information about active extensions
1007 debugfileset parse and apply a fileset specification
1007 debugfileset parse and apply a fileset specification
1008 debugformat display format information about the current repository
1008 debugformat display format information about the current repository
1009 debugfsinfo show information detected about current filesystem
1009 debugfsinfo show information detected about current filesystem
1010 debuggetbundle
1010 debuggetbundle
1011 retrieves a bundle from a repo
1011 retrieves a bundle from a repo
1012 debugignore display the combined ignore pattern and information about
1012 debugignore display the combined ignore pattern and information about
1013 ignored files
1013 ignored files
1014 debugindex dump index data for a storage primitive
1014 debugindex dump index data for a storage primitive
1015 debugindexdot
1015 debugindexdot
1016 dump an index DAG as a graphviz dot file
1016 dump an index DAG as a graphviz dot file
1017 debugindexstats
1017 debugindexstats
1018 show stats related to the changelog index
1018 show stats related to the changelog index
1019 debuginstall test Mercurial installation
1019 debuginstall test Mercurial installation
1020 debugknown test whether node ids are known to a repo
1020 debugknown test whether node ids are known to a repo
1021 debuglocks show or modify state of locks
1021 debuglocks show or modify state of locks
1022 debugmanifestfulltextcache
1022 debugmanifestfulltextcache
1023 show, clear or amend the contents of the manifest fulltext
1023 show, clear or amend the contents of the manifest fulltext
1024 cache
1024 cache
1025 debugmergestate
1025 debugmergestate
1026 print merge state
1026 print merge state
1027 debugnamecomplete
1027 debugnamecomplete
1028 complete "names" - tags, open branch names, bookmark names
1028 complete "names" - tags, open branch names, bookmark names
1029 debugnodemap write and inspect on disk nodemap
1029 debugnodemap write and inspect on disk nodemap
1030 debugobsolete
1030 debugobsolete
1031 create arbitrary obsolete marker
1031 create arbitrary obsolete marker
1032 debugoptADV (no help text available)
1032 debugoptADV (no help text available)
1033 debugoptDEP (no help text available)
1033 debugoptDEP (no help text available)
1034 debugoptEXP (no help text available)
1034 debugoptEXP (no help text available)
1035 debugp1copies
1035 debugp1copies
1036 dump copy information compared to p1
1036 dump copy information compared to p1
1037 debugp2copies
1037 debugp2copies
1038 dump copy information compared to p2
1038 dump copy information compared to p2
1039 debugpathcomplete
1039 debugpathcomplete
1040 complete part or all of a tracked path
1040 complete part or all of a tracked path
1041 debugpathcopies
1041 debugpathcopies
1042 show copies between two revisions
1042 show copies between two revisions
1043 debugpeer establish a connection to a peer repository
1043 debugpeer establish a connection to a peer repository
1044 debugpickmergetool
1044 debugpickmergetool
1045 examine which merge tool is chosen for specified file
1045 examine which merge tool is chosen for specified file
1046 debugpushkey access the pushkey key/value protocol
1046 debugpushkey access the pushkey key/value protocol
1047 debugpvec (no help text available)
1047 debugpvec (no help text available)
1048 debugrebuilddirstate
1048 debugrebuilddirstate
1049 rebuild the dirstate as it would look like for the given
1049 rebuild the dirstate as it would look like for the given
1050 revision
1050 revision
1051 debugrebuildfncache
1051 debugrebuildfncache
1052 rebuild the fncache file
1052 rebuild the fncache file
1053 debugrename dump rename information
1053 debugrename dump rename information
1054 debugrequires
1055 print the current repo requirements
1054 debugrevlog show data and statistics about a revlog
1056 debugrevlog show data and statistics about a revlog
1055 debugrevlogindex
1057 debugrevlogindex
1056 dump the contents of a revlog index
1058 dump the contents of a revlog index
1057 debugrevspec parse and apply a revision specification
1059 debugrevspec parse and apply a revision specification
1058 debugserve run a server with advanced settings
1060 debugserve run a server with advanced settings
1059 debugsetparents
1061 debugsetparents
1060 manually set the parents of the current working directory
1062 manually set the parents of the current working directory
1061 debugsidedata
1063 debugsidedata
1062 dump the side data for a cl/manifest/file revision
1064 dump the side data for a cl/manifest/file revision
1063 debugssl test a secure connection to a server
1065 debugssl test a secure connection to a server
1064 debugsub (no help text available)
1066 debugsub (no help text available)
1065 debugsuccessorssets
1067 debugsuccessorssets
1066 show set of successors for revision
1068 show set of successors for revision
1067 debugtagscache
1069 debugtagscache
1068 display the contents of .hg/cache/hgtagsfnodes1
1070 display the contents of .hg/cache/hgtagsfnodes1
1069 debugtemplate
1071 debugtemplate
1070 parse and apply a template
1072 parse and apply a template
1071 debuguigetpass
1073 debuguigetpass
1072 show prompt to type password
1074 show prompt to type password
1073 debuguiprompt
1075 debuguiprompt
1074 show plain prompt
1076 show plain prompt
1075 debugupdatecaches
1077 debugupdatecaches
1076 warm all known caches in the repository
1078 warm all known caches in the repository
1077 debugupgraderepo
1079 debugupgraderepo
1078 upgrade a repository to use different features
1080 upgrade a repository to use different features
1079 debugwalk show how files match on given patterns
1081 debugwalk show how files match on given patterns
1080 debugwhyunstable
1082 debugwhyunstable
1081 explain instabilities of a changeset
1083 explain instabilities of a changeset
1082 debugwireargs
1084 debugwireargs
1083 (no help text available)
1085 (no help text available)
1084 debugwireproto
1086 debugwireproto
1085 send wire protocol commands to a server
1087 send wire protocol commands to a server
1086
1088
1087 (use 'hg help -v debug' to show built-in aliases and global options)
1089 (use 'hg help -v debug' to show built-in aliases and global options)
1088
1090
1089 internals topic renders index of available sub-topics
1091 internals topic renders index of available sub-topics
1090
1092
1091 $ hg help internals
1093 $ hg help internals
1092 Technical implementation topics
1094 Technical implementation topics
1093 """""""""""""""""""""""""""""""
1095 """""""""""""""""""""""""""""""
1094
1096
1095 To access a subtopic, use "hg help internals.{subtopic-name}"
1097 To access a subtopic, use "hg help internals.{subtopic-name}"
1096
1098
1097 bid-merge Bid Merge Algorithm
1099 bid-merge Bid Merge Algorithm
1098 bundle2 Bundle2
1100 bundle2 Bundle2
1099 bundles Bundles
1101 bundles Bundles
1100 cbor CBOR
1102 cbor CBOR
1101 censor Censor
1103 censor Censor
1102 changegroups Changegroups
1104 changegroups Changegroups
1103 config Config Registrar
1105 config Config Registrar
1104 extensions Extension API
1106 extensions Extension API
1105 mergestate Mergestate
1107 mergestate Mergestate
1106 requirements Repository Requirements
1108 requirements Repository Requirements
1107 revlogs Revision Logs
1109 revlogs Revision Logs
1108 wireprotocol Wire Protocol
1110 wireprotocol Wire Protocol
1109 wireprotocolrpc
1111 wireprotocolrpc
1110 Wire Protocol RPC
1112 Wire Protocol RPC
1111 wireprotocolv2
1113 wireprotocolv2
1112 Wire Protocol Version 2
1114 Wire Protocol Version 2
1113
1115
1114 sub-topics can be accessed
1116 sub-topics can be accessed
1115
1117
1116 $ hg help internals.changegroups
1118 $ hg help internals.changegroups
1117 Changegroups
1119 Changegroups
1118 """"""""""""
1120 """"""""""""
1119
1121
1120 Changegroups are representations of repository revlog data, specifically
1122 Changegroups are representations of repository revlog data, specifically
1121 the changelog data, root/flat manifest data, treemanifest data, and
1123 the changelog data, root/flat manifest data, treemanifest data, and
1122 filelogs.
1124 filelogs.
1123
1125
1124 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1126 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1125 level, versions "1" and "2" are almost exactly the same, with the only
1127 level, versions "1" and "2" are almost exactly the same, with the only
1126 difference being an additional item in the *delta header*. Version "3"
1128 difference being an additional item in the *delta header*. Version "3"
1127 adds support for storage flags in the *delta header* and optionally
1129 adds support for storage flags in the *delta header* and optionally
1128 exchanging treemanifests (enabled by setting an option on the
1130 exchanging treemanifests (enabled by setting an option on the
1129 "changegroup" part in the bundle2).
1131 "changegroup" part in the bundle2).
1130
1132
1131 Changegroups when not exchanging treemanifests consist of 3 logical
1133 Changegroups when not exchanging treemanifests consist of 3 logical
1132 segments:
1134 segments:
1133
1135
1134 +---------------------------------+
1136 +---------------------------------+
1135 | | | |
1137 | | | |
1136 | changeset | manifest | filelogs |
1138 | changeset | manifest | filelogs |
1137 | | | |
1139 | | | |
1138 | | | |
1140 | | | |
1139 +---------------------------------+
1141 +---------------------------------+
1140
1142
1141 When exchanging treemanifests, there are 4 logical segments:
1143 When exchanging treemanifests, there are 4 logical segments:
1142
1144
1143 +-------------------------------------------------+
1145 +-------------------------------------------------+
1144 | | | | |
1146 | | | | |
1145 | changeset | root | treemanifests | filelogs |
1147 | changeset | root | treemanifests | filelogs |
1146 | | manifest | | |
1148 | | manifest | | |
1147 | | | | |
1149 | | | | |
1148 +-------------------------------------------------+
1150 +-------------------------------------------------+
1149
1151
1150 The principle building block of each segment is a *chunk*. A *chunk* is a
1152 The principle building block of each segment is a *chunk*. A *chunk* is a
1151 framed piece of data:
1153 framed piece of data:
1152
1154
1153 +---------------------------------------+
1155 +---------------------------------------+
1154 | | |
1156 | | |
1155 | length | data |
1157 | length | data |
1156 | (4 bytes) | (<length - 4> bytes) |
1158 | (4 bytes) | (<length - 4> bytes) |
1157 | | |
1159 | | |
1158 +---------------------------------------+
1160 +---------------------------------------+
1159
1161
1160 All integers are big-endian signed integers. Each chunk starts with a
1162 All integers are big-endian signed integers. Each chunk starts with a
1161 32-bit integer indicating the length of the entire chunk (including the
1163 32-bit integer indicating the length of the entire chunk (including the
1162 length field itself).
1164 length field itself).
1163
1165
1164 There is a special case chunk that has a value of 0 for the length
1166 There is a special case chunk that has a value of 0 for the length
1165 ("0x00000000"). We call this an *empty chunk*.
1167 ("0x00000000"). We call this an *empty chunk*.
1166
1168
1167 Delta Groups
1169 Delta Groups
1168 ============
1170 ============
1169
1171
1170 A *delta group* expresses the content of a revlog as a series of deltas,
1172 A *delta group* expresses the content of a revlog as a series of deltas,
1171 or patches against previous revisions.
1173 or patches against previous revisions.
1172
1174
1173 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1175 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1174 to signal the end of the delta group:
1176 to signal the end of the delta group:
1175
1177
1176 +------------------------------------------------------------------------+
1178 +------------------------------------------------------------------------+
1177 | | | | | |
1179 | | | | | |
1178 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1180 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1179 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1181 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1180 | | | | | |
1182 | | | | | |
1181 +------------------------------------------------------------------------+
1183 +------------------------------------------------------------------------+
1182
1184
1183 Each *chunk*'s data consists of the following:
1185 Each *chunk*'s data consists of the following:
1184
1186
1185 +---------------------------------------+
1187 +---------------------------------------+
1186 | | |
1188 | | |
1187 | delta header | delta data |
1189 | delta header | delta data |
1188 | (various by version) | (various) |
1190 | (various by version) | (various) |
1189 | | |
1191 | | |
1190 +---------------------------------------+
1192 +---------------------------------------+
1191
1193
1192 The *delta data* is a series of *delta*s that describe a diff from an
1194 The *delta data* is a series of *delta*s that describe a diff from an
1193 existing entry (either that the recipient already has, or previously
1195 existing entry (either that the recipient already has, or previously
1194 specified in the bundle/changegroup).
1196 specified in the bundle/changegroup).
1195
1197
1196 The *delta header* is different between versions "1", "2", and "3" of the
1198 The *delta header* is different between versions "1", "2", and "3" of the
1197 changegroup format.
1199 changegroup format.
1198
1200
1199 Version 1 (headerlen=80):
1201 Version 1 (headerlen=80):
1200
1202
1201 +------------------------------------------------------+
1203 +------------------------------------------------------+
1202 | | | | |
1204 | | | | |
1203 | node | p1 node | p2 node | link node |
1205 | node | p1 node | p2 node | link node |
1204 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1206 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1205 | | | | |
1207 | | | | |
1206 +------------------------------------------------------+
1208 +------------------------------------------------------+
1207
1209
1208 Version 2 (headerlen=100):
1210 Version 2 (headerlen=100):
1209
1211
1210 +------------------------------------------------------------------+
1212 +------------------------------------------------------------------+
1211 | | | | | |
1213 | | | | | |
1212 | node | p1 node | p2 node | base node | link node |
1214 | node | p1 node | p2 node | base node | link node |
1213 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1215 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1214 | | | | | |
1216 | | | | | |
1215 +------------------------------------------------------------------+
1217 +------------------------------------------------------------------+
1216
1218
1217 Version 3 (headerlen=102):
1219 Version 3 (headerlen=102):
1218
1220
1219 +------------------------------------------------------------------------------+
1221 +------------------------------------------------------------------------------+
1220 | | | | | | |
1222 | | | | | | |
1221 | node | p1 node | p2 node | base node | link node | flags |
1223 | node | p1 node | p2 node | base node | link node | flags |
1222 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1224 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1223 | | | | | | |
1225 | | | | | | |
1224 +------------------------------------------------------------------------------+
1226 +------------------------------------------------------------------------------+
1225
1227
1226 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1228 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1227 contain a series of *delta*s, densely packed (no separators). These deltas
1229 contain a series of *delta*s, densely packed (no separators). These deltas
1228 describe a diff from an existing entry (either that the recipient already
1230 describe a diff from an existing entry (either that the recipient already
1229 has, or previously specified in the bundle/changegroup). The format is
1231 has, or previously specified in the bundle/changegroup). The format is
1230 described more fully in "hg help internals.bdiff", but briefly:
1232 described more fully in "hg help internals.bdiff", but briefly:
1231
1233
1232 +---------------------------------------------------------------+
1234 +---------------------------------------------------------------+
1233 | | | | |
1235 | | | | |
1234 | start offset | end offset | new length | content |
1236 | start offset | end offset | new length | content |
1235 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1237 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1236 | | | | |
1238 | | | | |
1237 +---------------------------------------------------------------+
1239 +---------------------------------------------------------------+
1238
1240
1239 Please note that the length field in the delta data does *not* include
1241 Please note that the length field in the delta data does *not* include
1240 itself.
1242 itself.
1241
1243
1242 In version 1, the delta is always applied against the previous node from
1244 In version 1, the delta is always applied against the previous node from
1243 the changegroup or the first parent if this is the first entry in the
1245 the changegroup or the first parent if this is the first entry in the
1244 changegroup.
1246 changegroup.
1245
1247
1246 In version 2 and up, the delta base node is encoded in the entry in the
1248 In version 2 and up, the delta base node is encoded in the entry in the
1247 changegroup. This allows the delta to be expressed against any parent,
1249 changegroup. This allows the delta to be expressed against any parent,
1248 which can result in smaller deltas and more efficient encoding of data.
1250 which can result in smaller deltas and more efficient encoding of data.
1249
1251
1250 The *flags* field holds bitwise flags affecting the processing of revision
1252 The *flags* field holds bitwise flags affecting the processing of revision
1251 data. The following flags are defined:
1253 data. The following flags are defined:
1252
1254
1253 32768
1255 32768
1254 Censored revision. The revision's fulltext has been replaced by censor
1256 Censored revision. The revision's fulltext has been replaced by censor
1255 metadata. May only occur on file revisions.
1257 metadata. May only occur on file revisions.
1256
1258
1257 16384
1259 16384
1258 Ellipsis revision. Revision hash does not match data (likely due to
1260 Ellipsis revision. Revision hash does not match data (likely due to
1259 rewritten parents).
1261 rewritten parents).
1260
1262
1261 8192
1263 8192
1262 Externally stored. The revision fulltext contains "key:value" "\n"
1264 Externally stored. The revision fulltext contains "key:value" "\n"
1263 delimited metadata defining an object stored elsewhere. Used by the LFS
1265 delimited metadata defining an object stored elsewhere. Used by the LFS
1264 extension.
1266 extension.
1265
1267
1266 For historical reasons, the integer values are identical to revlog version
1268 For historical reasons, the integer values are identical to revlog version
1267 1 per-revision storage flags and correspond to bits being set in this
1269 1 per-revision storage flags and correspond to bits being set in this
1268 2-byte field. Bits were allocated starting from the most-significant bit,
1270 2-byte field. Bits were allocated starting from the most-significant bit,
1269 hence the reverse ordering and allocation of these flags.
1271 hence the reverse ordering and allocation of these flags.
1270
1272
1271 Changeset Segment
1273 Changeset Segment
1272 =================
1274 =================
1273
1275
1274 The *changeset segment* consists of a single *delta group* holding
1276 The *changeset segment* consists of a single *delta group* holding
1275 changelog data. The *empty chunk* at the end of the *delta group* denotes
1277 changelog data. The *empty chunk* at the end of the *delta group* denotes
1276 the boundary to the *manifest segment*.
1278 the boundary to the *manifest segment*.
1277
1279
1278 Manifest Segment
1280 Manifest Segment
1279 ================
1281 ================
1280
1282
1281 The *manifest segment* consists of a single *delta group* holding manifest
1283 The *manifest segment* consists of a single *delta group* holding manifest
1282 data. If treemanifests are in use, it contains only the manifest for the
1284 data. If treemanifests are in use, it contains only the manifest for the
1283 root directory of the repository. Otherwise, it contains the entire
1285 root directory of the repository. Otherwise, it contains the entire
1284 manifest data. The *empty chunk* at the end of the *delta group* denotes
1286 manifest data. The *empty chunk* at the end of the *delta group* denotes
1285 the boundary to the next segment (either the *treemanifests segment* or
1287 the boundary to the next segment (either the *treemanifests segment* or
1286 the *filelogs segment*, depending on version and the request options).
1288 the *filelogs segment*, depending on version and the request options).
1287
1289
1288 Treemanifests Segment
1290 Treemanifests Segment
1289 ---------------------
1291 ---------------------
1290
1292
1291 The *treemanifests segment* only exists in changegroup version "3", and
1293 The *treemanifests segment* only exists in changegroup version "3", and
1292 only if the 'treemanifest' param is part of the bundle2 changegroup part
1294 only if the 'treemanifest' param is part of the bundle2 changegroup part
1293 (it is not possible to use changegroup version 3 outside of bundle2).
1295 (it is not possible to use changegroup version 3 outside of bundle2).
1294 Aside from the filenames in the *treemanifests segment* containing a
1296 Aside from the filenames in the *treemanifests segment* containing a
1295 trailing "/" character, it behaves identically to the *filelogs segment*
1297 trailing "/" character, it behaves identically to the *filelogs segment*
1296 (see below). The final sub-segment is followed by an *empty chunk*
1298 (see below). The final sub-segment is followed by an *empty chunk*
1297 (logically, a sub-segment with filename size 0). This denotes the boundary
1299 (logically, a sub-segment with filename size 0). This denotes the boundary
1298 to the *filelogs segment*.
1300 to the *filelogs segment*.
1299
1301
1300 Filelogs Segment
1302 Filelogs Segment
1301 ================
1303 ================
1302
1304
1303 The *filelogs segment* consists of multiple sub-segments, each
1305 The *filelogs segment* consists of multiple sub-segments, each
1304 corresponding to an individual file whose data is being described:
1306 corresponding to an individual file whose data is being described:
1305
1307
1306 +--------------------------------------------------+
1308 +--------------------------------------------------+
1307 | | | | | |
1309 | | | | | |
1308 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1310 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1309 | | | | | (4 bytes) |
1311 | | | | | (4 bytes) |
1310 | | | | | |
1312 | | | | | |
1311 +--------------------------------------------------+
1313 +--------------------------------------------------+
1312
1314
1313 The final filelog sub-segment is followed by an *empty chunk* (logically,
1315 The final filelog sub-segment is followed by an *empty chunk* (logically,
1314 a sub-segment with filename size 0). This denotes the end of the segment
1316 a sub-segment with filename size 0). This denotes the end of the segment
1315 and of the overall changegroup.
1317 and of the overall changegroup.
1316
1318
1317 Each filelog sub-segment consists of the following:
1319 Each filelog sub-segment consists of the following:
1318
1320
1319 +------------------------------------------------------+
1321 +------------------------------------------------------+
1320 | | | |
1322 | | | |
1321 | filename length | filename | delta group |
1323 | filename length | filename | delta group |
1322 | (4 bytes) | (<length - 4> bytes) | (various) |
1324 | (4 bytes) | (<length - 4> bytes) | (various) |
1323 | | | |
1325 | | | |
1324 +------------------------------------------------------+
1326 +------------------------------------------------------+
1325
1327
1326 That is, a *chunk* consisting of the filename (not terminated or padded)
1328 That is, a *chunk* consisting of the filename (not terminated or padded)
1327 followed by N chunks constituting the *delta group* for this file. The
1329 followed by N chunks constituting the *delta group* for this file. The
1328 *empty chunk* at the end of each *delta group* denotes the boundary to the
1330 *empty chunk* at the end of each *delta group* denotes the boundary to the
1329 next filelog sub-segment.
1331 next filelog sub-segment.
1330
1332
1331 non-existent subtopics print an error
1333 non-existent subtopics print an error
1332
1334
1333 $ hg help internals.foo
1335 $ hg help internals.foo
1334 abort: no such help topic: internals.foo
1336 abort: no such help topic: internals.foo
1335 (try 'hg help --keyword foo')
1337 (try 'hg help --keyword foo')
1336 [255]
1338 [255]
1337
1339
1338 test advanced, deprecated and experimental options are hidden in command help
1340 test advanced, deprecated and experimental options are hidden in command help
1339 $ hg help debugoptADV
1341 $ hg help debugoptADV
1340 hg debugoptADV
1342 hg debugoptADV
1341
1343
1342 (no help text available)
1344 (no help text available)
1343
1345
1344 options:
1346 options:
1345
1347
1346 (some details hidden, use --verbose to show complete help)
1348 (some details hidden, use --verbose to show complete help)
1347 $ hg help debugoptDEP
1349 $ hg help debugoptDEP
1348 hg debugoptDEP
1350 hg debugoptDEP
1349
1351
1350 (no help text available)
1352 (no help text available)
1351
1353
1352 options:
1354 options:
1353
1355
1354 (some details hidden, use --verbose to show complete help)
1356 (some details hidden, use --verbose to show complete help)
1355
1357
1356 $ hg help debugoptEXP
1358 $ hg help debugoptEXP
1357 hg debugoptEXP
1359 hg debugoptEXP
1358
1360
1359 (no help text available)
1361 (no help text available)
1360
1362
1361 options:
1363 options:
1362
1364
1363 (some details hidden, use --verbose to show complete help)
1365 (some details hidden, use --verbose to show complete help)
1364
1366
1365 test advanced, deprecated and experimental options are shown with -v
1367 test advanced, deprecated and experimental options are shown with -v
1366 $ hg help -v debugoptADV | grep aopt
1368 $ hg help -v debugoptADV | grep aopt
1367 --aopt option is (ADVANCED)
1369 --aopt option is (ADVANCED)
1368 $ hg help -v debugoptDEP | grep dopt
1370 $ hg help -v debugoptDEP | grep dopt
1369 --dopt option is (DEPRECATED)
1371 --dopt option is (DEPRECATED)
1370 $ hg help -v debugoptEXP | grep eopt
1372 $ hg help -v debugoptEXP | grep eopt
1371 --eopt option is (EXPERIMENTAL)
1373 --eopt option is (EXPERIMENTAL)
1372
1374
1373 #if gettext
1375 #if gettext
1374 test deprecated option is hidden with translation with untranslated description
1376 test deprecated option is hidden with translation with untranslated description
1375 (use many globy for not failing on changed transaction)
1377 (use many globy for not failing on changed transaction)
1376 $ LANGUAGE=sv hg help debugoptDEP
1378 $ LANGUAGE=sv hg help debugoptDEP
1377 hg debugoptDEP
1379 hg debugoptDEP
1378
1380
1379 (*) (glob)
1381 (*) (glob)
1380
1382
1381 options:
1383 options:
1382
1384
1383 (some details hidden, use --verbose to show complete help)
1385 (some details hidden, use --verbose to show complete help)
1384 #endif
1386 #endif
1385
1387
1386 Test commands that collide with topics (issue4240)
1388 Test commands that collide with topics (issue4240)
1387
1389
1388 $ hg config -hq
1390 $ hg config -hq
1389 hg config [-u] [NAME]...
1391 hg config [-u] [NAME]...
1390
1392
1391 show combined config settings from all hgrc files
1393 show combined config settings from all hgrc files
1392 $ hg showconfig -hq
1394 $ hg showconfig -hq
1393 hg config [-u] [NAME]...
1395 hg config [-u] [NAME]...
1394
1396
1395 show combined config settings from all hgrc files
1397 show combined config settings from all hgrc files
1396
1398
1397 Test a help topic
1399 Test a help topic
1398
1400
1399 $ hg help dates
1401 $ hg help dates
1400 Date Formats
1402 Date Formats
1401 """"""""""""
1403 """"""""""""
1402
1404
1403 Some commands allow the user to specify a date, e.g.:
1405 Some commands allow the user to specify a date, e.g.:
1404
1406
1405 - backout, commit, import, tag: Specify the commit date.
1407 - backout, commit, import, tag: Specify the commit date.
1406 - log, revert, update: Select revision(s) by date.
1408 - log, revert, update: Select revision(s) by date.
1407
1409
1408 Many date formats are valid. Here are some examples:
1410 Many date formats are valid. Here are some examples:
1409
1411
1410 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1412 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1411 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1413 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1412 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1414 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1413 - "Dec 6" (midnight)
1415 - "Dec 6" (midnight)
1414 - "13:18" (today assumed)
1416 - "13:18" (today assumed)
1415 - "3:39" (3:39AM assumed)
1417 - "3:39" (3:39AM assumed)
1416 - "3:39pm" (15:39)
1418 - "3:39pm" (15:39)
1417 - "2006-12-06 13:18:29" (ISO 8601 format)
1419 - "2006-12-06 13:18:29" (ISO 8601 format)
1418 - "2006-12-6 13:18"
1420 - "2006-12-6 13:18"
1419 - "2006-12-6"
1421 - "2006-12-6"
1420 - "12-6"
1422 - "12-6"
1421 - "12/6"
1423 - "12/6"
1422 - "12/6/6" (Dec 6 2006)
1424 - "12/6/6" (Dec 6 2006)
1423 - "today" (midnight)
1425 - "today" (midnight)
1424 - "yesterday" (midnight)
1426 - "yesterday" (midnight)
1425 - "now" - right now
1427 - "now" - right now
1426
1428
1427 Lastly, there is Mercurial's internal format:
1429 Lastly, there is Mercurial's internal format:
1428
1430
1429 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1431 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1430
1432
1431 This is the internal representation format for dates. The first number is
1433 This is the internal representation format for dates. The first number is
1432 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1434 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1433 is the offset of the local timezone, in seconds west of UTC (negative if
1435 is the offset of the local timezone, in seconds west of UTC (negative if
1434 the timezone is east of UTC).
1436 the timezone is east of UTC).
1435
1437
1436 The log command also accepts date ranges:
1438 The log command also accepts date ranges:
1437
1439
1438 - "<DATE" - at or before a given date/time
1440 - "<DATE" - at or before a given date/time
1439 - ">DATE" - on or after a given date/time
1441 - ">DATE" - on or after a given date/time
1440 - "DATE to DATE" - a date range, inclusive
1442 - "DATE to DATE" - a date range, inclusive
1441 - "-DAYS" - within a given number of days of today
1443 - "-DAYS" - within a given number of days of today
1442
1444
1443 Test repeated config section name
1445 Test repeated config section name
1444
1446
1445 $ hg help config.host
1447 $ hg help config.host
1446 "http_proxy.host"
1448 "http_proxy.host"
1447 Host name and (optional) port of the proxy server, for example
1449 Host name and (optional) port of the proxy server, for example
1448 "myproxy:8000".
1450 "myproxy:8000".
1449
1451
1450 "smtp.host"
1452 "smtp.host"
1451 Host name of mail server, e.g. "mail.example.com".
1453 Host name of mail server, e.g. "mail.example.com".
1452
1454
1453
1455
1454 Test section name with dot
1456 Test section name with dot
1455
1457
1456 $ hg help config.ui.username
1458 $ hg help config.ui.username
1457 "ui.username"
1459 "ui.username"
1458 The committer of a changeset created when running "commit". Typically
1460 The committer of a changeset created when running "commit". Typically
1459 a person's name and email address, e.g. "Fred Widget
1461 a person's name and email address, e.g. "Fred Widget
1460 <fred@example.com>". Environment variables in the username are
1462 <fred@example.com>". Environment variables in the username are
1461 expanded.
1463 expanded.
1462
1464
1463 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1465 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1464 empty, e.g. if the system admin set "username =" in the system hgrc,
1466 empty, e.g. if the system admin set "username =" in the system hgrc,
1465 it has to be specified manually or in a different hgrc file)
1467 it has to be specified manually or in a different hgrc file)
1466
1468
1467
1469
1468 $ hg help config.annotate.git
1470 $ hg help config.annotate.git
1469 abort: help section not found: config.annotate.git
1471 abort: help section not found: config.annotate.git
1470 [255]
1472 [255]
1471
1473
1472 $ hg help config.update.check
1474 $ hg help config.update.check
1473 "commands.update.check"
1475 "commands.update.check"
1474 Determines what level of checking 'hg update' will perform before
1476 Determines what level of checking 'hg update' will perform before
1475 moving to a destination revision. Valid values are "abort", "none",
1477 moving to a destination revision. Valid values are "abort", "none",
1476 "linear", and "noconflict". "abort" always fails if the working
1478 "linear", and "noconflict". "abort" always fails if the working
1477 directory has uncommitted changes. "none" performs no checking, and
1479 directory has uncommitted changes. "none" performs no checking, and
1478 may result in a merge with uncommitted changes. "linear" allows any
1480 may result in a merge with uncommitted changes. "linear" allows any
1479 update as long as it follows a straight line in the revision history,
1481 update as long as it follows a straight line in the revision history,
1480 and may trigger a merge with uncommitted changes. "noconflict" will
1482 and may trigger a merge with uncommitted changes. "noconflict" will
1481 allow any update which would not trigger a merge with uncommitted
1483 allow any update which would not trigger a merge with uncommitted
1482 changes, if any are present. (default: "linear")
1484 changes, if any are present. (default: "linear")
1483
1485
1484
1486
1485 $ hg help config.commands.update.check
1487 $ hg help config.commands.update.check
1486 "commands.update.check"
1488 "commands.update.check"
1487 Determines what level of checking 'hg update' will perform before
1489 Determines what level of checking 'hg update' will perform before
1488 moving to a destination revision. Valid values are "abort", "none",
1490 moving to a destination revision. Valid values are "abort", "none",
1489 "linear", and "noconflict". "abort" always fails if the working
1491 "linear", and "noconflict". "abort" always fails if the working
1490 directory has uncommitted changes. "none" performs no checking, and
1492 directory has uncommitted changes. "none" performs no checking, and
1491 may result in a merge with uncommitted changes. "linear" allows any
1493 may result in a merge with uncommitted changes. "linear" allows any
1492 update as long as it follows a straight line in the revision history,
1494 update as long as it follows a straight line in the revision history,
1493 and may trigger a merge with uncommitted changes. "noconflict" will
1495 and may trigger a merge with uncommitted changes. "noconflict" will
1494 allow any update which would not trigger a merge with uncommitted
1496 allow any update which would not trigger a merge with uncommitted
1495 changes, if any are present. (default: "linear")
1497 changes, if any are present. (default: "linear")
1496
1498
1497
1499
1498 $ hg help config.ommands.update.check
1500 $ hg help config.ommands.update.check
1499 abort: help section not found: config.ommands.update.check
1501 abort: help section not found: config.ommands.update.check
1500 [255]
1502 [255]
1501
1503
1502 Unrelated trailing paragraphs shouldn't be included
1504 Unrelated trailing paragraphs shouldn't be included
1503
1505
1504 $ hg help config.extramsg | grep '^$'
1506 $ hg help config.extramsg | grep '^$'
1505
1507
1506
1508
1507 Test capitalized section name
1509 Test capitalized section name
1508
1510
1509 $ hg help scripting.HGPLAIN > /dev/null
1511 $ hg help scripting.HGPLAIN > /dev/null
1510
1512
1511 Help subsection:
1513 Help subsection:
1512
1514
1513 $ hg help config.charsets |grep "Email example:" > /dev/null
1515 $ hg help config.charsets |grep "Email example:" > /dev/null
1514 [1]
1516 [1]
1515
1517
1516 Show nested definitions
1518 Show nested definitions
1517 ("profiling.type"[break]"ls"[break]"stat"[break])
1519 ("profiling.type"[break]"ls"[break]"stat"[break])
1518
1520
1519 $ hg help config.type | egrep '^$'|wc -l
1521 $ hg help config.type | egrep '^$'|wc -l
1520 \s*3 (re)
1522 \s*3 (re)
1521
1523
1522 $ hg help config.profiling.type.ls
1524 $ hg help config.profiling.type.ls
1523 "profiling.type.ls"
1525 "profiling.type.ls"
1524 Use Python's built-in instrumenting profiler. This profiler works on
1526 Use Python's built-in instrumenting profiler. This profiler works on
1525 all platforms, but each line number it reports is the first line of
1527 all platforms, but each line number it reports is the first line of
1526 a function. This restriction makes it difficult to identify the
1528 a function. This restriction makes it difficult to identify the
1527 expensive parts of a non-trivial function.
1529 expensive parts of a non-trivial function.
1528
1530
1529
1531
1530 Separate sections from subsections
1532 Separate sections from subsections
1531
1533
1532 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1534 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1533 "format"
1535 "format"
1534 --------
1536 --------
1535
1537
1536 "usegeneraldelta"
1538 "usegeneraldelta"
1537
1539
1538 "dotencode"
1540 "dotencode"
1539
1541
1540 "usefncache"
1542 "usefncache"
1541
1543
1542 "usestore"
1544 "usestore"
1543
1545
1544 "sparse-revlog"
1546 "sparse-revlog"
1545
1547
1546 "revlog-compression"
1548 "revlog-compression"
1547
1549
1548 "bookmarks-in-store"
1550 "bookmarks-in-store"
1549
1551
1550 "profiling"
1552 "profiling"
1551 -----------
1553 -----------
1552
1554
1553 "format"
1555 "format"
1554
1556
1555 "progress"
1557 "progress"
1556 ----------
1558 ----------
1557
1559
1558 "format"
1560 "format"
1559
1561
1560
1562
1561 Last item in help config.*:
1563 Last item in help config.*:
1562
1564
1563 $ hg help config.`hg help config|grep '^ "'| \
1565 $ hg help config.`hg help config|grep '^ "'| \
1564 > tail -1|sed 's![ "]*!!g'`| \
1566 > tail -1|sed 's![ "]*!!g'`| \
1565 > grep 'hg help -c config' > /dev/null
1567 > grep 'hg help -c config' > /dev/null
1566 [1]
1568 [1]
1567
1569
1568 note to use help -c for general hg help config:
1570 note to use help -c for general hg help config:
1569
1571
1570 $ hg help config |grep 'hg help -c config' > /dev/null
1572 $ hg help config |grep 'hg help -c config' > /dev/null
1571
1573
1572 Test templating help
1574 Test templating help
1573
1575
1574 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1576 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1575 desc String. The text of the changeset description.
1577 desc String. The text of the changeset description.
1576 diffstat String. Statistics of changes with the following format:
1578 diffstat String. Statistics of changes with the following format:
1577 firstline Any text. Returns the first line of text.
1579 firstline Any text. Returns the first line of text.
1578 nonempty Any text. Returns '(none)' if the string is empty.
1580 nonempty Any text. Returns '(none)' if the string is empty.
1579
1581
1580 Test deprecated items
1582 Test deprecated items
1581
1583
1582 $ hg help -v templating | grep currentbookmark
1584 $ hg help -v templating | grep currentbookmark
1583 currentbookmark
1585 currentbookmark
1584 $ hg help templating | (grep currentbookmark || true)
1586 $ hg help templating | (grep currentbookmark || true)
1585
1587
1586 Test help hooks
1588 Test help hooks
1587
1589
1588 $ cat > helphook1.py <<EOF
1590 $ cat > helphook1.py <<EOF
1589 > from mercurial import help
1591 > from mercurial import help
1590 >
1592 >
1591 > def rewrite(ui, topic, doc):
1593 > def rewrite(ui, topic, doc):
1592 > return doc + b'\nhelphook1\n'
1594 > return doc + b'\nhelphook1\n'
1593 >
1595 >
1594 > def extsetup(ui):
1596 > def extsetup(ui):
1595 > help.addtopichook(b'revisions', rewrite)
1597 > help.addtopichook(b'revisions', rewrite)
1596 > EOF
1598 > EOF
1597 $ cat > helphook2.py <<EOF
1599 $ cat > helphook2.py <<EOF
1598 > from mercurial import help
1600 > from mercurial import help
1599 >
1601 >
1600 > def rewrite(ui, topic, doc):
1602 > def rewrite(ui, topic, doc):
1601 > return doc + b'\nhelphook2\n'
1603 > return doc + b'\nhelphook2\n'
1602 >
1604 >
1603 > def extsetup(ui):
1605 > def extsetup(ui):
1604 > help.addtopichook(b'revisions', rewrite)
1606 > help.addtopichook(b'revisions', rewrite)
1605 > EOF
1607 > EOF
1606 $ echo '[extensions]' >> $HGRCPATH
1608 $ echo '[extensions]' >> $HGRCPATH
1607 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1609 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1608 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1610 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1609 $ hg help revsets | grep helphook
1611 $ hg help revsets | grep helphook
1610 helphook1
1612 helphook1
1611 helphook2
1613 helphook2
1612
1614
1613 help -c should only show debug --debug
1615 help -c should only show debug --debug
1614
1616
1615 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1617 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1616 [1]
1618 [1]
1617
1619
1618 help -c should only show deprecated for -v
1620 help -c should only show deprecated for -v
1619
1621
1620 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1622 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1621 [1]
1623 [1]
1622
1624
1623 Test -s / --system
1625 Test -s / --system
1624
1626
1625 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1627 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1626 > wc -l | sed -e 's/ //g'
1628 > wc -l | sed -e 's/ //g'
1627 0
1629 0
1628 $ hg help config.files --system unix | grep 'USER' | \
1630 $ hg help config.files --system unix | grep 'USER' | \
1629 > wc -l | sed -e 's/ //g'
1631 > wc -l | sed -e 's/ //g'
1630 0
1632 0
1631
1633
1632 Test -e / -c / -k combinations
1634 Test -e / -c / -k combinations
1633
1635
1634 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1636 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1635 Commands:
1637 Commands:
1636 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1638 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1637 Extensions:
1639 Extensions:
1638 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1640 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1639 Topics:
1641 Topics:
1640 Commands:
1642 Commands:
1641 Extensions:
1643 Extensions:
1642 Extension Commands:
1644 Extension Commands:
1643 $ hg help -c schemes
1645 $ hg help -c schemes
1644 abort: no such help topic: schemes
1646 abort: no such help topic: schemes
1645 (try 'hg help --keyword schemes')
1647 (try 'hg help --keyword schemes')
1646 [255]
1648 [255]
1647 $ hg help -e schemes |head -1
1649 $ hg help -e schemes |head -1
1648 schemes extension - extend schemes with shortcuts to repository swarms
1650 schemes extension - extend schemes with shortcuts to repository swarms
1649 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1651 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1650 Commands:
1652 Commands:
1651 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1653 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1652 Extensions:
1654 Extensions:
1653 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1655 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1654 Extensions:
1656 Extensions:
1655 Commands:
1657 Commands:
1656 $ hg help -c commit > /dev/null
1658 $ hg help -c commit > /dev/null
1657 $ hg help -e -c commit > /dev/null
1659 $ hg help -e -c commit > /dev/null
1658 $ hg help -e commit
1660 $ hg help -e commit
1659 abort: no such help topic: commit
1661 abort: no such help topic: commit
1660 (try 'hg help --keyword commit')
1662 (try 'hg help --keyword commit')
1661 [255]
1663 [255]
1662
1664
1663 Test keyword search help
1665 Test keyword search help
1664
1666
1665 $ cat > prefixedname.py <<EOF
1667 $ cat > prefixedname.py <<EOF
1666 > '''matched against word "clone"
1668 > '''matched against word "clone"
1667 > '''
1669 > '''
1668 > EOF
1670 > EOF
1669 $ echo '[extensions]' >> $HGRCPATH
1671 $ echo '[extensions]' >> $HGRCPATH
1670 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1672 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1671 $ hg help -k clone
1673 $ hg help -k clone
1672 Topics:
1674 Topics:
1673
1675
1674 config Configuration Files
1676 config Configuration Files
1675 extensions Using Additional Features
1677 extensions Using Additional Features
1676 glossary Glossary
1678 glossary Glossary
1677 phases Working with Phases
1679 phases Working with Phases
1678 subrepos Subrepositories
1680 subrepos Subrepositories
1679 urls URL Paths
1681 urls URL Paths
1680
1682
1681 Commands:
1683 Commands:
1682
1684
1683 bookmarks create a new bookmark or list existing bookmarks
1685 bookmarks create a new bookmark or list existing bookmarks
1684 clone make a copy of an existing repository
1686 clone make a copy of an existing repository
1685 paths show aliases for remote repositories
1687 paths show aliases for remote repositories
1686 pull pull changes from the specified source
1688 pull pull changes from the specified source
1687 update update working directory (or switch revisions)
1689 update update working directory (or switch revisions)
1688
1690
1689 Extensions:
1691 Extensions:
1690
1692
1691 clonebundles advertise pre-generated bundles to seed clones
1693 clonebundles advertise pre-generated bundles to seed clones
1692 narrow create clones which fetch history data for subset of files
1694 narrow create clones which fetch history data for subset of files
1693 (EXPERIMENTAL)
1695 (EXPERIMENTAL)
1694 prefixedname matched against word "clone"
1696 prefixedname matched against word "clone"
1695 relink recreates hardlinks between repository clones
1697 relink recreates hardlinks between repository clones
1696
1698
1697 Extension Commands:
1699 Extension Commands:
1698
1700
1699 qclone clone main and patch repository at same time
1701 qclone clone main and patch repository at same time
1700
1702
1701 Test unfound topic
1703 Test unfound topic
1702
1704
1703 $ hg help nonexistingtopicthatwillneverexisteverever
1705 $ hg help nonexistingtopicthatwillneverexisteverever
1704 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1706 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1705 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1707 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1706 [255]
1708 [255]
1707
1709
1708 Test unfound keyword
1710 Test unfound keyword
1709
1711
1710 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1712 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1711 abort: no matches
1713 abort: no matches
1712 (try 'hg help' for a list of topics)
1714 (try 'hg help' for a list of topics)
1713 [255]
1715 [255]
1714
1716
1715 Test omit indicating for help
1717 Test omit indicating for help
1716
1718
1717 $ cat > addverboseitems.py <<EOF
1719 $ cat > addverboseitems.py <<EOF
1718 > r'''extension to test omit indicating.
1720 > r'''extension to test omit indicating.
1719 >
1721 >
1720 > This paragraph is never omitted (for extension)
1722 > This paragraph is never omitted (for extension)
1721 >
1723 >
1722 > .. container:: verbose
1724 > .. container:: verbose
1723 >
1725 >
1724 > This paragraph is omitted,
1726 > This paragraph is omitted,
1725 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1727 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1726 >
1728 >
1727 > This paragraph is never omitted, too (for extension)
1729 > This paragraph is never omitted, too (for extension)
1728 > '''
1730 > '''
1729 > from __future__ import absolute_import
1731 > from __future__ import absolute_import
1730 > from mercurial import commands, help
1732 > from mercurial import commands, help
1731 > testtopic = br"""This paragraph is never omitted (for topic).
1733 > testtopic = br"""This paragraph is never omitted (for topic).
1732 >
1734 >
1733 > .. container:: verbose
1735 > .. container:: verbose
1734 >
1736 >
1735 > This paragraph is omitted,
1737 > This paragraph is omitted,
1736 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1738 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1737 >
1739 >
1738 > This paragraph is never omitted, too (for topic)
1740 > This paragraph is never omitted, too (for topic)
1739 > """
1741 > """
1740 > def extsetup(ui):
1742 > def extsetup(ui):
1741 > help.helptable.append(([b"topic-containing-verbose"],
1743 > help.helptable.append(([b"topic-containing-verbose"],
1742 > b"This is the topic to test omit indicating.",
1744 > b"This is the topic to test omit indicating.",
1743 > lambda ui: testtopic))
1745 > lambda ui: testtopic))
1744 > EOF
1746 > EOF
1745 $ echo '[extensions]' >> $HGRCPATH
1747 $ echo '[extensions]' >> $HGRCPATH
1746 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1748 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1747 $ hg help addverboseitems
1749 $ hg help addverboseitems
1748 addverboseitems extension - extension to test omit indicating.
1750 addverboseitems extension - extension to test omit indicating.
1749
1751
1750 This paragraph is never omitted (for extension)
1752 This paragraph is never omitted (for extension)
1751
1753
1752 This paragraph is never omitted, too (for extension)
1754 This paragraph is never omitted, too (for extension)
1753
1755
1754 (some details hidden, use --verbose to show complete help)
1756 (some details hidden, use --verbose to show complete help)
1755
1757
1756 no commands defined
1758 no commands defined
1757 $ hg help -v addverboseitems
1759 $ hg help -v addverboseitems
1758 addverboseitems extension - extension to test omit indicating.
1760 addverboseitems extension - extension to test omit indicating.
1759
1761
1760 This paragraph is never omitted (for extension)
1762 This paragraph is never omitted (for extension)
1761
1763
1762 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1764 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1763 extension)
1765 extension)
1764
1766
1765 This paragraph is never omitted, too (for extension)
1767 This paragraph is never omitted, too (for extension)
1766
1768
1767 no commands defined
1769 no commands defined
1768 $ hg help topic-containing-verbose
1770 $ hg help topic-containing-verbose
1769 This is the topic to test omit indicating.
1771 This is the topic to test omit indicating.
1770 """"""""""""""""""""""""""""""""""""""""""
1772 """"""""""""""""""""""""""""""""""""""""""
1771
1773
1772 This paragraph is never omitted (for topic).
1774 This paragraph is never omitted (for topic).
1773
1775
1774 This paragraph is never omitted, too (for topic)
1776 This paragraph is never omitted, too (for topic)
1775
1777
1776 (some details hidden, use --verbose to show complete help)
1778 (some details hidden, use --verbose to show complete help)
1777 $ hg help -v topic-containing-verbose
1779 $ hg help -v topic-containing-verbose
1778 This is the topic to test omit indicating.
1780 This is the topic to test omit indicating.
1779 """"""""""""""""""""""""""""""""""""""""""
1781 """"""""""""""""""""""""""""""""""""""""""
1780
1782
1781 This paragraph is never omitted (for topic).
1783 This paragraph is never omitted (for topic).
1782
1784
1783 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1785 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1784 topic)
1786 topic)
1785
1787
1786 This paragraph is never omitted, too (for topic)
1788 This paragraph is never omitted, too (for topic)
1787
1789
1788 Test section lookup
1790 Test section lookup
1789
1791
1790 $ hg help revset.merge
1792 $ hg help revset.merge
1791 "merge()"
1793 "merge()"
1792 Changeset is a merge changeset.
1794 Changeset is a merge changeset.
1793
1795
1794 $ hg help glossary.dag
1796 $ hg help glossary.dag
1795 DAG
1797 DAG
1796 The repository of changesets of a distributed version control system
1798 The repository of changesets of a distributed version control system
1797 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1799 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1798 of nodes and edges, where nodes correspond to changesets and edges
1800 of nodes and edges, where nodes correspond to changesets and edges
1799 imply a parent -> child relation. This graph can be visualized by
1801 imply a parent -> child relation. This graph can be visualized by
1800 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1802 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1801 limited by the requirement for children to have at most two parents.
1803 limited by the requirement for children to have at most two parents.
1802
1804
1803
1805
1804 $ hg help hgrc.paths
1806 $ hg help hgrc.paths
1805 "paths"
1807 "paths"
1806 -------
1808 -------
1807
1809
1808 Assigns symbolic names and behavior to repositories.
1810 Assigns symbolic names and behavior to repositories.
1809
1811
1810 Options are symbolic names defining the URL or directory that is the
1812 Options are symbolic names defining the URL or directory that is the
1811 location of the repository. Example:
1813 location of the repository. Example:
1812
1814
1813 [paths]
1815 [paths]
1814 my_server = https://example.com/my_repo
1816 my_server = https://example.com/my_repo
1815 local_path = /home/me/repo
1817 local_path = /home/me/repo
1816
1818
1817 These symbolic names can be used from the command line. To pull from
1819 These symbolic names can be used from the command line. To pull from
1818 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1820 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1819 local_path'.
1821 local_path'.
1820
1822
1821 Options containing colons (":") denote sub-options that can influence
1823 Options containing colons (":") denote sub-options that can influence
1822 behavior for that specific path. Example:
1824 behavior for that specific path. Example:
1823
1825
1824 [paths]
1826 [paths]
1825 my_server = https://example.com/my_path
1827 my_server = https://example.com/my_path
1826 my_server:pushurl = ssh://example.com/my_path
1828 my_server:pushurl = ssh://example.com/my_path
1827
1829
1828 The following sub-options can be defined:
1830 The following sub-options can be defined:
1829
1831
1830 "pushurl"
1832 "pushurl"
1831 The URL to use for push operations. If not defined, the location
1833 The URL to use for push operations. If not defined, the location
1832 defined by the path's main entry is used.
1834 defined by the path's main entry is used.
1833
1835
1834 "pushrev"
1836 "pushrev"
1835 A revset defining which revisions to push by default.
1837 A revset defining which revisions to push by default.
1836
1838
1837 When 'hg push' is executed without a "-r" argument, the revset defined
1839 When 'hg push' is executed without a "-r" argument, the revset defined
1838 by this sub-option is evaluated to determine what to push.
1840 by this sub-option is evaluated to determine what to push.
1839
1841
1840 For example, a value of "." will push the working directory's revision
1842 For example, a value of "." will push the working directory's revision
1841 by default.
1843 by default.
1842
1844
1843 Revsets specifying bookmarks will not result in the bookmark being
1845 Revsets specifying bookmarks will not result in the bookmark being
1844 pushed.
1846 pushed.
1845
1847
1846 The following special named paths exist:
1848 The following special named paths exist:
1847
1849
1848 "default"
1850 "default"
1849 The URL or directory to use when no source or remote is specified.
1851 The URL or directory to use when no source or remote is specified.
1850
1852
1851 'hg clone' will automatically define this path to the location the
1853 'hg clone' will automatically define this path to the location the
1852 repository was cloned from.
1854 repository was cloned from.
1853
1855
1854 "default-push"
1856 "default-push"
1855 (deprecated) The URL or directory for the default 'hg push' location.
1857 (deprecated) The URL or directory for the default 'hg push' location.
1856 "default:pushurl" should be used instead.
1858 "default:pushurl" should be used instead.
1857
1859
1858 $ hg help glossary.mcguffin
1860 $ hg help glossary.mcguffin
1859 abort: help section not found: glossary.mcguffin
1861 abort: help section not found: glossary.mcguffin
1860 [255]
1862 [255]
1861
1863
1862 $ hg help glossary.mc.guffin
1864 $ hg help glossary.mc.guffin
1863 abort: help section not found: glossary.mc.guffin
1865 abort: help section not found: glossary.mc.guffin
1864 [255]
1866 [255]
1865
1867
1866 $ hg help template.files
1868 $ hg help template.files
1867 files List of strings. All files modified, added, or removed by
1869 files List of strings. All files modified, added, or removed by
1868 this changeset.
1870 this changeset.
1869 files(pattern)
1871 files(pattern)
1870 All files of the current changeset matching the pattern. See
1872 All files of the current changeset matching the pattern. See
1871 'hg help patterns'.
1873 'hg help patterns'.
1872
1874
1873 Test section lookup by translated message
1875 Test section lookup by translated message
1874
1876
1875 str.lower() instead of encoding.lower(str) on translated message might
1877 str.lower() instead of encoding.lower(str) on translated message might
1876 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1878 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1877 as the second or later byte of multi-byte character.
1879 as the second or later byte of multi-byte character.
1878
1880
1879 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1881 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1880 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1882 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1881 replacement makes message meaningless.
1883 replacement makes message meaningless.
1882
1884
1883 This tests that section lookup by translated string isn't broken by
1885 This tests that section lookup by translated string isn't broken by
1884 such str.lower().
1886 such str.lower().
1885
1887
1886 $ "$PYTHON" <<EOF
1888 $ "$PYTHON" <<EOF
1887 > def escape(s):
1889 > def escape(s):
1888 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1890 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1889 > # translation of "record" in ja_JP.cp932
1891 > # translation of "record" in ja_JP.cp932
1890 > upper = b"\x8bL\x98^"
1892 > upper = b"\x8bL\x98^"
1891 > # str.lower()-ed section name should be treated as different one
1893 > # str.lower()-ed section name should be treated as different one
1892 > lower = b"\x8bl\x98^"
1894 > lower = b"\x8bl\x98^"
1893 > with open('ambiguous.py', 'wb') as fp:
1895 > with open('ambiguous.py', 'wb') as fp:
1894 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1896 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1895 > u'''summary of extension
1897 > u'''summary of extension
1896 >
1898 >
1897 > %s
1899 > %s
1898 > ----
1900 > ----
1899 >
1901 >
1900 > Upper name should show only this message
1902 > Upper name should show only this message
1901 >
1903 >
1902 > %s
1904 > %s
1903 > ----
1905 > ----
1904 >
1906 >
1905 > Lower name should show only this message
1907 > Lower name should show only this message
1906 >
1908 >
1907 > subsequent section
1909 > subsequent section
1908 > ------------------
1910 > ------------------
1909 >
1911 >
1910 > This should be hidden at 'hg help ambiguous' with section name.
1912 > This should be hidden at 'hg help ambiguous' with section name.
1911 > '''
1913 > '''
1912 > """ % (escape(upper), escape(lower)))
1914 > """ % (escape(upper), escape(lower)))
1913 > EOF
1915 > EOF
1914
1916
1915 $ cat >> $HGRCPATH <<EOF
1917 $ cat >> $HGRCPATH <<EOF
1916 > [extensions]
1918 > [extensions]
1917 > ambiguous = ./ambiguous.py
1919 > ambiguous = ./ambiguous.py
1918 > EOF
1920 > EOF
1919
1921
1920 $ "$PYTHON" <<EOF | sh
1922 $ "$PYTHON" <<EOF | sh
1921 > from mercurial.utils import procutil
1923 > from mercurial.utils import procutil
1922 > upper = b"\x8bL\x98^"
1924 > upper = b"\x8bL\x98^"
1923 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1925 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1924 > EOF
1926 > EOF
1925 \x8bL\x98^ (esc)
1927 \x8bL\x98^ (esc)
1926 ----
1928 ----
1927
1929
1928 Upper name should show only this message
1930 Upper name should show only this message
1929
1931
1930
1932
1931 $ "$PYTHON" <<EOF | sh
1933 $ "$PYTHON" <<EOF | sh
1932 > from mercurial.utils import procutil
1934 > from mercurial.utils import procutil
1933 > lower = b"\x8bl\x98^"
1935 > lower = b"\x8bl\x98^"
1934 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1936 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1935 > EOF
1937 > EOF
1936 \x8bl\x98^ (esc)
1938 \x8bl\x98^ (esc)
1937 ----
1939 ----
1938
1940
1939 Lower name should show only this message
1941 Lower name should show only this message
1940
1942
1941
1943
1942 $ cat >> $HGRCPATH <<EOF
1944 $ cat >> $HGRCPATH <<EOF
1943 > [extensions]
1945 > [extensions]
1944 > ambiguous = !
1946 > ambiguous = !
1945 > EOF
1947 > EOF
1946
1948
1947 Show help content of disabled extensions
1949 Show help content of disabled extensions
1948
1950
1949 $ cat >> $HGRCPATH <<EOF
1951 $ cat >> $HGRCPATH <<EOF
1950 > [extensions]
1952 > [extensions]
1951 > ambiguous = !./ambiguous.py
1953 > ambiguous = !./ambiguous.py
1952 > EOF
1954 > EOF
1953 $ hg help -e ambiguous
1955 $ hg help -e ambiguous
1954 ambiguous extension - (no help text available)
1956 ambiguous extension - (no help text available)
1955
1957
1956 (use 'hg help extensions' for information on enabling extensions)
1958 (use 'hg help extensions' for information on enabling extensions)
1957
1959
1958 Test dynamic list of merge tools only shows up once
1960 Test dynamic list of merge tools only shows up once
1959 $ hg help merge-tools
1961 $ hg help merge-tools
1960 Merge Tools
1962 Merge Tools
1961 """""""""""
1963 """""""""""
1962
1964
1963 To merge files Mercurial uses merge tools.
1965 To merge files Mercurial uses merge tools.
1964
1966
1965 A merge tool combines two different versions of a file into a merged file.
1967 A merge tool combines two different versions of a file into a merged file.
1966 Merge tools are given the two files and the greatest common ancestor of
1968 Merge tools are given the two files and the greatest common ancestor of
1967 the two file versions, so they can determine the changes made on both
1969 the two file versions, so they can determine the changes made on both
1968 branches.
1970 branches.
1969
1971
1970 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1972 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1971 backout' and in several extensions.
1973 backout' and in several extensions.
1972
1974
1973 Usually, the merge tool tries to automatically reconcile the files by
1975 Usually, the merge tool tries to automatically reconcile the files by
1974 combining all non-overlapping changes that occurred separately in the two
1976 combining all non-overlapping changes that occurred separately in the two
1975 different evolutions of the same initial base file. Furthermore, some
1977 different evolutions of the same initial base file. Furthermore, some
1976 interactive merge programs make it easier to manually resolve conflicting
1978 interactive merge programs make it easier to manually resolve conflicting
1977 merges, either in a graphical way, or by inserting some conflict markers.
1979 merges, either in a graphical way, or by inserting some conflict markers.
1978 Mercurial does not include any interactive merge programs but relies on
1980 Mercurial does not include any interactive merge programs but relies on
1979 external tools for that.
1981 external tools for that.
1980
1982
1981 Available merge tools
1983 Available merge tools
1982 =====================
1984 =====================
1983
1985
1984 External merge tools and their properties are configured in the merge-
1986 External merge tools and their properties are configured in the merge-
1985 tools configuration section - see hgrc(5) - but they can often just be
1987 tools configuration section - see hgrc(5) - but they can often just be
1986 named by their executable.
1988 named by their executable.
1987
1989
1988 A merge tool is generally usable if its executable can be found on the
1990 A merge tool is generally usable if its executable can be found on the
1989 system and if it can handle the merge. The executable is found if it is an
1991 system and if it can handle the merge. The executable is found if it is an
1990 absolute or relative executable path or the name of an application in the
1992 absolute or relative executable path or the name of an application in the
1991 executable search path. The tool is assumed to be able to handle the merge
1993 executable search path. The tool is assumed to be able to handle the merge
1992 if it can handle symlinks if the file is a symlink, if it can handle
1994 if it can handle symlinks if the file is a symlink, if it can handle
1993 binary files if the file is binary, and if a GUI is available if the tool
1995 binary files if the file is binary, and if a GUI is available if the tool
1994 requires a GUI.
1996 requires a GUI.
1995
1997
1996 There are some internal merge tools which can be used. The internal merge
1998 There are some internal merge tools which can be used. The internal merge
1997 tools are:
1999 tools are:
1998
2000
1999 ":dump"
2001 ":dump"
2000 Creates three versions of the files to merge, containing the contents of
2002 Creates three versions of the files to merge, containing the contents of
2001 local, other and base. These files can then be used to perform a merge
2003 local, other and base. These files can then be used to perform a merge
2002 manually. If the file to be merged is named "a.txt", these files will
2004 manually. If the file to be merged is named "a.txt", these files will
2003 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2005 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2004 they will be placed in the same directory as "a.txt".
2006 they will be placed in the same directory as "a.txt".
2005
2007
2006 This implies premerge. Therefore, files aren't dumped, if premerge runs
2008 This implies premerge. Therefore, files aren't dumped, if premerge runs
2007 successfully. Use :forcedump to forcibly write files out.
2009 successfully. Use :forcedump to forcibly write files out.
2008
2010
2009 (actual capabilities: binary, symlink)
2011 (actual capabilities: binary, symlink)
2010
2012
2011 ":fail"
2013 ":fail"
2012 Rather than attempting to merge files that were modified on both
2014 Rather than attempting to merge files that were modified on both
2013 branches, it marks them as unresolved. The resolve command must be used
2015 branches, it marks them as unresolved. The resolve command must be used
2014 to resolve these conflicts.
2016 to resolve these conflicts.
2015
2017
2016 (actual capabilities: binary, symlink)
2018 (actual capabilities: binary, symlink)
2017
2019
2018 ":forcedump"
2020 ":forcedump"
2019 Creates three versions of the files as same as :dump, but omits
2021 Creates three versions of the files as same as :dump, but omits
2020 premerge.
2022 premerge.
2021
2023
2022 (actual capabilities: binary, symlink)
2024 (actual capabilities: binary, symlink)
2023
2025
2024 ":local"
2026 ":local"
2025 Uses the local 'p1()' version of files as the merged version.
2027 Uses the local 'p1()' version of files as the merged version.
2026
2028
2027 (actual capabilities: binary, symlink)
2029 (actual capabilities: binary, symlink)
2028
2030
2029 ":merge"
2031 ":merge"
2030 Uses the internal non-interactive simple merge algorithm for merging
2032 Uses the internal non-interactive simple merge algorithm for merging
2031 files. It will fail if there are any conflicts and leave markers in the
2033 files. It will fail if there are any conflicts and leave markers in the
2032 partially merged file. Markers will have two sections, one for each side
2034 partially merged file. Markers will have two sections, one for each side
2033 of merge.
2035 of merge.
2034
2036
2035 ":merge-local"
2037 ":merge-local"
2036 Like :merge, but resolve all conflicts non-interactively in favor of the
2038 Like :merge, but resolve all conflicts non-interactively in favor of the
2037 local 'p1()' changes.
2039 local 'p1()' changes.
2038
2040
2039 ":merge-other"
2041 ":merge-other"
2040 Like :merge, but resolve all conflicts non-interactively in favor of the
2042 Like :merge, but resolve all conflicts non-interactively in favor of the
2041 other 'p2()' changes.
2043 other 'p2()' changes.
2042
2044
2043 ":merge3"
2045 ":merge3"
2044 Uses the internal non-interactive simple merge algorithm for merging
2046 Uses the internal non-interactive simple merge algorithm for merging
2045 files. It will fail if there are any conflicts and leave markers in the
2047 files. It will fail if there are any conflicts and leave markers in the
2046 partially merged file. Marker will have three sections, one from each
2048 partially merged file. Marker will have three sections, one from each
2047 side of the merge and one for the base content.
2049 side of the merge and one for the base content.
2048
2050
2049 ":other"
2051 ":other"
2050 Uses the other 'p2()' version of files as the merged version.
2052 Uses the other 'p2()' version of files as the merged version.
2051
2053
2052 (actual capabilities: binary, symlink)
2054 (actual capabilities: binary, symlink)
2053
2055
2054 ":prompt"
2056 ":prompt"
2055 Asks the user which of the local 'p1()' or the other 'p2()' version to
2057 Asks the user which of the local 'p1()' or the other 'p2()' version to
2056 keep as the merged version.
2058 keep as the merged version.
2057
2059
2058 (actual capabilities: binary, symlink)
2060 (actual capabilities: binary, symlink)
2059
2061
2060 ":tagmerge"
2062 ":tagmerge"
2061 Uses the internal tag merge algorithm (experimental).
2063 Uses the internal tag merge algorithm (experimental).
2062
2064
2063 ":union"
2065 ":union"
2064 Uses the internal non-interactive simple merge algorithm for merging
2066 Uses the internal non-interactive simple merge algorithm for merging
2065 files. It will use both left and right sides for conflict regions. No
2067 files. It will use both left and right sides for conflict regions. No
2066 markers are inserted.
2068 markers are inserted.
2067
2069
2068 Internal tools are always available and do not require a GUI but will by
2070 Internal tools are always available and do not require a GUI but will by
2069 default not handle symlinks or binary files. See next section for detail
2071 default not handle symlinks or binary files. See next section for detail
2070 about "actual capabilities" described above.
2072 about "actual capabilities" described above.
2071
2073
2072 Choosing a merge tool
2074 Choosing a merge tool
2073 =====================
2075 =====================
2074
2076
2075 Mercurial uses these rules when deciding which merge tool to use:
2077 Mercurial uses these rules when deciding which merge tool to use:
2076
2078
2077 1. If a tool has been specified with the --tool option to merge or
2079 1. If a tool has been specified with the --tool option to merge or
2078 resolve, it is used. If it is the name of a tool in the merge-tools
2080 resolve, it is used. If it is the name of a tool in the merge-tools
2079 configuration, its configuration is used. Otherwise the specified tool
2081 configuration, its configuration is used. Otherwise the specified tool
2080 must be executable by the shell.
2082 must be executable by the shell.
2081 2. If the "HGMERGE" environment variable is present, its value is used and
2083 2. If the "HGMERGE" environment variable is present, its value is used and
2082 must be executable by the shell.
2084 must be executable by the shell.
2083 3. If the filename of the file to be merged matches any of the patterns in
2085 3. If the filename of the file to be merged matches any of the patterns in
2084 the merge-patterns configuration section, the first usable merge tool
2086 the merge-patterns configuration section, the first usable merge tool
2085 corresponding to a matching pattern is used.
2087 corresponding to a matching pattern is used.
2086 4. If ui.merge is set it will be considered next. If the value is not the
2088 4. If ui.merge is set it will be considered next. If the value is not the
2087 name of a configured tool, the specified value is used and must be
2089 name of a configured tool, the specified value is used and must be
2088 executable by the shell. Otherwise the named tool is used if it is
2090 executable by the shell. Otherwise the named tool is used if it is
2089 usable.
2091 usable.
2090 5. If any usable merge tools are present in the merge-tools configuration
2092 5. If any usable merge tools are present in the merge-tools configuration
2091 section, the one with the highest priority is used.
2093 section, the one with the highest priority is used.
2092 6. If a program named "hgmerge" can be found on the system, it is used -
2094 6. If a program named "hgmerge" can be found on the system, it is used -
2093 but it will by default not be used for symlinks and binary files.
2095 but it will by default not be used for symlinks and binary files.
2094 7. If the file to be merged is not binary and is not a symlink, then
2096 7. If the file to be merged is not binary and is not a symlink, then
2095 internal ":merge" is used.
2097 internal ":merge" is used.
2096 8. Otherwise, ":prompt" is used.
2098 8. Otherwise, ":prompt" is used.
2097
2099
2098 For historical reason, Mercurial treats merge tools as below while
2100 For historical reason, Mercurial treats merge tools as below while
2099 examining rules above.
2101 examining rules above.
2100
2102
2101 step specified via binary symlink
2103 step specified via binary symlink
2102 ----------------------------------
2104 ----------------------------------
2103 1. --tool o/o o/o
2105 1. --tool o/o o/o
2104 2. HGMERGE o/o o/o
2106 2. HGMERGE o/o o/o
2105 3. merge-patterns o/o(*) x/?(*)
2107 3. merge-patterns o/o(*) x/?(*)
2106 4. ui.merge x/?(*) x/?(*)
2108 4. ui.merge x/?(*) x/?(*)
2107
2109
2108 Each capability column indicates Mercurial behavior for internal/external
2110 Each capability column indicates Mercurial behavior for internal/external
2109 merge tools at examining each rule.
2111 merge tools at examining each rule.
2110
2112
2111 - "o": "assume that a tool has capability"
2113 - "o": "assume that a tool has capability"
2112 - "x": "assume that a tool does not have capability"
2114 - "x": "assume that a tool does not have capability"
2113 - "?": "check actual capability of a tool"
2115 - "?": "check actual capability of a tool"
2114
2116
2115 If "merge.strict-capability-check" configuration is true, Mercurial checks
2117 If "merge.strict-capability-check" configuration is true, Mercurial checks
2116 capabilities of merge tools strictly in (*) cases above (= each capability
2118 capabilities of merge tools strictly in (*) cases above (= each capability
2117 column becomes "?/?"). It is false by default for backward compatibility.
2119 column becomes "?/?"). It is false by default for backward compatibility.
2118
2120
2119 Note:
2121 Note:
2120 After selecting a merge program, Mercurial will by default attempt to
2122 After selecting a merge program, Mercurial will by default attempt to
2121 merge the files using a simple merge algorithm first. Only if it
2123 merge the files using a simple merge algorithm first. Only if it
2122 doesn't succeed because of conflicting changes will Mercurial actually
2124 doesn't succeed because of conflicting changes will Mercurial actually
2123 execute the merge program. Whether to use the simple merge algorithm
2125 execute the merge program. Whether to use the simple merge algorithm
2124 first can be controlled by the premerge setting of the merge tool.
2126 first can be controlled by the premerge setting of the merge tool.
2125 Premerge is enabled by default unless the file is binary or a symlink.
2127 Premerge is enabled by default unless the file is binary or a symlink.
2126
2128
2127 See the merge-tools and ui sections of hgrc(5) for details on the
2129 See the merge-tools and ui sections of hgrc(5) for details on the
2128 configuration of merge tools.
2130 configuration of merge tools.
2129
2131
2130 Compression engines listed in `hg help bundlespec`
2132 Compression engines listed in `hg help bundlespec`
2131
2133
2132 $ hg help bundlespec | grep gzip
2134 $ hg help bundlespec | grep gzip
2133 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2135 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2134 An algorithm that produces smaller bundles than "gzip".
2136 An algorithm that produces smaller bundles than "gzip".
2135 This engine will likely produce smaller bundles than "gzip" but will be
2137 This engine will likely produce smaller bundles than "gzip" but will be
2136 "gzip"
2138 "gzip"
2137 better compression than "gzip". It also frequently yields better (?)
2139 better compression than "gzip". It also frequently yields better (?)
2138
2140
2139 Test usage of section marks in help documents
2141 Test usage of section marks in help documents
2140
2142
2141 $ cd "$TESTDIR"/../doc
2143 $ cd "$TESTDIR"/../doc
2142 $ "$PYTHON" check-seclevel.py
2144 $ "$PYTHON" check-seclevel.py
2143 $ cd $TESTTMP
2145 $ cd $TESTTMP
2144
2146
2145 #if serve
2147 #if serve
2146
2148
2147 Test the help pages in hgweb.
2149 Test the help pages in hgweb.
2148
2150
2149 Dish up an empty repo; serve it cold.
2151 Dish up an empty repo; serve it cold.
2150
2152
2151 $ hg init "$TESTTMP/test"
2153 $ hg init "$TESTTMP/test"
2152 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2154 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2153 $ cat hg.pid >> $DAEMON_PIDS
2155 $ cat hg.pid >> $DAEMON_PIDS
2154
2156
2155 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2157 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2156 200 Script output follows
2158 200 Script output follows
2157
2159
2158 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2160 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2159 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2161 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2160 <head>
2162 <head>
2161 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2163 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2162 <meta name="robots" content="index, nofollow" />
2164 <meta name="robots" content="index, nofollow" />
2163 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2165 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2164 <script type="text/javascript" src="/static/mercurial.js"></script>
2166 <script type="text/javascript" src="/static/mercurial.js"></script>
2165
2167
2166 <title>Help: Index</title>
2168 <title>Help: Index</title>
2167 </head>
2169 </head>
2168 <body>
2170 <body>
2169
2171
2170 <div class="container">
2172 <div class="container">
2171 <div class="menu">
2173 <div class="menu">
2172 <div class="logo">
2174 <div class="logo">
2173 <a href="https://mercurial-scm.org/">
2175 <a href="https://mercurial-scm.org/">
2174 <img src="/static/hglogo.png" alt="mercurial" /></a>
2176 <img src="/static/hglogo.png" alt="mercurial" /></a>
2175 </div>
2177 </div>
2176 <ul>
2178 <ul>
2177 <li><a href="/shortlog">log</a></li>
2179 <li><a href="/shortlog">log</a></li>
2178 <li><a href="/graph">graph</a></li>
2180 <li><a href="/graph">graph</a></li>
2179 <li><a href="/tags">tags</a></li>
2181 <li><a href="/tags">tags</a></li>
2180 <li><a href="/bookmarks">bookmarks</a></li>
2182 <li><a href="/bookmarks">bookmarks</a></li>
2181 <li><a href="/branches">branches</a></li>
2183 <li><a href="/branches">branches</a></li>
2182 </ul>
2184 </ul>
2183 <ul>
2185 <ul>
2184 <li class="active">help</li>
2186 <li class="active">help</li>
2185 </ul>
2187 </ul>
2186 </div>
2188 </div>
2187
2189
2188 <div class="main">
2190 <div class="main">
2189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2191 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2190
2192
2191 <form class="search" action="/log">
2193 <form class="search" action="/log">
2192
2194
2193 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2195 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2194 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2196 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2195 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2197 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2196 </form>
2198 </form>
2197 <table class="bigtable">
2199 <table class="bigtable">
2198 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2200 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2199
2201
2200 <tr><td>
2202 <tr><td>
2201 <a href="/help/bundlespec">
2203 <a href="/help/bundlespec">
2202 bundlespec
2204 bundlespec
2203 </a>
2205 </a>
2204 </td><td>
2206 </td><td>
2205 Bundle File Formats
2207 Bundle File Formats
2206 </td></tr>
2208 </td></tr>
2207 <tr><td>
2209 <tr><td>
2208 <a href="/help/color">
2210 <a href="/help/color">
2209 color
2211 color
2210 </a>
2212 </a>
2211 </td><td>
2213 </td><td>
2212 Colorizing Outputs
2214 Colorizing Outputs
2213 </td></tr>
2215 </td></tr>
2214 <tr><td>
2216 <tr><td>
2215 <a href="/help/config">
2217 <a href="/help/config">
2216 config
2218 config
2217 </a>
2219 </a>
2218 </td><td>
2220 </td><td>
2219 Configuration Files
2221 Configuration Files
2220 </td></tr>
2222 </td></tr>
2221 <tr><td>
2223 <tr><td>
2222 <a href="/help/dates">
2224 <a href="/help/dates">
2223 dates
2225 dates
2224 </a>
2226 </a>
2225 </td><td>
2227 </td><td>
2226 Date Formats
2228 Date Formats
2227 </td></tr>
2229 </td></tr>
2228 <tr><td>
2230 <tr><td>
2229 <a href="/help/deprecated">
2231 <a href="/help/deprecated">
2230 deprecated
2232 deprecated
2231 </a>
2233 </a>
2232 </td><td>
2234 </td><td>
2233 Deprecated Features
2235 Deprecated Features
2234 </td></tr>
2236 </td></tr>
2235 <tr><td>
2237 <tr><td>
2236 <a href="/help/diffs">
2238 <a href="/help/diffs">
2237 diffs
2239 diffs
2238 </a>
2240 </a>
2239 </td><td>
2241 </td><td>
2240 Diff Formats
2242 Diff Formats
2241 </td></tr>
2243 </td></tr>
2242 <tr><td>
2244 <tr><td>
2243 <a href="/help/environment">
2245 <a href="/help/environment">
2244 environment
2246 environment
2245 </a>
2247 </a>
2246 </td><td>
2248 </td><td>
2247 Environment Variables
2249 Environment Variables
2248 </td></tr>
2250 </td></tr>
2249 <tr><td>
2251 <tr><td>
2250 <a href="/help/extensions">
2252 <a href="/help/extensions">
2251 extensions
2253 extensions
2252 </a>
2254 </a>
2253 </td><td>
2255 </td><td>
2254 Using Additional Features
2256 Using Additional Features
2255 </td></tr>
2257 </td></tr>
2256 <tr><td>
2258 <tr><td>
2257 <a href="/help/filesets">
2259 <a href="/help/filesets">
2258 filesets
2260 filesets
2259 </a>
2261 </a>
2260 </td><td>
2262 </td><td>
2261 Specifying File Sets
2263 Specifying File Sets
2262 </td></tr>
2264 </td></tr>
2263 <tr><td>
2265 <tr><td>
2264 <a href="/help/flags">
2266 <a href="/help/flags">
2265 flags
2267 flags
2266 </a>
2268 </a>
2267 </td><td>
2269 </td><td>
2268 Command-line flags
2270 Command-line flags
2269 </td></tr>
2271 </td></tr>
2270 <tr><td>
2272 <tr><td>
2271 <a href="/help/glossary">
2273 <a href="/help/glossary">
2272 glossary
2274 glossary
2273 </a>
2275 </a>
2274 </td><td>
2276 </td><td>
2275 Glossary
2277 Glossary
2276 </td></tr>
2278 </td></tr>
2277 <tr><td>
2279 <tr><td>
2278 <a href="/help/hgignore">
2280 <a href="/help/hgignore">
2279 hgignore
2281 hgignore
2280 </a>
2282 </a>
2281 </td><td>
2283 </td><td>
2282 Syntax for Mercurial Ignore Files
2284 Syntax for Mercurial Ignore Files
2283 </td></tr>
2285 </td></tr>
2284 <tr><td>
2286 <tr><td>
2285 <a href="/help/hgweb">
2287 <a href="/help/hgweb">
2286 hgweb
2288 hgweb
2287 </a>
2289 </a>
2288 </td><td>
2290 </td><td>
2289 Configuring hgweb
2291 Configuring hgweb
2290 </td></tr>
2292 </td></tr>
2291 <tr><td>
2293 <tr><td>
2292 <a href="/help/internals">
2294 <a href="/help/internals">
2293 internals
2295 internals
2294 </a>
2296 </a>
2295 </td><td>
2297 </td><td>
2296 Technical implementation topics
2298 Technical implementation topics
2297 </td></tr>
2299 </td></tr>
2298 <tr><td>
2300 <tr><td>
2299 <a href="/help/merge-tools">
2301 <a href="/help/merge-tools">
2300 merge-tools
2302 merge-tools
2301 </a>
2303 </a>
2302 </td><td>
2304 </td><td>
2303 Merge Tools
2305 Merge Tools
2304 </td></tr>
2306 </td></tr>
2305 <tr><td>
2307 <tr><td>
2306 <a href="/help/pager">
2308 <a href="/help/pager">
2307 pager
2309 pager
2308 </a>
2310 </a>
2309 </td><td>
2311 </td><td>
2310 Pager Support
2312 Pager Support
2311 </td></tr>
2313 </td></tr>
2312 <tr><td>
2314 <tr><td>
2313 <a href="/help/patterns">
2315 <a href="/help/patterns">
2314 patterns
2316 patterns
2315 </a>
2317 </a>
2316 </td><td>
2318 </td><td>
2317 File Name Patterns
2319 File Name Patterns
2318 </td></tr>
2320 </td></tr>
2319 <tr><td>
2321 <tr><td>
2320 <a href="/help/phases">
2322 <a href="/help/phases">
2321 phases
2323 phases
2322 </a>
2324 </a>
2323 </td><td>
2325 </td><td>
2324 Working with Phases
2326 Working with Phases
2325 </td></tr>
2327 </td></tr>
2326 <tr><td>
2328 <tr><td>
2327 <a href="/help/revisions">
2329 <a href="/help/revisions">
2328 revisions
2330 revisions
2329 </a>
2331 </a>
2330 </td><td>
2332 </td><td>
2331 Specifying Revisions
2333 Specifying Revisions
2332 </td></tr>
2334 </td></tr>
2333 <tr><td>
2335 <tr><td>
2334 <a href="/help/scripting">
2336 <a href="/help/scripting">
2335 scripting
2337 scripting
2336 </a>
2338 </a>
2337 </td><td>
2339 </td><td>
2338 Using Mercurial from scripts and automation
2340 Using Mercurial from scripts and automation
2339 </td></tr>
2341 </td></tr>
2340 <tr><td>
2342 <tr><td>
2341 <a href="/help/subrepos">
2343 <a href="/help/subrepos">
2342 subrepos
2344 subrepos
2343 </a>
2345 </a>
2344 </td><td>
2346 </td><td>
2345 Subrepositories
2347 Subrepositories
2346 </td></tr>
2348 </td></tr>
2347 <tr><td>
2349 <tr><td>
2348 <a href="/help/templating">
2350 <a href="/help/templating">
2349 templating
2351 templating
2350 </a>
2352 </a>
2351 </td><td>
2353 </td><td>
2352 Template Usage
2354 Template Usage
2353 </td></tr>
2355 </td></tr>
2354 <tr><td>
2356 <tr><td>
2355 <a href="/help/urls">
2357 <a href="/help/urls">
2356 urls
2358 urls
2357 </a>
2359 </a>
2358 </td><td>
2360 </td><td>
2359 URL Paths
2361 URL Paths
2360 </td></tr>
2362 </td></tr>
2361 <tr><td>
2363 <tr><td>
2362 <a href="/help/topic-containing-verbose">
2364 <a href="/help/topic-containing-verbose">
2363 topic-containing-verbose
2365 topic-containing-verbose
2364 </a>
2366 </a>
2365 </td><td>
2367 </td><td>
2366 This is the topic to test omit indicating.
2368 This is the topic to test omit indicating.
2367 </td></tr>
2369 </td></tr>
2368
2370
2369
2371
2370 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2372 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2371
2373
2372 <tr><td>
2374 <tr><td>
2373 <a href="/help/abort">
2375 <a href="/help/abort">
2374 abort
2376 abort
2375 </a>
2377 </a>
2376 </td><td>
2378 </td><td>
2377 abort an unfinished operation (EXPERIMENTAL)
2379 abort an unfinished operation (EXPERIMENTAL)
2378 </td></tr>
2380 </td></tr>
2379 <tr><td>
2381 <tr><td>
2380 <a href="/help/add">
2382 <a href="/help/add">
2381 add
2383 add
2382 </a>
2384 </a>
2383 </td><td>
2385 </td><td>
2384 add the specified files on the next commit
2386 add the specified files on the next commit
2385 </td></tr>
2387 </td></tr>
2386 <tr><td>
2388 <tr><td>
2387 <a href="/help/annotate">
2389 <a href="/help/annotate">
2388 annotate
2390 annotate
2389 </a>
2391 </a>
2390 </td><td>
2392 </td><td>
2391 show changeset information by line for each file
2393 show changeset information by line for each file
2392 </td></tr>
2394 </td></tr>
2393 <tr><td>
2395 <tr><td>
2394 <a href="/help/clone">
2396 <a href="/help/clone">
2395 clone
2397 clone
2396 </a>
2398 </a>
2397 </td><td>
2399 </td><td>
2398 make a copy of an existing repository
2400 make a copy of an existing repository
2399 </td></tr>
2401 </td></tr>
2400 <tr><td>
2402 <tr><td>
2401 <a href="/help/commit">
2403 <a href="/help/commit">
2402 commit
2404 commit
2403 </a>
2405 </a>
2404 </td><td>
2406 </td><td>
2405 commit the specified files or all outstanding changes
2407 commit the specified files or all outstanding changes
2406 </td></tr>
2408 </td></tr>
2407 <tr><td>
2409 <tr><td>
2408 <a href="/help/continue">
2410 <a href="/help/continue">
2409 continue
2411 continue
2410 </a>
2412 </a>
2411 </td><td>
2413 </td><td>
2412 resumes an interrupted operation (EXPERIMENTAL)
2414 resumes an interrupted operation (EXPERIMENTAL)
2413 </td></tr>
2415 </td></tr>
2414 <tr><td>
2416 <tr><td>
2415 <a href="/help/diff">
2417 <a href="/help/diff">
2416 diff
2418 diff
2417 </a>
2419 </a>
2418 </td><td>
2420 </td><td>
2419 diff repository (or selected files)
2421 diff repository (or selected files)
2420 </td></tr>
2422 </td></tr>
2421 <tr><td>
2423 <tr><td>
2422 <a href="/help/export">
2424 <a href="/help/export">
2423 export
2425 export
2424 </a>
2426 </a>
2425 </td><td>
2427 </td><td>
2426 dump the header and diffs for one or more changesets
2428 dump the header and diffs for one or more changesets
2427 </td></tr>
2429 </td></tr>
2428 <tr><td>
2430 <tr><td>
2429 <a href="/help/forget">
2431 <a href="/help/forget">
2430 forget
2432 forget
2431 </a>
2433 </a>
2432 </td><td>
2434 </td><td>
2433 forget the specified files on the next commit
2435 forget the specified files on the next commit
2434 </td></tr>
2436 </td></tr>
2435 <tr><td>
2437 <tr><td>
2436 <a href="/help/init">
2438 <a href="/help/init">
2437 init
2439 init
2438 </a>
2440 </a>
2439 </td><td>
2441 </td><td>
2440 create a new repository in the given directory
2442 create a new repository in the given directory
2441 </td></tr>
2443 </td></tr>
2442 <tr><td>
2444 <tr><td>
2443 <a href="/help/log">
2445 <a href="/help/log">
2444 log
2446 log
2445 </a>
2447 </a>
2446 </td><td>
2448 </td><td>
2447 show revision history of entire repository or files
2449 show revision history of entire repository or files
2448 </td></tr>
2450 </td></tr>
2449 <tr><td>
2451 <tr><td>
2450 <a href="/help/merge">
2452 <a href="/help/merge">
2451 merge
2453 merge
2452 </a>
2454 </a>
2453 </td><td>
2455 </td><td>
2454 merge another revision into working directory
2456 merge another revision into working directory
2455 </td></tr>
2457 </td></tr>
2456 <tr><td>
2458 <tr><td>
2457 <a href="/help/pull">
2459 <a href="/help/pull">
2458 pull
2460 pull
2459 </a>
2461 </a>
2460 </td><td>
2462 </td><td>
2461 pull changes from the specified source
2463 pull changes from the specified source
2462 </td></tr>
2464 </td></tr>
2463 <tr><td>
2465 <tr><td>
2464 <a href="/help/push">
2466 <a href="/help/push">
2465 push
2467 push
2466 </a>
2468 </a>
2467 </td><td>
2469 </td><td>
2468 push changes to the specified destination
2470 push changes to the specified destination
2469 </td></tr>
2471 </td></tr>
2470 <tr><td>
2472 <tr><td>
2471 <a href="/help/remove">
2473 <a href="/help/remove">
2472 remove
2474 remove
2473 </a>
2475 </a>
2474 </td><td>
2476 </td><td>
2475 remove the specified files on the next commit
2477 remove the specified files on the next commit
2476 </td></tr>
2478 </td></tr>
2477 <tr><td>
2479 <tr><td>
2478 <a href="/help/serve">
2480 <a href="/help/serve">
2479 serve
2481 serve
2480 </a>
2482 </a>
2481 </td><td>
2483 </td><td>
2482 start stand-alone webserver
2484 start stand-alone webserver
2483 </td></tr>
2485 </td></tr>
2484 <tr><td>
2486 <tr><td>
2485 <a href="/help/status">
2487 <a href="/help/status">
2486 status
2488 status
2487 </a>
2489 </a>
2488 </td><td>
2490 </td><td>
2489 show changed files in the working directory
2491 show changed files in the working directory
2490 </td></tr>
2492 </td></tr>
2491 <tr><td>
2493 <tr><td>
2492 <a href="/help/summary">
2494 <a href="/help/summary">
2493 summary
2495 summary
2494 </a>
2496 </a>
2495 </td><td>
2497 </td><td>
2496 summarize working directory state
2498 summarize working directory state
2497 </td></tr>
2499 </td></tr>
2498 <tr><td>
2500 <tr><td>
2499 <a href="/help/update">
2501 <a href="/help/update">
2500 update
2502 update
2501 </a>
2503 </a>
2502 </td><td>
2504 </td><td>
2503 update working directory (or switch revisions)
2505 update working directory (or switch revisions)
2504 </td></tr>
2506 </td></tr>
2505
2507
2506
2508
2507
2509
2508 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2510 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2509
2511
2510 <tr><td>
2512 <tr><td>
2511 <a href="/help/addremove">
2513 <a href="/help/addremove">
2512 addremove
2514 addremove
2513 </a>
2515 </a>
2514 </td><td>
2516 </td><td>
2515 add all new files, delete all missing files
2517 add all new files, delete all missing files
2516 </td></tr>
2518 </td></tr>
2517 <tr><td>
2519 <tr><td>
2518 <a href="/help/archive">
2520 <a href="/help/archive">
2519 archive
2521 archive
2520 </a>
2522 </a>
2521 </td><td>
2523 </td><td>
2522 create an unversioned archive of a repository revision
2524 create an unversioned archive of a repository revision
2523 </td></tr>
2525 </td></tr>
2524 <tr><td>
2526 <tr><td>
2525 <a href="/help/backout">
2527 <a href="/help/backout">
2526 backout
2528 backout
2527 </a>
2529 </a>
2528 </td><td>
2530 </td><td>
2529 reverse effect of earlier changeset
2531 reverse effect of earlier changeset
2530 </td></tr>
2532 </td></tr>
2531 <tr><td>
2533 <tr><td>
2532 <a href="/help/bisect">
2534 <a href="/help/bisect">
2533 bisect
2535 bisect
2534 </a>
2536 </a>
2535 </td><td>
2537 </td><td>
2536 subdivision search of changesets
2538 subdivision search of changesets
2537 </td></tr>
2539 </td></tr>
2538 <tr><td>
2540 <tr><td>
2539 <a href="/help/bookmarks">
2541 <a href="/help/bookmarks">
2540 bookmarks
2542 bookmarks
2541 </a>
2543 </a>
2542 </td><td>
2544 </td><td>
2543 create a new bookmark or list existing bookmarks
2545 create a new bookmark or list existing bookmarks
2544 </td></tr>
2546 </td></tr>
2545 <tr><td>
2547 <tr><td>
2546 <a href="/help/branch">
2548 <a href="/help/branch">
2547 branch
2549 branch
2548 </a>
2550 </a>
2549 </td><td>
2551 </td><td>
2550 set or show the current branch name
2552 set or show the current branch name
2551 </td></tr>
2553 </td></tr>
2552 <tr><td>
2554 <tr><td>
2553 <a href="/help/branches">
2555 <a href="/help/branches">
2554 branches
2556 branches
2555 </a>
2557 </a>
2556 </td><td>
2558 </td><td>
2557 list repository named branches
2559 list repository named branches
2558 </td></tr>
2560 </td></tr>
2559 <tr><td>
2561 <tr><td>
2560 <a href="/help/bundle">
2562 <a href="/help/bundle">
2561 bundle
2563 bundle
2562 </a>
2564 </a>
2563 </td><td>
2565 </td><td>
2564 create a bundle file
2566 create a bundle file
2565 </td></tr>
2567 </td></tr>
2566 <tr><td>
2568 <tr><td>
2567 <a href="/help/cat">
2569 <a href="/help/cat">
2568 cat
2570 cat
2569 </a>
2571 </a>
2570 </td><td>
2572 </td><td>
2571 output the current or given revision of files
2573 output the current or given revision of files
2572 </td></tr>
2574 </td></tr>
2573 <tr><td>
2575 <tr><td>
2574 <a href="/help/config">
2576 <a href="/help/config">
2575 config
2577 config
2576 </a>
2578 </a>
2577 </td><td>
2579 </td><td>
2578 show combined config settings from all hgrc files
2580 show combined config settings from all hgrc files
2579 </td></tr>
2581 </td></tr>
2580 <tr><td>
2582 <tr><td>
2581 <a href="/help/copy">
2583 <a href="/help/copy">
2582 copy
2584 copy
2583 </a>
2585 </a>
2584 </td><td>
2586 </td><td>
2585 mark files as copied for the next commit
2587 mark files as copied for the next commit
2586 </td></tr>
2588 </td></tr>
2587 <tr><td>
2589 <tr><td>
2588 <a href="/help/files">
2590 <a href="/help/files">
2589 files
2591 files
2590 </a>
2592 </a>
2591 </td><td>
2593 </td><td>
2592 list tracked files
2594 list tracked files
2593 </td></tr>
2595 </td></tr>
2594 <tr><td>
2596 <tr><td>
2595 <a href="/help/graft">
2597 <a href="/help/graft">
2596 graft
2598 graft
2597 </a>
2599 </a>
2598 </td><td>
2600 </td><td>
2599 copy changes from other branches onto the current branch
2601 copy changes from other branches onto the current branch
2600 </td></tr>
2602 </td></tr>
2601 <tr><td>
2603 <tr><td>
2602 <a href="/help/grep">
2604 <a href="/help/grep">
2603 grep
2605 grep
2604 </a>
2606 </a>
2605 </td><td>
2607 </td><td>
2606 search for a pattern in specified files
2608 search for a pattern in specified files
2607 </td></tr>
2609 </td></tr>
2608 <tr><td>
2610 <tr><td>
2609 <a href="/help/hashelp">
2611 <a href="/help/hashelp">
2610 hashelp
2612 hashelp
2611 </a>
2613 </a>
2612 </td><td>
2614 </td><td>
2613 Extension command's help
2615 Extension command's help
2614 </td></tr>
2616 </td></tr>
2615 <tr><td>
2617 <tr><td>
2616 <a href="/help/heads">
2618 <a href="/help/heads">
2617 heads
2619 heads
2618 </a>
2620 </a>
2619 </td><td>
2621 </td><td>
2620 show branch heads
2622 show branch heads
2621 </td></tr>
2623 </td></tr>
2622 <tr><td>
2624 <tr><td>
2623 <a href="/help/help">
2625 <a href="/help/help">
2624 help
2626 help
2625 </a>
2627 </a>
2626 </td><td>
2628 </td><td>
2627 show help for a given topic or a help overview
2629 show help for a given topic or a help overview
2628 </td></tr>
2630 </td></tr>
2629 <tr><td>
2631 <tr><td>
2630 <a href="/help/hgalias">
2632 <a href="/help/hgalias">
2631 hgalias
2633 hgalias
2632 </a>
2634 </a>
2633 </td><td>
2635 </td><td>
2634 My doc
2636 My doc
2635 </td></tr>
2637 </td></tr>
2636 <tr><td>
2638 <tr><td>
2637 <a href="/help/hgaliasnodoc">
2639 <a href="/help/hgaliasnodoc">
2638 hgaliasnodoc
2640 hgaliasnodoc
2639 </a>
2641 </a>
2640 </td><td>
2642 </td><td>
2641 summarize working directory state
2643 summarize working directory state
2642 </td></tr>
2644 </td></tr>
2643 <tr><td>
2645 <tr><td>
2644 <a href="/help/identify">
2646 <a href="/help/identify">
2645 identify
2647 identify
2646 </a>
2648 </a>
2647 </td><td>
2649 </td><td>
2648 identify the working directory or specified revision
2650 identify the working directory or specified revision
2649 </td></tr>
2651 </td></tr>
2650 <tr><td>
2652 <tr><td>
2651 <a href="/help/import">
2653 <a href="/help/import">
2652 import
2654 import
2653 </a>
2655 </a>
2654 </td><td>
2656 </td><td>
2655 import an ordered set of patches
2657 import an ordered set of patches
2656 </td></tr>
2658 </td></tr>
2657 <tr><td>
2659 <tr><td>
2658 <a href="/help/incoming">
2660 <a href="/help/incoming">
2659 incoming
2661 incoming
2660 </a>
2662 </a>
2661 </td><td>
2663 </td><td>
2662 show new changesets found in source
2664 show new changesets found in source
2663 </td></tr>
2665 </td></tr>
2664 <tr><td>
2666 <tr><td>
2665 <a href="/help/manifest">
2667 <a href="/help/manifest">
2666 manifest
2668 manifest
2667 </a>
2669 </a>
2668 </td><td>
2670 </td><td>
2669 output the current or given revision of the project manifest
2671 output the current or given revision of the project manifest
2670 </td></tr>
2672 </td></tr>
2671 <tr><td>
2673 <tr><td>
2672 <a href="/help/nohelp">
2674 <a href="/help/nohelp">
2673 nohelp
2675 nohelp
2674 </a>
2676 </a>
2675 </td><td>
2677 </td><td>
2676 (no help text available)
2678 (no help text available)
2677 </td></tr>
2679 </td></tr>
2678 <tr><td>
2680 <tr><td>
2679 <a href="/help/outgoing">
2681 <a href="/help/outgoing">
2680 outgoing
2682 outgoing
2681 </a>
2683 </a>
2682 </td><td>
2684 </td><td>
2683 show changesets not found in the destination
2685 show changesets not found in the destination
2684 </td></tr>
2686 </td></tr>
2685 <tr><td>
2687 <tr><td>
2686 <a href="/help/paths">
2688 <a href="/help/paths">
2687 paths
2689 paths
2688 </a>
2690 </a>
2689 </td><td>
2691 </td><td>
2690 show aliases for remote repositories
2692 show aliases for remote repositories
2691 </td></tr>
2693 </td></tr>
2692 <tr><td>
2694 <tr><td>
2693 <a href="/help/phase">
2695 <a href="/help/phase">
2694 phase
2696 phase
2695 </a>
2697 </a>
2696 </td><td>
2698 </td><td>
2697 set or show the current phase name
2699 set or show the current phase name
2698 </td></tr>
2700 </td></tr>
2699 <tr><td>
2701 <tr><td>
2700 <a href="/help/recover">
2702 <a href="/help/recover">
2701 recover
2703 recover
2702 </a>
2704 </a>
2703 </td><td>
2705 </td><td>
2704 roll back an interrupted transaction
2706 roll back an interrupted transaction
2705 </td></tr>
2707 </td></tr>
2706 <tr><td>
2708 <tr><td>
2707 <a href="/help/rename">
2709 <a href="/help/rename">
2708 rename
2710 rename
2709 </a>
2711 </a>
2710 </td><td>
2712 </td><td>
2711 rename files; equivalent of copy + remove
2713 rename files; equivalent of copy + remove
2712 </td></tr>
2714 </td></tr>
2713 <tr><td>
2715 <tr><td>
2714 <a href="/help/resolve">
2716 <a href="/help/resolve">
2715 resolve
2717 resolve
2716 </a>
2718 </a>
2717 </td><td>
2719 </td><td>
2718 redo merges or set/view the merge status of files
2720 redo merges or set/view the merge status of files
2719 </td></tr>
2721 </td></tr>
2720 <tr><td>
2722 <tr><td>
2721 <a href="/help/revert">
2723 <a href="/help/revert">
2722 revert
2724 revert
2723 </a>
2725 </a>
2724 </td><td>
2726 </td><td>
2725 restore files to their checkout state
2727 restore files to their checkout state
2726 </td></tr>
2728 </td></tr>
2727 <tr><td>
2729 <tr><td>
2728 <a href="/help/root">
2730 <a href="/help/root">
2729 root
2731 root
2730 </a>
2732 </a>
2731 </td><td>
2733 </td><td>
2732 print the root (top) of the current working directory
2734 print the root (top) of the current working directory
2733 </td></tr>
2735 </td></tr>
2734 <tr><td>
2736 <tr><td>
2735 <a href="/help/shellalias">
2737 <a href="/help/shellalias">
2736 shellalias
2738 shellalias
2737 </a>
2739 </a>
2738 </td><td>
2740 </td><td>
2739 (no help text available)
2741 (no help text available)
2740 </td></tr>
2742 </td></tr>
2741 <tr><td>
2743 <tr><td>
2742 <a href="/help/shelve">
2744 <a href="/help/shelve">
2743 shelve
2745 shelve
2744 </a>
2746 </a>
2745 </td><td>
2747 </td><td>
2746 save and set aside changes from the working directory
2748 save and set aside changes from the working directory
2747 </td></tr>
2749 </td></tr>
2748 <tr><td>
2750 <tr><td>
2749 <a href="/help/tag">
2751 <a href="/help/tag">
2750 tag
2752 tag
2751 </a>
2753 </a>
2752 </td><td>
2754 </td><td>
2753 add one or more tags for the current or given revision
2755 add one or more tags for the current or given revision
2754 </td></tr>
2756 </td></tr>
2755 <tr><td>
2757 <tr><td>
2756 <a href="/help/tags">
2758 <a href="/help/tags">
2757 tags
2759 tags
2758 </a>
2760 </a>
2759 </td><td>
2761 </td><td>
2760 list repository tags
2762 list repository tags
2761 </td></tr>
2763 </td></tr>
2762 <tr><td>
2764 <tr><td>
2763 <a href="/help/unbundle">
2765 <a href="/help/unbundle">
2764 unbundle
2766 unbundle
2765 </a>
2767 </a>
2766 </td><td>
2768 </td><td>
2767 apply one or more bundle files
2769 apply one or more bundle files
2768 </td></tr>
2770 </td></tr>
2769 <tr><td>
2771 <tr><td>
2770 <a href="/help/unshelve">
2772 <a href="/help/unshelve">
2771 unshelve
2773 unshelve
2772 </a>
2774 </a>
2773 </td><td>
2775 </td><td>
2774 restore a shelved change to the working directory
2776 restore a shelved change to the working directory
2775 </td></tr>
2777 </td></tr>
2776 <tr><td>
2778 <tr><td>
2777 <a href="/help/verify">
2779 <a href="/help/verify">
2778 verify
2780 verify
2779 </a>
2781 </a>
2780 </td><td>
2782 </td><td>
2781 verify the integrity of the repository
2783 verify the integrity of the repository
2782 </td></tr>
2784 </td></tr>
2783 <tr><td>
2785 <tr><td>
2784 <a href="/help/version">
2786 <a href="/help/version">
2785 version
2787 version
2786 </a>
2788 </a>
2787 </td><td>
2789 </td><td>
2788 output version and copyright information
2790 output version and copyright information
2789 </td></tr>
2791 </td></tr>
2790
2792
2791
2793
2792 </table>
2794 </table>
2793 </div>
2795 </div>
2794 </div>
2796 </div>
2795
2797
2796
2798
2797
2799
2798 </body>
2800 </body>
2799 </html>
2801 </html>
2800
2802
2801
2803
2802 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2804 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2803 200 Script output follows
2805 200 Script output follows
2804
2806
2805 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2807 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2806 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2808 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2807 <head>
2809 <head>
2808 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2810 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2809 <meta name="robots" content="index, nofollow" />
2811 <meta name="robots" content="index, nofollow" />
2810 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2812 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2811 <script type="text/javascript" src="/static/mercurial.js"></script>
2813 <script type="text/javascript" src="/static/mercurial.js"></script>
2812
2814
2813 <title>Help: add</title>
2815 <title>Help: add</title>
2814 </head>
2816 </head>
2815 <body>
2817 <body>
2816
2818
2817 <div class="container">
2819 <div class="container">
2818 <div class="menu">
2820 <div class="menu">
2819 <div class="logo">
2821 <div class="logo">
2820 <a href="https://mercurial-scm.org/">
2822 <a href="https://mercurial-scm.org/">
2821 <img src="/static/hglogo.png" alt="mercurial" /></a>
2823 <img src="/static/hglogo.png" alt="mercurial" /></a>
2822 </div>
2824 </div>
2823 <ul>
2825 <ul>
2824 <li><a href="/shortlog">log</a></li>
2826 <li><a href="/shortlog">log</a></li>
2825 <li><a href="/graph">graph</a></li>
2827 <li><a href="/graph">graph</a></li>
2826 <li><a href="/tags">tags</a></li>
2828 <li><a href="/tags">tags</a></li>
2827 <li><a href="/bookmarks">bookmarks</a></li>
2829 <li><a href="/bookmarks">bookmarks</a></li>
2828 <li><a href="/branches">branches</a></li>
2830 <li><a href="/branches">branches</a></li>
2829 </ul>
2831 </ul>
2830 <ul>
2832 <ul>
2831 <li class="active"><a href="/help">help</a></li>
2833 <li class="active"><a href="/help">help</a></li>
2832 </ul>
2834 </ul>
2833 </div>
2835 </div>
2834
2836
2835 <div class="main">
2837 <div class="main">
2836 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2838 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2837 <h3>Help: add</h3>
2839 <h3>Help: add</h3>
2838
2840
2839 <form class="search" action="/log">
2841 <form class="search" action="/log">
2840
2842
2841 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2843 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2842 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2844 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2843 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2845 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2844 </form>
2846 </form>
2845 <div id="doc">
2847 <div id="doc">
2846 <p>
2848 <p>
2847 hg add [OPTION]... [FILE]...
2849 hg add [OPTION]... [FILE]...
2848 </p>
2850 </p>
2849 <p>
2851 <p>
2850 add the specified files on the next commit
2852 add the specified files on the next commit
2851 </p>
2853 </p>
2852 <p>
2854 <p>
2853 Schedule files to be version controlled and added to the
2855 Schedule files to be version controlled and added to the
2854 repository.
2856 repository.
2855 </p>
2857 </p>
2856 <p>
2858 <p>
2857 The files will be added to the repository at the next commit. To
2859 The files will be added to the repository at the next commit. To
2858 undo an add before that, see 'hg forget'.
2860 undo an add before that, see 'hg forget'.
2859 </p>
2861 </p>
2860 <p>
2862 <p>
2861 If no names are given, add all files to the repository (except
2863 If no names are given, add all files to the repository (except
2862 files matching &quot;.hgignore&quot;).
2864 files matching &quot;.hgignore&quot;).
2863 </p>
2865 </p>
2864 <p>
2866 <p>
2865 Examples:
2867 Examples:
2866 </p>
2868 </p>
2867 <ul>
2869 <ul>
2868 <li> New (unknown) files are added automatically by 'hg add':
2870 <li> New (unknown) files are added automatically by 'hg add':
2869 <pre>
2871 <pre>
2870 \$ ls (re)
2872 \$ ls (re)
2871 foo.c
2873 foo.c
2872 \$ hg status (re)
2874 \$ hg status (re)
2873 ? foo.c
2875 ? foo.c
2874 \$ hg add (re)
2876 \$ hg add (re)
2875 adding foo.c
2877 adding foo.c
2876 \$ hg status (re)
2878 \$ hg status (re)
2877 A foo.c
2879 A foo.c
2878 </pre>
2880 </pre>
2879 <li> Specific files to be added can be specified:
2881 <li> Specific files to be added can be specified:
2880 <pre>
2882 <pre>
2881 \$ ls (re)
2883 \$ ls (re)
2882 bar.c foo.c
2884 bar.c foo.c
2883 \$ hg status (re)
2885 \$ hg status (re)
2884 ? bar.c
2886 ? bar.c
2885 ? foo.c
2887 ? foo.c
2886 \$ hg add bar.c (re)
2888 \$ hg add bar.c (re)
2887 \$ hg status (re)
2889 \$ hg status (re)
2888 A bar.c
2890 A bar.c
2889 ? foo.c
2891 ? foo.c
2890 </pre>
2892 </pre>
2891 </ul>
2893 </ul>
2892 <p>
2894 <p>
2893 Returns 0 if all files are successfully added.
2895 Returns 0 if all files are successfully added.
2894 </p>
2896 </p>
2895 <p>
2897 <p>
2896 options ([+] can be repeated):
2898 options ([+] can be repeated):
2897 </p>
2899 </p>
2898 <table>
2900 <table>
2899 <tr><td>-I</td>
2901 <tr><td>-I</td>
2900 <td>--include PATTERN [+]</td>
2902 <td>--include PATTERN [+]</td>
2901 <td>include names matching the given patterns</td></tr>
2903 <td>include names matching the given patterns</td></tr>
2902 <tr><td>-X</td>
2904 <tr><td>-X</td>
2903 <td>--exclude PATTERN [+]</td>
2905 <td>--exclude PATTERN [+]</td>
2904 <td>exclude names matching the given patterns</td></tr>
2906 <td>exclude names matching the given patterns</td></tr>
2905 <tr><td>-S</td>
2907 <tr><td>-S</td>
2906 <td>--subrepos</td>
2908 <td>--subrepos</td>
2907 <td>recurse into subrepositories</td></tr>
2909 <td>recurse into subrepositories</td></tr>
2908 <tr><td>-n</td>
2910 <tr><td>-n</td>
2909 <td>--dry-run</td>
2911 <td>--dry-run</td>
2910 <td>do not perform actions, just print output</td></tr>
2912 <td>do not perform actions, just print output</td></tr>
2911 </table>
2913 </table>
2912 <p>
2914 <p>
2913 global options ([+] can be repeated):
2915 global options ([+] can be repeated):
2914 </p>
2916 </p>
2915 <table>
2917 <table>
2916 <tr><td>-R</td>
2918 <tr><td>-R</td>
2917 <td>--repository REPO</td>
2919 <td>--repository REPO</td>
2918 <td>repository root directory or name of overlay bundle file</td></tr>
2920 <td>repository root directory or name of overlay bundle file</td></tr>
2919 <tr><td></td>
2921 <tr><td></td>
2920 <td>--cwd DIR</td>
2922 <td>--cwd DIR</td>
2921 <td>change working directory</td></tr>
2923 <td>change working directory</td></tr>
2922 <tr><td>-y</td>
2924 <tr><td>-y</td>
2923 <td>--noninteractive</td>
2925 <td>--noninteractive</td>
2924 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2926 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2925 <tr><td>-q</td>
2927 <tr><td>-q</td>
2926 <td>--quiet</td>
2928 <td>--quiet</td>
2927 <td>suppress output</td></tr>
2929 <td>suppress output</td></tr>
2928 <tr><td>-v</td>
2930 <tr><td>-v</td>
2929 <td>--verbose</td>
2931 <td>--verbose</td>
2930 <td>enable additional output</td></tr>
2932 <td>enable additional output</td></tr>
2931 <tr><td></td>
2933 <tr><td></td>
2932 <td>--color TYPE</td>
2934 <td>--color TYPE</td>
2933 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2935 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2934 <tr><td></td>
2936 <tr><td></td>
2935 <td>--config CONFIG [+]</td>
2937 <td>--config CONFIG [+]</td>
2936 <td>set/override config option (use 'section.name=value')</td></tr>
2938 <td>set/override config option (use 'section.name=value')</td></tr>
2937 <tr><td></td>
2939 <tr><td></td>
2938 <td>--debug</td>
2940 <td>--debug</td>
2939 <td>enable debugging output</td></tr>
2941 <td>enable debugging output</td></tr>
2940 <tr><td></td>
2942 <tr><td></td>
2941 <td>--debugger</td>
2943 <td>--debugger</td>
2942 <td>start debugger</td></tr>
2944 <td>start debugger</td></tr>
2943 <tr><td></td>
2945 <tr><td></td>
2944 <td>--encoding ENCODE</td>
2946 <td>--encoding ENCODE</td>
2945 <td>set the charset encoding (default: ascii)</td></tr>
2947 <td>set the charset encoding (default: ascii)</td></tr>
2946 <tr><td></td>
2948 <tr><td></td>
2947 <td>--encodingmode MODE</td>
2949 <td>--encodingmode MODE</td>
2948 <td>set the charset encoding mode (default: strict)</td></tr>
2950 <td>set the charset encoding mode (default: strict)</td></tr>
2949 <tr><td></td>
2951 <tr><td></td>
2950 <td>--traceback</td>
2952 <td>--traceback</td>
2951 <td>always print a traceback on exception</td></tr>
2953 <td>always print a traceback on exception</td></tr>
2952 <tr><td></td>
2954 <tr><td></td>
2953 <td>--time</td>
2955 <td>--time</td>
2954 <td>time how long the command takes</td></tr>
2956 <td>time how long the command takes</td></tr>
2955 <tr><td></td>
2957 <tr><td></td>
2956 <td>--profile</td>
2958 <td>--profile</td>
2957 <td>print command execution profile</td></tr>
2959 <td>print command execution profile</td></tr>
2958 <tr><td></td>
2960 <tr><td></td>
2959 <td>--version</td>
2961 <td>--version</td>
2960 <td>output version information and exit</td></tr>
2962 <td>output version information and exit</td></tr>
2961 <tr><td>-h</td>
2963 <tr><td>-h</td>
2962 <td>--help</td>
2964 <td>--help</td>
2963 <td>display help and exit</td></tr>
2965 <td>display help and exit</td></tr>
2964 <tr><td></td>
2966 <tr><td></td>
2965 <td>--hidden</td>
2967 <td>--hidden</td>
2966 <td>consider hidden changesets</td></tr>
2968 <td>consider hidden changesets</td></tr>
2967 <tr><td></td>
2969 <tr><td></td>
2968 <td>--pager TYPE</td>
2970 <td>--pager TYPE</td>
2969 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2971 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2970 </table>
2972 </table>
2971
2973
2972 </div>
2974 </div>
2973 </div>
2975 </div>
2974 </div>
2976 </div>
2975
2977
2976
2978
2977
2979
2978 </body>
2980 </body>
2979 </html>
2981 </html>
2980
2982
2981
2983
2982 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2984 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2983 200 Script output follows
2985 200 Script output follows
2984
2986
2985 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2987 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2986 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2988 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2987 <head>
2989 <head>
2988 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2990 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2989 <meta name="robots" content="index, nofollow" />
2991 <meta name="robots" content="index, nofollow" />
2990 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2992 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2991 <script type="text/javascript" src="/static/mercurial.js"></script>
2993 <script type="text/javascript" src="/static/mercurial.js"></script>
2992
2994
2993 <title>Help: remove</title>
2995 <title>Help: remove</title>
2994 </head>
2996 </head>
2995 <body>
2997 <body>
2996
2998
2997 <div class="container">
2999 <div class="container">
2998 <div class="menu">
3000 <div class="menu">
2999 <div class="logo">
3001 <div class="logo">
3000 <a href="https://mercurial-scm.org/">
3002 <a href="https://mercurial-scm.org/">
3001 <img src="/static/hglogo.png" alt="mercurial" /></a>
3003 <img src="/static/hglogo.png" alt="mercurial" /></a>
3002 </div>
3004 </div>
3003 <ul>
3005 <ul>
3004 <li><a href="/shortlog">log</a></li>
3006 <li><a href="/shortlog">log</a></li>
3005 <li><a href="/graph">graph</a></li>
3007 <li><a href="/graph">graph</a></li>
3006 <li><a href="/tags">tags</a></li>
3008 <li><a href="/tags">tags</a></li>
3007 <li><a href="/bookmarks">bookmarks</a></li>
3009 <li><a href="/bookmarks">bookmarks</a></li>
3008 <li><a href="/branches">branches</a></li>
3010 <li><a href="/branches">branches</a></li>
3009 </ul>
3011 </ul>
3010 <ul>
3012 <ul>
3011 <li class="active"><a href="/help">help</a></li>
3013 <li class="active"><a href="/help">help</a></li>
3012 </ul>
3014 </ul>
3013 </div>
3015 </div>
3014
3016
3015 <div class="main">
3017 <div class="main">
3016 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3018 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3017 <h3>Help: remove</h3>
3019 <h3>Help: remove</h3>
3018
3020
3019 <form class="search" action="/log">
3021 <form class="search" action="/log">
3020
3022
3021 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3023 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3022 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3024 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3023 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3025 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3024 </form>
3026 </form>
3025 <div id="doc">
3027 <div id="doc">
3026 <p>
3028 <p>
3027 hg remove [OPTION]... FILE...
3029 hg remove [OPTION]... FILE...
3028 </p>
3030 </p>
3029 <p>
3031 <p>
3030 aliases: rm
3032 aliases: rm
3031 </p>
3033 </p>
3032 <p>
3034 <p>
3033 remove the specified files on the next commit
3035 remove the specified files on the next commit
3034 </p>
3036 </p>
3035 <p>
3037 <p>
3036 Schedule the indicated files for removal from the current branch.
3038 Schedule the indicated files for removal from the current branch.
3037 </p>
3039 </p>
3038 <p>
3040 <p>
3039 This command schedules the files to be removed at the next commit.
3041 This command schedules the files to be removed at the next commit.
3040 To undo a remove before that, see 'hg revert'. To undo added
3042 To undo a remove before that, see 'hg revert'. To undo added
3041 files, see 'hg forget'.
3043 files, see 'hg forget'.
3042 </p>
3044 </p>
3043 <p>
3045 <p>
3044 -A/--after can be used to remove only files that have already
3046 -A/--after can be used to remove only files that have already
3045 been deleted, -f/--force can be used to force deletion, and -Af
3047 been deleted, -f/--force can be used to force deletion, and -Af
3046 can be used to remove files from the next revision without
3048 can be used to remove files from the next revision without
3047 deleting them from the working directory.
3049 deleting them from the working directory.
3048 </p>
3050 </p>
3049 <p>
3051 <p>
3050 The following table details the behavior of remove for different
3052 The following table details the behavior of remove for different
3051 file states (columns) and option combinations (rows). The file
3053 file states (columns) and option combinations (rows). The file
3052 states are Added [A], Clean [C], Modified [M] and Missing [!]
3054 states are Added [A], Clean [C], Modified [M] and Missing [!]
3053 (as reported by 'hg status'). The actions are Warn, Remove
3055 (as reported by 'hg status'). The actions are Warn, Remove
3054 (from branch) and Delete (from disk):
3056 (from branch) and Delete (from disk):
3055 </p>
3057 </p>
3056 <table>
3058 <table>
3057 <tr><td>opt/state</td>
3059 <tr><td>opt/state</td>
3058 <td>A</td>
3060 <td>A</td>
3059 <td>C</td>
3061 <td>C</td>
3060 <td>M</td>
3062 <td>M</td>
3061 <td>!</td></tr>
3063 <td>!</td></tr>
3062 <tr><td>none</td>
3064 <tr><td>none</td>
3063 <td>W</td>
3065 <td>W</td>
3064 <td>RD</td>
3066 <td>RD</td>
3065 <td>W</td>
3067 <td>W</td>
3066 <td>R</td></tr>
3068 <td>R</td></tr>
3067 <tr><td>-f</td>
3069 <tr><td>-f</td>
3068 <td>R</td>
3070 <td>R</td>
3069 <td>RD</td>
3071 <td>RD</td>
3070 <td>RD</td>
3072 <td>RD</td>
3071 <td>R</td></tr>
3073 <td>R</td></tr>
3072 <tr><td>-A</td>
3074 <tr><td>-A</td>
3073 <td>W</td>
3075 <td>W</td>
3074 <td>W</td>
3076 <td>W</td>
3075 <td>W</td>
3077 <td>W</td>
3076 <td>R</td></tr>
3078 <td>R</td></tr>
3077 <tr><td>-Af</td>
3079 <tr><td>-Af</td>
3078 <td>R</td>
3080 <td>R</td>
3079 <td>R</td>
3081 <td>R</td>
3080 <td>R</td>
3082 <td>R</td>
3081 <td>R</td></tr>
3083 <td>R</td></tr>
3082 </table>
3084 </table>
3083 <p>
3085 <p>
3084 <b>Note:</b>
3086 <b>Note:</b>
3085 </p>
3087 </p>
3086 <p>
3088 <p>
3087 'hg remove' never deletes files in Added [A] state from the
3089 'hg remove' never deletes files in Added [A] state from the
3088 working directory, not even if &quot;--force&quot; is specified.
3090 working directory, not even if &quot;--force&quot; is specified.
3089 </p>
3091 </p>
3090 <p>
3092 <p>
3091 Returns 0 on success, 1 if any warnings encountered.
3093 Returns 0 on success, 1 if any warnings encountered.
3092 </p>
3094 </p>
3093 <p>
3095 <p>
3094 options ([+] can be repeated):
3096 options ([+] can be repeated):
3095 </p>
3097 </p>
3096 <table>
3098 <table>
3097 <tr><td>-A</td>
3099 <tr><td>-A</td>
3098 <td>--after</td>
3100 <td>--after</td>
3099 <td>record delete for missing files</td></tr>
3101 <td>record delete for missing files</td></tr>
3100 <tr><td>-f</td>
3102 <tr><td>-f</td>
3101 <td>--force</td>
3103 <td>--force</td>
3102 <td>forget added files, delete modified files</td></tr>
3104 <td>forget added files, delete modified files</td></tr>
3103 <tr><td>-S</td>
3105 <tr><td>-S</td>
3104 <td>--subrepos</td>
3106 <td>--subrepos</td>
3105 <td>recurse into subrepositories</td></tr>
3107 <td>recurse into subrepositories</td></tr>
3106 <tr><td>-I</td>
3108 <tr><td>-I</td>
3107 <td>--include PATTERN [+]</td>
3109 <td>--include PATTERN [+]</td>
3108 <td>include names matching the given patterns</td></tr>
3110 <td>include names matching the given patterns</td></tr>
3109 <tr><td>-X</td>
3111 <tr><td>-X</td>
3110 <td>--exclude PATTERN [+]</td>
3112 <td>--exclude PATTERN [+]</td>
3111 <td>exclude names matching the given patterns</td></tr>
3113 <td>exclude names matching the given patterns</td></tr>
3112 <tr><td>-n</td>
3114 <tr><td>-n</td>
3113 <td>--dry-run</td>
3115 <td>--dry-run</td>
3114 <td>do not perform actions, just print output</td></tr>
3116 <td>do not perform actions, just print output</td></tr>
3115 </table>
3117 </table>
3116 <p>
3118 <p>
3117 global options ([+] can be repeated):
3119 global options ([+] can be repeated):
3118 </p>
3120 </p>
3119 <table>
3121 <table>
3120 <tr><td>-R</td>
3122 <tr><td>-R</td>
3121 <td>--repository REPO</td>
3123 <td>--repository REPO</td>
3122 <td>repository root directory or name of overlay bundle file</td></tr>
3124 <td>repository root directory or name of overlay bundle file</td></tr>
3123 <tr><td></td>
3125 <tr><td></td>
3124 <td>--cwd DIR</td>
3126 <td>--cwd DIR</td>
3125 <td>change working directory</td></tr>
3127 <td>change working directory</td></tr>
3126 <tr><td>-y</td>
3128 <tr><td>-y</td>
3127 <td>--noninteractive</td>
3129 <td>--noninteractive</td>
3128 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3130 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3129 <tr><td>-q</td>
3131 <tr><td>-q</td>
3130 <td>--quiet</td>
3132 <td>--quiet</td>
3131 <td>suppress output</td></tr>
3133 <td>suppress output</td></tr>
3132 <tr><td>-v</td>
3134 <tr><td>-v</td>
3133 <td>--verbose</td>
3135 <td>--verbose</td>
3134 <td>enable additional output</td></tr>
3136 <td>enable additional output</td></tr>
3135 <tr><td></td>
3137 <tr><td></td>
3136 <td>--color TYPE</td>
3138 <td>--color TYPE</td>
3137 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3139 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3138 <tr><td></td>
3140 <tr><td></td>
3139 <td>--config CONFIG [+]</td>
3141 <td>--config CONFIG [+]</td>
3140 <td>set/override config option (use 'section.name=value')</td></tr>
3142 <td>set/override config option (use 'section.name=value')</td></tr>
3141 <tr><td></td>
3143 <tr><td></td>
3142 <td>--debug</td>
3144 <td>--debug</td>
3143 <td>enable debugging output</td></tr>
3145 <td>enable debugging output</td></tr>
3144 <tr><td></td>
3146 <tr><td></td>
3145 <td>--debugger</td>
3147 <td>--debugger</td>
3146 <td>start debugger</td></tr>
3148 <td>start debugger</td></tr>
3147 <tr><td></td>
3149 <tr><td></td>
3148 <td>--encoding ENCODE</td>
3150 <td>--encoding ENCODE</td>
3149 <td>set the charset encoding (default: ascii)</td></tr>
3151 <td>set the charset encoding (default: ascii)</td></tr>
3150 <tr><td></td>
3152 <tr><td></td>
3151 <td>--encodingmode MODE</td>
3153 <td>--encodingmode MODE</td>
3152 <td>set the charset encoding mode (default: strict)</td></tr>
3154 <td>set the charset encoding mode (default: strict)</td></tr>
3153 <tr><td></td>
3155 <tr><td></td>
3154 <td>--traceback</td>
3156 <td>--traceback</td>
3155 <td>always print a traceback on exception</td></tr>
3157 <td>always print a traceback on exception</td></tr>
3156 <tr><td></td>
3158 <tr><td></td>
3157 <td>--time</td>
3159 <td>--time</td>
3158 <td>time how long the command takes</td></tr>
3160 <td>time how long the command takes</td></tr>
3159 <tr><td></td>
3161 <tr><td></td>
3160 <td>--profile</td>
3162 <td>--profile</td>
3161 <td>print command execution profile</td></tr>
3163 <td>print command execution profile</td></tr>
3162 <tr><td></td>
3164 <tr><td></td>
3163 <td>--version</td>
3165 <td>--version</td>
3164 <td>output version information and exit</td></tr>
3166 <td>output version information and exit</td></tr>
3165 <tr><td>-h</td>
3167 <tr><td>-h</td>
3166 <td>--help</td>
3168 <td>--help</td>
3167 <td>display help and exit</td></tr>
3169 <td>display help and exit</td></tr>
3168 <tr><td></td>
3170 <tr><td></td>
3169 <td>--hidden</td>
3171 <td>--hidden</td>
3170 <td>consider hidden changesets</td></tr>
3172 <td>consider hidden changesets</td></tr>
3171 <tr><td></td>
3173 <tr><td></td>
3172 <td>--pager TYPE</td>
3174 <td>--pager TYPE</td>
3173 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3175 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3174 </table>
3176 </table>
3175
3177
3176 </div>
3178 </div>
3177 </div>
3179 </div>
3178 </div>
3180 </div>
3179
3181
3180
3182
3181
3183
3182 </body>
3184 </body>
3183 </html>
3185 </html>
3184
3186
3185
3187
3186 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3188 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3187 200 Script output follows
3189 200 Script output follows
3188
3190
3189 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3191 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3190 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3192 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3191 <head>
3193 <head>
3192 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3194 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3193 <meta name="robots" content="index, nofollow" />
3195 <meta name="robots" content="index, nofollow" />
3194 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3196 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3195 <script type="text/javascript" src="/static/mercurial.js"></script>
3197 <script type="text/javascript" src="/static/mercurial.js"></script>
3196
3198
3197 <title>Help: dates</title>
3199 <title>Help: dates</title>
3198 </head>
3200 </head>
3199 <body>
3201 <body>
3200
3202
3201 <div class="container">
3203 <div class="container">
3202 <div class="menu">
3204 <div class="menu">
3203 <div class="logo">
3205 <div class="logo">
3204 <a href="https://mercurial-scm.org/">
3206 <a href="https://mercurial-scm.org/">
3205 <img src="/static/hglogo.png" alt="mercurial" /></a>
3207 <img src="/static/hglogo.png" alt="mercurial" /></a>
3206 </div>
3208 </div>
3207 <ul>
3209 <ul>
3208 <li><a href="/shortlog">log</a></li>
3210 <li><a href="/shortlog">log</a></li>
3209 <li><a href="/graph">graph</a></li>
3211 <li><a href="/graph">graph</a></li>
3210 <li><a href="/tags">tags</a></li>
3212 <li><a href="/tags">tags</a></li>
3211 <li><a href="/bookmarks">bookmarks</a></li>
3213 <li><a href="/bookmarks">bookmarks</a></li>
3212 <li><a href="/branches">branches</a></li>
3214 <li><a href="/branches">branches</a></li>
3213 </ul>
3215 </ul>
3214 <ul>
3216 <ul>
3215 <li class="active"><a href="/help">help</a></li>
3217 <li class="active"><a href="/help">help</a></li>
3216 </ul>
3218 </ul>
3217 </div>
3219 </div>
3218
3220
3219 <div class="main">
3221 <div class="main">
3220 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3222 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3221 <h3>Help: dates</h3>
3223 <h3>Help: dates</h3>
3222
3224
3223 <form class="search" action="/log">
3225 <form class="search" action="/log">
3224
3226
3225 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3227 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3226 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3228 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3227 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3229 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3228 </form>
3230 </form>
3229 <div id="doc">
3231 <div id="doc">
3230 <h1>Date Formats</h1>
3232 <h1>Date Formats</h1>
3231 <p>
3233 <p>
3232 Some commands allow the user to specify a date, e.g.:
3234 Some commands allow the user to specify a date, e.g.:
3233 </p>
3235 </p>
3234 <ul>
3236 <ul>
3235 <li> backout, commit, import, tag: Specify the commit date.
3237 <li> backout, commit, import, tag: Specify the commit date.
3236 <li> log, revert, update: Select revision(s) by date.
3238 <li> log, revert, update: Select revision(s) by date.
3237 </ul>
3239 </ul>
3238 <p>
3240 <p>
3239 Many date formats are valid. Here are some examples:
3241 Many date formats are valid. Here are some examples:
3240 </p>
3242 </p>
3241 <ul>
3243 <ul>
3242 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3244 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3243 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3245 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3244 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3246 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3245 <li> &quot;Dec 6&quot; (midnight)
3247 <li> &quot;Dec 6&quot; (midnight)
3246 <li> &quot;13:18&quot; (today assumed)
3248 <li> &quot;13:18&quot; (today assumed)
3247 <li> &quot;3:39&quot; (3:39AM assumed)
3249 <li> &quot;3:39&quot; (3:39AM assumed)
3248 <li> &quot;3:39pm&quot; (15:39)
3250 <li> &quot;3:39pm&quot; (15:39)
3249 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3251 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3250 <li> &quot;2006-12-6 13:18&quot;
3252 <li> &quot;2006-12-6 13:18&quot;
3251 <li> &quot;2006-12-6&quot;
3253 <li> &quot;2006-12-6&quot;
3252 <li> &quot;12-6&quot;
3254 <li> &quot;12-6&quot;
3253 <li> &quot;12/6&quot;
3255 <li> &quot;12/6&quot;
3254 <li> &quot;12/6/6&quot; (Dec 6 2006)
3256 <li> &quot;12/6/6&quot; (Dec 6 2006)
3255 <li> &quot;today&quot; (midnight)
3257 <li> &quot;today&quot; (midnight)
3256 <li> &quot;yesterday&quot; (midnight)
3258 <li> &quot;yesterday&quot; (midnight)
3257 <li> &quot;now&quot; - right now
3259 <li> &quot;now&quot; - right now
3258 </ul>
3260 </ul>
3259 <p>
3261 <p>
3260 Lastly, there is Mercurial's internal format:
3262 Lastly, there is Mercurial's internal format:
3261 </p>
3263 </p>
3262 <ul>
3264 <ul>
3263 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3265 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3264 </ul>
3266 </ul>
3265 <p>
3267 <p>
3266 This is the internal representation format for dates. The first number
3268 This is the internal representation format for dates. The first number
3267 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3269 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3268 second is the offset of the local timezone, in seconds west of UTC
3270 second is the offset of the local timezone, in seconds west of UTC
3269 (negative if the timezone is east of UTC).
3271 (negative if the timezone is east of UTC).
3270 </p>
3272 </p>
3271 <p>
3273 <p>
3272 The log command also accepts date ranges:
3274 The log command also accepts date ranges:
3273 </p>
3275 </p>
3274 <ul>
3276 <ul>
3275 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3277 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3276 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3278 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3277 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3279 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3278 <li> &quot;-DAYS&quot; - within a given number of days of today
3280 <li> &quot;-DAYS&quot; - within a given number of days of today
3279 </ul>
3281 </ul>
3280
3282
3281 </div>
3283 </div>
3282 </div>
3284 </div>
3283 </div>
3285 </div>
3284
3286
3285
3287
3286
3288
3287 </body>
3289 </body>
3288 </html>
3290 </html>
3289
3291
3290
3292
3291 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3293 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3292 200 Script output follows
3294 200 Script output follows
3293
3295
3294 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3296 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3295 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3297 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3296 <head>
3298 <head>
3297 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3299 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3298 <meta name="robots" content="index, nofollow" />
3300 <meta name="robots" content="index, nofollow" />
3299 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3301 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3300 <script type="text/javascript" src="/static/mercurial.js"></script>
3302 <script type="text/javascript" src="/static/mercurial.js"></script>
3301
3303
3302 <title>Help: pager</title>
3304 <title>Help: pager</title>
3303 </head>
3305 </head>
3304 <body>
3306 <body>
3305
3307
3306 <div class="container">
3308 <div class="container">
3307 <div class="menu">
3309 <div class="menu">
3308 <div class="logo">
3310 <div class="logo">
3309 <a href="https://mercurial-scm.org/">
3311 <a href="https://mercurial-scm.org/">
3310 <img src="/static/hglogo.png" alt="mercurial" /></a>
3312 <img src="/static/hglogo.png" alt="mercurial" /></a>
3311 </div>
3313 </div>
3312 <ul>
3314 <ul>
3313 <li><a href="/shortlog">log</a></li>
3315 <li><a href="/shortlog">log</a></li>
3314 <li><a href="/graph">graph</a></li>
3316 <li><a href="/graph">graph</a></li>
3315 <li><a href="/tags">tags</a></li>
3317 <li><a href="/tags">tags</a></li>
3316 <li><a href="/bookmarks">bookmarks</a></li>
3318 <li><a href="/bookmarks">bookmarks</a></li>
3317 <li><a href="/branches">branches</a></li>
3319 <li><a href="/branches">branches</a></li>
3318 </ul>
3320 </ul>
3319 <ul>
3321 <ul>
3320 <li class="active"><a href="/help">help</a></li>
3322 <li class="active"><a href="/help">help</a></li>
3321 </ul>
3323 </ul>
3322 </div>
3324 </div>
3323
3325
3324 <div class="main">
3326 <div class="main">
3325 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3327 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3326 <h3>Help: pager</h3>
3328 <h3>Help: pager</h3>
3327
3329
3328 <form class="search" action="/log">
3330 <form class="search" action="/log">
3329
3331
3330 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3332 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3331 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3333 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3332 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3334 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3333 </form>
3335 </form>
3334 <div id="doc">
3336 <div id="doc">
3335 <h1>Pager Support</h1>
3337 <h1>Pager Support</h1>
3336 <p>
3338 <p>
3337 Some Mercurial commands can produce a lot of output, and Mercurial will
3339 Some Mercurial commands can produce a lot of output, and Mercurial will
3338 attempt to use a pager to make those commands more pleasant.
3340 attempt to use a pager to make those commands more pleasant.
3339 </p>
3341 </p>
3340 <p>
3342 <p>
3341 To set the pager that should be used, set the application variable:
3343 To set the pager that should be used, set the application variable:
3342 </p>
3344 </p>
3343 <pre>
3345 <pre>
3344 [pager]
3346 [pager]
3345 pager = less -FRX
3347 pager = less -FRX
3346 </pre>
3348 </pre>
3347 <p>
3349 <p>
3348 If no pager is set in the user or repository configuration, Mercurial uses the
3350 If no pager is set in the user or repository configuration, Mercurial uses the
3349 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3351 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3350 or system configuration is used. If none of these are set, a default pager will
3352 or system configuration is used. If none of these are set, a default pager will
3351 be used, typically 'less' on Unix and 'more' on Windows.
3353 be used, typically 'less' on Unix and 'more' on Windows.
3352 </p>
3354 </p>
3353 <p>
3355 <p>
3354 You can disable the pager for certain commands by adding them to the
3356 You can disable the pager for certain commands by adding them to the
3355 pager.ignore list:
3357 pager.ignore list:
3356 </p>
3358 </p>
3357 <pre>
3359 <pre>
3358 [pager]
3360 [pager]
3359 ignore = version, help, update
3361 ignore = version, help, update
3360 </pre>
3362 </pre>
3361 <p>
3363 <p>
3362 To ignore global commands like 'hg version' or 'hg help', you have
3364 To ignore global commands like 'hg version' or 'hg help', you have
3363 to specify them in your user configuration file.
3365 to specify them in your user configuration file.
3364 </p>
3366 </p>
3365 <p>
3367 <p>
3366 To control whether the pager is used at all for an individual command,
3368 To control whether the pager is used at all for an individual command,
3367 you can use --pager=&lt;value&gt;:
3369 you can use --pager=&lt;value&gt;:
3368 </p>
3370 </p>
3369 <ul>
3371 <ul>
3370 <li> use as needed: 'auto'.
3372 <li> use as needed: 'auto'.
3371 <li> require the pager: 'yes' or 'on'.
3373 <li> require the pager: 'yes' or 'on'.
3372 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3374 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3373 </ul>
3375 </ul>
3374 <p>
3376 <p>
3375 To globally turn off all attempts to use a pager, set:
3377 To globally turn off all attempts to use a pager, set:
3376 </p>
3378 </p>
3377 <pre>
3379 <pre>
3378 [ui]
3380 [ui]
3379 paginate = never
3381 paginate = never
3380 </pre>
3382 </pre>
3381 <p>
3383 <p>
3382 which will prevent the pager from running.
3384 which will prevent the pager from running.
3383 </p>
3385 </p>
3384
3386
3385 </div>
3387 </div>
3386 </div>
3388 </div>
3387 </div>
3389 </div>
3388
3390
3389
3391
3390
3392
3391 </body>
3393 </body>
3392 </html>
3394 </html>
3393
3395
3394
3396
3395 Sub-topic indexes rendered properly
3397 Sub-topic indexes rendered properly
3396
3398
3397 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3399 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3398 200 Script output follows
3400 200 Script output follows
3399
3401
3400 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3402 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3401 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3403 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3402 <head>
3404 <head>
3403 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3405 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3404 <meta name="robots" content="index, nofollow" />
3406 <meta name="robots" content="index, nofollow" />
3405 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3407 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3406 <script type="text/javascript" src="/static/mercurial.js"></script>
3408 <script type="text/javascript" src="/static/mercurial.js"></script>
3407
3409
3408 <title>Help: internals</title>
3410 <title>Help: internals</title>
3409 </head>
3411 </head>
3410 <body>
3412 <body>
3411
3413
3412 <div class="container">
3414 <div class="container">
3413 <div class="menu">
3415 <div class="menu">
3414 <div class="logo">
3416 <div class="logo">
3415 <a href="https://mercurial-scm.org/">
3417 <a href="https://mercurial-scm.org/">
3416 <img src="/static/hglogo.png" alt="mercurial" /></a>
3418 <img src="/static/hglogo.png" alt="mercurial" /></a>
3417 </div>
3419 </div>
3418 <ul>
3420 <ul>
3419 <li><a href="/shortlog">log</a></li>
3421 <li><a href="/shortlog">log</a></li>
3420 <li><a href="/graph">graph</a></li>
3422 <li><a href="/graph">graph</a></li>
3421 <li><a href="/tags">tags</a></li>
3423 <li><a href="/tags">tags</a></li>
3422 <li><a href="/bookmarks">bookmarks</a></li>
3424 <li><a href="/bookmarks">bookmarks</a></li>
3423 <li><a href="/branches">branches</a></li>
3425 <li><a href="/branches">branches</a></li>
3424 </ul>
3426 </ul>
3425 <ul>
3427 <ul>
3426 <li><a href="/help">help</a></li>
3428 <li><a href="/help">help</a></li>
3427 </ul>
3429 </ul>
3428 </div>
3430 </div>
3429
3431
3430 <div class="main">
3432 <div class="main">
3431 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3433 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3432
3434
3433 <form class="search" action="/log">
3435 <form class="search" action="/log">
3434
3436
3435 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3437 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3436 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3438 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3437 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3439 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3438 </form>
3440 </form>
3439 <table class="bigtable">
3441 <table class="bigtable">
3440 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3442 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3441
3443
3442 <tr><td>
3444 <tr><td>
3443 <a href="/help/internals.bid-merge">
3445 <a href="/help/internals.bid-merge">
3444 bid-merge
3446 bid-merge
3445 </a>
3447 </a>
3446 </td><td>
3448 </td><td>
3447 Bid Merge Algorithm
3449 Bid Merge Algorithm
3448 </td></tr>
3450 </td></tr>
3449 <tr><td>
3451 <tr><td>
3450 <a href="/help/internals.bundle2">
3452 <a href="/help/internals.bundle2">
3451 bundle2
3453 bundle2
3452 </a>
3454 </a>
3453 </td><td>
3455 </td><td>
3454 Bundle2
3456 Bundle2
3455 </td></tr>
3457 </td></tr>
3456 <tr><td>
3458 <tr><td>
3457 <a href="/help/internals.bundles">
3459 <a href="/help/internals.bundles">
3458 bundles
3460 bundles
3459 </a>
3461 </a>
3460 </td><td>
3462 </td><td>
3461 Bundles
3463 Bundles
3462 </td></tr>
3464 </td></tr>
3463 <tr><td>
3465 <tr><td>
3464 <a href="/help/internals.cbor">
3466 <a href="/help/internals.cbor">
3465 cbor
3467 cbor
3466 </a>
3468 </a>
3467 </td><td>
3469 </td><td>
3468 CBOR
3470 CBOR
3469 </td></tr>
3471 </td></tr>
3470 <tr><td>
3472 <tr><td>
3471 <a href="/help/internals.censor">
3473 <a href="/help/internals.censor">
3472 censor
3474 censor
3473 </a>
3475 </a>
3474 </td><td>
3476 </td><td>
3475 Censor
3477 Censor
3476 </td></tr>
3478 </td></tr>
3477 <tr><td>
3479 <tr><td>
3478 <a href="/help/internals.changegroups">
3480 <a href="/help/internals.changegroups">
3479 changegroups
3481 changegroups
3480 </a>
3482 </a>
3481 </td><td>
3483 </td><td>
3482 Changegroups
3484 Changegroups
3483 </td></tr>
3485 </td></tr>
3484 <tr><td>
3486 <tr><td>
3485 <a href="/help/internals.config">
3487 <a href="/help/internals.config">
3486 config
3488 config
3487 </a>
3489 </a>
3488 </td><td>
3490 </td><td>
3489 Config Registrar
3491 Config Registrar
3490 </td></tr>
3492 </td></tr>
3491 <tr><td>
3493 <tr><td>
3492 <a href="/help/internals.extensions">
3494 <a href="/help/internals.extensions">
3493 extensions
3495 extensions
3494 </a>
3496 </a>
3495 </td><td>
3497 </td><td>
3496 Extension API
3498 Extension API
3497 </td></tr>
3499 </td></tr>
3498 <tr><td>
3500 <tr><td>
3499 <a href="/help/internals.mergestate">
3501 <a href="/help/internals.mergestate">
3500 mergestate
3502 mergestate
3501 </a>
3503 </a>
3502 </td><td>
3504 </td><td>
3503 Mergestate
3505 Mergestate
3504 </td></tr>
3506 </td></tr>
3505 <tr><td>
3507 <tr><td>
3506 <a href="/help/internals.requirements">
3508 <a href="/help/internals.requirements">
3507 requirements
3509 requirements
3508 </a>
3510 </a>
3509 </td><td>
3511 </td><td>
3510 Repository Requirements
3512 Repository Requirements
3511 </td></tr>
3513 </td></tr>
3512 <tr><td>
3514 <tr><td>
3513 <a href="/help/internals.revlogs">
3515 <a href="/help/internals.revlogs">
3514 revlogs
3516 revlogs
3515 </a>
3517 </a>
3516 </td><td>
3518 </td><td>
3517 Revision Logs
3519 Revision Logs
3518 </td></tr>
3520 </td></tr>
3519 <tr><td>
3521 <tr><td>
3520 <a href="/help/internals.wireprotocol">
3522 <a href="/help/internals.wireprotocol">
3521 wireprotocol
3523 wireprotocol
3522 </a>
3524 </a>
3523 </td><td>
3525 </td><td>
3524 Wire Protocol
3526 Wire Protocol
3525 </td></tr>
3527 </td></tr>
3526 <tr><td>
3528 <tr><td>
3527 <a href="/help/internals.wireprotocolrpc">
3529 <a href="/help/internals.wireprotocolrpc">
3528 wireprotocolrpc
3530 wireprotocolrpc
3529 </a>
3531 </a>
3530 </td><td>
3532 </td><td>
3531 Wire Protocol RPC
3533 Wire Protocol RPC
3532 </td></tr>
3534 </td></tr>
3533 <tr><td>
3535 <tr><td>
3534 <a href="/help/internals.wireprotocolv2">
3536 <a href="/help/internals.wireprotocolv2">
3535 wireprotocolv2
3537 wireprotocolv2
3536 </a>
3538 </a>
3537 </td><td>
3539 </td><td>
3538 Wire Protocol Version 2
3540 Wire Protocol Version 2
3539 </td></tr>
3541 </td></tr>
3540
3542
3541
3543
3542
3544
3543
3545
3544
3546
3545 </table>
3547 </table>
3546 </div>
3548 </div>
3547 </div>
3549 </div>
3548
3550
3549
3551
3550
3552
3551 </body>
3553 </body>
3552 </html>
3554 </html>
3553
3555
3554
3556
3555 Sub-topic topics rendered properly
3557 Sub-topic topics rendered properly
3556
3558
3557 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3559 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3558 200 Script output follows
3560 200 Script output follows
3559
3561
3560 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3562 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3561 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3563 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3562 <head>
3564 <head>
3563 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3565 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3564 <meta name="robots" content="index, nofollow" />
3566 <meta name="robots" content="index, nofollow" />
3565 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3567 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3566 <script type="text/javascript" src="/static/mercurial.js"></script>
3568 <script type="text/javascript" src="/static/mercurial.js"></script>
3567
3569
3568 <title>Help: internals.changegroups</title>
3570 <title>Help: internals.changegroups</title>
3569 </head>
3571 </head>
3570 <body>
3572 <body>
3571
3573
3572 <div class="container">
3574 <div class="container">
3573 <div class="menu">
3575 <div class="menu">
3574 <div class="logo">
3576 <div class="logo">
3575 <a href="https://mercurial-scm.org/">
3577 <a href="https://mercurial-scm.org/">
3576 <img src="/static/hglogo.png" alt="mercurial" /></a>
3578 <img src="/static/hglogo.png" alt="mercurial" /></a>
3577 </div>
3579 </div>
3578 <ul>
3580 <ul>
3579 <li><a href="/shortlog">log</a></li>
3581 <li><a href="/shortlog">log</a></li>
3580 <li><a href="/graph">graph</a></li>
3582 <li><a href="/graph">graph</a></li>
3581 <li><a href="/tags">tags</a></li>
3583 <li><a href="/tags">tags</a></li>
3582 <li><a href="/bookmarks">bookmarks</a></li>
3584 <li><a href="/bookmarks">bookmarks</a></li>
3583 <li><a href="/branches">branches</a></li>
3585 <li><a href="/branches">branches</a></li>
3584 </ul>
3586 </ul>
3585 <ul>
3587 <ul>
3586 <li class="active"><a href="/help">help</a></li>
3588 <li class="active"><a href="/help">help</a></li>
3587 </ul>
3589 </ul>
3588 </div>
3590 </div>
3589
3591
3590 <div class="main">
3592 <div class="main">
3591 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3593 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3592 <h3>Help: internals.changegroups</h3>
3594 <h3>Help: internals.changegroups</h3>
3593
3595
3594 <form class="search" action="/log">
3596 <form class="search" action="/log">
3595
3597
3596 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3598 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3597 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3599 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3598 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3600 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3599 </form>
3601 </form>
3600 <div id="doc">
3602 <div id="doc">
3601 <h1>Changegroups</h1>
3603 <h1>Changegroups</h1>
3602 <p>
3604 <p>
3603 Changegroups are representations of repository revlog data, specifically
3605 Changegroups are representations of repository revlog data, specifically
3604 the changelog data, root/flat manifest data, treemanifest data, and
3606 the changelog data, root/flat manifest data, treemanifest data, and
3605 filelogs.
3607 filelogs.
3606 </p>
3608 </p>
3607 <p>
3609 <p>
3608 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3610 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3609 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3611 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3610 only difference being an additional item in the *delta header*. Version
3612 only difference being an additional item in the *delta header*. Version
3611 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3613 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3612 exchanging treemanifests (enabled by setting an option on the
3614 exchanging treemanifests (enabled by setting an option on the
3613 &quot;changegroup&quot; part in the bundle2).
3615 &quot;changegroup&quot; part in the bundle2).
3614 </p>
3616 </p>
3615 <p>
3617 <p>
3616 Changegroups when not exchanging treemanifests consist of 3 logical
3618 Changegroups when not exchanging treemanifests consist of 3 logical
3617 segments:
3619 segments:
3618 </p>
3620 </p>
3619 <pre>
3621 <pre>
3620 +---------------------------------+
3622 +---------------------------------+
3621 | | | |
3623 | | | |
3622 | changeset | manifest | filelogs |
3624 | changeset | manifest | filelogs |
3623 | | | |
3625 | | | |
3624 | | | |
3626 | | | |
3625 +---------------------------------+
3627 +---------------------------------+
3626 </pre>
3628 </pre>
3627 <p>
3629 <p>
3628 When exchanging treemanifests, there are 4 logical segments:
3630 When exchanging treemanifests, there are 4 logical segments:
3629 </p>
3631 </p>
3630 <pre>
3632 <pre>
3631 +-------------------------------------------------+
3633 +-------------------------------------------------+
3632 | | | | |
3634 | | | | |
3633 | changeset | root | treemanifests | filelogs |
3635 | changeset | root | treemanifests | filelogs |
3634 | | manifest | | |
3636 | | manifest | | |
3635 | | | | |
3637 | | | | |
3636 +-------------------------------------------------+
3638 +-------------------------------------------------+
3637 </pre>
3639 </pre>
3638 <p>
3640 <p>
3639 The principle building block of each segment is a *chunk*. A *chunk*
3641 The principle building block of each segment is a *chunk*. A *chunk*
3640 is a framed piece of data:
3642 is a framed piece of data:
3641 </p>
3643 </p>
3642 <pre>
3644 <pre>
3643 +---------------------------------------+
3645 +---------------------------------------+
3644 | | |
3646 | | |
3645 | length | data |
3647 | length | data |
3646 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3648 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3647 | | |
3649 | | |
3648 +---------------------------------------+
3650 +---------------------------------------+
3649 </pre>
3651 </pre>
3650 <p>
3652 <p>
3651 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3653 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3652 integer indicating the length of the entire chunk (including the length field
3654 integer indicating the length of the entire chunk (including the length field
3653 itself).
3655 itself).
3654 </p>
3656 </p>
3655 <p>
3657 <p>
3656 There is a special case chunk that has a value of 0 for the length
3658 There is a special case chunk that has a value of 0 for the length
3657 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3659 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3658 </p>
3660 </p>
3659 <h2>Delta Groups</h2>
3661 <h2>Delta Groups</h2>
3660 <p>
3662 <p>
3661 A *delta group* expresses the content of a revlog as a series of deltas,
3663 A *delta group* expresses the content of a revlog as a series of deltas,
3662 or patches against previous revisions.
3664 or patches against previous revisions.
3663 </p>
3665 </p>
3664 <p>
3666 <p>
3665 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3667 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3666 to signal the end of the delta group:
3668 to signal the end of the delta group:
3667 </p>
3669 </p>
3668 <pre>
3670 <pre>
3669 +------------------------------------------------------------------------+
3671 +------------------------------------------------------------------------+
3670 | | | | | |
3672 | | | | | |
3671 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3673 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3672 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3674 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3673 | | | | | |
3675 | | | | | |
3674 +------------------------------------------------------------------------+
3676 +------------------------------------------------------------------------+
3675 </pre>
3677 </pre>
3676 <p>
3678 <p>
3677 Each *chunk*'s data consists of the following:
3679 Each *chunk*'s data consists of the following:
3678 </p>
3680 </p>
3679 <pre>
3681 <pre>
3680 +---------------------------------------+
3682 +---------------------------------------+
3681 | | |
3683 | | |
3682 | delta header | delta data |
3684 | delta header | delta data |
3683 | (various by version) | (various) |
3685 | (various by version) | (various) |
3684 | | |
3686 | | |
3685 +---------------------------------------+
3687 +---------------------------------------+
3686 </pre>
3688 </pre>
3687 <p>
3689 <p>
3688 The *delta data* is a series of *delta*s that describe a diff from an existing
3690 The *delta data* is a series of *delta*s that describe a diff from an existing
3689 entry (either that the recipient already has, or previously specified in the
3691 entry (either that the recipient already has, or previously specified in the
3690 bundle/changegroup).
3692 bundle/changegroup).
3691 </p>
3693 </p>
3692 <p>
3694 <p>
3693 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3695 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3694 &quot;3&quot; of the changegroup format.
3696 &quot;3&quot; of the changegroup format.
3695 </p>
3697 </p>
3696 <p>
3698 <p>
3697 Version 1 (headerlen=80):
3699 Version 1 (headerlen=80):
3698 </p>
3700 </p>
3699 <pre>
3701 <pre>
3700 +------------------------------------------------------+
3702 +------------------------------------------------------+
3701 | | | | |
3703 | | | | |
3702 | node | p1 node | p2 node | link node |
3704 | node | p1 node | p2 node | link node |
3703 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3705 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3704 | | | | |
3706 | | | | |
3705 +------------------------------------------------------+
3707 +------------------------------------------------------+
3706 </pre>
3708 </pre>
3707 <p>
3709 <p>
3708 Version 2 (headerlen=100):
3710 Version 2 (headerlen=100):
3709 </p>
3711 </p>
3710 <pre>
3712 <pre>
3711 +------------------------------------------------------------------+
3713 +------------------------------------------------------------------+
3712 | | | | | |
3714 | | | | | |
3713 | node | p1 node | p2 node | base node | link node |
3715 | node | p1 node | p2 node | base node | link node |
3714 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3716 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3715 | | | | | |
3717 | | | | | |
3716 +------------------------------------------------------------------+
3718 +------------------------------------------------------------------+
3717 </pre>
3719 </pre>
3718 <p>
3720 <p>
3719 Version 3 (headerlen=102):
3721 Version 3 (headerlen=102):
3720 </p>
3722 </p>
3721 <pre>
3723 <pre>
3722 +------------------------------------------------------------------------------+
3724 +------------------------------------------------------------------------------+
3723 | | | | | | |
3725 | | | | | | |
3724 | node | p1 node | p2 node | base node | link node | flags |
3726 | node | p1 node | p2 node | base node | link node | flags |
3725 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3727 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3726 | | | | | | |
3728 | | | | | | |
3727 +------------------------------------------------------------------------------+
3729 +------------------------------------------------------------------------------+
3728 </pre>
3730 </pre>
3729 <p>
3731 <p>
3730 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3732 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3731 series of *delta*s, densely packed (no separators). These deltas describe a diff
3733 series of *delta*s, densely packed (no separators). These deltas describe a diff
3732 from an existing entry (either that the recipient already has, or previously
3734 from an existing entry (either that the recipient already has, or previously
3733 specified in the bundle/changegroup). The format is described more fully in
3735 specified in the bundle/changegroup). The format is described more fully in
3734 &quot;hg help internals.bdiff&quot;, but briefly:
3736 &quot;hg help internals.bdiff&quot;, but briefly:
3735 </p>
3737 </p>
3736 <pre>
3738 <pre>
3737 +---------------------------------------------------------------+
3739 +---------------------------------------------------------------+
3738 | | | | |
3740 | | | | |
3739 | start offset | end offset | new length | content |
3741 | start offset | end offset | new length | content |
3740 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3742 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3741 | | | | |
3743 | | | | |
3742 +---------------------------------------------------------------+
3744 +---------------------------------------------------------------+
3743 </pre>
3745 </pre>
3744 <p>
3746 <p>
3745 Please note that the length field in the delta data does *not* include itself.
3747 Please note that the length field in the delta data does *not* include itself.
3746 </p>
3748 </p>
3747 <p>
3749 <p>
3748 In version 1, the delta is always applied against the previous node from
3750 In version 1, the delta is always applied against the previous node from
3749 the changegroup or the first parent if this is the first entry in the
3751 the changegroup or the first parent if this is the first entry in the
3750 changegroup.
3752 changegroup.
3751 </p>
3753 </p>
3752 <p>
3754 <p>
3753 In version 2 and up, the delta base node is encoded in the entry in the
3755 In version 2 and up, the delta base node is encoded in the entry in the
3754 changegroup. This allows the delta to be expressed against any parent,
3756 changegroup. This allows the delta to be expressed against any parent,
3755 which can result in smaller deltas and more efficient encoding of data.
3757 which can result in smaller deltas and more efficient encoding of data.
3756 </p>
3758 </p>
3757 <p>
3759 <p>
3758 The *flags* field holds bitwise flags affecting the processing of revision
3760 The *flags* field holds bitwise flags affecting the processing of revision
3759 data. The following flags are defined:
3761 data. The following flags are defined:
3760 </p>
3762 </p>
3761 <dl>
3763 <dl>
3762 <dt>32768
3764 <dt>32768
3763 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3765 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3764 <dt>16384
3766 <dt>16384
3765 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3767 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3766 <dt>8192
3768 <dt>8192
3767 <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.
3769 <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.
3768 </dl>
3770 </dl>
3769 <p>
3771 <p>
3770 For historical reasons, the integer values are identical to revlog version 1
3772 For historical reasons, the integer values are identical to revlog version 1
3771 per-revision storage flags and correspond to bits being set in this 2-byte
3773 per-revision storage flags and correspond to bits being set in this 2-byte
3772 field. Bits were allocated starting from the most-significant bit, hence the
3774 field. Bits were allocated starting from the most-significant bit, hence the
3773 reverse ordering and allocation of these flags.
3775 reverse ordering and allocation of these flags.
3774 </p>
3776 </p>
3775 <h2>Changeset Segment</h2>
3777 <h2>Changeset Segment</h2>
3776 <p>
3778 <p>
3777 The *changeset segment* consists of a single *delta group* holding
3779 The *changeset segment* consists of a single *delta group* holding
3778 changelog data. The *empty chunk* at the end of the *delta group* denotes
3780 changelog data. The *empty chunk* at the end of the *delta group* denotes
3779 the boundary to the *manifest segment*.
3781 the boundary to the *manifest segment*.
3780 </p>
3782 </p>
3781 <h2>Manifest Segment</h2>
3783 <h2>Manifest Segment</h2>
3782 <p>
3784 <p>
3783 The *manifest segment* consists of a single *delta group* holding manifest
3785 The *manifest segment* consists of a single *delta group* holding manifest
3784 data. If treemanifests are in use, it contains only the manifest for the
3786 data. If treemanifests are in use, it contains only the manifest for the
3785 root directory of the repository. Otherwise, it contains the entire
3787 root directory of the repository. Otherwise, it contains the entire
3786 manifest data. The *empty chunk* at the end of the *delta group* denotes
3788 manifest data. The *empty chunk* at the end of the *delta group* denotes
3787 the boundary to the next segment (either the *treemanifests segment* or the
3789 the boundary to the next segment (either the *treemanifests segment* or the
3788 *filelogs segment*, depending on version and the request options).
3790 *filelogs segment*, depending on version and the request options).
3789 </p>
3791 </p>
3790 <h3>Treemanifests Segment</h3>
3792 <h3>Treemanifests Segment</h3>
3791 <p>
3793 <p>
3792 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3794 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3793 only if the 'treemanifest' param is part of the bundle2 changegroup part
3795 only if the 'treemanifest' param is part of the bundle2 changegroup part
3794 (it is not possible to use changegroup version 3 outside of bundle2).
3796 (it is not possible to use changegroup version 3 outside of bundle2).
3795 Aside from the filenames in the *treemanifests segment* containing a
3797 Aside from the filenames in the *treemanifests segment* containing a
3796 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3798 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3797 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3799 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3798 a sub-segment with filename size 0). This denotes the boundary to the
3800 a sub-segment with filename size 0). This denotes the boundary to the
3799 *filelogs segment*.
3801 *filelogs segment*.
3800 </p>
3802 </p>
3801 <h2>Filelogs Segment</h2>
3803 <h2>Filelogs Segment</h2>
3802 <p>
3804 <p>
3803 The *filelogs segment* consists of multiple sub-segments, each
3805 The *filelogs segment* consists of multiple sub-segments, each
3804 corresponding to an individual file whose data is being described:
3806 corresponding to an individual file whose data is being described:
3805 </p>
3807 </p>
3806 <pre>
3808 <pre>
3807 +--------------------------------------------------+
3809 +--------------------------------------------------+
3808 | | | | | |
3810 | | | | | |
3809 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3811 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3810 | | | | | (4 bytes) |
3812 | | | | | (4 bytes) |
3811 | | | | | |
3813 | | | | | |
3812 +--------------------------------------------------+
3814 +--------------------------------------------------+
3813 </pre>
3815 </pre>
3814 <p>
3816 <p>
3815 The final filelog sub-segment is followed by an *empty chunk* (logically,
3817 The final filelog sub-segment is followed by an *empty chunk* (logically,
3816 a sub-segment with filename size 0). This denotes the end of the segment
3818 a sub-segment with filename size 0). This denotes the end of the segment
3817 and of the overall changegroup.
3819 and of the overall changegroup.
3818 </p>
3820 </p>
3819 <p>
3821 <p>
3820 Each filelog sub-segment consists of the following:
3822 Each filelog sub-segment consists of the following:
3821 </p>
3823 </p>
3822 <pre>
3824 <pre>
3823 +------------------------------------------------------+
3825 +------------------------------------------------------+
3824 | | | |
3826 | | | |
3825 | filename length | filename | delta group |
3827 | filename length | filename | delta group |
3826 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3828 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3827 | | | |
3829 | | | |
3828 +------------------------------------------------------+
3830 +------------------------------------------------------+
3829 </pre>
3831 </pre>
3830 <p>
3832 <p>
3831 That is, a *chunk* consisting of the filename (not terminated or padded)
3833 That is, a *chunk* consisting of the filename (not terminated or padded)
3832 followed by N chunks constituting the *delta group* for this file. The
3834 followed by N chunks constituting the *delta group* for this file. The
3833 *empty chunk* at the end of each *delta group* denotes the boundary to the
3835 *empty chunk* at the end of each *delta group* denotes the boundary to the
3834 next filelog sub-segment.
3836 next filelog sub-segment.
3835 </p>
3837 </p>
3836
3838
3837 </div>
3839 </div>
3838 </div>
3840 </div>
3839 </div>
3841 </div>
3840
3842
3841
3843
3842
3844
3843 </body>
3845 </body>
3844 </html>
3846 </html>
3845
3847
3846
3848
3847 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3849 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3848 404 Not Found
3850 404 Not Found
3849
3851
3850 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3852 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3851 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3853 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3852 <head>
3854 <head>
3853 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3855 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3854 <meta name="robots" content="index, nofollow" />
3856 <meta name="robots" content="index, nofollow" />
3855 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3857 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3856 <script type="text/javascript" src="/static/mercurial.js"></script>
3858 <script type="text/javascript" src="/static/mercurial.js"></script>
3857
3859
3858 <title>test: error</title>
3860 <title>test: error</title>
3859 </head>
3861 </head>
3860 <body>
3862 <body>
3861
3863
3862 <div class="container">
3864 <div class="container">
3863 <div class="menu">
3865 <div class="menu">
3864 <div class="logo">
3866 <div class="logo">
3865 <a href="https://mercurial-scm.org/">
3867 <a href="https://mercurial-scm.org/">
3866 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3868 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3867 </div>
3869 </div>
3868 <ul>
3870 <ul>
3869 <li><a href="/shortlog">log</a></li>
3871 <li><a href="/shortlog">log</a></li>
3870 <li><a href="/graph">graph</a></li>
3872 <li><a href="/graph">graph</a></li>
3871 <li><a href="/tags">tags</a></li>
3873 <li><a href="/tags">tags</a></li>
3872 <li><a href="/bookmarks">bookmarks</a></li>
3874 <li><a href="/bookmarks">bookmarks</a></li>
3873 <li><a href="/branches">branches</a></li>
3875 <li><a href="/branches">branches</a></li>
3874 </ul>
3876 </ul>
3875 <ul>
3877 <ul>
3876 <li><a href="/help">help</a></li>
3878 <li><a href="/help">help</a></li>
3877 </ul>
3879 </ul>
3878 </div>
3880 </div>
3879
3881
3880 <div class="main">
3882 <div class="main">
3881
3883
3882 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3884 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3883 <h3>error</h3>
3885 <h3>error</h3>
3884
3886
3885
3887
3886 <form class="search" action="/log">
3888 <form class="search" action="/log">
3887
3889
3888 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3890 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3889 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3891 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3890 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3892 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3891 </form>
3893 </form>
3892
3894
3893 <div class="description">
3895 <div class="description">
3894 <p>
3896 <p>
3895 An error occurred while processing your request:
3897 An error occurred while processing your request:
3896 </p>
3898 </p>
3897 <p>
3899 <p>
3898 Not Found
3900 Not Found
3899 </p>
3901 </p>
3900 </div>
3902 </div>
3901 </div>
3903 </div>
3902 </div>
3904 </div>
3903
3905
3904
3906
3905
3907
3906 </body>
3908 </body>
3907 </html>
3909 </html>
3908
3910
3909 [1]
3911 [1]
3910
3912
3911 $ killdaemons.py
3913 $ killdaemons.py
3912
3914
3913 #endif
3915 #endif
@@ -1,73 +1,81
1 $ hg init t
1 $ hg init t
2 $ cd t
2 $ cd t
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ hg commit -m test
5 $ hg commit -m test
6 $ rm .hg/requires
6 $ rm .hg/requires
7 $ hg tip
7 $ hg tip
8 abort: unknown version (2) in revlog 00changelog.i!
8 abort: unknown version (2) in revlog 00changelog.i!
9 [255]
9 [255]
10 $ echo indoor-pool > .hg/requires
10 $ echo indoor-pool > .hg/requires
11 $ hg tip
11 $ hg tip
12 abort: repository requires features unknown to this Mercurial: indoor-pool!
12 abort: repository requires features unknown to this Mercurial: indoor-pool!
13 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
13 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
14 [255]
14 [255]
15 $ echo outdoor-pool >> .hg/requires
15 $ echo outdoor-pool >> .hg/requires
16 $ hg tip
16 $ hg tip
17 abort: repository requires features unknown to this Mercurial: indoor-pool outdoor-pool!
17 abort: repository requires features unknown to this Mercurial: indoor-pool outdoor-pool!
18 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
18 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
19 [255]
19 [255]
20 $ cd ..
20 $ cd ..
21
21
22 Test checking between features supported locally and ones required in
22 Test checking between features supported locally and ones required in
23 another repository of push/pull/clone on localhost:
23 another repository of push/pull/clone on localhost:
24
24
25 $ mkdir supported-locally
25 $ mkdir supported-locally
26 $ cd supported-locally
26 $ cd supported-locally
27
27
28 $ hg init supported
28 $ hg init supported
29 $ echo a > supported/a
29 $ echo a > supported/a
30 $ hg -R supported commit -Am '#0 at supported'
30 $ hg -R supported commit -Am '#0 at supported'
31 adding a
31 adding a
32
32
33 $ echo 'featuresetup-test' >> supported/.hg/requires
33 $ echo 'featuresetup-test' >> supported/.hg/requires
34 $ cat > $TESTTMP/supported-locally/supportlocally.py <<EOF
34 $ cat > $TESTTMP/supported-locally/supportlocally.py <<EOF
35 > from __future__ import absolute_import
35 > from __future__ import absolute_import
36 > from mercurial import extensions, localrepo
36 > from mercurial import extensions, localrepo
37 > def featuresetup(ui, supported):
37 > def featuresetup(ui, supported):
38 > for name, module in extensions.extensions(ui):
38 > for name, module in extensions.extensions(ui):
39 > if __name__ == module.__name__:
39 > if __name__ == module.__name__:
40 > # support specific feature locally
40 > # support specific feature locally
41 > supported |= {b'featuresetup-test'}
41 > supported |= {b'featuresetup-test'}
42 > return
42 > return
43 > def uisetup(ui):
43 > def uisetup(ui):
44 > localrepo.featuresetupfuncs.add(featuresetup)
44 > localrepo.featuresetupfuncs.add(featuresetup)
45 > EOF
45 > EOF
46 $ cat > supported/.hg/hgrc <<EOF
46 $ cat > supported/.hg/hgrc <<EOF
47 > [extensions]
47 > [extensions]
48 > # enable extension locally
48 > # enable extension locally
49 > supportlocally = $TESTTMP/supported-locally/supportlocally.py
49 > supportlocally = $TESTTMP/supported-locally/supportlocally.py
50 > EOF
50 > EOF
51 $ hg -R supported debugrequirements
52 dotencode
53 featuresetup-test
54 fncache
55 generaldelta
56 revlogv1
57 sparserevlog
58 store
51 $ hg -R supported status
59 $ hg -R supported status
52
60
53 $ hg init push-dst
61 $ hg init push-dst
54 $ hg -R supported push push-dst
62 $ hg -R supported push push-dst
55 pushing to push-dst
63 pushing to push-dst
56 abort: required features are not supported in the destination: featuresetup-test
64 abort: required features are not supported in the destination: featuresetup-test
57 [255]
65 [255]
58
66
59 $ hg init pull-src
67 $ hg init pull-src
60 $ hg -R pull-src pull supported
68 $ hg -R pull-src pull supported
61 pulling from supported
69 pulling from supported
62 abort: required features are not supported in the destination: featuresetup-test
70 abort: required features are not supported in the destination: featuresetup-test
63 [255]
71 [255]
64
72
65 $ hg clone supported clone-dst
73 $ hg clone supported clone-dst
66 abort: repository requires features unknown to this Mercurial: featuresetup-test!
74 abort: repository requires features unknown to this Mercurial: featuresetup-test!
67 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
75 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
68 [255]
76 [255]
69 $ hg clone --pull supported clone-dst
77 $ hg clone --pull supported clone-dst
70 abort: required features are not supported in the destination: featuresetup-test
78 abort: required features are not supported in the destination: featuresetup-test
71 [255]
79 [255]
72
80
73 $ cd ..
81 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now