##// END OF EJS Templates
debugindex: rename to debugindex debug-revlog-index...
marmoute -
r50144:db19f6be default
parent child Browse files
Show More
@@ -1,5051 +1,5051 b''
1 # debugcommands.py - command processing for debug* commands
1 # debugcommands.py - command processing for debug* commands
2 #
2 #
3 # Copyright 2005-2016 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2005-2016 Olivia Mackall <olivia@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
8
9 import binascii
9 import binascii
10 import codecs
10 import codecs
11 import collections
11 import collections
12 import contextlib
12 import contextlib
13 import difflib
13 import difflib
14 import errno
14 import errno
15 import glob
15 import glob
16 import operator
16 import operator
17 import os
17 import os
18 import platform
18 import platform
19 import random
19 import random
20 import re
20 import re
21 import socket
21 import socket
22 import ssl
22 import ssl
23 import stat
23 import stat
24 import string
24 import string
25 import subprocess
25 import subprocess
26 import sys
26 import sys
27 import time
27 import time
28
28
29 from .i18n import _
29 from .i18n import _
30 from .node import (
30 from .node import (
31 bin,
31 bin,
32 hex,
32 hex,
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 dirstateutils,
49 dirstateutils,
50 encoding,
50 encoding,
51 error,
51 error,
52 exchange,
52 exchange,
53 extensions,
53 extensions,
54 filemerge,
54 filemerge,
55 filesetlang,
55 filesetlang,
56 formatter,
56 formatter,
57 hg,
57 hg,
58 httppeer,
58 httppeer,
59 localrepo,
59 localrepo,
60 lock as lockmod,
60 lock as lockmod,
61 logcmdutil,
61 logcmdutil,
62 mergestate as mergestatemod,
62 mergestate as mergestatemod,
63 metadata,
63 metadata,
64 obsolete,
64 obsolete,
65 obsutil,
65 obsutil,
66 pathutil,
66 pathutil,
67 phases,
67 phases,
68 policy,
68 policy,
69 pvec,
69 pvec,
70 pycompat,
70 pycompat,
71 registrar,
71 registrar,
72 repair,
72 repair,
73 repoview,
73 repoview,
74 requirements,
74 requirements,
75 revlog,
75 revlog,
76 revlogutils,
76 revlogutils,
77 revset,
77 revset,
78 revsetlang,
78 revsetlang,
79 scmutil,
79 scmutil,
80 setdiscovery,
80 setdiscovery,
81 simplemerge,
81 simplemerge,
82 sshpeer,
82 sshpeer,
83 sslutil,
83 sslutil,
84 streamclone,
84 streamclone,
85 strip,
85 strip,
86 tags as tagsmod,
86 tags as tagsmod,
87 templater,
87 templater,
88 treediscovery,
88 treediscovery,
89 upgrade,
89 upgrade,
90 url as urlmod,
90 url as urlmod,
91 util,
91 util,
92 vfs as vfsmod,
92 vfs as vfsmod,
93 wireprotoframing,
93 wireprotoframing,
94 wireprotoserver,
94 wireprotoserver,
95 )
95 )
96 from .interfaces import repository
96 from .interfaces import repository
97 from .utils import (
97 from .utils import (
98 cborutil,
98 cborutil,
99 compression,
99 compression,
100 dateutil,
100 dateutil,
101 procutil,
101 procutil,
102 stringutil,
102 stringutil,
103 urlutil,
103 urlutil,
104 )
104 )
105
105
106 from .revlogutils import (
106 from .revlogutils import (
107 constants as revlog_constants,
107 constants as revlog_constants,
108 deltas as deltautil,
108 deltas as deltautil,
109 nodemap,
109 nodemap,
110 rewrite,
110 rewrite,
111 sidedata,
111 sidedata,
112 )
112 )
113
113
114 release = lockmod.release
114 release = lockmod.release
115
115
116 table = {}
116 table = {}
117 table.update(strip.command._table)
117 table.update(strip.command._table)
118 command = registrar.command(table)
118 command = registrar.command(table)
119
119
120
120
121 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
121 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
122 def debugancestor(ui, repo, *args):
122 def debugancestor(ui, repo, *args):
123 """find the ancestor revision of two revisions in a given index"""
123 """find the ancestor revision of two revisions in a given index"""
124 if len(args) == 3:
124 if len(args) == 3:
125 index, rev1, rev2 = args
125 index, rev1, rev2 = args
126 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
126 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
127 lookup = r.lookup
127 lookup = r.lookup
128 elif len(args) == 2:
128 elif len(args) == 2:
129 if not repo:
129 if not repo:
130 raise error.Abort(
130 raise error.Abort(
131 _(b'there is no Mercurial repository here (.hg not found)')
131 _(b'there is no Mercurial repository here (.hg not found)')
132 )
132 )
133 rev1, rev2 = args
133 rev1, rev2 = args
134 r = repo.changelog
134 r = repo.changelog
135 lookup = repo.lookup
135 lookup = repo.lookup
136 else:
136 else:
137 raise error.Abort(_(b'either two or three arguments required'))
137 raise error.Abort(_(b'either two or three arguments required'))
138 a = r.ancestor(lookup(rev1), lookup(rev2))
138 a = r.ancestor(lookup(rev1), lookup(rev2))
139 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
139 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
140
140
141
141
142 @command(b'debugantivirusrunning', [])
142 @command(b'debugantivirusrunning', [])
143 def debugantivirusrunning(ui, repo):
143 def debugantivirusrunning(ui, repo):
144 """attempt to trigger an antivirus scanner to see if one is active"""
144 """attempt to trigger an antivirus scanner to see if one is active"""
145 with repo.cachevfs.open('eicar-test-file.com', b'wb') as f:
145 with repo.cachevfs.open('eicar-test-file.com', b'wb') as f:
146 f.write(
146 f.write(
147 util.b85decode(
147 util.b85decode(
148 # This is a base85-armored version of the EICAR test file. See
148 # This is a base85-armored version of the EICAR test file. See
149 # https://en.wikipedia.org/wiki/EICAR_test_file for details.
149 # https://en.wikipedia.org/wiki/EICAR_test_file for details.
150 b'ST#=}P$fV?P+K%yP+C|uG$>GBDK|qyDK~v2MM*<JQY}+dK~6+LQba95P'
150 b'ST#=}P$fV?P+K%yP+C|uG$>GBDK|qyDK~v2MM*<JQY}+dK~6+LQba95P'
151 b'E<)&Nm5l)EmTEQR4qnHOhq9iNGnJx'
151 b'E<)&Nm5l)EmTEQR4qnHOhq9iNGnJx'
152 )
152 )
153 )
153 )
154 # Give an AV engine time to scan the file.
154 # Give an AV engine time to scan the file.
155 time.sleep(2)
155 time.sleep(2)
156 util.unlink(repo.cachevfs.join('eicar-test-file.com'))
156 util.unlink(repo.cachevfs.join('eicar-test-file.com'))
157
157
158
158
159 @command(b'debugapplystreamclonebundle', [], b'FILE')
159 @command(b'debugapplystreamclonebundle', [], b'FILE')
160 def debugapplystreamclonebundle(ui, repo, fname):
160 def debugapplystreamclonebundle(ui, repo, fname):
161 """apply a stream clone bundle file"""
161 """apply a stream clone bundle file"""
162 f = hg.openpath(ui, fname)
162 f = hg.openpath(ui, fname)
163 gen = exchange.readbundle(ui, f, fname)
163 gen = exchange.readbundle(ui, f, fname)
164 gen.apply(repo)
164 gen.apply(repo)
165
165
166
166
167 @command(
167 @command(
168 b'debugbuilddag',
168 b'debugbuilddag',
169 [
169 [
170 (
170 (
171 b'm',
171 b'm',
172 b'mergeable-file',
172 b'mergeable-file',
173 None,
173 None,
174 _(b'add single file mergeable changes'),
174 _(b'add single file mergeable changes'),
175 ),
175 ),
176 (
176 (
177 b'o',
177 b'o',
178 b'overwritten-file',
178 b'overwritten-file',
179 None,
179 None,
180 _(b'add single file all revs overwrite'),
180 _(b'add single file all revs overwrite'),
181 ),
181 ),
182 (b'n', b'new-file', None, _(b'add new file at each rev')),
182 (b'n', b'new-file', None, _(b'add new file at each rev')),
183 (
183 (
184 b'',
184 b'',
185 b'from-existing',
185 b'from-existing',
186 None,
186 None,
187 _(b'continue from a non-empty repository'),
187 _(b'continue from a non-empty repository'),
188 ),
188 ),
189 ],
189 ],
190 _(b'[OPTION]... [TEXT]'),
190 _(b'[OPTION]... [TEXT]'),
191 )
191 )
192 def debugbuilddag(
192 def debugbuilddag(
193 ui,
193 ui,
194 repo,
194 repo,
195 text=None,
195 text=None,
196 mergeable_file=False,
196 mergeable_file=False,
197 overwritten_file=False,
197 overwritten_file=False,
198 new_file=False,
198 new_file=False,
199 from_existing=False,
199 from_existing=False,
200 ):
200 ):
201 """builds a repo with a given DAG from scratch in the current empty repo
201 """builds a repo with a given DAG from scratch in the current empty repo
202
202
203 The description of the DAG is read from stdin if not given on the
203 The description of the DAG is read from stdin if not given on the
204 command line.
204 command line.
205
205
206 Elements:
206 Elements:
207
207
208 - "+n" is a linear run of n nodes based on the current default parent
208 - "+n" is a linear run of n nodes based on the current default parent
209 - "." is a single node based on the current default parent
209 - "." is a single node based on the current default parent
210 - "$" resets the default parent to null (implied at the start);
210 - "$" resets the default parent to null (implied at the start);
211 otherwise the default parent is always the last node created
211 otherwise the default parent is always the last node created
212 - "<p" sets the default parent to the backref p
212 - "<p" sets the default parent to the backref p
213 - "*p" is a fork at parent p, which is a backref
213 - "*p" is a fork at parent p, which is a backref
214 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
214 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
215 - "/p2" is a merge of the preceding node and p2
215 - "/p2" is a merge of the preceding node and p2
216 - ":tag" defines a local tag for the preceding node
216 - ":tag" defines a local tag for the preceding node
217 - "@branch" sets the named branch for subsequent nodes
217 - "@branch" sets the named branch for subsequent nodes
218 - "#...\\n" is a comment up to the end of the line
218 - "#...\\n" is a comment up to the end of the line
219
219
220 Whitespace between the above elements is ignored.
220 Whitespace between the above elements is ignored.
221
221
222 A backref is either
222 A backref is either
223
223
224 - a number n, which references the node curr-n, where curr is the current
224 - a number n, which references the node curr-n, where curr is the current
225 node, or
225 node, or
226 - the name of a local tag you placed earlier using ":tag", or
226 - the name of a local tag you placed earlier using ":tag", or
227 - empty to denote the default parent.
227 - empty to denote the default parent.
228
228
229 All string valued-elements are either strictly alphanumeric, or must
229 All string valued-elements are either strictly alphanumeric, or must
230 be enclosed in double quotes ("..."), with "\\" as escape character.
230 be enclosed in double quotes ("..."), with "\\" as escape character.
231 """
231 """
232
232
233 if text is None:
233 if text is None:
234 ui.status(_(b"reading DAG from stdin\n"))
234 ui.status(_(b"reading DAG from stdin\n"))
235 text = ui.fin.read()
235 text = ui.fin.read()
236
236
237 cl = repo.changelog
237 cl = repo.changelog
238 if len(cl) > 0 and not from_existing:
238 if len(cl) > 0 and not from_existing:
239 raise error.Abort(_(b'repository is not empty'))
239 raise error.Abort(_(b'repository is not empty'))
240
240
241 # determine number of revs in DAG
241 # determine number of revs in DAG
242 total = 0
242 total = 0
243 for type, data in dagparser.parsedag(text):
243 for type, data in dagparser.parsedag(text):
244 if type == b'n':
244 if type == b'n':
245 total += 1
245 total += 1
246
246
247 if mergeable_file:
247 if mergeable_file:
248 linesperrev = 2
248 linesperrev = 2
249 # make a file with k lines per rev
249 # make a file with k lines per rev
250 initialmergedlines = [
250 initialmergedlines = [
251 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
251 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
252 ]
252 ]
253 initialmergedlines.append(b"")
253 initialmergedlines.append(b"")
254
254
255 tags = []
255 tags = []
256 progress = ui.makeprogress(
256 progress = ui.makeprogress(
257 _(b'building'), unit=_(b'revisions'), total=total
257 _(b'building'), unit=_(b'revisions'), total=total
258 )
258 )
259 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
259 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
260 at = -1
260 at = -1
261 atbranch = b'default'
261 atbranch = b'default'
262 nodeids = []
262 nodeids = []
263 id = 0
263 id = 0
264 progress.update(id)
264 progress.update(id)
265 for type, data in dagparser.parsedag(text):
265 for type, data in dagparser.parsedag(text):
266 if type == b'n':
266 if type == b'n':
267 ui.note((b'node %s\n' % pycompat.bytestr(data)))
267 ui.note((b'node %s\n' % pycompat.bytestr(data)))
268 id, ps = data
268 id, ps = data
269
269
270 files = []
270 files = []
271 filecontent = {}
271 filecontent = {}
272
272
273 p2 = None
273 p2 = None
274 if mergeable_file:
274 if mergeable_file:
275 fn = b"mf"
275 fn = b"mf"
276 p1 = repo[ps[0]]
276 p1 = repo[ps[0]]
277 if len(ps) > 1:
277 if len(ps) > 1:
278 p2 = repo[ps[1]]
278 p2 = repo[ps[1]]
279 pa = p1.ancestor(p2)
279 pa = p1.ancestor(p2)
280 base, local, other = [
280 base, local, other = [
281 x[fn].data() for x in (pa, p1, p2)
281 x[fn].data() for x in (pa, p1, p2)
282 ]
282 ]
283 m3 = simplemerge.Merge3Text(base, local, other)
283 m3 = simplemerge.Merge3Text(base, local, other)
284 ml = [
284 ml = [
285 l.strip()
285 l.strip()
286 for l in simplemerge.render_minimized(m3)[0]
286 for l in simplemerge.render_minimized(m3)[0]
287 ]
287 ]
288 ml.append(b"")
288 ml.append(b"")
289 elif at > 0:
289 elif at > 0:
290 ml = p1[fn].data().split(b"\n")
290 ml = p1[fn].data().split(b"\n")
291 else:
291 else:
292 ml = initialmergedlines
292 ml = initialmergedlines
293 ml[id * linesperrev] += b" r%i" % id
293 ml[id * linesperrev] += b" r%i" % id
294 mergedtext = b"\n".join(ml)
294 mergedtext = b"\n".join(ml)
295 files.append(fn)
295 files.append(fn)
296 filecontent[fn] = mergedtext
296 filecontent[fn] = mergedtext
297
297
298 if overwritten_file:
298 if overwritten_file:
299 fn = b"of"
299 fn = b"of"
300 files.append(fn)
300 files.append(fn)
301 filecontent[fn] = b"r%i\n" % id
301 filecontent[fn] = b"r%i\n" % id
302
302
303 if new_file:
303 if new_file:
304 fn = b"nf%i" % id
304 fn = b"nf%i" % id
305 files.append(fn)
305 files.append(fn)
306 filecontent[fn] = b"r%i\n" % id
306 filecontent[fn] = b"r%i\n" % id
307 if len(ps) > 1:
307 if len(ps) > 1:
308 if not p2:
308 if not p2:
309 p2 = repo[ps[1]]
309 p2 = repo[ps[1]]
310 for fn in p2:
310 for fn in p2:
311 if fn.startswith(b"nf"):
311 if fn.startswith(b"nf"):
312 files.append(fn)
312 files.append(fn)
313 filecontent[fn] = p2[fn].data()
313 filecontent[fn] = p2[fn].data()
314
314
315 def fctxfn(repo, cx, path):
315 def fctxfn(repo, cx, path):
316 if path in filecontent:
316 if path in filecontent:
317 return context.memfilectx(
317 return context.memfilectx(
318 repo, cx, path, filecontent[path]
318 repo, cx, path, filecontent[path]
319 )
319 )
320 return None
320 return None
321
321
322 if len(ps) == 0 or ps[0] < 0:
322 if len(ps) == 0 or ps[0] < 0:
323 pars = [None, None]
323 pars = [None, None]
324 elif len(ps) == 1:
324 elif len(ps) == 1:
325 pars = [nodeids[ps[0]], None]
325 pars = [nodeids[ps[0]], None]
326 else:
326 else:
327 pars = [nodeids[p] for p in ps]
327 pars = [nodeids[p] for p in ps]
328 cx = context.memctx(
328 cx = context.memctx(
329 repo,
329 repo,
330 pars,
330 pars,
331 b"r%i" % id,
331 b"r%i" % id,
332 files,
332 files,
333 fctxfn,
333 fctxfn,
334 date=(id, 0),
334 date=(id, 0),
335 user=b"debugbuilddag",
335 user=b"debugbuilddag",
336 extra={b'branch': atbranch},
336 extra={b'branch': atbranch},
337 )
337 )
338 nodeid = repo.commitctx(cx)
338 nodeid = repo.commitctx(cx)
339 nodeids.append(nodeid)
339 nodeids.append(nodeid)
340 at = id
340 at = id
341 elif type == b'l':
341 elif type == b'l':
342 id, name = data
342 id, name = data
343 ui.note((b'tag %s\n' % name))
343 ui.note((b'tag %s\n' % name))
344 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
344 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
345 elif type == b'a':
345 elif type == b'a':
346 ui.note((b'branch %s\n' % data))
346 ui.note((b'branch %s\n' % data))
347 atbranch = data
347 atbranch = data
348 progress.update(id)
348 progress.update(id)
349
349
350 if tags:
350 if tags:
351 repo.vfs.write(b"localtags", b"".join(tags))
351 repo.vfs.write(b"localtags", b"".join(tags))
352
352
353
353
354 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
354 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
355 indent_string = b' ' * indent
355 indent_string = b' ' * indent
356 if all:
356 if all:
357 ui.writenoi18n(
357 ui.writenoi18n(
358 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
358 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
359 % indent_string
359 % indent_string
360 )
360 )
361
361
362 def showchunks(named):
362 def showchunks(named):
363 ui.write(b"\n%s%s\n" % (indent_string, named))
363 ui.write(b"\n%s%s\n" % (indent_string, named))
364 for deltadata in gen.deltaiter():
364 for deltadata in gen.deltaiter():
365 node, p1, p2, cs, deltabase, delta, flags, sidedata = deltadata
365 node, p1, p2, cs, deltabase, delta, flags, sidedata = deltadata
366 ui.write(
366 ui.write(
367 b"%s%s %s %s %s %s %d\n"
367 b"%s%s %s %s %s %s %d\n"
368 % (
368 % (
369 indent_string,
369 indent_string,
370 hex(node),
370 hex(node),
371 hex(p1),
371 hex(p1),
372 hex(p2),
372 hex(p2),
373 hex(cs),
373 hex(cs),
374 hex(deltabase),
374 hex(deltabase),
375 len(delta),
375 len(delta),
376 )
376 )
377 )
377 )
378
378
379 gen.changelogheader()
379 gen.changelogheader()
380 showchunks(b"changelog")
380 showchunks(b"changelog")
381 gen.manifestheader()
381 gen.manifestheader()
382 showchunks(b"manifest")
382 showchunks(b"manifest")
383 for chunkdata in iter(gen.filelogheader, {}):
383 for chunkdata in iter(gen.filelogheader, {}):
384 fname = chunkdata[b'filename']
384 fname = chunkdata[b'filename']
385 showchunks(fname)
385 showchunks(fname)
386 else:
386 else:
387 if isinstance(gen, bundle2.unbundle20):
387 if isinstance(gen, bundle2.unbundle20):
388 raise error.Abort(_(b'use debugbundle2 for this file'))
388 raise error.Abort(_(b'use debugbundle2 for this file'))
389 gen.changelogheader()
389 gen.changelogheader()
390 for deltadata in gen.deltaiter():
390 for deltadata in gen.deltaiter():
391 node, p1, p2, cs, deltabase, delta, flags, sidedata = deltadata
391 node, p1, p2, cs, deltabase, delta, flags, sidedata = deltadata
392 ui.write(b"%s%s\n" % (indent_string, hex(node)))
392 ui.write(b"%s%s\n" % (indent_string, hex(node)))
393
393
394
394
395 def _debugobsmarkers(ui, part, indent=0, **opts):
395 def _debugobsmarkers(ui, part, indent=0, **opts):
396 """display version and markers contained in 'data'"""
396 """display version and markers contained in 'data'"""
397 opts = pycompat.byteskwargs(opts)
397 opts = pycompat.byteskwargs(opts)
398 data = part.read()
398 data = part.read()
399 indent_string = b' ' * indent
399 indent_string = b' ' * indent
400 try:
400 try:
401 version, markers = obsolete._readmarkers(data)
401 version, markers = obsolete._readmarkers(data)
402 except error.UnknownVersion as exc:
402 except error.UnknownVersion as exc:
403 msg = b"%sunsupported version: %s (%d bytes)\n"
403 msg = b"%sunsupported version: %s (%d bytes)\n"
404 msg %= indent_string, exc.version, len(data)
404 msg %= indent_string, exc.version, len(data)
405 ui.write(msg)
405 ui.write(msg)
406 else:
406 else:
407 msg = b"%sversion: %d (%d bytes)\n"
407 msg = b"%sversion: %d (%d bytes)\n"
408 msg %= indent_string, version, len(data)
408 msg %= indent_string, version, len(data)
409 ui.write(msg)
409 ui.write(msg)
410 fm = ui.formatter(b'debugobsolete', opts)
410 fm = ui.formatter(b'debugobsolete', opts)
411 for rawmarker in sorted(markers):
411 for rawmarker in sorted(markers):
412 m = obsutil.marker(None, rawmarker)
412 m = obsutil.marker(None, rawmarker)
413 fm.startitem()
413 fm.startitem()
414 fm.plain(indent_string)
414 fm.plain(indent_string)
415 cmdutil.showmarker(fm, m)
415 cmdutil.showmarker(fm, m)
416 fm.end()
416 fm.end()
417
417
418
418
419 def _debugphaseheads(ui, data, indent=0):
419 def _debugphaseheads(ui, data, indent=0):
420 """display version and markers contained in 'data'"""
420 """display version and markers contained in 'data'"""
421 indent_string = b' ' * indent
421 indent_string = b' ' * indent
422 headsbyphase = phases.binarydecode(data)
422 headsbyphase = phases.binarydecode(data)
423 for phase in phases.allphases:
423 for phase in phases.allphases:
424 for head in headsbyphase[phase]:
424 for head in headsbyphase[phase]:
425 ui.write(indent_string)
425 ui.write(indent_string)
426 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
426 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
427
427
428
428
429 def _quasirepr(thing):
429 def _quasirepr(thing):
430 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
430 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
431 return b'{%s}' % (
431 return b'{%s}' % (
432 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
432 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
433 )
433 )
434 return pycompat.bytestr(repr(thing))
434 return pycompat.bytestr(repr(thing))
435
435
436
436
437 def _debugbundle2(ui, gen, all=None, **opts):
437 def _debugbundle2(ui, gen, all=None, **opts):
438 """lists the contents of a bundle2"""
438 """lists the contents of a bundle2"""
439 if not isinstance(gen, bundle2.unbundle20):
439 if not isinstance(gen, bundle2.unbundle20):
440 raise error.Abort(_(b'not a bundle2 file'))
440 raise error.Abort(_(b'not a bundle2 file'))
441 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
441 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
442 parttypes = opts.get('part_type', [])
442 parttypes = opts.get('part_type', [])
443 for part in gen.iterparts():
443 for part in gen.iterparts():
444 if parttypes and part.type not in parttypes:
444 if parttypes and part.type not in parttypes:
445 continue
445 continue
446 msg = b'%s -- %s (mandatory: %r)\n'
446 msg = b'%s -- %s (mandatory: %r)\n'
447 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
447 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
448 if part.type == b'changegroup':
448 if part.type == b'changegroup':
449 version = part.params.get(b'version', b'01')
449 version = part.params.get(b'version', b'01')
450 cg = changegroup.getunbundler(version, part, b'UN')
450 cg = changegroup.getunbundler(version, part, b'UN')
451 if not ui.quiet:
451 if not ui.quiet:
452 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
452 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
453 if part.type == b'obsmarkers':
453 if part.type == b'obsmarkers':
454 if not ui.quiet:
454 if not ui.quiet:
455 _debugobsmarkers(ui, part, indent=4, **opts)
455 _debugobsmarkers(ui, part, indent=4, **opts)
456 if part.type == b'phase-heads':
456 if part.type == b'phase-heads':
457 if not ui.quiet:
457 if not ui.quiet:
458 _debugphaseheads(ui, part, indent=4)
458 _debugphaseheads(ui, part, indent=4)
459
459
460
460
461 @command(
461 @command(
462 b'debugbundle',
462 b'debugbundle',
463 [
463 [
464 (b'a', b'all', None, _(b'show all details')),
464 (b'a', b'all', None, _(b'show all details')),
465 (b'', b'part-type', [], _(b'show only the named part type')),
465 (b'', b'part-type', [], _(b'show only the named part type')),
466 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
466 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
467 ],
467 ],
468 _(b'FILE'),
468 _(b'FILE'),
469 norepo=True,
469 norepo=True,
470 )
470 )
471 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
471 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
472 """lists the contents of a bundle"""
472 """lists the contents of a bundle"""
473 with hg.openpath(ui, bundlepath) as f:
473 with hg.openpath(ui, bundlepath) as f:
474 if spec:
474 if spec:
475 spec = exchange.getbundlespec(ui, f)
475 spec = exchange.getbundlespec(ui, f)
476 ui.write(b'%s\n' % spec)
476 ui.write(b'%s\n' % spec)
477 return
477 return
478
478
479 gen = exchange.readbundle(ui, f, bundlepath)
479 gen = exchange.readbundle(ui, f, bundlepath)
480 if isinstance(gen, bundle2.unbundle20):
480 if isinstance(gen, bundle2.unbundle20):
481 return _debugbundle2(ui, gen, all=all, **opts)
481 return _debugbundle2(ui, gen, all=all, **opts)
482 _debugchangegroup(ui, gen, all=all, **opts)
482 _debugchangegroup(ui, gen, all=all, **opts)
483
483
484
484
485 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
485 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
486 def debugcapabilities(ui, path, **opts):
486 def debugcapabilities(ui, path, **opts):
487 """lists the capabilities of a remote peer"""
487 """lists the capabilities of a remote peer"""
488 opts = pycompat.byteskwargs(opts)
488 opts = pycompat.byteskwargs(opts)
489 peer = hg.peer(ui, opts, path)
489 peer = hg.peer(ui, opts, path)
490 try:
490 try:
491 caps = peer.capabilities()
491 caps = peer.capabilities()
492 ui.writenoi18n(b'Main capabilities:\n')
492 ui.writenoi18n(b'Main capabilities:\n')
493 for c in sorted(caps):
493 for c in sorted(caps):
494 ui.write(b' %s\n' % c)
494 ui.write(b' %s\n' % c)
495 b2caps = bundle2.bundle2caps(peer)
495 b2caps = bundle2.bundle2caps(peer)
496 if b2caps:
496 if b2caps:
497 ui.writenoi18n(b'Bundle2 capabilities:\n')
497 ui.writenoi18n(b'Bundle2 capabilities:\n')
498 for key, values in sorted(b2caps.items()):
498 for key, values in sorted(b2caps.items()):
499 ui.write(b' %s\n' % key)
499 ui.write(b' %s\n' % key)
500 for v in values:
500 for v in values:
501 ui.write(b' %s\n' % v)
501 ui.write(b' %s\n' % v)
502 finally:
502 finally:
503 peer.close()
503 peer.close()
504
504
505
505
506 @command(
506 @command(
507 b'debugchangedfiles',
507 b'debugchangedfiles',
508 [
508 [
509 (
509 (
510 b'',
510 b'',
511 b'compute',
511 b'compute',
512 False,
512 False,
513 b"compute information instead of reading it from storage",
513 b"compute information instead of reading it from storage",
514 ),
514 ),
515 ],
515 ],
516 b'REV',
516 b'REV',
517 )
517 )
518 def debugchangedfiles(ui, repo, rev, **opts):
518 def debugchangedfiles(ui, repo, rev, **opts):
519 """list the stored files changes for a revision"""
519 """list the stored files changes for a revision"""
520 ctx = logcmdutil.revsingle(repo, rev, None)
520 ctx = logcmdutil.revsingle(repo, rev, None)
521 files = None
521 files = None
522
522
523 if opts['compute']:
523 if opts['compute']:
524 files = metadata.compute_all_files_changes(ctx)
524 files = metadata.compute_all_files_changes(ctx)
525 else:
525 else:
526 sd = repo.changelog.sidedata(ctx.rev())
526 sd = repo.changelog.sidedata(ctx.rev())
527 files_block = sd.get(sidedata.SD_FILES)
527 files_block = sd.get(sidedata.SD_FILES)
528 if files_block is not None:
528 if files_block is not None:
529 files = metadata.decode_files_sidedata(sd)
529 files = metadata.decode_files_sidedata(sd)
530 if files is not None:
530 if files is not None:
531 for f in sorted(files.touched):
531 for f in sorted(files.touched):
532 if f in files.added:
532 if f in files.added:
533 action = b"added"
533 action = b"added"
534 elif f in files.removed:
534 elif f in files.removed:
535 action = b"removed"
535 action = b"removed"
536 elif f in files.merged:
536 elif f in files.merged:
537 action = b"merged"
537 action = b"merged"
538 elif f in files.salvaged:
538 elif f in files.salvaged:
539 action = b"salvaged"
539 action = b"salvaged"
540 else:
540 else:
541 action = b"touched"
541 action = b"touched"
542
542
543 copy_parent = b""
543 copy_parent = b""
544 copy_source = b""
544 copy_source = b""
545 if f in files.copied_from_p1:
545 if f in files.copied_from_p1:
546 copy_parent = b"p1"
546 copy_parent = b"p1"
547 copy_source = files.copied_from_p1[f]
547 copy_source = files.copied_from_p1[f]
548 elif f in files.copied_from_p2:
548 elif f in files.copied_from_p2:
549 copy_parent = b"p2"
549 copy_parent = b"p2"
550 copy_source = files.copied_from_p2[f]
550 copy_source = files.copied_from_p2[f]
551
551
552 data = (action, copy_parent, f, copy_source)
552 data = (action, copy_parent, f, copy_source)
553 template = b"%-8s %2s: %s, %s;\n"
553 template = b"%-8s %2s: %s, %s;\n"
554 ui.write(template % data)
554 ui.write(template % data)
555
555
556
556
557 @command(b'debugcheckstate', [], b'')
557 @command(b'debugcheckstate', [], b'')
558 def debugcheckstate(ui, repo):
558 def debugcheckstate(ui, repo):
559 """validate the correctness of the current dirstate"""
559 """validate the correctness of the current dirstate"""
560 parent1, parent2 = repo.dirstate.parents()
560 parent1, parent2 = repo.dirstate.parents()
561 m1 = repo[parent1].manifest()
561 m1 = repo[parent1].manifest()
562 m2 = repo[parent2].manifest()
562 m2 = repo[parent2].manifest()
563 errors = 0
563 errors = 0
564 for err in repo.dirstate.verify(m1, m2):
564 for err in repo.dirstate.verify(m1, m2):
565 ui.warn(err[0] % err[1:])
565 ui.warn(err[0] % err[1:])
566 errors += 1
566 errors += 1
567 if errors:
567 if errors:
568 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
568 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
569 raise error.Abort(errstr)
569 raise error.Abort(errstr)
570
570
571
571
572 @command(
572 @command(
573 b'debugcolor',
573 b'debugcolor',
574 [(b'', b'style', None, _(b'show all configured styles'))],
574 [(b'', b'style', None, _(b'show all configured styles'))],
575 b'hg debugcolor',
575 b'hg debugcolor',
576 )
576 )
577 def debugcolor(ui, repo, **opts):
577 def debugcolor(ui, repo, **opts):
578 """show available color, effects or style"""
578 """show available color, effects or style"""
579 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
579 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
580 if opts.get('style'):
580 if opts.get('style'):
581 return _debugdisplaystyle(ui)
581 return _debugdisplaystyle(ui)
582 else:
582 else:
583 return _debugdisplaycolor(ui)
583 return _debugdisplaycolor(ui)
584
584
585
585
586 def _debugdisplaycolor(ui):
586 def _debugdisplaycolor(ui):
587 ui = ui.copy()
587 ui = ui.copy()
588 ui._styles.clear()
588 ui._styles.clear()
589 for effect in color._activeeffects(ui).keys():
589 for effect in color._activeeffects(ui).keys():
590 ui._styles[effect] = effect
590 ui._styles[effect] = effect
591 if ui._terminfoparams:
591 if ui._terminfoparams:
592 for k, v in ui.configitems(b'color'):
592 for k, v in ui.configitems(b'color'):
593 if k.startswith(b'color.'):
593 if k.startswith(b'color.'):
594 ui._styles[k] = k[6:]
594 ui._styles[k] = k[6:]
595 elif k.startswith(b'terminfo.'):
595 elif k.startswith(b'terminfo.'):
596 ui._styles[k] = k[9:]
596 ui._styles[k] = k[9:]
597 ui.write(_(b'available colors:\n'))
597 ui.write(_(b'available colors:\n'))
598 # sort label with a '_' after the other to group '_background' entry.
598 # sort label with a '_' after the other to group '_background' entry.
599 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
599 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
600 for colorname, label in items:
600 for colorname, label in items:
601 ui.write(b'%s\n' % colorname, label=label)
601 ui.write(b'%s\n' % colorname, label=label)
602
602
603
603
604 def _debugdisplaystyle(ui):
604 def _debugdisplaystyle(ui):
605 ui.write(_(b'available style:\n'))
605 ui.write(_(b'available style:\n'))
606 if not ui._styles:
606 if not ui._styles:
607 return
607 return
608 width = max(len(s) for s in ui._styles)
608 width = max(len(s) for s in ui._styles)
609 for label, effects in sorted(ui._styles.items()):
609 for label, effects in sorted(ui._styles.items()):
610 ui.write(b'%s' % label, label=label)
610 ui.write(b'%s' % label, label=label)
611 if effects:
611 if effects:
612 # 50
612 # 50
613 ui.write(b': ')
613 ui.write(b': ')
614 ui.write(b' ' * (max(0, width - len(label))))
614 ui.write(b' ' * (max(0, width - len(label))))
615 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
615 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
616 ui.write(b'\n')
616 ui.write(b'\n')
617
617
618
618
619 @command(b'debugcreatestreamclonebundle', [], b'FILE')
619 @command(b'debugcreatestreamclonebundle', [], b'FILE')
620 def debugcreatestreamclonebundle(ui, repo, fname):
620 def debugcreatestreamclonebundle(ui, repo, fname):
621 """create a stream clone bundle file
621 """create a stream clone bundle file
622
622
623 Stream bundles are special bundles that are essentially archives of
623 Stream bundles are special bundles that are essentially archives of
624 revlog files. They are commonly used for cloning very quickly.
624 revlog files. They are commonly used for cloning very quickly.
625 """
625 """
626 # TODO we may want to turn this into an abort when this functionality
626 # TODO we may want to turn this into an abort when this functionality
627 # is moved into `hg bundle`.
627 # is moved into `hg bundle`.
628 if phases.hassecret(repo):
628 if phases.hassecret(repo):
629 ui.warn(
629 ui.warn(
630 _(
630 _(
631 b'(warning: stream clone bundle will contain secret '
631 b'(warning: stream clone bundle will contain secret '
632 b'revisions)\n'
632 b'revisions)\n'
633 )
633 )
634 )
634 )
635
635
636 requirements, gen = streamclone.generatebundlev1(repo)
636 requirements, gen = streamclone.generatebundlev1(repo)
637 changegroup.writechunks(ui, gen, fname)
637 changegroup.writechunks(ui, gen, fname)
638
638
639 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
639 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
640
640
641
641
642 @command(
642 @command(
643 b'debugdag',
643 b'debugdag',
644 [
644 [
645 (b't', b'tags', None, _(b'use tags as labels')),
645 (b't', b'tags', None, _(b'use tags as labels')),
646 (b'b', b'branches', None, _(b'annotate with branch names')),
646 (b'b', b'branches', None, _(b'annotate with branch names')),
647 (b'', b'dots', None, _(b'use dots for runs')),
647 (b'', b'dots', None, _(b'use dots for runs')),
648 (b's', b'spaces', None, _(b'separate elements by spaces')),
648 (b's', b'spaces', None, _(b'separate elements by spaces')),
649 ],
649 ],
650 _(b'[OPTION]... [FILE [REV]...]'),
650 _(b'[OPTION]... [FILE [REV]...]'),
651 optionalrepo=True,
651 optionalrepo=True,
652 )
652 )
653 def debugdag(ui, repo, file_=None, *revs, **opts):
653 def debugdag(ui, repo, file_=None, *revs, **opts):
654 """format the changelog or an index DAG as a concise textual description
654 """format the changelog or an index DAG as a concise textual description
655
655
656 If you pass a revlog index, the revlog's DAG is emitted. If you list
656 If you pass a revlog index, the revlog's DAG is emitted. If you list
657 revision numbers, they get labeled in the output as rN.
657 revision numbers, they get labeled in the output as rN.
658
658
659 Otherwise, the changelog DAG of the current repo is emitted.
659 Otherwise, the changelog DAG of the current repo is emitted.
660 """
660 """
661 spaces = opts.get('spaces')
661 spaces = opts.get('spaces')
662 dots = opts.get('dots')
662 dots = opts.get('dots')
663 if file_:
663 if file_:
664 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
664 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
665 revs = {int(r) for r in revs}
665 revs = {int(r) for r in revs}
666
666
667 def events():
667 def events():
668 for r in rlog:
668 for r in rlog:
669 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
669 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
670 if r in revs:
670 if r in revs:
671 yield b'l', (r, b"r%i" % r)
671 yield b'l', (r, b"r%i" % r)
672
672
673 elif repo:
673 elif repo:
674 cl = repo.changelog
674 cl = repo.changelog
675 tags = opts.get('tags')
675 tags = opts.get('tags')
676 branches = opts.get('branches')
676 branches = opts.get('branches')
677 if tags:
677 if tags:
678 labels = {}
678 labels = {}
679 for l, n in repo.tags().items():
679 for l, n in repo.tags().items():
680 labels.setdefault(cl.rev(n), []).append(l)
680 labels.setdefault(cl.rev(n), []).append(l)
681
681
682 def events():
682 def events():
683 b = b"default"
683 b = b"default"
684 for r in cl:
684 for r in cl:
685 if branches:
685 if branches:
686 newb = cl.read(cl.node(r))[5][b'branch']
686 newb = cl.read(cl.node(r))[5][b'branch']
687 if newb != b:
687 if newb != b:
688 yield b'a', newb
688 yield b'a', newb
689 b = newb
689 b = newb
690 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
690 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
691 if tags:
691 if tags:
692 ls = labels.get(r)
692 ls = labels.get(r)
693 if ls:
693 if ls:
694 for l in ls:
694 for l in ls:
695 yield b'l', (r, l)
695 yield b'l', (r, l)
696
696
697 else:
697 else:
698 raise error.Abort(_(b'need repo for changelog dag'))
698 raise error.Abort(_(b'need repo for changelog dag'))
699
699
700 for line in dagparser.dagtextlines(
700 for line in dagparser.dagtextlines(
701 events(),
701 events(),
702 addspaces=spaces,
702 addspaces=spaces,
703 wraplabels=True,
703 wraplabels=True,
704 wrapannotations=True,
704 wrapannotations=True,
705 wrapnonlinear=dots,
705 wrapnonlinear=dots,
706 usedots=dots,
706 usedots=dots,
707 maxlinewidth=70,
707 maxlinewidth=70,
708 ):
708 ):
709 ui.write(line)
709 ui.write(line)
710 ui.write(b"\n")
710 ui.write(b"\n")
711
711
712
712
713 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
713 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
714 def debugdata(ui, repo, file_, rev=None, **opts):
714 def debugdata(ui, repo, file_, rev=None, **opts):
715 """dump the contents of a data file revision"""
715 """dump the contents of a data file revision"""
716 opts = pycompat.byteskwargs(opts)
716 opts = pycompat.byteskwargs(opts)
717 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
717 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
718 if rev is not None:
718 if rev is not None:
719 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
719 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
720 file_, rev = None, file_
720 file_, rev = None, file_
721 elif rev is None:
721 elif rev is None:
722 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
722 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
723 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
723 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
724 try:
724 try:
725 ui.write(r.rawdata(r.lookup(rev)))
725 ui.write(r.rawdata(r.lookup(rev)))
726 except KeyError:
726 except KeyError:
727 raise error.Abort(_(b'invalid revision identifier %s') % rev)
727 raise error.Abort(_(b'invalid revision identifier %s') % rev)
728
728
729
729
730 @command(
730 @command(
731 b'debugdate',
731 b'debugdate',
732 [(b'e', b'extended', None, _(b'try extended date formats'))],
732 [(b'e', b'extended', None, _(b'try extended date formats'))],
733 _(b'[-e] DATE [RANGE]'),
733 _(b'[-e] DATE [RANGE]'),
734 norepo=True,
734 norepo=True,
735 optionalrepo=True,
735 optionalrepo=True,
736 )
736 )
737 def debugdate(ui, date, range=None, **opts):
737 def debugdate(ui, date, range=None, **opts):
738 """parse and display a date"""
738 """parse and display a date"""
739 if opts["extended"]:
739 if opts["extended"]:
740 d = dateutil.parsedate(date, dateutil.extendeddateformats)
740 d = dateutil.parsedate(date, dateutil.extendeddateformats)
741 else:
741 else:
742 d = dateutil.parsedate(date)
742 d = dateutil.parsedate(date)
743 ui.writenoi18n(b"internal: %d %d\n" % d)
743 ui.writenoi18n(b"internal: %d %d\n" % d)
744 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
744 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
745 if range:
745 if range:
746 m = dateutil.matchdate(range)
746 m = dateutil.matchdate(range)
747 ui.writenoi18n(b"match: %s\n" % m(d[0]))
747 ui.writenoi18n(b"match: %s\n" % m(d[0]))
748
748
749
749
750 @command(
750 @command(
751 b'debugdeltachain',
751 b'debugdeltachain',
752 cmdutil.debugrevlogopts + cmdutil.formatteropts,
752 cmdutil.debugrevlogopts + cmdutil.formatteropts,
753 _(b'-c|-m|FILE'),
753 _(b'-c|-m|FILE'),
754 optionalrepo=True,
754 optionalrepo=True,
755 )
755 )
756 def debugdeltachain(ui, repo, file_=None, **opts):
756 def debugdeltachain(ui, repo, file_=None, **opts):
757 """dump information about delta chains in a revlog
757 """dump information about delta chains in a revlog
758
758
759 Output can be templatized. Available template keywords are:
759 Output can be templatized. Available template keywords are:
760
760
761 :``rev``: revision number
761 :``rev``: revision number
762 :``p1``: parent 1 revision number (for reference)
762 :``p1``: parent 1 revision number (for reference)
763 :``p2``: parent 2 revision number (for reference)
763 :``p2``: parent 2 revision number (for reference)
764 :``chainid``: delta chain identifier (numbered by unique base)
764 :``chainid``: delta chain identifier (numbered by unique base)
765 :``chainlen``: delta chain length to this revision
765 :``chainlen``: delta chain length to this revision
766 :``prevrev``: previous revision in delta chain
766 :``prevrev``: previous revision in delta chain
767 :``deltatype``: role of delta / how it was computed
767 :``deltatype``: role of delta / how it was computed
768 - base: a full snapshot
768 - base: a full snapshot
769 - snap: an intermediate snapshot
769 - snap: an intermediate snapshot
770 - p1: a delta against the first parent
770 - p1: a delta against the first parent
771 - p2: a delta against the second parent
771 - p2: a delta against the second parent
772 - skip1: a delta against the same base as p1
772 - skip1: a delta against the same base as p1
773 (when p1 has empty delta
773 (when p1 has empty delta
774 - skip2: a delta against the same base as p2
774 - skip2: a delta against the same base as p2
775 (when p2 has empty delta
775 (when p2 has empty delta
776 - prev: a delta against the previous revision
776 - prev: a delta against the previous revision
777 - other: a delta against an arbitrary revision
777 - other: a delta against an arbitrary revision
778 :``compsize``: compressed size of revision
778 :``compsize``: compressed size of revision
779 :``uncompsize``: uncompressed size of revision
779 :``uncompsize``: uncompressed size of revision
780 :``chainsize``: total size of compressed revisions in chain
780 :``chainsize``: total size of compressed revisions in chain
781 :``chainratio``: total chain size divided by uncompressed revision size
781 :``chainratio``: total chain size divided by uncompressed revision size
782 (new delta chains typically start at ratio 2.00)
782 (new delta chains typically start at ratio 2.00)
783 :``lindist``: linear distance from base revision in delta chain to end
783 :``lindist``: linear distance from base revision in delta chain to end
784 of this revision
784 of this revision
785 :``extradist``: total size of revisions not part of this delta chain from
785 :``extradist``: total size of revisions not part of this delta chain from
786 base of delta chain to end of this revision; a measurement
786 base of delta chain to end of this revision; a measurement
787 of how much extra data we need to read/seek across to read
787 of how much extra data we need to read/seek across to read
788 the delta chain for this revision
788 the delta chain for this revision
789 :``extraratio``: extradist divided by chainsize; another representation of
789 :``extraratio``: extradist divided by chainsize; another representation of
790 how much unrelated data is needed to load this delta chain
790 how much unrelated data is needed to load this delta chain
791
791
792 If the repository is configured to use the sparse read, additional keywords
792 If the repository is configured to use the sparse read, additional keywords
793 are available:
793 are available:
794
794
795 :``readsize``: total size of data read from the disk for a revision
795 :``readsize``: total size of data read from the disk for a revision
796 (sum of the sizes of all the blocks)
796 (sum of the sizes of all the blocks)
797 :``largestblock``: size of the largest block of data read from the disk
797 :``largestblock``: size of the largest block of data read from the disk
798 :``readdensity``: density of useful bytes in the data read from the disk
798 :``readdensity``: density of useful bytes in the data read from the disk
799 :``srchunks``: in how many data hunks the whole revision would be read
799 :``srchunks``: in how many data hunks the whole revision would be read
800
800
801 The sparse read can be enabled with experimental.sparse-read = True
801 The sparse read can be enabled with experimental.sparse-read = True
802 """
802 """
803 opts = pycompat.byteskwargs(opts)
803 opts = pycompat.byteskwargs(opts)
804 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
804 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
805 index = r.index
805 index = r.index
806 start = r.start
806 start = r.start
807 length = r.length
807 length = r.length
808 generaldelta = r._generaldelta
808 generaldelta = r._generaldelta
809 withsparseread = getattr(r, '_withsparseread', False)
809 withsparseread = getattr(r, '_withsparseread', False)
810
810
811 # security to avoid crash on corrupted revlogs
811 # security to avoid crash on corrupted revlogs
812 total_revs = len(index)
812 total_revs = len(index)
813
813
814 def revinfo(rev):
814 def revinfo(rev):
815 e = index[rev]
815 e = index[rev]
816 compsize = e[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH]
816 compsize = e[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH]
817 uncompsize = e[revlog_constants.ENTRY_DATA_UNCOMPRESSED_LENGTH]
817 uncompsize = e[revlog_constants.ENTRY_DATA_UNCOMPRESSED_LENGTH]
818 chainsize = 0
818 chainsize = 0
819
819
820 base = e[revlog_constants.ENTRY_DELTA_BASE]
820 base = e[revlog_constants.ENTRY_DELTA_BASE]
821 p1 = e[revlog_constants.ENTRY_PARENT_1]
821 p1 = e[revlog_constants.ENTRY_PARENT_1]
822 p2 = e[revlog_constants.ENTRY_PARENT_2]
822 p2 = e[revlog_constants.ENTRY_PARENT_2]
823
823
824 # If the parents of a revision has an empty delta, we never try to delta
824 # If the parents of a revision has an empty delta, we never try to delta
825 # against that parent, but directly against the delta base of that
825 # against that parent, but directly against the delta base of that
826 # parent (recursively). It avoids adding a useless entry in the chain.
826 # parent (recursively). It avoids adding a useless entry in the chain.
827 #
827 #
828 # However we need to detect that as a special case for delta-type, that
828 # However we need to detect that as a special case for delta-type, that
829 # is not simply "other".
829 # is not simply "other".
830 p1_base = p1
830 p1_base = p1
831 if p1 != nullrev and p1 < total_revs:
831 if p1 != nullrev and p1 < total_revs:
832 e1 = index[p1]
832 e1 = index[p1]
833 while e1[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0:
833 while e1[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0:
834 new_base = e1[revlog_constants.ENTRY_DELTA_BASE]
834 new_base = e1[revlog_constants.ENTRY_DELTA_BASE]
835 if (
835 if (
836 new_base == p1_base
836 new_base == p1_base
837 or new_base == nullrev
837 or new_base == nullrev
838 or new_base >= total_revs
838 or new_base >= total_revs
839 ):
839 ):
840 break
840 break
841 p1_base = new_base
841 p1_base = new_base
842 e1 = index[p1_base]
842 e1 = index[p1_base]
843 p2_base = p2
843 p2_base = p2
844 if p2 != nullrev and p2 < total_revs:
844 if p2 != nullrev and p2 < total_revs:
845 e2 = index[p2]
845 e2 = index[p2]
846 while e2[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0:
846 while e2[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0:
847 new_base = e2[revlog_constants.ENTRY_DELTA_BASE]
847 new_base = e2[revlog_constants.ENTRY_DELTA_BASE]
848 if (
848 if (
849 new_base == p2_base
849 new_base == p2_base
850 or new_base == nullrev
850 or new_base == nullrev
851 or new_base >= total_revs
851 or new_base >= total_revs
852 ):
852 ):
853 break
853 break
854 p2_base = new_base
854 p2_base = new_base
855 e2 = index[p2_base]
855 e2 = index[p2_base]
856
856
857 if generaldelta:
857 if generaldelta:
858 if base == p1:
858 if base == p1:
859 deltatype = b'p1'
859 deltatype = b'p1'
860 elif base == p2:
860 elif base == p2:
861 deltatype = b'p2'
861 deltatype = b'p2'
862 elif base == rev:
862 elif base == rev:
863 deltatype = b'base'
863 deltatype = b'base'
864 elif base == p1_base:
864 elif base == p1_base:
865 deltatype = b'skip1'
865 deltatype = b'skip1'
866 elif base == p2_base:
866 elif base == p2_base:
867 deltatype = b'skip2'
867 deltatype = b'skip2'
868 elif r.issnapshot(rev):
868 elif r.issnapshot(rev):
869 deltatype = b'snap'
869 deltatype = b'snap'
870 elif base == rev - 1:
870 elif base == rev - 1:
871 deltatype = b'prev'
871 deltatype = b'prev'
872 else:
872 else:
873 deltatype = b'other'
873 deltatype = b'other'
874 else:
874 else:
875 if base == rev:
875 if base == rev:
876 deltatype = b'base'
876 deltatype = b'base'
877 else:
877 else:
878 deltatype = b'prev'
878 deltatype = b'prev'
879
879
880 chain = r._deltachain(rev)[0]
880 chain = r._deltachain(rev)[0]
881 for iterrev in chain:
881 for iterrev in chain:
882 e = index[iterrev]
882 e = index[iterrev]
883 chainsize += e[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH]
883 chainsize += e[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH]
884
884
885 return p1, p2, compsize, uncompsize, deltatype, chain, chainsize
885 return p1, p2, compsize, uncompsize, deltatype, chain, chainsize
886
886
887 fm = ui.formatter(b'debugdeltachain', opts)
887 fm = ui.formatter(b'debugdeltachain', opts)
888
888
889 fm.plain(
889 fm.plain(
890 b' rev p1 p2 chain# chainlen prev delta '
890 b' rev p1 p2 chain# chainlen prev delta '
891 b'size rawsize chainsize ratio lindist extradist '
891 b'size rawsize chainsize ratio lindist extradist '
892 b'extraratio'
892 b'extraratio'
893 )
893 )
894 if withsparseread:
894 if withsparseread:
895 fm.plain(b' readsize largestblk rddensity srchunks')
895 fm.plain(b' readsize largestblk rddensity srchunks')
896 fm.plain(b'\n')
896 fm.plain(b'\n')
897
897
898 chainbases = {}
898 chainbases = {}
899 for rev in r:
899 for rev in r:
900 p1, p2, comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
900 p1, p2, comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
901 chainbase = chain[0]
901 chainbase = chain[0]
902 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
902 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
903 basestart = start(chainbase)
903 basestart = start(chainbase)
904 revstart = start(rev)
904 revstart = start(rev)
905 lineardist = revstart + comp - basestart
905 lineardist = revstart + comp - basestart
906 extradist = lineardist - chainsize
906 extradist = lineardist - chainsize
907 try:
907 try:
908 prevrev = chain[-2]
908 prevrev = chain[-2]
909 except IndexError:
909 except IndexError:
910 prevrev = -1
910 prevrev = -1
911
911
912 if uncomp != 0:
912 if uncomp != 0:
913 chainratio = float(chainsize) / float(uncomp)
913 chainratio = float(chainsize) / float(uncomp)
914 else:
914 else:
915 chainratio = chainsize
915 chainratio = chainsize
916
916
917 if chainsize != 0:
917 if chainsize != 0:
918 extraratio = float(extradist) / float(chainsize)
918 extraratio = float(extradist) / float(chainsize)
919 else:
919 else:
920 extraratio = extradist
920 extraratio = extradist
921
921
922 fm.startitem()
922 fm.startitem()
923 fm.write(
923 fm.write(
924 b'rev p1 p2 chainid chainlen prevrev deltatype compsize '
924 b'rev p1 p2 chainid chainlen prevrev deltatype compsize '
925 b'uncompsize chainsize chainratio lindist extradist '
925 b'uncompsize chainsize chainratio lindist extradist '
926 b'extraratio',
926 b'extraratio',
927 b'%7d %7d %7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
927 b'%7d %7d %7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
928 rev,
928 rev,
929 p1,
929 p1,
930 p2,
930 p2,
931 chainid,
931 chainid,
932 len(chain),
932 len(chain),
933 prevrev,
933 prevrev,
934 deltatype,
934 deltatype,
935 comp,
935 comp,
936 uncomp,
936 uncomp,
937 chainsize,
937 chainsize,
938 chainratio,
938 chainratio,
939 lineardist,
939 lineardist,
940 extradist,
940 extradist,
941 extraratio,
941 extraratio,
942 rev=rev,
942 rev=rev,
943 chainid=chainid,
943 chainid=chainid,
944 chainlen=len(chain),
944 chainlen=len(chain),
945 prevrev=prevrev,
945 prevrev=prevrev,
946 deltatype=deltatype,
946 deltatype=deltatype,
947 compsize=comp,
947 compsize=comp,
948 uncompsize=uncomp,
948 uncompsize=uncomp,
949 chainsize=chainsize,
949 chainsize=chainsize,
950 chainratio=chainratio,
950 chainratio=chainratio,
951 lindist=lineardist,
951 lindist=lineardist,
952 extradist=extradist,
952 extradist=extradist,
953 extraratio=extraratio,
953 extraratio=extraratio,
954 )
954 )
955 if withsparseread:
955 if withsparseread:
956 readsize = 0
956 readsize = 0
957 largestblock = 0
957 largestblock = 0
958 srchunks = 0
958 srchunks = 0
959
959
960 for revschunk in deltautil.slicechunk(r, chain):
960 for revschunk in deltautil.slicechunk(r, chain):
961 srchunks += 1
961 srchunks += 1
962 blkend = start(revschunk[-1]) + length(revschunk[-1])
962 blkend = start(revschunk[-1]) + length(revschunk[-1])
963 blksize = blkend - start(revschunk[0])
963 blksize = blkend - start(revschunk[0])
964
964
965 readsize += blksize
965 readsize += blksize
966 if largestblock < blksize:
966 if largestblock < blksize:
967 largestblock = blksize
967 largestblock = blksize
968
968
969 if readsize:
969 if readsize:
970 readdensity = float(chainsize) / float(readsize)
970 readdensity = float(chainsize) / float(readsize)
971 else:
971 else:
972 readdensity = 1
972 readdensity = 1
973
973
974 fm.write(
974 fm.write(
975 b'readsize largestblock readdensity srchunks',
975 b'readsize largestblock readdensity srchunks',
976 b' %10d %10d %9.5f %8d',
976 b' %10d %10d %9.5f %8d',
977 readsize,
977 readsize,
978 largestblock,
978 largestblock,
979 readdensity,
979 readdensity,
980 srchunks,
980 srchunks,
981 readsize=readsize,
981 readsize=readsize,
982 largestblock=largestblock,
982 largestblock=largestblock,
983 readdensity=readdensity,
983 readdensity=readdensity,
984 srchunks=srchunks,
984 srchunks=srchunks,
985 )
985 )
986
986
987 fm.plain(b'\n')
987 fm.plain(b'\n')
988
988
989 fm.end()
989 fm.end()
990
990
991
991
992 @command(
992 @command(
993 b'debug-delta-find',
993 b'debug-delta-find',
994 cmdutil.debugrevlogopts + cmdutil.formatteropts,
994 cmdutil.debugrevlogopts + cmdutil.formatteropts,
995 _(b'-c|-m|FILE REV'),
995 _(b'-c|-m|FILE REV'),
996 optionalrepo=True,
996 optionalrepo=True,
997 )
997 )
998 def debugdeltafind(ui, repo, arg_1, arg_2=None, **opts):
998 def debugdeltafind(ui, repo, arg_1, arg_2=None, **opts):
999 """display the computation to get to a valid delta for storing REV
999 """display the computation to get to a valid delta for storing REV
1000
1000
1001 This command will replay the process used to find the "best" delta to store
1001 This command will replay the process used to find the "best" delta to store
1002 a revision and display information about all the steps used to get to that
1002 a revision and display information about all the steps used to get to that
1003 result.
1003 result.
1004
1004
1005 The revision use the revision number of the target storage (not changelog
1005 The revision use the revision number of the target storage (not changelog
1006 revision number).
1006 revision number).
1007
1007
1008 note: the process is initiated from a full text of the revision to store.
1008 note: the process is initiated from a full text of the revision to store.
1009 """
1009 """
1010 opts = pycompat.byteskwargs(opts)
1010 opts = pycompat.byteskwargs(opts)
1011 if arg_2 is None:
1011 if arg_2 is None:
1012 file_ = None
1012 file_ = None
1013 rev = arg_1
1013 rev = arg_1
1014 else:
1014 else:
1015 file_ = arg_1
1015 file_ = arg_1
1016 rev = arg_2
1016 rev = arg_2
1017
1017
1018 rev = int(rev)
1018 rev = int(rev)
1019
1019
1020 revlog = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
1020 revlog = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
1021
1021
1022 deltacomputer = deltautil.deltacomputer(
1022 deltacomputer = deltautil.deltacomputer(
1023 revlog,
1023 revlog,
1024 write_debug=ui.write,
1024 write_debug=ui.write,
1025 debug_search=True,
1025 debug_search=True,
1026 )
1026 )
1027
1027
1028 node = revlog.node(rev)
1028 node = revlog.node(rev)
1029 p1r, p2r = revlog.parentrevs(rev)
1029 p1r, p2r = revlog.parentrevs(rev)
1030 p1 = revlog.node(p1r)
1030 p1 = revlog.node(p1r)
1031 p2 = revlog.node(p2r)
1031 p2 = revlog.node(p2r)
1032 btext = [revlog.revision(rev)]
1032 btext = [revlog.revision(rev)]
1033 textlen = len(btext[0])
1033 textlen = len(btext[0])
1034 cachedelta = None
1034 cachedelta = None
1035 flags = revlog.flags(rev)
1035 flags = revlog.flags(rev)
1036
1036
1037 revinfo = revlogutils.revisioninfo(
1037 revinfo = revlogutils.revisioninfo(
1038 node,
1038 node,
1039 p1,
1039 p1,
1040 p2,
1040 p2,
1041 btext,
1041 btext,
1042 textlen,
1042 textlen,
1043 cachedelta,
1043 cachedelta,
1044 flags,
1044 flags,
1045 )
1045 )
1046
1046
1047 fh = revlog._datafp()
1047 fh = revlog._datafp()
1048 deltacomputer.finddeltainfo(revinfo, fh, target_rev=rev)
1048 deltacomputer.finddeltainfo(revinfo, fh, target_rev=rev)
1049
1049
1050
1050
1051 @command(
1051 @command(
1052 b'debugdirstate|debugstate',
1052 b'debugdirstate|debugstate',
1053 [
1053 [
1054 (
1054 (
1055 b'',
1055 b'',
1056 b'nodates',
1056 b'nodates',
1057 None,
1057 None,
1058 _(b'do not display the saved mtime (DEPRECATED)'),
1058 _(b'do not display the saved mtime (DEPRECATED)'),
1059 ),
1059 ),
1060 (b'', b'dates', True, _(b'display the saved mtime')),
1060 (b'', b'dates', True, _(b'display the saved mtime')),
1061 (b'', b'datesort', None, _(b'sort by saved mtime')),
1061 (b'', b'datesort', None, _(b'sort by saved mtime')),
1062 (
1062 (
1063 b'',
1063 b'',
1064 b'docket',
1064 b'docket',
1065 False,
1065 False,
1066 _(b'display the docket (metadata file) instead'),
1066 _(b'display the docket (metadata file) instead'),
1067 ),
1067 ),
1068 (
1068 (
1069 b'',
1069 b'',
1070 b'all',
1070 b'all',
1071 False,
1071 False,
1072 _(b'display dirstate-v2 tree nodes that would not exist in v1'),
1072 _(b'display dirstate-v2 tree nodes that would not exist in v1'),
1073 ),
1073 ),
1074 ],
1074 ],
1075 _(b'[OPTION]...'),
1075 _(b'[OPTION]...'),
1076 )
1076 )
1077 def debugstate(ui, repo, **opts):
1077 def debugstate(ui, repo, **opts):
1078 """show the contents of the current dirstate"""
1078 """show the contents of the current dirstate"""
1079
1079
1080 if opts.get("docket"):
1080 if opts.get("docket"):
1081 if not repo.dirstate._use_dirstate_v2:
1081 if not repo.dirstate._use_dirstate_v2:
1082 raise error.Abort(_(b'dirstate v1 does not have a docket'))
1082 raise error.Abort(_(b'dirstate v1 does not have a docket'))
1083
1083
1084 docket = repo.dirstate._map.docket
1084 docket = repo.dirstate._map.docket
1085 (
1085 (
1086 start_offset,
1086 start_offset,
1087 root_nodes,
1087 root_nodes,
1088 nodes_with_entry,
1088 nodes_with_entry,
1089 nodes_with_copy,
1089 nodes_with_copy,
1090 unused_bytes,
1090 unused_bytes,
1091 _unused,
1091 _unused,
1092 ignore_pattern,
1092 ignore_pattern,
1093 ) = dirstateutils.v2.TREE_METADATA.unpack(docket.tree_metadata)
1093 ) = dirstateutils.v2.TREE_METADATA.unpack(docket.tree_metadata)
1094
1094
1095 ui.write(_(b"size of dirstate data: %d\n") % docket.data_size)
1095 ui.write(_(b"size of dirstate data: %d\n") % docket.data_size)
1096 ui.write(_(b"data file uuid: %s\n") % docket.uuid)
1096 ui.write(_(b"data file uuid: %s\n") % docket.uuid)
1097 ui.write(_(b"start offset of root nodes: %d\n") % start_offset)
1097 ui.write(_(b"start offset of root nodes: %d\n") % start_offset)
1098 ui.write(_(b"number of root nodes: %d\n") % root_nodes)
1098 ui.write(_(b"number of root nodes: %d\n") % root_nodes)
1099 ui.write(_(b"nodes with entries: %d\n") % nodes_with_entry)
1099 ui.write(_(b"nodes with entries: %d\n") % nodes_with_entry)
1100 ui.write(_(b"nodes with copies: %d\n") % nodes_with_copy)
1100 ui.write(_(b"nodes with copies: %d\n") % nodes_with_copy)
1101 ui.write(_(b"number of unused bytes: %d\n") % unused_bytes)
1101 ui.write(_(b"number of unused bytes: %d\n") % unused_bytes)
1102 ui.write(
1102 ui.write(
1103 _(b"ignore pattern hash: %s\n") % binascii.hexlify(ignore_pattern)
1103 _(b"ignore pattern hash: %s\n") % binascii.hexlify(ignore_pattern)
1104 )
1104 )
1105 return
1105 return
1106
1106
1107 nodates = not opts['dates']
1107 nodates = not opts['dates']
1108 if opts.get('nodates') is not None:
1108 if opts.get('nodates') is not None:
1109 nodates = True
1109 nodates = True
1110 datesort = opts.get('datesort')
1110 datesort = opts.get('datesort')
1111
1111
1112 if datesort:
1112 if datesort:
1113
1113
1114 def keyfunc(entry):
1114 def keyfunc(entry):
1115 filename, _state, _mode, _size, mtime = entry
1115 filename, _state, _mode, _size, mtime = entry
1116 return (mtime, filename)
1116 return (mtime, filename)
1117
1117
1118 else:
1118 else:
1119 keyfunc = None # sort by filename
1119 keyfunc = None # sort by filename
1120 entries = list(repo.dirstate._map.debug_iter(all=opts['all']))
1120 entries = list(repo.dirstate._map.debug_iter(all=opts['all']))
1121 entries.sort(key=keyfunc)
1121 entries.sort(key=keyfunc)
1122 for entry in entries:
1122 for entry in entries:
1123 filename, state, mode, size, mtime = entry
1123 filename, state, mode, size, mtime = entry
1124 if mtime == -1:
1124 if mtime == -1:
1125 timestr = b'unset '
1125 timestr = b'unset '
1126 elif nodates:
1126 elif nodates:
1127 timestr = b'set '
1127 timestr = b'set '
1128 else:
1128 else:
1129 timestr = time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime(mtime))
1129 timestr = time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime(mtime))
1130 timestr = encoding.strtolocal(timestr)
1130 timestr = encoding.strtolocal(timestr)
1131 if mode & 0o20000:
1131 if mode & 0o20000:
1132 mode = b'lnk'
1132 mode = b'lnk'
1133 else:
1133 else:
1134 mode = b'%3o' % (mode & 0o777 & ~util.umask)
1134 mode = b'%3o' % (mode & 0o777 & ~util.umask)
1135 ui.write(b"%c %s %10d %s%s\n" % (state, mode, size, timestr, filename))
1135 ui.write(b"%c %s %10d %s%s\n" % (state, mode, size, timestr, filename))
1136 for f in repo.dirstate.copies():
1136 for f in repo.dirstate.copies():
1137 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1137 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1138
1138
1139
1139
1140 @command(
1140 @command(
1141 b'debugdirstateignorepatternshash',
1141 b'debugdirstateignorepatternshash',
1142 [],
1142 [],
1143 _(b''),
1143 _(b''),
1144 )
1144 )
1145 def debugdirstateignorepatternshash(ui, repo, **opts):
1145 def debugdirstateignorepatternshash(ui, repo, **opts):
1146 """show the hash of ignore patterns stored in dirstate if v2,
1146 """show the hash of ignore patterns stored in dirstate if v2,
1147 or nothing for dirstate-v2
1147 or nothing for dirstate-v2
1148 """
1148 """
1149 if repo.dirstate._use_dirstate_v2:
1149 if repo.dirstate._use_dirstate_v2:
1150 docket = repo.dirstate._map.docket
1150 docket = repo.dirstate._map.docket
1151 hash_len = 20 # 160 bits for SHA-1
1151 hash_len = 20 # 160 bits for SHA-1
1152 hash_bytes = docket.tree_metadata[-hash_len:]
1152 hash_bytes = docket.tree_metadata[-hash_len:]
1153 ui.write(binascii.hexlify(hash_bytes) + b'\n')
1153 ui.write(binascii.hexlify(hash_bytes) + b'\n')
1154
1154
1155
1155
1156 @command(
1156 @command(
1157 b'debugdiscovery',
1157 b'debugdiscovery',
1158 [
1158 [
1159 (b'', b'old', None, _(b'use old-style discovery')),
1159 (b'', b'old', None, _(b'use old-style discovery')),
1160 (
1160 (
1161 b'',
1161 b'',
1162 b'nonheads',
1162 b'nonheads',
1163 None,
1163 None,
1164 _(b'use old-style discovery with non-heads included'),
1164 _(b'use old-style discovery with non-heads included'),
1165 ),
1165 ),
1166 (b'', b'rev', [], b'restrict discovery to this set of revs'),
1166 (b'', b'rev', [], b'restrict discovery to this set of revs'),
1167 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
1167 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
1168 (
1168 (
1169 b'',
1169 b'',
1170 b'local-as-revs',
1170 b'local-as-revs',
1171 b"",
1171 b"",
1172 b'treat local has having these revisions only',
1172 b'treat local has having these revisions only',
1173 ),
1173 ),
1174 (
1174 (
1175 b'',
1175 b'',
1176 b'remote-as-revs',
1176 b'remote-as-revs',
1177 b"",
1177 b"",
1178 b'use local as remote, with only these revisions',
1178 b'use local as remote, with only these revisions',
1179 ),
1179 ),
1180 ]
1180 ]
1181 + cmdutil.remoteopts
1181 + cmdutil.remoteopts
1182 + cmdutil.formatteropts,
1182 + cmdutil.formatteropts,
1183 _(b'[--rev REV] [OTHER]'),
1183 _(b'[--rev REV] [OTHER]'),
1184 )
1184 )
1185 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
1185 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
1186 """runs the changeset discovery protocol in isolation
1186 """runs the changeset discovery protocol in isolation
1187
1187
1188 The local peer can be "replaced" by a subset of the local repository by
1188 The local peer can be "replaced" by a subset of the local repository by
1189 using the `--local-as-revs` flag. Int he same way, usual `remote` peer can
1189 using the `--local-as-revs` flag. Int he same way, usual `remote` peer can
1190 be "replaced" by a subset of the local repository using the
1190 be "replaced" by a subset of the local repository using the
1191 `--local-as-revs` flag. This is useful to efficiently debug pathological
1191 `--local-as-revs` flag. This is useful to efficiently debug pathological
1192 discovery situation.
1192 discovery situation.
1193
1193
1194 The following developer oriented config are relevant for people playing with this command:
1194 The following developer oriented config are relevant for people playing with this command:
1195
1195
1196 * devel.discovery.exchange-heads=True
1196 * devel.discovery.exchange-heads=True
1197
1197
1198 If False, the discovery will not start with
1198 If False, the discovery will not start with
1199 remote head fetching and local head querying.
1199 remote head fetching and local head querying.
1200
1200
1201 * devel.discovery.grow-sample=True
1201 * devel.discovery.grow-sample=True
1202
1202
1203 If False, the sample size used in set discovery will not be increased
1203 If False, the sample size used in set discovery will not be increased
1204 through the process
1204 through the process
1205
1205
1206 * devel.discovery.grow-sample.dynamic=True
1206 * devel.discovery.grow-sample.dynamic=True
1207
1207
1208 When discovery.grow-sample.dynamic is True, the default, the sample size is
1208 When discovery.grow-sample.dynamic is True, the default, the sample size is
1209 adapted to the shape of the undecided set (it is set to the max of:
1209 adapted to the shape of the undecided set (it is set to the max of:
1210 <target-size>, len(roots(undecided)), len(heads(undecided)
1210 <target-size>, len(roots(undecided)), len(heads(undecided)
1211
1211
1212 * devel.discovery.grow-sample.rate=1.05
1212 * devel.discovery.grow-sample.rate=1.05
1213
1213
1214 the rate at which the sample grow
1214 the rate at which the sample grow
1215
1215
1216 * devel.discovery.randomize=True
1216 * devel.discovery.randomize=True
1217
1217
1218 If andom sampling during discovery are deterministic. It is meant for
1218 If andom sampling during discovery are deterministic. It is meant for
1219 integration tests.
1219 integration tests.
1220
1220
1221 * devel.discovery.sample-size=200
1221 * devel.discovery.sample-size=200
1222
1222
1223 Control the initial size of the discovery sample
1223 Control the initial size of the discovery sample
1224
1224
1225 * devel.discovery.sample-size.initial=100
1225 * devel.discovery.sample-size.initial=100
1226
1226
1227 Control the initial size of the discovery for initial change
1227 Control the initial size of the discovery for initial change
1228 """
1228 """
1229 opts = pycompat.byteskwargs(opts)
1229 opts = pycompat.byteskwargs(opts)
1230 unfi = repo.unfiltered()
1230 unfi = repo.unfiltered()
1231
1231
1232 # setup potential extra filtering
1232 # setup potential extra filtering
1233 local_revs = opts[b"local_as_revs"]
1233 local_revs = opts[b"local_as_revs"]
1234 remote_revs = opts[b"remote_as_revs"]
1234 remote_revs = opts[b"remote_as_revs"]
1235
1235
1236 # make sure tests are repeatable
1236 # make sure tests are repeatable
1237 random.seed(int(opts[b'seed']))
1237 random.seed(int(opts[b'seed']))
1238
1238
1239 if not remote_revs:
1239 if not remote_revs:
1240
1240
1241 remoteurl, branches = urlutil.get_unique_pull_path(
1241 remoteurl, branches = urlutil.get_unique_pull_path(
1242 b'debugdiscovery', repo, ui, remoteurl
1242 b'debugdiscovery', repo, ui, remoteurl
1243 )
1243 )
1244 remote = hg.peer(repo, opts, remoteurl)
1244 remote = hg.peer(repo, opts, remoteurl)
1245 ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(remoteurl))
1245 ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(remoteurl))
1246 else:
1246 else:
1247 branches = (None, [])
1247 branches = (None, [])
1248 remote_filtered_revs = logcmdutil.revrange(
1248 remote_filtered_revs = logcmdutil.revrange(
1249 unfi, [b"not (::(%s))" % remote_revs]
1249 unfi, [b"not (::(%s))" % remote_revs]
1250 )
1250 )
1251 remote_filtered_revs = frozenset(remote_filtered_revs)
1251 remote_filtered_revs = frozenset(remote_filtered_revs)
1252
1252
1253 def remote_func(x):
1253 def remote_func(x):
1254 return remote_filtered_revs
1254 return remote_filtered_revs
1255
1255
1256 repoview.filtertable[b'debug-discovery-remote-filter'] = remote_func
1256 repoview.filtertable[b'debug-discovery-remote-filter'] = remote_func
1257
1257
1258 remote = repo.peer()
1258 remote = repo.peer()
1259 remote._repo = remote._repo.filtered(b'debug-discovery-remote-filter')
1259 remote._repo = remote._repo.filtered(b'debug-discovery-remote-filter')
1260
1260
1261 if local_revs:
1261 if local_revs:
1262 local_filtered_revs = logcmdutil.revrange(
1262 local_filtered_revs = logcmdutil.revrange(
1263 unfi, [b"not (::(%s))" % local_revs]
1263 unfi, [b"not (::(%s))" % local_revs]
1264 )
1264 )
1265 local_filtered_revs = frozenset(local_filtered_revs)
1265 local_filtered_revs = frozenset(local_filtered_revs)
1266
1266
1267 def local_func(x):
1267 def local_func(x):
1268 return local_filtered_revs
1268 return local_filtered_revs
1269
1269
1270 repoview.filtertable[b'debug-discovery-local-filter'] = local_func
1270 repoview.filtertable[b'debug-discovery-local-filter'] = local_func
1271 repo = repo.filtered(b'debug-discovery-local-filter')
1271 repo = repo.filtered(b'debug-discovery-local-filter')
1272
1272
1273 data = {}
1273 data = {}
1274 if opts.get(b'old'):
1274 if opts.get(b'old'):
1275
1275
1276 def doit(pushedrevs, remoteheads, remote=remote):
1276 def doit(pushedrevs, remoteheads, remote=remote):
1277 if not util.safehasattr(remote, b'branches'):
1277 if not util.safehasattr(remote, b'branches'):
1278 # enable in-client legacy support
1278 # enable in-client legacy support
1279 remote = localrepo.locallegacypeer(remote.local())
1279 remote = localrepo.locallegacypeer(remote.local())
1280 common, _in, hds = treediscovery.findcommonincoming(
1280 common, _in, hds = treediscovery.findcommonincoming(
1281 repo, remote, force=True, audit=data
1281 repo, remote, force=True, audit=data
1282 )
1282 )
1283 common = set(common)
1283 common = set(common)
1284 if not opts.get(b'nonheads'):
1284 if not opts.get(b'nonheads'):
1285 ui.writenoi18n(
1285 ui.writenoi18n(
1286 b"unpruned common: %s\n"
1286 b"unpruned common: %s\n"
1287 % b" ".join(sorted(short(n) for n in common))
1287 % b" ".join(sorted(short(n) for n in common))
1288 )
1288 )
1289
1289
1290 clnode = repo.changelog.node
1290 clnode = repo.changelog.node
1291 common = repo.revs(b'heads(::%ln)', common)
1291 common = repo.revs(b'heads(::%ln)', common)
1292 common = {clnode(r) for r in common}
1292 common = {clnode(r) for r in common}
1293 return common, hds
1293 return common, hds
1294
1294
1295 else:
1295 else:
1296
1296
1297 def doit(pushedrevs, remoteheads, remote=remote):
1297 def doit(pushedrevs, remoteheads, remote=remote):
1298 nodes = None
1298 nodes = None
1299 if pushedrevs:
1299 if pushedrevs:
1300 revs = logcmdutil.revrange(repo, pushedrevs)
1300 revs = logcmdutil.revrange(repo, pushedrevs)
1301 nodes = [repo[r].node() for r in revs]
1301 nodes = [repo[r].node() for r in revs]
1302 common, any, hds = setdiscovery.findcommonheads(
1302 common, any, hds = setdiscovery.findcommonheads(
1303 ui, repo, remote, ancestorsof=nodes, audit=data
1303 ui, repo, remote, ancestorsof=nodes, audit=data
1304 )
1304 )
1305 return common, hds
1305 return common, hds
1306
1306
1307 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
1307 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
1308 localrevs = opts[b'rev']
1308 localrevs = opts[b'rev']
1309
1309
1310 fm = ui.formatter(b'debugdiscovery', opts)
1310 fm = ui.formatter(b'debugdiscovery', opts)
1311 if fm.strict_format:
1311 if fm.strict_format:
1312
1312
1313 @contextlib.contextmanager
1313 @contextlib.contextmanager
1314 def may_capture_output():
1314 def may_capture_output():
1315 ui.pushbuffer()
1315 ui.pushbuffer()
1316 yield
1316 yield
1317 data[b'output'] = ui.popbuffer()
1317 data[b'output'] = ui.popbuffer()
1318
1318
1319 else:
1319 else:
1320 may_capture_output = util.nullcontextmanager
1320 may_capture_output = util.nullcontextmanager
1321 with may_capture_output():
1321 with may_capture_output():
1322 with util.timedcm('debug-discovery') as t:
1322 with util.timedcm('debug-discovery') as t:
1323 common, hds = doit(localrevs, remoterevs)
1323 common, hds = doit(localrevs, remoterevs)
1324
1324
1325 # compute all statistics
1325 # compute all statistics
1326 heads_common = set(common)
1326 heads_common = set(common)
1327 heads_remote = set(hds)
1327 heads_remote = set(hds)
1328 heads_local = set(repo.heads())
1328 heads_local = set(repo.heads())
1329 # note: they cannot be a local or remote head that is in common and not
1329 # note: they cannot be a local or remote head that is in common and not
1330 # itself a head of common.
1330 # itself a head of common.
1331 heads_common_local = heads_common & heads_local
1331 heads_common_local = heads_common & heads_local
1332 heads_common_remote = heads_common & heads_remote
1332 heads_common_remote = heads_common & heads_remote
1333 heads_common_both = heads_common & heads_remote & heads_local
1333 heads_common_both = heads_common & heads_remote & heads_local
1334
1334
1335 all = repo.revs(b'all()')
1335 all = repo.revs(b'all()')
1336 common = repo.revs(b'::%ln', common)
1336 common = repo.revs(b'::%ln', common)
1337 roots_common = repo.revs(b'roots(::%ld)', common)
1337 roots_common = repo.revs(b'roots(::%ld)', common)
1338 missing = repo.revs(b'not ::%ld', common)
1338 missing = repo.revs(b'not ::%ld', common)
1339 heads_missing = repo.revs(b'heads(%ld)', missing)
1339 heads_missing = repo.revs(b'heads(%ld)', missing)
1340 roots_missing = repo.revs(b'roots(%ld)', missing)
1340 roots_missing = repo.revs(b'roots(%ld)', missing)
1341 assert len(common) + len(missing) == len(all)
1341 assert len(common) + len(missing) == len(all)
1342
1342
1343 initial_undecided = repo.revs(
1343 initial_undecided = repo.revs(
1344 b'not (::%ln or %ln::)', heads_common_remote, heads_common_local
1344 b'not (::%ln or %ln::)', heads_common_remote, heads_common_local
1345 )
1345 )
1346 heads_initial_undecided = repo.revs(b'heads(%ld)', initial_undecided)
1346 heads_initial_undecided = repo.revs(b'heads(%ld)', initial_undecided)
1347 roots_initial_undecided = repo.revs(b'roots(%ld)', initial_undecided)
1347 roots_initial_undecided = repo.revs(b'roots(%ld)', initial_undecided)
1348 common_initial_undecided = initial_undecided & common
1348 common_initial_undecided = initial_undecided & common
1349 missing_initial_undecided = initial_undecided & missing
1349 missing_initial_undecided = initial_undecided & missing
1350
1350
1351 data[b'elapsed'] = t.elapsed
1351 data[b'elapsed'] = t.elapsed
1352 data[b'nb-common-heads'] = len(heads_common)
1352 data[b'nb-common-heads'] = len(heads_common)
1353 data[b'nb-common-heads-local'] = len(heads_common_local)
1353 data[b'nb-common-heads-local'] = len(heads_common_local)
1354 data[b'nb-common-heads-remote'] = len(heads_common_remote)
1354 data[b'nb-common-heads-remote'] = len(heads_common_remote)
1355 data[b'nb-common-heads-both'] = len(heads_common_both)
1355 data[b'nb-common-heads-both'] = len(heads_common_both)
1356 data[b'nb-common-roots'] = len(roots_common)
1356 data[b'nb-common-roots'] = len(roots_common)
1357 data[b'nb-head-local'] = len(heads_local)
1357 data[b'nb-head-local'] = len(heads_local)
1358 data[b'nb-head-local-missing'] = len(heads_local) - len(heads_common_local)
1358 data[b'nb-head-local-missing'] = len(heads_local) - len(heads_common_local)
1359 data[b'nb-head-remote'] = len(heads_remote)
1359 data[b'nb-head-remote'] = len(heads_remote)
1360 data[b'nb-head-remote-unknown'] = len(heads_remote) - len(
1360 data[b'nb-head-remote-unknown'] = len(heads_remote) - len(
1361 heads_common_remote
1361 heads_common_remote
1362 )
1362 )
1363 data[b'nb-revs'] = len(all)
1363 data[b'nb-revs'] = len(all)
1364 data[b'nb-revs-common'] = len(common)
1364 data[b'nb-revs-common'] = len(common)
1365 data[b'nb-revs-missing'] = len(missing)
1365 data[b'nb-revs-missing'] = len(missing)
1366 data[b'nb-missing-heads'] = len(heads_missing)
1366 data[b'nb-missing-heads'] = len(heads_missing)
1367 data[b'nb-missing-roots'] = len(roots_missing)
1367 data[b'nb-missing-roots'] = len(roots_missing)
1368 data[b'nb-ini_und'] = len(initial_undecided)
1368 data[b'nb-ini_und'] = len(initial_undecided)
1369 data[b'nb-ini_und-heads'] = len(heads_initial_undecided)
1369 data[b'nb-ini_und-heads'] = len(heads_initial_undecided)
1370 data[b'nb-ini_und-roots'] = len(roots_initial_undecided)
1370 data[b'nb-ini_und-roots'] = len(roots_initial_undecided)
1371 data[b'nb-ini_und-common'] = len(common_initial_undecided)
1371 data[b'nb-ini_und-common'] = len(common_initial_undecided)
1372 data[b'nb-ini_und-missing'] = len(missing_initial_undecided)
1372 data[b'nb-ini_und-missing'] = len(missing_initial_undecided)
1373
1373
1374 fm.startitem()
1374 fm.startitem()
1375 fm.data(**pycompat.strkwargs(data))
1375 fm.data(**pycompat.strkwargs(data))
1376 # display discovery summary
1376 # display discovery summary
1377 fm.plain(b"elapsed time: %(elapsed)f seconds\n" % data)
1377 fm.plain(b"elapsed time: %(elapsed)f seconds\n" % data)
1378 fm.plain(b"round-trips: %(total-roundtrips)9d\n" % data)
1378 fm.plain(b"round-trips: %(total-roundtrips)9d\n" % data)
1379 fm.plain(b"queries: %(total-queries)9d\n" % data)
1379 fm.plain(b"queries: %(total-queries)9d\n" % data)
1380 fm.plain(b"heads summary:\n")
1380 fm.plain(b"heads summary:\n")
1381 fm.plain(b" total common heads: %(nb-common-heads)9d\n" % data)
1381 fm.plain(b" total common heads: %(nb-common-heads)9d\n" % data)
1382 fm.plain(b" also local heads: %(nb-common-heads-local)9d\n" % data)
1382 fm.plain(b" also local heads: %(nb-common-heads-local)9d\n" % data)
1383 fm.plain(b" also remote heads: %(nb-common-heads-remote)9d\n" % data)
1383 fm.plain(b" also remote heads: %(nb-common-heads-remote)9d\n" % data)
1384 fm.plain(b" both: %(nb-common-heads-both)9d\n" % data)
1384 fm.plain(b" both: %(nb-common-heads-both)9d\n" % data)
1385 fm.plain(b" local heads: %(nb-head-local)9d\n" % data)
1385 fm.plain(b" local heads: %(nb-head-local)9d\n" % data)
1386 fm.plain(b" common: %(nb-common-heads-local)9d\n" % data)
1386 fm.plain(b" common: %(nb-common-heads-local)9d\n" % data)
1387 fm.plain(b" missing: %(nb-head-local-missing)9d\n" % data)
1387 fm.plain(b" missing: %(nb-head-local-missing)9d\n" % data)
1388 fm.plain(b" remote heads: %(nb-head-remote)9d\n" % data)
1388 fm.plain(b" remote heads: %(nb-head-remote)9d\n" % data)
1389 fm.plain(b" common: %(nb-common-heads-remote)9d\n" % data)
1389 fm.plain(b" common: %(nb-common-heads-remote)9d\n" % data)
1390 fm.plain(b" unknown: %(nb-head-remote-unknown)9d\n" % data)
1390 fm.plain(b" unknown: %(nb-head-remote-unknown)9d\n" % data)
1391 fm.plain(b"local changesets: %(nb-revs)9d\n" % data)
1391 fm.plain(b"local changesets: %(nb-revs)9d\n" % data)
1392 fm.plain(b" common: %(nb-revs-common)9d\n" % data)
1392 fm.plain(b" common: %(nb-revs-common)9d\n" % data)
1393 fm.plain(b" heads: %(nb-common-heads)9d\n" % data)
1393 fm.plain(b" heads: %(nb-common-heads)9d\n" % data)
1394 fm.plain(b" roots: %(nb-common-roots)9d\n" % data)
1394 fm.plain(b" roots: %(nb-common-roots)9d\n" % data)
1395 fm.plain(b" missing: %(nb-revs-missing)9d\n" % data)
1395 fm.plain(b" missing: %(nb-revs-missing)9d\n" % data)
1396 fm.plain(b" heads: %(nb-missing-heads)9d\n" % data)
1396 fm.plain(b" heads: %(nb-missing-heads)9d\n" % data)
1397 fm.plain(b" roots: %(nb-missing-roots)9d\n" % data)
1397 fm.plain(b" roots: %(nb-missing-roots)9d\n" % data)
1398 fm.plain(b" first undecided set: %(nb-ini_und)9d\n" % data)
1398 fm.plain(b" first undecided set: %(nb-ini_und)9d\n" % data)
1399 fm.plain(b" heads: %(nb-ini_und-heads)9d\n" % data)
1399 fm.plain(b" heads: %(nb-ini_und-heads)9d\n" % data)
1400 fm.plain(b" roots: %(nb-ini_und-roots)9d\n" % data)
1400 fm.plain(b" roots: %(nb-ini_und-roots)9d\n" % data)
1401 fm.plain(b" common: %(nb-ini_und-common)9d\n" % data)
1401 fm.plain(b" common: %(nb-ini_und-common)9d\n" % data)
1402 fm.plain(b" missing: %(nb-ini_und-missing)9d\n" % data)
1402 fm.plain(b" missing: %(nb-ini_und-missing)9d\n" % data)
1403
1403
1404 if ui.verbose:
1404 if ui.verbose:
1405 fm.plain(
1405 fm.plain(
1406 b"common heads: %s\n"
1406 b"common heads: %s\n"
1407 % b" ".join(sorted(short(n) for n in heads_common))
1407 % b" ".join(sorted(short(n) for n in heads_common))
1408 )
1408 )
1409 fm.end()
1409 fm.end()
1410
1410
1411
1411
1412 _chunksize = 4 << 10
1412 _chunksize = 4 << 10
1413
1413
1414
1414
1415 @command(
1415 @command(
1416 b'debugdownload',
1416 b'debugdownload',
1417 [
1417 [
1418 (b'o', b'output', b'', _(b'path')),
1418 (b'o', b'output', b'', _(b'path')),
1419 ],
1419 ],
1420 optionalrepo=True,
1420 optionalrepo=True,
1421 )
1421 )
1422 def debugdownload(ui, repo, url, output=None, **opts):
1422 def debugdownload(ui, repo, url, output=None, **opts):
1423 """download a resource using Mercurial logic and config"""
1423 """download a resource using Mercurial logic and config"""
1424 fh = urlmod.open(ui, url, output)
1424 fh = urlmod.open(ui, url, output)
1425
1425
1426 dest = ui
1426 dest = ui
1427 if output:
1427 if output:
1428 dest = open(output, b"wb", _chunksize)
1428 dest = open(output, b"wb", _chunksize)
1429 try:
1429 try:
1430 data = fh.read(_chunksize)
1430 data = fh.read(_chunksize)
1431 while data:
1431 while data:
1432 dest.write(data)
1432 dest.write(data)
1433 data = fh.read(_chunksize)
1433 data = fh.read(_chunksize)
1434 finally:
1434 finally:
1435 if output:
1435 if output:
1436 dest.close()
1436 dest.close()
1437
1437
1438
1438
1439 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1439 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1440 def debugextensions(ui, repo, **opts):
1440 def debugextensions(ui, repo, **opts):
1441 '''show information about active extensions'''
1441 '''show information about active extensions'''
1442 opts = pycompat.byteskwargs(opts)
1442 opts = pycompat.byteskwargs(opts)
1443 exts = extensions.extensions(ui)
1443 exts = extensions.extensions(ui)
1444 hgver = util.version()
1444 hgver = util.version()
1445 fm = ui.formatter(b'debugextensions', opts)
1445 fm = ui.formatter(b'debugextensions', opts)
1446 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1446 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1447 isinternal = extensions.ismoduleinternal(extmod)
1447 isinternal = extensions.ismoduleinternal(extmod)
1448 extsource = None
1448 extsource = None
1449
1449
1450 if util.safehasattr(extmod, '__file__'):
1450 if util.safehasattr(extmod, '__file__'):
1451 extsource = pycompat.fsencode(extmod.__file__)
1451 extsource = pycompat.fsencode(extmod.__file__)
1452 elif getattr(sys, 'oxidized', False):
1452 elif getattr(sys, 'oxidized', False):
1453 extsource = pycompat.sysexecutable
1453 extsource = pycompat.sysexecutable
1454 if isinternal:
1454 if isinternal:
1455 exttestedwith = [] # never expose magic string to users
1455 exttestedwith = [] # never expose magic string to users
1456 else:
1456 else:
1457 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1457 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1458 extbuglink = getattr(extmod, 'buglink', None)
1458 extbuglink = getattr(extmod, 'buglink', None)
1459
1459
1460 fm.startitem()
1460 fm.startitem()
1461
1461
1462 if ui.quiet or ui.verbose:
1462 if ui.quiet or ui.verbose:
1463 fm.write(b'name', b'%s\n', extname)
1463 fm.write(b'name', b'%s\n', extname)
1464 else:
1464 else:
1465 fm.write(b'name', b'%s', extname)
1465 fm.write(b'name', b'%s', extname)
1466 if isinternal or hgver in exttestedwith:
1466 if isinternal or hgver in exttestedwith:
1467 fm.plain(b'\n')
1467 fm.plain(b'\n')
1468 elif not exttestedwith:
1468 elif not exttestedwith:
1469 fm.plain(_(b' (untested!)\n'))
1469 fm.plain(_(b' (untested!)\n'))
1470 else:
1470 else:
1471 lasttestedversion = exttestedwith[-1]
1471 lasttestedversion = exttestedwith[-1]
1472 fm.plain(b' (%s!)\n' % lasttestedversion)
1472 fm.plain(b' (%s!)\n' % lasttestedversion)
1473
1473
1474 fm.condwrite(
1474 fm.condwrite(
1475 ui.verbose and extsource,
1475 ui.verbose and extsource,
1476 b'source',
1476 b'source',
1477 _(b' location: %s\n'),
1477 _(b' location: %s\n'),
1478 extsource or b"",
1478 extsource or b"",
1479 )
1479 )
1480
1480
1481 if ui.verbose:
1481 if ui.verbose:
1482 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1482 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1483 fm.data(bundled=isinternal)
1483 fm.data(bundled=isinternal)
1484
1484
1485 fm.condwrite(
1485 fm.condwrite(
1486 ui.verbose and exttestedwith,
1486 ui.verbose and exttestedwith,
1487 b'testedwith',
1487 b'testedwith',
1488 _(b' tested with: %s\n'),
1488 _(b' tested with: %s\n'),
1489 fm.formatlist(exttestedwith, name=b'ver'),
1489 fm.formatlist(exttestedwith, name=b'ver'),
1490 )
1490 )
1491
1491
1492 fm.condwrite(
1492 fm.condwrite(
1493 ui.verbose and extbuglink,
1493 ui.verbose and extbuglink,
1494 b'buglink',
1494 b'buglink',
1495 _(b' bug reporting: %s\n'),
1495 _(b' bug reporting: %s\n'),
1496 extbuglink or b"",
1496 extbuglink or b"",
1497 )
1497 )
1498
1498
1499 fm.end()
1499 fm.end()
1500
1500
1501
1501
1502 @command(
1502 @command(
1503 b'debugfileset',
1503 b'debugfileset',
1504 [
1504 [
1505 (
1505 (
1506 b'r',
1506 b'r',
1507 b'rev',
1507 b'rev',
1508 b'',
1508 b'',
1509 _(b'apply the filespec on this revision'),
1509 _(b'apply the filespec on this revision'),
1510 _(b'REV'),
1510 _(b'REV'),
1511 ),
1511 ),
1512 (
1512 (
1513 b'',
1513 b'',
1514 b'all-files',
1514 b'all-files',
1515 False,
1515 False,
1516 _(b'test files from all revisions and working directory'),
1516 _(b'test files from all revisions and working directory'),
1517 ),
1517 ),
1518 (
1518 (
1519 b's',
1519 b's',
1520 b'show-matcher',
1520 b'show-matcher',
1521 None,
1521 None,
1522 _(b'print internal representation of matcher'),
1522 _(b'print internal representation of matcher'),
1523 ),
1523 ),
1524 (
1524 (
1525 b'p',
1525 b'p',
1526 b'show-stage',
1526 b'show-stage',
1527 [],
1527 [],
1528 _(b'print parsed tree at the given stage'),
1528 _(b'print parsed tree at the given stage'),
1529 _(b'NAME'),
1529 _(b'NAME'),
1530 ),
1530 ),
1531 ],
1531 ],
1532 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1532 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1533 )
1533 )
1534 def debugfileset(ui, repo, expr, **opts):
1534 def debugfileset(ui, repo, expr, **opts):
1535 '''parse and apply a fileset specification'''
1535 '''parse and apply a fileset specification'''
1536 from . import fileset
1536 from . import fileset
1537
1537
1538 fileset.symbols # force import of fileset so we have predicates to optimize
1538 fileset.symbols # force import of fileset so we have predicates to optimize
1539 opts = pycompat.byteskwargs(opts)
1539 opts = pycompat.byteskwargs(opts)
1540 ctx = logcmdutil.revsingle(repo, opts.get(b'rev'), None)
1540 ctx = logcmdutil.revsingle(repo, opts.get(b'rev'), None)
1541
1541
1542 stages = [
1542 stages = [
1543 (b'parsed', pycompat.identity),
1543 (b'parsed', pycompat.identity),
1544 (b'analyzed', filesetlang.analyze),
1544 (b'analyzed', filesetlang.analyze),
1545 (b'optimized', filesetlang.optimize),
1545 (b'optimized', filesetlang.optimize),
1546 ]
1546 ]
1547 stagenames = {n for n, f in stages}
1547 stagenames = {n for n, f in stages}
1548
1548
1549 showalways = set()
1549 showalways = set()
1550 if ui.verbose and not opts[b'show_stage']:
1550 if ui.verbose and not opts[b'show_stage']:
1551 # show parsed tree by --verbose (deprecated)
1551 # show parsed tree by --verbose (deprecated)
1552 showalways.add(b'parsed')
1552 showalways.add(b'parsed')
1553 if opts[b'show_stage'] == [b'all']:
1553 if opts[b'show_stage'] == [b'all']:
1554 showalways.update(stagenames)
1554 showalways.update(stagenames)
1555 else:
1555 else:
1556 for n in opts[b'show_stage']:
1556 for n in opts[b'show_stage']:
1557 if n not in stagenames:
1557 if n not in stagenames:
1558 raise error.Abort(_(b'invalid stage name: %s') % n)
1558 raise error.Abort(_(b'invalid stage name: %s') % n)
1559 showalways.update(opts[b'show_stage'])
1559 showalways.update(opts[b'show_stage'])
1560
1560
1561 tree = filesetlang.parse(expr)
1561 tree = filesetlang.parse(expr)
1562 for n, f in stages:
1562 for n, f in stages:
1563 tree = f(tree)
1563 tree = f(tree)
1564 if n in showalways:
1564 if n in showalways:
1565 if opts[b'show_stage'] or n != b'parsed':
1565 if opts[b'show_stage'] or n != b'parsed':
1566 ui.write(b"* %s:\n" % n)
1566 ui.write(b"* %s:\n" % n)
1567 ui.write(filesetlang.prettyformat(tree), b"\n")
1567 ui.write(filesetlang.prettyformat(tree), b"\n")
1568
1568
1569 files = set()
1569 files = set()
1570 if opts[b'all_files']:
1570 if opts[b'all_files']:
1571 for r in repo:
1571 for r in repo:
1572 c = repo[r]
1572 c = repo[r]
1573 files.update(c.files())
1573 files.update(c.files())
1574 files.update(c.substate)
1574 files.update(c.substate)
1575 if opts[b'all_files'] or ctx.rev() is None:
1575 if opts[b'all_files'] or ctx.rev() is None:
1576 wctx = repo[None]
1576 wctx = repo[None]
1577 files.update(
1577 files.update(
1578 repo.dirstate.walk(
1578 repo.dirstate.walk(
1579 scmutil.matchall(repo),
1579 scmutil.matchall(repo),
1580 subrepos=list(wctx.substate),
1580 subrepos=list(wctx.substate),
1581 unknown=True,
1581 unknown=True,
1582 ignored=True,
1582 ignored=True,
1583 )
1583 )
1584 )
1584 )
1585 files.update(wctx.substate)
1585 files.update(wctx.substate)
1586 else:
1586 else:
1587 files.update(ctx.files())
1587 files.update(ctx.files())
1588 files.update(ctx.substate)
1588 files.update(ctx.substate)
1589
1589
1590 m = ctx.matchfileset(repo.getcwd(), expr)
1590 m = ctx.matchfileset(repo.getcwd(), expr)
1591 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1591 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1592 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1592 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1593 for f in sorted(files):
1593 for f in sorted(files):
1594 if not m(f):
1594 if not m(f):
1595 continue
1595 continue
1596 ui.write(b"%s\n" % f)
1596 ui.write(b"%s\n" % f)
1597
1597
1598
1598
1599 @command(
1599 @command(
1600 b"debug-repair-issue6528",
1600 b"debug-repair-issue6528",
1601 [
1601 [
1602 (
1602 (
1603 b'',
1603 b'',
1604 b'to-report',
1604 b'to-report',
1605 b'',
1605 b'',
1606 _(b'build a report of affected revisions to this file'),
1606 _(b'build a report of affected revisions to this file'),
1607 _(b'FILE'),
1607 _(b'FILE'),
1608 ),
1608 ),
1609 (
1609 (
1610 b'',
1610 b'',
1611 b'from-report',
1611 b'from-report',
1612 b'',
1612 b'',
1613 _(b'repair revisions listed in this report file'),
1613 _(b'repair revisions listed in this report file'),
1614 _(b'FILE'),
1614 _(b'FILE'),
1615 ),
1615 ),
1616 (
1616 (
1617 b'',
1617 b'',
1618 b'paranoid',
1618 b'paranoid',
1619 False,
1619 False,
1620 _(b'check that both detection methods do the same thing'),
1620 _(b'check that both detection methods do the same thing'),
1621 ),
1621 ),
1622 ]
1622 ]
1623 + cmdutil.dryrunopts,
1623 + cmdutil.dryrunopts,
1624 )
1624 )
1625 def debug_repair_issue6528(ui, repo, **opts):
1625 def debug_repair_issue6528(ui, repo, **opts):
1626 """find affected revisions and repair them. See issue6528 for more details.
1626 """find affected revisions and repair them. See issue6528 for more details.
1627
1627
1628 The `--to-report` and `--from-report` flags allow you to cache and reuse the
1628 The `--to-report` and `--from-report` flags allow you to cache and reuse the
1629 computation of affected revisions for a given repository across clones.
1629 computation of affected revisions for a given repository across clones.
1630 The report format is line-based (with empty lines ignored):
1630 The report format is line-based (with empty lines ignored):
1631
1631
1632 ```
1632 ```
1633 <ascii-hex of the affected revision>,... <unencoded filelog index filename>
1633 <ascii-hex of the affected revision>,... <unencoded filelog index filename>
1634 ```
1634 ```
1635
1635
1636 There can be multiple broken revisions per filelog, they are separated by
1636 There can be multiple broken revisions per filelog, they are separated by
1637 a comma with no spaces. The only space is between the revision(s) and the
1637 a comma with no spaces. The only space is between the revision(s) and the
1638 filename.
1638 filename.
1639
1639
1640 Note that this does *not* mean that this repairs future affected revisions,
1640 Note that this does *not* mean that this repairs future affected revisions,
1641 that needs a separate fix at the exchange level that was introduced in
1641 that needs a separate fix at the exchange level that was introduced in
1642 Mercurial 5.9.1.
1642 Mercurial 5.9.1.
1643
1643
1644 There is a `--paranoid` flag to test that the fast implementation is correct
1644 There is a `--paranoid` flag to test that the fast implementation is correct
1645 by checking it against the slow implementation. Since this matter is quite
1645 by checking it against the slow implementation. Since this matter is quite
1646 urgent and testing every edge-case is probably quite costly, we use this
1646 urgent and testing every edge-case is probably quite costly, we use this
1647 method to test on large repositories as a fuzzing method of sorts.
1647 method to test on large repositories as a fuzzing method of sorts.
1648 """
1648 """
1649 cmdutil.check_incompatible_arguments(
1649 cmdutil.check_incompatible_arguments(
1650 opts, 'to_report', ['from_report', 'dry_run']
1650 opts, 'to_report', ['from_report', 'dry_run']
1651 )
1651 )
1652 dry_run = opts.get('dry_run')
1652 dry_run = opts.get('dry_run')
1653 to_report = opts.get('to_report')
1653 to_report = opts.get('to_report')
1654 from_report = opts.get('from_report')
1654 from_report = opts.get('from_report')
1655 paranoid = opts.get('paranoid')
1655 paranoid = opts.get('paranoid')
1656 # TODO maybe add filelog pattern and revision pattern parameters to help
1656 # TODO maybe add filelog pattern and revision pattern parameters to help
1657 # narrow down the search for users that know what they're looking for?
1657 # narrow down the search for users that know what they're looking for?
1658
1658
1659 if requirements.REVLOGV1_REQUIREMENT not in repo.requirements:
1659 if requirements.REVLOGV1_REQUIREMENT not in repo.requirements:
1660 msg = b"can only repair revlogv1 repositories, v2 is not affected"
1660 msg = b"can only repair revlogv1 repositories, v2 is not affected"
1661 raise error.Abort(_(msg))
1661 raise error.Abort(_(msg))
1662
1662
1663 rewrite.repair_issue6528(
1663 rewrite.repair_issue6528(
1664 ui,
1664 ui,
1665 repo,
1665 repo,
1666 dry_run=dry_run,
1666 dry_run=dry_run,
1667 to_report=to_report,
1667 to_report=to_report,
1668 from_report=from_report,
1668 from_report=from_report,
1669 paranoid=paranoid,
1669 paranoid=paranoid,
1670 )
1670 )
1671
1671
1672
1672
1673 @command(b'debugformat', [] + cmdutil.formatteropts)
1673 @command(b'debugformat', [] + cmdutil.formatteropts)
1674 def debugformat(ui, repo, **opts):
1674 def debugformat(ui, repo, **opts):
1675 """display format information about the current repository
1675 """display format information about the current repository
1676
1676
1677 Use --verbose to get extra information about current config value and
1677 Use --verbose to get extra information about current config value and
1678 Mercurial default."""
1678 Mercurial default."""
1679 opts = pycompat.byteskwargs(opts)
1679 opts = pycompat.byteskwargs(opts)
1680 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1680 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1681 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1681 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1682
1682
1683 def makeformatname(name):
1683 def makeformatname(name):
1684 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1684 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1685
1685
1686 fm = ui.formatter(b'debugformat', opts)
1686 fm = ui.formatter(b'debugformat', opts)
1687 if fm.isplain():
1687 if fm.isplain():
1688
1688
1689 def formatvalue(value):
1689 def formatvalue(value):
1690 if util.safehasattr(value, b'startswith'):
1690 if util.safehasattr(value, b'startswith'):
1691 return value
1691 return value
1692 if value:
1692 if value:
1693 return b'yes'
1693 return b'yes'
1694 else:
1694 else:
1695 return b'no'
1695 return b'no'
1696
1696
1697 else:
1697 else:
1698 formatvalue = pycompat.identity
1698 formatvalue = pycompat.identity
1699
1699
1700 fm.plain(b'format-variant')
1700 fm.plain(b'format-variant')
1701 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1701 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1702 fm.plain(b' repo')
1702 fm.plain(b' repo')
1703 if ui.verbose:
1703 if ui.verbose:
1704 fm.plain(b' config default')
1704 fm.plain(b' config default')
1705 fm.plain(b'\n')
1705 fm.plain(b'\n')
1706 for fv in upgrade.allformatvariant:
1706 for fv in upgrade.allformatvariant:
1707 fm.startitem()
1707 fm.startitem()
1708 repovalue = fv.fromrepo(repo)
1708 repovalue = fv.fromrepo(repo)
1709 configvalue = fv.fromconfig(repo)
1709 configvalue = fv.fromconfig(repo)
1710
1710
1711 if repovalue != configvalue:
1711 if repovalue != configvalue:
1712 namelabel = b'formatvariant.name.mismatchconfig'
1712 namelabel = b'formatvariant.name.mismatchconfig'
1713 repolabel = b'formatvariant.repo.mismatchconfig'
1713 repolabel = b'formatvariant.repo.mismatchconfig'
1714 elif repovalue != fv.default:
1714 elif repovalue != fv.default:
1715 namelabel = b'formatvariant.name.mismatchdefault'
1715 namelabel = b'formatvariant.name.mismatchdefault'
1716 repolabel = b'formatvariant.repo.mismatchdefault'
1716 repolabel = b'formatvariant.repo.mismatchdefault'
1717 else:
1717 else:
1718 namelabel = b'formatvariant.name.uptodate'
1718 namelabel = b'formatvariant.name.uptodate'
1719 repolabel = b'formatvariant.repo.uptodate'
1719 repolabel = b'formatvariant.repo.uptodate'
1720
1720
1721 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1721 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1722 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1722 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1723 if fv.default != configvalue:
1723 if fv.default != configvalue:
1724 configlabel = b'formatvariant.config.special'
1724 configlabel = b'formatvariant.config.special'
1725 else:
1725 else:
1726 configlabel = b'formatvariant.config.default'
1726 configlabel = b'formatvariant.config.default'
1727 fm.condwrite(
1727 fm.condwrite(
1728 ui.verbose,
1728 ui.verbose,
1729 b'config',
1729 b'config',
1730 b' %6s',
1730 b' %6s',
1731 formatvalue(configvalue),
1731 formatvalue(configvalue),
1732 label=configlabel,
1732 label=configlabel,
1733 )
1733 )
1734 fm.condwrite(
1734 fm.condwrite(
1735 ui.verbose,
1735 ui.verbose,
1736 b'default',
1736 b'default',
1737 b' %7s',
1737 b' %7s',
1738 formatvalue(fv.default),
1738 formatvalue(fv.default),
1739 label=b'formatvariant.default',
1739 label=b'formatvariant.default',
1740 )
1740 )
1741 fm.plain(b'\n')
1741 fm.plain(b'\n')
1742 fm.end()
1742 fm.end()
1743
1743
1744
1744
1745 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1745 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1746 def debugfsinfo(ui, path=b"."):
1746 def debugfsinfo(ui, path=b"."):
1747 """show information detected about current filesystem"""
1747 """show information detected about current filesystem"""
1748 ui.writenoi18n(b'path: %s\n' % path)
1748 ui.writenoi18n(b'path: %s\n' % path)
1749 ui.writenoi18n(
1749 ui.writenoi18n(
1750 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1750 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1751 )
1751 )
1752 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1752 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1753 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1753 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1754 ui.writenoi18n(
1754 ui.writenoi18n(
1755 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1755 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1756 )
1756 )
1757 ui.writenoi18n(
1757 ui.writenoi18n(
1758 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1758 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1759 )
1759 )
1760 casesensitive = b'(unknown)'
1760 casesensitive = b'(unknown)'
1761 try:
1761 try:
1762 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1762 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1763 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1763 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1764 except OSError:
1764 except OSError:
1765 pass
1765 pass
1766 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1766 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1767
1767
1768
1768
1769 @command(
1769 @command(
1770 b'debuggetbundle',
1770 b'debuggetbundle',
1771 [
1771 [
1772 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1772 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1773 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1773 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1774 (
1774 (
1775 b't',
1775 b't',
1776 b'type',
1776 b'type',
1777 b'bzip2',
1777 b'bzip2',
1778 _(b'bundle compression type to use'),
1778 _(b'bundle compression type to use'),
1779 _(b'TYPE'),
1779 _(b'TYPE'),
1780 ),
1780 ),
1781 ],
1781 ],
1782 _(b'REPO FILE [-H|-C ID]...'),
1782 _(b'REPO FILE [-H|-C ID]...'),
1783 norepo=True,
1783 norepo=True,
1784 )
1784 )
1785 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1785 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1786 """retrieves a bundle from a repo
1786 """retrieves a bundle from a repo
1787
1787
1788 Every ID must be a full-length hex node id string. Saves the bundle to the
1788 Every ID must be a full-length hex node id string. Saves the bundle to the
1789 given file.
1789 given file.
1790 """
1790 """
1791 opts = pycompat.byteskwargs(opts)
1791 opts = pycompat.byteskwargs(opts)
1792 repo = hg.peer(ui, opts, repopath)
1792 repo = hg.peer(ui, opts, repopath)
1793 if not repo.capable(b'getbundle'):
1793 if not repo.capable(b'getbundle'):
1794 raise error.Abort(b"getbundle() not supported by target repository")
1794 raise error.Abort(b"getbundle() not supported by target repository")
1795 args = {}
1795 args = {}
1796 if common:
1796 if common:
1797 args['common'] = [bin(s) for s in common]
1797 args['common'] = [bin(s) for s in common]
1798 if head:
1798 if head:
1799 args['heads'] = [bin(s) for s in head]
1799 args['heads'] = [bin(s) for s in head]
1800 # TODO: get desired bundlecaps from command line.
1800 # TODO: get desired bundlecaps from command line.
1801 args['bundlecaps'] = None
1801 args['bundlecaps'] = None
1802 bundle = repo.getbundle(b'debug', **args)
1802 bundle = repo.getbundle(b'debug', **args)
1803
1803
1804 bundletype = opts.get(b'type', b'bzip2').lower()
1804 bundletype = opts.get(b'type', b'bzip2').lower()
1805 btypes = {
1805 btypes = {
1806 b'none': b'HG10UN',
1806 b'none': b'HG10UN',
1807 b'bzip2': b'HG10BZ',
1807 b'bzip2': b'HG10BZ',
1808 b'gzip': b'HG10GZ',
1808 b'gzip': b'HG10GZ',
1809 b'bundle2': b'HG20',
1809 b'bundle2': b'HG20',
1810 }
1810 }
1811 bundletype = btypes.get(bundletype)
1811 bundletype = btypes.get(bundletype)
1812 if bundletype not in bundle2.bundletypes:
1812 if bundletype not in bundle2.bundletypes:
1813 raise error.Abort(_(b'unknown bundle type specified with --type'))
1813 raise error.Abort(_(b'unknown bundle type specified with --type'))
1814 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1814 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1815
1815
1816
1816
1817 @command(b'debugignore', [], b'[FILE]')
1817 @command(b'debugignore', [], b'[FILE]')
1818 def debugignore(ui, repo, *files, **opts):
1818 def debugignore(ui, repo, *files, **opts):
1819 """display the combined ignore pattern and information about ignored files
1819 """display the combined ignore pattern and information about ignored files
1820
1820
1821 With no argument display the combined ignore pattern.
1821 With no argument display the combined ignore pattern.
1822
1822
1823 Given space separated file names, shows if the given file is ignored and
1823 Given space separated file names, shows if the given file is ignored and
1824 if so, show the ignore rule (file and line number) that matched it.
1824 if so, show the ignore rule (file and line number) that matched it.
1825 """
1825 """
1826 ignore = repo.dirstate._ignore
1826 ignore = repo.dirstate._ignore
1827 if not files:
1827 if not files:
1828 # Show all the patterns
1828 # Show all the patterns
1829 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1829 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1830 else:
1830 else:
1831 m = scmutil.match(repo[None], pats=files)
1831 m = scmutil.match(repo[None], pats=files)
1832 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1832 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1833 for f in m.files():
1833 for f in m.files():
1834 nf = util.normpath(f)
1834 nf = util.normpath(f)
1835 ignored = None
1835 ignored = None
1836 ignoredata = None
1836 ignoredata = None
1837 if nf != b'.':
1837 if nf != b'.':
1838 if ignore(nf):
1838 if ignore(nf):
1839 ignored = nf
1839 ignored = nf
1840 ignoredata = repo.dirstate._ignorefileandline(nf)
1840 ignoredata = repo.dirstate._ignorefileandline(nf)
1841 else:
1841 else:
1842 for p in pathutil.finddirs(nf):
1842 for p in pathutil.finddirs(nf):
1843 if ignore(p):
1843 if ignore(p):
1844 ignored = p
1844 ignored = p
1845 ignoredata = repo.dirstate._ignorefileandline(p)
1845 ignoredata = repo.dirstate._ignorefileandline(p)
1846 break
1846 break
1847 if ignored:
1847 if ignored:
1848 if ignored == nf:
1848 if ignored == nf:
1849 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1849 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1850 else:
1850 else:
1851 ui.write(
1851 ui.write(
1852 _(
1852 _(
1853 b"%s is ignored because of "
1853 b"%s is ignored because of "
1854 b"containing directory %s\n"
1854 b"containing directory %s\n"
1855 )
1855 )
1856 % (uipathfn(f), ignored)
1856 % (uipathfn(f), ignored)
1857 )
1857 )
1858 ignorefile, lineno, line = ignoredata
1858 ignorefile, lineno, line = ignoredata
1859 ui.write(
1859 ui.write(
1860 _(b"(ignore rule in %s, line %d: '%s')\n")
1860 _(b"(ignore rule in %s, line %d: '%s')\n")
1861 % (ignorefile, lineno, line)
1861 % (ignorefile, lineno, line)
1862 )
1862 )
1863 else:
1863 else:
1864 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1864 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1865
1865
1866
1866
1867 @command(
1867 @command(
1868 b'debugindex',
1868 b'debug-revlog-index|debugindex',
1869 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1869 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1870 _(b'-c|-m|FILE'),
1870 _(b'-c|-m|FILE'),
1871 )
1871 )
1872 def debugindex(ui, repo, file_=None, **opts):
1872 def debugindex(ui, repo, file_=None, **opts):
1873 """dump index data for a storage primitive"""
1873 """dump index data for a revlog"""
1874 opts = pycompat.byteskwargs(opts)
1874 opts = pycompat.byteskwargs(opts)
1875 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1875 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1876
1876
1877 if ui.debugflag:
1877 if ui.debugflag:
1878 shortfn = hex
1878 shortfn = hex
1879 else:
1879 else:
1880 shortfn = short
1880 shortfn = short
1881
1881
1882 idlen = 12
1882 idlen = 12
1883 for i in store:
1883 for i in store:
1884 idlen = len(shortfn(store.node(i)))
1884 idlen = len(shortfn(store.node(i)))
1885 break
1885 break
1886
1886
1887 fm = ui.formatter(b'debugindex', opts)
1887 fm = ui.formatter(b'debugindex', opts)
1888 fm.plain(
1888 fm.plain(
1889 b' rev linkrev %s %s p2\n'
1889 b' rev linkrev %s %s p2\n'
1890 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1890 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1891 )
1891 )
1892
1892
1893 for rev in store:
1893 for rev in store:
1894 node = store.node(rev)
1894 node = store.node(rev)
1895 parents = store.parents(node)
1895 parents = store.parents(node)
1896
1896
1897 fm.startitem()
1897 fm.startitem()
1898 fm.write(b'rev', b'%6d ', rev)
1898 fm.write(b'rev', b'%6d ', rev)
1899 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1899 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1900 fm.write(b'node', b'%s ', shortfn(node))
1900 fm.write(b'node', b'%s ', shortfn(node))
1901 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1901 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1902 fm.write(b'p2', b'%s', shortfn(parents[1]))
1902 fm.write(b'p2', b'%s', shortfn(parents[1]))
1903 fm.plain(b'\n')
1903 fm.plain(b'\n')
1904
1904
1905 fm.end()
1905 fm.end()
1906
1906
1907
1907
1908 @command(
1908 @command(
1909 b'debugindexdot',
1909 b'debugindexdot',
1910 cmdutil.debugrevlogopts,
1910 cmdutil.debugrevlogopts,
1911 _(b'-c|-m|FILE'),
1911 _(b'-c|-m|FILE'),
1912 optionalrepo=True,
1912 optionalrepo=True,
1913 )
1913 )
1914 def debugindexdot(ui, repo, file_=None, **opts):
1914 def debugindexdot(ui, repo, file_=None, **opts):
1915 """dump an index DAG as a graphviz dot file"""
1915 """dump an index DAG as a graphviz dot file"""
1916 opts = pycompat.byteskwargs(opts)
1916 opts = pycompat.byteskwargs(opts)
1917 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1917 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1918 ui.writenoi18n(b"digraph G {\n")
1918 ui.writenoi18n(b"digraph G {\n")
1919 for i in r:
1919 for i in r:
1920 node = r.node(i)
1920 node = r.node(i)
1921 pp = r.parents(node)
1921 pp = r.parents(node)
1922 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1922 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1923 if pp[1] != repo.nullid:
1923 if pp[1] != repo.nullid:
1924 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1924 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1925 ui.write(b"}\n")
1925 ui.write(b"}\n")
1926
1926
1927
1927
1928 @command(b'debugindexstats', [])
1928 @command(b'debugindexstats', [])
1929 def debugindexstats(ui, repo):
1929 def debugindexstats(ui, repo):
1930 """show stats related to the changelog index"""
1930 """show stats related to the changelog index"""
1931 repo.changelog.shortest(repo.nullid, 1)
1931 repo.changelog.shortest(repo.nullid, 1)
1932 index = repo.changelog.index
1932 index = repo.changelog.index
1933 if not util.safehasattr(index, b'stats'):
1933 if not util.safehasattr(index, b'stats'):
1934 raise error.Abort(_(b'debugindexstats only works with native code'))
1934 raise error.Abort(_(b'debugindexstats only works with native code'))
1935 for k, v in sorted(index.stats().items()):
1935 for k, v in sorted(index.stats().items()):
1936 ui.write(b'%s: %d\n' % (k, v))
1936 ui.write(b'%s: %d\n' % (k, v))
1937
1937
1938
1938
1939 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1939 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1940 def debuginstall(ui, **opts):
1940 def debuginstall(ui, **opts):
1941 """test Mercurial installation
1941 """test Mercurial installation
1942
1942
1943 Returns 0 on success.
1943 Returns 0 on success.
1944 """
1944 """
1945 opts = pycompat.byteskwargs(opts)
1945 opts = pycompat.byteskwargs(opts)
1946
1946
1947 problems = 0
1947 problems = 0
1948
1948
1949 fm = ui.formatter(b'debuginstall', opts)
1949 fm = ui.formatter(b'debuginstall', opts)
1950 fm.startitem()
1950 fm.startitem()
1951
1951
1952 # encoding might be unknown or wrong. don't translate these messages.
1952 # encoding might be unknown or wrong. don't translate these messages.
1953 fm.write(b'encoding', b"checking encoding (%s)...\n", encoding.encoding)
1953 fm.write(b'encoding', b"checking encoding (%s)...\n", encoding.encoding)
1954 err = None
1954 err = None
1955 try:
1955 try:
1956 codecs.lookup(pycompat.sysstr(encoding.encoding))
1956 codecs.lookup(pycompat.sysstr(encoding.encoding))
1957 except LookupError as inst:
1957 except LookupError as inst:
1958 err = stringutil.forcebytestr(inst)
1958 err = stringutil.forcebytestr(inst)
1959 problems += 1
1959 problems += 1
1960 fm.condwrite(
1960 fm.condwrite(
1961 err,
1961 err,
1962 b'encodingerror',
1962 b'encodingerror',
1963 b" %s\n (check that your locale is properly set)\n",
1963 b" %s\n (check that your locale is properly set)\n",
1964 err,
1964 err,
1965 )
1965 )
1966
1966
1967 # Python
1967 # Python
1968 pythonlib = None
1968 pythonlib = None
1969 if util.safehasattr(os, '__file__'):
1969 if util.safehasattr(os, '__file__'):
1970 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1970 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1971 elif getattr(sys, 'oxidized', False):
1971 elif getattr(sys, 'oxidized', False):
1972 pythonlib = pycompat.sysexecutable
1972 pythonlib = pycompat.sysexecutable
1973
1973
1974 fm.write(
1974 fm.write(
1975 b'pythonexe',
1975 b'pythonexe',
1976 _(b"checking Python executable (%s)\n"),
1976 _(b"checking Python executable (%s)\n"),
1977 pycompat.sysexecutable or _(b"unknown"),
1977 pycompat.sysexecutable or _(b"unknown"),
1978 )
1978 )
1979 fm.write(
1979 fm.write(
1980 b'pythonimplementation',
1980 b'pythonimplementation',
1981 _(b"checking Python implementation (%s)\n"),
1981 _(b"checking Python implementation (%s)\n"),
1982 pycompat.sysbytes(platform.python_implementation()),
1982 pycompat.sysbytes(platform.python_implementation()),
1983 )
1983 )
1984 fm.write(
1984 fm.write(
1985 b'pythonver',
1985 b'pythonver',
1986 _(b"checking Python version (%s)\n"),
1986 _(b"checking Python version (%s)\n"),
1987 (b"%d.%d.%d" % sys.version_info[:3]),
1987 (b"%d.%d.%d" % sys.version_info[:3]),
1988 )
1988 )
1989 fm.write(
1989 fm.write(
1990 b'pythonlib',
1990 b'pythonlib',
1991 _(b"checking Python lib (%s)...\n"),
1991 _(b"checking Python lib (%s)...\n"),
1992 pythonlib or _(b"unknown"),
1992 pythonlib or _(b"unknown"),
1993 )
1993 )
1994
1994
1995 try:
1995 try:
1996 from . import rustext # pytype: disable=import-error
1996 from . import rustext # pytype: disable=import-error
1997
1997
1998 rustext.__doc__ # trigger lazy import
1998 rustext.__doc__ # trigger lazy import
1999 except ImportError:
1999 except ImportError:
2000 rustext = None
2000 rustext = None
2001
2001
2002 security = set(sslutil.supportedprotocols)
2002 security = set(sslutil.supportedprotocols)
2003 if sslutil.hassni:
2003 if sslutil.hassni:
2004 security.add(b'sni')
2004 security.add(b'sni')
2005
2005
2006 fm.write(
2006 fm.write(
2007 b'pythonsecurity',
2007 b'pythonsecurity',
2008 _(b"checking Python security support (%s)\n"),
2008 _(b"checking Python security support (%s)\n"),
2009 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
2009 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
2010 )
2010 )
2011
2011
2012 # These are warnings, not errors. So don't increment problem count. This
2012 # These are warnings, not errors. So don't increment problem count. This
2013 # may change in the future.
2013 # may change in the future.
2014 if b'tls1.2' not in security:
2014 if b'tls1.2' not in security:
2015 fm.plain(
2015 fm.plain(
2016 _(
2016 _(
2017 b' TLS 1.2 not supported by Python install; '
2017 b' TLS 1.2 not supported by Python install; '
2018 b'network connections lack modern security\n'
2018 b'network connections lack modern security\n'
2019 )
2019 )
2020 )
2020 )
2021 if b'sni' not in security:
2021 if b'sni' not in security:
2022 fm.plain(
2022 fm.plain(
2023 _(
2023 _(
2024 b' SNI not supported by Python install; may have '
2024 b' SNI not supported by Python install; may have '
2025 b'connectivity issues with some servers\n'
2025 b'connectivity issues with some servers\n'
2026 )
2026 )
2027 )
2027 )
2028
2028
2029 fm.plain(
2029 fm.plain(
2030 _(
2030 _(
2031 b"checking Rust extensions (%s)\n"
2031 b"checking Rust extensions (%s)\n"
2032 % (b'missing' if rustext is None else b'installed')
2032 % (b'missing' if rustext is None else b'installed')
2033 ),
2033 ),
2034 )
2034 )
2035
2035
2036 # TODO print CA cert info
2036 # TODO print CA cert info
2037
2037
2038 # hg version
2038 # hg version
2039 hgver = util.version()
2039 hgver = util.version()
2040 fm.write(
2040 fm.write(
2041 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
2041 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
2042 )
2042 )
2043 fm.write(
2043 fm.write(
2044 b'hgverextra',
2044 b'hgverextra',
2045 _(b"checking Mercurial custom build (%s)\n"),
2045 _(b"checking Mercurial custom build (%s)\n"),
2046 b'+'.join(hgver.split(b'+')[1:]),
2046 b'+'.join(hgver.split(b'+')[1:]),
2047 )
2047 )
2048
2048
2049 # compiled modules
2049 # compiled modules
2050 hgmodules = None
2050 hgmodules = None
2051 if util.safehasattr(sys.modules[__name__], '__file__'):
2051 if util.safehasattr(sys.modules[__name__], '__file__'):
2052 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
2052 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
2053 elif getattr(sys, 'oxidized', False):
2053 elif getattr(sys, 'oxidized', False):
2054 hgmodules = pycompat.sysexecutable
2054 hgmodules = pycompat.sysexecutable
2055
2055
2056 fm.write(
2056 fm.write(
2057 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
2057 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
2058 )
2058 )
2059 fm.write(
2059 fm.write(
2060 b'hgmodules',
2060 b'hgmodules',
2061 _(b"checking installed modules (%s)...\n"),
2061 _(b"checking installed modules (%s)...\n"),
2062 hgmodules or _(b"unknown"),
2062 hgmodules or _(b"unknown"),
2063 )
2063 )
2064
2064
2065 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
2065 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
2066 rustext = rustandc # for now, that's the only case
2066 rustext = rustandc # for now, that's the only case
2067 cext = policy.policy in (b'c', b'allow') or rustandc
2067 cext = policy.policy in (b'c', b'allow') or rustandc
2068 nopure = cext or rustext
2068 nopure = cext or rustext
2069 if nopure:
2069 if nopure:
2070 err = None
2070 err = None
2071 try:
2071 try:
2072 if cext:
2072 if cext:
2073 from .cext import ( # pytype: disable=import-error
2073 from .cext import ( # pytype: disable=import-error
2074 base85,
2074 base85,
2075 bdiff,
2075 bdiff,
2076 mpatch,
2076 mpatch,
2077 osutil,
2077 osutil,
2078 )
2078 )
2079
2079
2080 # quiet pyflakes
2080 # quiet pyflakes
2081 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
2081 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
2082 if rustext:
2082 if rustext:
2083 from .rustext import ( # pytype: disable=import-error
2083 from .rustext import ( # pytype: disable=import-error
2084 ancestor,
2084 ancestor,
2085 dirstate,
2085 dirstate,
2086 )
2086 )
2087
2087
2088 dir(ancestor), dir(dirstate) # quiet pyflakes
2088 dir(ancestor), dir(dirstate) # quiet pyflakes
2089 except Exception as inst:
2089 except Exception as inst:
2090 err = stringutil.forcebytestr(inst)
2090 err = stringutil.forcebytestr(inst)
2091 problems += 1
2091 problems += 1
2092 fm.condwrite(err, b'extensionserror', b" %s\n", err)
2092 fm.condwrite(err, b'extensionserror', b" %s\n", err)
2093
2093
2094 compengines = util.compengines._engines.values()
2094 compengines = util.compengines._engines.values()
2095 fm.write(
2095 fm.write(
2096 b'compengines',
2096 b'compengines',
2097 _(b'checking registered compression engines (%s)\n'),
2097 _(b'checking registered compression engines (%s)\n'),
2098 fm.formatlist(
2098 fm.formatlist(
2099 sorted(e.name() for e in compengines),
2099 sorted(e.name() for e in compengines),
2100 name=b'compengine',
2100 name=b'compengine',
2101 fmt=b'%s',
2101 fmt=b'%s',
2102 sep=b', ',
2102 sep=b', ',
2103 ),
2103 ),
2104 )
2104 )
2105 fm.write(
2105 fm.write(
2106 b'compenginesavail',
2106 b'compenginesavail',
2107 _(b'checking available compression engines (%s)\n'),
2107 _(b'checking available compression engines (%s)\n'),
2108 fm.formatlist(
2108 fm.formatlist(
2109 sorted(e.name() for e in compengines if e.available()),
2109 sorted(e.name() for e in compengines if e.available()),
2110 name=b'compengine',
2110 name=b'compengine',
2111 fmt=b'%s',
2111 fmt=b'%s',
2112 sep=b', ',
2112 sep=b', ',
2113 ),
2113 ),
2114 )
2114 )
2115 wirecompengines = compression.compengines.supportedwireengines(
2115 wirecompengines = compression.compengines.supportedwireengines(
2116 compression.SERVERROLE
2116 compression.SERVERROLE
2117 )
2117 )
2118 fm.write(
2118 fm.write(
2119 b'compenginesserver',
2119 b'compenginesserver',
2120 _(
2120 _(
2121 b'checking available compression engines '
2121 b'checking available compression engines '
2122 b'for wire protocol (%s)\n'
2122 b'for wire protocol (%s)\n'
2123 ),
2123 ),
2124 fm.formatlist(
2124 fm.formatlist(
2125 [e.name() for e in wirecompengines if e.wireprotosupport()],
2125 [e.name() for e in wirecompengines if e.wireprotosupport()],
2126 name=b'compengine',
2126 name=b'compengine',
2127 fmt=b'%s',
2127 fmt=b'%s',
2128 sep=b', ',
2128 sep=b', ',
2129 ),
2129 ),
2130 )
2130 )
2131 re2 = b'missing'
2131 re2 = b'missing'
2132 if util._re2:
2132 if util._re2:
2133 re2 = b'available'
2133 re2 = b'available'
2134 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
2134 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
2135 fm.data(re2=bool(util._re2))
2135 fm.data(re2=bool(util._re2))
2136
2136
2137 # templates
2137 # templates
2138 p = templater.templatedir()
2138 p = templater.templatedir()
2139 fm.write(b'templatedirs', b'checking templates (%s)...\n', p or b'')
2139 fm.write(b'templatedirs', b'checking templates (%s)...\n', p or b'')
2140 fm.condwrite(not p, b'', _(b" no template directories found\n"))
2140 fm.condwrite(not p, b'', _(b" no template directories found\n"))
2141 if p:
2141 if p:
2142 (m, fp) = templater.try_open_template(b"map-cmdline.default")
2142 (m, fp) = templater.try_open_template(b"map-cmdline.default")
2143 if m:
2143 if m:
2144 # template found, check if it is working
2144 # template found, check if it is working
2145 err = None
2145 err = None
2146 try:
2146 try:
2147 templater.templater.frommapfile(m)
2147 templater.templater.frommapfile(m)
2148 except Exception as inst:
2148 except Exception as inst:
2149 err = stringutil.forcebytestr(inst)
2149 err = stringutil.forcebytestr(inst)
2150 p = None
2150 p = None
2151 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
2151 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
2152 else:
2152 else:
2153 p = None
2153 p = None
2154 fm.condwrite(
2154 fm.condwrite(
2155 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
2155 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
2156 )
2156 )
2157 fm.condwrite(
2157 fm.condwrite(
2158 not m,
2158 not m,
2159 b'defaulttemplatenotfound',
2159 b'defaulttemplatenotfound',
2160 _(b" template '%s' not found\n"),
2160 _(b" template '%s' not found\n"),
2161 b"default",
2161 b"default",
2162 )
2162 )
2163 if not p:
2163 if not p:
2164 problems += 1
2164 problems += 1
2165 fm.condwrite(
2165 fm.condwrite(
2166 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
2166 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
2167 )
2167 )
2168
2168
2169 # editor
2169 # editor
2170 editor = ui.geteditor()
2170 editor = ui.geteditor()
2171 editor = util.expandpath(editor)
2171 editor = util.expandpath(editor)
2172 editorbin = procutil.shellsplit(editor)[0]
2172 editorbin = procutil.shellsplit(editor)[0]
2173 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
2173 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
2174 cmdpath = procutil.findexe(editorbin)
2174 cmdpath = procutil.findexe(editorbin)
2175 fm.condwrite(
2175 fm.condwrite(
2176 not cmdpath and editor == b'vi',
2176 not cmdpath and editor == b'vi',
2177 b'vinotfound',
2177 b'vinotfound',
2178 _(
2178 _(
2179 b" No commit editor set and can't find %s in PATH\n"
2179 b" No commit editor set and can't find %s in PATH\n"
2180 b" (specify a commit editor in your configuration"
2180 b" (specify a commit editor in your configuration"
2181 b" file)\n"
2181 b" file)\n"
2182 ),
2182 ),
2183 not cmdpath and editor == b'vi' and editorbin,
2183 not cmdpath and editor == b'vi' and editorbin,
2184 )
2184 )
2185 fm.condwrite(
2185 fm.condwrite(
2186 not cmdpath and editor != b'vi',
2186 not cmdpath and editor != b'vi',
2187 b'editornotfound',
2187 b'editornotfound',
2188 _(
2188 _(
2189 b" Can't find editor '%s' in PATH\n"
2189 b" Can't find editor '%s' in PATH\n"
2190 b" (specify a commit editor in your configuration"
2190 b" (specify a commit editor in your configuration"
2191 b" file)\n"
2191 b" file)\n"
2192 ),
2192 ),
2193 not cmdpath and editorbin,
2193 not cmdpath and editorbin,
2194 )
2194 )
2195 if not cmdpath and editor != b'vi':
2195 if not cmdpath and editor != b'vi':
2196 problems += 1
2196 problems += 1
2197
2197
2198 # check username
2198 # check username
2199 username = None
2199 username = None
2200 err = None
2200 err = None
2201 try:
2201 try:
2202 username = ui.username()
2202 username = ui.username()
2203 except error.Abort as e:
2203 except error.Abort as e:
2204 err = e.message
2204 err = e.message
2205 problems += 1
2205 problems += 1
2206
2206
2207 fm.condwrite(
2207 fm.condwrite(
2208 username, b'username', _(b"checking username (%s)\n"), username
2208 username, b'username', _(b"checking username (%s)\n"), username
2209 )
2209 )
2210 fm.condwrite(
2210 fm.condwrite(
2211 err,
2211 err,
2212 b'usernameerror',
2212 b'usernameerror',
2213 _(
2213 _(
2214 b"checking username...\n %s\n"
2214 b"checking username...\n %s\n"
2215 b" (specify a username in your configuration file)\n"
2215 b" (specify a username in your configuration file)\n"
2216 ),
2216 ),
2217 err,
2217 err,
2218 )
2218 )
2219
2219
2220 for name, mod in extensions.extensions():
2220 for name, mod in extensions.extensions():
2221 handler = getattr(mod, 'debuginstall', None)
2221 handler = getattr(mod, 'debuginstall', None)
2222 if handler is not None:
2222 if handler is not None:
2223 problems += handler(ui, fm)
2223 problems += handler(ui, fm)
2224
2224
2225 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
2225 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
2226 if not problems:
2226 if not problems:
2227 fm.data(problems=problems)
2227 fm.data(problems=problems)
2228 fm.condwrite(
2228 fm.condwrite(
2229 problems,
2229 problems,
2230 b'problems',
2230 b'problems',
2231 _(b"%d problems detected, please check your install!\n"),
2231 _(b"%d problems detected, please check your install!\n"),
2232 problems,
2232 problems,
2233 )
2233 )
2234 fm.end()
2234 fm.end()
2235
2235
2236 return problems
2236 return problems
2237
2237
2238
2238
2239 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
2239 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
2240 def debugknown(ui, repopath, *ids, **opts):
2240 def debugknown(ui, repopath, *ids, **opts):
2241 """test whether node ids are known to a repo
2241 """test whether node ids are known to a repo
2242
2242
2243 Every ID must be a full-length hex node id string. Returns a list of 0s
2243 Every ID must be a full-length hex node id string. Returns a list of 0s
2244 and 1s indicating unknown/known.
2244 and 1s indicating unknown/known.
2245 """
2245 """
2246 opts = pycompat.byteskwargs(opts)
2246 opts = pycompat.byteskwargs(opts)
2247 repo = hg.peer(ui, opts, repopath)
2247 repo = hg.peer(ui, opts, repopath)
2248 if not repo.capable(b'known'):
2248 if not repo.capable(b'known'):
2249 raise error.Abort(b"known() not supported by target repository")
2249 raise error.Abort(b"known() not supported by target repository")
2250 flags = repo.known([bin(s) for s in ids])
2250 flags = repo.known([bin(s) for s in ids])
2251 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
2251 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
2252
2252
2253
2253
2254 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
2254 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
2255 def debuglabelcomplete(ui, repo, *args):
2255 def debuglabelcomplete(ui, repo, *args):
2256 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2256 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2257 debugnamecomplete(ui, repo, *args)
2257 debugnamecomplete(ui, repo, *args)
2258
2258
2259
2259
2260 @command(
2260 @command(
2261 b'debuglocks',
2261 b'debuglocks',
2262 [
2262 [
2263 (b'L', b'force-free-lock', None, _(b'free the store lock (DANGEROUS)')),
2263 (b'L', b'force-free-lock', None, _(b'free the store lock (DANGEROUS)')),
2264 (
2264 (
2265 b'W',
2265 b'W',
2266 b'force-free-wlock',
2266 b'force-free-wlock',
2267 None,
2267 None,
2268 _(b'free the working state lock (DANGEROUS)'),
2268 _(b'free the working state lock (DANGEROUS)'),
2269 ),
2269 ),
2270 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
2270 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
2271 (
2271 (
2272 b'S',
2272 b'S',
2273 b'set-wlock',
2273 b'set-wlock',
2274 None,
2274 None,
2275 _(b'set the working state lock until stopped'),
2275 _(b'set the working state lock until stopped'),
2276 ),
2276 ),
2277 ],
2277 ],
2278 _(b'[OPTION]...'),
2278 _(b'[OPTION]...'),
2279 )
2279 )
2280 def debuglocks(ui, repo, **opts):
2280 def debuglocks(ui, repo, **opts):
2281 """show or modify state of locks
2281 """show or modify state of locks
2282
2282
2283 By default, this command will show which locks are held. This
2283 By default, this command will show which locks are held. This
2284 includes the user and process holding the lock, the amount of time
2284 includes the user and process holding the lock, the amount of time
2285 the lock has been held, and the machine name where the process is
2285 the lock has been held, and the machine name where the process is
2286 running if it's not local.
2286 running if it's not local.
2287
2287
2288 Locks protect the integrity of Mercurial's data, so should be
2288 Locks protect the integrity of Mercurial's data, so should be
2289 treated with care. System crashes or other interruptions may cause
2289 treated with care. System crashes or other interruptions may cause
2290 locks to not be properly released, though Mercurial will usually
2290 locks to not be properly released, though Mercurial will usually
2291 detect and remove such stale locks automatically.
2291 detect and remove such stale locks automatically.
2292
2292
2293 However, detecting stale locks may not always be possible (for
2293 However, detecting stale locks may not always be possible (for
2294 instance, on a shared filesystem). Removing locks may also be
2294 instance, on a shared filesystem). Removing locks may also be
2295 blocked by filesystem permissions.
2295 blocked by filesystem permissions.
2296
2296
2297 Setting a lock will prevent other commands from changing the data.
2297 Setting a lock will prevent other commands from changing the data.
2298 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
2298 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
2299 The set locks are removed when the command exits.
2299 The set locks are removed when the command exits.
2300
2300
2301 Returns 0 if no locks are held.
2301 Returns 0 if no locks are held.
2302
2302
2303 """
2303 """
2304
2304
2305 if opts.get('force_free_lock'):
2305 if opts.get('force_free_lock'):
2306 repo.svfs.tryunlink(b'lock')
2306 repo.svfs.tryunlink(b'lock')
2307 if opts.get('force_free_wlock'):
2307 if opts.get('force_free_wlock'):
2308 repo.vfs.tryunlink(b'wlock')
2308 repo.vfs.tryunlink(b'wlock')
2309 if opts.get('force_free_lock') or opts.get('force_free_wlock'):
2309 if opts.get('force_free_lock') or opts.get('force_free_wlock'):
2310 return 0
2310 return 0
2311
2311
2312 locks = []
2312 locks = []
2313 try:
2313 try:
2314 if opts.get('set_wlock'):
2314 if opts.get('set_wlock'):
2315 try:
2315 try:
2316 locks.append(repo.wlock(False))
2316 locks.append(repo.wlock(False))
2317 except error.LockHeld:
2317 except error.LockHeld:
2318 raise error.Abort(_(b'wlock is already held'))
2318 raise error.Abort(_(b'wlock is already held'))
2319 if opts.get('set_lock'):
2319 if opts.get('set_lock'):
2320 try:
2320 try:
2321 locks.append(repo.lock(False))
2321 locks.append(repo.lock(False))
2322 except error.LockHeld:
2322 except error.LockHeld:
2323 raise error.Abort(_(b'lock is already held'))
2323 raise error.Abort(_(b'lock is already held'))
2324 if len(locks):
2324 if len(locks):
2325 try:
2325 try:
2326 if ui.interactive():
2326 if ui.interactive():
2327 prompt = _(b"ready to release the lock (y)? $$ &Yes")
2327 prompt = _(b"ready to release the lock (y)? $$ &Yes")
2328 ui.promptchoice(prompt)
2328 ui.promptchoice(prompt)
2329 else:
2329 else:
2330 msg = b"%d locks held, waiting for signal\n"
2330 msg = b"%d locks held, waiting for signal\n"
2331 msg %= len(locks)
2331 msg %= len(locks)
2332 ui.status(msg)
2332 ui.status(msg)
2333 while True: # XXX wait for a signal
2333 while True: # XXX wait for a signal
2334 time.sleep(0.1)
2334 time.sleep(0.1)
2335 except KeyboardInterrupt:
2335 except KeyboardInterrupt:
2336 msg = b"signal-received releasing locks\n"
2336 msg = b"signal-received releasing locks\n"
2337 ui.status(msg)
2337 ui.status(msg)
2338 return 0
2338 return 0
2339 finally:
2339 finally:
2340 release(*locks)
2340 release(*locks)
2341
2341
2342 now = time.time()
2342 now = time.time()
2343 held = 0
2343 held = 0
2344
2344
2345 def report(vfs, name, method):
2345 def report(vfs, name, method):
2346 # this causes stale locks to get reaped for more accurate reporting
2346 # this causes stale locks to get reaped for more accurate reporting
2347 try:
2347 try:
2348 l = method(False)
2348 l = method(False)
2349 except error.LockHeld:
2349 except error.LockHeld:
2350 l = None
2350 l = None
2351
2351
2352 if l:
2352 if l:
2353 l.release()
2353 l.release()
2354 else:
2354 else:
2355 try:
2355 try:
2356 st = vfs.lstat(name)
2356 st = vfs.lstat(name)
2357 age = now - st[stat.ST_MTIME]
2357 age = now - st[stat.ST_MTIME]
2358 user = util.username(st.st_uid)
2358 user = util.username(st.st_uid)
2359 locker = vfs.readlock(name)
2359 locker = vfs.readlock(name)
2360 if b":" in locker:
2360 if b":" in locker:
2361 host, pid = locker.split(b':')
2361 host, pid = locker.split(b':')
2362 if host == socket.gethostname():
2362 if host == socket.gethostname():
2363 locker = b'user %s, process %s' % (user or b'None', pid)
2363 locker = b'user %s, process %s' % (user or b'None', pid)
2364 else:
2364 else:
2365 locker = b'user %s, process %s, host %s' % (
2365 locker = b'user %s, process %s, host %s' % (
2366 user or b'None',
2366 user or b'None',
2367 pid,
2367 pid,
2368 host,
2368 host,
2369 )
2369 )
2370 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
2370 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
2371 return 1
2371 return 1
2372 except OSError as e:
2372 except OSError as e:
2373 if e.errno != errno.ENOENT:
2373 if e.errno != errno.ENOENT:
2374 raise
2374 raise
2375
2375
2376 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
2376 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
2377 return 0
2377 return 0
2378
2378
2379 held += report(repo.svfs, b"lock", repo.lock)
2379 held += report(repo.svfs, b"lock", repo.lock)
2380 held += report(repo.vfs, b"wlock", repo.wlock)
2380 held += report(repo.vfs, b"wlock", repo.wlock)
2381
2381
2382 return held
2382 return held
2383
2383
2384
2384
2385 @command(
2385 @command(
2386 b'debugmanifestfulltextcache',
2386 b'debugmanifestfulltextcache',
2387 [
2387 [
2388 (b'', b'clear', False, _(b'clear the cache')),
2388 (b'', b'clear', False, _(b'clear the cache')),
2389 (
2389 (
2390 b'a',
2390 b'a',
2391 b'add',
2391 b'add',
2392 [],
2392 [],
2393 _(b'add the given manifest nodes to the cache'),
2393 _(b'add the given manifest nodes to the cache'),
2394 _(b'NODE'),
2394 _(b'NODE'),
2395 ),
2395 ),
2396 ],
2396 ],
2397 b'',
2397 b'',
2398 )
2398 )
2399 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
2399 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
2400 """show, clear or amend the contents of the manifest fulltext cache"""
2400 """show, clear or amend the contents of the manifest fulltext cache"""
2401
2401
2402 def getcache():
2402 def getcache():
2403 r = repo.manifestlog.getstorage(b'')
2403 r = repo.manifestlog.getstorage(b'')
2404 try:
2404 try:
2405 return r._fulltextcache
2405 return r._fulltextcache
2406 except AttributeError:
2406 except AttributeError:
2407 msg = _(
2407 msg = _(
2408 b"Current revlog implementation doesn't appear to have a "
2408 b"Current revlog implementation doesn't appear to have a "
2409 b"manifest fulltext cache\n"
2409 b"manifest fulltext cache\n"
2410 )
2410 )
2411 raise error.Abort(msg)
2411 raise error.Abort(msg)
2412
2412
2413 if opts.get('clear'):
2413 if opts.get('clear'):
2414 with repo.wlock():
2414 with repo.wlock():
2415 cache = getcache()
2415 cache = getcache()
2416 cache.clear(clear_persisted_data=True)
2416 cache.clear(clear_persisted_data=True)
2417 return
2417 return
2418
2418
2419 if add:
2419 if add:
2420 with repo.wlock():
2420 with repo.wlock():
2421 m = repo.manifestlog
2421 m = repo.manifestlog
2422 store = m.getstorage(b'')
2422 store = m.getstorage(b'')
2423 for n in add:
2423 for n in add:
2424 try:
2424 try:
2425 manifest = m[store.lookup(n)]
2425 manifest = m[store.lookup(n)]
2426 except error.LookupError as e:
2426 except error.LookupError as e:
2427 raise error.Abort(
2427 raise error.Abort(
2428 bytes(e), hint=b"Check your manifest node id"
2428 bytes(e), hint=b"Check your manifest node id"
2429 )
2429 )
2430 manifest.read() # stores revisision in cache too
2430 manifest.read() # stores revisision in cache too
2431 return
2431 return
2432
2432
2433 cache = getcache()
2433 cache = getcache()
2434 if not len(cache):
2434 if not len(cache):
2435 ui.write(_(b'cache empty\n'))
2435 ui.write(_(b'cache empty\n'))
2436 else:
2436 else:
2437 ui.write(
2437 ui.write(
2438 _(
2438 _(
2439 b'cache contains %d manifest entries, in order of most to '
2439 b'cache contains %d manifest entries, in order of most to '
2440 b'least recent:\n'
2440 b'least recent:\n'
2441 )
2441 )
2442 % (len(cache),)
2442 % (len(cache),)
2443 )
2443 )
2444 totalsize = 0
2444 totalsize = 0
2445 for nodeid in cache:
2445 for nodeid in cache:
2446 # Use cache.get to not update the LRU order
2446 # Use cache.get to not update the LRU order
2447 data = cache.peek(nodeid)
2447 data = cache.peek(nodeid)
2448 size = len(data)
2448 size = len(data)
2449 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
2449 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
2450 ui.write(
2450 ui.write(
2451 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
2451 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
2452 )
2452 )
2453 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
2453 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
2454 ui.write(
2454 ui.write(
2455 _(b'total cache data size %s, on-disk %s\n')
2455 _(b'total cache data size %s, on-disk %s\n')
2456 % (util.bytecount(totalsize), util.bytecount(ondisk))
2456 % (util.bytecount(totalsize), util.bytecount(ondisk))
2457 )
2457 )
2458
2458
2459
2459
2460 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
2460 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
2461 def debugmergestate(ui, repo, *args, **opts):
2461 def debugmergestate(ui, repo, *args, **opts):
2462 """print merge state
2462 """print merge state
2463
2463
2464 Use --verbose to print out information about whether v1 or v2 merge state
2464 Use --verbose to print out information about whether v1 or v2 merge state
2465 was chosen."""
2465 was chosen."""
2466
2466
2467 if ui.verbose:
2467 if ui.verbose:
2468 ms = mergestatemod.mergestate(repo)
2468 ms = mergestatemod.mergestate(repo)
2469
2469
2470 # sort so that reasonable information is on top
2470 # sort so that reasonable information is on top
2471 v1records = ms._readrecordsv1()
2471 v1records = ms._readrecordsv1()
2472 v2records = ms._readrecordsv2()
2472 v2records = ms._readrecordsv2()
2473
2473
2474 if not v1records and not v2records:
2474 if not v1records and not v2records:
2475 pass
2475 pass
2476 elif not v2records:
2476 elif not v2records:
2477 ui.writenoi18n(b'no version 2 merge state\n')
2477 ui.writenoi18n(b'no version 2 merge state\n')
2478 elif ms._v1v2match(v1records, v2records):
2478 elif ms._v1v2match(v1records, v2records):
2479 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
2479 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
2480 else:
2480 else:
2481 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
2481 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
2482
2482
2483 opts = pycompat.byteskwargs(opts)
2483 opts = pycompat.byteskwargs(opts)
2484 if not opts[b'template']:
2484 if not opts[b'template']:
2485 opts[b'template'] = (
2485 opts[b'template'] = (
2486 b'{if(commits, "", "no merge state found\n")}'
2486 b'{if(commits, "", "no merge state found\n")}'
2487 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
2487 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
2488 b'{files % "file: {path} (state \\"{state}\\")\n'
2488 b'{files % "file: {path} (state \\"{state}\\")\n'
2489 b'{if(local_path, "'
2489 b'{if(local_path, "'
2490 b' local path: {local_path} (hash {local_key}, flags \\"{local_flags}\\")\n'
2490 b' local path: {local_path} (hash {local_key}, flags \\"{local_flags}\\")\n'
2491 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
2491 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
2492 b' other path: {other_path} (node {other_node})\n'
2492 b' other path: {other_path} (node {other_node})\n'
2493 b'")}'
2493 b'")}'
2494 b'{if(rename_side, "'
2494 b'{if(rename_side, "'
2495 b' rename side: {rename_side}\n'
2495 b' rename side: {rename_side}\n'
2496 b' renamed path: {renamed_path}\n'
2496 b' renamed path: {renamed_path}\n'
2497 b'")}'
2497 b'")}'
2498 b'{extras % " extra: {key} = {value}\n"}'
2498 b'{extras % " extra: {key} = {value}\n"}'
2499 b'"}'
2499 b'"}'
2500 b'{extras % "extra: {file} ({key} = {value})\n"}'
2500 b'{extras % "extra: {file} ({key} = {value})\n"}'
2501 )
2501 )
2502
2502
2503 ms = mergestatemod.mergestate.read(repo)
2503 ms = mergestatemod.mergestate.read(repo)
2504
2504
2505 fm = ui.formatter(b'debugmergestate', opts)
2505 fm = ui.formatter(b'debugmergestate', opts)
2506 fm.startitem()
2506 fm.startitem()
2507
2507
2508 fm_commits = fm.nested(b'commits')
2508 fm_commits = fm.nested(b'commits')
2509 if ms.active():
2509 if ms.active():
2510 for name, node, label_index in (
2510 for name, node, label_index in (
2511 (b'local', ms.local, 0),
2511 (b'local', ms.local, 0),
2512 (b'other', ms.other, 1),
2512 (b'other', ms.other, 1),
2513 ):
2513 ):
2514 fm_commits.startitem()
2514 fm_commits.startitem()
2515 fm_commits.data(name=name)
2515 fm_commits.data(name=name)
2516 fm_commits.data(node=hex(node))
2516 fm_commits.data(node=hex(node))
2517 if ms._labels and len(ms._labels) > label_index:
2517 if ms._labels and len(ms._labels) > label_index:
2518 fm_commits.data(label=ms._labels[label_index])
2518 fm_commits.data(label=ms._labels[label_index])
2519 fm_commits.end()
2519 fm_commits.end()
2520
2520
2521 fm_files = fm.nested(b'files')
2521 fm_files = fm.nested(b'files')
2522 if ms.active():
2522 if ms.active():
2523 for f in ms:
2523 for f in ms:
2524 fm_files.startitem()
2524 fm_files.startitem()
2525 fm_files.data(path=f)
2525 fm_files.data(path=f)
2526 state = ms._state[f]
2526 state = ms._state[f]
2527 fm_files.data(state=state[0])
2527 fm_files.data(state=state[0])
2528 if state[0] in (
2528 if state[0] in (
2529 mergestatemod.MERGE_RECORD_UNRESOLVED,
2529 mergestatemod.MERGE_RECORD_UNRESOLVED,
2530 mergestatemod.MERGE_RECORD_RESOLVED,
2530 mergestatemod.MERGE_RECORD_RESOLVED,
2531 ):
2531 ):
2532 fm_files.data(local_key=state[1])
2532 fm_files.data(local_key=state[1])
2533 fm_files.data(local_path=state[2])
2533 fm_files.data(local_path=state[2])
2534 fm_files.data(ancestor_path=state[3])
2534 fm_files.data(ancestor_path=state[3])
2535 fm_files.data(ancestor_node=state[4])
2535 fm_files.data(ancestor_node=state[4])
2536 fm_files.data(other_path=state[5])
2536 fm_files.data(other_path=state[5])
2537 fm_files.data(other_node=state[6])
2537 fm_files.data(other_node=state[6])
2538 fm_files.data(local_flags=state[7])
2538 fm_files.data(local_flags=state[7])
2539 elif state[0] in (
2539 elif state[0] in (
2540 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
2540 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
2541 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
2541 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
2542 ):
2542 ):
2543 fm_files.data(renamed_path=state[1])
2543 fm_files.data(renamed_path=state[1])
2544 fm_files.data(rename_side=state[2])
2544 fm_files.data(rename_side=state[2])
2545 fm_extras = fm_files.nested(b'extras')
2545 fm_extras = fm_files.nested(b'extras')
2546 for k, v in sorted(ms.extras(f).items()):
2546 for k, v in sorted(ms.extras(f).items()):
2547 fm_extras.startitem()
2547 fm_extras.startitem()
2548 fm_extras.data(key=k)
2548 fm_extras.data(key=k)
2549 fm_extras.data(value=v)
2549 fm_extras.data(value=v)
2550 fm_extras.end()
2550 fm_extras.end()
2551
2551
2552 fm_files.end()
2552 fm_files.end()
2553
2553
2554 fm_extras = fm.nested(b'extras')
2554 fm_extras = fm.nested(b'extras')
2555 for f, d in sorted(ms.allextras().items()):
2555 for f, d in sorted(ms.allextras().items()):
2556 if f in ms:
2556 if f in ms:
2557 # If file is in mergestate, we have already processed it's extras
2557 # If file is in mergestate, we have already processed it's extras
2558 continue
2558 continue
2559 for k, v in d.items():
2559 for k, v in d.items():
2560 fm_extras.startitem()
2560 fm_extras.startitem()
2561 fm_extras.data(file=f)
2561 fm_extras.data(file=f)
2562 fm_extras.data(key=k)
2562 fm_extras.data(key=k)
2563 fm_extras.data(value=v)
2563 fm_extras.data(value=v)
2564 fm_extras.end()
2564 fm_extras.end()
2565
2565
2566 fm.end()
2566 fm.end()
2567
2567
2568
2568
2569 @command(b'debugnamecomplete', [], _(b'NAME...'))
2569 @command(b'debugnamecomplete', [], _(b'NAME...'))
2570 def debugnamecomplete(ui, repo, *args):
2570 def debugnamecomplete(ui, repo, *args):
2571 '''complete "names" - tags, open branch names, bookmark names'''
2571 '''complete "names" - tags, open branch names, bookmark names'''
2572
2572
2573 names = set()
2573 names = set()
2574 # since we previously only listed open branches, we will handle that
2574 # since we previously only listed open branches, we will handle that
2575 # specially (after this for loop)
2575 # specially (after this for loop)
2576 for name, ns in repo.names.items():
2576 for name, ns in repo.names.items():
2577 if name != b'branches':
2577 if name != b'branches':
2578 names.update(ns.listnames(repo))
2578 names.update(ns.listnames(repo))
2579 names.update(
2579 names.update(
2580 tag
2580 tag
2581 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2581 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2582 if not closed
2582 if not closed
2583 )
2583 )
2584 completions = set()
2584 completions = set()
2585 if not args:
2585 if not args:
2586 args = [b'']
2586 args = [b'']
2587 for a in args:
2587 for a in args:
2588 completions.update(n for n in names if n.startswith(a))
2588 completions.update(n for n in names if n.startswith(a))
2589 ui.write(b'\n'.join(sorted(completions)))
2589 ui.write(b'\n'.join(sorted(completions)))
2590 ui.write(b'\n')
2590 ui.write(b'\n')
2591
2591
2592
2592
2593 @command(
2593 @command(
2594 b'debugnodemap',
2594 b'debugnodemap',
2595 [
2595 [
2596 (
2596 (
2597 b'',
2597 b'',
2598 b'dump-new',
2598 b'dump-new',
2599 False,
2599 False,
2600 _(b'write a (new) persistent binary nodemap on stdout'),
2600 _(b'write a (new) persistent binary nodemap on stdout'),
2601 ),
2601 ),
2602 (b'', b'dump-disk', False, _(b'dump on-disk data on stdout')),
2602 (b'', b'dump-disk', False, _(b'dump on-disk data on stdout')),
2603 (
2603 (
2604 b'',
2604 b'',
2605 b'check',
2605 b'check',
2606 False,
2606 False,
2607 _(b'check that the data on disk data are correct.'),
2607 _(b'check that the data on disk data are correct.'),
2608 ),
2608 ),
2609 (
2609 (
2610 b'',
2610 b'',
2611 b'metadata',
2611 b'metadata',
2612 False,
2612 False,
2613 _(b'display the on disk meta data for the nodemap'),
2613 _(b'display the on disk meta data for the nodemap'),
2614 ),
2614 ),
2615 ],
2615 ],
2616 )
2616 )
2617 def debugnodemap(ui, repo, **opts):
2617 def debugnodemap(ui, repo, **opts):
2618 """write and inspect on disk nodemap"""
2618 """write and inspect on disk nodemap"""
2619 if opts['dump_new']:
2619 if opts['dump_new']:
2620 unfi = repo.unfiltered()
2620 unfi = repo.unfiltered()
2621 cl = unfi.changelog
2621 cl = unfi.changelog
2622 if util.safehasattr(cl.index, "nodemap_data_all"):
2622 if util.safehasattr(cl.index, "nodemap_data_all"):
2623 data = cl.index.nodemap_data_all()
2623 data = cl.index.nodemap_data_all()
2624 else:
2624 else:
2625 data = nodemap.persistent_data(cl.index)
2625 data = nodemap.persistent_data(cl.index)
2626 ui.write(data)
2626 ui.write(data)
2627 elif opts['dump_disk']:
2627 elif opts['dump_disk']:
2628 unfi = repo.unfiltered()
2628 unfi = repo.unfiltered()
2629 cl = unfi.changelog
2629 cl = unfi.changelog
2630 nm_data = nodemap.persisted_data(cl)
2630 nm_data = nodemap.persisted_data(cl)
2631 if nm_data is not None:
2631 if nm_data is not None:
2632 docket, data = nm_data
2632 docket, data = nm_data
2633 ui.write(data[:])
2633 ui.write(data[:])
2634 elif opts['check']:
2634 elif opts['check']:
2635 unfi = repo.unfiltered()
2635 unfi = repo.unfiltered()
2636 cl = unfi.changelog
2636 cl = unfi.changelog
2637 nm_data = nodemap.persisted_data(cl)
2637 nm_data = nodemap.persisted_data(cl)
2638 if nm_data is not None:
2638 if nm_data is not None:
2639 docket, data = nm_data
2639 docket, data = nm_data
2640 return nodemap.check_data(ui, cl.index, data)
2640 return nodemap.check_data(ui, cl.index, data)
2641 elif opts['metadata']:
2641 elif opts['metadata']:
2642 unfi = repo.unfiltered()
2642 unfi = repo.unfiltered()
2643 cl = unfi.changelog
2643 cl = unfi.changelog
2644 nm_data = nodemap.persisted_data(cl)
2644 nm_data = nodemap.persisted_data(cl)
2645 if nm_data is not None:
2645 if nm_data is not None:
2646 docket, data = nm_data
2646 docket, data = nm_data
2647 ui.write((b"uid: %s\n") % docket.uid)
2647 ui.write((b"uid: %s\n") % docket.uid)
2648 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2648 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2649 ui.write((b"tip-node: %s\n") % hex(docket.tip_node))
2649 ui.write((b"tip-node: %s\n") % hex(docket.tip_node))
2650 ui.write((b"data-length: %d\n") % docket.data_length)
2650 ui.write((b"data-length: %d\n") % docket.data_length)
2651 ui.write((b"data-unused: %d\n") % docket.data_unused)
2651 ui.write((b"data-unused: %d\n") % docket.data_unused)
2652 unused_perc = docket.data_unused * 100.0 / docket.data_length
2652 unused_perc = docket.data_unused * 100.0 / docket.data_length
2653 ui.write((b"data-unused: %2.3f%%\n") % unused_perc)
2653 ui.write((b"data-unused: %2.3f%%\n") % unused_perc)
2654
2654
2655
2655
2656 @command(
2656 @command(
2657 b'debugobsolete',
2657 b'debugobsolete',
2658 [
2658 [
2659 (b'', b'flags', 0, _(b'markers flag')),
2659 (b'', b'flags', 0, _(b'markers flag')),
2660 (
2660 (
2661 b'',
2661 b'',
2662 b'record-parents',
2662 b'record-parents',
2663 False,
2663 False,
2664 _(b'record parent information for the precursor'),
2664 _(b'record parent information for the precursor'),
2665 ),
2665 ),
2666 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2666 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2667 (
2667 (
2668 b'',
2668 b'',
2669 b'exclusive',
2669 b'exclusive',
2670 False,
2670 False,
2671 _(b'restrict display to markers only relevant to REV'),
2671 _(b'restrict display to markers only relevant to REV'),
2672 ),
2672 ),
2673 (b'', b'index', False, _(b'display index of the marker')),
2673 (b'', b'index', False, _(b'display index of the marker')),
2674 (b'', b'delete', [], _(b'delete markers specified by indices')),
2674 (b'', b'delete', [], _(b'delete markers specified by indices')),
2675 ]
2675 ]
2676 + cmdutil.commitopts2
2676 + cmdutil.commitopts2
2677 + cmdutil.formatteropts,
2677 + cmdutil.formatteropts,
2678 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2678 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2679 )
2679 )
2680 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2680 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2681 """create arbitrary obsolete marker
2681 """create arbitrary obsolete marker
2682
2682
2683 With no arguments, displays the list of obsolescence markers."""
2683 With no arguments, displays the list of obsolescence markers."""
2684
2684
2685 opts = pycompat.byteskwargs(opts)
2685 opts = pycompat.byteskwargs(opts)
2686
2686
2687 def parsenodeid(s):
2687 def parsenodeid(s):
2688 try:
2688 try:
2689 # We do not use revsingle/revrange functions here to accept
2689 # We do not use revsingle/revrange functions here to accept
2690 # arbitrary node identifiers, possibly not present in the
2690 # arbitrary node identifiers, possibly not present in the
2691 # local repository.
2691 # local repository.
2692 n = bin(s)
2692 n = bin(s)
2693 if len(n) != repo.nodeconstants.nodelen:
2693 if len(n) != repo.nodeconstants.nodelen:
2694 raise ValueError
2694 raise ValueError
2695 return n
2695 return n
2696 except ValueError:
2696 except ValueError:
2697 raise error.InputError(
2697 raise error.InputError(
2698 b'changeset references must be full hexadecimal '
2698 b'changeset references must be full hexadecimal '
2699 b'node identifiers'
2699 b'node identifiers'
2700 )
2700 )
2701
2701
2702 if opts.get(b'delete'):
2702 if opts.get(b'delete'):
2703 indices = []
2703 indices = []
2704 for v in opts.get(b'delete'):
2704 for v in opts.get(b'delete'):
2705 try:
2705 try:
2706 indices.append(int(v))
2706 indices.append(int(v))
2707 except ValueError:
2707 except ValueError:
2708 raise error.InputError(
2708 raise error.InputError(
2709 _(b'invalid index value: %r') % v,
2709 _(b'invalid index value: %r') % v,
2710 hint=_(b'use integers for indices'),
2710 hint=_(b'use integers for indices'),
2711 )
2711 )
2712
2712
2713 if repo.currenttransaction():
2713 if repo.currenttransaction():
2714 raise error.Abort(
2714 raise error.Abort(
2715 _(b'cannot delete obsmarkers in the middle of transaction.')
2715 _(b'cannot delete obsmarkers in the middle of transaction.')
2716 )
2716 )
2717
2717
2718 with repo.lock():
2718 with repo.lock():
2719 n = repair.deleteobsmarkers(repo.obsstore, indices)
2719 n = repair.deleteobsmarkers(repo.obsstore, indices)
2720 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2720 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2721
2721
2722 return
2722 return
2723
2723
2724 if precursor is not None:
2724 if precursor is not None:
2725 if opts[b'rev']:
2725 if opts[b'rev']:
2726 raise error.InputError(
2726 raise error.InputError(
2727 b'cannot select revision when creating marker'
2727 b'cannot select revision when creating marker'
2728 )
2728 )
2729 metadata = {}
2729 metadata = {}
2730 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2730 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2731 succs = tuple(parsenodeid(succ) for succ in successors)
2731 succs = tuple(parsenodeid(succ) for succ in successors)
2732 l = repo.lock()
2732 l = repo.lock()
2733 try:
2733 try:
2734 tr = repo.transaction(b'debugobsolete')
2734 tr = repo.transaction(b'debugobsolete')
2735 try:
2735 try:
2736 date = opts.get(b'date')
2736 date = opts.get(b'date')
2737 if date:
2737 if date:
2738 date = dateutil.parsedate(date)
2738 date = dateutil.parsedate(date)
2739 else:
2739 else:
2740 date = None
2740 date = None
2741 prec = parsenodeid(precursor)
2741 prec = parsenodeid(precursor)
2742 parents = None
2742 parents = None
2743 if opts[b'record_parents']:
2743 if opts[b'record_parents']:
2744 if prec not in repo.unfiltered():
2744 if prec not in repo.unfiltered():
2745 raise error.Abort(
2745 raise error.Abort(
2746 b'cannot used --record-parents on '
2746 b'cannot used --record-parents on '
2747 b'unknown changesets'
2747 b'unknown changesets'
2748 )
2748 )
2749 parents = repo.unfiltered()[prec].parents()
2749 parents = repo.unfiltered()[prec].parents()
2750 parents = tuple(p.node() for p in parents)
2750 parents = tuple(p.node() for p in parents)
2751 repo.obsstore.create(
2751 repo.obsstore.create(
2752 tr,
2752 tr,
2753 prec,
2753 prec,
2754 succs,
2754 succs,
2755 opts[b'flags'],
2755 opts[b'flags'],
2756 parents=parents,
2756 parents=parents,
2757 date=date,
2757 date=date,
2758 metadata=metadata,
2758 metadata=metadata,
2759 ui=ui,
2759 ui=ui,
2760 )
2760 )
2761 tr.close()
2761 tr.close()
2762 except ValueError as exc:
2762 except ValueError as exc:
2763 raise error.Abort(
2763 raise error.Abort(
2764 _(b'bad obsmarker input: %s') % stringutil.forcebytestr(exc)
2764 _(b'bad obsmarker input: %s') % stringutil.forcebytestr(exc)
2765 )
2765 )
2766 finally:
2766 finally:
2767 tr.release()
2767 tr.release()
2768 finally:
2768 finally:
2769 l.release()
2769 l.release()
2770 else:
2770 else:
2771 if opts[b'rev']:
2771 if opts[b'rev']:
2772 revs = logcmdutil.revrange(repo, opts[b'rev'])
2772 revs = logcmdutil.revrange(repo, opts[b'rev'])
2773 nodes = [repo[r].node() for r in revs]
2773 nodes = [repo[r].node() for r in revs]
2774 markers = list(
2774 markers = list(
2775 obsutil.getmarkers(
2775 obsutil.getmarkers(
2776 repo, nodes=nodes, exclusive=opts[b'exclusive']
2776 repo, nodes=nodes, exclusive=opts[b'exclusive']
2777 )
2777 )
2778 )
2778 )
2779 markers.sort(key=lambda x: x._data)
2779 markers.sort(key=lambda x: x._data)
2780 else:
2780 else:
2781 markers = obsutil.getmarkers(repo)
2781 markers = obsutil.getmarkers(repo)
2782
2782
2783 markerstoiter = markers
2783 markerstoiter = markers
2784 isrelevant = lambda m: True
2784 isrelevant = lambda m: True
2785 if opts.get(b'rev') and opts.get(b'index'):
2785 if opts.get(b'rev') and opts.get(b'index'):
2786 markerstoiter = obsutil.getmarkers(repo)
2786 markerstoiter = obsutil.getmarkers(repo)
2787 markerset = set(markers)
2787 markerset = set(markers)
2788 isrelevant = lambda m: m in markerset
2788 isrelevant = lambda m: m in markerset
2789
2789
2790 fm = ui.formatter(b'debugobsolete', opts)
2790 fm = ui.formatter(b'debugobsolete', opts)
2791 for i, m in enumerate(markerstoiter):
2791 for i, m in enumerate(markerstoiter):
2792 if not isrelevant(m):
2792 if not isrelevant(m):
2793 # marker can be irrelevant when we're iterating over a set
2793 # marker can be irrelevant when we're iterating over a set
2794 # of markers (markerstoiter) which is bigger than the set
2794 # of markers (markerstoiter) which is bigger than the set
2795 # of markers we want to display (markers)
2795 # of markers we want to display (markers)
2796 # this can happen if both --index and --rev options are
2796 # this can happen if both --index and --rev options are
2797 # provided and thus we need to iterate over all of the markers
2797 # provided and thus we need to iterate over all of the markers
2798 # to get the correct indices, but only display the ones that
2798 # to get the correct indices, but only display the ones that
2799 # are relevant to --rev value
2799 # are relevant to --rev value
2800 continue
2800 continue
2801 fm.startitem()
2801 fm.startitem()
2802 ind = i if opts.get(b'index') else None
2802 ind = i if opts.get(b'index') else None
2803 cmdutil.showmarker(fm, m, index=ind)
2803 cmdutil.showmarker(fm, m, index=ind)
2804 fm.end()
2804 fm.end()
2805
2805
2806
2806
2807 @command(
2807 @command(
2808 b'debugp1copies',
2808 b'debugp1copies',
2809 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2809 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2810 _(b'[-r REV]'),
2810 _(b'[-r REV]'),
2811 )
2811 )
2812 def debugp1copies(ui, repo, **opts):
2812 def debugp1copies(ui, repo, **opts):
2813 """dump copy information compared to p1"""
2813 """dump copy information compared to p1"""
2814
2814
2815 opts = pycompat.byteskwargs(opts)
2815 opts = pycompat.byteskwargs(opts)
2816 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2816 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2817 for dst, src in ctx.p1copies().items():
2817 for dst, src in ctx.p1copies().items():
2818 ui.write(b'%s -> %s\n' % (src, dst))
2818 ui.write(b'%s -> %s\n' % (src, dst))
2819
2819
2820
2820
2821 @command(
2821 @command(
2822 b'debugp2copies',
2822 b'debugp2copies',
2823 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2823 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2824 _(b'[-r REV]'),
2824 _(b'[-r REV]'),
2825 )
2825 )
2826 def debugp1copies(ui, repo, **opts):
2826 def debugp1copies(ui, repo, **opts):
2827 """dump copy information compared to p2"""
2827 """dump copy information compared to p2"""
2828
2828
2829 opts = pycompat.byteskwargs(opts)
2829 opts = pycompat.byteskwargs(opts)
2830 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2830 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2831 for dst, src in ctx.p2copies().items():
2831 for dst, src in ctx.p2copies().items():
2832 ui.write(b'%s -> %s\n' % (src, dst))
2832 ui.write(b'%s -> %s\n' % (src, dst))
2833
2833
2834
2834
2835 @command(
2835 @command(
2836 b'debugpathcomplete',
2836 b'debugpathcomplete',
2837 [
2837 [
2838 (b'f', b'full', None, _(b'complete an entire path')),
2838 (b'f', b'full', None, _(b'complete an entire path')),
2839 (b'n', b'normal', None, _(b'show only normal files')),
2839 (b'n', b'normal', None, _(b'show only normal files')),
2840 (b'a', b'added', None, _(b'show only added files')),
2840 (b'a', b'added', None, _(b'show only added files')),
2841 (b'r', b'removed', None, _(b'show only removed files')),
2841 (b'r', b'removed', None, _(b'show only removed files')),
2842 ],
2842 ],
2843 _(b'FILESPEC...'),
2843 _(b'FILESPEC...'),
2844 )
2844 )
2845 def debugpathcomplete(ui, repo, *specs, **opts):
2845 def debugpathcomplete(ui, repo, *specs, **opts):
2846 """complete part or all of a tracked path
2846 """complete part or all of a tracked path
2847
2847
2848 This command supports shells that offer path name completion. It
2848 This command supports shells that offer path name completion. It
2849 currently completes only files already known to the dirstate.
2849 currently completes only files already known to the dirstate.
2850
2850
2851 Completion extends only to the next path segment unless
2851 Completion extends only to the next path segment unless
2852 --full is specified, in which case entire paths are used."""
2852 --full is specified, in which case entire paths are used."""
2853
2853
2854 def complete(path, acceptable):
2854 def complete(path, acceptable):
2855 dirstate = repo.dirstate
2855 dirstate = repo.dirstate
2856 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2856 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2857 rootdir = repo.root + pycompat.ossep
2857 rootdir = repo.root + pycompat.ossep
2858 if spec != repo.root and not spec.startswith(rootdir):
2858 if spec != repo.root and not spec.startswith(rootdir):
2859 return [], []
2859 return [], []
2860 if os.path.isdir(spec):
2860 if os.path.isdir(spec):
2861 spec += b'/'
2861 spec += b'/'
2862 spec = spec[len(rootdir) :]
2862 spec = spec[len(rootdir) :]
2863 fixpaths = pycompat.ossep != b'/'
2863 fixpaths = pycompat.ossep != b'/'
2864 if fixpaths:
2864 if fixpaths:
2865 spec = spec.replace(pycompat.ossep, b'/')
2865 spec = spec.replace(pycompat.ossep, b'/')
2866 speclen = len(spec)
2866 speclen = len(spec)
2867 fullpaths = opts['full']
2867 fullpaths = opts['full']
2868 files, dirs = set(), set()
2868 files, dirs = set(), set()
2869 adddir, addfile = dirs.add, files.add
2869 adddir, addfile = dirs.add, files.add
2870 for f, st in dirstate.items():
2870 for f, st in dirstate.items():
2871 if f.startswith(spec) and st.state in acceptable:
2871 if f.startswith(spec) and st.state in acceptable:
2872 if fixpaths:
2872 if fixpaths:
2873 f = f.replace(b'/', pycompat.ossep)
2873 f = f.replace(b'/', pycompat.ossep)
2874 if fullpaths:
2874 if fullpaths:
2875 addfile(f)
2875 addfile(f)
2876 continue
2876 continue
2877 s = f.find(pycompat.ossep, speclen)
2877 s = f.find(pycompat.ossep, speclen)
2878 if s >= 0:
2878 if s >= 0:
2879 adddir(f[:s])
2879 adddir(f[:s])
2880 else:
2880 else:
2881 addfile(f)
2881 addfile(f)
2882 return files, dirs
2882 return files, dirs
2883
2883
2884 acceptable = b''
2884 acceptable = b''
2885 if opts['normal']:
2885 if opts['normal']:
2886 acceptable += b'nm'
2886 acceptable += b'nm'
2887 if opts['added']:
2887 if opts['added']:
2888 acceptable += b'a'
2888 acceptable += b'a'
2889 if opts['removed']:
2889 if opts['removed']:
2890 acceptable += b'r'
2890 acceptable += b'r'
2891 cwd = repo.getcwd()
2891 cwd = repo.getcwd()
2892 if not specs:
2892 if not specs:
2893 specs = [b'.']
2893 specs = [b'.']
2894
2894
2895 files, dirs = set(), set()
2895 files, dirs = set(), set()
2896 for spec in specs:
2896 for spec in specs:
2897 f, d = complete(spec, acceptable or b'nmar')
2897 f, d = complete(spec, acceptable or b'nmar')
2898 files.update(f)
2898 files.update(f)
2899 dirs.update(d)
2899 dirs.update(d)
2900 files.update(dirs)
2900 files.update(dirs)
2901 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2901 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2902 ui.write(b'\n')
2902 ui.write(b'\n')
2903
2903
2904
2904
2905 @command(
2905 @command(
2906 b'debugpathcopies',
2906 b'debugpathcopies',
2907 cmdutil.walkopts,
2907 cmdutil.walkopts,
2908 b'hg debugpathcopies REV1 REV2 [FILE]',
2908 b'hg debugpathcopies REV1 REV2 [FILE]',
2909 inferrepo=True,
2909 inferrepo=True,
2910 )
2910 )
2911 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2911 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2912 """show copies between two revisions"""
2912 """show copies between two revisions"""
2913 ctx1 = scmutil.revsingle(repo, rev1)
2913 ctx1 = scmutil.revsingle(repo, rev1)
2914 ctx2 = scmutil.revsingle(repo, rev2)
2914 ctx2 = scmutil.revsingle(repo, rev2)
2915 m = scmutil.match(ctx1, pats, opts)
2915 m = scmutil.match(ctx1, pats, opts)
2916 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2916 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2917 ui.write(b'%s -> %s\n' % (src, dst))
2917 ui.write(b'%s -> %s\n' % (src, dst))
2918
2918
2919
2919
2920 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2920 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2921 def debugpeer(ui, path):
2921 def debugpeer(ui, path):
2922 """establish a connection to a peer repository"""
2922 """establish a connection to a peer repository"""
2923 # Always enable peer request logging. Requires --debug to display
2923 # Always enable peer request logging. Requires --debug to display
2924 # though.
2924 # though.
2925 overrides = {
2925 overrides = {
2926 (b'devel', b'debug.peer-request'): True,
2926 (b'devel', b'debug.peer-request'): True,
2927 }
2927 }
2928
2928
2929 with ui.configoverride(overrides):
2929 with ui.configoverride(overrides):
2930 peer = hg.peer(ui, {}, path)
2930 peer = hg.peer(ui, {}, path)
2931
2931
2932 try:
2932 try:
2933 local = peer.local() is not None
2933 local = peer.local() is not None
2934 canpush = peer.canpush()
2934 canpush = peer.canpush()
2935
2935
2936 ui.write(_(b'url: %s\n') % peer.url())
2936 ui.write(_(b'url: %s\n') % peer.url())
2937 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2937 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2938 ui.write(
2938 ui.write(
2939 _(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no'))
2939 _(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no'))
2940 )
2940 )
2941 finally:
2941 finally:
2942 peer.close()
2942 peer.close()
2943
2943
2944
2944
2945 @command(
2945 @command(
2946 b'debugpickmergetool',
2946 b'debugpickmergetool',
2947 [
2947 [
2948 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2948 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2949 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2949 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2950 ]
2950 ]
2951 + cmdutil.walkopts
2951 + cmdutil.walkopts
2952 + cmdutil.mergetoolopts,
2952 + cmdutil.mergetoolopts,
2953 _(b'[PATTERN]...'),
2953 _(b'[PATTERN]...'),
2954 inferrepo=True,
2954 inferrepo=True,
2955 )
2955 )
2956 def debugpickmergetool(ui, repo, *pats, **opts):
2956 def debugpickmergetool(ui, repo, *pats, **opts):
2957 """examine which merge tool is chosen for specified file
2957 """examine which merge tool is chosen for specified file
2958
2958
2959 As described in :hg:`help merge-tools`, Mercurial examines
2959 As described in :hg:`help merge-tools`, Mercurial examines
2960 configurations below in this order to decide which merge tool is
2960 configurations below in this order to decide which merge tool is
2961 chosen for specified file.
2961 chosen for specified file.
2962
2962
2963 1. ``--tool`` option
2963 1. ``--tool`` option
2964 2. ``HGMERGE`` environment variable
2964 2. ``HGMERGE`` environment variable
2965 3. configurations in ``merge-patterns`` section
2965 3. configurations in ``merge-patterns`` section
2966 4. configuration of ``ui.merge``
2966 4. configuration of ``ui.merge``
2967 5. configurations in ``merge-tools`` section
2967 5. configurations in ``merge-tools`` section
2968 6. ``hgmerge`` tool (for historical reason only)
2968 6. ``hgmerge`` tool (for historical reason only)
2969 7. default tool for fallback (``:merge`` or ``:prompt``)
2969 7. default tool for fallback (``:merge`` or ``:prompt``)
2970
2970
2971 This command writes out examination result in the style below::
2971 This command writes out examination result in the style below::
2972
2972
2973 FILE = MERGETOOL
2973 FILE = MERGETOOL
2974
2974
2975 By default, all files known in the first parent context of the
2975 By default, all files known in the first parent context of the
2976 working directory are examined. Use file patterns and/or -I/-X
2976 working directory are examined. Use file patterns and/or -I/-X
2977 options to limit target files. -r/--rev is also useful to examine
2977 options to limit target files. -r/--rev is also useful to examine
2978 files in another context without actual updating to it.
2978 files in another context without actual updating to it.
2979
2979
2980 With --debug, this command shows warning messages while matching
2980 With --debug, this command shows warning messages while matching
2981 against ``merge-patterns`` and so on, too. It is recommended to
2981 against ``merge-patterns`` and so on, too. It is recommended to
2982 use this option with explicit file patterns and/or -I/-X options,
2982 use this option with explicit file patterns and/or -I/-X options,
2983 because this option increases amount of output per file according
2983 because this option increases amount of output per file according
2984 to configurations in hgrc.
2984 to configurations in hgrc.
2985
2985
2986 With -v/--verbose, this command shows configurations below at
2986 With -v/--verbose, this command shows configurations below at
2987 first (only if specified).
2987 first (only if specified).
2988
2988
2989 - ``--tool`` option
2989 - ``--tool`` option
2990 - ``HGMERGE`` environment variable
2990 - ``HGMERGE`` environment variable
2991 - configuration of ``ui.merge``
2991 - configuration of ``ui.merge``
2992
2992
2993 If merge tool is chosen before matching against
2993 If merge tool is chosen before matching against
2994 ``merge-patterns``, this command can't show any helpful
2994 ``merge-patterns``, this command can't show any helpful
2995 information, even with --debug. In such case, information above is
2995 information, even with --debug. In such case, information above is
2996 useful to know why a merge tool is chosen.
2996 useful to know why a merge tool is chosen.
2997 """
2997 """
2998 opts = pycompat.byteskwargs(opts)
2998 opts = pycompat.byteskwargs(opts)
2999 overrides = {}
2999 overrides = {}
3000 if opts[b'tool']:
3000 if opts[b'tool']:
3001 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
3001 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
3002 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
3002 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
3003
3003
3004 with ui.configoverride(overrides, b'debugmergepatterns'):
3004 with ui.configoverride(overrides, b'debugmergepatterns'):
3005 hgmerge = encoding.environ.get(b"HGMERGE")
3005 hgmerge = encoding.environ.get(b"HGMERGE")
3006 if hgmerge is not None:
3006 if hgmerge is not None:
3007 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
3007 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
3008 uimerge = ui.config(b"ui", b"merge")
3008 uimerge = ui.config(b"ui", b"merge")
3009 if uimerge:
3009 if uimerge:
3010 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
3010 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
3011
3011
3012 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
3012 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
3013 m = scmutil.match(ctx, pats, opts)
3013 m = scmutil.match(ctx, pats, opts)
3014 changedelete = opts[b'changedelete']
3014 changedelete = opts[b'changedelete']
3015 for path in ctx.walk(m):
3015 for path in ctx.walk(m):
3016 fctx = ctx[path]
3016 fctx = ctx[path]
3017 with ui.silent(
3017 with ui.silent(
3018 error=True
3018 error=True
3019 ) if not ui.debugflag else util.nullcontextmanager():
3019 ) if not ui.debugflag else util.nullcontextmanager():
3020 tool, toolpath = filemerge._picktool(
3020 tool, toolpath = filemerge._picktool(
3021 repo,
3021 repo,
3022 ui,
3022 ui,
3023 path,
3023 path,
3024 fctx.isbinary(),
3024 fctx.isbinary(),
3025 b'l' in fctx.flags(),
3025 b'l' in fctx.flags(),
3026 changedelete,
3026 changedelete,
3027 )
3027 )
3028 ui.write(b'%s = %s\n' % (path, tool))
3028 ui.write(b'%s = %s\n' % (path, tool))
3029
3029
3030
3030
3031 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
3031 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
3032 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
3032 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
3033 """access the pushkey key/value protocol
3033 """access the pushkey key/value protocol
3034
3034
3035 With two args, list the keys in the given namespace.
3035 With two args, list the keys in the given namespace.
3036
3036
3037 With five args, set a key to new if it currently is set to old.
3037 With five args, set a key to new if it currently is set to old.
3038 Reports success or failure.
3038 Reports success or failure.
3039 """
3039 """
3040
3040
3041 target = hg.peer(ui, {}, repopath)
3041 target = hg.peer(ui, {}, repopath)
3042 try:
3042 try:
3043 if keyinfo:
3043 if keyinfo:
3044 key, old, new = keyinfo
3044 key, old, new = keyinfo
3045 with target.commandexecutor() as e:
3045 with target.commandexecutor() as e:
3046 r = e.callcommand(
3046 r = e.callcommand(
3047 b'pushkey',
3047 b'pushkey',
3048 {
3048 {
3049 b'namespace': namespace,
3049 b'namespace': namespace,
3050 b'key': key,
3050 b'key': key,
3051 b'old': old,
3051 b'old': old,
3052 b'new': new,
3052 b'new': new,
3053 },
3053 },
3054 ).result()
3054 ).result()
3055
3055
3056 ui.status(pycompat.bytestr(r) + b'\n')
3056 ui.status(pycompat.bytestr(r) + b'\n')
3057 return not r
3057 return not r
3058 else:
3058 else:
3059 for k, v in sorted(target.listkeys(namespace).items()):
3059 for k, v in sorted(target.listkeys(namespace).items()):
3060 ui.write(
3060 ui.write(
3061 b"%s\t%s\n"
3061 b"%s\t%s\n"
3062 % (stringutil.escapestr(k), stringutil.escapestr(v))
3062 % (stringutil.escapestr(k), stringutil.escapestr(v))
3063 )
3063 )
3064 finally:
3064 finally:
3065 target.close()
3065 target.close()
3066
3066
3067
3067
3068 @command(b'debugpvec', [], _(b'A B'))
3068 @command(b'debugpvec', [], _(b'A B'))
3069 def debugpvec(ui, repo, a, b=None):
3069 def debugpvec(ui, repo, a, b=None):
3070 ca = scmutil.revsingle(repo, a)
3070 ca = scmutil.revsingle(repo, a)
3071 cb = scmutil.revsingle(repo, b)
3071 cb = scmutil.revsingle(repo, b)
3072 pa = pvec.ctxpvec(ca)
3072 pa = pvec.ctxpvec(ca)
3073 pb = pvec.ctxpvec(cb)
3073 pb = pvec.ctxpvec(cb)
3074 if pa == pb:
3074 if pa == pb:
3075 rel = b"="
3075 rel = b"="
3076 elif pa > pb:
3076 elif pa > pb:
3077 rel = b">"
3077 rel = b">"
3078 elif pa < pb:
3078 elif pa < pb:
3079 rel = b"<"
3079 rel = b"<"
3080 elif pa | pb:
3080 elif pa | pb:
3081 rel = b"|"
3081 rel = b"|"
3082 ui.write(_(b"a: %s\n") % pa)
3082 ui.write(_(b"a: %s\n") % pa)
3083 ui.write(_(b"b: %s\n") % pb)
3083 ui.write(_(b"b: %s\n") % pb)
3084 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
3084 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
3085 ui.write(
3085 ui.write(
3086 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
3086 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
3087 % (
3087 % (
3088 abs(pa._depth - pb._depth),
3088 abs(pa._depth - pb._depth),
3089 pvec._hamming(pa._vec, pb._vec),
3089 pvec._hamming(pa._vec, pb._vec),
3090 pa.distance(pb),
3090 pa.distance(pb),
3091 rel,
3091 rel,
3092 )
3092 )
3093 )
3093 )
3094
3094
3095
3095
3096 @command(
3096 @command(
3097 b'debugrebuilddirstate|debugrebuildstate',
3097 b'debugrebuilddirstate|debugrebuildstate',
3098 [
3098 [
3099 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
3099 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
3100 (
3100 (
3101 b'',
3101 b'',
3102 b'minimal',
3102 b'minimal',
3103 None,
3103 None,
3104 _(
3104 _(
3105 b'only rebuild files that are inconsistent with '
3105 b'only rebuild files that are inconsistent with '
3106 b'the working copy parent'
3106 b'the working copy parent'
3107 ),
3107 ),
3108 ),
3108 ),
3109 ],
3109 ],
3110 _(b'[-r REV]'),
3110 _(b'[-r REV]'),
3111 )
3111 )
3112 def debugrebuilddirstate(ui, repo, rev, **opts):
3112 def debugrebuilddirstate(ui, repo, rev, **opts):
3113 """rebuild the dirstate as it would look like for the given revision
3113 """rebuild the dirstate as it would look like for the given revision
3114
3114
3115 If no revision is specified the first current parent will be used.
3115 If no revision is specified the first current parent will be used.
3116
3116
3117 The dirstate will be set to the files of the given revision.
3117 The dirstate will be set to the files of the given revision.
3118 The actual working directory content or existing dirstate
3118 The actual working directory content or existing dirstate
3119 information such as adds or removes is not considered.
3119 information such as adds or removes is not considered.
3120
3120
3121 ``minimal`` will only rebuild the dirstate status for files that claim to be
3121 ``minimal`` will only rebuild the dirstate status for files that claim to be
3122 tracked but are not in the parent manifest, or that exist in the parent
3122 tracked but are not in the parent manifest, or that exist in the parent
3123 manifest but are not in the dirstate. It will not change adds, removes, or
3123 manifest but are not in the dirstate. It will not change adds, removes, or
3124 modified files that are in the working copy parent.
3124 modified files that are in the working copy parent.
3125
3125
3126 One use of this command is to make the next :hg:`status` invocation
3126 One use of this command is to make the next :hg:`status` invocation
3127 check the actual file content.
3127 check the actual file content.
3128 """
3128 """
3129 ctx = scmutil.revsingle(repo, rev)
3129 ctx = scmutil.revsingle(repo, rev)
3130 with repo.wlock():
3130 with repo.wlock():
3131 dirstate = repo.dirstate
3131 dirstate = repo.dirstate
3132 changedfiles = None
3132 changedfiles = None
3133 # See command doc for what minimal does.
3133 # See command doc for what minimal does.
3134 if opts.get('minimal'):
3134 if opts.get('minimal'):
3135 manifestfiles = set(ctx.manifest().keys())
3135 manifestfiles = set(ctx.manifest().keys())
3136 dirstatefiles = set(dirstate)
3136 dirstatefiles = set(dirstate)
3137 manifestonly = manifestfiles - dirstatefiles
3137 manifestonly = manifestfiles - dirstatefiles
3138 dsonly = dirstatefiles - manifestfiles
3138 dsonly = dirstatefiles - manifestfiles
3139 dsnotadded = {f for f in dsonly if not dirstate.get_entry(f).added}
3139 dsnotadded = {f for f in dsonly if not dirstate.get_entry(f).added}
3140 changedfiles = manifestonly | dsnotadded
3140 changedfiles = manifestonly | dsnotadded
3141
3141
3142 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
3142 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
3143
3143
3144
3144
3145 @command(
3145 @command(
3146 b'debugrebuildfncache',
3146 b'debugrebuildfncache',
3147 [
3147 [
3148 (
3148 (
3149 b'',
3149 b'',
3150 b'only-data',
3150 b'only-data',
3151 False,
3151 False,
3152 _(b'only look for wrong .d files (much faster)'),
3152 _(b'only look for wrong .d files (much faster)'),
3153 )
3153 )
3154 ],
3154 ],
3155 b'',
3155 b'',
3156 )
3156 )
3157 def debugrebuildfncache(ui, repo, **opts):
3157 def debugrebuildfncache(ui, repo, **opts):
3158 """rebuild the fncache file"""
3158 """rebuild the fncache file"""
3159 opts = pycompat.byteskwargs(opts)
3159 opts = pycompat.byteskwargs(opts)
3160 repair.rebuildfncache(ui, repo, opts.get(b"only_data"))
3160 repair.rebuildfncache(ui, repo, opts.get(b"only_data"))
3161
3161
3162
3162
3163 @command(
3163 @command(
3164 b'debugrename',
3164 b'debugrename',
3165 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
3165 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
3166 _(b'[-r REV] [FILE]...'),
3166 _(b'[-r REV] [FILE]...'),
3167 )
3167 )
3168 def debugrename(ui, repo, *pats, **opts):
3168 def debugrename(ui, repo, *pats, **opts):
3169 """dump rename information"""
3169 """dump rename information"""
3170
3170
3171 opts = pycompat.byteskwargs(opts)
3171 opts = pycompat.byteskwargs(opts)
3172 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
3172 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
3173 m = scmutil.match(ctx, pats, opts)
3173 m = scmutil.match(ctx, pats, opts)
3174 for abs in ctx.walk(m):
3174 for abs in ctx.walk(m):
3175 fctx = ctx[abs]
3175 fctx = ctx[abs]
3176 o = fctx.filelog().renamed(fctx.filenode())
3176 o = fctx.filelog().renamed(fctx.filenode())
3177 rel = repo.pathto(abs)
3177 rel = repo.pathto(abs)
3178 if o:
3178 if o:
3179 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
3179 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
3180 else:
3180 else:
3181 ui.write(_(b"%s not renamed\n") % rel)
3181 ui.write(_(b"%s not renamed\n") % rel)
3182
3182
3183
3183
3184 @command(b'debugrequires|debugrequirements', [], b'')
3184 @command(b'debugrequires|debugrequirements', [], b'')
3185 def debugrequirements(ui, repo):
3185 def debugrequirements(ui, repo):
3186 """print the current repo requirements"""
3186 """print the current repo requirements"""
3187 for r in sorted(repo.requirements):
3187 for r in sorted(repo.requirements):
3188 ui.write(b"%s\n" % r)
3188 ui.write(b"%s\n" % r)
3189
3189
3190
3190
3191 @command(
3191 @command(
3192 b'debugrevlog',
3192 b'debugrevlog',
3193 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
3193 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
3194 _(b'-c|-m|FILE'),
3194 _(b'-c|-m|FILE'),
3195 optionalrepo=True,
3195 optionalrepo=True,
3196 )
3196 )
3197 def debugrevlog(ui, repo, file_=None, **opts):
3197 def debugrevlog(ui, repo, file_=None, **opts):
3198 """show data and statistics about a revlog"""
3198 """show data and statistics about a revlog"""
3199 opts = pycompat.byteskwargs(opts)
3199 opts = pycompat.byteskwargs(opts)
3200 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
3200 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
3201
3201
3202 if opts.get(b"dump"):
3202 if opts.get(b"dump"):
3203 numrevs = len(r)
3203 numrevs = len(r)
3204 ui.write(
3204 ui.write(
3205 (
3205 (
3206 b"# rev p1rev p2rev start end deltastart base p1 p2"
3206 b"# rev p1rev p2rev start end deltastart base p1 p2"
3207 b" rawsize totalsize compression heads chainlen\n"
3207 b" rawsize totalsize compression heads chainlen\n"
3208 )
3208 )
3209 )
3209 )
3210 ts = 0
3210 ts = 0
3211 heads = set()
3211 heads = set()
3212
3212
3213 for rev in pycompat.xrange(numrevs):
3213 for rev in pycompat.xrange(numrevs):
3214 dbase = r.deltaparent(rev)
3214 dbase = r.deltaparent(rev)
3215 if dbase == -1:
3215 if dbase == -1:
3216 dbase = rev
3216 dbase = rev
3217 cbase = r.chainbase(rev)
3217 cbase = r.chainbase(rev)
3218 clen = r.chainlen(rev)
3218 clen = r.chainlen(rev)
3219 p1, p2 = r.parentrevs(rev)
3219 p1, p2 = r.parentrevs(rev)
3220 rs = r.rawsize(rev)
3220 rs = r.rawsize(rev)
3221 ts = ts + rs
3221 ts = ts + rs
3222 heads -= set(r.parentrevs(rev))
3222 heads -= set(r.parentrevs(rev))
3223 heads.add(rev)
3223 heads.add(rev)
3224 try:
3224 try:
3225 compression = ts / r.end(rev)
3225 compression = ts / r.end(rev)
3226 except ZeroDivisionError:
3226 except ZeroDivisionError:
3227 compression = 0
3227 compression = 0
3228 ui.write(
3228 ui.write(
3229 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
3229 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
3230 b"%11d %5d %8d\n"
3230 b"%11d %5d %8d\n"
3231 % (
3231 % (
3232 rev,
3232 rev,
3233 p1,
3233 p1,
3234 p2,
3234 p2,
3235 r.start(rev),
3235 r.start(rev),
3236 r.end(rev),
3236 r.end(rev),
3237 r.start(dbase),
3237 r.start(dbase),
3238 r.start(cbase),
3238 r.start(cbase),
3239 r.start(p1),
3239 r.start(p1),
3240 r.start(p2),
3240 r.start(p2),
3241 rs,
3241 rs,
3242 ts,
3242 ts,
3243 compression,
3243 compression,
3244 len(heads),
3244 len(heads),
3245 clen,
3245 clen,
3246 )
3246 )
3247 )
3247 )
3248 return 0
3248 return 0
3249
3249
3250 format = r._format_version
3250 format = r._format_version
3251 v = r._format_flags
3251 v = r._format_flags
3252 flags = []
3252 flags = []
3253 gdelta = False
3253 gdelta = False
3254 if v & revlog.FLAG_INLINE_DATA:
3254 if v & revlog.FLAG_INLINE_DATA:
3255 flags.append(b'inline')
3255 flags.append(b'inline')
3256 if v & revlog.FLAG_GENERALDELTA:
3256 if v & revlog.FLAG_GENERALDELTA:
3257 gdelta = True
3257 gdelta = True
3258 flags.append(b'generaldelta')
3258 flags.append(b'generaldelta')
3259 if not flags:
3259 if not flags:
3260 flags = [b'(none)']
3260 flags = [b'(none)']
3261
3261
3262 ### tracks merge vs single parent
3262 ### tracks merge vs single parent
3263 nummerges = 0
3263 nummerges = 0
3264
3264
3265 ### tracks ways the "delta" are build
3265 ### tracks ways the "delta" are build
3266 # nodelta
3266 # nodelta
3267 numempty = 0
3267 numempty = 0
3268 numemptytext = 0
3268 numemptytext = 0
3269 numemptydelta = 0
3269 numemptydelta = 0
3270 # full file content
3270 # full file content
3271 numfull = 0
3271 numfull = 0
3272 # intermediate snapshot against a prior snapshot
3272 # intermediate snapshot against a prior snapshot
3273 numsemi = 0
3273 numsemi = 0
3274 # snapshot count per depth
3274 # snapshot count per depth
3275 numsnapdepth = collections.defaultdict(lambda: 0)
3275 numsnapdepth = collections.defaultdict(lambda: 0)
3276 # delta against previous revision
3276 # delta against previous revision
3277 numprev = 0
3277 numprev = 0
3278 # delta against first or second parent (not prev)
3278 # delta against first or second parent (not prev)
3279 nump1 = 0
3279 nump1 = 0
3280 nump2 = 0
3280 nump2 = 0
3281 # delta against neither prev nor parents
3281 # delta against neither prev nor parents
3282 numother = 0
3282 numother = 0
3283 # delta against prev that are also first or second parent
3283 # delta against prev that are also first or second parent
3284 # (details of `numprev`)
3284 # (details of `numprev`)
3285 nump1prev = 0
3285 nump1prev = 0
3286 nump2prev = 0
3286 nump2prev = 0
3287
3287
3288 # data about delta chain of each revs
3288 # data about delta chain of each revs
3289 chainlengths = []
3289 chainlengths = []
3290 chainbases = []
3290 chainbases = []
3291 chainspans = []
3291 chainspans = []
3292
3292
3293 # data about each revision
3293 # data about each revision
3294 datasize = [None, 0, 0]
3294 datasize = [None, 0, 0]
3295 fullsize = [None, 0, 0]
3295 fullsize = [None, 0, 0]
3296 semisize = [None, 0, 0]
3296 semisize = [None, 0, 0]
3297 # snapshot count per depth
3297 # snapshot count per depth
3298 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
3298 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
3299 deltasize = [None, 0, 0]
3299 deltasize = [None, 0, 0]
3300 chunktypecounts = {}
3300 chunktypecounts = {}
3301 chunktypesizes = {}
3301 chunktypesizes = {}
3302
3302
3303 def addsize(size, l):
3303 def addsize(size, l):
3304 if l[0] is None or size < l[0]:
3304 if l[0] is None or size < l[0]:
3305 l[0] = size
3305 l[0] = size
3306 if size > l[1]:
3306 if size > l[1]:
3307 l[1] = size
3307 l[1] = size
3308 l[2] += size
3308 l[2] += size
3309
3309
3310 numrevs = len(r)
3310 numrevs = len(r)
3311 for rev in pycompat.xrange(numrevs):
3311 for rev in pycompat.xrange(numrevs):
3312 p1, p2 = r.parentrevs(rev)
3312 p1, p2 = r.parentrevs(rev)
3313 delta = r.deltaparent(rev)
3313 delta = r.deltaparent(rev)
3314 if format > 0:
3314 if format > 0:
3315 addsize(r.rawsize(rev), datasize)
3315 addsize(r.rawsize(rev), datasize)
3316 if p2 != nullrev:
3316 if p2 != nullrev:
3317 nummerges += 1
3317 nummerges += 1
3318 size = r.length(rev)
3318 size = r.length(rev)
3319 if delta == nullrev:
3319 if delta == nullrev:
3320 chainlengths.append(0)
3320 chainlengths.append(0)
3321 chainbases.append(r.start(rev))
3321 chainbases.append(r.start(rev))
3322 chainspans.append(size)
3322 chainspans.append(size)
3323 if size == 0:
3323 if size == 0:
3324 numempty += 1
3324 numempty += 1
3325 numemptytext += 1
3325 numemptytext += 1
3326 else:
3326 else:
3327 numfull += 1
3327 numfull += 1
3328 numsnapdepth[0] += 1
3328 numsnapdepth[0] += 1
3329 addsize(size, fullsize)
3329 addsize(size, fullsize)
3330 addsize(size, snapsizedepth[0])
3330 addsize(size, snapsizedepth[0])
3331 else:
3331 else:
3332 chainlengths.append(chainlengths[delta] + 1)
3332 chainlengths.append(chainlengths[delta] + 1)
3333 baseaddr = chainbases[delta]
3333 baseaddr = chainbases[delta]
3334 revaddr = r.start(rev)
3334 revaddr = r.start(rev)
3335 chainbases.append(baseaddr)
3335 chainbases.append(baseaddr)
3336 chainspans.append((revaddr - baseaddr) + size)
3336 chainspans.append((revaddr - baseaddr) + size)
3337 if size == 0:
3337 if size == 0:
3338 numempty += 1
3338 numempty += 1
3339 numemptydelta += 1
3339 numemptydelta += 1
3340 elif r.issnapshot(rev):
3340 elif r.issnapshot(rev):
3341 addsize(size, semisize)
3341 addsize(size, semisize)
3342 numsemi += 1
3342 numsemi += 1
3343 depth = r.snapshotdepth(rev)
3343 depth = r.snapshotdepth(rev)
3344 numsnapdepth[depth] += 1
3344 numsnapdepth[depth] += 1
3345 addsize(size, snapsizedepth[depth])
3345 addsize(size, snapsizedepth[depth])
3346 else:
3346 else:
3347 addsize(size, deltasize)
3347 addsize(size, deltasize)
3348 if delta == rev - 1:
3348 if delta == rev - 1:
3349 numprev += 1
3349 numprev += 1
3350 if delta == p1:
3350 if delta == p1:
3351 nump1prev += 1
3351 nump1prev += 1
3352 elif delta == p2:
3352 elif delta == p2:
3353 nump2prev += 1
3353 nump2prev += 1
3354 elif delta == p1:
3354 elif delta == p1:
3355 nump1 += 1
3355 nump1 += 1
3356 elif delta == p2:
3356 elif delta == p2:
3357 nump2 += 1
3357 nump2 += 1
3358 elif delta != nullrev:
3358 elif delta != nullrev:
3359 numother += 1
3359 numother += 1
3360
3360
3361 # Obtain data on the raw chunks in the revlog.
3361 # Obtain data on the raw chunks in the revlog.
3362 if util.safehasattr(r, b'_getsegmentforrevs'):
3362 if util.safehasattr(r, b'_getsegmentforrevs'):
3363 segment = r._getsegmentforrevs(rev, rev)[1]
3363 segment = r._getsegmentforrevs(rev, rev)[1]
3364 else:
3364 else:
3365 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
3365 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
3366 if segment:
3366 if segment:
3367 chunktype = bytes(segment[0:1])
3367 chunktype = bytes(segment[0:1])
3368 else:
3368 else:
3369 chunktype = b'empty'
3369 chunktype = b'empty'
3370
3370
3371 if chunktype not in chunktypecounts:
3371 if chunktype not in chunktypecounts:
3372 chunktypecounts[chunktype] = 0
3372 chunktypecounts[chunktype] = 0
3373 chunktypesizes[chunktype] = 0
3373 chunktypesizes[chunktype] = 0
3374
3374
3375 chunktypecounts[chunktype] += 1
3375 chunktypecounts[chunktype] += 1
3376 chunktypesizes[chunktype] += size
3376 chunktypesizes[chunktype] += size
3377
3377
3378 # Adjust size min value for empty cases
3378 # Adjust size min value for empty cases
3379 for size in (datasize, fullsize, semisize, deltasize):
3379 for size in (datasize, fullsize, semisize, deltasize):
3380 if size[0] is None:
3380 if size[0] is None:
3381 size[0] = 0
3381 size[0] = 0
3382
3382
3383 numdeltas = numrevs - numfull - numempty - numsemi
3383 numdeltas = numrevs - numfull - numempty - numsemi
3384 numoprev = numprev - nump1prev - nump2prev
3384 numoprev = numprev - nump1prev - nump2prev
3385 totalrawsize = datasize[2]
3385 totalrawsize = datasize[2]
3386 datasize[2] /= numrevs
3386 datasize[2] /= numrevs
3387 fulltotal = fullsize[2]
3387 fulltotal = fullsize[2]
3388 if numfull == 0:
3388 if numfull == 0:
3389 fullsize[2] = 0
3389 fullsize[2] = 0
3390 else:
3390 else:
3391 fullsize[2] /= numfull
3391 fullsize[2] /= numfull
3392 semitotal = semisize[2]
3392 semitotal = semisize[2]
3393 snaptotal = {}
3393 snaptotal = {}
3394 if numsemi > 0:
3394 if numsemi > 0:
3395 semisize[2] /= numsemi
3395 semisize[2] /= numsemi
3396 for depth in snapsizedepth:
3396 for depth in snapsizedepth:
3397 snaptotal[depth] = snapsizedepth[depth][2]
3397 snaptotal[depth] = snapsizedepth[depth][2]
3398 snapsizedepth[depth][2] /= numsnapdepth[depth]
3398 snapsizedepth[depth][2] /= numsnapdepth[depth]
3399
3399
3400 deltatotal = deltasize[2]
3400 deltatotal = deltasize[2]
3401 if numdeltas > 0:
3401 if numdeltas > 0:
3402 deltasize[2] /= numdeltas
3402 deltasize[2] /= numdeltas
3403 totalsize = fulltotal + semitotal + deltatotal
3403 totalsize = fulltotal + semitotal + deltatotal
3404 avgchainlen = sum(chainlengths) / numrevs
3404 avgchainlen = sum(chainlengths) / numrevs
3405 maxchainlen = max(chainlengths)
3405 maxchainlen = max(chainlengths)
3406 maxchainspan = max(chainspans)
3406 maxchainspan = max(chainspans)
3407 compratio = 1
3407 compratio = 1
3408 if totalsize:
3408 if totalsize:
3409 compratio = totalrawsize / totalsize
3409 compratio = totalrawsize / totalsize
3410
3410
3411 basedfmtstr = b'%%%dd\n'
3411 basedfmtstr = b'%%%dd\n'
3412 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
3412 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
3413
3413
3414 def dfmtstr(max):
3414 def dfmtstr(max):
3415 return basedfmtstr % len(str(max))
3415 return basedfmtstr % len(str(max))
3416
3416
3417 def pcfmtstr(max, padding=0):
3417 def pcfmtstr(max, padding=0):
3418 return basepcfmtstr % (len(str(max)), b' ' * padding)
3418 return basepcfmtstr % (len(str(max)), b' ' * padding)
3419
3419
3420 def pcfmt(value, total):
3420 def pcfmt(value, total):
3421 if total:
3421 if total:
3422 return (value, 100 * float(value) / total)
3422 return (value, 100 * float(value) / total)
3423 else:
3423 else:
3424 return value, 100.0
3424 return value, 100.0
3425
3425
3426 ui.writenoi18n(b'format : %d\n' % format)
3426 ui.writenoi18n(b'format : %d\n' % format)
3427 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
3427 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
3428
3428
3429 ui.write(b'\n')
3429 ui.write(b'\n')
3430 fmt = pcfmtstr(totalsize)
3430 fmt = pcfmtstr(totalsize)
3431 fmt2 = dfmtstr(totalsize)
3431 fmt2 = dfmtstr(totalsize)
3432 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
3432 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
3433 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
3433 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
3434 ui.writenoi18n(
3434 ui.writenoi18n(
3435 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
3435 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
3436 )
3436 )
3437 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
3437 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
3438 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
3438 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
3439 ui.writenoi18n(
3439 ui.writenoi18n(
3440 b' text : '
3440 b' text : '
3441 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
3441 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
3442 )
3442 )
3443 ui.writenoi18n(
3443 ui.writenoi18n(
3444 b' delta : '
3444 b' delta : '
3445 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
3445 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
3446 )
3446 )
3447 ui.writenoi18n(
3447 ui.writenoi18n(
3448 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
3448 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
3449 )
3449 )
3450 for depth in sorted(numsnapdepth):
3450 for depth in sorted(numsnapdepth):
3451 ui.write(
3451 ui.write(
3452 (b' lvl-%-3d : ' % depth)
3452 (b' lvl-%-3d : ' % depth)
3453 + fmt % pcfmt(numsnapdepth[depth], numrevs)
3453 + fmt % pcfmt(numsnapdepth[depth], numrevs)
3454 )
3454 )
3455 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
3455 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
3456 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
3456 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
3457 ui.writenoi18n(
3457 ui.writenoi18n(
3458 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
3458 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
3459 )
3459 )
3460 for depth in sorted(numsnapdepth):
3460 for depth in sorted(numsnapdepth):
3461 ui.write(
3461 ui.write(
3462 (b' lvl-%-3d : ' % depth)
3462 (b' lvl-%-3d : ' % depth)
3463 + fmt % pcfmt(snaptotal[depth], totalsize)
3463 + fmt % pcfmt(snaptotal[depth], totalsize)
3464 )
3464 )
3465 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
3465 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
3466
3466
3467 def fmtchunktype(chunktype):
3467 def fmtchunktype(chunktype):
3468 if chunktype == b'empty':
3468 if chunktype == b'empty':
3469 return b' %s : ' % chunktype
3469 return b' %s : ' % chunktype
3470 elif chunktype in pycompat.bytestr(string.ascii_letters):
3470 elif chunktype in pycompat.bytestr(string.ascii_letters):
3471 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
3471 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
3472 else:
3472 else:
3473 return b' 0x%s : ' % hex(chunktype)
3473 return b' 0x%s : ' % hex(chunktype)
3474
3474
3475 ui.write(b'\n')
3475 ui.write(b'\n')
3476 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
3476 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
3477 for chunktype in sorted(chunktypecounts):
3477 for chunktype in sorted(chunktypecounts):
3478 ui.write(fmtchunktype(chunktype))
3478 ui.write(fmtchunktype(chunktype))
3479 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
3479 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
3480 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
3480 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
3481 for chunktype in sorted(chunktypecounts):
3481 for chunktype in sorted(chunktypecounts):
3482 ui.write(fmtchunktype(chunktype))
3482 ui.write(fmtchunktype(chunktype))
3483 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
3483 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
3484
3484
3485 ui.write(b'\n')
3485 ui.write(b'\n')
3486 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
3486 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
3487 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
3487 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
3488 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
3488 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
3489 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
3489 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
3490 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
3490 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
3491
3491
3492 if format > 0:
3492 if format > 0:
3493 ui.write(b'\n')
3493 ui.write(b'\n')
3494 ui.writenoi18n(
3494 ui.writenoi18n(
3495 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
3495 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
3496 % tuple(datasize)
3496 % tuple(datasize)
3497 )
3497 )
3498 ui.writenoi18n(
3498 ui.writenoi18n(
3499 b'full revision size (min/max/avg) : %d / %d / %d\n'
3499 b'full revision size (min/max/avg) : %d / %d / %d\n'
3500 % tuple(fullsize)
3500 % tuple(fullsize)
3501 )
3501 )
3502 ui.writenoi18n(
3502 ui.writenoi18n(
3503 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
3503 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
3504 % tuple(semisize)
3504 % tuple(semisize)
3505 )
3505 )
3506 for depth in sorted(snapsizedepth):
3506 for depth in sorted(snapsizedepth):
3507 if depth == 0:
3507 if depth == 0:
3508 continue
3508 continue
3509 ui.writenoi18n(
3509 ui.writenoi18n(
3510 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
3510 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
3511 % ((depth,) + tuple(snapsizedepth[depth]))
3511 % ((depth,) + tuple(snapsizedepth[depth]))
3512 )
3512 )
3513 ui.writenoi18n(
3513 ui.writenoi18n(
3514 b'delta size (min/max/avg) : %d / %d / %d\n'
3514 b'delta size (min/max/avg) : %d / %d / %d\n'
3515 % tuple(deltasize)
3515 % tuple(deltasize)
3516 )
3516 )
3517
3517
3518 if numdeltas > 0:
3518 if numdeltas > 0:
3519 ui.write(b'\n')
3519 ui.write(b'\n')
3520 fmt = pcfmtstr(numdeltas)
3520 fmt = pcfmtstr(numdeltas)
3521 fmt2 = pcfmtstr(numdeltas, 4)
3521 fmt2 = pcfmtstr(numdeltas, 4)
3522 ui.writenoi18n(
3522 ui.writenoi18n(
3523 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
3523 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
3524 )
3524 )
3525 if numprev > 0:
3525 if numprev > 0:
3526 ui.writenoi18n(
3526 ui.writenoi18n(
3527 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
3527 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
3528 )
3528 )
3529 ui.writenoi18n(
3529 ui.writenoi18n(
3530 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
3530 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
3531 )
3531 )
3532 ui.writenoi18n(
3532 ui.writenoi18n(
3533 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
3533 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
3534 )
3534 )
3535 if gdelta:
3535 if gdelta:
3536 ui.writenoi18n(
3536 ui.writenoi18n(
3537 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
3537 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
3538 )
3538 )
3539 ui.writenoi18n(
3539 ui.writenoi18n(
3540 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
3540 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
3541 )
3541 )
3542 ui.writenoi18n(
3542 ui.writenoi18n(
3543 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
3543 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
3544 )
3544 )
3545
3545
3546
3546
3547 @command(
3547 @command(
3548 b'debugrevlogindex',
3548 b'debugrevlogindex',
3549 cmdutil.debugrevlogopts
3549 cmdutil.debugrevlogopts
3550 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
3550 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
3551 _(b'[-f FORMAT] -c|-m|FILE'),
3551 _(b'[-f FORMAT] -c|-m|FILE'),
3552 optionalrepo=True,
3552 optionalrepo=True,
3553 )
3553 )
3554 def debugrevlogindex(ui, repo, file_=None, **opts):
3554 def debugrevlogindex(ui, repo, file_=None, **opts):
3555 """dump the contents of a revlog index"""
3555 """dump the contents of a revlog index"""
3556 opts = pycompat.byteskwargs(opts)
3556 opts = pycompat.byteskwargs(opts)
3557 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
3557 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
3558 format = opts.get(b'format', 0)
3558 format = opts.get(b'format', 0)
3559 if format not in (0, 1):
3559 if format not in (0, 1):
3560 raise error.Abort(_(b"unknown format %d") % format)
3560 raise error.Abort(_(b"unknown format %d") % format)
3561
3561
3562 if ui.debugflag:
3562 if ui.debugflag:
3563 shortfn = hex
3563 shortfn = hex
3564 else:
3564 else:
3565 shortfn = short
3565 shortfn = short
3566
3566
3567 # There might not be anything in r, so have a sane default
3567 # There might not be anything in r, so have a sane default
3568 idlen = 12
3568 idlen = 12
3569 for i in r:
3569 for i in r:
3570 idlen = len(shortfn(r.node(i)))
3570 idlen = len(shortfn(r.node(i)))
3571 break
3571 break
3572
3572
3573 if format == 0:
3573 if format == 0:
3574 if ui.verbose:
3574 if ui.verbose:
3575 ui.writenoi18n(
3575 ui.writenoi18n(
3576 b" rev offset length linkrev %s %s p2\n"
3576 b" rev offset length linkrev %s %s p2\n"
3577 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3577 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3578 )
3578 )
3579 else:
3579 else:
3580 ui.writenoi18n(
3580 ui.writenoi18n(
3581 b" rev linkrev %s %s p2\n"
3581 b" rev linkrev %s %s p2\n"
3582 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3582 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3583 )
3583 )
3584 elif format == 1:
3584 elif format == 1:
3585 if ui.verbose:
3585 if ui.verbose:
3586 ui.writenoi18n(
3586 ui.writenoi18n(
3587 (
3587 (
3588 b" rev flag offset length size link p1"
3588 b" rev flag offset length size link p1"
3589 b" p2 %s\n"
3589 b" p2 %s\n"
3590 )
3590 )
3591 % b"nodeid".rjust(idlen)
3591 % b"nodeid".rjust(idlen)
3592 )
3592 )
3593 else:
3593 else:
3594 ui.writenoi18n(
3594 ui.writenoi18n(
3595 b" rev flag size link p1 p2 %s\n"
3595 b" rev flag size link p1 p2 %s\n"
3596 % b"nodeid".rjust(idlen)
3596 % b"nodeid".rjust(idlen)
3597 )
3597 )
3598
3598
3599 for i in r:
3599 for i in r:
3600 node = r.node(i)
3600 node = r.node(i)
3601 if format == 0:
3601 if format == 0:
3602 try:
3602 try:
3603 pp = r.parents(node)
3603 pp = r.parents(node)
3604 except Exception:
3604 except Exception:
3605 pp = [repo.nullid, repo.nullid]
3605 pp = [repo.nullid, repo.nullid]
3606 if ui.verbose:
3606 if ui.verbose:
3607 ui.write(
3607 ui.write(
3608 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3608 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3609 % (
3609 % (
3610 i,
3610 i,
3611 r.start(i),
3611 r.start(i),
3612 r.length(i),
3612 r.length(i),
3613 r.linkrev(i),
3613 r.linkrev(i),
3614 shortfn(node),
3614 shortfn(node),
3615 shortfn(pp[0]),
3615 shortfn(pp[0]),
3616 shortfn(pp[1]),
3616 shortfn(pp[1]),
3617 )
3617 )
3618 )
3618 )
3619 else:
3619 else:
3620 ui.write(
3620 ui.write(
3621 b"% 6d % 7d %s %s %s\n"
3621 b"% 6d % 7d %s %s %s\n"
3622 % (
3622 % (
3623 i,
3623 i,
3624 r.linkrev(i),
3624 r.linkrev(i),
3625 shortfn(node),
3625 shortfn(node),
3626 shortfn(pp[0]),
3626 shortfn(pp[0]),
3627 shortfn(pp[1]),
3627 shortfn(pp[1]),
3628 )
3628 )
3629 )
3629 )
3630 elif format == 1:
3630 elif format == 1:
3631 pr = r.parentrevs(i)
3631 pr = r.parentrevs(i)
3632 if ui.verbose:
3632 if ui.verbose:
3633 ui.write(
3633 ui.write(
3634 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3634 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3635 % (
3635 % (
3636 i,
3636 i,
3637 r.flags(i),
3637 r.flags(i),
3638 r.start(i),
3638 r.start(i),
3639 r.length(i),
3639 r.length(i),
3640 r.rawsize(i),
3640 r.rawsize(i),
3641 r.linkrev(i),
3641 r.linkrev(i),
3642 pr[0],
3642 pr[0],
3643 pr[1],
3643 pr[1],
3644 shortfn(node),
3644 shortfn(node),
3645 )
3645 )
3646 )
3646 )
3647 else:
3647 else:
3648 ui.write(
3648 ui.write(
3649 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3649 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3650 % (
3650 % (
3651 i,
3651 i,
3652 r.flags(i),
3652 r.flags(i),
3653 r.rawsize(i),
3653 r.rawsize(i),
3654 r.linkrev(i),
3654 r.linkrev(i),
3655 pr[0],
3655 pr[0],
3656 pr[1],
3656 pr[1],
3657 shortfn(node),
3657 shortfn(node),
3658 )
3658 )
3659 )
3659 )
3660
3660
3661
3661
3662 @command(
3662 @command(
3663 b'debugrevspec',
3663 b'debugrevspec',
3664 [
3664 [
3665 (
3665 (
3666 b'',
3666 b'',
3667 b'optimize',
3667 b'optimize',
3668 None,
3668 None,
3669 _(b'print parsed tree after optimizing (DEPRECATED)'),
3669 _(b'print parsed tree after optimizing (DEPRECATED)'),
3670 ),
3670 ),
3671 (
3671 (
3672 b'',
3672 b'',
3673 b'show-revs',
3673 b'show-revs',
3674 True,
3674 True,
3675 _(b'print list of result revisions (default)'),
3675 _(b'print list of result revisions (default)'),
3676 ),
3676 ),
3677 (
3677 (
3678 b's',
3678 b's',
3679 b'show-set',
3679 b'show-set',
3680 None,
3680 None,
3681 _(b'print internal representation of result set'),
3681 _(b'print internal representation of result set'),
3682 ),
3682 ),
3683 (
3683 (
3684 b'p',
3684 b'p',
3685 b'show-stage',
3685 b'show-stage',
3686 [],
3686 [],
3687 _(b'print parsed tree at the given stage'),
3687 _(b'print parsed tree at the given stage'),
3688 _(b'NAME'),
3688 _(b'NAME'),
3689 ),
3689 ),
3690 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3690 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3691 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3691 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3692 ],
3692 ],
3693 b'REVSPEC',
3693 b'REVSPEC',
3694 )
3694 )
3695 def debugrevspec(ui, repo, expr, **opts):
3695 def debugrevspec(ui, repo, expr, **opts):
3696 """parse and apply a revision specification
3696 """parse and apply a revision specification
3697
3697
3698 Use -p/--show-stage option to print the parsed tree at the given stages.
3698 Use -p/--show-stage option to print the parsed tree at the given stages.
3699 Use -p all to print tree at every stage.
3699 Use -p all to print tree at every stage.
3700
3700
3701 Use --no-show-revs option with -s or -p to print only the set
3701 Use --no-show-revs option with -s or -p to print only the set
3702 representation or the parsed tree respectively.
3702 representation or the parsed tree respectively.
3703
3703
3704 Use --verify-optimized to compare the optimized result with the unoptimized
3704 Use --verify-optimized to compare the optimized result with the unoptimized
3705 one. Returns 1 if the optimized result differs.
3705 one. Returns 1 if the optimized result differs.
3706 """
3706 """
3707 opts = pycompat.byteskwargs(opts)
3707 opts = pycompat.byteskwargs(opts)
3708 aliases = ui.configitems(b'revsetalias')
3708 aliases = ui.configitems(b'revsetalias')
3709 stages = [
3709 stages = [
3710 (b'parsed', lambda tree: tree),
3710 (b'parsed', lambda tree: tree),
3711 (
3711 (
3712 b'expanded',
3712 b'expanded',
3713 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3713 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3714 ),
3714 ),
3715 (b'concatenated', revsetlang.foldconcat),
3715 (b'concatenated', revsetlang.foldconcat),
3716 (b'analyzed', revsetlang.analyze),
3716 (b'analyzed', revsetlang.analyze),
3717 (b'optimized', revsetlang.optimize),
3717 (b'optimized', revsetlang.optimize),
3718 ]
3718 ]
3719 if opts[b'no_optimized']:
3719 if opts[b'no_optimized']:
3720 stages = stages[:-1]
3720 stages = stages[:-1]
3721 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3721 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3722 raise error.Abort(
3722 raise error.Abort(
3723 _(b'cannot use --verify-optimized with --no-optimized')
3723 _(b'cannot use --verify-optimized with --no-optimized')
3724 )
3724 )
3725 stagenames = {n for n, f in stages}
3725 stagenames = {n for n, f in stages}
3726
3726
3727 showalways = set()
3727 showalways = set()
3728 showchanged = set()
3728 showchanged = set()
3729 if ui.verbose and not opts[b'show_stage']:
3729 if ui.verbose and not opts[b'show_stage']:
3730 # show parsed tree by --verbose (deprecated)
3730 # show parsed tree by --verbose (deprecated)
3731 showalways.add(b'parsed')
3731 showalways.add(b'parsed')
3732 showchanged.update([b'expanded', b'concatenated'])
3732 showchanged.update([b'expanded', b'concatenated'])
3733 if opts[b'optimize']:
3733 if opts[b'optimize']:
3734 showalways.add(b'optimized')
3734 showalways.add(b'optimized')
3735 if opts[b'show_stage'] and opts[b'optimize']:
3735 if opts[b'show_stage'] and opts[b'optimize']:
3736 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3736 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3737 if opts[b'show_stage'] == [b'all']:
3737 if opts[b'show_stage'] == [b'all']:
3738 showalways.update(stagenames)
3738 showalways.update(stagenames)
3739 else:
3739 else:
3740 for n in opts[b'show_stage']:
3740 for n in opts[b'show_stage']:
3741 if n not in stagenames:
3741 if n not in stagenames:
3742 raise error.Abort(_(b'invalid stage name: %s') % n)
3742 raise error.Abort(_(b'invalid stage name: %s') % n)
3743 showalways.update(opts[b'show_stage'])
3743 showalways.update(opts[b'show_stage'])
3744
3744
3745 treebystage = {}
3745 treebystage = {}
3746 printedtree = None
3746 printedtree = None
3747 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3747 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3748 for n, f in stages:
3748 for n, f in stages:
3749 treebystage[n] = tree = f(tree)
3749 treebystage[n] = tree = f(tree)
3750 if n in showalways or (n in showchanged and tree != printedtree):
3750 if n in showalways or (n in showchanged and tree != printedtree):
3751 if opts[b'show_stage'] or n != b'parsed':
3751 if opts[b'show_stage'] or n != b'parsed':
3752 ui.write(b"* %s:\n" % n)
3752 ui.write(b"* %s:\n" % n)
3753 ui.write(revsetlang.prettyformat(tree), b"\n")
3753 ui.write(revsetlang.prettyformat(tree), b"\n")
3754 printedtree = tree
3754 printedtree = tree
3755
3755
3756 if opts[b'verify_optimized']:
3756 if opts[b'verify_optimized']:
3757 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3757 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3758 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3758 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3759 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3759 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3760 ui.writenoi18n(
3760 ui.writenoi18n(
3761 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3761 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3762 )
3762 )
3763 ui.writenoi18n(
3763 ui.writenoi18n(
3764 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3764 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3765 )
3765 )
3766 arevs = list(arevs)
3766 arevs = list(arevs)
3767 brevs = list(brevs)
3767 brevs = list(brevs)
3768 if arevs == brevs:
3768 if arevs == brevs:
3769 return 0
3769 return 0
3770 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3770 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3771 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3771 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3772 sm = difflib.SequenceMatcher(None, arevs, brevs)
3772 sm = difflib.SequenceMatcher(None, arevs, brevs)
3773 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3773 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3774 if tag in ('delete', 'replace'):
3774 if tag in ('delete', 'replace'):
3775 for c in arevs[alo:ahi]:
3775 for c in arevs[alo:ahi]:
3776 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3776 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3777 if tag in ('insert', 'replace'):
3777 if tag in ('insert', 'replace'):
3778 for c in brevs[blo:bhi]:
3778 for c in brevs[blo:bhi]:
3779 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3779 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3780 if tag == 'equal':
3780 if tag == 'equal':
3781 for c in arevs[alo:ahi]:
3781 for c in arevs[alo:ahi]:
3782 ui.write(b' %d\n' % c)
3782 ui.write(b' %d\n' % c)
3783 return 1
3783 return 1
3784
3784
3785 func = revset.makematcher(tree)
3785 func = revset.makematcher(tree)
3786 revs = func(repo)
3786 revs = func(repo)
3787 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3787 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3788 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3788 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3789 if not opts[b'show_revs']:
3789 if not opts[b'show_revs']:
3790 return
3790 return
3791 for c in revs:
3791 for c in revs:
3792 ui.write(b"%d\n" % c)
3792 ui.write(b"%d\n" % c)
3793
3793
3794
3794
3795 @command(
3795 @command(
3796 b'debugserve',
3796 b'debugserve',
3797 [
3797 [
3798 (
3798 (
3799 b'',
3799 b'',
3800 b'sshstdio',
3800 b'sshstdio',
3801 False,
3801 False,
3802 _(b'run an SSH server bound to process handles'),
3802 _(b'run an SSH server bound to process handles'),
3803 ),
3803 ),
3804 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3804 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3805 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3805 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3806 ],
3806 ],
3807 b'',
3807 b'',
3808 )
3808 )
3809 def debugserve(ui, repo, **opts):
3809 def debugserve(ui, repo, **opts):
3810 """run a server with advanced settings
3810 """run a server with advanced settings
3811
3811
3812 This command is similar to :hg:`serve`. It exists partially as a
3812 This command is similar to :hg:`serve`. It exists partially as a
3813 workaround to the fact that ``hg serve --stdio`` must have specific
3813 workaround to the fact that ``hg serve --stdio`` must have specific
3814 arguments for security reasons.
3814 arguments for security reasons.
3815 """
3815 """
3816 opts = pycompat.byteskwargs(opts)
3816 opts = pycompat.byteskwargs(opts)
3817
3817
3818 if not opts[b'sshstdio']:
3818 if not opts[b'sshstdio']:
3819 raise error.Abort(_(b'only --sshstdio is currently supported'))
3819 raise error.Abort(_(b'only --sshstdio is currently supported'))
3820
3820
3821 logfh = None
3821 logfh = None
3822
3822
3823 if opts[b'logiofd'] and opts[b'logiofile']:
3823 if opts[b'logiofd'] and opts[b'logiofile']:
3824 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3824 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3825
3825
3826 if opts[b'logiofd']:
3826 if opts[b'logiofd']:
3827 # Ideally we would be line buffered. But line buffering in binary
3827 # Ideally we would be line buffered. But line buffering in binary
3828 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3828 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3829 # buffering could have performance impacts. But since this isn't
3829 # buffering could have performance impacts. But since this isn't
3830 # performance critical code, it should be fine.
3830 # performance critical code, it should be fine.
3831 try:
3831 try:
3832 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3832 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3833 except OSError as e:
3833 except OSError as e:
3834 if e.errno != errno.ESPIPE:
3834 if e.errno != errno.ESPIPE:
3835 raise
3835 raise
3836 # can't seek a pipe, so `ab` mode fails on py3
3836 # can't seek a pipe, so `ab` mode fails on py3
3837 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3837 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3838 elif opts[b'logiofile']:
3838 elif opts[b'logiofile']:
3839 logfh = open(opts[b'logiofile'], b'ab', 0)
3839 logfh = open(opts[b'logiofile'], b'ab', 0)
3840
3840
3841 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3841 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3842 s.serve_forever()
3842 s.serve_forever()
3843
3843
3844
3844
3845 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3845 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3846 def debugsetparents(ui, repo, rev1, rev2=None):
3846 def debugsetparents(ui, repo, rev1, rev2=None):
3847 """manually set the parents of the current working directory (DANGEROUS)
3847 """manually set the parents of the current working directory (DANGEROUS)
3848
3848
3849 This command is not what you are looking for and should not be used. Using
3849 This command is not what you are looking for and should not be used. Using
3850 this command will most certainly results in slight corruption of the file
3850 this command will most certainly results in slight corruption of the file
3851 level histories withing your repository. DO NOT USE THIS COMMAND.
3851 level histories withing your repository. DO NOT USE THIS COMMAND.
3852
3852
3853 The command update the p1 and p2 field in the dirstate, and not touching
3853 The command update the p1 and p2 field in the dirstate, and not touching
3854 anything else. This useful for writing repository conversion tools, but
3854 anything else. This useful for writing repository conversion tools, but
3855 should be used with extreme care. For example, neither the working
3855 should be used with extreme care. For example, neither the working
3856 directory nor the dirstate is updated, so file status may be incorrect
3856 directory nor the dirstate is updated, so file status may be incorrect
3857 after running this command. Only used if you are one of the few people that
3857 after running this command. Only used if you are one of the few people that
3858 deeply unstand both conversion tools and file level histories. If you are
3858 deeply unstand both conversion tools and file level histories. If you are
3859 reading this help, you are not one of this people (most of them sailed west
3859 reading this help, you are not one of this people (most of them sailed west
3860 from Mithlond anyway.
3860 from Mithlond anyway.
3861
3861
3862 So one last time DO NOT USE THIS COMMAND.
3862 So one last time DO NOT USE THIS COMMAND.
3863
3863
3864 Returns 0 on success.
3864 Returns 0 on success.
3865 """
3865 """
3866
3866
3867 node1 = scmutil.revsingle(repo, rev1).node()
3867 node1 = scmutil.revsingle(repo, rev1).node()
3868 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3868 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3869
3869
3870 with repo.wlock():
3870 with repo.wlock():
3871 repo.setparents(node1, node2)
3871 repo.setparents(node1, node2)
3872
3872
3873
3873
3874 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3874 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3875 def debugsidedata(ui, repo, file_, rev=None, **opts):
3875 def debugsidedata(ui, repo, file_, rev=None, **opts):
3876 """dump the side data for a cl/manifest/file revision
3876 """dump the side data for a cl/manifest/file revision
3877
3877
3878 Use --verbose to dump the sidedata content."""
3878 Use --verbose to dump the sidedata content."""
3879 opts = pycompat.byteskwargs(opts)
3879 opts = pycompat.byteskwargs(opts)
3880 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3880 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3881 if rev is not None:
3881 if rev is not None:
3882 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3882 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3883 file_, rev = None, file_
3883 file_, rev = None, file_
3884 elif rev is None:
3884 elif rev is None:
3885 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3885 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3886 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3886 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3887 r = getattr(r, '_revlog', r)
3887 r = getattr(r, '_revlog', r)
3888 try:
3888 try:
3889 sidedata = r.sidedata(r.lookup(rev))
3889 sidedata = r.sidedata(r.lookup(rev))
3890 except KeyError:
3890 except KeyError:
3891 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3891 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3892 if sidedata:
3892 if sidedata:
3893 sidedata = list(sidedata.items())
3893 sidedata = list(sidedata.items())
3894 sidedata.sort()
3894 sidedata.sort()
3895 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3895 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3896 for key, value in sidedata:
3896 for key, value in sidedata:
3897 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3897 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3898 if ui.verbose:
3898 if ui.verbose:
3899 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3899 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3900
3900
3901
3901
3902 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3902 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3903 def debugssl(ui, repo, source=None, **opts):
3903 def debugssl(ui, repo, source=None, **opts):
3904 """test a secure connection to a server
3904 """test a secure connection to a server
3905
3905
3906 This builds the certificate chain for the server on Windows, installing the
3906 This builds the certificate chain for the server on Windows, installing the
3907 missing intermediates and trusted root via Windows Update if necessary. It
3907 missing intermediates and trusted root via Windows Update if necessary. It
3908 does nothing on other platforms.
3908 does nothing on other platforms.
3909
3909
3910 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3910 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3911 that server is used. See :hg:`help urls` for more information.
3911 that server is used. See :hg:`help urls` for more information.
3912
3912
3913 If the update succeeds, retry the original operation. Otherwise, the cause
3913 If the update succeeds, retry the original operation. Otherwise, the cause
3914 of the SSL error is likely another issue.
3914 of the SSL error is likely another issue.
3915 """
3915 """
3916 if not pycompat.iswindows:
3916 if not pycompat.iswindows:
3917 raise error.Abort(
3917 raise error.Abort(
3918 _(b'certificate chain building is only possible on Windows')
3918 _(b'certificate chain building is only possible on Windows')
3919 )
3919 )
3920
3920
3921 if not source:
3921 if not source:
3922 if not repo:
3922 if not repo:
3923 raise error.Abort(
3923 raise error.Abort(
3924 _(
3924 _(
3925 b"there is no Mercurial repository here, and no "
3925 b"there is no Mercurial repository here, and no "
3926 b"server specified"
3926 b"server specified"
3927 )
3927 )
3928 )
3928 )
3929 source = b"default"
3929 source = b"default"
3930
3930
3931 source, branches = urlutil.get_unique_pull_path(
3931 source, branches = urlutil.get_unique_pull_path(
3932 b'debugssl', repo, ui, source
3932 b'debugssl', repo, ui, source
3933 )
3933 )
3934 url = urlutil.url(source)
3934 url = urlutil.url(source)
3935
3935
3936 defaultport = {b'https': 443, b'ssh': 22}
3936 defaultport = {b'https': 443, b'ssh': 22}
3937 if url.scheme in defaultport:
3937 if url.scheme in defaultport:
3938 try:
3938 try:
3939 addr = (url.host, int(url.port or defaultport[url.scheme]))
3939 addr = (url.host, int(url.port or defaultport[url.scheme]))
3940 except ValueError:
3940 except ValueError:
3941 raise error.Abort(_(b"malformed port number in URL"))
3941 raise error.Abort(_(b"malformed port number in URL"))
3942 else:
3942 else:
3943 raise error.Abort(_(b"only https and ssh connections are supported"))
3943 raise error.Abort(_(b"only https and ssh connections are supported"))
3944
3944
3945 from . import win32
3945 from . import win32
3946
3946
3947 s = ssl.wrap_socket(
3947 s = ssl.wrap_socket(
3948 socket.socket(),
3948 socket.socket(),
3949 ssl_version=ssl.PROTOCOL_TLS,
3949 ssl_version=ssl.PROTOCOL_TLS,
3950 cert_reqs=ssl.CERT_NONE,
3950 cert_reqs=ssl.CERT_NONE,
3951 ca_certs=None,
3951 ca_certs=None,
3952 )
3952 )
3953
3953
3954 try:
3954 try:
3955 s.connect(addr)
3955 s.connect(addr)
3956 cert = s.getpeercert(True)
3956 cert = s.getpeercert(True)
3957
3957
3958 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3958 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3959
3959
3960 complete = win32.checkcertificatechain(cert, build=False)
3960 complete = win32.checkcertificatechain(cert, build=False)
3961
3961
3962 if not complete:
3962 if not complete:
3963 ui.status(_(b'certificate chain is incomplete, updating... '))
3963 ui.status(_(b'certificate chain is incomplete, updating... '))
3964
3964
3965 if not win32.checkcertificatechain(cert):
3965 if not win32.checkcertificatechain(cert):
3966 ui.status(_(b'failed.\n'))
3966 ui.status(_(b'failed.\n'))
3967 else:
3967 else:
3968 ui.status(_(b'done.\n'))
3968 ui.status(_(b'done.\n'))
3969 else:
3969 else:
3970 ui.status(_(b'full certificate chain is available\n'))
3970 ui.status(_(b'full certificate chain is available\n'))
3971 finally:
3971 finally:
3972 s.close()
3972 s.close()
3973
3973
3974
3974
3975 @command(
3975 @command(
3976 b"debugbackupbundle",
3976 b"debugbackupbundle",
3977 [
3977 [
3978 (
3978 (
3979 b"",
3979 b"",
3980 b"recover",
3980 b"recover",
3981 b"",
3981 b"",
3982 b"brings the specified changeset back into the repository",
3982 b"brings the specified changeset back into the repository",
3983 )
3983 )
3984 ]
3984 ]
3985 + cmdutil.logopts,
3985 + cmdutil.logopts,
3986 _(b"hg debugbackupbundle [--recover HASH]"),
3986 _(b"hg debugbackupbundle [--recover HASH]"),
3987 )
3987 )
3988 def debugbackupbundle(ui, repo, *pats, **opts):
3988 def debugbackupbundle(ui, repo, *pats, **opts):
3989 """lists the changesets available in backup bundles
3989 """lists the changesets available in backup bundles
3990
3990
3991 Without any arguments, this command prints a list of the changesets in each
3991 Without any arguments, this command prints a list of the changesets in each
3992 backup bundle.
3992 backup bundle.
3993
3993
3994 --recover takes a changeset hash and unbundles the first bundle that
3994 --recover takes a changeset hash and unbundles the first bundle that
3995 contains that hash, which puts that changeset back in your repository.
3995 contains that hash, which puts that changeset back in your repository.
3996
3996
3997 --verbose will print the entire commit message and the bundle path for that
3997 --verbose will print the entire commit message and the bundle path for that
3998 backup.
3998 backup.
3999 """
3999 """
4000 backups = list(
4000 backups = list(
4001 filter(
4001 filter(
4002 os.path.isfile, glob.glob(repo.vfs.join(b"strip-backup") + b"/*.hg")
4002 os.path.isfile, glob.glob(repo.vfs.join(b"strip-backup") + b"/*.hg")
4003 )
4003 )
4004 )
4004 )
4005 backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
4005 backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
4006
4006
4007 opts = pycompat.byteskwargs(opts)
4007 opts = pycompat.byteskwargs(opts)
4008 opts[b"bundle"] = b""
4008 opts[b"bundle"] = b""
4009 opts[b"force"] = None
4009 opts[b"force"] = None
4010 limit = logcmdutil.getlimit(opts)
4010 limit = logcmdutil.getlimit(opts)
4011
4011
4012 def display(other, chlist, displayer):
4012 def display(other, chlist, displayer):
4013 if opts.get(b"newest_first"):
4013 if opts.get(b"newest_first"):
4014 chlist.reverse()
4014 chlist.reverse()
4015 count = 0
4015 count = 0
4016 for n in chlist:
4016 for n in chlist:
4017 if limit is not None and count >= limit:
4017 if limit is not None and count >= limit:
4018 break
4018 break
4019 parents = [
4019 parents = [
4020 True for p in other.changelog.parents(n) if p != repo.nullid
4020 True for p in other.changelog.parents(n) if p != repo.nullid
4021 ]
4021 ]
4022 if opts.get(b"no_merges") and len(parents) == 2:
4022 if opts.get(b"no_merges") and len(parents) == 2:
4023 continue
4023 continue
4024 count += 1
4024 count += 1
4025 displayer.show(other[n])
4025 displayer.show(other[n])
4026
4026
4027 recovernode = opts.get(b"recover")
4027 recovernode = opts.get(b"recover")
4028 if recovernode:
4028 if recovernode:
4029 if scmutil.isrevsymbol(repo, recovernode):
4029 if scmutil.isrevsymbol(repo, recovernode):
4030 ui.warn(_(b"%s already exists in the repo\n") % recovernode)
4030 ui.warn(_(b"%s already exists in the repo\n") % recovernode)
4031 return
4031 return
4032 elif backups:
4032 elif backups:
4033 msg = _(
4033 msg = _(
4034 b"Recover changesets using: hg debugbackupbundle --recover "
4034 b"Recover changesets using: hg debugbackupbundle --recover "
4035 b"<changeset hash>\n\nAvailable backup changesets:"
4035 b"<changeset hash>\n\nAvailable backup changesets:"
4036 )
4036 )
4037 ui.status(msg, label=b"status.removed")
4037 ui.status(msg, label=b"status.removed")
4038 else:
4038 else:
4039 ui.status(_(b"no backup changesets found\n"))
4039 ui.status(_(b"no backup changesets found\n"))
4040 return
4040 return
4041
4041
4042 for backup in backups:
4042 for backup in backups:
4043 # Much of this is copied from the hg incoming logic
4043 # Much of this is copied from the hg incoming logic
4044 source = os.path.relpath(backup, encoding.getcwd())
4044 source = os.path.relpath(backup, encoding.getcwd())
4045 source, branches = urlutil.get_unique_pull_path(
4045 source, branches = urlutil.get_unique_pull_path(
4046 b'debugbackupbundle',
4046 b'debugbackupbundle',
4047 repo,
4047 repo,
4048 ui,
4048 ui,
4049 source,
4049 source,
4050 default_branches=opts.get(b'branch'),
4050 default_branches=opts.get(b'branch'),
4051 )
4051 )
4052 try:
4052 try:
4053 other = hg.peer(repo, opts, source)
4053 other = hg.peer(repo, opts, source)
4054 except error.LookupError as ex:
4054 except error.LookupError as ex:
4055 msg = _(b"\nwarning: unable to open bundle %s") % source
4055 msg = _(b"\nwarning: unable to open bundle %s") % source
4056 hint = _(b"\n(missing parent rev %s)\n") % short(ex.name)
4056 hint = _(b"\n(missing parent rev %s)\n") % short(ex.name)
4057 ui.warn(msg, hint=hint)
4057 ui.warn(msg, hint=hint)
4058 continue
4058 continue
4059 revs, checkout = hg.addbranchrevs(
4059 revs, checkout = hg.addbranchrevs(
4060 repo, other, branches, opts.get(b"rev")
4060 repo, other, branches, opts.get(b"rev")
4061 )
4061 )
4062
4062
4063 if revs:
4063 if revs:
4064 revs = [other.lookup(rev) for rev in revs]
4064 revs = [other.lookup(rev) for rev in revs]
4065
4065
4066 with ui.silent():
4066 with ui.silent():
4067 try:
4067 try:
4068 other, chlist, cleanupfn = bundlerepo.getremotechanges(
4068 other, chlist, cleanupfn = bundlerepo.getremotechanges(
4069 ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
4069 ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
4070 )
4070 )
4071 except error.LookupError:
4071 except error.LookupError:
4072 continue
4072 continue
4073
4073
4074 try:
4074 try:
4075 if not chlist:
4075 if not chlist:
4076 continue
4076 continue
4077 if recovernode:
4077 if recovernode:
4078 with repo.lock(), repo.transaction(b"unbundle") as tr:
4078 with repo.lock(), repo.transaction(b"unbundle") as tr:
4079 if scmutil.isrevsymbol(other, recovernode):
4079 if scmutil.isrevsymbol(other, recovernode):
4080 ui.status(_(b"Unbundling %s\n") % (recovernode))
4080 ui.status(_(b"Unbundling %s\n") % (recovernode))
4081 f = hg.openpath(ui, source)
4081 f = hg.openpath(ui, source)
4082 gen = exchange.readbundle(ui, f, source)
4082 gen = exchange.readbundle(ui, f, source)
4083 if isinstance(gen, bundle2.unbundle20):
4083 if isinstance(gen, bundle2.unbundle20):
4084 bundle2.applybundle(
4084 bundle2.applybundle(
4085 repo,
4085 repo,
4086 gen,
4086 gen,
4087 tr,
4087 tr,
4088 source=b"unbundle",
4088 source=b"unbundle",
4089 url=b"bundle:" + source,
4089 url=b"bundle:" + source,
4090 )
4090 )
4091 else:
4091 else:
4092 gen.apply(repo, b"unbundle", b"bundle:" + source)
4092 gen.apply(repo, b"unbundle", b"bundle:" + source)
4093 break
4093 break
4094 else:
4094 else:
4095 backupdate = encoding.strtolocal(
4095 backupdate = encoding.strtolocal(
4096 time.strftime(
4096 time.strftime(
4097 "%a %H:%M, %Y-%m-%d",
4097 "%a %H:%M, %Y-%m-%d",
4098 time.localtime(os.path.getmtime(source)),
4098 time.localtime(os.path.getmtime(source)),
4099 )
4099 )
4100 )
4100 )
4101 ui.status(b"\n%s\n" % (backupdate.ljust(50)))
4101 ui.status(b"\n%s\n" % (backupdate.ljust(50)))
4102 if ui.verbose:
4102 if ui.verbose:
4103 ui.status(b"%s%s\n" % (b"bundle:".ljust(13), source))
4103 ui.status(b"%s%s\n" % (b"bundle:".ljust(13), source))
4104 else:
4104 else:
4105 opts[
4105 opts[
4106 b"template"
4106 b"template"
4107 ] = b"{label('status.modified', node|short)} {desc|firstline}\n"
4107 ] = b"{label('status.modified', node|short)} {desc|firstline}\n"
4108 displayer = logcmdutil.changesetdisplayer(
4108 displayer = logcmdutil.changesetdisplayer(
4109 ui, other, opts, False
4109 ui, other, opts, False
4110 )
4110 )
4111 display(other, chlist, displayer)
4111 display(other, chlist, displayer)
4112 displayer.close()
4112 displayer.close()
4113 finally:
4113 finally:
4114 cleanupfn()
4114 cleanupfn()
4115
4115
4116
4116
4117 @command(
4117 @command(
4118 b'debugsub',
4118 b'debugsub',
4119 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
4119 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
4120 _(b'[-r REV] [REV]'),
4120 _(b'[-r REV] [REV]'),
4121 )
4121 )
4122 def debugsub(ui, repo, rev=None):
4122 def debugsub(ui, repo, rev=None):
4123 ctx = scmutil.revsingle(repo, rev, None)
4123 ctx = scmutil.revsingle(repo, rev, None)
4124 for k, v in sorted(ctx.substate.items()):
4124 for k, v in sorted(ctx.substate.items()):
4125 ui.writenoi18n(b'path %s\n' % k)
4125 ui.writenoi18n(b'path %s\n' % k)
4126 ui.writenoi18n(b' source %s\n' % v[0])
4126 ui.writenoi18n(b' source %s\n' % v[0])
4127 ui.writenoi18n(b' revision %s\n' % v[1])
4127 ui.writenoi18n(b' revision %s\n' % v[1])
4128
4128
4129
4129
4130 @command(b'debugshell', optionalrepo=True)
4130 @command(b'debugshell', optionalrepo=True)
4131 def debugshell(ui, repo):
4131 def debugshell(ui, repo):
4132 """run an interactive Python interpreter
4132 """run an interactive Python interpreter
4133
4133
4134 The local namespace is provided with a reference to the ui and
4134 The local namespace is provided with a reference to the ui and
4135 the repo instance (if available).
4135 the repo instance (if available).
4136 """
4136 """
4137 import code
4137 import code
4138
4138
4139 imported_objects = {
4139 imported_objects = {
4140 'ui': ui,
4140 'ui': ui,
4141 'repo': repo,
4141 'repo': repo,
4142 }
4142 }
4143
4143
4144 code.interact(local=imported_objects)
4144 code.interact(local=imported_objects)
4145
4145
4146
4146
4147 @command(
4147 @command(
4148 b'debugsuccessorssets',
4148 b'debugsuccessorssets',
4149 [(b'', b'closest', False, _(b'return closest successors sets only'))],
4149 [(b'', b'closest', False, _(b'return closest successors sets only'))],
4150 _(b'[REV]'),
4150 _(b'[REV]'),
4151 )
4151 )
4152 def debugsuccessorssets(ui, repo, *revs, **opts):
4152 def debugsuccessorssets(ui, repo, *revs, **opts):
4153 """show set of successors for revision
4153 """show set of successors for revision
4154
4154
4155 A successors set of changeset A is a consistent group of revisions that
4155 A successors set of changeset A is a consistent group of revisions that
4156 succeed A. It contains non-obsolete changesets only unless closests
4156 succeed A. It contains non-obsolete changesets only unless closests
4157 successors set is set.
4157 successors set is set.
4158
4158
4159 In most cases a changeset A has a single successors set containing a single
4159 In most cases a changeset A has a single successors set containing a single
4160 successor (changeset A replaced by A').
4160 successor (changeset A replaced by A').
4161
4161
4162 A changeset that is made obsolete with no successors are called "pruned".
4162 A changeset that is made obsolete with no successors are called "pruned".
4163 Such changesets have no successors sets at all.
4163 Such changesets have no successors sets at all.
4164
4164
4165 A changeset that has been "split" will have a successors set containing
4165 A changeset that has been "split" will have a successors set containing
4166 more than one successor.
4166 more than one successor.
4167
4167
4168 A changeset that has been rewritten in multiple different ways is called
4168 A changeset that has been rewritten in multiple different ways is called
4169 "divergent". Such changesets have multiple successor sets (each of which
4169 "divergent". Such changesets have multiple successor sets (each of which
4170 may also be split, i.e. have multiple successors).
4170 may also be split, i.e. have multiple successors).
4171
4171
4172 Results are displayed as follows::
4172 Results are displayed as follows::
4173
4173
4174 <rev1>
4174 <rev1>
4175 <successors-1A>
4175 <successors-1A>
4176 <rev2>
4176 <rev2>
4177 <successors-2A>
4177 <successors-2A>
4178 <successors-2B1> <successors-2B2> <successors-2B3>
4178 <successors-2B1> <successors-2B2> <successors-2B3>
4179
4179
4180 Here rev2 has two possible (i.e. divergent) successors sets. The first
4180 Here rev2 has two possible (i.e. divergent) successors sets. The first
4181 holds one element, whereas the second holds three (i.e. the changeset has
4181 holds one element, whereas the second holds three (i.e. the changeset has
4182 been split).
4182 been split).
4183 """
4183 """
4184 # passed to successorssets caching computation from one call to another
4184 # passed to successorssets caching computation from one call to another
4185 cache = {}
4185 cache = {}
4186 ctx2str = bytes
4186 ctx2str = bytes
4187 node2str = short
4187 node2str = short
4188 for rev in logcmdutil.revrange(repo, revs):
4188 for rev in logcmdutil.revrange(repo, revs):
4189 ctx = repo[rev]
4189 ctx = repo[rev]
4190 ui.write(b'%s\n' % ctx2str(ctx))
4190 ui.write(b'%s\n' % ctx2str(ctx))
4191 for succsset in obsutil.successorssets(
4191 for succsset in obsutil.successorssets(
4192 repo, ctx.node(), closest=opts['closest'], cache=cache
4192 repo, ctx.node(), closest=opts['closest'], cache=cache
4193 ):
4193 ):
4194 if succsset:
4194 if succsset:
4195 ui.write(b' ')
4195 ui.write(b' ')
4196 ui.write(node2str(succsset[0]))
4196 ui.write(node2str(succsset[0]))
4197 for node in succsset[1:]:
4197 for node in succsset[1:]:
4198 ui.write(b' ')
4198 ui.write(b' ')
4199 ui.write(node2str(node))
4199 ui.write(node2str(node))
4200 ui.write(b'\n')
4200 ui.write(b'\n')
4201
4201
4202
4202
4203 @command(b'debugtagscache', [])
4203 @command(b'debugtagscache', [])
4204 def debugtagscache(ui, repo):
4204 def debugtagscache(ui, repo):
4205 """display the contents of .hg/cache/hgtagsfnodes1"""
4205 """display the contents of .hg/cache/hgtagsfnodes1"""
4206 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
4206 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
4207 flog = repo.file(b'.hgtags')
4207 flog = repo.file(b'.hgtags')
4208 for r in repo:
4208 for r in repo:
4209 node = repo[r].node()
4209 node = repo[r].node()
4210 tagsnode = cache.getfnode(node, computemissing=False)
4210 tagsnode = cache.getfnode(node, computemissing=False)
4211 if tagsnode:
4211 if tagsnode:
4212 tagsnodedisplay = hex(tagsnode)
4212 tagsnodedisplay = hex(tagsnode)
4213 if not flog.hasnode(tagsnode):
4213 if not flog.hasnode(tagsnode):
4214 tagsnodedisplay += b' (unknown node)'
4214 tagsnodedisplay += b' (unknown node)'
4215 elif tagsnode is None:
4215 elif tagsnode is None:
4216 tagsnodedisplay = b'missing'
4216 tagsnodedisplay = b'missing'
4217 else:
4217 else:
4218 tagsnodedisplay = b'invalid'
4218 tagsnodedisplay = b'invalid'
4219
4219
4220 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
4220 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
4221
4221
4222
4222
4223 @command(
4223 @command(
4224 b'debugtemplate',
4224 b'debugtemplate',
4225 [
4225 [
4226 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
4226 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
4227 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
4227 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
4228 ],
4228 ],
4229 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
4229 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
4230 optionalrepo=True,
4230 optionalrepo=True,
4231 )
4231 )
4232 def debugtemplate(ui, repo, tmpl, **opts):
4232 def debugtemplate(ui, repo, tmpl, **opts):
4233 """parse and apply a template
4233 """parse and apply a template
4234
4234
4235 If -r/--rev is given, the template is processed as a log template and
4235 If -r/--rev is given, the template is processed as a log template and
4236 applied to the given changesets. Otherwise, it is processed as a generic
4236 applied to the given changesets. Otherwise, it is processed as a generic
4237 template.
4237 template.
4238
4238
4239 Use --verbose to print the parsed tree.
4239 Use --verbose to print the parsed tree.
4240 """
4240 """
4241 revs = None
4241 revs = None
4242 if opts['rev']:
4242 if opts['rev']:
4243 if repo is None:
4243 if repo is None:
4244 raise error.RepoError(
4244 raise error.RepoError(
4245 _(b'there is no Mercurial repository here (.hg not found)')
4245 _(b'there is no Mercurial repository here (.hg not found)')
4246 )
4246 )
4247 revs = logcmdutil.revrange(repo, opts['rev'])
4247 revs = logcmdutil.revrange(repo, opts['rev'])
4248
4248
4249 props = {}
4249 props = {}
4250 for d in opts['define']:
4250 for d in opts['define']:
4251 try:
4251 try:
4252 k, v = (e.strip() for e in d.split(b'=', 1))
4252 k, v = (e.strip() for e in d.split(b'=', 1))
4253 if not k or k == b'ui':
4253 if not k or k == b'ui':
4254 raise ValueError
4254 raise ValueError
4255 props[k] = v
4255 props[k] = v
4256 except ValueError:
4256 except ValueError:
4257 raise error.Abort(_(b'malformed keyword definition: %s') % d)
4257 raise error.Abort(_(b'malformed keyword definition: %s') % d)
4258
4258
4259 if ui.verbose:
4259 if ui.verbose:
4260 aliases = ui.configitems(b'templatealias')
4260 aliases = ui.configitems(b'templatealias')
4261 tree = templater.parse(tmpl)
4261 tree = templater.parse(tmpl)
4262 ui.note(templater.prettyformat(tree), b'\n')
4262 ui.note(templater.prettyformat(tree), b'\n')
4263 newtree = templater.expandaliases(tree, aliases)
4263 newtree = templater.expandaliases(tree, aliases)
4264 if newtree != tree:
4264 if newtree != tree:
4265 ui.notenoi18n(
4265 ui.notenoi18n(
4266 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
4266 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
4267 )
4267 )
4268
4268
4269 if revs is None:
4269 if revs is None:
4270 tres = formatter.templateresources(ui, repo)
4270 tres = formatter.templateresources(ui, repo)
4271 t = formatter.maketemplater(ui, tmpl, resources=tres)
4271 t = formatter.maketemplater(ui, tmpl, resources=tres)
4272 if ui.verbose:
4272 if ui.verbose:
4273 kwds, funcs = t.symbolsuseddefault()
4273 kwds, funcs = t.symbolsuseddefault()
4274 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
4274 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
4275 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
4275 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
4276 ui.write(t.renderdefault(props))
4276 ui.write(t.renderdefault(props))
4277 else:
4277 else:
4278 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
4278 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
4279 if ui.verbose:
4279 if ui.verbose:
4280 kwds, funcs = displayer.t.symbolsuseddefault()
4280 kwds, funcs = displayer.t.symbolsuseddefault()
4281 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
4281 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
4282 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
4282 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
4283 for r in revs:
4283 for r in revs:
4284 displayer.show(repo[r], **pycompat.strkwargs(props))
4284 displayer.show(repo[r], **pycompat.strkwargs(props))
4285 displayer.close()
4285 displayer.close()
4286
4286
4287
4287
4288 @command(
4288 @command(
4289 b'debuguigetpass',
4289 b'debuguigetpass',
4290 [
4290 [
4291 (b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),
4291 (b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),
4292 ],
4292 ],
4293 _(b'[-p TEXT]'),
4293 _(b'[-p TEXT]'),
4294 norepo=True,
4294 norepo=True,
4295 )
4295 )
4296 def debuguigetpass(ui, prompt=b''):
4296 def debuguigetpass(ui, prompt=b''):
4297 """show prompt to type password"""
4297 """show prompt to type password"""
4298 r = ui.getpass(prompt)
4298 r = ui.getpass(prompt)
4299 if r is None:
4299 if r is None:
4300 r = b"<default response>"
4300 r = b"<default response>"
4301 ui.writenoi18n(b'response: %s\n' % r)
4301 ui.writenoi18n(b'response: %s\n' % r)
4302
4302
4303
4303
4304 @command(
4304 @command(
4305 b'debuguiprompt',
4305 b'debuguiprompt',
4306 [
4306 [
4307 (b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),
4307 (b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),
4308 ],
4308 ],
4309 _(b'[-p TEXT]'),
4309 _(b'[-p TEXT]'),
4310 norepo=True,
4310 norepo=True,
4311 )
4311 )
4312 def debuguiprompt(ui, prompt=b''):
4312 def debuguiprompt(ui, prompt=b''):
4313 """show plain prompt"""
4313 """show plain prompt"""
4314 r = ui.prompt(prompt)
4314 r = ui.prompt(prompt)
4315 ui.writenoi18n(b'response: %s\n' % r)
4315 ui.writenoi18n(b'response: %s\n' % r)
4316
4316
4317
4317
4318 @command(b'debugupdatecaches', [])
4318 @command(b'debugupdatecaches', [])
4319 def debugupdatecaches(ui, repo, *pats, **opts):
4319 def debugupdatecaches(ui, repo, *pats, **opts):
4320 """warm all known caches in the repository"""
4320 """warm all known caches in the repository"""
4321 with repo.wlock(), repo.lock():
4321 with repo.wlock(), repo.lock():
4322 repo.updatecaches(caches=repository.CACHES_ALL)
4322 repo.updatecaches(caches=repository.CACHES_ALL)
4323
4323
4324
4324
4325 @command(
4325 @command(
4326 b'debugupgraderepo',
4326 b'debugupgraderepo',
4327 [
4327 [
4328 (
4328 (
4329 b'o',
4329 b'o',
4330 b'optimize',
4330 b'optimize',
4331 [],
4331 [],
4332 _(b'extra optimization to perform'),
4332 _(b'extra optimization to perform'),
4333 _(b'NAME'),
4333 _(b'NAME'),
4334 ),
4334 ),
4335 (b'', b'run', False, _(b'performs an upgrade')),
4335 (b'', b'run', False, _(b'performs an upgrade')),
4336 (b'', b'backup', True, _(b'keep the old repository content around')),
4336 (b'', b'backup', True, _(b'keep the old repository content around')),
4337 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
4337 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
4338 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
4338 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
4339 (b'', b'filelogs', None, _(b'select all filelogs for upgrade')),
4339 (b'', b'filelogs', None, _(b'select all filelogs for upgrade')),
4340 ],
4340 ],
4341 )
4341 )
4342 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
4342 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
4343 """upgrade a repository to use different features
4343 """upgrade a repository to use different features
4344
4344
4345 If no arguments are specified, the repository is evaluated for upgrade
4345 If no arguments are specified, the repository is evaluated for upgrade
4346 and a list of problems and potential optimizations is printed.
4346 and a list of problems and potential optimizations is printed.
4347
4347
4348 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
4348 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
4349 can be influenced via additional arguments. More details will be provided
4349 can be influenced via additional arguments. More details will be provided
4350 by the command output when run without ``--run``.
4350 by the command output when run without ``--run``.
4351
4351
4352 During the upgrade, the repository will be locked and no writes will be
4352 During the upgrade, the repository will be locked and no writes will be
4353 allowed.
4353 allowed.
4354
4354
4355 At the end of the upgrade, the repository may not be readable while new
4355 At the end of the upgrade, the repository may not be readable while new
4356 repository data is swapped in. This window will be as long as it takes to
4356 repository data is swapped in. This window will be as long as it takes to
4357 rename some directories inside the ``.hg`` directory. On most machines, this
4357 rename some directories inside the ``.hg`` directory. On most machines, this
4358 should complete almost instantaneously and the chances of a consumer being
4358 should complete almost instantaneously and the chances of a consumer being
4359 unable to access the repository should be low.
4359 unable to access the repository should be low.
4360
4360
4361 By default, all revlogs will be upgraded. You can restrict this using flags
4361 By default, all revlogs will be upgraded. You can restrict this using flags
4362 such as `--manifest`:
4362 such as `--manifest`:
4363
4363
4364 * `--manifest`: only optimize the manifest
4364 * `--manifest`: only optimize the manifest
4365 * `--no-manifest`: optimize all revlog but the manifest
4365 * `--no-manifest`: optimize all revlog but the manifest
4366 * `--changelog`: optimize the changelog only
4366 * `--changelog`: optimize the changelog only
4367 * `--no-changelog --no-manifest`: optimize filelogs only
4367 * `--no-changelog --no-manifest`: optimize filelogs only
4368 * `--filelogs`: optimize the filelogs only
4368 * `--filelogs`: optimize the filelogs only
4369 * `--no-changelog --no-manifest --no-filelogs`: skip all revlog optimizations
4369 * `--no-changelog --no-manifest --no-filelogs`: skip all revlog optimizations
4370 """
4370 """
4371 return upgrade.upgraderepo(
4371 return upgrade.upgraderepo(
4372 ui, repo, run=run, optimize=set(optimize), backup=backup, **opts
4372 ui, repo, run=run, optimize=set(optimize), backup=backup, **opts
4373 )
4373 )
4374
4374
4375
4375
4376 @command(
4376 @command(
4377 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
4377 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
4378 )
4378 )
4379 def debugwalk(ui, repo, *pats, **opts):
4379 def debugwalk(ui, repo, *pats, **opts):
4380 """show how files match on given patterns"""
4380 """show how files match on given patterns"""
4381 opts = pycompat.byteskwargs(opts)
4381 opts = pycompat.byteskwargs(opts)
4382 m = scmutil.match(repo[None], pats, opts)
4382 m = scmutil.match(repo[None], pats, opts)
4383 if ui.verbose:
4383 if ui.verbose:
4384 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
4384 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
4385 items = list(repo[None].walk(m))
4385 items = list(repo[None].walk(m))
4386 if not items:
4386 if not items:
4387 return
4387 return
4388 f = lambda fn: fn
4388 f = lambda fn: fn
4389 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
4389 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
4390 f = lambda fn: util.normpath(fn)
4390 f = lambda fn: util.normpath(fn)
4391 fmt = b'f %%-%ds %%-%ds %%s' % (
4391 fmt = b'f %%-%ds %%-%ds %%s' % (
4392 max([len(abs) for abs in items]),
4392 max([len(abs) for abs in items]),
4393 max([len(repo.pathto(abs)) for abs in items]),
4393 max([len(repo.pathto(abs)) for abs in items]),
4394 )
4394 )
4395 for abs in items:
4395 for abs in items:
4396 line = fmt % (
4396 line = fmt % (
4397 abs,
4397 abs,
4398 f(repo.pathto(abs)),
4398 f(repo.pathto(abs)),
4399 m.exact(abs) and b'exact' or b'',
4399 m.exact(abs) and b'exact' or b'',
4400 )
4400 )
4401 ui.write(b"%s\n" % line.rstrip())
4401 ui.write(b"%s\n" % line.rstrip())
4402
4402
4403
4403
4404 @command(b'debugwhyunstable', [], _(b'REV'))
4404 @command(b'debugwhyunstable', [], _(b'REV'))
4405 def debugwhyunstable(ui, repo, rev):
4405 def debugwhyunstable(ui, repo, rev):
4406 """explain instabilities of a changeset"""
4406 """explain instabilities of a changeset"""
4407 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
4407 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
4408 dnodes = b''
4408 dnodes = b''
4409 if entry.get(b'divergentnodes'):
4409 if entry.get(b'divergentnodes'):
4410 dnodes = (
4410 dnodes = (
4411 b' '.join(
4411 b' '.join(
4412 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
4412 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
4413 for ctx in entry[b'divergentnodes']
4413 for ctx in entry[b'divergentnodes']
4414 )
4414 )
4415 + b' '
4415 + b' '
4416 )
4416 )
4417 ui.write(
4417 ui.write(
4418 b'%s: %s%s %s\n'
4418 b'%s: %s%s %s\n'
4419 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
4419 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
4420 )
4420 )
4421
4421
4422
4422
4423 @command(
4423 @command(
4424 b'debugwireargs',
4424 b'debugwireargs',
4425 [
4425 [
4426 (b'', b'three', b'', b'three'),
4426 (b'', b'three', b'', b'three'),
4427 (b'', b'four', b'', b'four'),
4427 (b'', b'four', b'', b'four'),
4428 (b'', b'five', b'', b'five'),
4428 (b'', b'five', b'', b'five'),
4429 ]
4429 ]
4430 + cmdutil.remoteopts,
4430 + cmdutil.remoteopts,
4431 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
4431 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
4432 norepo=True,
4432 norepo=True,
4433 )
4433 )
4434 def debugwireargs(ui, repopath, *vals, **opts):
4434 def debugwireargs(ui, repopath, *vals, **opts):
4435 opts = pycompat.byteskwargs(opts)
4435 opts = pycompat.byteskwargs(opts)
4436 repo = hg.peer(ui, opts, repopath)
4436 repo = hg.peer(ui, opts, repopath)
4437 try:
4437 try:
4438 for opt in cmdutil.remoteopts:
4438 for opt in cmdutil.remoteopts:
4439 del opts[opt[1]]
4439 del opts[opt[1]]
4440 args = {}
4440 args = {}
4441 for k, v in opts.items():
4441 for k, v in opts.items():
4442 if v:
4442 if v:
4443 args[k] = v
4443 args[k] = v
4444 args = pycompat.strkwargs(args)
4444 args = pycompat.strkwargs(args)
4445 # run twice to check that we don't mess up the stream for the next command
4445 # run twice to check that we don't mess up the stream for the next command
4446 res1 = repo.debugwireargs(*vals, **args)
4446 res1 = repo.debugwireargs(*vals, **args)
4447 res2 = repo.debugwireargs(*vals, **args)
4447 res2 = repo.debugwireargs(*vals, **args)
4448 ui.write(b"%s\n" % res1)
4448 ui.write(b"%s\n" % res1)
4449 if res1 != res2:
4449 if res1 != res2:
4450 ui.warn(b"%s\n" % res2)
4450 ui.warn(b"%s\n" % res2)
4451 finally:
4451 finally:
4452 repo.close()
4452 repo.close()
4453
4453
4454
4454
4455 def _parsewirelangblocks(fh):
4455 def _parsewirelangblocks(fh):
4456 activeaction = None
4456 activeaction = None
4457 blocklines = []
4457 blocklines = []
4458 lastindent = 0
4458 lastindent = 0
4459
4459
4460 for line in fh:
4460 for line in fh:
4461 line = line.rstrip()
4461 line = line.rstrip()
4462 if not line:
4462 if not line:
4463 continue
4463 continue
4464
4464
4465 if line.startswith(b'#'):
4465 if line.startswith(b'#'):
4466 continue
4466 continue
4467
4467
4468 if not line.startswith(b' '):
4468 if not line.startswith(b' '):
4469 # New block. Flush previous one.
4469 # New block. Flush previous one.
4470 if activeaction:
4470 if activeaction:
4471 yield activeaction, blocklines
4471 yield activeaction, blocklines
4472
4472
4473 activeaction = line
4473 activeaction = line
4474 blocklines = []
4474 blocklines = []
4475 lastindent = 0
4475 lastindent = 0
4476 continue
4476 continue
4477
4477
4478 # Else we start with an indent.
4478 # Else we start with an indent.
4479
4479
4480 if not activeaction:
4480 if not activeaction:
4481 raise error.Abort(_(b'indented line outside of block'))
4481 raise error.Abort(_(b'indented line outside of block'))
4482
4482
4483 indent = len(line) - len(line.lstrip())
4483 indent = len(line) - len(line.lstrip())
4484
4484
4485 # If this line is indented more than the last line, concatenate it.
4485 # If this line is indented more than the last line, concatenate it.
4486 if indent > lastindent and blocklines:
4486 if indent > lastindent and blocklines:
4487 blocklines[-1] += line.lstrip()
4487 blocklines[-1] += line.lstrip()
4488 else:
4488 else:
4489 blocklines.append(line)
4489 blocklines.append(line)
4490 lastindent = indent
4490 lastindent = indent
4491
4491
4492 # Flush last block.
4492 # Flush last block.
4493 if activeaction:
4493 if activeaction:
4494 yield activeaction, blocklines
4494 yield activeaction, blocklines
4495
4495
4496
4496
4497 @command(
4497 @command(
4498 b'debugwireproto',
4498 b'debugwireproto',
4499 [
4499 [
4500 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
4500 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
4501 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
4501 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
4502 (
4502 (
4503 b'',
4503 b'',
4504 b'noreadstderr',
4504 b'noreadstderr',
4505 False,
4505 False,
4506 _(b'do not read from stderr of the remote'),
4506 _(b'do not read from stderr of the remote'),
4507 ),
4507 ),
4508 (
4508 (
4509 b'',
4509 b'',
4510 b'nologhandshake',
4510 b'nologhandshake',
4511 False,
4511 False,
4512 _(b'do not log I/O related to the peer handshake'),
4512 _(b'do not log I/O related to the peer handshake'),
4513 ),
4513 ),
4514 ]
4514 ]
4515 + cmdutil.remoteopts,
4515 + cmdutil.remoteopts,
4516 _(b'[PATH]'),
4516 _(b'[PATH]'),
4517 optionalrepo=True,
4517 optionalrepo=True,
4518 )
4518 )
4519 def debugwireproto(ui, repo, path=None, **opts):
4519 def debugwireproto(ui, repo, path=None, **opts):
4520 """send wire protocol commands to a server
4520 """send wire protocol commands to a server
4521
4521
4522 This command can be used to issue wire protocol commands to remote
4522 This command can be used to issue wire protocol commands to remote
4523 peers and to debug the raw data being exchanged.
4523 peers and to debug the raw data being exchanged.
4524
4524
4525 ``--localssh`` will start an SSH server against the current repository
4525 ``--localssh`` will start an SSH server against the current repository
4526 and connect to that. By default, the connection will perform a handshake
4526 and connect to that. By default, the connection will perform a handshake
4527 and establish an appropriate peer instance.
4527 and establish an appropriate peer instance.
4528
4528
4529 ``--peer`` can be used to bypass the handshake protocol and construct a
4529 ``--peer`` can be used to bypass the handshake protocol and construct a
4530 peer instance using the specified class type. Valid values are ``raw``,
4530 peer instance using the specified class type. Valid values are ``raw``,
4531 ``ssh1``. ``raw`` instances only allow sending raw data payloads and
4531 ``ssh1``. ``raw`` instances only allow sending raw data payloads and
4532 don't support higher-level command actions.
4532 don't support higher-level command actions.
4533
4533
4534 ``--noreadstderr`` can be used to disable automatic reading from stderr
4534 ``--noreadstderr`` can be used to disable automatic reading from stderr
4535 of the peer (for SSH connections only). Disabling automatic reading of
4535 of the peer (for SSH connections only). Disabling automatic reading of
4536 stderr is useful for making output more deterministic.
4536 stderr is useful for making output more deterministic.
4537
4537
4538 Commands are issued via a mini language which is specified via stdin.
4538 Commands are issued via a mini language which is specified via stdin.
4539 The language consists of individual actions to perform. An action is
4539 The language consists of individual actions to perform. An action is
4540 defined by a block. A block is defined as a line with no leading
4540 defined by a block. A block is defined as a line with no leading
4541 space followed by 0 or more lines with leading space. Blocks are
4541 space followed by 0 or more lines with leading space. Blocks are
4542 effectively a high-level command with additional metadata.
4542 effectively a high-level command with additional metadata.
4543
4543
4544 Lines beginning with ``#`` are ignored.
4544 Lines beginning with ``#`` are ignored.
4545
4545
4546 The following sections denote available actions.
4546 The following sections denote available actions.
4547
4547
4548 raw
4548 raw
4549 ---
4549 ---
4550
4550
4551 Send raw data to the server.
4551 Send raw data to the server.
4552
4552
4553 The block payload contains the raw data to send as one atomic send
4553 The block payload contains the raw data to send as one atomic send
4554 operation. The data may not actually be delivered in a single system
4554 operation. The data may not actually be delivered in a single system
4555 call: it depends on the abilities of the transport being used.
4555 call: it depends on the abilities of the transport being used.
4556
4556
4557 Each line in the block is de-indented and concatenated. Then, that
4557 Each line in the block is de-indented and concatenated. Then, that
4558 value is evaluated as a Python b'' literal. This allows the use of
4558 value is evaluated as a Python b'' literal. This allows the use of
4559 backslash escaping, etc.
4559 backslash escaping, etc.
4560
4560
4561 raw+
4561 raw+
4562 ----
4562 ----
4563
4563
4564 Behaves like ``raw`` except flushes output afterwards.
4564 Behaves like ``raw`` except flushes output afterwards.
4565
4565
4566 command <X>
4566 command <X>
4567 -----------
4567 -----------
4568
4568
4569 Send a request to run a named command, whose name follows the ``command``
4569 Send a request to run a named command, whose name follows the ``command``
4570 string.
4570 string.
4571
4571
4572 Arguments to the command are defined as lines in this block. The format of
4572 Arguments to the command are defined as lines in this block. The format of
4573 each line is ``<key> <value>``. e.g.::
4573 each line is ``<key> <value>``. e.g.::
4574
4574
4575 command listkeys
4575 command listkeys
4576 namespace bookmarks
4576 namespace bookmarks
4577
4577
4578 If the value begins with ``eval:``, it will be interpreted as a Python
4578 If the value begins with ``eval:``, it will be interpreted as a Python
4579 literal expression. Otherwise values are interpreted as Python b'' literals.
4579 literal expression. Otherwise values are interpreted as Python b'' literals.
4580 This allows sending complex types and encoding special byte sequences via
4580 This allows sending complex types and encoding special byte sequences via
4581 backslash escaping.
4581 backslash escaping.
4582
4582
4583 The following arguments have special meaning:
4583 The following arguments have special meaning:
4584
4584
4585 ``PUSHFILE``
4585 ``PUSHFILE``
4586 When defined, the *push* mechanism of the peer will be used instead
4586 When defined, the *push* mechanism of the peer will be used instead
4587 of the static request-response mechanism and the content of the
4587 of the static request-response mechanism and the content of the
4588 file specified in the value of this argument will be sent as the
4588 file specified in the value of this argument will be sent as the
4589 command payload.
4589 command payload.
4590
4590
4591 This can be used to submit a local bundle file to the remote.
4591 This can be used to submit a local bundle file to the remote.
4592
4592
4593 batchbegin
4593 batchbegin
4594 ----------
4594 ----------
4595
4595
4596 Instruct the peer to begin a batched send.
4596 Instruct the peer to begin a batched send.
4597
4597
4598 All ``command`` blocks are queued for execution until the next
4598 All ``command`` blocks are queued for execution until the next
4599 ``batchsubmit`` block.
4599 ``batchsubmit`` block.
4600
4600
4601 batchsubmit
4601 batchsubmit
4602 -----------
4602 -----------
4603
4603
4604 Submit previously queued ``command`` blocks as a batch request.
4604 Submit previously queued ``command`` blocks as a batch request.
4605
4605
4606 This action MUST be paired with a ``batchbegin`` action.
4606 This action MUST be paired with a ``batchbegin`` action.
4607
4607
4608 httprequest <method> <path>
4608 httprequest <method> <path>
4609 ---------------------------
4609 ---------------------------
4610
4610
4611 (HTTP peer only)
4611 (HTTP peer only)
4612
4612
4613 Send an HTTP request to the peer.
4613 Send an HTTP request to the peer.
4614
4614
4615 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
4615 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
4616
4616
4617 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
4617 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
4618 headers to add to the request. e.g. ``Accept: foo``.
4618 headers to add to the request. e.g. ``Accept: foo``.
4619
4619
4620 The following arguments are special:
4620 The following arguments are special:
4621
4621
4622 ``BODYFILE``
4622 ``BODYFILE``
4623 The content of the file defined as the value to this argument will be
4623 The content of the file defined as the value to this argument will be
4624 transferred verbatim as the HTTP request body.
4624 transferred verbatim as the HTTP request body.
4625
4625
4626 ``frame <type> <flags> <payload>``
4626 ``frame <type> <flags> <payload>``
4627 Send a unified protocol frame as part of the request body.
4627 Send a unified protocol frame as part of the request body.
4628
4628
4629 All frames will be collected and sent as the body to the HTTP
4629 All frames will be collected and sent as the body to the HTTP
4630 request.
4630 request.
4631
4631
4632 close
4632 close
4633 -----
4633 -----
4634
4634
4635 Close the connection to the server.
4635 Close the connection to the server.
4636
4636
4637 flush
4637 flush
4638 -----
4638 -----
4639
4639
4640 Flush data written to the server.
4640 Flush data written to the server.
4641
4641
4642 readavailable
4642 readavailable
4643 -------------
4643 -------------
4644
4644
4645 Close the write end of the connection and read all available data from
4645 Close the write end of the connection and read all available data from
4646 the server.
4646 the server.
4647
4647
4648 If the connection to the server encompasses multiple pipes, we poll both
4648 If the connection to the server encompasses multiple pipes, we poll both
4649 pipes and read available data.
4649 pipes and read available data.
4650
4650
4651 readline
4651 readline
4652 --------
4652 --------
4653
4653
4654 Read a line of output from the server. If there are multiple output
4654 Read a line of output from the server. If there are multiple output
4655 pipes, reads only the main pipe.
4655 pipes, reads only the main pipe.
4656
4656
4657 ereadline
4657 ereadline
4658 ---------
4658 ---------
4659
4659
4660 Like ``readline``, but read from the stderr pipe, if available.
4660 Like ``readline``, but read from the stderr pipe, if available.
4661
4661
4662 read <X>
4662 read <X>
4663 --------
4663 --------
4664
4664
4665 ``read()`` N bytes from the server's main output pipe.
4665 ``read()`` N bytes from the server's main output pipe.
4666
4666
4667 eread <X>
4667 eread <X>
4668 ---------
4668 ---------
4669
4669
4670 ``read()`` N bytes from the server's stderr pipe, if available.
4670 ``read()`` N bytes from the server's stderr pipe, if available.
4671
4671
4672 Specifying Unified Frame-Based Protocol Frames
4672 Specifying Unified Frame-Based Protocol Frames
4673 ----------------------------------------------
4673 ----------------------------------------------
4674
4674
4675 It is possible to emit a *Unified Frame-Based Protocol* by using special
4675 It is possible to emit a *Unified Frame-Based Protocol* by using special
4676 syntax.
4676 syntax.
4677
4677
4678 A frame is composed as a type, flags, and payload. These can be parsed
4678 A frame is composed as a type, flags, and payload. These can be parsed
4679 from a string of the form:
4679 from a string of the form:
4680
4680
4681 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
4681 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
4682
4682
4683 ``request-id`` and ``stream-id`` are integers defining the request and
4683 ``request-id`` and ``stream-id`` are integers defining the request and
4684 stream identifiers.
4684 stream identifiers.
4685
4685
4686 ``type`` can be an integer value for the frame type or the string name
4686 ``type`` can be an integer value for the frame type or the string name
4687 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
4687 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
4688 ``command-name``.
4688 ``command-name``.
4689
4689
4690 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
4690 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
4691 components. Each component (and there can be just one) can be an integer
4691 components. Each component (and there can be just one) can be an integer
4692 or a flag name for stream flags or frame flags, respectively. Values are
4692 or a flag name for stream flags or frame flags, respectively. Values are
4693 resolved to integers and then bitwise OR'd together.
4693 resolved to integers and then bitwise OR'd together.
4694
4694
4695 ``payload`` represents the raw frame payload. If it begins with
4695 ``payload`` represents the raw frame payload. If it begins with
4696 ``cbor:``, the following string is evaluated as Python code and the
4696 ``cbor:``, the following string is evaluated as Python code and the
4697 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
4697 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
4698 as a Python byte string literal.
4698 as a Python byte string literal.
4699 """
4699 """
4700 opts = pycompat.byteskwargs(opts)
4700 opts = pycompat.byteskwargs(opts)
4701
4701
4702 if opts[b'localssh'] and not repo:
4702 if opts[b'localssh'] and not repo:
4703 raise error.Abort(_(b'--localssh requires a repository'))
4703 raise error.Abort(_(b'--localssh requires a repository'))
4704
4704
4705 if opts[b'peer'] and opts[b'peer'] not in (
4705 if opts[b'peer'] and opts[b'peer'] not in (
4706 b'raw',
4706 b'raw',
4707 b'ssh1',
4707 b'ssh1',
4708 ):
4708 ):
4709 raise error.Abort(
4709 raise error.Abort(
4710 _(b'invalid value for --peer'),
4710 _(b'invalid value for --peer'),
4711 hint=_(b'valid values are "raw" and "ssh1"'),
4711 hint=_(b'valid values are "raw" and "ssh1"'),
4712 )
4712 )
4713
4713
4714 if path and opts[b'localssh']:
4714 if path and opts[b'localssh']:
4715 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
4715 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
4716
4716
4717 if ui.interactive():
4717 if ui.interactive():
4718 ui.write(_(b'(waiting for commands on stdin)\n'))
4718 ui.write(_(b'(waiting for commands on stdin)\n'))
4719
4719
4720 blocks = list(_parsewirelangblocks(ui.fin))
4720 blocks = list(_parsewirelangblocks(ui.fin))
4721
4721
4722 proc = None
4722 proc = None
4723 stdin = None
4723 stdin = None
4724 stdout = None
4724 stdout = None
4725 stderr = None
4725 stderr = None
4726 opener = None
4726 opener = None
4727
4727
4728 if opts[b'localssh']:
4728 if opts[b'localssh']:
4729 # We start the SSH server in its own process so there is process
4729 # We start the SSH server in its own process so there is process
4730 # separation. This prevents a whole class of potential bugs around
4730 # separation. This prevents a whole class of potential bugs around
4731 # shared state from interfering with server operation.
4731 # shared state from interfering with server operation.
4732 args = procutil.hgcmd() + [
4732 args = procutil.hgcmd() + [
4733 b'-R',
4733 b'-R',
4734 repo.root,
4734 repo.root,
4735 b'debugserve',
4735 b'debugserve',
4736 b'--sshstdio',
4736 b'--sshstdio',
4737 ]
4737 ]
4738 proc = subprocess.Popen(
4738 proc = subprocess.Popen(
4739 pycompat.rapply(procutil.tonativestr, args),
4739 pycompat.rapply(procutil.tonativestr, args),
4740 stdin=subprocess.PIPE,
4740 stdin=subprocess.PIPE,
4741 stdout=subprocess.PIPE,
4741 stdout=subprocess.PIPE,
4742 stderr=subprocess.PIPE,
4742 stderr=subprocess.PIPE,
4743 bufsize=0,
4743 bufsize=0,
4744 )
4744 )
4745
4745
4746 stdin = proc.stdin
4746 stdin = proc.stdin
4747 stdout = proc.stdout
4747 stdout = proc.stdout
4748 stderr = proc.stderr
4748 stderr = proc.stderr
4749
4749
4750 # We turn the pipes into observers so we can log I/O.
4750 # We turn the pipes into observers so we can log I/O.
4751 if ui.verbose or opts[b'peer'] == b'raw':
4751 if ui.verbose or opts[b'peer'] == b'raw':
4752 stdin = util.makeloggingfileobject(
4752 stdin = util.makeloggingfileobject(
4753 ui, proc.stdin, b'i', logdata=True
4753 ui, proc.stdin, b'i', logdata=True
4754 )
4754 )
4755 stdout = util.makeloggingfileobject(
4755 stdout = util.makeloggingfileobject(
4756 ui, proc.stdout, b'o', logdata=True
4756 ui, proc.stdout, b'o', logdata=True
4757 )
4757 )
4758 stderr = util.makeloggingfileobject(
4758 stderr = util.makeloggingfileobject(
4759 ui, proc.stderr, b'e', logdata=True
4759 ui, proc.stderr, b'e', logdata=True
4760 )
4760 )
4761
4761
4762 # --localssh also implies the peer connection settings.
4762 # --localssh also implies the peer connection settings.
4763
4763
4764 url = b'ssh://localserver'
4764 url = b'ssh://localserver'
4765 autoreadstderr = not opts[b'noreadstderr']
4765 autoreadstderr = not opts[b'noreadstderr']
4766
4766
4767 if opts[b'peer'] == b'ssh1':
4767 if opts[b'peer'] == b'ssh1':
4768 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4768 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4769 peer = sshpeer.sshv1peer(
4769 peer = sshpeer.sshv1peer(
4770 ui,
4770 ui,
4771 url,
4771 url,
4772 proc,
4772 proc,
4773 stdin,
4773 stdin,
4774 stdout,
4774 stdout,
4775 stderr,
4775 stderr,
4776 None,
4776 None,
4777 autoreadstderr=autoreadstderr,
4777 autoreadstderr=autoreadstderr,
4778 )
4778 )
4779 elif opts[b'peer'] == b'raw':
4779 elif opts[b'peer'] == b'raw':
4780 ui.write(_(b'using raw connection to peer\n'))
4780 ui.write(_(b'using raw connection to peer\n'))
4781 peer = None
4781 peer = None
4782 else:
4782 else:
4783 ui.write(_(b'creating ssh peer from handshake results\n'))
4783 ui.write(_(b'creating ssh peer from handshake results\n'))
4784 peer = sshpeer.makepeer(
4784 peer = sshpeer.makepeer(
4785 ui,
4785 ui,
4786 url,
4786 url,
4787 proc,
4787 proc,
4788 stdin,
4788 stdin,
4789 stdout,
4789 stdout,
4790 stderr,
4790 stderr,
4791 autoreadstderr=autoreadstderr,
4791 autoreadstderr=autoreadstderr,
4792 )
4792 )
4793
4793
4794 elif path:
4794 elif path:
4795 # We bypass hg.peer() so we can proxy the sockets.
4795 # We bypass hg.peer() so we can proxy the sockets.
4796 # TODO consider not doing this because we skip
4796 # TODO consider not doing this because we skip
4797 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4797 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4798 u = urlutil.url(path)
4798 u = urlutil.url(path)
4799 if u.scheme != b'http':
4799 if u.scheme != b'http':
4800 raise error.Abort(_(b'only http:// paths are currently supported'))
4800 raise error.Abort(_(b'only http:// paths are currently supported'))
4801
4801
4802 url, authinfo = u.authinfo()
4802 url, authinfo = u.authinfo()
4803 openerargs = {
4803 openerargs = {
4804 'useragent': b'Mercurial debugwireproto',
4804 'useragent': b'Mercurial debugwireproto',
4805 }
4805 }
4806
4806
4807 # Turn pipes/sockets into observers so we can log I/O.
4807 # Turn pipes/sockets into observers so we can log I/O.
4808 if ui.verbose:
4808 if ui.verbose:
4809 openerargs.update(
4809 openerargs.update(
4810 {
4810 {
4811 'loggingfh': ui,
4811 'loggingfh': ui,
4812 'loggingname': b's',
4812 'loggingname': b's',
4813 'loggingopts': {
4813 'loggingopts': {
4814 'logdata': True,
4814 'logdata': True,
4815 'logdataapis': False,
4815 'logdataapis': False,
4816 },
4816 },
4817 }
4817 }
4818 )
4818 )
4819
4819
4820 if ui.debugflag:
4820 if ui.debugflag:
4821 openerargs['loggingopts']['logdataapis'] = True
4821 openerargs['loggingopts']['logdataapis'] = True
4822
4822
4823 # Don't send default headers when in raw mode. This allows us to
4823 # Don't send default headers when in raw mode. This allows us to
4824 # bypass most of the behavior of our URL handling code so we can
4824 # bypass most of the behavior of our URL handling code so we can
4825 # have near complete control over what's sent on the wire.
4825 # have near complete control over what's sent on the wire.
4826 if opts[b'peer'] == b'raw':
4826 if opts[b'peer'] == b'raw':
4827 openerargs['sendaccept'] = False
4827 openerargs['sendaccept'] = False
4828
4828
4829 opener = urlmod.opener(ui, authinfo, **openerargs)
4829 opener = urlmod.opener(ui, authinfo, **openerargs)
4830
4830
4831 if opts[b'peer'] == b'raw':
4831 if opts[b'peer'] == b'raw':
4832 ui.write(_(b'using raw connection to peer\n'))
4832 ui.write(_(b'using raw connection to peer\n'))
4833 peer = None
4833 peer = None
4834 elif opts[b'peer']:
4834 elif opts[b'peer']:
4835 raise error.Abort(
4835 raise error.Abort(
4836 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4836 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4837 )
4837 )
4838 else:
4838 else:
4839 peer = httppeer.makepeer(ui, path, opener=opener)
4839 peer = httppeer.makepeer(ui, path, opener=opener)
4840
4840
4841 # We /could/ populate stdin/stdout with sock.makefile()...
4841 # We /could/ populate stdin/stdout with sock.makefile()...
4842 else:
4842 else:
4843 raise error.Abort(_(b'unsupported connection configuration'))
4843 raise error.Abort(_(b'unsupported connection configuration'))
4844
4844
4845 batchedcommands = None
4845 batchedcommands = None
4846
4846
4847 # Now perform actions based on the parsed wire language instructions.
4847 # Now perform actions based on the parsed wire language instructions.
4848 for action, lines in blocks:
4848 for action, lines in blocks:
4849 if action in (b'raw', b'raw+'):
4849 if action in (b'raw', b'raw+'):
4850 if not stdin:
4850 if not stdin:
4851 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4851 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4852
4852
4853 # Concatenate the data together.
4853 # Concatenate the data together.
4854 data = b''.join(l.lstrip() for l in lines)
4854 data = b''.join(l.lstrip() for l in lines)
4855 data = stringutil.unescapestr(data)
4855 data = stringutil.unescapestr(data)
4856 stdin.write(data)
4856 stdin.write(data)
4857
4857
4858 if action == b'raw+':
4858 if action == b'raw+':
4859 stdin.flush()
4859 stdin.flush()
4860 elif action == b'flush':
4860 elif action == b'flush':
4861 if not stdin:
4861 if not stdin:
4862 raise error.Abort(_(b'cannot call flush on this peer'))
4862 raise error.Abort(_(b'cannot call flush on this peer'))
4863 stdin.flush()
4863 stdin.flush()
4864 elif action.startswith(b'command'):
4864 elif action.startswith(b'command'):
4865 if not peer:
4865 if not peer:
4866 raise error.Abort(
4866 raise error.Abort(
4867 _(
4867 _(
4868 b'cannot send commands unless peer instance '
4868 b'cannot send commands unless peer instance '
4869 b'is available'
4869 b'is available'
4870 )
4870 )
4871 )
4871 )
4872
4872
4873 command = action.split(b' ', 1)[1]
4873 command = action.split(b' ', 1)[1]
4874
4874
4875 args = {}
4875 args = {}
4876 for line in lines:
4876 for line in lines:
4877 # We need to allow empty values.
4877 # We need to allow empty values.
4878 fields = line.lstrip().split(b' ', 1)
4878 fields = line.lstrip().split(b' ', 1)
4879 if len(fields) == 1:
4879 if len(fields) == 1:
4880 key = fields[0]
4880 key = fields[0]
4881 value = b''
4881 value = b''
4882 else:
4882 else:
4883 key, value = fields
4883 key, value = fields
4884
4884
4885 if value.startswith(b'eval:'):
4885 if value.startswith(b'eval:'):
4886 value = stringutil.evalpythonliteral(value[5:])
4886 value = stringutil.evalpythonliteral(value[5:])
4887 else:
4887 else:
4888 value = stringutil.unescapestr(value)
4888 value = stringutil.unescapestr(value)
4889
4889
4890 args[key] = value
4890 args[key] = value
4891
4891
4892 if batchedcommands is not None:
4892 if batchedcommands is not None:
4893 batchedcommands.append((command, args))
4893 batchedcommands.append((command, args))
4894 continue
4894 continue
4895
4895
4896 ui.status(_(b'sending %s command\n') % command)
4896 ui.status(_(b'sending %s command\n') % command)
4897
4897
4898 if b'PUSHFILE' in args:
4898 if b'PUSHFILE' in args:
4899 with open(args[b'PUSHFILE'], 'rb') as fh:
4899 with open(args[b'PUSHFILE'], 'rb') as fh:
4900 del args[b'PUSHFILE']
4900 del args[b'PUSHFILE']
4901 res, output = peer._callpush(
4901 res, output = peer._callpush(
4902 command, fh, **pycompat.strkwargs(args)
4902 command, fh, **pycompat.strkwargs(args)
4903 )
4903 )
4904 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4904 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4905 ui.status(
4905 ui.status(
4906 _(b'remote output: %s\n') % stringutil.escapestr(output)
4906 _(b'remote output: %s\n') % stringutil.escapestr(output)
4907 )
4907 )
4908 else:
4908 else:
4909 with peer.commandexecutor() as e:
4909 with peer.commandexecutor() as e:
4910 res = e.callcommand(command, args).result()
4910 res = e.callcommand(command, args).result()
4911
4911
4912 ui.status(
4912 ui.status(
4913 _(b'response: %s\n')
4913 _(b'response: %s\n')
4914 % stringutil.pprint(res, bprefix=True, indent=2)
4914 % stringutil.pprint(res, bprefix=True, indent=2)
4915 )
4915 )
4916
4916
4917 elif action == b'batchbegin':
4917 elif action == b'batchbegin':
4918 if batchedcommands is not None:
4918 if batchedcommands is not None:
4919 raise error.Abort(_(b'nested batchbegin not allowed'))
4919 raise error.Abort(_(b'nested batchbegin not allowed'))
4920
4920
4921 batchedcommands = []
4921 batchedcommands = []
4922 elif action == b'batchsubmit':
4922 elif action == b'batchsubmit':
4923 # There is a batching API we could go through. But it would be
4923 # There is a batching API we could go through. But it would be
4924 # difficult to normalize requests into function calls. It is easier
4924 # difficult to normalize requests into function calls. It is easier
4925 # to bypass this layer and normalize to commands + args.
4925 # to bypass this layer and normalize to commands + args.
4926 ui.status(
4926 ui.status(
4927 _(b'sending batch with %d sub-commands\n')
4927 _(b'sending batch with %d sub-commands\n')
4928 % len(batchedcommands)
4928 % len(batchedcommands)
4929 )
4929 )
4930 assert peer is not None
4930 assert peer is not None
4931 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4931 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4932 ui.status(
4932 ui.status(
4933 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4933 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4934 )
4934 )
4935
4935
4936 batchedcommands = None
4936 batchedcommands = None
4937
4937
4938 elif action.startswith(b'httprequest '):
4938 elif action.startswith(b'httprequest '):
4939 if not opener:
4939 if not opener:
4940 raise error.Abort(
4940 raise error.Abort(
4941 _(b'cannot use httprequest without an HTTP peer')
4941 _(b'cannot use httprequest without an HTTP peer')
4942 )
4942 )
4943
4943
4944 request = action.split(b' ', 2)
4944 request = action.split(b' ', 2)
4945 if len(request) != 3:
4945 if len(request) != 3:
4946 raise error.Abort(
4946 raise error.Abort(
4947 _(
4947 _(
4948 b'invalid httprequest: expected format is '
4948 b'invalid httprequest: expected format is '
4949 b'"httprequest <method> <path>'
4949 b'"httprequest <method> <path>'
4950 )
4950 )
4951 )
4951 )
4952
4952
4953 method, httppath = request[1:]
4953 method, httppath = request[1:]
4954 headers = {}
4954 headers = {}
4955 body = None
4955 body = None
4956 frames = []
4956 frames = []
4957 for line in lines:
4957 for line in lines:
4958 line = line.lstrip()
4958 line = line.lstrip()
4959 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4959 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4960 if m:
4960 if m:
4961 # Headers need to use native strings.
4961 # Headers need to use native strings.
4962 key = pycompat.strurl(m.group(1))
4962 key = pycompat.strurl(m.group(1))
4963 value = pycompat.strurl(m.group(2))
4963 value = pycompat.strurl(m.group(2))
4964 headers[key] = value
4964 headers[key] = value
4965 continue
4965 continue
4966
4966
4967 if line.startswith(b'BODYFILE '):
4967 if line.startswith(b'BODYFILE '):
4968 with open(line.split(b' ', 1), b'rb') as fh:
4968 with open(line.split(b' ', 1), b'rb') as fh:
4969 body = fh.read()
4969 body = fh.read()
4970 elif line.startswith(b'frame '):
4970 elif line.startswith(b'frame '):
4971 frame = wireprotoframing.makeframefromhumanstring(
4971 frame = wireprotoframing.makeframefromhumanstring(
4972 line[len(b'frame ') :]
4972 line[len(b'frame ') :]
4973 )
4973 )
4974
4974
4975 frames.append(frame)
4975 frames.append(frame)
4976 else:
4976 else:
4977 raise error.Abort(
4977 raise error.Abort(
4978 _(b'unknown argument to httprequest: %s') % line
4978 _(b'unknown argument to httprequest: %s') % line
4979 )
4979 )
4980
4980
4981 url = path + httppath
4981 url = path + httppath
4982
4982
4983 if frames:
4983 if frames:
4984 body = b''.join(bytes(f) for f in frames)
4984 body = b''.join(bytes(f) for f in frames)
4985
4985
4986 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4986 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4987
4987
4988 # urllib.Request insists on using has_data() as a proxy for
4988 # urllib.Request insists on using has_data() as a proxy for
4989 # determining the request method. Override that to use our
4989 # determining the request method. Override that to use our
4990 # explicitly requested method.
4990 # explicitly requested method.
4991 req.get_method = lambda: pycompat.sysstr(method)
4991 req.get_method = lambda: pycompat.sysstr(method)
4992
4992
4993 try:
4993 try:
4994 res = opener.open(req)
4994 res = opener.open(req)
4995 body = res.read()
4995 body = res.read()
4996 except util.urlerr.urlerror as e:
4996 except util.urlerr.urlerror as e:
4997 # read() method must be called, but only exists in Python 2
4997 # read() method must be called, but only exists in Python 2
4998 getattr(e, 'read', lambda: None)()
4998 getattr(e, 'read', lambda: None)()
4999 continue
4999 continue
5000
5000
5001 ct = res.headers.get('Content-Type')
5001 ct = res.headers.get('Content-Type')
5002 if ct == 'application/mercurial-cbor':
5002 if ct == 'application/mercurial-cbor':
5003 ui.write(
5003 ui.write(
5004 _(b'cbor> %s\n')
5004 _(b'cbor> %s\n')
5005 % stringutil.pprint(
5005 % stringutil.pprint(
5006 cborutil.decodeall(body), bprefix=True, indent=2
5006 cborutil.decodeall(body), bprefix=True, indent=2
5007 )
5007 )
5008 )
5008 )
5009
5009
5010 elif action == b'close':
5010 elif action == b'close':
5011 assert peer is not None
5011 assert peer is not None
5012 peer.close()
5012 peer.close()
5013 elif action == b'readavailable':
5013 elif action == b'readavailable':
5014 if not stdout or not stderr:
5014 if not stdout or not stderr:
5015 raise error.Abort(
5015 raise error.Abort(
5016 _(b'readavailable not available on this peer')
5016 _(b'readavailable not available on this peer')
5017 )
5017 )
5018
5018
5019 stdin.close()
5019 stdin.close()
5020 stdout.read()
5020 stdout.read()
5021 stderr.read()
5021 stderr.read()
5022
5022
5023 elif action == b'readline':
5023 elif action == b'readline':
5024 if not stdout:
5024 if not stdout:
5025 raise error.Abort(_(b'readline not available on this peer'))
5025 raise error.Abort(_(b'readline not available on this peer'))
5026 stdout.readline()
5026 stdout.readline()
5027 elif action == b'ereadline':
5027 elif action == b'ereadline':
5028 if not stderr:
5028 if not stderr:
5029 raise error.Abort(_(b'ereadline not available on this peer'))
5029 raise error.Abort(_(b'ereadline not available on this peer'))
5030 stderr.readline()
5030 stderr.readline()
5031 elif action.startswith(b'read '):
5031 elif action.startswith(b'read '):
5032 count = int(action.split(b' ', 1)[1])
5032 count = int(action.split(b' ', 1)[1])
5033 if not stdout:
5033 if not stdout:
5034 raise error.Abort(_(b'read not available on this peer'))
5034 raise error.Abort(_(b'read not available on this peer'))
5035 stdout.read(count)
5035 stdout.read(count)
5036 elif action.startswith(b'eread '):
5036 elif action.startswith(b'eread '):
5037 count = int(action.split(b' ', 1)[1])
5037 count = int(action.split(b' ', 1)[1])
5038 if not stderr:
5038 if not stderr:
5039 raise error.Abort(_(b'eread not available on this peer'))
5039 raise error.Abort(_(b'eread not available on this peer'))
5040 stderr.read(count)
5040 stderr.read(count)
5041 else:
5041 else:
5042 raise error.Abort(_(b'unknown action: %s') % action)
5042 raise error.Abort(_(b'unknown action: %s') % action)
5043
5043
5044 if batchedcommands is not None:
5044 if batchedcommands is not None:
5045 raise error.Abort(_(b'unclosed "batchbegin" request'))
5045 raise error.Abort(_(b'unclosed "batchbegin" request'))
5046
5046
5047 if peer:
5047 if peer:
5048 peer.close()
5048 peer.close()
5049
5049
5050 if proc:
5050 if proc:
5051 proc.kill()
5051 proc.kill()
@@ -1,449 +1,449 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 abort
4 add
4 add
5 addremove
5 addremove
6 annotate
6 annotate
7 archive
7 archive
8 backout
8 backout
9 bisect
9 bisect
10 bookmarks
10 bookmarks
11 branch
11 branch
12 branches
12 branches
13 bundle
13 bundle
14 cat
14 cat
15 clone
15 clone
16 commit
16 commit
17 config
17 config
18 continue
18 continue
19 copy
19 copy
20 diff
20 diff
21 export
21 export
22 files
22 files
23 forget
23 forget
24 graft
24 graft
25 grep
25 grep
26 heads
26 heads
27 help
27 help
28 identify
28 identify
29 import
29 import
30 incoming
30 incoming
31 init
31 init
32 locate
32 locate
33 log
33 log
34 manifest
34 manifest
35 merge
35 merge
36 outgoing
36 outgoing
37 parents
37 parents
38 paths
38 paths
39 phase
39 phase
40 pull
40 pull
41 purge
41 purge
42 push
42 push
43 recover
43 recover
44 remove
44 remove
45 rename
45 rename
46 resolve
46 resolve
47 revert
47 revert
48 rollback
48 rollback
49 root
49 root
50 serve
50 serve
51 shelve
51 shelve
52 status
52 status
53 summary
53 summary
54 tag
54 tag
55 tags
55 tags
56 tip
56 tip
57 unbundle
57 unbundle
58 unshelve
58 unshelve
59 update
59 update
60 verify
60 verify
61 version
61 version
62
62
63 Show all commands that start with "a"
63 Show all commands that start with "a"
64 $ hg debugcomplete a
64 $ hg debugcomplete a
65 abort
65 abort
66 add
66 add
67 addremove
67 addremove
68 annotate
68 annotate
69 archive
69 archive
70
70
71 Do not show debug commands if there are other candidates
71 Do not show debug commands if there are other candidates
72 $ hg debugcomplete d
72 $ hg debugcomplete d
73 diff
73 diff
74
74
75 Show debug commands if there are no other candidates
75 Show debug commands if there are no other candidates
76 $ hg debugcomplete debug
76 $ hg debugcomplete debug
77 debug-delta-find
77 debug-delta-find
78 debug-repair-issue6528
78 debug-repair-issue6528
79 debug-revlog-index
79 debugancestor
80 debugancestor
80 debugantivirusrunning
81 debugantivirusrunning
81 debugapplystreamclonebundle
82 debugapplystreamclonebundle
82 debugbackupbundle
83 debugbackupbundle
83 debugbuilddag
84 debugbuilddag
84 debugbundle
85 debugbundle
85 debugcapabilities
86 debugcapabilities
86 debugchangedfiles
87 debugchangedfiles
87 debugcheckstate
88 debugcheckstate
88 debugcolor
89 debugcolor
89 debugcommands
90 debugcommands
90 debugcomplete
91 debugcomplete
91 debugconfig
92 debugconfig
92 debugcreatestreamclonebundle
93 debugcreatestreamclonebundle
93 debugdag
94 debugdag
94 debugdata
95 debugdata
95 debugdate
96 debugdate
96 debugdeltachain
97 debugdeltachain
97 debugdirstate
98 debugdirstate
98 debugdirstateignorepatternshash
99 debugdirstateignorepatternshash
99 debugdiscovery
100 debugdiscovery
100 debugdownload
101 debugdownload
101 debugextensions
102 debugextensions
102 debugfileset
103 debugfileset
103 debugformat
104 debugformat
104 debugfsinfo
105 debugfsinfo
105 debuggetbundle
106 debuggetbundle
106 debugignore
107 debugignore
107 debugindex
108 debugindexdot
108 debugindexdot
109 debugindexstats
109 debugindexstats
110 debuginstall
110 debuginstall
111 debugknown
111 debugknown
112 debuglabelcomplete
112 debuglabelcomplete
113 debuglocks
113 debuglocks
114 debugmanifestfulltextcache
114 debugmanifestfulltextcache
115 debugmergestate
115 debugmergestate
116 debugnamecomplete
116 debugnamecomplete
117 debugnodemap
117 debugnodemap
118 debugobsolete
118 debugobsolete
119 debugp1copies
119 debugp1copies
120 debugp2copies
120 debugp2copies
121 debugpathcomplete
121 debugpathcomplete
122 debugpathcopies
122 debugpathcopies
123 debugpeer
123 debugpeer
124 debugpickmergetool
124 debugpickmergetool
125 debugpushkey
125 debugpushkey
126 debugpvec
126 debugpvec
127 debugrebuilddirstate
127 debugrebuilddirstate
128 debugrebuildfncache
128 debugrebuildfncache
129 debugrename
129 debugrename
130 debugrequires
130 debugrequires
131 debugrevlog
131 debugrevlog
132 debugrevlogindex
132 debugrevlogindex
133 debugrevspec
133 debugrevspec
134 debugserve
134 debugserve
135 debugsetparents
135 debugsetparents
136 debugshell
136 debugshell
137 debugsidedata
137 debugsidedata
138 debugssl
138 debugssl
139 debugstrip
139 debugstrip
140 debugsub
140 debugsub
141 debugsuccessorssets
141 debugsuccessorssets
142 debugtagscache
142 debugtagscache
143 debugtemplate
143 debugtemplate
144 debuguigetpass
144 debuguigetpass
145 debuguiprompt
145 debuguiprompt
146 debugupdatecaches
146 debugupdatecaches
147 debugupgraderepo
147 debugupgraderepo
148 debugwalk
148 debugwalk
149 debugwhyunstable
149 debugwhyunstable
150 debugwireargs
150 debugwireargs
151 debugwireproto
151 debugwireproto
152
152
153 Do not show the alias of a debug command if there are other candidates
153 Do not show the alias of a debug command if there are other candidates
154 (this should hide rawcommit)
154 (this should hide rawcommit)
155 $ hg debugcomplete r
155 $ hg debugcomplete r
156 recover
156 recover
157 remove
157 remove
158 rename
158 rename
159 resolve
159 resolve
160 revert
160 revert
161 rollback
161 rollback
162 root
162 root
163 Show the alias of a debug command if there are no other candidates
163 Show the alias of a debug command if there are no other candidates
164 $ hg debugcomplete rawc
164 $ hg debugcomplete rawc
165
165
166
166
167 Show the global options
167 Show the global options
168 $ hg debugcomplete --options | sort
168 $ hg debugcomplete --options | sort
169 --color
169 --color
170 --config
170 --config
171 --cwd
171 --cwd
172 --debug
172 --debug
173 --debugger
173 --debugger
174 --encoding
174 --encoding
175 --encodingmode
175 --encodingmode
176 --help
176 --help
177 --hidden
177 --hidden
178 --noninteractive
178 --noninteractive
179 --pager
179 --pager
180 --profile
180 --profile
181 --quiet
181 --quiet
182 --repository
182 --repository
183 --time
183 --time
184 --traceback
184 --traceback
185 --verbose
185 --verbose
186 --version
186 --version
187 -R
187 -R
188 -h
188 -h
189 -q
189 -q
190 -v
190 -v
191 -y
191 -y
192
192
193 Show the options for the "serve" command
193 Show the options for the "serve" command
194 $ hg debugcomplete --options serve | sort
194 $ hg debugcomplete --options serve | sort
195 --accesslog
195 --accesslog
196 --address
196 --address
197 --certificate
197 --certificate
198 --cmdserver
198 --cmdserver
199 --color
199 --color
200 --config
200 --config
201 --cwd
201 --cwd
202 --daemon
202 --daemon
203 --daemon-postexec
203 --daemon-postexec
204 --debug
204 --debug
205 --debugger
205 --debugger
206 --encoding
206 --encoding
207 --encodingmode
207 --encodingmode
208 --errorlog
208 --errorlog
209 --help
209 --help
210 --hidden
210 --hidden
211 --ipv6
211 --ipv6
212 --name
212 --name
213 --noninteractive
213 --noninteractive
214 --pager
214 --pager
215 --pid-file
215 --pid-file
216 --port
216 --port
217 --prefix
217 --prefix
218 --print-url
218 --print-url
219 --profile
219 --profile
220 --quiet
220 --quiet
221 --repository
221 --repository
222 --stdio
222 --stdio
223 --style
223 --style
224 --subrepos
224 --subrepos
225 --templates
225 --templates
226 --time
226 --time
227 --traceback
227 --traceback
228 --verbose
228 --verbose
229 --version
229 --version
230 --web-conf
230 --web-conf
231 -6
231 -6
232 -A
232 -A
233 -E
233 -E
234 -R
234 -R
235 -S
235 -S
236 -a
236 -a
237 -d
237 -d
238 -h
238 -h
239 -n
239 -n
240 -p
240 -p
241 -q
241 -q
242 -t
242 -t
243 -v
243 -v
244 -y
244 -y
245
245
246 Show an error if we use --options with an ambiguous abbreviation
246 Show an error if we use --options with an ambiguous abbreviation
247 $ hg debugcomplete --options s
247 $ hg debugcomplete --options s
248 hg: command 's' is ambiguous:
248 hg: command 's' is ambiguous:
249 serve shelve showconfig status summary
249 serve shelve showconfig status summary
250 [10]
250 [10]
251
251
252 Show all commands + options
252 Show all commands + options
253 $ hg debugcommands
253 $ hg debugcommands
254 abort: dry-run
254 abort: dry-run
255 add: include, exclude, subrepos, dry-run
255 add: include, exclude, subrepos, dry-run
256 addremove: similarity, subrepos, include, exclude, dry-run
256 addremove: similarity, subrepos, include, exclude, dry-run
257 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
257 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
258 archive: no-decode, prefix, rev, type, subrepos, include, exclude
258 archive: no-decode, prefix, rev, type, subrepos, include, exclude
259 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
259 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
260 bisect: reset, good, bad, skip, extend, command, noupdate
260 bisect: reset, good, bad, skip, extend, command, noupdate
261 bookmarks: force, rev, delete, rename, inactive, list, template
261 bookmarks: force, rev, delete, rename, inactive, list, template
262 branch: force, clean, rev
262 branch: force, clean, rev
263 branches: active, closed, rev, template
263 branches: active, closed, rev, template
264 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
264 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
265 cat: output, rev, decode, include, exclude, template
265 cat: output, rev, decode, include, exclude, template
266 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
266 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
267 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
267 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
268 config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template
268 config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template
269 continue: dry-run
269 continue: dry-run
270 copy: forget, after, at-rev, force, include, exclude, dry-run
270 copy: forget, after, at-rev, force, include, exclude, dry-run
271 debug-delta-find: changelog, manifest, dir, template
271 debug-delta-find: changelog, manifest, dir, template
272 debug-repair-issue6528: to-report, from-report, paranoid, dry-run
272 debug-repair-issue6528: to-report, from-report, paranoid, dry-run
273 debug-revlog-index: changelog, manifest, dir, template
273 debugancestor:
274 debugancestor:
274 debugantivirusrunning:
275 debugantivirusrunning:
275 debugapplystreamclonebundle:
276 debugapplystreamclonebundle:
276 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
277 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
277 debugbuilddag: mergeable-file, overwritten-file, new-file, from-existing
278 debugbuilddag: mergeable-file, overwritten-file, new-file, from-existing
278 debugbundle: all, part-type, spec
279 debugbundle: all, part-type, spec
279 debugcapabilities:
280 debugcapabilities:
280 debugchangedfiles: compute
281 debugchangedfiles: compute
281 debugcheckstate:
282 debugcheckstate:
282 debugcolor: style
283 debugcolor: style
283 debugcommands:
284 debugcommands:
284 debugcomplete: options
285 debugcomplete: options
285 debugcreatestreamclonebundle:
286 debugcreatestreamclonebundle:
286 debugdag: tags, branches, dots, spaces
287 debugdag: tags, branches, dots, spaces
287 debugdata: changelog, manifest, dir
288 debugdata: changelog, manifest, dir
288 debugdate: extended
289 debugdate: extended
289 debugdeltachain: changelog, manifest, dir, template
290 debugdeltachain: changelog, manifest, dir, template
290 debugdirstateignorepatternshash:
291 debugdirstateignorepatternshash:
291 debugdirstate: nodates, dates, datesort, docket, all
292 debugdirstate: nodates, dates, datesort, docket, all
292 debugdiscovery: old, nonheads, rev, seed, local-as-revs, remote-as-revs, ssh, remotecmd, insecure, template
293 debugdiscovery: old, nonheads, rev, seed, local-as-revs, remote-as-revs, ssh, remotecmd, insecure, template
293 debugdownload: output
294 debugdownload: output
294 debugextensions: template
295 debugextensions: template
295 debugfileset: rev, all-files, show-matcher, show-stage
296 debugfileset: rev, all-files, show-matcher, show-stage
296 debugformat: template
297 debugformat: template
297 debugfsinfo:
298 debugfsinfo:
298 debuggetbundle: head, common, type
299 debuggetbundle: head, common, type
299 debugignore:
300 debugignore:
300 debugindex: changelog, manifest, dir, template
301 debugindexdot: changelog, manifest, dir
301 debugindexdot: changelog, manifest, dir
302 debugindexstats:
302 debugindexstats:
303 debuginstall: template
303 debuginstall: template
304 debugknown:
304 debugknown:
305 debuglabelcomplete:
305 debuglabelcomplete:
306 debuglocks: force-free-lock, force-free-wlock, set-lock, set-wlock
306 debuglocks: force-free-lock, force-free-wlock, set-lock, set-wlock
307 debugmanifestfulltextcache: clear, add
307 debugmanifestfulltextcache: clear, add
308 debugmergestate: style, template
308 debugmergestate: style, template
309 debugnamecomplete:
309 debugnamecomplete:
310 debugnodemap: dump-new, dump-disk, check, metadata
310 debugnodemap: dump-new, dump-disk, check, metadata
311 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
311 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
312 debugp1copies: rev
312 debugp1copies: rev
313 debugp2copies: rev
313 debugp2copies: rev
314 debugpathcomplete: full, normal, added, removed
314 debugpathcomplete: full, normal, added, removed
315 debugpathcopies: include, exclude
315 debugpathcopies: include, exclude
316 debugpeer:
316 debugpeer:
317 debugpickmergetool: rev, changedelete, include, exclude, tool
317 debugpickmergetool: rev, changedelete, include, exclude, tool
318 debugpushkey:
318 debugpushkey:
319 debugpvec:
319 debugpvec:
320 debugrebuilddirstate: rev, minimal
320 debugrebuilddirstate: rev, minimal
321 debugrebuildfncache: only-data
321 debugrebuildfncache: only-data
322 debugrename: rev
322 debugrename: rev
323 debugrequires:
323 debugrequires:
324 debugrevlog: changelog, manifest, dir, dump
324 debugrevlog: changelog, manifest, dir, dump
325 debugrevlogindex: changelog, manifest, dir, format
325 debugrevlogindex: changelog, manifest, dir, format
326 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
326 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
327 debugserve: sshstdio, logiofd, logiofile
327 debugserve: sshstdio, logiofd, logiofile
328 debugsetparents:
328 debugsetparents:
329 debugshell:
329 debugshell:
330 debugsidedata: changelog, manifest, dir
330 debugsidedata: changelog, manifest, dir
331 debugssl:
331 debugssl:
332 debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft
332 debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft
333 debugsub: rev
333 debugsub: rev
334 debugsuccessorssets: closest
334 debugsuccessorssets: closest
335 debugtagscache:
335 debugtagscache:
336 debugtemplate: rev, define
336 debugtemplate: rev, define
337 debuguigetpass: prompt
337 debuguigetpass: prompt
338 debuguiprompt: prompt
338 debuguiprompt: prompt
339 debugupdatecaches:
339 debugupdatecaches:
340 debugupgraderepo: optimize, run, backup, changelog, manifest, filelogs
340 debugupgraderepo: optimize, run, backup, changelog, manifest, filelogs
341 debugwalk: include, exclude
341 debugwalk: include, exclude
342 debugwhyunstable:
342 debugwhyunstable:
343 debugwireargs: three, four, five, ssh, remotecmd, insecure
343 debugwireargs: three, four, five, ssh, remotecmd, insecure
344 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
344 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
345 diff: rev, from, to, 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
345 diff: rev, from, to, 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
346 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
346 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
347 files: rev, print0, include, exclude, template, subrepos
347 files: rev, print0, include, exclude, template, subrepos
348 forget: interactive, include, exclude, dry-run
348 forget: interactive, include, exclude, dry-run
349 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
349 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
350 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
350 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
351 heads: rev, topo, active, closed, style, template
351 heads: rev, topo, active, closed, style, template
352 help: extension, command, keyword, system
352 help: extension, command, keyword, system
353 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
353 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
354 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
354 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
355 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
355 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
356 init: ssh, remotecmd, insecure
356 init: ssh, remotecmd, insecure
357 locate: rev, print0, fullpath, include, exclude
357 locate: rev, print0, fullpath, include, exclude
358 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, bookmark, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
358 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, bookmark, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
359 manifest: rev, all, template
359 manifest: rev, all, template
360 merge: force, rev, preview, abort, tool
360 merge: force, rev, preview, abort, tool
361 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
361 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
362 parents: rev, style, template
362 parents: rev, style, template
363 paths: template
363 paths: template
364 phase: public, draft, secret, force, rev
364 phase: public, draft, secret, force, rev
365 pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure
365 pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure
366 purge: abort-on-err, all, ignored, dirs, files, print, print0, confirm, include, exclude
366 purge: abort-on-err, all, ignored, dirs, files, print, print0, confirm, include, exclude
367 push: force, rev, bookmark, all-bookmarks, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
367 push: force, rev, bookmark, all-bookmarks, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
368 recover: verify
368 recover: verify
369 remove: after, force, subrepos, include, exclude, dry-run
369 remove: after, force, subrepos, include, exclude, dry-run
370 rename: forget, after, at-rev, force, include, exclude, dry-run
370 rename: forget, after, at-rev, force, include, exclude, dry-run
371 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
371 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
372 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
372 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
373 rollback: dry-run, force
373 rollback: dry-run, force
374 root: template
374 root: template
375 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
375 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
376 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
376 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
377 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
377 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
378 summary: remote
378 summary: remote
379 tag: force, local, rev, remove, edit, message, date, user
379 tag: force, local, rev, remove, edit, message, date, user
380 tags: template
380 tags: template
381 tip: patch, git, style, template
381 tip: patch, git, style, template
382 unbundle: update
382 unbundle: update
383 unshelve: abort, continue, interactive, keep, name, tool, date
383 unshelve: abort, continue, interactive, keep, name, tool, date
384 update: clean, check, merge, date, rev, tool
384 update: clean, check, merge, date, rev, tool
385 verify: full
385 verify: full
386 version: template
386 version: template
387
387
388 $ hg init a
388 $ hg init a
389 $ cd a
389 $ cd a
390 $ echo fee > fee
390 $ echo fee > fee
391 $ hg ci -q -Amfee
391 $ hg ci -q -Amfee
392 $ hg tag fee
392 $ hg tag fee
393 $ mkdir fie
393 $ mkdir fie
394 $ echo dead > fie/dead
394 $ echo dead > fie/dead
395 $ echo live > fie/live
395 $ echo live > fie/live
396 $ hg bookmark fo
396 $ hg bookmark fo
397 $ hg branch -q fie
397 $ hg branch -q fie
398 $ hg ci -q -Amfie
398 $ hg ci -q -Amfie
399 $ echo fo > fo
399 $ echo fo > fo
400 $ hg branch -qf default
400 $ hg branch -qf default
401 $ hg ci -q -Amfo
401 $ hg ci -q -Amfo
402 $ echo Fum > Fum
402 $ echo Fum > Fum
403 $ hg ci -q -AmFum
403 $ hg ci -q -AmFum
404 $ hg bookmark Fum
404 $ hg bookmark Fum
405
405
406 Test debugpathcomplete
406 Test debugpathcomplete
407
407
408 $ hg debugpathcomplete f
408 $ hg debugpathcomplete f
409 fee
409 fee
410 fie
410 fie
411 fo
411 fo
412 $ hg debugpathcomplete -f f
412 $ hg debugpathcomplete -f f
413 fee
413 fee
414 fie/dead
414 fie/dead
415 fie/live
415 fie/live
416 fo
416 fo
417
417
418 $ hg rm Fum
418 $ hg rm Fum
419 $ hg debugpathcomplete -r F
419 $ hg debugpathcomplete -r F
420 Fum
420 Fum
421
421
422 Test debugnamecomplete
422 Test debugnamecomplete
423
423
424 $ hg debugnamecomplete
424 $ hg debugnamecomplete
425 Fum
425 Fum
426 default
426 default
427 fee
427 fee
428 fie
428 fie
429 fo
429 fo
430 tip
430 tip
431 $ hg debugnamecomplete f
431 $ hg debugnamecomplete f
432 fee
432 fee
433 fie
433 fie
434 fo
434 fo
435
435
436 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
436 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
437 used for completions in some shells.
437 used for completions in some shells.
438
438
439 $ hg debuglabelcomplete
439 $ hg debuglabelcomplete
440 Fum
440 Fum
441 default
441 default
442 fee
442 fee
443 fie
443 fie
444 fo
444 fo
445 tip
445 tip
446 $ hg debuglabelcomplete f
446 $ hg debuglabelcomplete f
447 fee
447 fee
448 fie
448 fie
449 fo
449 fo
@@ -1,4065 +1,4066 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 Extra extensions will be printed in help output in a non-reliable order since
47 Extra extensions will be printed in help output in a non-reliable order since
48 the extension is unknown.
48 the extension is unknown.
49 #if no-extraextensions
49 #if no-extraextensions
50
50
51 $ hg help
51 $ hg help
52 Mercurial Distributed SCM
52 Mercurial Distributed SCM
53
53
54 list of commands:
54 list of commands:
55
55
56 Repository creation:
56 Repository creation:
57
57
58 clone make a copy of an existing repository
58 clone make a copy of an existing repository
59 init create a new repository in the given directory
59 init create a new repository in the given directory
60
60
61 Remote repository management:
61 Remote repository management:
62
62
63 incoming show new changesets found in source
63 incoming show new changesets found in source
64 outgoing show changesets not found in the destination
64 outgoing show changesets not found in the destination
65 paths show aliases for remote repositories
65 paths show aliases for remote repositories
66 pull pull changes from the specified source
66 pull pull changes from the specified source
67 push push changes to the specified destination
67 push push changes to the specified destination
68 serve start stand-alone webserver
68 serve start stand-alone webserver
69
69
70 Change creation:
70 Change creation:
71
71
72 commit commit the specified files or all outstanding changes
72 commit commit the specified files or all outstanding changes
73
73
74 Change manipulation:
74 Change manipulation:
75
75
76 backout reverse effect of earlier changeset
76 backout reverse effect of earlier changeset
77 graft copy changes from other branches onto the current branch
77 graft copy changes from other branches onto the current branch
78 merge merge another revision into working directory
78 merge merge another revision into working directory
79
79
80 Change organization:
80 Change organization:
81
81
82 bookmarks create a new bookmark or list existing bookmarks
82 bookmarks create a new bookmark or list existing bookmarks
83 branch set or show the current branch name
83 branch set or show the current branch name
84 branches list repository named branches
84 branches list repository named branches
85 phase set or show the current phase name
85 phase set or show the current phase name
86 tag add one or more tags for the current or given revision
86 tag add one or more tags for the current or given revision
87 tags list repository tags
87 tags list repository tags
88
88
89 File content management:
89 File content management:
90
90
91 annotate show changeset information by line for each file
91 annotate show changeset information by line for each file
92 cat output the current or given revision of files
92 cat output the current or given revision of files
93 copy mark files as copied for the next commit
93 copy mark files as copied for the next commit
94 diff diff repository (or selected files)
94 diff diff repository (or selected files)
95 grep search for a pattern in specified files
95 grep search for a pattern in specified files
96
96
97 Change navigation:
97 Change navigation:
98
98
99 bisect subdivision search of changesets
99 bisect subdivision search of changesets
100 heads show branch heads
100 heads show branch heads
101 identify identify the working directory or specified revision
101 identify identify the working directory or specified revision
102 log show revision history of entire repository or files
102 log show revision history of entire repository or files
103
103
104 Working directory management:
104 Working directory management:
105
105
106 add add the specified files on the next commit
106 add add the specified files on the next commit
107 addremove add all new files, delete all missing files
107 addremove add all new files, delete all missing files
108 files list tracked files
108 files list tracked files
109 forget forget the specified files on the next commit
109 forget forget the specified files on the next commit
110 purge removes files not tracked by Mercurial
110 purge removes files not tracked by Mercurial
111 remove remove the specified files on the next commit
111 remove remove the specified files on the next commit
112 rename rename files; equivalent of copy + remove
112 rename rename files; equivalent of copy + remove
113 resolve redo merges or set/view the merge status of files
113 resolve redo merges or set/view the merge status of files
114 revert restore files to their checkout state
114 revert restore files to their checkout state
115 root print the root (top) of the current working directory
115 root print the root (top) of the current working directory
116 shelve save and set aside changes from the working directory
116 shelve save and set aside changes from the working directory
117 status show changed files in the working directory
117 status show changed files in the working directory
118 summary summarize working directory state
118 summary summarize working directory state
119 unshelve restore a shelved change to the working directory
119 unshelve restore a shelved change to the working directory
120 update update working directory (or switch revisions)
120 update update working directory (or switch revisions)
121
121
122 Change import/export:
122 Change import/export:
123
123
124 archive create an unversioned archive of a repository revision
124 archive create an unversioned archive of a repository revision
125 bundle create a bundle file
125 bundle create a bundle file
126 export dump the header and diffs for one or more changesets
126 export dump the header and diffs for one or more changesets
127 import import an ordered set of patches
127 import import an ordered set of patches
128 unbundle apply one or more bundle files
128 unbundle apply one or more bundle files
129
129
130 Repository maintenance:
130 Repository maintenance:
131
131
132 manifest output the current or given revision of the project manifest
132 manifest output the current or given revision of the project manifest
133 recover roll back an interrupted transaction
133 recover roll back an interrupted transaction
134 verify verify the integrity of the repository
134 verify verify the integrity of the repository
135
135
136 Help:
136 Help:
137
137
138 config show combined config settings from all hgrc files
138 config show combined config settings from all hgrc files
139 help show help for a given topic or a help overview
139 help show help for a given topic or a help overview
140 version output version and copyright information
140 version output version and copyright information
141
141
142 additional help topics:
142 additional help topics:
143
143
144 Mercurial identifiers:
144 Mercurial identifiers:
145
145
146 filesets Specifying File Sets
146 filesets Specifying File Sets
147 hgignore Syntax for Mercurial Ignore Files
147 hgignore Syntax for Mercurial Ignore Files
148 patterns File Name Patterns
148 patterns File Name Patterns
149 revisions Specifying Revisions
149 revisions Specifying Revisions
150 urls URL Paths
150 urls URL Paths
151
151
152 Mercurial output:
152 Mercurial output:
153
153
154 color Colorizing Outputs
154 color Colorizing Outputs
155 dates Date Formats
155 dates Date Formats
156 diffs Diff Formats
156 diffs Diff Formats
157 templating Template Usage
157 templating Template Usage
158
158
159 Mercurial configuration:
159 Mercurial configuration:
160
160
161 config Configuration Files
161 config Configuration Files
162 environment Environment Variables
162 environment Environment Variables
163 extensions Using Additional Features
163 extensions Using Additional Features
164 flags Command-line flags
164 flags Command-line flags
165 hgweb Configuring hgweb
165 hgweb Configuring hgweb
166 merge-tools Merge Tools
166 merge-tools Merge Tools
167 pager Pager Support
167 pager Pager Support
168 rust Rust in Mercurial
168 rust Rust in Mercurial
169
169
170 Concepts:
170 Concepts:
171
171
172 bundlespec Bundle File Formats
172 bundlespec Bundle File Formats
173 evolution Safely rewriting history (EXPERIMENTAL)
173 evolution Safely rewriting history (EXPERIMENTAL)
174 glossary Glossary
174 glossary Glossary
175 phases Working with Phases
175 phases Working with Phases
176 subrepos Subrepositories
176 subrepos Subrepositories
177
177
178 Miscellaneous:
178 Miscellaneous:
179
179
180 deprecated Deprecated Features
180 deprecated Deprecated Features
181 internals Technical implementation topics
181 internals Technical implementation topics
182 scripting Using Mercurial from scripts and automation
182 scripting Using Mercurial from scripts and automation
183
183
184 (use 'hg help -v' to show built-in aliases and global options)
184 (use 'hg help -v' to show built-in aliases and global options)
185
185
186 $ hg -q help
186 $ hg -q help
187 Repository creation:
187 Repository creation:
188
188
189 clone make a copy of an existing repository
189 clone make a copy of an existing repository
190 init create a new repository in the given directory
190 init create a new repository in the given directory
191
191
192 Remote repository management:
192 Remote repository management:
193
193
194 incoming show new changesets found in source
194 incoming show new changesets found in source
195 outgoing show changesets not found in the destination
195 outgoing show changesets not found in the destination
196 paths show aliases for remote repositories
196 paths show aliases for remote repositories
197 pull pull changes from the specified source
197 pull pull changes from the specified source
198 push push changes to the specified destination
198 push push changes to the specified destination
199 serve start stand-alone webserver
199 serve start stand-alone webserver
200
200
201 Change creation:
201 Change creation:
202
202
203 commit commit the specified files or all outstanding changes
203 commit commit the specified files or all outstanding changes
204
204
205 Change manipulation:
205 Change manipulation:
206
206
207 backout reverse effect of earlier changeset
207 backout reverse effect of earlier changeset
208 graft copy changes from other branches onto the current branch
208 graft copy changes from other branches onto the current branch
209 merge merge another revision into working directory
209 merge merge another revision into working directory
210
210
211 Change organization:
211 Change organization:
212
212
213 bookmarks create a new bookmark or list existing bookmarks
213 bookmarks create a new bookmark or list existing bookmarks
214 branch set or show the current branch name
214 branch set or show the current branch name
215 branches list repository named branches
215 branches list repository named branches
216 phase set or show the current phase name
216 phase set or show the current phase name
217 tag add one or more tags for the current or given revision
217 tag add one or more tags for the current or given revision
218 tags list repository tags
218 tags list repository tags
219
219
220 File content management:
220 File content management:
221
221
222 annotate show changeset information by line for each file
222 annotate show changeset information by line for each file
223 cat output the current or given revision of files
223 cat output the current or given revision of files
224 copy mark files as copied for the next commit
224 copy mark files as copied for the next commit
225 diff diff repository (or selected files)
225 diff diff repository (or selected files)
226 grep search for a pattern in specified files
226 grep search for a pattern in specified files
227
227
228 Change navigation:
228 Change navigation:
229
229
230 bisect subdivision search of changesets
230 bisect subdivision search of changesets
231 heads show branch heads
231 heads show branch heads
232 identify identify the working directory or specified revision
232 identify identify the working directory or specified revision
233 log show revision history of entire repository or files
233 log show revision history of entire repository or files
234
234
235 Working directory management:
235 Working directory management:
236
236
237 add add the specified files on the next commit
237 add add the specified files on the next commit
238 addremove add all new files, delete all missing files
238 addremove add all new files, delete all missing files
239 files list tracked files
239 files list tracked files
240 forget forget the specified files on the next commit
240 forget forget the specified files on the next commit
241 purge removes files not tracked by Mercurial
241 purge removes files not tracked by Mercurial
242 remove remove the specified files on the next commit
242 remove remove the specified files on the next commit
243 rename rename files; equivalent of copy + remove
243 rename rename files; equivalent of copy + remove
244 resolve redo merges or set/view the merge status of files
244 resolve redo merges or set/view the merge status of files
245 revert restore files to their checkout state
245 revert restore files to their checkout state
246 root print the root (top) of the current working directory
246 root print the root (top) of the current working directory
247 shelve save and set aside changes from the working directory
247 shelve save and set aside changes from the working directory
248 status show changed files in the working directory
248 status show changed files in the working directory
249 summary summarize working directory state
249 summary summarize working directory state
250 unshelve restore a shelved change to the working directory
250 unshelve restore a shelved change to the working directory
251 update update working directory (or switch revisions)
251 update update working directory (or switch revisions)
252
252
253 Change import/export:
253 Change import/export:
254
254
255 archive create an unversioned archive of a repository revision
255 archive create an unversioned archive of a repository revision
256 bundle create a bundle file
256 bundle create a bundle file
257 export dump the header and diffs for one or more changesets
257 export dump the header and diffs for one or more changesets
258 import import an ordered set of patches
258 import import an ordered set of patches
259 unbundle apply one or more bundle files
259 unbundle apply one or more bundle files
260
260
261 Repository maintenance:
261 Repository maintenance:
262
262
263 manifest output the current or given revision of the project manifest
263 manifest output the current or given revision of the project manifest
264 recover roll back an interrupted transaction
264 recover roll back an interrupted transaction
265 verify verify the integrity of the repository
265 verify verify the integrity of the repository
266
266
267 Help:
267 Help:
268
268
269 config show combined config settings from all hgrc files
269 config show combined config settings from all hgrc files
270 help show help for a given topic or a help overview
270 help show help for a given topic or a help overview
271 version output version and copyright information
271 version output version and copyright information
272
272
273 additional help topics:
273 additional help topics:
274
274
275 Mercurial identifiers:
275 Mercurial identifiers:
276
276
277 filesets Specifying File Sets
277 filesets Specifying File Sets
278 hgignore Syntax for Mercurial Ignore Files
278 hgignore Syntax for Mercurial Ignore Files
279 patterns File Name Patterns
279 patterns File Name Patterns
280 revisions Specifying Revisions
280 revisions Specifying Revisions
281 urls URL Paths
281 urls URL Paths
282
282
283 Mercurial output:
283 Mercurial output:
284
284
285 color Colorizing Outputs
285 color Colorizing Outputs
286 dates Date Formats
286 dates Date Formats
287 diffs Diff Formats
287 diffs Diff Formats
288 templating Template Usage
288 templating Template Usage
289
289
290 Mercurial configuration:
290 Mercurial configuration:
291
291
292 config Configuration Files
292 config Configuration Files
293 environment Environment Variables
293 environment Environment Variables
294 extensions Using Additional Features
294 extensions Using Additional Features
295 flags Command-line flags
295 flags Command-line flags
296 hgweb Configuring hgweb
296 hgweb Configuring hgweb
297 merge-tools Merge Tools
297 merge-tools Merge Tools
298 pager Pager Support
298 pager Pager Support
299 rust Rust in Mercurial
299 rust Rust in Mercurial
300
300
301 Concepts:
301 Concepts:
302
302
303 bundlespec Bundle File Formats
303 bundlespec Bundle File Formats
304 evolution Safely rewriting history (EXPERIMENTAL)
304 evolution Safely rewriting history (EXPERIMENTAL)
305 glossary Glossary
305 glossary Glossary
306 phases Working with Phases
306 phases Working with Phases
307 subrepos Subrepositories
307 subrepos Subrepositories
308
308
309 Miscellaneous:
309 Miscellaneous:
310
310
311 deprecated Deprecated Features
311 deprecated Deprecated Features
312 internals Technical implementation topics
312 internals Technical implementation topics
313 scripting Using Mercurial from scripts and automation
313 scripting Using Mercurial from scripts and automation
314
314
315 Test extension help:
315 Test extension help:
316 $ hg help extensions --config extensions.rebase= --config extensions.children=
316 $ hg help extensions --config extensions.rebase= --config extensions.children=
317 Using Additional Features
317 Using Additional Features
318 """""""""""""""""""""""""
318 """""""""""""""""""""""""
319
319
320 Mercurial has the ability to add new features through the use of
320 Mercurial has the ability to add new features through the use of
321 extensions. Extensions may add new commands, add options to existing
321 extensions. Extensions may add new commands, add options to existing
322 commands, change the default behavior of commands, or implement hooks.
322 commands, change the default behavior of commands, or implement hooks.
323
323
324 To enable the "foo" extension, either shipped with Mercurial or in the
324 To enable the "foo" extension, either shipped with Mercurial or in the
325 Python search path, create an entry for it in your configuration file,
325 Python search path, create an entry for it in your configuration file,
326 like this:
326 like this:
327
327
328 [extensions]
328 [extensions]
329 foo =
329 foo =
330
330
331 You may also specify the full path to an extension:
331 You may also specify the full path to an extension:
332
332
333 [extensions]
333 [extensions]
334 myfeature = ~/.hgext/myfeature.py
334 myfeature = ~/.hgext/myfeature.py
335
335
336 See 'hg help config' for more information on configuration files.
336 See 'hg help config' for more information on configuration files.
337
337
338 Extensions are not loaded by default for a variety of reasons: they can
338 Extensions are not loaded by default for a variety of reasons: they can
339 increase startup overhead; they may be meant for advanced usage only; they
339 increase startup overhead; they may be meant for advanced usage only; they
340 may provide potentially dangerous abilities (such as letting you destroy
340 may provide potentially dangerous abilities (such as letting you destroy
341 or modify history); they might not be ready for prime time; or they may
341 or modify history); they might not be ready for prime time; or they may
342 alter some usual behaviors of stock Mercurial. It is thus up to the user
342 alter some usual behaviors of stock Mercurial. It is thus up to the user
343 to activate extensions as needed.
343 to activate extensions as needed.
344
344
345 To explicitly disable an extension enabled in a configuration file of
345 To explicitly disable an extension enabled in a configuration file of
346 broader scope, prepend its path with !:
346 broader scope, prepend its path with !:
347
347
348 [extensions]
348 [extensions]
349 # disabling extension bar residing in /path/to/extension/bar.py
349 # disabling extension bar residing in /path/to/extension/bar.py
350 bar = !/path/to/extension/bar.py
350 bar = !/path/to/extension/bar.py
351 # ditto, but no path was supplied for extension baz
351 # ditto, but no path was supplied for extension baz
352 baz = !
352 baz = !
353
353
354 enabled extensions:
354 enabled extensions:
355
355
356 children command to display child changesets (DEPRECATED)
356 children command to display child changesets (DEPRECATED)
357 rebase command to move sets of revisions to a different ancestor
357 rebase command to move sets of revisions to a different ancestor
358
358
359 disabled extensions:
359 disabled extensions:
360
360
361 acl hooks for controlling repository access
361 acl hooks for controlling repository access
362 blackbox log repository events to a blackbox for debugging
362 blackbox log repository events to a blackbox for debugging
363 bugzilla hooks for integrating with the Bugzilla bug tracker
363 bugzilla hooks for integrating with the Bugzilla bug tracker
364 censor erase file content at a given revision
364 censor erase file content at a given revision
365 churn command to display statistics about repository history
365 churn command to display statistics about repository history
366 clonebundles advertise pre-generated bundles to seed clones
366 clonebundles advertise pre-generated bundles to seed clones
367 closehead close arbitrary heads without checking them out first
367 closehead close arbitrary heads without checking them out first
368 convert import revisions from foreign VCS repositories into
368 convert import revisions from foreign VCS repositories into
369 Mercurial
369 Mercurial
370 eol automatically manage newlines in repository files
370 eol automatically manage newlines in repository files
371 extdiff command to allow external programs to compare revisions
371 extdiff command to allow external programs to compare revisions
372 factotum http authentication with factotum
372 factotum http authentication with factotum
373 fastexport export repositories as git fast-import stream
373 fastexport export repositories as git fast-import stream
374 githelp try mapping git commands to Mercurial commands
374 githelp try mapping git commands to Mercurial commands
375 gpg commands to sign and verify changesets
375 gpg commands to sign and verify changesets
376 hgk browse the repository in a graphical way
376 hgk browse the repository in a graphical way
377 highlight syntax highlighting for hgweb (requires Pygments)
377 highlight syntax highlighting for hgweb (requires Pygments)
378 histedit interactive history editing
378 histedit interactive history editing
379 keyword expand keywords in tracked files
379 keyword expand keywords in tracked files
380 largefiles track large binary files
380 largefiles track large binary files
381 mq manage a stack of patches
381 mq manage a stack of patches
382 notify hooks for sending email push notifications
382 notify hooks for sending email push notifications
383 patchbomb command to send changesets as (a series of) patch emails
383 patchbomb command to send changesets as (a series of) patch emails
384 relink recreates hardlinks between repository clones
384 relink recreates hardlinks between repository clones
385 schemes extend schemes with shortcuts to repository swarms
385 schemes extend schemes with shortcuts to repository swarms
386 share share a common history between several working directories
386 share share a common history between several working directories
387 transplant command to transplant changesets from another branch
387 transplant command to transplant changesets from another branch
388 win32mbcs allow the use of MBCS paths with problematic encodings
388 win32mbcs allow the use of MBCS paths with problematic encodings
389 zeroconf discover and advertise repositories on the local network
389 zeroconf discover and advertise repositories on the local network
390
390
391 #endif
391 #endif
392
392
393 Verify that deprecated extensions are included if --verbose:
393 Verify that deprecated extensions are included if --verbose:
394
394
395 $ hg -v help extensions | grep children
395 $ hg -v help extensions | grep children
396 children command to display child changesets (DEPRECATED)
396 children command to display child changesets (DEPRECATED)
397
397
398 Verify that extension keywords appear in help templates
398 Verify that extension keywords appear in help templates
399
399
400 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
400 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
401
401
402 Test short command list with verbose option
402 Test short command list with verbose option
403
403
404 $ hg -v help shortlist
404 $ hg -v help shortlist
405 Mercurial Distributed SCM
405 Mercurial Distributed SCM
406
406
407 basic commands:
407 basic commands:
408
408
409 abort abort an unfinished operation (EXPERIMENTAL)
409 abort abort an unfinished operation (EXPERIMENTAL)
410 add add the specified files on the next commit
410 add add the specified files on the next commit
411 annotate, blame
411 annotate, blame
412 show changeset information by line for each file
412 show changeset information by line for each file
413 clone make a copy of an existing repository
413 clone make a copy of an existing repository
414 commit, ci commit the specified files or all outstanding changes
414 commit, ci commit the specified files or all outstanding changes
415 continue resumes an interrupted operation (EXPERIMENTAL)
415 continue resumes an interrupted operation (EXPERIMENTAL)
416 diff diff repository (or selected files)
416 diff diff repository (or selected files)
417 export dump the header and diffs for one or more changesets
417 export dump the header and diffs for one or more changesets
418 forget forget the specified files on the next commit
418 forget forget the specified files on the next commit
419 init create a new repository in the given directory
419 init create a new repository in the given directory
420 log, history show revision history of entire repository or files
420 log, history show revision history of entire repository or files
421 merge merge another revision into working directory
421 merge merge another revision into working directory
422 pull pull changes from the specified source
422 pull pull changes from the specified source
423 push push changes to the specified destination
423 push push changes to the specified destination
424 remove, rm remove the specified files on the next commit
424 remove, rm remove the specified files on the next commit
425 serve start stand-alone webserver
425 serve start stand-alone webserver
426 status, st show changed files in the working directory
426 status, st show changed files in the working directory
427 summary, sum summarize working directory state
427 summary, sum summarize working directory state
428 update, up, checkout, co
428 update, up, checkout, co
429 update working directory (or switch revisions)
429 update working directory (or switch revisions)
430
430
431 global options ([+] can be repeated):
431 global options ([+] can be repeated):
432
432
433 -R --repository REPO repository root directory or name of overlay bundle
433 -R --repository REPO repository root directory or name of overlay bundle
434 file
434 file
435 --cwd DIR change working directory
435 --cwd DIR change working directory
436 -y --noninteractive do not prompt, automatically pick the first choice for
436 -y --noninteractive do not prompt, automatically pick the first choice for
437 all prompts
437 all prompts
438 -q --quiet suppress output
438 -q --quiet suppress output
439 -v --verbose enable additional output
439 -v --verbose enable additional output
440 --color TYPE when to colorize (boolean, always, auto, never, or
440 --color TYPE when to colorize (boolean, always, auto, never, or
441 debug)
441 debug)
442 --config CONFIG [+] set/override config option (use 'section.name=value')
442 --config CONFIG [+] set/override config option (use 'section.name=value')
443 --debug enable debugging output
443 --debug enable debugging output
444 --debugger start debugger
444 --debugger start debugger
445 --encoding ENCODE set the charset encoding (default: ascii)
445 --encoding ENCODE set the charset encoding (default: ascii)
446 --encodingmode MODE set the charset encoding mode (default: strict)
446 --encodingmode MODE set the charset encoding mode (default: strict)
447 --traceback always print a traceback on exception
447 --traceback always print a traceback on exception
448 --time time how long the command takes
448 --time time how long the command takes
449 --profile print command execution profile
449 --profile print command execution profile
450 --version output version information and exit
450 --version output version information and exit
451 -h --help display help and exit
451 -h --help display help and exit
452 --hidden consider hidden changesets
452 --hidden consider hidden changesets
453 --pager TYPE when to paginate (boolean, always, auto, or never)
453 --pager TYPE when to paginate (boolean, always, auto, or never)
454 (default: auto)
454 (default: auto)
455
455
456 (use 'hg help' for the full list of commands)
456 (use 'hg help' for the full list of commands)
457
457
458 $ hg add -h
458 $ hg add -h
459 hg add [OPTION]... [FILE]...
459 hg add [OPTION]... [FILE]...
460
460
461 add the specified files on the next commit
461 add the specified files on the next commit
462
462
463 Schedule files to be version controlled and added to the repository.
463 Schedule files to be version controlled and added to the repository.
464
464
465 The files will be added to the repository at the next commit. To undo an
465 The files will be added to the repository at the next commit. To undo an
466 add before that, see 'hg forget'.
466 add before that, see 'hg forget'.
467
467
468 If no names are given, add all files to the repository (except files
468 If no names are given, add all files to the repository (except files
469 matching ".hgignore").
469 matching ".hgignore").
470
470
471 Returns 0 if all files are successfully added.
471 Returns 0 if all files are successfully added.
472
472
473 options ([+] can be repeated):
473 options ([+] can be repeated):
474
474
475 -I --include PATTERN [+] include names matching the given patterns
475 -I --include PATTERN [+] include names matching the given patterns
476 -X --exclude PATTERN [+] exclude names matching the given patterns
476 -X --exclude PATTERN [+] exclude names matching the given patterns
477 -S --subrepos recurse into subrepositories
477 -S --subrepos recurse into subrepositories
478 -n --dry-run do not perform actions, just print output
478 -n --dry-run do not perform actions, just print output
479
479
480 (some details hidden, use --verbose to show complete help)
480 (some details hidden, use --verbose to show complete help)
481
481
482 Verbose help for add
482 Verbose help for add
483
483
484 $ hg add -hv
484 $ hg add -hv
485 hg add [OPTION]... [FILE]...
485 hg add [OPTION]... [FILE]...
486
486
487 add the specified files on the next commit
487 add the specified files on the next commit
488
488
489 Schedule files to be version controlled and added to the repository.
489 Schedule files to be version controlled and added to the repository.
490
490
491 The files will be added to the repository at the next commit. To undo an
491 The files will be added to the repository at the next commit. To undo an
492 add before that, see 'hg forget'.
492 add before that, see 'hg forget'.
493
493
494 If no names are given, add all files to the repository (except files
494 If no names are given, add all files to the repository (except files
495 matching ".hgignore").
495 matching ".hgignore").
496
496
497 Examples:
497 Examples:
498
498
499 - New (unknown) files are added automatically by 'hg add':
499 - New (unknown) files are added automatically by 'hg add':
500
500
501 $ ls
501 $ ls
502 foo.c
502 foo.c
503 $ hg status
503 $ hg status
504 ? foo.c
504 ? foo.c
505 $ hg add
505 $ hg add
506 adding foo.c
506 adding foo.c
507 $ hg status
507 $ hg status
508 A foo.c
508 A foo.c
509
509
510 - Specific files to be added can be specified:
510 - Specific files to be added can be specified:
511
511
512 $ ls
512 $ ls
513 bar.c foo.c
513 bar.c foo.c
514 $ hg status
514 $ hg status
515 ? bar.c
515 ? bar.c
516 ? foo.c
516 ? foo.c
517 $ hg add bar.c
517 $ hg add bar.c
518 $ hg status
518 $ hg status
519 A bar.c
519 A bar.c
520 ? foo.c
520 ? foo.c
521
521
522 Returns 0 if all files are successfully added.
522 Returns 0 if all files are successfully added.
523
523
524 options ([+] can be repeated):
524 options ([+] can be repeated):
525
525
526 -I --include PATTERN [+] include names matching the given patterns
526 -I --include PATTERN [+] include names matching the given patterns
527 -X --exclude PATTERN [+] exclude names matching the given patterns
527 -X --exclude PATTERN [+] exclude names matching the given patterns
528 -S --subrepos recurse into subrepositories
528 -S --subrepos recurse into subrepositories
529 -n --dry-run do not perform actions, just print output
529 -n --dry-run do not perform actions, just print output
530
530
531 global options ([+] can be repeated):
531 global options ([+] can be repeated):
532
532
533 -R --repository REPO repository root directory or name of overlay bundle
533 -R --repository REPO repository root directory or name of overlay bundle
534 file
534 file
535 --cwd DIR change working directory
535 --cwd DIR change working directory
536 -y --noninteractive do not prompt, automatically pick the first choice for
536 -y --noninteractive do not prompt, automatically pick the first choice for
537 all prompts
537 all prompts
538 -q --quiet suppress output
538 -q --quiet suppress output
539 -v --verbose enable additional output
539 -v --verbose enable additional output
540 --color TYPE when to colorize (boolean, always, auto, never, or
540 --color TYPE when to colorize (boolean, always, auto, never, or
541 debug)
541 debug)
542 --config CONFIG [+] set/override config option (use 'section.name=value')
542 --config CONFIG [+] set/override config option (use 'section.name=value')
543 --debug enable debugging output
543 --debug enable debugging output
544 --debugger start debugger
544 --debugger start debugger
545 --encoding ENCODE set the charset encoding (default: ascii)
545 --encoding ENCODE set the charset encoding (default: ascii)
546 --encodingmode MODE set the charset encoding mode (default: strict)
546 --encodingmode MODE set the charset encoding mode (default: strict)
547 --traceback always print a traceback on exception
547 --traceback always print a traceback on exception
548 --time time how long the command takes
548 --time time how long the command takes
549 --profile print command execution profile
549 --profile print command execution profile
550 --version output version information and exit
550 --version output version information and exit
551 -h --help display help and exit
551 -h --help display help and exit
552 --hidden consider hidden changesets
552 --hidden consider hidden changesets
553 --pager TYPE when to paginate (boolean, always, auto, or never)
553 --pager TYPE when to paginate (boolean, always, auto, or never)
554 (default: auto)
554 (default: auto)
555
555
556 Test the textwidth config option
556 Test the textwidth config option
557
557
558 $ hg root -h --config ui.textwidth=50
558 $ hg root -h --config ui.textwidth=50
559 hg root
559 hg root
560
560
561 print the root (top) of the current working
561 print the root (top) of the current working
562 directory
562 directory
563
563
564 Print the root directory of the current
564 Print the root directory of the current
565 repository.
565 repository.
566
566
567 Returns 0 on success.
567 Returns 0 on success.
568
568
569 options:
569 options:
570
570
571 -T --template TEMPLATE display with template
571 -T --template TEMPLATE display with template
572
572
573 (some details hidden, use --verbose to show
573 (some details hidden, use --verbose to show
574 complete help)
574 complete help)
575
575
576 Test help option with version option
576 Test help option with version option
577
577
578 $ hg add -h --version
578 $ hg add -h --version
579 Mercurial Distributed SCM (version *) (glob)
579 Mercurial Distributed SCM (version *) (glob)
580 (see https://mercurial-scm.org for more information)
580 (see https://mercurial-scm.org for more information)
581
581
582 Copyright (C) 2005-* Olivia Mackall and others (glob)
582 Copyright (C) 2005-* Olivia Mackall and others (glob)
583 This is free software; see the source for copying conditions. There is NO
583 This is free software; see the source for copying conditions. There is NO
584 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
584 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
585
585
586 $ hg add --skjdfks
586 $ hg add --skjdfks
587 hg add: option --skjdfks not recognized
587 hg add: option --skjdfks not recognized
588 hg add [OPTION]... [FILE]...
588 hg add [OPTION]... [FILE]...
589
589
590 add the specified files on the next commit
590 add the specified files on the next commit
591
591
592 options ([+] can be repeated):
592 options ([+] can be repeated):
593
593
594 -I --include PATTERN [+] include names matching the given patterns
594 -I --include PATTERN [+] include names matching the given patterns
595 -X --exclude PATTERN [+] exclude names matching the given patterns
595 -X --exclude PATTERN [+] exclude names matching the given patterns
596 -S --subrepos recurse into subrepositories
596 -S --subrepos recurse into subrepositories
597 -n --dry-run do not perform actions, just print output
597 -n --dry-run do not perform actions, just print output
598
598
599 (use 'hg add -h' to show more help)
599 (use 'hg add -h' to show more help)
600 [10]
600 [10]
601
601
602 Test ambiguous command help
602 Test ambiguous command help
603
603
604 $ hg help ad
604 $ hg help ad
605 list of commands:
605 list of commands:
606
606
607 add add the specified files on the next commit
607 add add the specified files on the next commit
608 addremove add all new files, delete all missing files
608 addremove add all new files, delete all missing files
609
609
610 (use 'hg help -v ad' to show built-in aliases and global options)
610 (use 'hg help -v ad' to show built-in aliases and global options)
611
611
612 Test command without options
612 Test command without options
613
613
614 $ hg help verify
614 $ hg help verify
615 hg verify
615 hg verify
616
616
617 verify the integrity of the repository
617 verify the integrity of the repository
618
618
619 Verify the integrity of the current repository.
619 Verify the integrity of the current repository.
620
620
621 This will perform an extensive check of the repository's integrity,
621 This will perform an extensive check of the repository's integrity,
622 validating the hashes and checksums of each entry in the changelog,
622 validating the hashes and checksums of each entry in the changelog,
623 manifest, and tracked files, as well as the integrity of their crosslinks
623 manifest, and tracked files, as well as the integrity of their crosslinks
624 and indices.
624 and indices.
625
625
626 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
626 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
627 information about recovery from corruption of the repository.
627 information about recovery from corruption of the repository.
628
628
629 Returns 0 on success, 1 if errors are encountered.
629 Returns 0 on success, 1 if errors are encountered.
630
630
631 options:
631 options:
632
632
633 (some details hidden, use --verbose to show complete help)
633 (some details hidden, use --verbose to show complete help)
634
634
635 $ hg help diff
635 $ hg help diff
636 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
636 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
637
637
638 diff repository (or selected files)
638 diff repository (or selected files)
639
639
640 Show differences between revisions for the specified files.
640 Show differences between revisions for the specified files.
641
641
642 Differences between files are shown using the unified diff format.
642 Differences between files are shown using the unified diff format.
643
643
644 Note:
644 Note:
645 'hg diff' may generate unexpected results for merges, as it will
645 'hg diff' may generate unexpected results for merges, as it will
646 default to comparing against the working directory's first parent
646 default to comparing against the working directory's first parent
647 changeset if no revisions are specified. To diff against the conflict
647 changeset if no revisions are specified. To diff against the conflict
648 regions, you can use '--config diff.merge=yes'.
648 regions, you can use '--config diff.merge=yes'.
649
649
650 By default, the working directory files are compared to its first parent.
650 By default, the working directory files are compared to its first parent.
651 To see the differences from another revision, use --from. To see the
651 To see the differences from another revision, use --from. To see the
652 difference to another revision, use --to. For example, 'hg diff --from .^'
652 difference to another revision, use --to. For example, 'hg diff --from .^'
653 will show the differences from the working copy's grandparent to the
653 will show the differences from the working copy's grandparent to the
654 working copy, 'hg diff --to .' will show the diff from the working copy to
654 working copy, 'hg diff --to .' will show the diff from the working copy to
655 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
655 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
656 1.2' will show the diff between those two revisions.
656 1.2' will show the diff between those two revisions.
657
657
658 Alternatively you can specify -c/--change with a revision to see the
658 Alternatively you can specify -c/--change with a revision to see the
659 changes in that changeset relative to its first parent (i.e. 'hg diff -c
659 changes in that changeset relative to its first parent (i.e. 'hg diff -c
660 42' is equivalent to 'hg diff --from 42^ --to 42')
660 42' is equivalent to 'hg diff --from 42^ --to 42')
661
661
662 Without the -a/--text option, diff will avoid generating diffs of files it
662 Without the -a/--text option, diff will avoid generating diffs of files it
663 detects as binary. With -a, diff will generate a diff anyway, probably
663 detects as binary. With -a, diff will generate a diff anyway, probably
664 with undesirable results.
664 with undesirable results.
665
665
666 Use the -g/--git option to generate diffs in the git extended diff format.
666 Use the -g/--git option to generate diffs in the git extended diff format.
667 For more information, read 'hg help diffs'.
667 For more information, read 'hg help diffs'.
668
668
669 Returns 0 on success.
669 Returns 0 on success.
670
670
671 options ([+] can be repeated):
671 options ([+] can be repeated):
672
672
673 --from REV1 revision to diff from
673 --from REV1 revision to diff from
674 --to REV2 revision to diff to
674 --to REV2 revision to diff to
675 -c --change REV change made by revision
675 -c --change REV change made by revision
676 -a --text treat all files as text
676 -a --text treat all files as text
677 -g --git use git extended diff format
677 -g --git use git extended diff format
678 --binary generate binary diffs in git mode (default)
678 --binary generate binary diffs in git mode (default)
679 --nodates omit dates from diff headers
679 --nodates omit dates from diff headers
680 --noprefix omit a/ and b/ prefixes from filenames
680 --noprefix omit a/ and b/ prefixes from filenames
681 -p --show-function show which function each change is in
681 -p --show-function show which function each change is in
682 --reverse produce a diff that undoes the changes
682 --reverse produce a diff that undoes the changes
683 -w --ignore-all-space ignore white space when comparing lines
683 -w --ignore-all-space ignore white space when comparing lines
684 -b --ignore-space-change ignore changes in the amount of white space
684 -b --ignore-space-change ignore changes in the amount of white space
685 -B --ignore-blank-lines ignore changes whose lines are all blank
685 -B --ignore-blank-lines ignore changes whose lines are all blank
686 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
686 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
687 -U --unified NUM number of lines of context to show
687 -U --unified NUM number of lines of context to show
688 --stat output diffstat-style summary of changes
688 --stat output diffstat-style summary of changes
689 --root DIR produce diffs relative to subdirectory
689 --root DIR produce diffs relative to subdirectory
690 -I --include PATTERN [+] include names matching the given patterns
690 -I --include PATTERN [+] include names matching the given patterns
691 -X --exclude PATTERN [+] exclude names matching the given patterns
691 -X --exclude PATTERN [+] exclude names matching the given patterns
692 -S --subrepos recurse into subrepositories
692 -S --subrepos recurse into subrepositories
693
693
694 (some details hidden, use --verbose to show complete help)
694 (some details hidden, use --verbose to show complete help)
695
695
696 $ hg help status
696 $ hg help status
697 hg status [OPTION]... [FILE]...
697 hg status [OPTION]... [FILE]...
698
698
699 aliases: st
699 aliases: st
700
700
701 show changed files in the working directory
701 show changed files in the working directory
702
702
703 Show status of files in the repository. If names are given, only files
703 Show status of files in the repository. If names are given, only files
704 that match are shown. Files that are clean or ignored or the source of a
704 that match are shown. Files that are clean or ignored or the source of a
705 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
705 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
706 -C/--copies or -A/--all are given. Unless options described with "show
706 -C/--copies or -A/--all are given. Unless options described with "show
707 only ..." are given, the options -mardu are used.
707 only ..." are given, the options -mardu are used.
708
708
709 Option -q/--quiet hides untracked (unknown and ignored) files unless
709 Option -q/--quiet hides untracked (unknown and ignored) files unless
710 explicitly requested with -u/--unknown or -i/--ignored.
710 explicitly requested with -u/--unknown or -i/--ignored.
711
711
712 Note:
712 Note:
713 'hg status' may appear to disagree with diff if permissions have
713 'hg status' may appear to disagree with diff if permissions have
714 changed or a merge has occurred. The standard diff format does not
714 changed or a merge has occurred. The standard diff format does not
715 report permission changes and diff only reports changes relative to one
715 report permission changes and diff only reports changes relative to one
716 merge parent.
716 merge parent.
717
717
718 If one revision is given, it is used as the base revision. If two
718 If one revision is given, it is used as the base revision. If two
719 revisions are given, the differences between them are shown. The --change
719 revisions are given, the differences between them are shown. The --change
720 option can also be used as a shortcut to list the changed files of a
720 option can also be used as a shortcut to list the changed files of a
721 revision from its first parent.
721 revision from its first parent.
722
722
723 The codes used to show the status of files are:
723 The codes used to show the status of files are:
724
724
725 M = modified
725 M = modified
726 A = added
726 A = added
727 R = removed
727 R = removed
728 C = clean
728 C = clean
729 ! = missing (deleted by non-hg command, but still tracked)
729 ! = missing (deleted by non-hg command, but still tracked)
730 ? = not tracked
730 ? = not tracked
731 I = ignored
731 I = ignored
732 = origin of the previous file (with --copies)
732 = origin of the previous file (with --copies)
733
733
734 Returns 0 on success.
734 Returns 0 on success.
735
735
736 options ([+] can be repeated):
736 options ([+] can be repeated):
737
737
738 -A --all show status of all files
738 -A --all show status of all files
739 -m --modified show only modified files
739 -m --modified show only modified files
740 -a --added show only added files
740 -a --added show only added files
741 -r --removed show only removed files
741 -r --removed show only removed files
742 -d --deleted show only missing files
742 -d --deleted show only missing files
743 -c --clean show only files without changes
743 -c --clean show only files without changes
744 -u --unknown show only unknown (not tracked) files
744 -u --unknown show only unknown (not tracked) files
745 -i --ignored show only ignored files
745 -i --ignored show only ignored files
746 -n --no-status hide status prefix
746 -n --no-status hide status prefix
747 -C --copies show source of copied files
747 -C --copies show source of copied files
748 -0 --print0 end filenames with NUL, for use with xargs
748 -0 --print0 end filenames with NUL, for use with xargs
749 --rev REV [+] show difference from revision
749 --rev REV [+] show difference from revision
750 --change REV list the changed files of a revision
750 --change REV list the changed files of a revision
751 -I --include PATTERN [+] include names matching the given patterns
751 -I --include PATTERN [+] include names matching the given patterns
752 -X --exclude PATTERN [+] exclude names matching the given patterns
752 -X --exclude PATTERN [+] exclude names matching the given patterns
753 -S --subrepos recurse into subrepositories
753 -S --subrepos recurse into subrepositories
754 -T --template TEMPLATE display with template
754 -T --template TEMPLATE display with template
755
755
756 (some details hidden, use --verbose to show complete help)
756 (some details hidden, use --verbose to show complete help)
757
757
758 $ hg -q help status
758 $ hg -q help status
759 hg status [OPTION]... [FILE]...
759 hg status [OPTION]... [FILE]...
760
760
761 show changed files in the working directory
761 show changed files in the working directory
762
762
763 $ hg help foo
763 $ hg help foo
764 abort: no such help topic: foo
764 abort: no such help topic: foo
765 (try 'hg help --keyword foo')
765 (try 'hg help --keyword foo')
766 [10]
766 [10]
767
767
768 $ hg skjdfks
768 $ hg skjdfks
769 hg: unknown command 'skjdfks'
769 hg: unknown command 'skjdfks'
770 (use 'hg help' for a list of commands)
770 (use 'hg help' for a list of commands)
771 [10]
771 [10]
772
772
773 Typoed command gives suggestion
773 Typoed command gives suggestion
774 $ hg puls
774 $ hg puls
775 hg: unknown command 'puls'
775 hg: unknown command 'puls'
776 (did you mean one of pull, push?)
776 (did you mean one of pull, push?)
777 [10]
777 [10]
778
778
779 Not enabled extension gets suggested
779 Not enabled extension gets suggested
780
780
781 $ hg rebase
781 $ hg rebase
782 hg: unknown command 'rebase'
782 hg: unknown command 'rebase'
783 'rebase' is provided by the following extension:
783 'rebase' is provided by the following extension:
784
784
785 rebase command to move sets of revisions to a different ancestor
785 rebase command to move sets of revisions to a different ancestor
786
786
787 (use 'hg help extensions' for information on enabling extensions)
787 (use 'hg help extensions' for information on enabling extensions)
788 [10]
788 [10]
789
789
790 Disabled extension gets suggested
790 Disabled extension gets suggested
791 $ hg --config extensions.rebase=! rebase
791 $ hg --config extensions.rebase=! rebase
792 hg: unknown command 'rebase'
792 hg: unknown command 'rebase'
793 'rebase' is provided by the following extension:
793 'rebase' is provided by the following extension:
794
794
795 rebase command to move sets of revisions to a different ancestor
795 rebase command to move sets of revisions to a different ancestor
796
796
797 (use 'hg help extensions' for information on enabling extensions)
797 (use 'hg help extensions' for information on enabling extensions)
798 [10]
798 [10]
799
799
800 Checking that help adapts based on the config:
800 Checking that help adapts based on the config:
801
801
802 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
802 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
803 -g --[no-]git use git extended diff format (default: on from
803 -g --[no-]git use git extended diff format (default: on from
804 config)
804 config)
805
805
806 Make sure that we don't run afoul of the help system thinking that
806 Make sure that we don't run afoul of the help system thinking that
807 this is a section and erroring out weirdly.
807 this is a section and erroring out weirdly.
808
808
809 $ hg .log
809 $ hg .log
810 hg: unknown command '.log'
810 hg: unknown command '.log'
811 (did you mean log?)
811 (did you mean log?)
812 [10]
812 [10]
813
813
814 $ hg log.
814 $ hg log.
815 hg: unknown command 'log.'
815 hg: unknown command 'log.'
816 (did you mean log?)
816 (did you mean log?)
817 [10]
817 [10]
818 $ hg pu.lh
818 $ hg pu.lh
819 hg: unknown command 'pu.lh'
819 hg: unknown command 'pu.lh'
820 (did you mean one of pull, push?)
820 (did you mean one of pull, push?)
821 [10]
821 [10]
822
822
823 $ cat > helpext.py <<EOF
823 $ cat > helpext.py <<EOF
824 > import os
824 > import os
825 > from mercurial import commands, fancyopts, registrar
825 > from mercurial import commands, fancyopts, registrar
826 >
826 >
827 > def func(arg):
827 > def func(arg):
828 > return '%sfoo' % arg
828 > return '%sfoo' % arg
829 > class customopt(fancyopts.customopt):
829 > class customopt(fancyopts.customopt):
830 > def newstate(self, oldstate, newparam, abort):
830 > def newstate(self, oldstate, newparam, abort):
831 > return '%sbar' % oldstate
831 > return '%sbar' % oldstate
832 > cmdtable = {}
832 > cmdtable = {}
833 > command = registrar.command(cmdtable)
833 > command = registrar.command(cmdtable)
834 >
834 >
835 > @command(b'nohelp',
835 > @command(b'nohelp',
836 > [(b'', b'longdesc', 3, b'x'*67),
836 > [(b'', b'longdesc', 3, b'x'*67),
837 > (b'n', b'', None, b'normal desc'),
837 > (b'n', b'', None, b'normal desc'),
838 > (b'', b'newline', b'', b'line1\nline2'),
838 > (b'', b'newline', b'', b'line1\nline2'),
839 > (b'', b'default-off', False, b'enable X'),
839 > (b'', b'default-off', False, b'enable X'),
840 > (b'', b'default-on', True, b'enable Y'),
840 > (b'', b'default-on', True, b'enable Y'),
841 > (b'', b'callableopt', func, b'adds foo'),
841 > (b'', b'callableopt', func, b'adds foo'),
842 > (b'', b'customopt', customopt(''), b'adds bar'),
842 > (b'', b'customopt', customopt(''), b'adds bar'),
843 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
843 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
844 > b'hg nohelp',
844 > b'hg nohelp',
845 > norepo=True)
845 > norepo=True)
846 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
846 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
847 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
847 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
848 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
848 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
849 > def nohelp(ui, *args, **kwargs):
849 > def nohelp(ui, *args, **kwargs):
850 > pass
850 > pass
851 >
851 >
852 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
852 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
853 > def hashelp(ui, *args, **kwargs):
853 > def hashelp(ui, *args, **kwargs):
854 > """Extension command's help"""
854 > """Extension command's help"""
855 >
855 >
856 > def uisetup(ui):
856 > def uisetup(ui):
857 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
857 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
858 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
858 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
859 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
859 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
860 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
860 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
861 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
861 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
862 >
862 >
863 > EOF
863 > EOF
864 $ echo '[extensions]' >> $HGRCPATH
864 $ echo '[extensions]' >> $HGRCPATH
865 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
865 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
866
866
867 Test for aliases
867 Test for aliases
868
868
869 $ hg help | grep hgalias
869 $ hg help | grep hgalias
870 hgalias My doc
870 hgalias My doc
871
871
872 $ hg help hgalias
872 $ hg help hgalias
873 hg hgalias [--remote]
873 hg hgalias [--remote]
874
874
875 alias for: hg summary
875 alias for: hg summary
876
876
877 My doc
877 My doc
878
878
879 defined by: helpext
879 defined by: helpext
880
880
881 options:
881 options:
882
882
883 --remote check for push and pull
883 --remote check for push and pull
884
884
885 (some details hidden, use --verbose to show complete help)
885 (some details hidden, use --verbose to show complete help)
886 $ hg help hgaliasnodoc
886 $ hg help hgaliasnodoc
887 hg hgaliasnodoc [--remote]
887 hg hgaliasnodoc [--remote]
888
888
889 alias for: hg summary
889 alias for: hg summary
890
890
891 summarize working directory state
891 summarize working directory state
892
892
893 This generates a brief summary of the working directory state, including
893 This generates a brief summary of the working directory state, including
894 parents, branch, commit status, phase and available updates.
894 parents, branch, commit status, phase and available updates.
895
895
896 With the --remote option, this will check the default paths for incoming
896 With the --remote option, this will check the default paths for incoming
897 and outgoing changes. This can be time-consuming.
897 and outgoing changes. This can be time-consuming.
898
898
899 Returns 0 on success.
899 Returns 0 on success.
900
900
901 defined by: helpext
901 defined by: helpext
902
902
903 options:
903 options:
904
904
905 --remote check for push and pull
905 --remote check for push and pull
906
906
907 (some details hidden, use --verbose to show complete help)
907 (some details hidden, use --verbose to show complete help)
908
908
909 $ hg help shellalias
909 $ hg help shellalias
910 hg shellalias
910 hg shellalias
911
911
912 shell alias for: echo hi
912 shell alias for: echo hi
913
913
914 (no help text available)
914 (no help text available)
915
915
916 defined by: helpext
916 defined by: helpext
917
917
918 (some details hidden, use --verbose to show complete help)
918 (some details hidden, use --verbose to show complete help)
919
919
920 Test command with no help text
920 Test command with no help text
921
921
922 $ hg help nohelp
922 $ hg help nohelp
923 hg nohelp
923 hg nohelp
924
924
925 (no help text available)
925 (no help text available)
926
926
927 options:
927 options:
928
928
929 --longdesc VALUE
929 --longdesc VALUE
930 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
930 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
931 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
931 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
932 -n -- normal desc
932 -n -- normal desc
933 --newline VALUE line1 line2
933 --newline VALUE line1 line2
934 --default-off enable X
934 --default-off enable X
935 --[no-]default-on enable Y (default: on)
935 --[no-]default-on enable Y (default: on)
936 --callableopt VALUE adds foo
936 --callableopt VALUE adds foo
937 --customopt VALUE adds bar
937 --customopt VALUE adds bar
938 --customopt-withdefault VALUE adds bar (default: foo)
938 --customopt-withdefault VALUE adds bar (default: foo)
939
939
940 (some details hidden, use --verbose to show complete help)
940 (some details hidden, use --verbose to show complete help)
941
941
942 Test that default list of commands includes extension commands that have help,
942 Test that default list of commands includes extension commands that have help,
943 but not those that don't, except in verbose mode, when a keyword is passed, or
943 but not those that don't, except in verbose mode, when a keyword is passed, or
944 when help about the extension is requested.
944 when help about the extension is requested.
945
945
946 #if no-extraextensions
946 #if no-extraextensions
947
947
948 $ hg help | grep hashelp
948 $ hg help | grep hashelp
949 hashelp Extension command's help
949 hashelp Extension command's help
950 $ hg help | grep nohelp
950 $ hg help | grep nohelp
951 [1]
951 [1]
952 $ hg help -v | grep nohelp
952 $ hg help -v | grep nohelp
953 nohelp (no help text available)
953 nohelp (no help text available)
954
954
955 $ hg help -k nohelp
955 $ hg help -k nohelp
956 Commands:
956 Commands:
957
957
958 nohelp hg nohelp
958 nohelp hg nohelp
959
959
960 Extension Commands:
960 Extension Commands:
961
961
962 nohelp (no help text available)
962 nohelp (no help text available)
963
963
964 $ hg help helpext
964 $ hg help helpext
965 helpext extension - no help text available
965 helpext extension - no help text available
966
966
967 list of commands:
967 list of commands:
968
968
969 hashelp Extension command's help
969 hashelp Extension command's help
970 nohelp (no help text available)
970 nohelp (no help text available)
971
971
972 (use 'hg help -v helpext' to show built-in aliases and global options)
972 (use 'hg help -v helpext' to show built-in aliases and global options)
973
973
974 #endif
974 #endif
975
975
976 Test list of internal help commands
976 Test list of internal help commands
977
977
978 $ hg help debug
978 $ hg help debug
979 debug commands (internal and unsupported):
979 debug commands (internal and unsupported):
980
980
981 debug-delta-find
981 debug-delta-find
982 display the computation to get to a valid delta for storing REV
982 display the computation to get to a valid delta for storing REV
983 debug-repair-issue6528
983 debug-repair-issue6528
984 find affected revisions and repair them. See issue6528 for more
984 find affected revisions and repair them. See issue6528 for more
985 details.
985 details.
986 debug-revlog-index
987 dump index data for a revlog
986 debugancestor
988 debugancestor
987 find the ancestor revision of two revisions in a given index
989 find the ancestor revision of two revisions in a given index
988 debugantivirusrunning
990 debugantivirusrunning
989 attempt to trigger an antivirus scanner to see if one is active
991 attempt to trigger an antivirus scanner to see if one is active
990 debugapplystreamclonebundle
992 debugapplystreamclonebundle
991 apply a stream clone bundle file
993 apply a stream clone bundle file
992 debugbackupbundle
994 debugbackupbundle
993 lists the changesets available in backup bundles
995 lists the changesets available in backup bundles
994 debugbuilddag
996 debugbuilddag
995 builds a repo with a given DAG from scratch in the current
997 builds a repo with a given DAG from scratch in the current
996 empty repo
998 empty repo
997 debugbundle lists the contents of a bundle
999 debugbundle lists the contents of a bundle
998 debugcapabilities
1000 debugcapabilities
999 lists the capabilities of a remote peer
1001 lists the capabilities of a remote peer
1000 debugchangedfiles
1002 debugchangedfiles
1001 list the stored files changes for a revision
1003 list the stored files changes for a revision
1002 debugcheckstate
1004 debugcheckstate
1003 validate the correctness of the current dirstate
1005 validate the correctness of the current dirstate
1004 debugcolor show available color, effects or style
1006 debugcolor show available color, effects or style
1005 debugcommands
1007 debugcommands
1006 list all available commands and options
1008 list all available commands and options
1007 debugcomplete
1009 debugcomplete
1008 returns the completion list associated with the given command
1010 returns the completion list associated with the given command
1009 debugcreatestreamclonebundle
1011 debugcreatestreamclonebundle
1010 create a stream clone bundle file
1012 create a stream clone bundle file
1011 debugdag format the changelog or an index DAG as a concise textual
1013 debugdag format the changelog or an index DAG as a concise textual
1012 description
1014 description
1013 debugdata dump the contents of a data file revision
1015 debugdata dump the contents of a data file revision
1014 debugdate parse and display a date
1016 debugdate parse and display a date
1015 debugdeltachain
1017 debugdeltachain
1016 dump information about delta chains in a revlog
1018 dump information about delta chains in a revlog
1017 debugdirstate
1019 debugdirstate
1018 show the contents of the current dirstate
1020 show the contents of the current dirstate
1019 debugdirstateignorepatternshash
1021 debugdirstateignorepatternshash
1020 show the hash of ignore patterns stored in dirstate if v2,
1022 show the hash of ignore patterns stored in dirstate if v2,
1021 debugdiscovery
1023 debugdiscovery
1022 runs the changeset discovery protocol in isolation
1024 runs the changeset discovery protocol in isolation
1023 debugdownload
1025 debugdownload
1024 download a resource using Mercurial logic and config
1026 download a resource using Mercurial logic and config
1025 debugextensions
1027 debugextensions
1026 show information about active extensions
1028 show information about active extensions
1027 debugfileset parse and apply a fileset specification
1029 debugfileset parse and apply a fileset specification
1028 debugformat display format information about the current repository
1030 debugformat display format information about the current repository
1029 debugfsinfo show information detected about current filesystem
1031 debugfsinfo show information detected about current filesystem
1030 debuggetbundle
1032 debuggetbundle
1031 retrieves a bundle from a repo
1033 retrieves a bundle from a repo
1032 debugignore display the combined ignore pattern and information about
1034 debugignore display the combined ignore pattern and information about
1033 ignored files
1035 ignored files
1034 debugindex dump index data for a storage primitive
1035 debugindexdot
1036 debugindexdot
1036 dump an index DAG as a graphviz dot file
1037 dump an index DAG as a graphviz dot file
1037 debugindexstats
1038 debugindexstats
1038 show stats related to the changelog index
1039 show stats related to the changelog index
1039 debuginstall test Mercurial installation
1040 debuginstall test Mercurial installation
1040 debugknown test whether node ids are known to a repo
1041 debugknown test whether node ids are known to a repo
1041 debuglocks show or modify state of locks
1042 debuglocks show or modify state of locks
1042 debugmanifestfulltextcache
1043 debugmanifestfulltextcache
1043 show, clear or amend the contents of the manifest fulltext
1044 show, clear or amend the contents of the manifest fulltext
1044 cache
1045 cache
1045 debugmergestate
1046 debugmergestate
1046 print merge state
1047 print merge state
1047 debugnamecomplete
1048 debugnamecomplete
1048 complete "names" - tags, open branch names, bookmark names
1049 complete "names" - tags, open branch names, bookmark names
1049 debugnodemap write and inspect on disk nodemap
1050 debugnodemap write and inspect on disk nodemap
1050 debugobsolete
1051 debugobsolete
1051 create arbitrary obsolete marker
1052 create arbitrary obsolete marker
1052 debugoptADV (no help text available)
1053 debugoptADV (no help text available)
1053 debugoptDEP (no help text available)
1054 debugoptDEP (no help text available)
1054 debugoptEXP (no help text available)
1055 debugoptEXP (no help text available)
1055 debugp1copies
1056 debugp1copies
1056 dump copy information compared to p1
1057 dump copy information compared to p1
1057 debugp2copies
1058 debugp2copies
1058 dump copy information compared to p2
1059 dump copy information compared to p2
1059 debugpathcomplete
1060 debugpathcomplete
1060 complete part or all of a tracked path
1061 complete part or all of a tracked path
1061 debugpathcopies
1062 debugpathcopies
1062 show copies between two revisions
1063 show copies between two revisions
1063 debugpeer establish a connection to a peer repository
1064 debugpeer establish a connection to a peer repository
1064 debugpickmergetool
1065 debugpickmergetool
1065 examine which merge tool is chosen for specified file
1066 examine which merge tool is chosen for specified file
1066 debugpushkey access the pushkey key/value protocol
1067 debugpushkey access the pushkey key/value protocol
1067 debugpvec (no help text available)
1068 debugpvec (no help text available)
1068 debugrebuilddirstate
1069 debugrebuilddirstate
1069 rebuild the dirstate as it would look like for the given
1070 rebuild the dirstate as it would look like for the given
1070 revision
1071 revision
1071 debugrebuildfncache
1072 debugrebuildfncache
1072 rebuild the fncache file
1073 rebuild the fncache file
1073 debugrename dump rename information
1074 debugrename dump rename information
1074 debugrequires
1075 debugrequires
1075 print the current repo requirements
1076 print the current repo requirements
1076 debugrevlog show data and statistics about a revlog
1077 debugrevlog show data and statistics about a revlog
1077 debugrevlogindex
1078 debugrevlogindex
1078 dump the contents of a revlog index
1079 dump the contents of a revlog index
1079 debugrevspec parse and apply a revision specification
1080 debugrevspec parse and apply a revision specification
1080 debugserve run a server with advanced settings
1081 debugserve run a server with advanced settings
1081 debugsetparents
1082 debugsetparents
1082 manually set the parents of the current working directory
1083 manually set the parents of the current working directory
1083 (DANGEROUS)
1084 (DANGEROUS)
1084 debugshell run an interactive Python interpreter
1085 debugshell run an interactive Python interpreter
1085 debugsidedata
1086 debugsidedata
1086 dump the side data for a cl/manifest/file revision
1087 dump the side data for a cl/manifest/file revision
1087 debugssl test a secure connection to a server
1088 debugssl test a secure connection to a server
1088 debugstrip strip changesets and all their descendants from the repository
1089 debugstrip strip changesets and all their descendants from the repository
1089 debugsub (no help text available)
1090 debugsub (no help text available)
1090 debugsuccessorssets
1091 debugsuccessorssets
1091 show set of successors for revision
1092 show set of successors for revision
1092 debugtagscache
1093 debugtagscache
1093 display the contents of .hg/cache/hgtagsfnodes1
1094 display the contents of .hg/cache/hgtagsfnodes1
1094 debugtemplate
1095 debugtemplate
1095 parse and apply a template
1096 parse and apply a template
1096 debuguigetpass
1097 debuguigetpass
1097 show prompt to type password
1098 show prompt to type password
1098 debuguiprompt
1099 debuguiprompt
1099 show plain prompt
1100 show plain prompt
1100 debugupdatecaches
1101 debugupdatecaches
1101 warm all known caches in the repository
1102 warm all known caches in the repository
1102 debugupgraderepo
1103 debugupgraderepo
1103 upgrade a repository to use different features
1104 upgrade a repository to use different features
1104 debugwalk show how files match on given patterns
1105 debugwalk show how files match on given patterns
1105 debugwhyunstable
1106 debugwhyunstable
1106 explain instabilities of a changeset
1107 explain instabilities of a changeset
1107 debugwireargs
1108 debugwireargs
1108 (no help text available)
1109 (no help text available)
1109 debugwireproto
1110 debugwireproto
1110 send wire protocol commands to a server
1111 send wire protocol commands to a server
1111
1112
1112 (use 'hg help -v debug' to show built-in aliases and global options)
1113 (use 'hg help -v debug' to show built-in aliases and global options)
1113
1114
1114 internals topic renders index of available sub-topics
1115 internals topic renders index of available sub-topics
1115
1116
1116 $ hg help internals
1117 $ hg help internals
1117 Technical implementation topics
1118 Technical implementation topics
1118 """""""""""""""""""""""""""""""
1119 """""""""""""""""""""""""""""""
1119
1120
1120 To access a subtopic, use "hg help internals.{subtopic-name}"
1121 To access a subtopic, use "hg help internals.{subtopic-name}"
1121
1122
1122 bid-merge Bid Merge Algorithm
1123 bid-merge Bid Merge Algorithm
1123 bundle2 Bundle2
1124 bundle2 Bundle2
1124 bundles Bundles
1125 bundles Bundles
1125 cbor CBOR
1126 cbor CBOR
1126 censor Censor
1127 censor Censor
1127 changegroups Changegroups
1128 changegroups Changegroups
1128 config Config Registrar
1129 config Config Registrar
1129 dirstate-v2 dirstate-v2 file format
1130 dirstate-v2 dirstate-v2 file format
1130 extensions Extension API
1131 extensions Extension API
1131 mergestate Mergestate
1132 mergestate Mergestate
1132 requirements Repository Requirements
1133 requirements Repository Requirements
1133 revlogs Revision Logs
1134 revlogs Revision Logs
1134 wireprotocol Wire Protocol
1135 wireprotocol Wire Protocol
1135 wireprotocolrpc
1136 wireprotocolrpc
1136 Wire Protocol RPC
1137 Wire Protocol RPC
1137 wireprotocolv2
1138 wireprotocolv2
1138 Wire Protocol Version 2
1139 Wire Protocol Version 2
1139
1140
1140 sub-topics can be accessed
1141 sub-topics can be accessed
1141
1142
1142 $ hg help internals.changegroups
1143 $ hg help internals.changegroups
1143 Changegroups
1144 Changegroups
1144 """"""""""""
1145 """"""""""""
1145
1146
1146 Changegroups are representations of repository revlog data, specifically
1147 Changegroups are representations of repository revlog data, specifically
1147 the changelog data, root/flat manifest data, treemanifest data, and
1148 the changelog data, root/flat manifest data, treemanifest data, and
1148 filelogs.
1149 filelogs.
1149
1150
1150 There are 4 versions of changegroups: "1", "2", "3" and "4". From a high-
1151 There are 4 versions of changegroups: "1", "2", "3" and "4". From a high-
1151 level, versions "1" and "2" are almost exactly the same, with the only
1152 level, versions "1" and "2" are almost exactly the same, with the only
1152 difference being an additional item in the *delta header*. Version "3"
1153 difference being an additional item in the *delta header*. Version "3"
1153 adds support for storage flags in the *delta header* and optionally
1154 adds support for storage flags in the *delta header* and optionally
1154 exchanging treemanifests (enabled by setting an option on the
1155 exchanging treemanifests (enabled by setting an option on the
1155 "changegroup" part in the bundle2). Version "4" adds support for
1156 "changegroup" part in the bundle2). Version "4" adds support for
1156 exchanging sidedata (additional revision metadata not part of the digest).
1157 exchanging sidedata (additional revision metadata not part of the digest).
1157
1158
1158 Changegroups when not exchanging treemanifests consist of 3 logical
1159 Changegroups when not exchanging treemanifests consist of 3 logical
1159 segments:
1160 segments:
1160
1161
1161 +---------------------------------+
1162 +---------------------------------+
1162 | | | |
1163 | | | |
1163 | changeset | manifest | filelogs |
1164 | changeset | manifest | filelogs |
1164 | | | |
1165 | | | |
1165 | | | |
1166 | | | |
1166 +---------------------------------+
1167 +---------------------------------+
1167
1168
1168 When exchanging treemanifests, there are 4 logical segments:
1169 When exchanging treemanifests, there are 4 logical segments:
1169
1170
1170 +-------------------------------------------------+
1171 +-------------------------------------------------+
1171 | | | | |
1172 | | | | |
1172 | changeset | root | treemanifests | filelogs |
1173 | changeset | root | treemanifests | filelogs |
1173 | | manifest | | |
1174 | | manifest | | |
1174 | | | | |
1175 | | | | |
1175 +-------------------------------------------------+
1176 +-------------------------------------------------+
1176
1177
1177 The principle building block of each segment is a *chunk*. A *chunk* is a
1178 The principle building block of each segment is a *chunk*. A *chunk* is a
1178 framed piece of data:
1179 framed piece of data:
1179
1180
1180 +---------------------------------------+
1181 +---------------------------------------+
1181 | | |
1182 | | |
1182 | length | data |
1183 | length | data |
1183 | (4 bytes) | (<length - 4> bytes) |
1184 | (4 bytes) | (<length - 4> bytes) |
1184 | | |
1185 | | |
1185 +---------------------------------------+
1186 +---------------------------------------+
1186
1187
1187 All integers are big-endian signed integers. Each chunk starts with a
1188 All integers are big-endian signed integers. Each chunk starts with a
1188 32-bit integer indicating the length of the entire chunk (including the
1189 32-bit integer indicating the length of the entire chunk (including the
1189 length field itself).
1190 length field itself).
1190
1191
1191 There is a special case chunk that has a value of 0 for the length
1192 There is a special case chunk that has a value of 0 for the length
1192 ("0x00000000"). We call this an *empty chunk*.
1193 ("0x00000000"). We call this an *empty chunk*.
1193
1194
1194 Delta Groups
1195 Delta Groups
1195 ============
1196 ============
1196
1197
1197 A *delta group* expresses the content of a revlog as a series of deltas,
1198 A *delta group* expresses the content of a revlog as a series of deltas,
1198 or patches against previous revisions.
1199 or patches against previous revisions.
1199
1200
1200 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1201 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1201 to signal the end of the delta group:
1202 to signal the end of the delta group:
1202
1203
1203 +------------------------------------------------------------------------+
1204 +------------------------------------------------------------------------+
1204 | | | | | |
1205 | | | | | |
1205 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1206 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1206 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1207 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1207 | | | | | |
1208 | | | | | |
1208 +------------------------------------------------------------------------+
1209 +------------------------------------------------------------------------+
1209
1210
1210 Each *chunk*'s data consists of the following:
1211 Each *chunk*'s data consists of the following:
1211
1212
1212 +---------------------------------------+
1213 +---------------------------------------+
1213 | | |
1214 | | |
1214 | delta header | delta data |
1215 | delta header | delta data |
1215 | (various by version) | (various) |
1216 | (various by version) | (various) |
1216 | | |
1217 | | |
1217 +---------------------------------------+
1218 +---------------------------------------+
1218
1219
1219 The *delta data* is a series of *delta*s that describe a diff from an
1220 The *delta data* is a series of *delta*s that describe a diff from an
1220 existing entry (either that the recipient already has, or previously
1221 existing entry (either that the recipient already has, or previously
1221 specified in the bundle/changegroup).
1222 specified in the bundle/changegroup).
1222
1223
1223 The *delta header* is different between versions "1", "2", "3" and "4" of
1224 The *delta header* is different between versions "1", "2", "3" and "4" of
1224 the changegroup format.
1225 the changegroup format.
1225
1226
1226 Version 1 (headerlen=80):
1227 Version 1 (headerlen=80):
1227
1228
1228 +------------------------------------------------------+
1229 +------------------------------------------------------+
1229 | | | | |
1230 | | | | |
1230 | node | p1 node | p2 node | link node |
1231 | node | p1 node | p2 node | link node |
1231 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1232 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1232 | | | | |
1233 | | | | |
1233 +------------------------------------------------------+
1234 +------------------------------------------------------+
1234
1235
1235 Version 2 (headerlen=100):
1236 Version 2 (headerlen=100):
1236
1237
1237 +------------------------------------------------------------------+
1238 +------------------------------------------------------------------+
1238 | | | | | |
1239 | | | | | |
1239 | node | p1 node | p2 node | base node | link node |
1240 | node | p1 node | p2 node | base node | link node |
1240 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1241 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1241 | | | | | |
1242 | | | | | |
1242 +------------------------------------------------------------------+
1243 +------------------------------------------------------------------+
1243
1244
1244 Version 3 (headerlen=102):
1245 Version 3 (headerlen=102):
1245
1246
1246 +------------------------------------------------------------------------------+
1247 +------------------------------------------------------------------------------+
1247 | | | | | | |
1248 | | | | | | |
1248 | node | p1 node | p2 node | base node | link node | flags |
1249 | node | p1 node | p2 node | base node | link node | flags |
1249 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1250 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1250 | | | | | | |
1251 | | | | | | |
1251 +------------------------------------------------------------------------------+
1252 +------------------------------------------------------------------------------+
1252
1253
1253 Version 4 (headerlen=103):
1254 Version 4 (headerlen=103):
1254
1255
1255 +------------------------------------------------------------------------------+----------+
1256 +------------------------------------------------------------------------------+----------+
1256 | | | | | | | |
1257 | | | | | | | |
1257 | node | p1 node | p2 node | base node | link node | flags | pflags |
1258 | node | p1 node | p2 node | base node | link node | flags | pflags |
1258 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
1259 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
1259 | | | | | | | |
1260 | | | | | | | |
1260 +------------------------------------------------------------------------------+----------+
1261 +------------------------------------------------------------------------------+----------+
1261
1262
1262 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1263 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1263 contain a series of *delta*s, densely packed (no separators). These deltas
1264 contain a series of *delta*s, densely packed (no separators). These deltas
1264 describe a diff from an existing entry (either that the recipient already
1265 describe a diff from an existing entry (either that the recipient already
1265 has, or previously specified in the bundle/changegroup). The format is
1266 has, or previously specified in the bundle/changegroup). The format is
1266 described more fully in "hg help internals.bdiff", but briefly:
1267 described more fully in "hg help internals.bdiff", but briefly:
1267
1268
1268 +---------------------------------------------------------------+
1269 +---------------------------------------------------------------+
1269 | | | | |
1270 | | | | |
1270 | start offset | end offset | new length | content |
1271 | start offset | end offset | new length | content |
1271 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1272 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1272 | | | | |
1273 | | | | |
1273 +---------------------------------------------------------------+
1274 +---------------------------------------------------------------+
1274
1275
1275 Please note that the length field in the delta data does *not* include
1276 Please note that the length field in the delta data does *not* include
1276 itself.
1277 itself.
1277
1278
1278 In version 1, the delta is always applied against the previous node from
1279 In version 1, the delta is always applied against the previous node from
1279 the changegroup or the first parent if this is the first entry in the
1280 the changegroup or the first parent if this is the first entry in the
1280 changegroup.
1281 changegroup.
1281
1282
1282 In version 2 and up, the delta base node is encoded in the entry in the
1283 In version 2 and up, the delta base node is encoded in the entry in the
1283 changegroup. This allows the delta to be expressed against any parent,
1284 changegroup. This allows the delta to be expressed against any parent,
1284 which can result in smaller deltas and more efficient encoding of data.
1285 which can result in smaller deltas and more efficient encoding of data.
1285
1286
1286 The *flags* field holds bitwise flags affecting the processing of revision
1287 The *flags* field holds bitwise flags affecting the processing of revision
1287 data. The following flags are defined:
1288 data. The following flags are defined:
1288
1289
1289 32768
1290 32768
1290 Censored revision. The revision's fulltext has been replaced by censor
1291 Censored revision. The revision's fulltext has been replaced by censor
1291 metadata. May only occur on file revisions.
1292 metadata. May only occur on file revisions.
1292
1293
1293 16384
1294 16384
1294 Ellipsis revision. Revision hash does not match data (likely due to
1295 Ellipsis revision. Revision hash does not match data (likely due to
1295 rewritten parents).
1296 rewritten parents).
1296
1297
1297 8192
1298 8192
1298 Externally stored. The revision fulltext contains "key:value" "\n"
1299 Externally stored. The revision fulltext contains "key:value" "\n"
1299 delimited metadata defining an object stored elsewhere. Used by the LFS
1300 delimited metadata defining an object stored elsewhere. Used by the LFS
1300 extension.
1301 extension.
1301
1302
1302 4096
1303 4096
1303 Contains copy information. This revision changes files in a way that
1304 Contains copy information. This revision changes files in a way that
1304 could affect copy tracing. This does *not* affect changegroup handling,
1305 could affect copy tracing. This does *not* affect changegroup handling,
1305 but is relevant for other parts of Mercurial.
1306 but is relevant for other parts of Mercurial.
1306
1307
1307 For historical reasons, the integer values are identical to revlog version
1308 For historical reasons, the integer values are identical to revlog version
1308 1 per-revision storage flags and correspond to bits being set in this
1309 1 per-revision storage flags and correspond to bits being set in this
1309 2-byte field. Bits were allocated starting from the most-significant bit,
1310 2-byte field. Bits were allocated starting from the most-significant bit,
1310 hence the reverse ordering and allocation of these flags.
1311 hence the reverse ordering and allocation of these flags.
1311
1312
1312 The *pflags* (protocol flags) field holds bitwise flags affecting the
1313 The *pflags* (protocol flags) field holds bitwise flags affecting the
1313 protocol itself. They are first in the header since they may affect the
1314 protocol itself. They are first in the header since they may affect the
1314 handling of the rest of the fields in a future version. They are defined
1315 handling of the rest of the fields in a future version. They are defined
1315 as such:
1316 as such:
1316
1317
1317 1 indicates whether to read a chunk of sidedata (of variable length) right
1318 1 indicates whether to read a chunk of sidedata (of variable length) right
1318 after the revision flags.
1319 after the revision flags.
1319
1320
1320 Changeset Segment
1321 Changeset Segment
1321 =================
1322 =================
1322
1323
1323 The *changeset segment* consists of a single *delta group* holding
1324 The *changeset segment* consists of a single *delta group* holding
1324 changelog data. The *empty chunk* at the end of the *delta group* denotes
1325 changelog data. The *empty chunk* at the end of the *delta group* denotes
1325 the boundary to the *manifest segment*.
1326 the boundary to the *manifest segment*.
1326
1327
1327 Manifest Segment
1328 Manifest Segment
1328 ================
1329 ================
1329
1330
1330 The *manifest segment* consists of a single *delta group* holding manifest
1331 The *manifest segment* consists of a single *delta group* holding manifest
1331 data. If treemanifests are in use, it contains only the manifest for the
1332 data. If treemanifests are in use, it contains only the manifest for the
1332 root directory of the repository. Otherwise, it contains the entire
1333 root directory of the repository. Otherwise, it contains the entire
1333 manifest data. The *empty chunk* at the end of the *delta group* denotes
1334 manifest data. The *empty chunk* at the end of the *delta group* denotes
1334 the boundary to the next segment (either the *treemanifests segment* or
1335 the boundary to the next segment (either the *treemanifests segment* or
1335 the *filelogs segment*, depending on version and the request options).
1336 the *filelogs segment*, depending on version and the request options).
1336
1337
1337 Treemanifests Segment
1338 Treemanifests Segment
1338 ---------------------
1339 ---------------------
1339
1340
1340 The *treemanifests segment* only exists in changegroup version "3" and
1341 The *treemanifests segment* only exists in changegroup version "3" and
1341 "4", and only if the 'treemanifest' param is part of the bundle2
1342 "4", and only if the 'treemanifest' param is part of the bundle2
1342 changegroup part (it is not possible to use changegroup version 3 or 4
1343 changegroup part (it is not possible to use changegroup version 3 or 4
1343 outside of bundle2). Aside from the filenames in the *treemanifests
1344 outside of bundle2). Aside from the filenames in the *treemanifests
1344 segment* containing a trailing "/" character, it behaves identically to
1345 segment* containing a trailing "/" character, it behaves identically to
1345 the *filelogs segment* (see below). The final sub-segment is followed by
1346 the *filelogs segment* (see below). The final sub-segment is followed by
1346 an *empty chunk* (logically, a sub-segment with filename size 0). This
1347 an *empty chunk* (logically, a sub-segment with filename size 0). This
1347 denotes the boundary to the *filelogs segment*.
1348 denotes the boundary to the *filelogs segment*.
1348
1349
1349 Filelogs Segment
1350 Filelogs Segment
1350 ================
1351 ================
1351
1352
1352 The *filelogs segment* consists of multiple sub-segments, each
1353 The *filelogs segment* consists of multiple sub-segments, each
1353 corresponding to an individual file whose data is being described:
1354 corresponding to an individual file whose data is being described:
1354
1355
1355 +--------------------------------------------------+
1356 +--------------------------------------------------+
1356 | | | | | |
1357 | | | | | |
1357 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1358 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1358 | | | | | (4 bytes) |
1359 | | | | | (4 bytes) |
1359 | | | | | |
1360 | | | | | |
1360 +--------------------------------------------------+
1361 +--------------------------------------------------+
1361
1362
1362 The final filelog sub-segment is followed by an *empty chunk* (logically,
1363 The final filelog sub-segment is followed by an *empty chunk* (logically,
1363 a sub-segment with filename size 0). This denotes the end of the segment
1364 a sub-segment with filename size 0). This denotes the end of the segment
1364 and of the overall changegroup.
1365 and of the overall changegroup.
1365
1366
1366 Each filelog sub-segment consists of the following:
1367 Each filelog sub-segment consists of the following:
1367
1368
1368 +------------------------------------------------------+
1369 +------------------------------------------------------+
1369 | | | |
1370 | | | |
1370 | filename length | filename | delta group |
1371 | filename length | filename | delta group |
1371 | (4 bytes) | (<length - 4> bytes) | (various) |
1372 | (4 bytes) | (<length - 4> bytes) | (various) |
1372 | | | |
1373 | | | |
1373 +------------------------------------------------------+
1374 +------------------------------------------------------+
1374
1375
1375 That is, a *chunk* consisting of the filename (not terminated or padded)
1376 That is, a *chunk* consisting of the filename (not terminated or padded)
1376 followed by N chunks constituting the *delta group* for this file. The
1377 followed by N chunks constituting the *delta group* for this file. The
1377 *empty chunk* at the end of each *delta group* denotes the boundary to the
1378 *empty chunk* at the end of each *delta group* denotes the boundary to the
1378 next filelog sub-segment.
1379 next filelog sub-segment.
1379
1380
1380 non-existent subtopics print an error
1381 non-existent subtopics print an error
1381
1382
1382 $ hg help internals.foo
1383 $ hg help internals.foo
1383 abort: no such help topic: internals.foo
1384 abort: no such help topic: internals.foo
1384 (try 'hg help --keyword foo')
1385 (try 'hg help --keyword foo')
1385 [10]
1386 [10]
1386
1387
1387 test advanced, deprecated and experimental options are hidden in command help
1388 test advanced, deprecated and experimental options are hidden in command help
1388 $ hg help debugoptADV
1389 $ hg help debugoptADV
1389 hg debugoptADV
1390 hg debugoptADV
1390
1391
1391 (no help text available)
1392 (no help text available)
1392
1393
1393 options:
1394 options:
1394
1395
1395 (some details hidden, use --verbose to show complete help)
1396 (some details hidden, use --verbose to show complete help)
1396 $ hg help debugoptDEP
1397 $ hg help debugoptDEP
1397 hg debugoptDEP
1398 hg debugoptDEP
1398
1399
1399 (no help text available)
1400 (no help text available)
1400
1401
1401 options:
1402 options:
1402
1403
1403 (some details hidden, use --verbose to show complete help)
1404 (some details hidden, use --verbose to show complete help)
1404
1405
1405 $ hg help debugoptEXP
1406 $ hg help debugoptEXP
1406 hg debugoptEXP
1407 hg debugoptEXP
1407
1408
1408 (no help text available)
1409 (no help text available)
1409
1410
1410 options:
1411 options:
1411
1412
1412 (some details hidden, use --verbose to show complete help)
1413 (some details hidden, use --verbose to show complete help)
1413
1414
1414 test advanced, deprecated and experimental options are shown with -v
1415 test advanced, deprecated and experimental options are shown with -v
1415 $ hg help -v debugoptADV | grep aopt
1416 $ hg help -v debugoptADV | grep aopt
1416 --aopt option is (ADVANCED)
1417 --aopt option is (ADVANCED)
1417 $ hg help -v debugoptDEP | grep dopt
1418 $ hg help -v debugoptDEP | grep dopt
1418 --dopt option is (DEPRECATED)
1419 --dopt option is (DEPRECATED)
1419 $ hg help -v debugoptEXP | grep eopt
1420 $ hg help -v debugoptEXP | grep eopt
1420 --eopt option is (EXPERIMENTAL)
1421 --eopt option is (EXPERIMENTAL)
1421
1422
1422 #if gettext
1423 #if gettext
1423 test deprecated option is hidden with translation with untranslated description
1424 test deprecated option is hidden with translation with untranslated description
1424 (use many globy for not failing on changed transaction)
1425 (use many globy for not failing on changed transaction)
1425 $ LANGUAGE=sv hg help debugoptDEP
1426 $ LANGUAGE=sv hg help debugoptDEP
1426 hg debugoptDEP
1427 hg debugoptDEP
1427
1428
1428 (*) (glob)
1429 (*) (glob)
1429
1430
1430 options:
1431 options:
1431
1432
1432 (some details hidden, use --verbose to show complete help)
1433 (some details hidden, use --verbose to show complete help)
1433 #endif
1434 #endif
1434
1435
1435 Test commands that collide with topics (issue4240)
1436 Test commands that collide with topics (issue4240)
1436
1437
1437 $ hg config -hq
1438 $ hg config -hq
1438 hg config [-u] [NAME]...
1439 hg config [-u] [NAME]...
1439
1440
1440 show combined config settings from all hgrc files
1441 show combined config settings from all hgrc files
1441 $ hg showconfig -hq
1442 $ hg showconfig -hq
1442 hg config [-u] [NAME]...
1443 hg config [-u] [NAME]...
1443
1444
1444 show combined config settings from all hgrc files
1445 show combined config settings from all hgrc files
1445
1446
1446 Test a help topic
1447 Test a help topic
1447
1448
1448 $ hg help dates
1449 $ hg help dates
1449 Date Formats
1450 Date Formats
1450 """"""""""""
1451 """"""""""""
1451
1452
1452 Some commands allow the user to specify a date, e.g.:
1453 Some commands allow the user to specify a date, e.g.:
1453
1454
1454 - backout, commit, import, tag: Specify the commit date.
1455 - backout, commit, import, tag: Specify the commit date.
1455 - log, revert, update: Select revision(s) by date.
1456 - log, revert, update: Select revision(s) by date.
1456
1457
1457 Many date formats are valid. Here are some examples:
1458 Many date formats are valid. Here are some examples:
1458
1459
1459 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1460 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1460 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1461 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1461 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1462 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1462 - "Dec 6" (midnight)
1463 - "Dec 6" (midnight)
1463 - "13:18" (today assumed)
1464 - "13:18" (today assumed)
1464 - "3:39" (3:39AM assumed)
1465 - "3:39" (3:39AM assumed)
1465 - "3:39pm" (15:39)
1466 - "3:39pm" (15:39)
1466 - "2006-12-06 13:18:29" (ISO 8601 format)
1467 - "2006-12-06 13:18:29" (ISO 8601 format)
1467 - "2006-12-6 13:18"
1468 - "2006-12-6 13:18"
1468 - "2006-12-6"
1469 - "2006-12-6"
1469 - "12-6"
1470 - "12-6"
1470 - "12/6"
1471 - "12/6"
1471 - "12/6/6" (Dec 6 2006)
1472 - "12/6/6" (Dec 6 2006)
1472 - "today" (midnight)
1473 - "today" (midnight)
1473 - "yesterday" (midnight)
1474 - "yesterday" (midnight)
1474 - "now" - right now
1475 - "now" - right now
1475
1476
1476 Lastly, there is Mercurial's internal format:
1477 Lastly, there is Mercurial's internal format:
1477
1478
1478 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1479 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1479
1480
1480 This is the internal representation format for dates. The first number is
1481 This is the internal representation format for dates. The first number is
1481 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1482 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1482 is the offset of the local timezone, in seconds west of UTC (negative if
1483 is the offset of the local timezone, in seconds west of UTC (negative if
1483 the timezone is east of UTC).
1484 the timezone is east of UTC).
1484
1485
1485 The log command also accepts date ranges:
1486 The log command also accepts date ranges:
1486
1487
1487 - "<DATE" - at or before a given date/time
1488 - "<DATE" - at or before a given date/time
1488 - ">DATE" - on or after a given date/time
1489 - ">DATE" - on or after a given date/time
1489 - "DATE to DATE" - a date range, inclusive
1490 - "DATE to DATE" - a date range, inclusive
1490 - "-DAYS" - within a given number of days from today
1491 - "-DAYS" - within a given number of days from today
1491
1492
1492 Test repeated config section name
1493 Test repeated config section name
1493
1494
1494 $ hg help config.host
1495 $ hg help config.host
1495 "http_proxy.host"
1496 "http_proxy.host"
1496 Host name and (optional) port of the proxy server, for example
1497 Host name and (optional) port of the proxy server, for example
1497 "myproxy:8000".
1498 "myproxy:8000".
1498
1499
1499 "smtp.host"
1500 "smtp.host"
1500 Host name of mail server, e.g. "mail.example.com".
1501 Host name of mail server, e.g. "mail.example.com".
1501
1502
1502
1503
1503 Test section name with dot
1504 Test section name with dot
1504
1505
1505 $ hg help config.ui.username
1506 $ hg help config.ui.username
1506 "ui.username"
1507 "ui.username"
1507 The committer of a changeset created when running "commit". Typically
1508 The committer of a changeset created when running "commit". Typically
1508 a person's name and email address, e.g. "Fred Widget
1509 a person's name and email address, e.g. "Fred Widget
1509 <fred@example.com>". Environment variables in the username are
1510 <fred@example.com>". Environment variables in the username are
1510 expanded.
1511 expanded.
1511
1512
1512 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1513 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1513 empty, e.g. if the system admin set "username =" in the system hgrc,
1514 empty, e.g. if the system admin set "username =" in the system hgrc,
1514 it has to be specified manually or in a different hgrc file)
1515 it has to be specified manually or in a different hgrc file)
1515
1516
1516
1517
1517 $ hg help config.annotate.git
1518 $ hg help config.annotate.git
1518 abort: help section not found: config.annotate.git
1519 abort: help section not found: config.annotate.git
1519 [10]
1520 [10]
1520
1521
1521 $ hg help config.update.check
1522 $ hg help config.update.check
1522 "commands.update.check"
1523 "commands.update.check"
1523 Determines what level of checking 'hg update' will perform before
1524 Determines what level of checking 'hg update' will perform before
1524 moving to a destination revision. Valid values are "abort", "none",
1525 moving to a destination revision. Valid values are "abort", "none",
1525 "linear", and "noconflict".
1526 "linear", and "noconflict".
1526
1527
1527 - "abort" always fails if the working directory has uncommitted
1528 - "abort" always fails if the working directory has uncommitted
1528 changes.
1529 changes.
1529 - "none" performs no checking, and may result in a merge with
1530 - "none" performs no checking, and may result in a merge with
1530 uncommitted changes.
1531 uncommitted changes.
1531 - "linear" allows any update as long as it follows a straight line in
1532 - "linear" allows any update as long as it follows a straight line in
1532 the revision history, and may trigger a merge with uncommitted
1533 the revision history, and may trigger a merge with uncommitted
1533 changes.
1534 changes.
1534 - "noconflict" will allow any update which would not trigger a merge
1535 - "noconflict" will allow any update which would not trigger a merge
1535 with uncommitted changes, if any are present.
1536 with uncommitted changes, if any are present.
1536
1537
1537 (default: "linear")
1538 (default: "linear")
1538
1539
1539
1540
1540 $ hg help config.commands.update.check
1541 $ hg help config.commands.update.check
1541 "commands.update.check"
1542 "commands.update.check"
1542 Determines what level of checking 'hg update' will perform before
1543 Determines what level of checking 'hg update' will perform before
1543 moving to a destination revision. Valid values are "abort", "none",
1544 moving to a destination revision. Valid values are "abort", "none",
1544 "linear", and "noconflict".
1545 "linear", and "noconflict".
1545
1546
1546 - "abort" always fails if the working directory has uncommitted
1547 - "abort" always fails if the working directory has uncommitted
1547 changes.
1548 changes.
1548 - "none" performs no checking, and may result in a merge with
1549 - "none" performs no checking, and may result in a merge with
1549 uncommitted changes.
1550 uncommitted changes.
1550 - "linear" allows any update as long as it follows a straight line in
1551 - "linear" allows any update as long as it follows a straight line in
1551 the revision history, and may trigger a merge with uncommitted
1552 the revision history, and may trigger a merge with uncommitted
1552 changes.
1553 changes.
1553 - "noconflict" will allow any update which would not trigger a merge
1554 - "noconflict" will allow any update which would not trigger a merge
1554 with uncommitted changes, if any are present.
1555 with uncommitted changes, if any are present.
1555
1556
1556 (default: "linear")
1557 (default: "linear")
1557
1558
1558
1559
1559 $ hg help config.ommands.update.check
1560 $ hg help config.ommands.update.check
1560 abort: help section not found: config.ommands.update.check
1561 abort: help section not found: config.ommands.update.check
1561 [10]
1562 [10]
1562
1563
1563 Unrelated trailing paragraphs shouldn't be included
1564 Unrelated trailing paragraphs shouldn't be included
1564
1565
1565 $ hg help config.extramsg | grep '^$'
1566 $ hg help config.extramsg | grep '^$'
1566
1567
1567
1568
1568 Test capitalized section name
1569 Test capitalized section name
1569
1570
1570 $ hg help scripting.HGPLAIN > /dev/null
1571 $ hg help scripting.HGPLAIN > /dev/null
1571
1572
1572 Help subsection:
1573 Help subsection:
1573
1574
1574 $ hg help config.charsets |grep "Email example:" > /dev/null
1575 $ hg help config.charsets |grep "Email example:" > /dev/null
1575 [1]
1576 [1]
1576
1577
1577 Show nested definitions
1578 Show nested definitions
1578 ("profiling.type"[break]"ls"[break]"stat"[break])
1579 ("profiling.type"[break]"ls"[break]"stat"[break])
1579
1580
1580 $ hg help config.type | egrep '^$'|wc -l
1581 $ hg help config.type | egrep '^$'|wc -l
1581 \s*3 (re)
1582 \s*3 (re)
1582
1583
1583 $ hg help config.profiling.type.ls
1584 $ hg help config.profiling.type.ls
1584 "profiling.type.ls"
1585 "profiling.type.ls"
1585 Use Python's built-in instrumenting profiler. This profiler works on
1586 Use Python's built-in instrumenting profiler. This profiler works on
1586 all platforms, but each line number it reports is the first line of
1587 all platforms, but each line number it reports is the first line of
1587 a function. This restriction makes it difficult to identify the
1588 a function. This restriction makes it difficult to identify the
1588 expensive parts of a non-trivial function.
1589 expensive parts of a non-trivial function.
1589
1590
1590
1591
1591 Separate sections from subsections
1592 Separate sections from subsections
1592
1593
1593 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1594 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1594 "format"
1595 "format"
1595 --------
1596 --------
1596
1597
1597 "usegeneraldelta"
1598 "usegeneraldelta"
1598
1599
1599 "dotencode"
1600 "dotencode"
1600
1601
1601 "usefncache"
1602 "usefncache"
1602
1603
1603 "use-dirstate-v2"
1604 "use-dirstate-v2"
1604
1605
1605 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories"
1606 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories"
1606
1607
1607 "use-dirstate-tracked-hint"
1608 "use-dirstate-tracked-hint"
1608
1609
1609 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"
1610 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"
1610
1611
1611 "use-persistent-nodemap"
1612 "use-persistent-nodemap"
1612
1613
1613 "use-share-safe"
1614 "use-share-safe"
1614
1615
1615 "use-share-safe.automatic-upgrade-of-mismatching-repositories"
1616 "use-share-safe.automatic-upgrade-of-mismatching-repositories"
1616
1617
1617 "usestore"
1618 "usestore"
1618
1619
1619 "sparse-revlog"
1620 "sparse-revlog"
1620
1621
1621 "revlog-compression"
1622 "revlog-compression"
1622
1623
1623 "bookmarks-in-store"
1624 "bookmarks-in-store"
1624
1625
1625 "profiling"
1626 "profiling"
1626 -----------
1627 -----------
1627
1628
1628 "format"
1629 "format"
1629
1630
1630 "progress"
1631 "progress"
1631 ----------
1632 ----------
1632
1633
1633 "format"
1634 "format"
1634
1635
1635
1636
1636 Last item in help config.*:
1637 Last item in help config.*:
1637
1638
1638 $ hg help config.`hg help config|grep '^ "'| \
1639 $ hg help config.`hg help config|grep '^ "'| \
1639 > tail -1|sed 's![ "]*!!g'`| \
1640 > tail -1|sed 's![ "]*!!g'`| \
1640 > grep 'hg help -c config' > /dev/null
1641 > grep 'hg help -c config' > /dev/null
1641 [1]
1642 [1]
1642
1643
1643 note to use help -c for general hg help config:
1644 note to use help -c for general hg help config:
1644
1645
1645 $ hg help config |grep 'hg help -c config' > /dev/null
1646 $ hg help config |grep 'hg help -c config' > /dev/null
1646
1647
1647 Test templating help
1648 Test templating help
1648
1649
1649 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1650 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1650 desc String. The text of the changeset description.
1651 desc String. The text of the changeset description.
1651 diffstat String. Statistics of changes with the following format:
1652 diffstat String. Statistics of changes with the following format:
1652 firstline Any text. Returns the first line of text.
1653 firstline Any text. Returns the first line of text.
1653 nonempty Any text. Returns '(none)' if the string is empty.
1654 nonempty Any text. Returns '(none)' if the string is empty.
1654
1655
1655 Test deprecated items
1656 Test deprecated items
1656
1657
1657 $ hg help -v templating | grep currentbookmark
1658 $ hg help -v templating | grep currentbookmark
1658 currentbookmark
1659 currentbookmark
1659 $ hg help templating | (grep currentbookmark || true)
1660 $ hg help templating | (grep currentbookmark || true)
1660
1661
1661 Test help hooks
1662 Test help hooks
1662
1663
1663 $ cat > helphook1.py <<EOF
1664 $ cat > helphook1.py <<EOF
1664 > from mercurial import help
1665 > from mercurial import help
1665 >
1666 >
1666 > def rewrite(ui, topic, doc):
1667 > def rewrite(ui, topic, doc):
1667 > return doc + b'\nhelphook1\n'
1668 > return doc + b'\nhelphook1\n'
1668 >
1669 >
1669 > def extsetup(ui):
1670 > def extsetup(ui):
1670 > help.addtopichook(b'revisions', rewrite)
1671 > help.addtopichook(b'revisions', rewrite)
1671 > EOF
1672 > EOF
1672 $ cat > helphook2.py <<EOF
1673 $ cat > helphook2.py <<EOF
1673 > from mercurial import help
1674 > from mercurial import help
1674 >
1675 >
1675 > def rewrite(ui, topic, doc):
1676 > def rewrite(ui, topic, doc):
1676 > return doc + b'\nhelphook2\n'
1677 > return doc + b'\nhelphook2\n'
1677 >
1678 >
1678 > def extsetup(ui):
1679 > def extsetup(ui):
1679 > help.addtopichook(b'revisions', rewrite)
1680 > help.addtopichook(b'revisions', rewrite)
1680 > EOF
1681 > EOF
1681 $ echo '[extensions]' >> $HGRCPATH
1682 $ echo '[extensions]' >> $HGRCPATH
1682 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1683 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1683 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1684 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1684 $ hg help revsets | grep helphook
1685 $ hg help revsets | grep helphook
1685 helphook1
1686 helphook1
1686 helphook2
1687 helphook2
1687
1688
1688 help -c should only show debug --debug
1689 help -c should only show debug --debug
1689
1690
1690 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1691 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1691 [1]
1692 [1]
1692
1693
1693 help -c should only show deprecated for -v
1694 help -c should only show deprecated for -v
1694
1695
1695 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1696 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1696 [1]
1697 [1]
1697
1698
1698 Test -s / --system
1699 Test -s / --system
1699
1700
1700 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1701 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1701 > wc -l | sed -e 's/ //g'
1702 > wc -l | sed -e 's/ //g'
1702 0
1703 0
1703 $ hg help config.files --system unix | grep 'USER' | \
1704 $ hg help config.files --system unix | grep 'USER' | \
1704 > wc -l | sed -e 's/ //g'
1705 > wc -l | sed -e 's/ //g'
1705 0
1706 0
1706
1707
1707 Test -e / -c / -k combinations
1708 Test -e / -c / -k combinations
1708
1709
1709 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1710 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1710 Commands:
1711 Commands:
1711 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1712 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1712 Extensions:
1713 Extensions:
1713 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1714 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1714 Topics:
1715 Topics:
1715 Commands:
1716 Commands:
1716 Extensions:
1717 Extensions:
1717 Extension Commands:
1718 Extension Commands:
1718 $ hg help -c schemes
1719 $ hg help -c schemes
1719 abort: no such help topic: schemes
1720 abort: no such help topic: schemes
1720 (try 'hg help --keyword schemes')
1721 (try 'hg help --keyword schemes')
1721 [10]
1722 [10]
1722 $ hg help -e schemes |head -1
1723 $ hg help -e schemes |head -1
1723 schemes extension - extend schemes with shortcuts to repository swarms
1724 schemes extension - extend schemes with shortcuts to repository swarms
1724 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1725 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1725 Commands:
1726 Commands:
1726 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1727 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1727 Extensions:
1728 Extensions:
1728 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1729 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1729 Extensions:
1730 Extensions:
1730 Commands:
1731 Commands:
1731 $ hg help -c commit > /dev/null
1732 $ hg help -c commit > /dev/null
1732 $ hg help -e -c commit > /dev/null
1733 $ hg help -e -c commit > /dev/null
1733 $ hg help -e commit
1734 $ hg help -e commit
1734 abort: no such help topic: commit
1735 abort: no such help topic: commit
1735 (try 'hg help --keyword commit')
1736 (try 'hg help --keyword commit')
1736 [10]
1737 [10]
1737
1738
1738 Test keyword search help
1739 Test keyword search help
1739
1740
1740 $ cat > prefixedname.py <<EOF
1741 $ cat > prefixedname.py <<EOF
1741 > '''matched against word "clone"
1742 > '''matched against word "clone"
1742 > '''
1743 > '''
1743 > EOF
1744 > EOF
1744 $ echo '[extensions]' >> $HGRCPATH
1745 $ echo '[extensions]' >> $HGRCPATH
1745 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1746 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1746 $ hg help -k clone
1747 $ hg help -k clone
1747 Topics:
1748 Topics:
1748
1749
1749 config Configuration Files
1750 config Configuration Files
1750 extensions Using Additional Features
1751 extensions Using Additional Features
1751 glossary Glossary
1752 glossary Glossary
1752 phases Working with Phases
1753 phases Working with Phases
1753 subrepos Subrepositories
1754 subrepos Subrepositories
1754 urls URL Paths
1755 urls URL Paths
1755
1756
1756 Commands:
1757 Commands:
1757
1758
1758 bookmarks create a new bookmark or list existing bookmarks
1759 bookmarks create a new bookmark or list existing bookmarks
1759 clone make a copy of an existing repository
1760 clone make a copy of an existing repository
1760 paths show aliases for remote repositories
1761 paths show aliases for remote repositories
1761 pull pull changes from the specified source
1762 pull pull changes from the specified source
1762 update update working directory (or switch revisions)
1763 update update working directory (or switch revisions)
1763
1764
1764 Extensions:
1765 Extensions:
1765
1766
1766 clonebundles advertise pre-generated bundles to seed clones
1767 clonebundles advertise pre-generated bundles to seed clones
1767 narrow create clones which fetch history data for subset of files
1768 narrow create clones which fetch history data for subset of files
1768 (EXPERIMENTAL)
1769 (EXPERIMENTAL)
1769 prefixedname matched against word "clone"
1770 prefixedname matched against word "clone"
1770 relink recreates hardlinks between repository clones
1771 relink recreates hardlinks between repository clones
1771
1772
1772 Extension Commands:
1773 Extension Commands:
1773
1774
1774 qclone clone main and patch repository at same time
1775 qclone clone main and patch repository at same time
1775
1776
1776 Test unfound topic
1777 Test unfound topic
1777
1778
1778 $ hg help nonexistingtopicthatwillneverexisteverever
1779 $ hg help nonexistingtopicthatwillneverexisteverever
1779 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1780 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1780 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1781 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1781 [10]
1782 [10]
1782
1783
1783 Test unfound keyword
1784 Test unfound keyword
1784
1785
1785 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1786 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1786 abort: no matches
1787 abort: no matches
1787 (try 'hg help' for a list of topics)
1788 (try 'hg help' for a list of topics)
1788 [10]
1789 [10]
1789
1790
1790 Test omit indicating for help
1791 Test omit indicating for help
1791
1792
1792 $ cat > addverboseitems.py <<EOF
1793 $ cat > addverboseitems.py <<EOF
1793 > r'''extension to test omit indicating.
1794 > r'''extension to test omit indicating.
1794 >
1795 >
1795 > This paragraph is never omitted (for extension)
1796 > This paragraph is never omitted (for extension)
1796 >
1797 >
1797 > .. container:: verbose
1798 > .. container:: verbose
1798 >
1799 >
1799 > This paragraph is omitted,
1800 > This paragraph is omitted,
1800 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1801 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1801 >
1802 >
1802 > This paragraph is never omitted, too (for extension)
1803 > This paragraph is never omitted, too (for extension)
1803 > '''
1804 > '''
1804 > from mercurial import commands, help
1805 > from mercurial import commands, help
1805 > testtopic = br"""This paragraph is never omitted (for topic).
1806 > testtopic = br"""This paragraph is never omitted (for topic).
1806 >
1807 >
1807 > .. container:: verbose
1808 > .. container:: verbose
1808 >
1809 >
1809 > This paragraph is omitted,
1810 > This paragraph is omitted,
1810 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1811 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1811 >
1812 >
1812 > This paragraph is never omitted, too (for topic)
1813 > This paragraph is never omitted, too (for topic)
1813 > """
1814 > """
1814 > def extsetup(ui):
1815 > def extsetup(ui):
1815 > help.helptable.append(([b"topic-containing-verbose"],
1816 > help.helptable.append(([b"topic-containing-verbose"],
1816 > b"This is the topic to test omit indicating.",
1817 > b"This is the topic to test omit indicating.",
1817 > lambda ui: testtopic))
1818 > lambda ui: testtopic))
1818 > EOF
1819 > EOF
1819 $ echo '[extensions]' >> $HGRCPATH
1820 $ echo '[extensions]' >> $HGRCPATH
1820 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1821 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1821 $ hg help addverboseitems
1822 $ hg help addverboseitems
1822 addverboseitems extension - extension to test omit indicating.
1823 addverboseitems extension - extension to test omit indicating.
1823
1824
1824 This paragraph is never omitted (for extension)
1825 This paragraph is never omitted (for extension)
1825
1826
1826 This paragraph is never omitted, too (for extension)
1827 This paragraph is never omitted, too (for extension)
1827
1828
1828 (some details hidden, use --verbose to show complete help)
1829 (some details hidden, use --verbose to show complete help)
1829
1830
1830 no commands defined
1831 no commands defined
1831 $ hg help -v addverboseitems
1832 $ hg help -v addverboseitems
1832 addverboseitems extension - extension to test omit indicating.
1833 addverboseitems extension - extension to test omit indicating.
1833
1834
1834 This paragraph is never omitted (for extension)
1835 This paragraph is never omitted (for extension)
1835
1836
1836 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1837 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1837 extension)
1838 extension)
1838
1839
1839 This paragraph is never omitted, too (for extension)
1840 This paragraph is never omitted, too (for extension)
1840
1841
1841 no commands defined
1842 no commands defined
1842 $ hg help topic-containing-verbose
1843 $ hg help topic-containing-verbose
1843 This is the topic to test omit indicating.
1844 This is the topic to test omit indicating.
1844 """"""""""""""""""""""""""""""""""""""""""
1845 """"""""""""""""""""""""""""""""""""""""""
1845
1846
1846 This paragraph is never omitted (for topic).
1847 This paragraph is never omitted (for topic).
1847
1848
1848 This paragraph is never omitted, too (for topic)
1849 This paragraph is never omitted, too (for topic)
1849
1850
1850 (some details hidden, use --verbose to show complete help)
1851 (some details hidden, use --verbose to show complete help)
1851 $ hg help -v topic-containing-verbose
1852 $ hg help -v topic-containing-verbose
1852 This is the topic to test omit indicating.
1853 This is the topic to test omit indicating.
1853 """"""""""""""""""""""""""""""""""""""""""
1854 """"""""""""""""""""""""""""""""""""""""""
1854
1855
1855 This paragraph is never omitted (for topic).
1856 This paragraph is never omitted (for topic).
1856
1857
1857 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1858 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1858 topic)
1859 topic)
1859
1860
1860 This paragraph is never omitted, too (for topic)
1861 This paragraph is never omitted, too (for topic)
1861
1862
1862 Test section lookup
1863 Test section lookup
1863
1864
1864 $ hg help revset.merge
1865 $ hg help revset.merge
1865 "merge()"
1866 "merge()"
1866 Changeset is a merge changeset.
1867 Changeset is a merge changeset.
1867
1868
1868 $ hg help glossary.dag
1869 $ hg help glossary.dag
1869 DAG
1870 DAG
1870 The repository of changesets of a distributed version control system
1871 The repository of changesets of a distributed version control system
1871 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1872 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1872 of nodes and edges, where nodes correspond to changesets and edges
1873 of nodes and edges, where nodes correspond to changesets and edges
1873 imply a parent -> child relation. This graph can be visualized by
1874 imply a parent -> child relation. This graph can be visualized by
1874 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1875 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1875 limited by the requirement for children to have at most two parents.
1876 limited by the requirement for children to have at most two parents.
1876
1877
1877
1878
1878 $ hg help hgrc.paths
1879 $ hg help hgrc.paths
1879 "paths"
1880 "paths"
1880 -------
1881 -------
1881
1882
1882 Assigns symbolic names and behavior to repositories.
1883 Assigns symbolic names and behavior to repositories.
1883
1884
1884 Options are symbolic names defining the URL or directory that is the
1885 Options are symbolic names defining the URL or directory that is the
1885 location of the repository. Example:
1886 location of the repository. Example:
1886
1887
1887 [paths]
1888 [paths]
1888 my_server = https://example.com/my_repo
1889 my_server = https://example.com/my_repo
1889 local_path = /home/me/repo
1890 local_path = /home/me/repo
1890
1891
1891 These symbolic names can be used from the command line. To pull from
1892 These symbolic names can be used from the command line. To pull from
1892 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1893 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1893 local_path'. You can check 'hg help urls' for details about valid URLs.
1894 local_path'. You can check 'hg help urls' for details about valid URLs.
1894
1895
1895 Options containing colons (":") denote sub-options that can influence
1896 Options containing colons (":") denote sub-options that can influence
1896 behavior for that specific path. Example:
1897 behavior for that specific path. Example:
1897
1898
1898 [paths]
1899 [paths]
1899 my_server = https://example.com/my_path
1900 my_server = https://example.com/my_path
1900 my_server:pushurl = ssh://example.com/my_path
1901 my_server:pushurl = ssh://example.com/my_path
1901
1902
1902 Paths using the 'path://otherpath' scheme will inherit the sub-options
1903 Paths using the 'path://otherpath' scheme will inherit the sub-options
1903 value from the path they point to.
1904 value from the path they point to.
1904
1905
1905 The following sub-options can be defined:
1906 The following sub-options can be defined:
1906
1907
1907 "multi-urls"
1908 "multi-urls"
1908 A boolean option. When enabled the value of the '[paths]' entry will be
1909 A boolean option. When enabled the value of the '[paths]' entry will be
1909 parsed as a list and the alias will resolve to multiple destination. If
1910 parsed as a list and the alias will resolve to multiple destination. If
1910 some of the list entry use the 'path://' syntax, the suboption will be
1911 some of the list entry use the 'path://' syntax, the suboption will be
1911 inherited individually.
1912 inherited individually.
1912
1913
1913 "pushurl"
1914 "pushurl"
1914 The URL to use for push operations. If not defined, the location
1915 The URL to use for push operations. If not defined, the location
1915 defined by the path's main entry is used.
1916 defined by the path's main entry is used.
1916
1917
1917 "pushrev"
1918 "pushrev"
1918 A revset defining which revisions to push by default.
1919 A revset defining which revisions to push by default.
1919
1920
1920 When 'hg push' is executed without a "-r" argument, the revset defined
1921 When 'hg push' is executed without a "-r" argument, the revset defined
1921 by this sub-option is evaluated to determine what to push.
1922 by this sub-option is evaluated to determine what to push.
1922
1923
1923 For example, a value of "." will push the working directory's revision
1924 For example, a value of "." will push the working directory's revision
1924 by default.
1925 by default.
1925
1926
1926 Revsets specifying bookmarks will not result in the bookmark being
1927 Revsets specifying bookmarks will not result in the bookmark being
1927 pushed.
1928 pushed.
1928
1929
1929 "bookmarks.mode"
1930 "bookmarks.mode"
1930 How bookmark will be dealt during the exchange. It support the following
1931 How bookmark will be dealt during the exchange. It support the following
1931 value
1932 value
1932
1933
1933 - "default": the default behavior, local and remote bookmarks are
1934 - "default": the default behavior, local and remote bookmarks are
1934 "merged" on push/pull.
1935 "merged" on push/pull.
1935 - "mirror": when pulling, replace local bookmarks by remote bookmarks.
1936 - "mirror": when pulling, replace local bookmarks by remote bookmarks.
1936 This is useful to replicate a repository, or as an optimization.
1937 This is useful to replicate a repository, or as an optimization.
1937 - "ignore": ignore bookmarks during exchange. (This currently only
1938 - "ignore": ignore bookmarks during exchange. (This currently only
1938 affect pulling)
1939 affect pulling)
1939
1940
1940 The following special named paths exist:
1941 The following special named paths exist:
1941
1942
1942 "default"
1943 "default"
1943 The URL or directory to use when no source or remote is specified.
1944 The URL or directory to use when no source or remote is specified.
1944
1945
1945 'hg clone' will automatically define this path to the location the
1946 'hg clone' will automatically define this path to the location the
1946 repository was cloned from.
1947 repository was cloned from.
1947
1948
1948 "default-push"
1949 "default-push"
1949 (deprecated) The URL or directory for the default 'hg push' location.
1950 (deprecated) The URL or directory for the default 'hg push' location.
1950 "default:pushurl" should be used instead.
1951 "default:pushurl" should be used instead.
1951
1952
1952 $ hg help glossary.mcguffin
1953 $ hg help glossary.mcguffin
1953 abort: help section not found: glossary.mcguffin
1954 abort: help section not found: glossary.mcguffin
1954 [10]
1955 [10]
1955
1956
1956 $ hg help glossary.mc.guffin
1957 $ hg help glossary.mc.guffin
1957 abort: help section not found: glossary.mc.guffin
1958 abort: help section not found: glossary.mc.guffin
1958 [10]
1959 [10]
1959
1960
1960 $ hg help template.files
1961 $ hg help template.files
1961 files List of strings. All files modified, added, or removed by
1962 files List of strings. All files modified, added, or removed by
1962 this changeset.
1963 this changeset.
1963 files(pattern)
1964 files(pattern)
1964 All files of the current changeset matching the pattern. See
1965 All files of the current changeset matching the pattern. See
1965 'hg help patterns'.
1966 'hg help patterns'.
1966
1967
1967 Test section lookup by translated message
1968 Test section lookup by translated message
1968
1969
1969 str.lower() instead of encoding.lower(str) on translated message might
1970 str.lower() instead of encoding.lower(str) on translated message might
1970 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1971 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1971 as the second or later byte of multi-byte character.
1972 as the second or later byte of multi-byte character.
1972
1973
1973 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1974 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1974 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1975 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1975 replacement makes message meaningless.
1976 replacement makes message meaningless.
1976
1977
1977 This tests that section lookup by translated string isn't broken by
1978 This tests that section lookup by translated string isn't broken by
1978 such str.lower().
1979 such str.lower().
1979
1980
1980 $ "$PYTHON" <<EOF
1981 $ "$PYTHON" <<EOF
1981 > def escape(s):
1982 > def escape(s):
1982 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1983 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1983 > # translation of "record" in ja_JP.cp932
1984 > # translation of "record" in ja_JP.cp932
1984 > upper = b"\x8bL\x98^"
1985 > upper = b"\x8bL\x98^"
1985 > # str.lower()-ed section name should be treated as different one
1986 > # str.lower()-ed section name should be treated as different one
1986 > lower = b"\x8bl\x98^"
1987 > lower = b"\x8bl\x98^"
1987 > with open('ambiguous.py', 'wb') as fp:
1988 > with open('ambiguous.py', 'wb') as fp:
1988 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1989 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1989 > u'''summary of extension
1990 > u'''summary of extension
1990 >
1991 >
1991 > %s
1992 > %s
1992 > ----
1993 > ----
1993 >
1994 >
1994 > Upper name should show only this message
1995 > Upper name should show only this message
1995 >
1996 >
1996 > %s
1997 > %s
1997 > ----
1998 > ----
1998 >
1999 >
1999 > Lower name should show only this message
2000 > Lower name should show only this message
2000 >
2001 >
2001 > subsequent section
2002 > subsequent section
2002 > ------------------
2003 > ------------------
2003 >
2004 >
2004 > This should be hidden at 'hg help ambiguous' with section name.
2005 > This should be hidden at 'hg help ambiguous' with section name.
2005 > '''
2006 > '''
2006 > """ % (escape(upper), escape(lower)))
2007 > """ % (escape(upper), escape(lower)))
2007 > EOF
2008 > EOF
2008
2009
2009 $ cat >> $HGRCPATH <<EOF
2010 $ cat >> $HGRCPATH <<EOF
2010 > [extensions]
2011 > [extensions]
2011 > ambiguous = ./ambiguous.py
2012 > ambiguous = ./ambiguous.py
2012 > EOF
2013 > EOF
2013
2014
2014 $ "$PYTHON" <<EOF | sh
2015 $ "$PYTHON" <<EOF | sh
2015 > from mercurial.utils import procutil
2016 > from mercurial.utils import procutil
2016 > upper = b"\x8bL\x98^"
2017 > upper = b"\x8bL\x98^"
2017 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
2018 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
2018 > EOF
2019 > EOF
2019 \x8bL\x98^ (esc)
2020 \x8bL\x98^ (esc)
2020 ----
2021 ----
2021
2022
2022 Upper name should show only this message
2023 Upper name should show only this message
2023
2024
2024
2025
2025 $ "$PYTHON" <<EOF | sh
2026 $ "$PYTHON" <<EOF | sh
2026 > from mercurial.utils import procutil
2027 > from mercurial.utils import procutil
2027 > lower = b"\x8bl\x98^"
2028 > lower = b"\x8bl\x98^"
2028 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
2029 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
2029 > EOF
2030 > EOF
2030 \x8bl\x98^ (esc)
2031 \x8bl\x98^ (esc)
2031 ----
2032 ----
2032
2033
2033 Lower name should show only this message
2034 Lower name should show only this message
2034
2035
2035
2036
2036 $ cat >> $HGRCPATH <<EOF
2037 $ cat >> $HGRCPATH <<EOF
2037 > [extensions]
2038 > [extensions]
2038 > ambiguous = !
2039 > ambiguous = !
2039 > EOF
2040 > EOF
2040
2041
2041 Show help content of disabled extensions
2042 Show help content of disabled extensions
2042
2043
2043 $ cat >> $HGRCPATH <<EOF
2044 $ cat >> $HGRCPATH <<EOF
2044 > [extensions]
2045 > [extensions]
2045 > ambiguous = !./ambiguous.py
2046 > ambiguous = !./ambiguous.py
2046 > EOF
2047 > EOF
2047 $ hg help -e ambiguous
2048 $ hg help -e ambiguous
2048 ambiguous extension - (no help text available)
2049 ambiguous extension - (no help text available)
2049
2050
2050 (use 'hg help extensions' for information on enabling extensions)
2051 (use 'hg help extensions' for information on enabling extensions)
2051
2052
2052 Test dynamic list of merge tools only shows up once
2053 Test dynamic list of merge tools only shows up once
2053 $ hg help merge-tools
2054 $ hg help merge-tools
2054 Merge Tools
2055 Merge Tools
2055 """""""""""
2056 """""""""""
2056
2057
2057 To merge files Mercurial uses merge tools.
2058 To merge files Mercurial uses merge tools.
2058
2059
2059 A merge tool combines two different versions of a file into a merged file.
2060 A merge tool combines two different versions of a file into a merged file.
2060 Merge tools are given the two files and the greatest common ancestor of
2061 Merge tools are given the two files and the greatest common ancestor of
2061 the two file versions, so they can determine the changes made on both
2062 the two file versions, so they can determine the changes made on both
2062 branches.
2063 branches.
2063
2064
2064 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
2065 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
2065 backout' and in several extensions.
2066 backout' and in several extensions.
2066
2067
2067 Usually, the merge tool tries to automatically reconcile the files by
2068 Usually, the merge tool tries to automatically reconcile the files by
2068 combining all non-overlapping changes that occurred separately in the two
2069 combining all non-overlapping changes that occurred separately in the two
2069 different evolutions of the same initial base file. Furthermore, some
2070 different evolutions of the same initial base file. Furthermore, some
2070 interactive merge programs make it easier to manually resolve conflicting
2071 interactive merge programs make it easier to manually resolve conflicting
2071 merges, either in a graphical way, or by inserting some conflict markers.
2072 merges, either in a graphical way, or by inserting some conflict markers.
2072 Mercurial does not include any interactive merge programs but relies on
2073 Mercurial does not include any interactive merge programs but relies on
2073 external tools for that.
2074 external tools for that.
2074
2075
2075 Available merge tools
2076 Available merge tools
2076 =====================
2077 =====================
2077
2078
2078 External merge tools and their properties are configured in the merge-
2079 External merge tools and their properties are configured in the merge-
2079 tools configuration section - see hgrc(5) - but they can often just be
2080 tools configuration section - see hgrc(5) - but they can often just be
2080 named by their executable.
2081 named by their executable.
2081
2082
2082 A merge tool is generally usable if its executable can be found on the
2083 A merge tool is generally usable if its executable can be found on the
2083 system and if it can handle the merge. The executable is found if it is an
2084 system and if it can handle the merge. The executable is found if it is an
2084 absolute or relative executable path or the name of an application in the
2085 absolute or relative executable path or the name of an application in the
2085 executable search path. The tool is assumed to be able to handle the merge
2086 executable search path. The tool is assumed to be able to handle the merge
2086 if it can handle symlinks if the file is a symlink, if it can handle
2087 if it can handle symlinks if the file is a symlink, if it can handle
2087 binary files if the file is binary, and if a GUI is available if the tool
2088 binary files if the file is binary, and if a GUI is available if the tool
2088 requires a GUI.
2089 requires a GUI.
2089
2090
2090 There are some internal merge tools which can be used. The internal merge
2091 There are some internal merge tools which can be used. The internal merge
2091 tools are:
2092 tools are:
2092
2093
2093 ":dump"
2094 ":dump"
2094 Creates three versions of the files to merge, containing the contents of
2095 Creates three versions of the files to merge, containing the contents of
2095 local, other and base. These files can then be used to perform a merge
2096 local, other and base. These files can then be used to perform a merge
2096 manually. If the file to be merged is named "a.txt", these files will
2097 manually. If the file to be merged is named "a.txt", these files will
2097 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2098 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2098 they will be placed in the same directory as "a.txt".
2099 they will be placed in the same directory as "a.txt".
2099
2100
2100 This implies premerge. Therefore, files aren't dumped, if premerge runs
2101 This implies premerge. Therefore, files aren't dumped, if premerge runs
2101 successfully. Use :forcedump to forcibly write files out.
2102 successfully. Use :forcedump to forcibly write files out.
2102
2103
2103 (actual capabilities: binary, symlink)
2104 (actual capabilities: binary, symlink)
2104
2105
2105 ":fail"
2106 ":fail"
2106 Rather than attempting to merge files that were modified on both
2107 Rather than attempting to merge files that were modified on both
2107 branches, it marks them as unresolved. The resolve command must be used
2108 branches, it marks them as unresolved. The resolve command must be used
2108 to resolve these conflicts.
2109 to resolve these conflicts.
2109
2110
2110 (actual capabilities: binary, symlink)
2111 (actual capabilities: binary, symlink)
2111
2112
2112 ":forcedump"
2113 ":forcedump"
2113 Creates three versions of the files as same as :dump, but omits
2114 Creates three versions of the files as same as :dump, but omits
2114 premerge.
2115 premerge.
2115
2116
2116 (actual capabilities: binary, symlink)
2117 (actual capabilities: binary, symlink)
2117
2118
2118 ":local"
2119 ":local"
2119 Uses the local 'p1()' version of files as the merged version.
2120 Uses the local 'p1()' version of files as the merged version.
2120
2121
2121 (actual capabilities: binary, symlink)
2122 (actual capabilities: binary, symlink)
2122
2123
2123 ":merge"
2124 ":merge"
2124 Uses the internal non-interactive simple merge algorithm for merging
2125 Uses the internal non-interactive simple merge algorithm for merging
2125 files. It will fail if there are any conflicts and leave markers in the
2126 files. It will fail if there are any conflicts and leave markers in the
2126 partially merged file. Markers will have two sections, one for each side
2127 partially merged file. Markers will have two sections, one for each side
2127 of merge.
2128 of merge.
2128
2129
2129 ":merge-local"
2130 ":merge-local"
2130 Like :merge, but resolve all conflicts non-interactively in favor of the
2131 Like :merge, but resolve all conflicts non-interactively in favor of the
2131 local 'p1()' changes.
2132 local 'p1()' changes.
2132
2133
2133 ":merge-other"
2134 ":merge-other"
2134 Like :merge, but resolve all conflicts non-interactively in favor of the
2135 Like :merge, but resolve all conflicts non-interactively in favor of the
2135 other 'p2()' changes.
2136 other 'p2()' changes.
2136
2137
2137 ":merge3"
2138 ":merge3"
2138 Uses the internal non-interactive simple merge algorithm for merging
2139 Uses the internal non-interactive simple merge algorithm for merging
2139 files. It will fail if there are any conflicts and leave markers in the
2140 files. It will fail if there are any conflicts and leave markers in the
2140 partially merged file. Marker will have three sections, one from each
2141 partially merged file. Marker will have three sections, one from each
2141 side of the merge and one for the base content.
2142 side of the merge and one for the base content.
2142
2143
2143 ":mergediff"
2144 ":mergediff"
2144 Uses the internal non-interactive simple merge algorithm for merging
2145 Uses the internal non-interactive simple merge algorithm for merging
2145 files. It will fail if there are any conflicts and leave markers in the
2146 files. It will fail if there are any conflicts and leave markers in the
2146 partially merged file. The marker will have two sections, one with the
2147 partially merged file. The marker will have two sections, one with the
2147 content from one side of the merge, and one with a diff from the base
2148 content from one side of the merge, and one with a diff from the base
2148 content to the content on the other side. (experimental)
2149 content to the content on the other side. (experimental)
2149
2150
2150 ":other"
2151 ":other"
2151 Uses the other 'p2()' version of files as the merged version.
2152 Uses the other 'p2()' version of files as the merged version.
2152
2153
2153 (actual capabilities: binary, symlink)
2154 (actual capabilities: binary, symlink)
2154
2155
2155 ":prompt"
2156 ":prompt"
2156 Asks the user which of the local 'p1()' or the other 'p2()' version to
2157 Asks the user which of the local 'p1()' or the other 'p2()' version to
2157 keep as the merged version.
2158 keep as the merged version.
2158
2159
2159 (actual capabilities: binary, symlink)
2160 (actual capabilities: binary, symlink)
2160
2161
2161 ":tagmerge"
2162 ":tagmerge"
2162 Uses the internal tag merge algorithm (experimental).
2163 Uses the internal tag merge algorithm (experimental).
2163
2164
2164 ":union"
2165 ":union"
2165 Uses the internal non-interactive simple merge algorithm for merging
2166 Uses the internal non-interactive simple merge algorithm for merging
2166 files. It will use both left and right sides for conflict regions. No
2167 files. It will use both left and right sides for conflict regions. No
2167 markers are inserted.
2168 markers are inserted.
2168
2169
2169 Internal tools are always available and do not require a GUI but will by
2170 Internal tools are always available and do not require a GUI but will by
2170 default not handle symlinks or binary files. See next section for detail
2171 default not handle symlinks or binary files. See next section for detail
2171 about "actual capabilities" described above.
2172 about "actual capabilities" described above.
2172
2173
2173 Choosing a merge tool
2174 Choosing a merge tool
2174 =====================
2175 =====================
2175
2176
2176 Mercurial uses these rules when deciding which merge tool to use:
2177 Mercurial uses these rules when deciding which merge tool to use:
2177
2178
2178 1. If a tool has been specified with the --tool option to merge or
2179 1. If a tool has been specified with the --tool option to merge or
2179 resolve, it is used. If it is the name of a tool in the merge-tools
2180 resolve, it is used. If it is the name of a tool in the merge-tools
2180 configuration, its configuration is used. Otherwise the specified tool
2181 configuration, its configuration is used. Otherwise the specified tool
2181 must be executable by the shell.
2182 must be executable by the shell.
2182 2. If the "HGMERGE" environment variable is present, its value is used and
2183 2. If the "HGMERGE" environment variable is present, its value is used and
2183 must be executable by the shell.
2184 must be executable by the shell.
2184 3. If the filename of the file to be merged matches any of the patterns in
2185 3. If the filename of the file to be merged matches any of the patterns in
2185 the merge-patterns configuration section, the first usable merge tool
2186 the merge-patterns configuration section, the first usable merge tool
2186 corresponding to a matching pattern is used.
2187 corresponding to a matching pattern is used.
2187 4. If ui.merge is set it will be considered next. If the value is not the
2188 4. If ui.merge is set it will be considered next. If the value is not the
2188 name of a configured tool, the specified value is used and must be
2189 name of a configured tool, the specified value is used and must be
2189 executable by the shell. Otherwise the named tool is used if it is
2190 executable by the shell. Otherwise the named tool is used if it is
2190 usable.
2191 usable.
2191 5. If any usable merge tools are present in the merge-tools configuration
2192 5. If any usable merge tools are present in the merge-tools configuration
2192 section, the one with the highest priority is used.
2193 section, the one with the highest priority is used.
2193 6. If a program named "hgmerge" can be found on the system, it is used -
2194 6. If a program named "hgmerge" can be found on the system, it is used -
2194 but it will by default not be used for symlinks and binary files.
2195 but it will by default not be used for symlinks and binary files.
2195 7. If the file to be merged is not binary and is not a symlink, then
2196 7. If the file to be merged is not binary and is not a symlink, then
2196 internal ":merge" is used.
2197 internal ":merge" is used.
2197 8. Otherwise, ":prompt" is used.
2198 8. Otherwise, ":prompt" is used.
2198
2199
2199 For historical reason, Mercurial treats merge tools as below while
2200 For historical reason, Mercurial treats merge tools as below while
2200 examining rules above.
2201 examining rules above.
2201
2202
2202 step specified via binary symlink
2203 step specified via binary symlink
2203 ----------------------------------
2204 ----------------------------------
2204 1. --tool o/o o/o
2205 1. --tool o/o o/o
2205 2. HGMERGE o/o o/o
2206 2. HGMERGE o/o o/o
2206 3. merge-patterns o/o(*) x/?(*)
2207 3. merge-patterns o/o(*) x/?(*)
2207 4. ui.merge x/?(*) x/?(*)
2208 4. ui.merge x/?(*) x/?(*)
2208
2209
2209 Each capability column indicates Mercurial behavior for internal/external
2210 Each capability column indicates Mercurial behavior for internal/external
2210 merge tools at examining each rule.
2211 merge tools at examining each rule.
2211
2212
2212 - "o": "assume that a tool has capability"
2213 - "o": "assume that a tool has capability"
2213 - "x": "assume that a tool does not have capability"
2214 - "x": "assume that a tool does not have capability"
2214 - "?": "check actual capability of a tool"
2215 - "?": "check actual capability of a tool"
2215
2216
2216 If "merge.strict-capability-check" configuration is true, Mercurial checks
2217 If "merge.strict-capability-check" configuration is true, Mercurial checks
2217 capabilities of merge tools strictly in (*) cases above (= each capability
2218 capabilities of merge tools strictly in (*) cases above (= each capability
2218 column becomes "?/?"). It is false by default for backward compatibility.
2219 column becomes "?/?"). It is false by default for backward compatibility.
2219
2220
2220 Note:
2221 Note:
2221 After selecting a merge program, Mercurial will by default attempt to
2222 After selecting a merge program, Mercurial will by default attempt to
2222 merge the files using a simple merge algorithm first. Only if it
2223 merge the files using a simple merge algorithm first. Only if it
2223 doesn't succeed because of conflicting changes will Mercurial actually
2224 doesn't succeed because of conflicting changes will Mercurial actually
2224 execute the merge program. Whether to use the simple merge algorithm
2225 execute the merge program. Whether to use the simple merge algorithm
2225 first can be controlled by the premerge setting of the merge tool.
2226 first can be controlled by the premerge setting of the merge tool.
2226 Premerge is enabled by default unless the file is binary or a symlink.
2227 Premerge is enabled by default unless the file is binary or a symlink.
2227
2228
2228 See the merge-tools and ui sections of hgrc(5) for details on the
2229 See the merge-tools and ui sections of hgrc(5) for details on the
2229 configuration of merge tools.
2230 configuration of merge tools.
2230
2231
2231 Compression engines listed in `hg help bundlespec`
2232 Compression engines listed in `hg help bundlespec`
2232
2233
2233 $ hg help bundlespec | grep gzip
2234 $ hg help bundlespec | grep gzip
2234 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2235 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2235 An algorithm that produces smaller bundles than "gzip".
2236 An algorithm that produces smaller bundles than "gzip".
2236 This engine will likely produce smaller bundles than "gzip" but will be
2237 This engine will likely produce smaller bundles than "gzip" but will be
2237 "gzip"
2238 "gzip"
2238 better compression than "gzip". It also frequently yields better (?)
2239 better compression than "gzip". It also frequently yields better (?)
2239
2240
2240 Test usage of section marks in help documents
2241 Test usage of section marks in help documents
2241
2242
2242 $ cd "$TESTDIR"/../doc
2243 $ cd "$TESTDIR"/../doc
2243 $ "$PYTHON" check-seclevel.py
2244 $ "$PYTHON" check-seclevel.py
2244 $ cd $TESTTMP
2245 $ cd $TESTTMP
2245
2246
2246 #if serve
2247 #if serve
2247
2248
2248 Test the help pages in hgweb.
2249 Test the help pages in hgweb.
2249
2250
2250 Dish up an empty repo; serve it cold.
2251 Dish up an empty repo; serve it cold.
2251
2252
2252 $ hg init "$TESTTMP/test"
2253 $ hg init "$TESTTMP/test"
2253 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2254 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2254 $ cat hg.pid >> $DAEMON_PIDS
2255 $ cat hg.pid >> $DAEMON_PIDS
2255
2256
2256 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2257 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2257 200 Script output follows
2258 200 Script output follows
2258
2259
2259 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2260 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2260 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2261 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2261 <head>
2262 <head>
2262 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2263 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2263 <meta name="robots" content="index, nofollow" />
2264 <meta name="robots" content="index, nofollow" />
2264 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2265 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2265 <script type="text/javascript" src="/static/mercurial.js"></script>
2266 <script type="text/javascript" src="/static/mercurial.js"></script>
2266
2267
2267 <title>Help: Index</title>
2268 <title>Help: Index</title>
2268 </head>
2269 </head>
2269 <body>
2270 <body>
2270
2271
2271 <div class="container">
2272 <div class="container">
2272 <div class="menu">
2273 <div class="menu">
2273 <div class="logo">
2274 <div class="logo">
2274 <a href="https://mercurial-scm.org/">
2275 <a href="https://mercurial-scm.org/">
2275 <img src="/static/hglogo.png" alt="mercurial" /></a>
2276 <img src="/static/hglogo.png" alt="mercurial" /></a>
2276 </div>
2277 </div>
2277 <ul>
2278 <ul>
2278 <li><a href="/shortlog">log</a></li>
2279 <li><a href="/shortlog">log</a></li>
2279 <li><a href="/graph">graph</a></li>
2280 <li><a href="/graph">graph</a></li>
2280 <li><a href="/tags">tags</a></li>
2281 <li><a href="/tags">tags</a></li>
2281 <li><a href="/bookmarks">bookmarks</a></li>
2282 <li><a href="/bookmarks">bookmarks</a></li>
2282 <li><a href="/branches">branches</a></li>
2283 <li><a href="/branches">branches</a></li>
2283 </ul>
2284 </ul>
2284 <ul>
2285 <ul>
2285 <li class="active">help</li>
2286 <li class="active">help</li>
2286 </ul>
2287 </ul>
2287 </div>
2288 </div>
2288
2289
2289 <div class="main">
2290 <div class="main">
2290 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2291 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2291
2292
2292 <form class="search" action="/log">
2293 <form class="search" action="/log">
2293
2294
2294 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2295 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2295 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2296 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2296 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2297 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2297 </form>
2298 </form>
2298 <table class="bigtable">
2299 <table class="bigtable">
2299 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2300 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2300
2301
2301 <tr><td>
2302 <tr><td>
2302 <a href="/help/bundlespec">
2303 <a href="/help/bundlespec">
2303 bundlespec
2304 bundlespec
2304 </a>
2305 </a>
2305 </td><td>
2306 </td><td>
2306 Bundle File Formats
2307 Bundle File Formats
2307 </td></tr>
2308 </td></tr>
2308 <tr><td>
2309 <tr><td>
2309 <a href="/help/color">
2310 <a href="/help/color">
2310 color
2311 color
2311 </a>
2312 </a>
2312 </td><td>
2313 </td><td>
2313 Colorizing Outputs
2314 Colorizing Outputs
2314 </td></tr>
2315 </td></tr>
2315 <tr><td>
2316 <tr><td>
2316 <a href="/help/config">
2317 <a href="/help/config">
2317 config
2318 config
2318 </a>
2319 </a>
2319 </td><td>
2320 </td><td>
2320 Configuration Files
2321 Configuration Files
2321 </td></tr>
2322 </td></tr>
2322 <tr><td>
2323 <tr><td>
2323 <a href="/help/dates">
2324 <a href="/help/dates">
2324 dates
2325 dates
2325 </a>
2326 </a>
2326 </td><td>
2327 </td><td>
2327 Date Formats
2328 Date Formats
2328 </td></tr>
2329 </td></tr>
2329 <tr><td>
2330 <tr><td>
2330 <a href="/help/deprecated">
2331 <a href="/help/deprecated">
2331 deprecated
2332 deprecated
2332 </a>
2333 </a>
2333 </td><td>
2334 </td><td>
2334 Deprecated Features
2335 Deprecated Features
2335 </td></tr>
2336 </td></tr>
2336 <tr><td>
2337 <tr><td>
2337 <a href="/help/diffs">
2338 <a href="/help/diffs">
2338 diffs
2339 diffs
2339 </a>
2340 </a>
2340 </td><td>
2341 </td><td>
2341 Diff Formats
2342 Diff Formats
2342 </td></tr>
2343 </td></tr>
2343 <tr><td>
2344 <tr><td>
2344 <a href="/help/environment">
2345 <a href="/help/environment">
2345 environment
2346 environment
2346 </a>
2347 </a>
2347 </td><td>
2348 </td><td>
2348 Environment Variables
2349 Environment Variables
2349 </td></tr>
2350 </td></tr>
2350 <tr><td>
2351 <tr><td>
2351 <a href="/help/evolution">
2352 <a href="/help/evolution">
2352 evolution
2353 evolution
2353 </a>
2354 </a>
2354 </td><td>
2355 </td><td>
2355 Safely rewriting history (EXPERIMENTAL)
2356 Safely rewriting history (EXPERIMENTAL)
2356 </td></tr>
2357 </td></tr>
2357 <tr><td>
2358 <tr><td>
2358 <a href="/help/extensions">
2359 <a href="/help/extensions">
2359 extensions
2360 extensions
2360 </a>
2361 </a>
2361 </td><td>
2362 </td><td>
2362 Using Additional Features
2363 Using Additional Features
2363 </td></tr>
2364 </td></tr>
2364 <tr><td>
2365 <tr><td>
2365 <a href="/help/filesets">
2366 <a href="/help/filesets">
2366 filesets
2367 filesets
2367 </a>
2368 </a>
2368 </td><td>
2369 </td><td>
2369 Specifying File Sets
2370 Specifying File Sets
2370 </td></tr>
2371 </td></tr>
2371 <tr><td>
2372 <tr><td>
2372 <a href="/help/flags">
2373 <a href="/help/flags">
2373 flags
2374 flags
2374 </a>
2375 </a>
2375 </td><td>
2376 </td><td>
2376 Command-line flags
2377 Command-line flags
2377 </td></tr>
2378 </td></tr>
2378 <tr><td>
2379 <tr><td>
2379 <a href="/help/glossary">
2380 <a href="/help/glossary">
2380 glossary
2381 glossary
2381 </a>
2382 </a>
2382 </td><td>
2383 </td><td>
2383 Glossary
2384 Glossary
2384 </td></tr>
2385 </td></tr>
2385 <tr><td>
2386 <tr><td>
2386 <a href="/help/hgignore">
2387 <a href="/help/hgignore">
2387 hgignore
2388 hgignore
2388 </a>
2389 </a>
2389 </td><td>
2390 </td><td>
2390 Syntax for Mercurial Ignore Files
2391 Syntax for Mercurial Ignore Files
2391 </td></tr>
2392 </td></tr>
2392 <tr><td>
2393 <tr><td>
2393 <a href="/help/hgweb">
2394 <a href="/help/hgweb">
2394 hgweb
2395 hgweb
2395 </a>
2396 </a>
2396 </td><td>
2397 </td><td>
2397 Configuring hgweb
2398 Configuring hgweb
2398 </td></tr>
2399 </td></tr>
2399 <tr><td>
2400 <tr><td>
2400 <a href="/help/internals">
2401 <a href="/help/internals">
2401 internals
2402 internals
2402 </a>
2403 </a>
2403 </td><td>
2404 </td><td>
2404 Technical implementation topics
2405 Technical implementation topics
2405 </td></tr>
2406 </td></tr>
2406 <tr><td>
2407 <tr><td>
2407 <a href="/help/merge-tools">
2408 <a href="/help/merge-tools">
2408 merge-tools
2409 merge-tools
2409 </a>
2410 </a>
2410 </td><td>
2411 </td><td>
2411 Merge Tools
2412 Merge Tools
2412 </td></tr>
2413 </td></tr>
2413 <tr><td>
2414 <tr><td>
2414 <a href="/help/pager">
2415 <a href="/help/pager">
2415 pager
2416 pager
2416 </a>
2417 </a>
2417 </td><td>
2418 </td><td>
2418 Pager Support
2419 Pager Support
2419 </td></tr>
2420 </td></tr>
2420 <tr><td>
2421 <tr><td>
2421 <a href="/help/patterns">
2422 <a href="/help/patterns">
2422 patterns
2423 patterns
2423 </a>
2424 </a>
2424 </td><td>
2425 </td><td>
2425 File Name Patterns
2426 File Name Patterns
2426 </td></tr>
2427 </td></tr>
2427 <tr><td>
2428 <tr><td>
2428 <a href="/help/phases">
2429 <a href="/help/phases">
2429 phases
2430 phases
2430 </a>
2431 </a>
2431 </td><td>
2432 </td><td>
2432 Working with Phases
2433 Working with Phases
2433 </td></tr>
2434 </td></tr>
2434 <tr><td>
2435 <tr><td>
2435 <a href="/help/revisions">
2436 <a href="/help/revisions">
2436 revisions
2437 revisions
2437 </a>
2438 </a>
2438 </td><td>
2439 </td><td>
2439 Specifying Revisions
2440 Specifying Revisions
2440 </td></tr>
2441 </td></tr>
2441 <tr><td>
2442 <tr><td>
2442 <a href="/help/rust">
2443 <a href="/help/rust">
2443 rust
2444 rust
2444 </a>
2445 </a>
2445 </td><td>
2446 </td><td>
2446 Rust in Mercurial
2447 Rust in Mercurial
2447 </td></tr>
2448 </td></tr>
2448 <tr><td>
2449 <tr><td>
2449 <a href="/help/scripting">
2450 <a href="/help/scripting">
2450 scripting
2451 scripting
2451 </a>
2452 </a>
2452 </td><td>
2453 </td><td>
2453 Using Mercurial from scripts and automation
2454 Using Mercurial from scripts and automation
2454 </td></tr>
2455 </td></tr>
2455 <tr><td>
2456 <tr><td>
2456 <a href="/help/subrepos">
2457 <a href="/help/subrepos">
2457 subrepos
2458 subrepos
2458 </a>
2459 </a>
2459 </td><td>
2460 </td><td>
2460 Subrepositories
2461 Subrepositories
2461 </td></tr>
2462 </td></tr>
2462 <tr><td>
2463 <tr><td>
2463 <a href="/help/templating">
2464 <a href="/help/templating">
2464 templating
2465 templating
2465 </a>
2466 </a>
2466 </td><td>
2467 </td><td>
2467 Template Usage
2468 Template Usage
2468 </td></tr>
2469 </td></tr>
2469 <tr><td>
2470 <tr><td>
2470 <a href="/help/urls">
2471 <a href="/help/urls">
2471 urls
2472 urls
2472 </a>
2473 </a>
2473 </td><td>
2474 </td><td>
2474 URL Paths
2475 URL Paths
2475 </td></tr>
2476 </td></tr>
2476 <tr><td>
2477 <tr><td>
2477 <a href="/help/topic-containing-verbose">
2478 <a href="/help/topic-containing-verbose">
2478 topic-containing-verbose
2479 topic-containing-verbose
2479 </a>
2480 </a>
2480 </td><td>
2481 </td><td>
2481 This is the topic to test omit indicating.
2482 This is the topic to test omit indicating.
2482 </td></tr>
2483 </td></tr>
2483
2484
2484
2485
2485 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2486 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2486
2487
2487 <tr><td>
2488 <tr><td>
2488 <a href="/help/abort">
2489 <a href="/help/abort">
2489 abort
2490 abort
2490 </a>
2491 </a>
2491 </td><td>
2492 </td><td>
2492 abort an unfinished operation (EXPERIMENTAL)
2493 abort an unfinished operation (EXPERIMENTAL)
2493 </td></tr>
2494 </td></tr>
2494 <tr><td>
2495 <tr><td>
2495 <a href="/help/add">
2496 <a href="/help/add">
2496 add
2497 add
2497 </a>
2498 </a>
2498 </td><td>
2499 </td><td>
2499 add the specified files on the next commit
2500 add the specified files on the next commit
2500 </td></tr>
2501 </td></tr>
2501 <tr><td>
2502 <tr><td>
2502 <a href="/help/annotate">
2503 <a href="/help/annotate">
2503 annotate
2504 annotate
2504 </a>
2505 </a>
2505 </td><td>
2506 </td><td>
2506 show changeset information by line for each file
2507 show changeset information by line for each file
2507 </td></tr>
2508 </td></tr>
2508 <tr><td>
2509 <tr><td>
2509 <a href="/help/clone">
2510 <a href="/help/clone">
2510 clone
2511 clone
2511 </a>
2512 </a>
2512 </td><td>
2513 </td><td>
2513 make a copy of an existing repository
2514 make a copy of an existing repository
2514 </td></tr>
2515 </td></tr>
2515 <tr><td>
2516 <tr><td>
2516 <a href="/help/commit">
2517 <a href="/help/commit">
2517 commit
2518 commit
2518 </a>
2519 </a>
2519 </td><td>
2520 </td><td>
2520 commit the specified files or all outstanding changes
2521 commit the specified files or all outstanding changes
2521 </td></tr>
2522 </td></tr>
2522 <tr><td>
2523 <tr><td>
2523 <a href="/help/continue">
2524 <a href="/help/continue">
2524 continue
2525 continue
2525 </a>
2526 </a>
2526 </td><td>
2527 </td><td>
2527 resumes an interrupted operation (EXPERIMENTAL)
2528 resumes an interrupted operation (EXPERIMENTAL)
2528 </td></tr>
2529 </td></tr>
2529 <tr><td>
2530 <tr><td>
2530 <a href="/help/diff">
2531 <a href="/help/diff">
2531 diff
2532 diff
2532 </a>
2533 </a>
2533 </td><td>
2534 </td><td>
2534 diff repository (or selected files)
2535 diff repository (or selected files)
2535 </td></tr>
2536 </td></tr>
2536 <tr><td>
2537 <tr><td>
2537 <a href="/help/export">
2538 <a href="/help/export">
2538 export
2539 export
2539 </a>
2540 </a>
2540 </td><td>
2541 </td><td>
2541 dump the header and diffs for one or more changesets
2542 dump the header and diffs for one or more changesets
2542 </td></tr>
2543 </td></tr>
2543 <tr><td>
2544 <tr><td>
2544 <a href="/help/forget">
2545 <a href="/help/forget">
2545 forget
2546 forget
2546 </a>
2547 </a>
2547 </td><td>
2548 </td><td>
2548 forget the specified files on the next commit
2549 forget the specified files on the next commit
2549 </td></tr>
2550 </td></tr>
2550 <tr><td>
2551 <tr><td>
2551 <a href="/help/init">
2552 <a href="/help/init">
2552 init
2553 init
2553 </a>
2554 </a>
2554 </td><td>
2555 </td><td>
2555 create a new repository in the given directory
2556 create a new repository in the given directory
2556 </td></tr>
2557 </td></tr>
2557 <tr><td>
2558 <tr><td>
2558 <a href="/help/log">
2559 <a href="/help/log">
2559 log
2560 log
2560 </a>
2561 </a>
2561 </td><td>
2562 </td><td>
2562 show revision history of entire repository or files
2563 show revision history of entire repository or files
2563 </td></tr>
2564 </td></tr>
2564 <tr><td>
2565 <tr><td>
2565 <a href="/help/merge">
2566 <a href="/help/merge">
2566 merge
2567 merge
2567 </a>
2568 </a>
2568 </td><td>
2569 </td><td>
2569 merge another revision into working directory
2570 merge another revision into working directory
2570 </td></tr>
2571 </td></tr>
2571 <tr><td>
2572 <tr><td>
2572 <a href="/help/pull">
2573 <a href="/help/pull">
2573 pull
2574 pull
2574 </a>
2575 </a>
2575 </td><td>
2576 </td><td>
2576 pull changes from the specified source
2577 pull changes from the specified source
2577 </td></tr>
2578 </td></tr>
2578 <tr><td>
2579 <tr><td>
2579 <a href="/help/push">
2580 <a href="/help/push">
2580 push
2581 push
2581 </a>
2582 </a>
2582 </td><td>
2583 </td><td>
2583 push changes to the specified destination
2584 push changes to the specified destination
2584 </td></tr>
2585 </td></tr>
2585 <tr><td>
2586 <tr><td>
2586 <a href="/help/remove">
2587 <a href="/help/remove">
2587 remove
2588 remove
2588 </a>
2589 </a>
2589 </td><td>
2590 </td><td>
2590 remove the specified files on the next commit
2591 remove the specified files on the next commit
2591 </td></tr>
2592 </td></tr>
2592 <tr><td>
2593 <tr><td>
2593 <a href="/help/serve">
2594 <a href="/help/serve">
2594 serve
2595 serve
2595 </a>
2596 </a>
2596 </td><td>
2597 </td><td>
2597 start stand-alone webserver
2598 start stand-alone webserver
2598 </td></tr>
2599 </td></tr>
2599 <tr><td>
2600 <tr><td>
2600 <a href="/help/status">
2601 <a href="/help/status">
2601 status
2602 status
2602 </a>
2603 </a>
2603 </td><td>
2604 </td><td>
2604 show changed files in the working directory
2605 show changed files in the working directory
2605 </td></tr>
2606 </td></tr>
2606 <tr><td>
2607 <tr><td>
2607 <a href="/help/summary">
2608 <a href="/help/summary">
2608 summary
2609 summary
2609 </a>
2610 </a>
2610 </td><td>
2611 </td><td>
2611 summarize working directory state
2612 summarize working directory state
2612 </td></tr>
2613 </td></tr>
2613 <tr><td>
2614 <tr><td>
2614 <a href="/help/update">
2615 <a href="/help/update">
2615 update
2616 update
2616 </a>
2617 </a>
2617 </td><td>
2618 </td><td>
2618 update working directory (or switch revisions)
2619 update working directory (or switch revisions)
2619 </td></tr>
2620 </td></tr>
2620
2621
2621
2622
2622
2623
2623 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2624 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2624
2625
2625 <tr><td>
2626 <tr><td>
2626 <a href="/help/addremove">
2627 <a href="/help/addremove">
2627 addremove
2628 addremove
2628 </a>
2629 </a>
2629 </td><td>
2630 </td><td>
2630 add all new files, delete all missing files
2631 add all new files, delete all missing files
2631 </td></tr>
2632 </td></tr>
2632 <tr><td>
2633 <tr><td>
2633 <a href="/help/archive">
2634 <a href="/help/archive">
2634 archive
2635 archive
2635 </a>
2636 </a>
2636 </td><td>
2637 </td><td>
2637 create an unversioned archive of a repository revision
2638 create an unversioned archive of a repository revision
2638 </td></tr>
2639 </td></tr>
2639 <tr><td>
2640 <tr><td>
2640 <a href="/help/backout">
2641 <a href="/help/backout">
2641 backout
2642 backout
2642 </a>
2643 </a>
2643 </td><td>
2644 </td><td>
2644 reverse effect of earlier changeset
2645 reverse effect of earlier changeset
2645 </td></tr>
2646 </td></tr>
2646 <tr><td>
2647 <tr><td>
2647 <a href="/help/bisect">
2648 <a href="/help/bisect">
2648 bisect
2649 bisect
2649 </a>
2650 </a>
2650 </td><td>
2651 </td><td>
2651 subdivision search of changesets
2652 subdivision search of changesets
2652 </td></tr>
2653 </td></tr>
2653 <tr><td>
2654 <tr><td>
2654 <a href="/help/bookmarks">
2655 <a href="/help/bookmarks">
2655 bookmarks
2656 bookmarks
2656 </a>
2657 </a>
2657 </td><td>
2658 </td><td>
2658 create a new bookmark or list existing bookmarks
2659 create a new bookmark or list existing bookmarks
2659 </td></tr>
2660 </td></tr>
2660 <tr><td>
2661 <tr><td>
2661 <a href="/help/branch">
2662 <a href="/help/branch">
2662 branch
2663 branch
2663 </a>
2664 </a>
2664 </td><td>
2665 </td><td>
2665 set or show the current branch name
2666 set or show the current branch name
2666 </td></tr>
2667 </td></tr>
2667 <tr><td>
2668 <tr><td>
2668 <a href="/help/branches">
2669 <a href="/help/branches">
2669 branches
2670 branches
2670 </a>
2671 </a>
2671 </td><td>
2672 </td><td>
2672 list repository named branches
2673 list repository named branches
2673 </td></tr>
2674 </td></tr>
2674 <tr><td>
2675 <tr><td>
2675 <a href="/help/bundle">
2676 <a href="/help/bundle">
2676 bundle
2677 bundle
2677 </a>
2678 </a>
2678 </td><td>
2679 </td><td>
2679 create a bundle file
2680 create a bundle file
2680 </td></tr>
2681 </td></tr>
2681 <tr><td>
2682 <tr><td>
2682 <a href="/help/cat">
2683 <a href="/help/cat">
2683 cat
2684 cat
2684 </a>
2685 </a>
2685 </td><td>
2686 </td><td>
2686 output the current or given revision of files
2687 output the current or given revision of files
2687 </td></tr>
2688 </td></tr>
2688 <tr><td>
2689 <tr><td>
2689 <a href="/help/config">
2690 <a href="/help/config">
2690 config
2691 config
2691 </a>
2692 </a>
2692 </td><td>
2693 </td><td>
2693 show combined config settings from all hgrc files
2694 show combined config settings from all hgrc files
2694 </td></tr>
2695 </td></tr>
2695 <tr><td>
2696 <tr><td>
2696 <a href="/help/copy">
2697 <a href="/help/copy">
2697 copy
2698 copy
2698 </a>
2699 </a>
2699 </td><td>
2700 </td><td>
2700 mark files as copied for the next commit
2701 mark files as copied for the next commit
2701 </td></tr>
2702 </td></tr>
2702 <tr><td>
2703 <tr><td>
2703 <a href="/help/files">
2704 <a href="/help/files">
2704 files
2705 files
2705 </a>
2706 </a>
2706 </td><td>
2707 </td><td>
2707 list tracked files
2708 list tracked files
2708 </td></tr>
2709 </td></tr>
2709 <tr><td>
2710 <tr><td>
2710 <a href="/help/graft">
2711 <a href="/help/graft">
2711 graft
2712 graft
2712 </a>
2713 </a>
2713 </td><td>
2714 </td><td>
2714 copy changes from other branches onto the current branch
2715 copy changes from other branches onto the current branch
2715 </td></tr>
2716 </td></tr>
2716 <tr><td>
2717 <tr><td>
2717 <a href="/help/grep">
2718 <a href="/help/grep">
2718 grep
2719 grep
2719 </a>
2720 </a>
2720 </td><td>
2721 </td><td>
2721 search for a pattern in specified files
2722 search for a pattern in specified files
2722 </td></tr>
2723 </td></tr>
2723 <tr><td>
2724 <tr><td>
2724 <a href="/help/hashelp">
2725 <a href="/help/hashelp">
2725 hashelp
2726 hashelp
2726 </a>
2727 </a>
2727 </td><td>
2728 </td><td>
2728 Extension command's help
2729 Extension command's help
2729 </td></tr>
2730 </td></tr>
2730 <tr><td>
2731 <tr><td>
2731 <a href="/help/heads">
2732 <a href="/help/heads">
2732 heads
2733 heads
2733 </a>
2734 </a>
2734 </td><td>
2735 </td><td>
2735 show branch heads
2736 show branch heads
2736 </td></tr>
2737 </td></tr>
2737 <tr><td>
2738 <tr><td>
2738 <a href="/help/help">
2739 <a href="/help/help">
2739 help
2740 help
2740 </a>
2741 </a>
2741 </td><td>
2742 </td><td>
2742 show help for a given topic or a help overview
2743 show help for a given topic or a help overview
2743 </td></tr>
2744 </td></tr>
2744 <tr><td>
2745 <tr><td>
2745 <a href="/help/hgalias">
2746 <a href="/help/hgalias">
2746 hgalias
2747 hgalias
2747 </a>
2748 </a>
2748 </td><td>
2749 </td><td>
2749 My doc
2750 My doc
2750 </td></tr>
2751 </td></tr>
2751 <tr><td>
2752 <tr><td>
2752 <a href="/help/hgaliasnodoc">
2753 <a href="/help/hgaliasnodoc">
2753 hgaliasnodoc
2754 hgaliasnodoc
2754 </a>
2755 </a>
2755 </td><td>
2756 </td><td>
2756 summarize working directory state
2757 summarize working directory state
2757 </td></tr>
2758 </td></tr>
2758 <tr><td>
2759 <tr><td>
2759 <a href="/help/identify">
2760 <a href="/help/identify">
2760 identify
2761 identify
2761 </a>
2762 </a>
2762 </td><td>
2763 </td><td>
2763 identify the working directory or specified revision
2764 identify the working directory or specified revision
2764 </td></tr>
2765 </td></tr>
2765 <tr><td>
2766 <tr><td>
2766 <a href="/help/import">
2767 <a href="/help/import">
2767 import
2768 import
2768 </a>
2769 </a>
2769 </td><td>
2770 </td><td>
2770 import an ordered set of patches
2771 import an ordered set of patches
2771 </td></tr>
2772 </td></tr>
2772 <tr><td>
2773 <tr><td>
2773 <a href="/help/incoming">
2774 <a href="/help/incoming">
2774 incoming
2775 incoming
2775 </a>
2776 </a>
2776 </td><td>
2777 </td><td>
2777 show new changesets found in source
2778 show new changesets found in source
2778 </td></tr>
2779 </td></tr>
2779 <tr><td>
2780 <tr><td>
2780 <a href="/help/manifest">
2781 <a href="/help/manifest">
2781 manifest
2782 manifest
2782 </a>
2783 </a>
2783 </td><td>
2784 </td><td>
2784 output the current or given revision of the project manifest
2785 output the current or given revision of the project manifest
2785 </td></tr>
2786 </td></tr>
2786 <tr><td>
2787 <tr><td>
2787 <a href="/help/nohelp">
2788 <a href="/help/nohelp">
2788 nohelp
2789 nohelp
2789 </a>
2790 </a>
2790 </td><td>
2791 </td><td>
2791 (no help text available)
2792 (no help text available)
2792 </td></tr>
2793 </td></tr>
2793 <tr><td>
2794 <tr><td>
2794 <a href="/help/outgoing">
2795 <a href="/help/outgoing">
2795 outgoing
2796 outgoing
2796 </a>
2797 </a>
2797 </td><td>
2798 </td><td>
2798 show changesets not found in the destination
2799 show changesets not found in the destination
2799 </td></tr>
2800 </td></tr>
2800 <tr><td>
2801 <tr><td>
2801 <a href="/help/paths">
2802 <a href="/help/paths">
2802 paths
2803 paths
2803 </a>
2804 </a>
2804 </td><td>
2805 </td><td>
2805 show aliases for remote repositories
2806 show aliases for remote repositories
2806 </td></tr>
2807 </td></tr>
2807 <tr><td>
2808 <tr><td>
2808 <a href="/help/phase">
2809 <a href="/help/phase">
2809 phase
2810 phase
2810 </a>
2811 </a>
2811 </td><td>
2812 </td><td>
2812 set or show the current phase name
2813 set or show the current phase name
2813 </td></tr>
2814 </td></tr>
2814 <tr><td>
2815 <tr><td>
2815 <a href="/help/purge">
2816 <a href="/help/purge">
2816 purge
2817 purge
2817 </a>
2818 </a>
2818 </td><td>
2819 </td><td>
2819 removes files not tracked by Mercurial
2820 removes files not tracked by Mercurial
2820 </td></tr>
2821 </td></tr>
2821 <tr><td>
2822 <tr><td>
2822 <a href="/help/recover">
2823 <a href="/help/recover">
2823 recover
2824 recover
2824 </a>
2825 </a>
2825 </td><td>
2826 </td><td>
2826 roll back an interrupted transaction
2827 roll back an interrupted transaction
2827 </td></tr>
2828 </td></tr>
2828 <tr><td>
2829 <tr><td>
2829 <a href="/help/rename">
2830 <a href="/help/rename">
2830 rename
2831 rename
2831 </a>
2832 </a>
2832 </td><td>
2833 </td><td>
2833 rename files; equivalent of copy + remove
2834 rename files; equivalent of copy + remove
2834 </td></tr>
2835 </td></tr>
2835 <tr><td>
2836 <tr><td>
2836 <a href="/help/resolve">
2837 <a href="/help/resolve">
2837 resolve
2838 resolve
2838 </a>
2839 </a>
2839 </td><td>
2840 </td><td>
2840 redo merges or set/view the merge status of files
2841 redo merges or set/view the merge status of files
2841 </td></tr>
2842 </td></tr>
2842 <tr><td>
2843 <tr><td>
2843 <a href="/help/revert">
2844 <a href="/help/revert">
2844 revert
2845 revert
2845 </a>
2846 </a>
2846 </td><td>
2847 </td><td>
2847 restore files to their checkout state
2848 restore files to their checkout state
2848 </td></tr>
2849 </td></tr>
2849 <tr><td>
2850 <tr><td>
2850 <a href="/help/root">
2851 <a href="/help/root">
2851 root
2852 root
2852 </a>
2853 </a>
2853 </td><td>
2854 </td><td>
2854 print the root (top) of the current working directory
2855 print the root (top) of the current working directory
2855 </td></tr>
2856 </td></tr>
2856 <tr><td>
2857 <tr><td>
2857 <a href="/help/shellalias">
2858 <a href="/help/shellalias">
2858 shellalias
2859 shellalias
2859 </a>
2860 </a>
2860 </td><td>
2861 </td><td>
2861 (no help text available)
2862 (no help text available)
2862 </td></tr>
2863 </td></tr>
2863 <tr><td>
2864 <tr><td>
2864 <a href="/help/shelve">
2865 <a href="/help/shelve">
2865 shelve
2866 shelve
2866 </a>
2867 </a>
2867 </td><td>
2868 </td><td>
2868 save and set aside changes from the working directory
2869 save and set aside changes from the working directory
2869 </td></tr>
2870 </td></tr>
2870 <tr><td>
2871 <tr><td>
2871 <a href="/help/tag">
2872 <a href="/help/tag">
2872 tag
2873 tag
2873 </a>
2874 </a>
2874 </td><td>
2875 </td><td>
2875 add one or more tags for the current or given revision
2876 add one or more tags for the current or given revision
2876 </td></tr>
2877 </td></tr>
2877 <tr><td>
2878 <tr><td>
2878 <a href="/help/tags">
2879 <a href="/help/tags">
2879 tags
2880 tags
2880 </a>
2881 </a>
2881 </td><td>
2882 </td><td>
2882 list repository tags
2883 list repository tags
2883 </td></tr>
2884 </td></tr>
2884 <tr><td>
2885 <tr><td>
2885 <a href="/help/unbundle">
2886 <a href="/help/unbundle">
2886 unbundle
2887 unbundle
2887 </a>
2888 </a>
2888 </td><td>
2889 </td><td>
2889 apply one or more bundle files
2890 apply one or more bundle files
2890 </td></tr>
2891 </td></tr>
2891 <tr><td>
2892 <tr><td>
2892 <a href="/help/unshelve">
2893 <a href="/help/unshelve">
2893 unshelve
2894 unshelve
2894 </a>
2895 </a>
2895 </td><td>
2896 </td><td>
2896 restore a shelved change to the working directory
2897 restore a shelved change to the working directory
2897 </td></tr>
2898 </td></tr>
2898 <tr><td>
2899 <tr><td>
2899 <a href="/help/verify">
2900 <a href="/help/verify">
2900 verify
2901 verify
2901 </a>
2902 </a>
2902 </td><td>
2903 </td><td>
2903 verify the integrity of the repository
2904 verify the integrity of the repository
2904 </td></tr>
2905 </td></tr>
2905 <tr><td>
2906 <tr><td>
2906 <a href="/help/version">
2907 <a href="/help/version">
2907 version
2908 version
2908 </a>
2909 </a>
2909 </td><td>
2910 </td><td>
2910 output version and copyright information
2911 output version and copyright information
2911 </td></tr>
2912 </td></tr>
2912
2913
2913
2914
2914 </table>
2915 </table>
2915 </div>
2916 </div>
2916 </div>
2917 </div>
2917
2918
2918
2919
2919
2920
2920 </body>
2921 </body>
2921 </html>
2922 </html>
2922
2923
2923
2924
2924 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2925 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2925 200 Script output follows
2926 200 Script output follows
2926
2927
2927 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2928 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2928 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2929 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2929 <head>
2930 <head>
2930 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2931 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2931 <meta name="robots" content="index, nofollow" />
2932 <meta name="robots" content="index, nofollow" />
2932 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2933 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2933 <script type="text/javascript" src="/static/mercurial.js"></script>
2934 <script type="text/javascript" src="/static/mercurial.js"></script>
2934
2935
2935 <title>Help: add</title>
2936 <title>Help: add</title>
2936 </head>
2937 </head>
2937 <body>
2938 <body>
2938
2939
2939 <div class="container">
2940 <div class="container">
2940 <div class="menu">
2941 <div class="menu">
2941 <div class="logo">
2942 <div class="logo">
2942 <a href="https://mercurial-scm.org/">
2943 <a href="https://mercurial-scm.org/">
2943 <img src="/static/hglogo.png" alt="mercurial" /></a>
2944 <img src="/static/hglogo.png" alt="mercurial" /></a>
2944 </div>
2945 </div>
2945 <ul>
2946 <ul>
2946 <li><a href="/shortlog">log</a></li>
2947 <li><a href="/shortlog">log</a></li>
2947 <li><a href="/graph">graph</a></li>
2948 <li><a href="/graph">graph</a></li>
2948 <li><a href="/tags">tags</a></li>
2949 <li><a href="/tags">tags</a></li>
2949 <li><a href="/bookmarks">bookmarks</a></li>
2950 <li><a href="/bookmarks">bookmarks</a></li>
2950 <li><a href="/branches">branches</a></li>
2951 <li><a href="/branches">branches</a></li>
2951 </ul>
2952 </ul>
2952 <ul>
2953 <ul>
2953 <li class="active"><a href="/help">help</a></li>
2954 <li class="active"><a href="/help">help</a></li>
2954 </ul>
2955 </ul>
2955 </div>
2956 </div>
2956
2957
2957 <div class="main">
2958 <div class="main">
2958 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2959 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2959 <h3>Help: add</h3>
2960 <h3>Help: add</h3>
2960
2961
2961 <form class="search" action="/log">
2962 <form class="search" action="/log">
2962
2963
2963 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2964 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2964 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2965 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2965 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2966 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2966 </form>
2967 </form>
2967 <div id="doc">
2968 <div id="doc">
2968 <p>
2969 <p>
2969 hg add [OPTION]... [FILE]...
2970 hg add [OPTION]... [FILE]...
2970 </p>
2971 </p>
2971 <p>
2972 <p>
2972 add the specified files on the next commit
2973 add the specified files on the next commit
2973 </p>
2974 </p>
2974 <p>
2975 <p>
2975 Schedule files to be version controlled and added to the
2976 Schedule files to be version controlled and added to the
2976 repository.
2977 repository.
2977 </p>
2978 </p>
2978 <p>
2979 <p>
2979 The files will be added to the repository at the next commit. To
2980 The files will be added to the repository at the next commit. To
2980 undo an add before that, see 'hg forget'.
2981 undo an add before that, see 'hg forget'.
2981 </p>
2982 </p>
2982 <p>
2983 <p>
2983 If no names are given, add all files to the repository (except
2984 If no names are given, add all files to the repository (except
2984 files matching &quot;.hgignore&quot;).
2985 files matching &quot;.hgignore&quot;).
2985 </p>
2986 </p>
2986 <p>
2987 <p>
2987 Examples:
2988 Examples:
2988 </p>
2989 </p>
2989 <ul>
2990 <ul>
2990 <li> New (unknown) files are added automatically by 'hg add':
2991 <li> New (unknown) files are added automatically by 'hg add':
2991 <pre>
2992 <pre>
2992 \$ ls (re)
2993 \$ ls (re)
2993 foo.c
2994 foo.c
2994 \$ hg status (re)
2995 \$ hg status (re)
2995 ? foo.c
2996 ? foo.c
2996 \$ hg add (re)
2997 \$ hg add (re)
2997 adding foo.c
2998 adding foo.c
2998 \$ hg status (re)
2999 \$ hg status (re)
2999 A foo.c
3000 A foo.c
3000 </pre>
3001 </pre>
3001 <li> Specific files to be added can be specified:
3002 <li> Specific files to be added can be specified:
3002 <pre>
3003 <pre>
3003 \$ ls (re)
3004 \$ ls (re)
3004 bar.c foo.c
3005 bar.c foo.c
3005 \$ hg status (re)
3006 \$ hg status (re)
3006 ? bar.c
3007 ? bar.c
3007 ? foo.c
3008 ? foo.c
3008 \$ hg add bar.c (re)
3009 \$ hg add bar.c (re)
3009 \$ hg status (re)
3010 \$ hg status (re)
3010 A bar.c
3011 A bar.c
3011 ? foo.c
3012 ? foo.c
3012 </pre>
3013 </pre>
3013 </ul>
3014 </ul>
3014 <p>
3015 <p>
3015 Returns 0 if all files are successfully added.
3016 Returns 0 if all files are successfully added.
3016 </p>
3017 </p>
3017 <p>
3018 <p>
3018 options ([+] can be repeated):
3019 options ([+] can be repeated):
3019 </p>
3020 </p>
3020 <table>
3021 <table>
3021 <tr><td>-I</td>
3022 <tr><td>-I</td>
3022 <td>--include PATTERN [+]</td>
3023 <td>--include PATTERN [+]</td>
3023 <td>include names matching the given patterns</td></tr>
3024 <td>include names matching the given patterns</td></tr>
3024 <tr><td>-X</td>
3025 <tr><td>-X</td>
3025 <td>--exclude PATTERN [+]</td>
3026 <td>--exclude PATTERN [+]</td>
3026 <td>exclude names matching the given patterns</td></tr>
3027 <td>exclude names matching the given patterns</td></tr>
3027 <tr><td>-S</td>
3028 <tr><td>-S</td>
3028 <td>--subrepos</td>
3029 <td>--subrepos</td>
3029 <td>recurse into subrepositories</td></tr>
3030 <td>recurse into subrepositories</td></tr>
3030 <tr><td>-n</td>
3031 <tr><td>-n</td>
3031 <td>--dry-run</td>
3032 <td>--dry-run</td>
3032 <td>do not perform actions, just print output</td></tr>
3033 <td>do not perform actions, just print output</td></tr>
3033 </table>
3034 </table>
3034 <p>
3035 <p>
3035 global options ([+] can be repeated):
3036 global options ([+] can be repeated):
3036 </p>
3037 </p>
3037 <table>
3038 <table>
3038 <tr><td>-R</td>
3039 <tr><td>-R</td>
3039 <td>--repository REPO</td>
3040 <td>--repository REPO</td>
3040 <td>repository root directory or name of overlay bundle file</td></tr>
3041 <td>repository root directory or name of overlay bundle file</td></tr>
3041 <tr><td></td>
3042 <tr><td></td>
3042 <td>--cwd DIR</td>
3043 <td>--cwd DIR</td>
3043 <td>change working directory</td></tr>
3044 <td>change working directory</td></tr>
3044 <tr><td>-y</td>
3045 <tr><td>-y</td>
3045 <td>--noninteractive</td>
3046 <td>--noninteractive</td>
3046 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3047 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3047 <tr><td>-q</td>
3048 <tr><td>-q</td>
3048 <td>--quiet</td>
3049 <td>--quiet</td>
3049 <td>suppress output</td></tr>
3050 <td>suppress output</td></tr>
3050 <tr><td>-v</td>
3051 <tr><td>-v</td>
3051 <td>--verbose</td>
3052 <td>--verbose</td>
3052 <td>enable additional output</td></tr>
3053 <td>enable additional output</td></tr>
3053 <tr><td></td>
3054 <tr><td></td>
3054 <td>--color TYPE</td>
3055 <td>--color TYPE</td>
3055 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3056 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3056 <tr><td></td>
3057 <tr><td></td>
3057 <td>--config CONFIG [+]</td>
3058 <td>--config CONFIG [+]</td>
3058 <td>set/override config option (use 'section.name=value')</td></tr>
3059 <td>set/override config option (use 'section.name=value')</td></tr>
3059 <tr><td></td>
3060 <tr><td></td>
3060 <td>--debug</td>
3061 <td>--debug</td>
3061 <td>enable debugging output</td></tr>
3062 <td>enable debugging output</td></tr>
3062 <tr><td></td>
3063 <tr><td></td>
3063 <td>--debugger</td>
3064 <td>--debugger</td>
3064 <td>start debugger</td></tr>
3065 <td>start debugger</td></tr>
3065 <tr><td></td>
3066 <tr><td></td>
3066 <td>--encoding ENCODE</td>
3067 <td>--encoding ENCODE</td>
3067 <td>set the charset encoding (default: ascii)</td></tr>
3068 <td>set the charset encoding (default: ascii)</td></tr>
3068 <tr><td></td>
3069 <tr><td></td>
3069 <td>--encodingmode MODE</td>
3070 <td>--encodingmode MODE</td>
3070 <td>set the charset encoding mode (default: strict)</td></tr>
3071 <td>set the charset encoding mode (default: strict)</td></tr>
3071 <tr><td></td>
3072 <tr><td></td>
3072 <td>--traceback</td>
3073 <td>--traceback</td>
3073 <td>always print a traceback on exception</td></tr>
3074 <td>always print a traceback on exception</td></tr>
3074 <tr><td></td>
3075 <tr><td></td>
3075 <td>--time</td>
3076 <td>--time</td>
3076 <td>time how long the command takes</td></tr>
3077 <td>time how long the command takes</td></tr>
3077 <tr><td></td>
3078 <tr><td></td>
3078 <td>--profile</td>
3079 <td>--profile</td>
3079 <td>print command execution profile</td></tr>
3080 <td>print command execution profile</td></tr>
3080 <tr><td></td>
3081 <tr><td></td>
3081 <td>--version</td>
3082 <td>--version</td>
3082 <td>output version information and exit</td></tr>
3083 <td>output version information and exit</td></tr>
3083 <tr><td>-h</td>
3084 <tr><td>-h</td>
3084 <td>--help</td>
3085 <td>--help</td>
3085 <td>display help and exit</td></tr>
3086 <td>display help and exit</td></tr>
3086 <tr><td></td>
3087 <tr><td></td>
3087 <td>--hidden</td>
3088 <td>--hidden</td>
3088 <td>consider hidden changesets</td></tr>
3089 <td>consider hidden changesets</td></tr>
3089 <tr><td></td>
3090 <tr><td></td>
3090 <td>--pager TYPE</td>
3091 <td>--pager TYPE</td>
3091 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3092 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3092 </table>
3093 </table>
3093
3094
3094 </div>
3095 </div>
3095 </div>
3096 </div>
3096 </div>
3097 </div>
3097
3098
3098
3099
3099
3100
3100 </body>
3101 </body>
3101 </html>
3102 </html>
3102
3103
3103
3104
3104 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
3105 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
3105 200 Script output follows
3106 200 Script output follows
3106
3107
3107 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3108 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3108 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3109 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3109 <head>
3110 <head>
3110 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3111 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3111 <meta name="robots" content="index, nofollow" />
3112 <meta name="robots" content="index, nofollow" />
3112 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3113 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3113 <script type="text/javascript" src="/static/mercurial.js"></script>
3114 <script type="text/javascript" src="/static/mercurial.js"></script>
3114
3115
3115 <title>Help: remove</title>
3116 <title>Help: remove</title>
3116 </head>
3117 </head>
3117 <body>
3118 <body>
3118
3119
3119 <div class="container">
3120 <div class="container">
3120 <div class="menu">
3121 <div class="menu">
3121 <div class="logo">
3122 <div class="logo">
3122 <a href="https://mercurial-scm.org/">
3123 <a href="https://mercurial-scm.org/">
3123 <img src="/static/hglogo.png" alt="mercurial" /></a>
3124 <img src="/static/hglogo.png" alt="mercurial" /></a>
3124 </div>
3125 </div>
3125 <ul>
3126 <ul>
3126 <li><a href="/shortlog">log</a></li>
3127 <li><a href="/shortlog">log</a></li>
3127 <li><a href="/graph">graph</a></li>
3128 <li><a href="/graph">graph</a></li>
3128 <li><a href="/tags">tags</a></li>
3129 <li><a href="/tags">tags</a></li>
3129 <li><a href="/bookmarks">bookmarks</a></li>
3130 <li><a href="/bookmarks">bookmarks</a></li>
3130 <li><a href="/branches">branches</a></li>
3131 <li><a href="/branches">branches</a></li>
3131 </ul>
3132 </ul>
3132 <ul>
3133 <ul>
3133 <li class="active"><a href="/help">help</a></li>
3134 <li class="active"><a href="/help">help</a></li>
3134 </ul>
3135 </ul>
3135 </div>
3136 </div>
3136
3137
3137 <div class="main">
3138 <div class="main">
3138 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3139 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3139 <h3>Help: remove</h3>
3140 <h3>Help: remove</h3>
3140
3141
3141 <form class="search" action="/log">
3142 <form class="search" action="/log">
3142
3143
3143 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3144 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3144 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3145 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3145 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3146 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3146 </form>
3147 </form>
3147 <div id="doc">
3148 <div id="doc">
3148 <p>
3149 <p>
3149 hg remove [OPTION]... FILE...
3150 hg remove [OPTION]... FILE...
3150 </p>
3151 </p>
3151 <p>
3152 <p>
3152 aliases: rm
3153 aliases: rm
3153 </p>
3154 </p>
3154 <p>
3155 <p>
3155 remove the specified files on the next commit
3156 remove the specified files on the next commit
3156 </p>
3157 </p>
3157 <p>
3158 <p>
3158 Schedule the indicated files for removal from the current branch.
3159 Schedule the indicated files for removal from the current branch.
3159 </p>
3160 </p>
3160 <p>
3161 <p>
3161 This command schedules the files to be removed at the next commit.
3162 This command schedules the files to be removed at the next commit.
3162 To undo a remove before that, see 'hg revert'. To undo added
3163 To undo a remove before that, see 'hg revert'. To undo added
3163 files, see 'hg forget'.
3164 files, see 'hg forget'.
3164 </p>
3165 </p>
3165 <p>
3166 <p>
3166 -A/--after can be used to remove only files that have already
3167 -A/--after can be used to remove only files that have already
3167 been deleted, -f/--force can be used to force deletion, and -Af
3168 been deleted, -f/--force can be used to force deletion, and -Af
3168 can be used to remove files from the next revision without
3169 can be used to remove files from the next revision without
3169 deleting them from the working directory.
3170 deleting them from the working directory.
3170 </p>
3171 </p>
3171 <p>
3172 <p>
3172 The following table details the behavior of remove for different
3173 The following table details the behavior of remove for different
3173 file states (columns) and option combinations (rows). The file
3174 file states (columns) and option combinations (rows). The file
3174 states are Added [A], Clean [C], Modified [M] and Missing [!]
3175 states are Added [A], Clean [C], Modified [M] and Missing [!]
3175 (as reported by 'hg status'). The actions are Warn, Remove
3176 (as reported by 'hg status'). The actions are Warn, Remove
3176 (from branch) and Delete (from disk):
3177 (from branch) and Delete (from disk):
3177 </p>
3178 </p>
3178 <table>
3179 <table>
3179 <tr><td>opt/state</td>
3180 <tr><td>opt/state</td>
3180 <td>A</td>
3181 <td>A</td>
3181 <td>C</td>
3182 <td>C</td>
3182 <td>M</td>
3183 <td>M</td>
3183 <td>!</td></tr>
3184 <td>!</td></tr>
3184 <tr><td>none</td>
3185 <tr><td>none</td>
3185 <td>W</td>
3186 <td>W</td>
3186 <td>RD</td>
3187 <td>RD</td>
3187 <td>W</td>
3188 <td>W</td>
3188 <td>R</td></tr>
3189 <td>R</td></tr>
3189 <tr><td>-f</td>
3190 <tr><td>-f</td>
3190 <td>R</td>
3191 <td>R</td>
3191 <td>RD</td>
3192 <td>RD</td>
3192 <td>RD</td>
3193 <td>RD</td>
3193 <td>R</td></tr>
3194 <td>R</td></tr>
3194 <tr><td>-A</td>
3195 <tr><td>-A</td>
3195 <td>W</td>
3196 <td>W</td>
3196 <td>W</td>
3197 <td>W</td>
3197 <td>W</td>
3198 <td>W</td>
3198 <td>R</td></tr>
3199 <td>R</td></tr>
3199 <tr><td>-Af</td>
3200 <tr><td>-Af</td>
3200 <td>R</td>
3201 <td>R</td>
3201 <td>R</td>
3202 <td>R</td>
3202 <td>R</td>
3203 <td>R</td>
3203 <td>R</td></tr>
3204 <td>R</td></tr>
3204 </table>
3205 </table>
3205 <p>
3206 <p>
3206 <b>Note:</b>
3207 <b>Note:</b>
3207 </p>
3208 </p>
3208 <p>
3209 <p>
3209 'hg remove' never deletes files in Added [A] state from the
3210 'hg remove' never deletes files in Added [A] state from the
3210 working directory, not even if &quot;--force&quot; is specified.
3211 working directory, not even if &quot;--force&quot; is specified.
3211 </p>
3212 </p>
3212 <p>
3213 <p>
3213 Returns 0 on success, 1 if any warnings encountered.
3214 Returns 0 on success, 1 if any warnings encountered.
3214 </p>
3215 </p>
3215 <p>
3216 <p>
3216 options ([+] can be repeated):
3217 options ([+] can be repeated):
3217 </p>
3218 </p>
3218 <table>
3219 <table>
3219 <tr><td>-A</td>
3220 <tr><td>-A</td>
3220 <td>--after</td>
3221 <td>--after</td>
3221 <td>record delete for missing files</td></tr>
3222 <td>record delete for missing files</td></tr>
3222 <tr><td>-f</td>
3223 <tr><td>-f</td>
3223 <td>--force</td>
3224 <td>--force</td>
3224 <td>forget added files, delete modified files</td></tr>
3225 <td>forget added files, delete modified files</td></tr>
3225 <tr><td>-S</td>
3226 <tr><td>-S</td>
3226 <td>--subrepos</td>
3227 <td>--subrepos</td>
3227 <td>recurse into subrepositories</td></tr>
3228 <td>recurse into subrepositories</td></tr>
3228 <tr><td>-I</td>
3229 <tr><td>-I</td>
3229 <td>--include PATTERN [+]</td>
3230 <td>--include PATTERN [+]</td>
3230 <td>include names matching the given patterns</td></tr>
3231 <td>include names matching the given patterns</td></tr>
3231 <tr><td>-X</td>
3232 <tr><td>-X</td>
3232 <td>--exclude PATTERN [+]</td>
3233 <td>--exclude PATTERN [+]</td>
3233 <td>exclude names matching the given patterns</td></tr>
3234 <td>exclude names matching the given patterns</td></tr>
3234 <tr><td>-n</td>
3235 <tr><td>-n</td>
3235 <td>--dry-run</td>
3236 <td>--dry-run</td>
3236 <td>do not perform actions, just print output</td></tr>
3237 <td>do not perform actions, just print output</td></tr>
3237 </table>
3238 </table>
3238 <p>
3239 <p>
3239 global options ([+] can be repeated):
3240 global options ([+] can be repeated):
3240 </p>
3241 </p>
3241 <table>
3242 <table>
3242 <tr><td>-R</td>
3243 <tr><td>-R</td>
3243 <td>--repository REPO</td>
3244 <td>--repository REPO</td>
3244 <td>repository root directory or name of overlay bundle file</td></tr>
3245 <td>repository root directory or name of overlay bundle file</td></tr>
3245 <tr><td></td>
3246 <tr><td></td>
3246 <td>--cwd DIR</td>
3247 <td>--cwd DIR</td>
3247 <td>change working directory</td></tr>
3248 <td>change working directory</td></tr>
3248 <tr><td>-y</td>
3249 <tr><td>-y</td>
3249 <td>--noninteractive</td>
3250 <td>--noninteractive</td>
3250 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3251 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3251 <tr><td>-q</td>
3252 <tr><td>-q</td>
3252 <td>--quiet</td>
3253 <td>--quiet</td>
3253 <td>suppress output</td></tr>
3254 <td>suppress output</td></tr>
3254 <tr><td>-v</td>
3255 <tr><td>-v</td>
3255 <td>--verbose</td>
3256 <td>--verbose</td>
3256 <td>enable additional output</td></tr>
3257 <td>enable additional output</td></tr>
3257 <tr><td></td>
3258 <tr><td></td>
3258 <td>--color TYPE</td>
3259 <td>--color TYPE</td>
3259 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3260 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3260 <tr><td></td>
3261 <tr><td></td>
3261 <td>--config CONFIG [+]</td>
3262 <td>--config CONFIG [+]</td>
3262 <td>set/override config option (use 'section.name=value')</td></tr>
3263 <td>set/override config option (use 'section.name=value')</td></tr>
3263 <tr><td></td>
3264 <tr><td></td>
3264 <td>--debug</td>
3265 <td>--debug</td>
3265 <td>enable debugging output</td></tr>
3266 <td>enable debugging output</td></tr>
3266 <tr><td></td>
3267 <tr><td></td>
3267 <td>--debugger</td>
3268 <td>--debugger</td>
3268 <td>start debugger</td></tr>
3269 <td>start debugger</td></tr>
3269 <tr><td></td>
3270 <tr><td></td>
3270 <td>--encoding ENCODE</td>
3271 <td>--encoding ENCODE</td>
3271 <td>set the charset encoding (default: ascii)</td></tr>
3272 <td>set the charset encoding (default: ascii)</td></tr>
3272 <tr><td></td>
3273 <tr><td></td>
3273 <td>--encodingmode MODE</td>
3274 <td>--encodingmode MODE</td>
3274 <td>set the charset encoding mode (default: strict)</td></tr>
3275 <td>set the charset encoding mode (default: strict)</td></tr>
3275 <tr><td></td>
3276 <tr><td></td>
3276 <td>--traceback</td>
3277 <td>--traceback</td>
3277 <td>always print a traceback on exception</td></tr>
3278 <td>always print a traceback on exception</td></tr>
3278 <tr><td></td>
3279 <tr><td></td>
3279 <td>--time</td>
3280 <td>--time</td>
3280 <td>time how long the command takes</td></tr>
3281 <td>time how long the command takes</td></tr>
3281 <tr><td></td>
3282 <tr><td></td>
3282 <td>--profile</td>
3283 <td>--profile</td>
3283 <td>print command execution profile</td></tr>
3284 <td>print command execution profile</td></tr>
3284 <tr><td></td>
3285 <tr><td></td>
3285 <td>--version</td>
3286 <td>--version</td>
3286 <td>output version information and exit</td></tr>
3287 <td>output version information and exit</td></tr>
3287 <tr><td>-h</td>
3288 <tr><td>-h</td>
3288 <td>--help</td>
3289 <td>--help</td>
3289 <td>display help and exit</td></tr>
3290 <td>display help and exit</td></tr>
3290 <tr><td></td>
3291 <tr><td></td>
3291 <td>--hidden</td>
3292 <td>--hidden</td>
3292 <td>consider hidden changesets</td></tr>
3293 <td>consider hidden changesets</td></tr>
3293 <tr><td></td>
3294 <tr><td></td>
3294 <td>--pager TYPE</td>
3295 <td>--pager TYPE</td>
3295 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3296 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3296 </table>
3297 </table>
3297
3298
3298 </div>
3299 </div>
3299 </div>
3300 </div>
3300 </div>
3301 </div>
3301
3302
3302
3303
3303
3304
3304 </body>
3305 </body>
3305 </html>
3306 </html>
3306
3307
3307
3308
3308 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3309 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3309 200 Script output follows
3310 200 Script output follows
3310
3311
3311 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3312 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3312 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3313 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3313 <head>
3314 <head>
3314 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3315 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3315 <meta name="robots" content="index, nofollow" />
3316 <meta name="robots" content="index, nofollow" />
3316 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3317 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3317 <script type="text/javascript" src="/static/mercurial.js"></script>
3318 <script type="text/javascript" src="/static/mercurial.js"></script>
3318
3319
3319 <title>Help: dates</title>
3320 <title>Help: dates</title>
3320 </head>
3321 </head>
3321 <body>
3322 <body>
3322
3323
3323 <div class="container">
3324 <div class="container">
3324 <div class="menu">
3325 <div class="menu">
3325 <div class="logo">
3326 <div class="logo">
3326 <a href="https://mercurial-scm.org/">
3327 <a href="https://mercurial-scm.org/">
3327 <img src="/static/hglogo.png" alt="mercurial" /></a>
3328 <img src="/static/hglogo.png" alt="mercurial" /></a>
3328 </div>
3329 </div>
3329 <ul>
3330 <ul>
3330 <li><a href="/shortlog">log</a></li>
3331 <li><a href="/shortlog">log</a></li>
3331 <li><a href="/graph">graph</a></li>
3332 <li><a href="/graph">graph</a></li>
3332 <li><a href="/tags">tags</a></li>
3333 <li><a href="/tags">tags</a></li>
3333 <li><a href="/bookmarks">bookmarks</a></li>
3334 <li><a href="/bookmarks">bookmarks</a></li>
3334 <li><a href="/branches">branches</a></li>
3335 <li><a href="/branches">branches</a></li>
3335 </ul>
3336 </ul>
3336 <ul>
3337 <ul>
3337 <li class="active"><a href="/help">help</a></li>
3338 <li class="active"><a href="/help">help</a></li>
3338 </ul>
3339 </ul>
3339 </div>
3340 </div>
3340
3341
3341 <div class="main">
3342 <div class="main">
3342 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3343 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3343 <h3>Help: dates</h3>
3344 <h3>Help: dates</h3>
3344
3345
3345 <form class="search" action="/log">
3346 <form class="search" action="/log">
3346
3347
3347 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3348 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3348 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3349 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3349 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3350 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3350 </form>
3351 </form>
3351 <div id="doc">
3352 <div id="doc">
3352 <h1>Date Formats</h1>
3353 <h1>Date Formats</h1>
3353 <p>
3354 <p>
3354 Some commands allow the user to specify a date, e.g.:
3355 Some commands allow the user to specify a date, e.g.:
3355 </p>
3356 </p>
3356 <ul>
3357 <ul>
3357 <li> backout, commit, import, tag: Specify the commit date.
3358 <li> backout, commit, import, tag: Specify the commit date.
3358 <li> log, revert, update: Select revision(s) by date.
3359 <li> log, revert, update: Select revision(s) by date.
3359 </ul>
3360 </ul>
3360 <p>
3361 <p>
3361 Many date formats are valid. Here are some examples:
3362 Many date formats are valid. Here are some examples:
3362 </p>
3363 </p>
3363 <ul>
3364 <ul>
3364 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3365 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3365 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3366 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3366 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3367 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3367 <li> &quot;Dec 6&quot; (midnight)
3368 <li> &quot;Dec 6&quot; (midnight)
3368 <li> &quot;13:18&quot; (today assumed)
3369 <li> &quot;13:18&quot; (today assumed)
3369 <li> &quot;3:39&quot; (3:39AM assumed)
3370 <li> &quot;3:39&quot; (3:39AM assumed)
3370 <li> &quot;3:39pm&quot; (15:39)
3371 <li> &quot;3:39pm&quot; (15:39)
3371 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3372 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3372 <li> &quot;2006-12-6 13:18&quot;
3373 <li> &quot;2006-12-6 13:18&quot;
3373 <li> &quot;2006-12-6&quot;
3374 <li> &quot;2006-12-6&quot;
3374 <li> &quot;12-6&quot;
3375 <li> &quot;12-6&quot;
3375 <li> &quot;12/6&quot;
3376 <li> &quot;12/6&quot;
3376 <li> &quot;12/6/6&quot; (Dec 6 2006)
3377 <li> &quot;12/6/6&quot; (Dec 6 2006)
3377 <li> &quot;today&quot; (midnight)
3378 <li> &quot;today&quot; (midnight)
3378 <li> &quot;yesterday&quot; (midnight)
3379 <li> &quot;yesterday&quot; (midnight)
3379 <li> &quot;now&quot; - right now
3380 <li> &quot;now&quot; - right now
3380 </ul>
3381 </ul>
3381 <p>
3382 <p>
3382 Lastly, there is Mercurial's internal format:
3383 Lastly, there is Mercurial's internal format:
3383 </p>
3384 </p>
3384 <ul>
3385 <ul>
3385 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3386 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3386 </ul>
3387 </ul>
3387 <p>
3388 <p>
3388 This is the internal representation format for dates. The first number
3389 This is the internal representation format for dates. The first number
3389 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3390 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3390 second is the offset of the local timezone, in seconds west of UTC
3391 second is the offset of the local timezone, in seconds west of UTC
3391 (negative if the timezone is east of UTC).
3392 (negative if the timezone is east of UTC).
3392 </p>
3393 </p>
3393 <p>
3394 <p>
3394 The log command also accepts date ranges:
3395 The log command also accepts date ranges:
3395 </p>
3396 </p>
3396 <ul>
3397 <ul>
3397 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3398 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3398 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3399 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3399 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3400 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3400 <li> &quot;-DAYS&quot; - within a given number of days from today
3401 <li> &quot;-DAYS&quot; - within a given number of days from today
3401 </ul>
3402 </ul>
3402
3403
3403 </div>
3404 </div>
3404 </div>
3405 </div>
3405 </div>
3406 </div>
3406
3407
3407
3408
3408
3409
3409 </body>
3410 </body>
3410 </html>
3411 </html>
3411
3412
3412
3413
3413 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3414 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3414 200 Script output follows
3415 200 Script output follows
3415
3416
3416 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3417 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3417 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3418 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3418 <head>
3419 <head>
3419 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3420 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3420 <meta name="robots" content="index, nofollow" />
3421 <meta name="robots" content="index, nofollow" />
3421 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3422 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3422 <script type="text/javascript" src="/static/mercurial.js"></script>
3423 <script type="text/javascript" src="/static/mercurial.js"></script>
3423
3424
3424 <title>Help: pager</title>
3425 <title>Help: pager</title>
3425 </head>
3426 </head>
3426 <body>
3427 <body>
3427
3428
3428 <div class="container">
3429 <div class="container">
3429 <div class="menu">
3430 <div class="menu">
3430 <div class="logo">
3431 <div class="logo">
3431 <a href="https://mercurial-scm.org/">
3432 <a href="https://mercurial-scm.org/">
3432 <img src="/static/hglogo.png" alt="mercurial" /></a>
3433 <img src="/static/hglogo.png" alt="mercurial" /></a>
3433 </div>
3434 </div>
3434 <ul>
3435 <ul>
3435 <li><a href="/shortlog">log</a></li>
3436 <li><a href="/shortlog">log</a></li>
3436 <li><a href="/graph">graph</a></li>
3437 <li><a href="/graph">graph</a></li>
3437 <li><a href="/tags">tags</a></li>
3438 <li><a href="/tags">tags</a></li>
3438 <li><a href="/bookmarks">bookmarks</a></li>
3439 <li><a href="/bookmarks">bookmarks</a></li>
3439 <li><a href="/branches">branches</a></li>
3440 <li><a href="/branches">branches</a></li>
3440 </ul>
3441 </ul>
3441 <ul>
3442 <ul>
3442 <li class="active"><a href="/help">help</a></li>
3443 <li class="active"><a href="/help">help</a></li>
3443 </ul>
3444 </ul>
3444 </div>
3445 </div>
3445
3446
3446 <div class="main">
3447 <div class="main">
3447 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3448 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3448 <h3>Help: pager</h3>
3449 <h3>Help: pager</h3>
3449
3450
3450 <form class="search" action="/log">
3451 <form class="search" action="/log">
3451
3452
3452 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3453 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3453 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3454 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3454 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3455 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3455 </form>
3456 </form>
3456 <div id="doc">
3457 <div id="doc">
3457 <h1>Pager Support</h1>
3458 <h1>Pager Support</h1>
3458 <p>
3459 <p>
3459 Some Mercurial commands can produce a lot of output, and Mercurial will
3460 Some Mercurial commands can produce a lot of output, and Mercurial will
3460 attempt to use a pager to make those commands more pleasant.
3461 attempt to use a pager to make those commands more pleasant.
3461 </p>
3462 </p>
3462 <p>
3463 <p>
3463 To set the pager that should be used, set the application variable:
3464 To set the pager that should be used, set the application variable:
3464 </p>
3465 </p>
3465 <pre>
3466 <pre>
3466 [pager]
3467 [pager]
3467 pager = less -FRX
3468 pager = less -FRX
3468 </pre>
3469 </pre>
3469 <p>
3470 <p>
3470 If no pager is set in the user or repository configuration, Mercurial uses the
3471 If no pager is set in the user or repository configuration, Mercurial uses the
3471 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3472 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3472 or system configuration is used. If none of these are set, a default pager will
3473 or system configuration is used. If none of these are set, a default pager will
3473 be used, typically 'less' on Unix and 'more' on Windows.
3474 be used, typically 'less' on Unix and 'more' on Windows.
3474 </p>
3475 </p>
3475 <p>
3476 <p>
3476 You can disable the pager for certain commands by adding them to the
3477 You can disable the pager for certain commands by adding them to the
3477 pager.ignore list:
3478 pager.ignore list:
3478 </p>
3479 </p>
3479 <pre>
3480 <pre>
3480 [pager]
3481 [pager]
3481 ignore = version, help, update
3482 ignore = version, help, update
3482 </pre>
3483 </pre>
3483 <p>
3484 <p>
3484 To ignore global commands like 'hg version' or 'hg help', you have
3485 To ignore global commands like 'hg version' or 'hg help', you have
3485 to specify them in your user configuration file.
3486 to specify them in your user configuration file.
3486 </p>
3487 </p>
3487 <p>
3488 <p>
3488 To control whether the pager is used at all for an individual command,
3489 To control whether the pager is used at all for an individual command,
3489 you can use --pager=&lt;value&gt;:
3490 you can use --pager=&lt;value&gt;:
3490 </p>
3491 </p>
3491 <ul>
3492 <ul>
3492 <li> use as needed: 'auto'.
3493 <li> use as needed: 'auto'.
3493 <li> require the pager: 'yes' or 'on'.
3494 <li> require the pager: 'yes' or 'on'.
3494 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3495 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3495 </ul>
3496 </ul>
3496 <p>
3497 <p>
3497 To globally turn off all attempts to use a pager, set:
3498 To globally turn off all attempts to use a pager, set:
3498 </p>
3499 </p>
3499 <pre>
3500 <pre>
3500 [ui]
3501 [ui]
3501 paginate = never
3502 paginate = never
3502 </pre>
3503 </pre>
3503 <p>
3504 <p>
3504 which will prevent the pager from running.
3505 which will prevent the pager from running.
3505 </p>
3506 </p>
3506
3507
3507 </div>
3508 </div>
3508 </div>
3509 </div>
3509 </div>
3510 </div>
3510
3511
3511
3512
3512
3513
3513 </body>
3514 </body>
3514 </html>
3515 </html>
3515
3516
3516
3517
3517 Sub-topic indexes rendered properly
3518 Sub-topic indexes rendered properly
3518
3519
3519 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3520 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3520 200 Script output follows
3521 200 Script output follows
3521
3522
3522 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3523 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3523 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3524 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3524 <head>
3525 <head>
3525 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3526 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3526 <meta name="robots" content="index, nofollow" />
3527 <meta name="robots" content="index, nofollow" />
3527 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3528 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3528 <script type="text/javascript" src="/static/mercurial.js"></script>
3529 <script type="text/javascript" src="/static/mercurial.js"></script>
3529
3530
3530 <title>Help: internals</title>
3531 <title>Help: internals</title>
3531 </head>
3532 </head>
3532 <body>
3533 <body>
3533
3534
3534 <div class="container">
3535 <div class="container">
3535 <div class="menu">
3536 <div class="menu">
3536 <div class="logo">
3537 <div class="logo">
3537 <a href="https://mercurial-scm.org/">
3538 <a href="https://mercurial-scm.org/">
3538 <img src="/static/hglogo.png" alt="mercurial" /></a>
3539 <img src="/static/hglogo.png" alt="mercurial" /></a>
3539 </div>
3540 </div>
3540 <ul>
3541 <ul>
3541 <li><a href="/shortlog">log</a></li>
3542 <li><a href="/shortlog">log</a></li>
3542 <li><a href="/graph">graph</a></li>
3543 <li><a href="/graph">graph</a></li>
3543 <li><a href="/tags">tags</a></li>
3544 <li><a href="/tags">tags</a></li>
3544 <li><a href="/bookmarks">bookmarks</a></li>
3545 <li><a href="/bookmarks">bookmarks</a></li>
3545 <li><a href="/branches">branches</a></li>
3546 <li><a href="/branches">branches</a></li>
3546 </ul>
3547 </ul>
3547 <ul>
3548 <ul>
3548 <li><a href="/help">help</a></li>
3549 <li><a href="/help">help</a></li>
3549 </ul>
3550 </ul>
3550 </div>
3551 </div>
3551
3552
3552 <div class="main">
3553 <div class="main">
3553 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3554 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3554
3555
3555 <form class="search" action="/log">
3556 <form class="search" action="/log">
3556
3557
3557 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3558 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3558 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3559 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3559 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3560 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3560 </form>
3561 </form>
3561 <table class="bigtable">
3562 <table class="bigtable">
3562 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3563 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3563
3564
3564 <tr><td>
3565 <tr><td>
3565 <a href="/help/internals.bid-merge">
3566 <a href="/help/internals.bid-merge">
3566 bid-merge
3567 bid-merge
3567 </a>
3568 </a>
3568 </td><td>
3569 </td><td>
3569 Bid Merge Algorithm
3570 Bid Merge Algorithm
3570 </td></tr>
3571 </td></tr>
3571 <tr><td>
3572 <tr><td>
3572 <a href="/help/internals.bundle2">
3573 <a href="/help/internals.bundle2">
3573 bundle2
3574 bundle2
3574 </a>
3575 </a>
3575 </td><td>
3576 </td><td>
3576 Bundle2
3577 Bundle2
3577 </td></tr>
3578 </td></tr>
3578 <tr><td>
3579 <tr><td>
3579 <a href="/help/internals.bundles">
3580 <a href="/help/internals.bundles">
3580 bundles
3581 bundles
3581 </a>
3582 </a>
3582 </td><td>
3583 </td><td>
3583 Bundles
3584 Bundles
3584 </td></tr>
3585 </td></tr>
3585 <tr><td>
3586 <tr><td>
3586 <a href="/help/internals.cbor">
3587 <a href="/help/internals.cbor">
3587 cbor
3588 cbor
3588 </a>
3589 </a>
3589 </td><td>
3590 </td><td>
3590 CBOR
3591 CBOR
3591 </td></tr>
3592 </td></tr>
3592 <tr><td>
3593 <tr><td>
3593 <a href="/help/internals.censor">
3594 <a href="/help/internals.censor">
3594 censor
3595 censor
3595 </a>
3596 </a>
3596 </td><td>
3597 </td><td>
3597 Censor
3598 Censor
3598 </td></tr>
3599 </td></tr>
3599 <tr><td>
3600 <tr><td>
3600 <a href="/help/internals.changegroups">
3601 <a href="/help/internals.changegroups">
3601 changegroups
3602 changegroups
3602 </a>
3603 </a>
3603 </td><td>
3604 </td><td>
3604 Changegroups
3605 Changegroups
3605 </td></tr>
3606 </td></tr>
3606 <tr><td>
3607 <tr><td>
3607 <a href="/help/internals.config">
3608 <a href="/help/internals.config">
3608 config
3609 config
3609 </a>
3610 </a>
3610 </td><td>
3611 </td><td>
3611 Config Registrar
3612 Config Registrar
3612 </td></tr>
3613 </td></tr>
3613 <tr><td>
3614 <tr><td>
3614 <a href="/help/internals.dirstate-v2">
3615 <a href="/help/internals.dirstate-v2">
3615 dirstate-v2
3616 dirstate-v2
3616 </a>
3617 </a>
3617 </td><td>
3618 </td><td>
3618 dirstate-v2 file format
3619 dirstate-v2 file format
3619 </td></tr>
3620 </td></tr>
3620 <tr><td>
3621 <tr><td>
3621 <a href="/help/internals.extensions">
3622 <a href="/help/internals.extensions">
3622 extensions
3623 extensions
3623 </a>
3624 </a>
3624 </td><td>
3625 </td><td>
3625 Extension API
3626 Extension API
3626 </td></tr>
3627 </td></tr>
3627 <tr><td>
3628 <tr><td>
3628 <a href="/help/internals.mergestate">
3629 <a href="/help/internals.mergestate">
3629 mergestate
3630 mergestate
3630 </a>
3631 </a>
3631 </td><td>
3632 </td><td>
3632 Mergestate
3633 Mergestate
3633 </td></tr>
3634 </td></tr>
3634 <tr><td>
3635 <tr><td>
3635 <a href="/help/internals.requirements">
3636 <a href="/help/internals.requirements">
3636 requirements
3637 requirements
3637 </a>
3638 </a>
3638 </td><td>
3639 </td><td>
3639 Repository Requirements
3640 Repository Requirements
3640 </td></tr>
3641 </td></tr>
3641 <tr><td>
3642 <tr><td>
3642 <a href="/help/internals.revlogs">
3643 <a href="/help/internals.revlogs">
3643 revlogs
3644 revlogs
3644 </a>
3645 </a>
3645 </td><td>
3646 </td><td>
3646 Revision Logs
3647 Revision Logs
3647 </td></tr>
3648 </td></tr>
3648 <tr><td>
3649 <tr><td>
3649 <a href="/help/internals.wireprotocol">
3650 <a href="/help/internals.wireprotocol">
3650 wireprotocol
3651 wireprotocol
3651 </a>
3652 </a>
3652 </td><td>
3653 </td><td>
3653 Wire Protocol
3654 Wire Protocol
3654 </td></tr>
3655 </td></tr>
3655 <tr><td>
3656 <tr><td>
3656 <a href="/help/internals.wireprotocolrpc">
3657 <a href="/help/internals.wireprotocolrpc">
3657 wireprotocolrpc
3658 wireprotocolrpc
3658 </a>
3659 </a>
3659 </td><td>
3660 </td><td>
3660 Wire Protocol RPC
3661 Wire Protocol RPC
3661 </td></tr>
3662 </td></tr>
3662 <tr><td>
3663 <tr><td>
3663 <a href="/help/internals.wireprotocolv2">
3664 <a href="/help/internals.wireprotocolv2">
3664 wireprotocolv2
3665 wireprotocolv2
3665 </a>
3666 </a>
3666 </td><td>
3667 </td><td>
3667 Wire Protocol Version 2
3668 Wire Protocol Version 2
3668 </td></tr>
3669 </td></tr>
3669
3670
3670
3671
3671
3672
3672
3673
3673
3674
3674 </table>
3675 </table>
3675 </div>
3676 </div>
3676 </div>
3677 </div>
3677
3678
3678
3679
3679
3680
3680 </body>
3681 </body>
3681 </html>
3682 </html>
3682
3683
3683
3684
3684 Sub-topic topics rendered properly
3685 Sub-topic topics rendered properly
3685
3686
3686 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3687 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3687 200 Script output follows
3688 200 Script output follows
3688
3689
3689 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3690 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3690 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3691 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3691 <head>
3692 <head>
3692 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3693 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3693 <meta name="robots" content="index, nofollow" />
3694 <meta name="robots" content="index, nofollow" />
3694 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3695 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3695 <script type="text/javascript" src="/static/mercurial.js"></script>
3696 <script type="text/javascript" src="/static/mercurial.js"></script>
3696
3697
3697 <title>Help: internals.changegroups</title>
3698 <title>Help: internals.changegroups</title>
3698 </head>
3699 </head>
3699 <body>
3700 <body>
3700
3701
3701 <div class="container">
3702 <div class="container">
3702 <div class="menu">
3703 <div class="menu">
3703 <div class="logo">
3704 <div class="logo">
3704 <a href="https://mercurial-scm.org/">
3705 <a href="https://mercurial-scm.org/">
3705 <img src="/static/hglogo.png" alt="mercurial" /></a>
3706 <img src="/static/hglogo.png" alt="mercurial" /></a>
3706 </div>
3707 </div>
3707 <ul>
3708 <ul>
3708 <li><a href="/shortlog">log</a></li>
3709 <li><a href="/shortlog">log</a></li>
3709 <li><a href="/graph">graph</a></li>
3710 <li><a href="/graph">graph</a></li>
3710 <li><a href="/tags">tags</a></li>
3711 <li><a href="/tags">tags</a></li>
3711 <li><a href="/bookmarks">bookmarks</a></li>
3712 <li><a href="/bookmarks">bookmarks</a></li>
3712 <li><a href="/branches">branches</a></li>
3713 <li><a href="/branches">branches</a></li>
3713 </ul>
3714 </ul>
3714 <ul>
3715 <ul>
3715 <li class="active"><a href="/help">help</a></li>
3716 <li class="active"><a href="/help">help</a></li>
3716 </ul>
3717 </ul>
3717 </div>
3718 </div>
3718
3719
3719 <div class="main">
3720 <div class="main">
3720 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3721 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3721 <h3>Help: internals.changegroups</h3>
3722 <h3>Help: internals.changegroups</h3>
3722
3723
3723 <form class="search" action="/log">
3724 <form class="search" action="/log">
3724
3725
3725 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3726 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3726 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3727 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3727 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3728 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3728 </form>
3729 </form>
3729 <div id="doc">
3730 <div id="doc">
3730 <h1>Changegroups</h1>
3731 <h1>Changegroups</h1>
3731 <p>
3732 <p>
3732 Changegroups are representations of repository revlog data, specifically
3733 Changegroups are representations of repository revlog data, specifically
3733 the changelog data, root/flat manifest data, treemanifest data, and
3734 the changelog data, root/flat manifest data, treemanifest data, and
3734 filelogs.
3735 filelogs.
3735 </p>
3736 </p>
3736 <p>
3737 <p>
3737 There are 4 versions of changegroups: &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;. From a
3738 There are 4 versions of changegroups: &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;. From a
3738 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3739 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3739 only difference being an additional item in the *delta header*. Version
3740 only difference being an additional item in the *delta header*. Version
3740 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3741 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3741 exchanging treemanifests (enabled by setting an option on the
3742 exchanging treemanifests (enabled by setting an option on the
3742 &quot;changegroup&quot; part in the bundle2). Version &quot;4&quot; adds support for exchanging
3743 &quot;changegroup&quot; part in the bundle2). Version &quot;4&quot; adds support for exchanging
3743 sidedata (additional revision metadata not part of the digest).
3744 sidedata (additional revision metadata not part of the digest).
3744 </p>
3745 </p>
3745 <p>
3746 <p>
3746 Changegroups when not exchanging treemanifests consist of 3 logical
3747 Changegroups when not exchanging treemanifests consist of 3 logical
3747 segments:
3748 segments:
3748 </p>
3749 </p>
3749 <pre>
3750 <pre>
3750 +---------------------------------+
3751 +---------------------------------+
3751 | | | |
3752 | | | |
3752 | changeset | manifest | filelogs |
3753 | changeset | manifest | filelogs |
3753 | | | |
3754 | | | |
3754 | | | |
3755 | | | |
3755 +---------------------------------+
3756 +---------------------------------+
3756 </pre>
3757 </pre>
3757 <p>
3758 <p>
3758 When exchanging treemanifests, there are 4 logical segments:
3759 When exchanging treemanifests, there are 4 logical segments:
3759 </p>
3760 </p>
3760 <pre>
3761 <pre>
3761 +-------------------------------------------------+
3762 +-------------------------------------------------+
3762 | | | | |
3763 | | | | |
3763 | changeset | root | treemanifests | filelogs |
3764 | changeset | root | treemanifests | filelogs |
3764 | | manifest | | |
3765 | | manifest | | |
3765 | | | | |
3766 | | | | |
3766 +-------------------------------------------------+
3767 +-------------------------------------------------+
3767 </pre>
3768 </pre>
3768 <p>
3769 <p>
3769 The principle building block of each segment is a *chunk*. A *chunk*
3770 The principle building block of each segment is a *chunk*. A *chunk*
3770 is a framed piece of data:
3771 is a framed piece of data:
3771 </p>
3772 </p>
3772 <pre>
3773 <pre>
3773 +---------------------------------------+
3774 +---------------------------------------+
3774 | | |
3775 | | |
3775 | length | data |
3776 | length | data |
3776 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3777 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3777 | | |
3778 | | |
3778 +---------------------------------------+
3779 +---------------------------------------+
3779 </pre>
3780 </pre>
3780 <p>
3781 <p>
3781 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3782 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3782 integer indicating the length of the entire chunk (including the length field
3783 integer indicating the length of the entire chunk (including the length field
3783 itself).
3784 itself).
3784 </p>
3785 </p>
3785 <p>
3786 <p>
3786 There is a special case chunk that has a value of 0 for the length
3787 There is a special case chunk that has a value of 0 for the length
3787 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3788 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3788 </p>
3789 </p>
3789 <h2>Delta Groups</h2>
3790 <h2>Delta Groups</h2>
3790 <p>
3791 <p>
3791 A *delta group* expresses the content of a revlog as a series of deltas,
3792 A *delta group* expresses the content of a revlog as a series of deltas,
3792 or patches against previous revisions.
3793 or patches against previous revisions.
3793 </p>
3794 </p>
3794 <p>
3795 <p>
3795 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3796 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3796 to signal the end of the delta group:
3797 to signal the end of the delta group:
3797 </p>
3798 </p>
3798 <pre>
3799 <pre>
3799 +------------------------------------------------------------------------+
3800 +------------------------------------------------------------------------+
3800 | | | | | |
3801 | | | | | |
3801 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3802 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3802 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3803 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3803 | | | | | |
3804 | | | | | |
3804 +------------------------------------------------------------------------+
3805 +------------------------------------------------------------------------+
3805 </pre>
3806 </pre>
3806 <p>
3807 <p>
3807 Each *chunk*'s data consists of the following:
3808 Each *chunk*'s data consists of the following:
3808 </p>
3809 </p>
3809 <pre>
3810 <pre>
3810 +---------------------------------------+
3811 +---------------------------------------+
3811 | | |
3812 | | |
3812 | delta header | delta data |
3813 | delta header | delta data |
3813 | (various by version) | (various) |
3814 | (various by version) | (various) |
3814 | | |
3815 | | |
3815 +---------------------------------------+
3816 +---------------------------------------+
3816 </pre>
3817 </pre>
3817 <p>
3818 <p>
3818 The *delta data* is a series of *delta*s that describe a diff from an existing
3819 The *delta data* is a series of *delta*s that describe a diff from an existing
3819 entry (either that the recipient already has, or previously specified in the
3820 entry (either that the recipient already has, or previously specified in the
3820 bundle/changegroup).
3821 bundle/changegroup).
3821 </p>
3822 </p>
3822 <p>
3823 <p>
3823 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;
3824 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;
3824 of the changegroup format.
3825 of the changegroup format.
3825 </p>
3826 </p>
3826 <p>
3827 <p>
3827 Version 1 (headerlen=80):
3828 Version 1 (headerlen=80):
3828 </p>
3829 </p>
3829 <pre>
3830 <pre>
3830 +------------------------------------------------------+
3831 +------------------------------------------------------+
3831 | | | | |
3832 | | | | |
3832 | node | p1 node | p2 node | link node |
3833 | node | p1 node | p2 node | link node |
3833 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3834 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3834 | | | | |
3835 | | | | |
3835 +------------------------------------------------------+
3836 +------------------------------------------------------+
3836 </pre>
3837 </pre>
3837 <p>
3838 <p>
3838 Version 2 (headerlen=100):
3839 Version 2 (headerlen=100):
3839 </p>
3840 </p>
3840 <pre>
3841 <pre>
3841 +------------------------------------------------------------------+
3842 +------------------------------------------------------------------+
3842 | | | | | |
3843 | | | | | |
3843 | node | p1 node | p2 node | base node | link node |
3844 | node | p1 node | p2 node | base node | link node |
3844 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3845 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3845 | | | | | |
3846 | | | | | |
3846 +------------------------------------------------------------------+
3847 +------------------------------------------------------------------+
3847 </pre>
3848 </pre>
3848 <p>
3849 <p>
3849 Version 3 (headerlen=102):
3850 Version 3 (headerlen=102):
3850 </p>
3851 </p>
3851 <pre>
3852 <pre>
3852 +------------------------------------------------------------------------------+
3853 +------------------------------------------------------------------------------+
3853 | | | | | | |
3854 | | | | | | |
3854 | node | p1 node | p2 node | base node | link node | flags |
3855 | node | p1 node | p2 node | base node | link node | flags |
3855 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3856 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3856 | | | | | | |
3857 | | | | | | |
3857 +------------------------------------------------------------------------------+
3858 +------------------------------------------------------------------------------+
3858 </pre>
3859 </pre>
3859 <p>
3860 <p>
3860 Version 4 (headerlen=103):
3861 Version 4 (headerlen=103):
3861 </p>
3862 </p>
3862 <pre>
3863 <pre>
3863 +------------------------------------------------------------------------------+----------+
3864 +------------------------------------------------------------------------------+----------+
3864 | | | | | | | |
3865 | | | | | | | |
3865 | node | p1 node | p2 node | base node | link node | flags | pflags |
3866 | node | p1 node | p2 node | base node | link node | flags | pflags |
3866 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
3867 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
3867 | | | | | | | |
3868 | | | | | | | |
3868 +------------------------------------------------------------------------------+----------+
3869 +------------------------------------------------------------------------------+----------+
3869 </pre>
3870 </pre>
3870 <p>
3871 <p>
3871 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3872 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3872 series of *delta*s, densely packed (no separators). These deltas describe a diff
3873 series of *delta*s, densely packed (no separators). These deltas describe a diff
3873 from an existing entry (either that the recipient already has, or previously
3874 from an existing entry (either that the recipient already has, or previously
3874 specified in the bundle/changegroup). The format is described more fully in
3875 specified in the bundle/changegroup). The format is described more fully in
3875 &quot;hg help internals.bdiff&quot;, but briefly:
3876 &quot;hg help internals.bdiff&quot;, but briefly:
3876 </p>
3877 </p>
3877 <pre>
3878 <pre>
3878 +---------------------------------------------------------------+
3879 +---------------------------------------------------------------+
3879 | | | | |
3880 | | | | |
3880 | start offset | end offset | new length | content |
3881 | start offset | end offset | new length | content |
3881 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3882 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3882 | | | | |
3883 | | | | |
3883 +---------------------------------------------------------------+
3884 +---------------------------------------------------------------+
3884 </pre>
3885 </pre>
3885 <p>
3886 <p>
3886 Please note that the length field in the delta data does *not* include itself.
3887 Please note that the length field in the delta data does *not* include itself.
3887 </p>
3888 </p>
3888 <p>
3889 <p>
3889 In version 1, the delta is always applied against the previous node from
3890 In version 1, the delta is always applied against the previous node from
3890 the changegroup or the first parent if this is the first entry in the
3891 the changegroup or the first parent if this is the first entry in the
3891 changegroup.
3892 changegroup.
3892 </p>
3893 </p>
3893 <p>
3894 <p>
3894 In version 2 and up, the delta base node is encoded in the entry in the
3895 In version 2 and up, the delta base node is encoded in the entry in the
3895 changegroup. This allows the delta to be expressed against any parent,
3896 changegroup. This allows the delta to be expressed against any parent,
3896 which can result in smaller deltas and more efficient encoding of data.
3897 which can result in smaller deltas and more efficient encoding of data.
3897 </p>
3898 </p>
3898 <p>
3899 <p>
3899 The *flags* field holds bitwise flags affecting the processing of revision
3900 The *flags* field holds bitwise flags affecting the processing of revision
3900 data. The following flags are defined:
3901 data. The following flags are defined:
3901 </p>
3902 </p>
3902 <dl>
3903 <dl>
3903 <dt>32768
3904 <dt>32768
3904 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3905 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3905 <dt>16384
3906 <dt>16384
3906 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3907 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3907 <dt>8192
3908 <dt>8192
3908 <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.
3909 <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.
3909 <dt>4096
3910 <dt>4096
3910 <dd>Contains copy information. This revision changes files in a way that could affect copy tracing. This does *not* affect changegroup handling, but is relevant for other parts of Mercurial.
3911 <dd>Contains copy information. This revision changes files in a way that could affect copy tracing. This does *not* affect changegroup handling, but is relevant for other parts of Mercurial.
3911 </dl>
3912 </dl>
3912 <p>
3913 <p>
3913 For historical reasons, the integer values are identical to revlog version 1
3914 For historical reasons, the integer values are identical to revlog version 1
3914 per-revision storage flags and correspond to bits being set in this 2-byte
3915 per-revision storage flags and correspond to bits being set in this 2-byte
3915 field. Bits were allocated starting from the most-significant bit, hence the
3916 field. Bits were allocated starting from the most-significant bit, hence the
3916 reverse ordering and allocation of these flags.
3917 reverse ordering and allocation of these flags.
3917 </p>
3918 </p>
3918 <p>
3919 <p>
3919 The *pflags* (protocol flags) field holds bitwise flags affecting the protocol
3920 The *pflags* (protocol flags) field holds bitwise flags affecting the protocol
3920 itself. They are first in the header since they may affect the handling of the
3921 itself. They are first in the header since they may affect the handling of the
3921 rest of the fields in a future version. They are defined as such:
3922 rest of the fields in a future version. They are defined as such:
3922 </p>
3923 </p>
3923 <dl>
3924 <dl>
3924 <dt>1 indicates whether to read a chunk of sidedata (of variable length) right
3925 <dt>1 indicates whether to read a chunk of sidedata (of variable length) right
3925 <dd>after the revision flags.
3926 <dd>after the revision flags.
3926 </dl>
3927 </dl>
3927 <h2>Changeset Segment</h2>
3928 <h2>Changeset Segment</h2>
3928 <p>
3929 <p>
3929 The *changeset segment* consists of a single *delta group* holding
3930 The *changeset segment* consists of a single *delta group* holding
3930 changelog data. The *empty chunk* at the end of the *delta group* denotes
3931 changelog data. The *empty chunk* at the end of the *delta group* denotes
3931 the boundary to the *manifest segment*.
3932 the boundary to the *manifest segment*.
3932 </p>
3933 </p>
3933 <h2>Manifest Segment</h2>
3934 <h2>Manifest Segment</h2>
3934 <p>
3935 <p>
3935 The *manifest segment* consists of a single *delta group* holding manifest
3936 The *manifest segment* consists of a single *delta group* holding manifest
3936 data. If treemanifests are in use, it contains only the manifest for the
3937 data. If treemanifests are in use, it contains only the manifest for the
3937 root directory of the repository. Otherwise, it contains the entire
3938 root directory of the repository. Otherwise, it contains the entire
3938 manifest data. The *empty chunk* at the end of the *delta group* denotes
3939 manifest data. The *empty chunk* at the end of the *delta group* denotes
3939 the boundary to the next segment (either the *treemanifests segment* or the
3940 the boundary to the next segment (either the *treemanifests segment* or the
3940 *filelogs segment*, depending on version and the request options).
3941 *filelogs segment*, depending on version and the request options).
3941 </p>
3942 </p>
3942 <h3>Treemanifests Segment</h3>
3943 <h3>Treemanifests Segment</h3>
3943 <p>
3944 <p>
3944 The *treemanifests segment* only exists in changegroup version &quot;3&quot; and &quot;4&quot;,
3945 The *treemanifests segment* only exists in changegroup version &quot;3&quot; and &quot;4&quot;,
3945 and only if the 'treemanifest' param is part of the bundle2 changegroup part
3946 and only if the 'treemanifest' param is part of the bundle2 changegroup part
3946 (it is not possible to use changegroup version 3 or 4 outside of bundle2).
3947 (it is not possible to use changegroup version 3 or 4 outside of bundle2).
3947 Aside from the filenames in the *treemanifests segment* containing a
3948 Aside from the filenames in the *treemanifests segment* containing a
3948 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3949 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3949 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3950 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3950 a sub-segment with filename size 0). This denotes the boundary to the
3951 a sub-segment with filename size 0). This denotes the boundary to the
3951 *filelogs segment*.
3952 *filelogs segment*.
3952 </p>
3953 </p>
3953 <h2>Filelogs Segment</h2>
3954 <h2>Filelogs Segment</h2>
3954 <p>
3955 <p>
3955 The *filelogs segment* consists of multiple sub-segments, each
3956 The *filelogs segment* consists of multiple sub-segments, each
3956 corresponding to an individual file whose data is being described:
3957 corresponding to an individual file whose data is being described:
3957 </p>
3958 </p>
3958 <pre>
3959 <pre>
3959 +--------------------------------------------------+
3960 +--------------------------------------------------+
3960 | | | | | |
3961 | | | | | |
3961 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3962 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3962 | | | | | (4 bytes) |
3963 | | | | | (4 bytes) |
3963 | | | | | |
3964 | | | | | |
3964 +--------------------------------------------------+
3965 +--------------------------------------------------+
3965 </pre>
3966 </pre>
3966 <p>
3967 <p>
3967 The final filelog sub-segment is followed by an *empty chunk* (logically,
3968 The final filelog sub-segment is followed by an *empty chunk* (logically,
3968 a sub-segment with filename size 0). This denotes the end of the segment
3969 a sub-segment with filename size 0). This denotes the end of the segment
3969 and of the overall changegroup.
3970 and of the overall changegroup.
3970 </p>
3971 </p>
3971 <p>
3972 <p>
3972 Each filelog sub-segment consists of the following:
3973 Each filelog sub-segment consists of the following:
3973 </p>
3974 </p>
3974 <pre>
3975 <pre>
3975 +------------------------------------------------------+
3976 +------------------------------------------------------+
3976 | | | |
3977 | | | |
3977 | filename length | filename | delta group |
3978 | filename length | filename | delta group |
3978 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3979 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3979 | | | |
3980 | | | |
3980 +------------------------------------------------------+
3981 +------------------------------------------------------+
3981 </pre>
3982 </pre>
3982 <p>
3983 <p>
3983 That is, a *chunk* consisting of the filename (not terminated or padded)
3984 That is, a *chunk* consisting of the filename (not terminated or padded)
3984 followed by N chunks constituting the *delta group* for this file. The
3985 followed by N chunks constituting the *delta group* for this file. The
3985 *empty chunk* at the end of each *delta group* denotes the boundary to the
3986 *empty chunk* at the end of each *delta group* denotes the boundary to the
3986 next filelog sub-segment.
3987 next filelog sub-segment.
3987 </p>
3988 </p>
3988
3989
3989 </div>
3990 </div>
3990 </div>
3991 </div>
3991 </div>
3992 </div>
3992
3993
3993
3994
3994
3995
3995 </body>
3996 </body>
3996 </html>
3997 </html>
3997
3998
3998
3999
3999 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
4000 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
4000 404 Not Found
4001 404 Not Found
4001
4002
4002 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4003 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4003 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
4004 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
4004 <head>
4005 <head>
4005 <link rel="icon" href="/static/hgicon.png" type="image/png" />
4006 <link rel="icon" href="/static/hgicon.png" type="image/png" />
4006 <meta name="robots" content="index, nofollow" />
4007 <meta name="robots" content="index, nofollow" />
4007 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
4008 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
4008 <script type="text/javascript" src="/static/mercurial.js"></script>
4009 <script type="text/javascript" src="/static/mercurial.js"></script>
4009
4010
4010 <title>test: error</title>
4011 <title>test: error</title>
4011 </head>
4012 </head>
4012 <body>
4013 <body>
4013
4014
4014 <div class="container">
4015 <div class="container">
4015 <div class="menu">
4016 <div class="menu">
4016 <div class="logo">
4017 <div class="logo">
4017 <a href="https://mercurial-scm.org/">
4018 <a href="https://mercurial-scm.org/">
4018 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
4019 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
4019 </div>
4020 </div>
4020 <ul>
4021 <ul>
4021 <li><a href="/shortlog">log</a></li>
4022 <li><a href="/shortlog">log</a></li>
4022 <li><a href="/graph">graph</a></li>
4023 <li><a href="/graph">graph</a></li>
4023 <li><a href="/tags">tags</a></li>
4024 <li><a href="/tags">tags</a></li>
4024 <li><a href="/bookmarks">bookmarks</a></li>
4025 <li><a href="/bookmarks">bookmarks</a></li>
4025 <li><a href="/branches">branches</a></li>
4026 <li><a href="/branches">branches</a></li>
4026 </ul>
4027 </ul>
4027 <ul>
4028 <ul>
4028 <li><a href="/help">help</a></li>
4029 <li><a href="/help">help</a></li>
4029 </ul>
4030 </ul>
4030 </div>
4031 </div>
4031
4032
4032 <div class="main">
4033 <div class="main">
4033
4034
4034 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
4035 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
4035 <h3>error</h3>
4036 <h3>error</h3>
4036
4037
4037
4038
4038 <form class="search" action="/log">
4039 <form class="search" action="/log">
4039
4040
4040 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
4041 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
4041 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
4042 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
4042 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
4043 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
4043 </form>
4044 </form>
4044
4045
4045 <div class="description">
4046 <div class="description">
4046 <p>
4047 <p>
4047 An error occurred while processing your request:
4048 An error occurred while processing your request:
4048 </p>
4049 </p>
4049 <p>
4050 <p>
4050 Not Found
4051 Not Found
4051 </p>
4052 </p>
4052 </div>
4053 </div>
4053 </div>
4054 </div>
4054 </div>
4055 </div>
4055
4056
4056
4057
4057
4058
4058 </body>
4059 </body>
4059 </html>
4060 </html>
4060
4061
4061 [1]
4062 [1]
4062
4063
4063 $ killdaemons.py
4064 $ killdaemons.py
4064
4065
4065 #endif
4066 #endif
General Comments 0
You need to be logged in to leave comments. Login now