##// END OF EJS Templates
debugmergestate: make templated...
Martin von Zweigbergk -
r44841:088ab52a default draft
parent child Browse files
Show More
@@ -1,4367 +1,4330 b''
1 # debugcommands.py - command processing for debug* commands
1 # debugcommands.py - command processing for debug* commands
2 #
2 #
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import codecs
10 import codecs
11 import collections
11 import collections
12 import difflib
12 import difflib
13 import errno
13 import errno
14 import operator
14 import operator
15 import os
15 import os
16 import platform
16 import platform
17 import random
17 import random
18 import re
18 import re
19 import socket
19 import socket
20 import ssl
20 import ssl
21 import stat
21 import stat
22 import string
22 import string
23 import subprocess
23 import subprocess
24 import sys
24 import sys
25 import time
25 import time
26
26
27 from .i18n import _
27 from .i18n import _
28 from .node import (
28 from .node import (
29 bin,
29 bin,
30 hex,
30 hex,
31 nullhex,
32 nullid,
31 nullid,
33 nullrev,
32 nullrev,
34 short,
33 short,
35 )
34 )
36 from .pycompat import (
35 from .pycompat import (
37 getattr,
36 getattr,
38 open,
37 open,
39 )
38 )
40 from . import (
39 from . import (
41 bundle2,
40 bundle2,
42 changegroup,
41 changegroup,
43 cmdutil,
42 cmdutil,
44 color,
43 color,
45 context,
44 context,
46 copies,
45 copies,
47 dagparser,
46 dagparser,
48 encoding,
47 encoding,
49 error,
48 error,
50 exchange,
49 exchange,
51 extensions,
50 extensions,
52 filemerge,
51 filemerge,
53 filesetlang,
52 filesetlang,
54 formatter,
53 formatter,
55 hg,
54 hg,
56 httppeer,
55 httppeer,
57 localrepo,
56 localrepo,
58 lock as lockmod,
57 lock as lockmod,
59 logcmdutil,
58 logcmdutil,
60 merge as mergemod,
59 merge as mergemod,
61 obsolete,
60 obsolete,
62 obsutil,
61 obsutil,
63 pathutil,
62 pathutil,
64 phases,
63 phases,
65 policy,
64 policy,
66 pvec,
65 pvec,
67 pycompat,
66 pycompat,
68 registrar,
67 registrar,
69 repair,
68 repair,
70 revlog,
69 revlog,
71 revset,
70 revset,
72 revsetlang,
71 revsetlang,
73 scmutil,
72 scmutil,
74 setdiscovery,
73 setdiscovery,
75 simplemerge,
74 simplemerge,
76 sshpeer,
75 sshpeer,
77 sslutil,
76 sslutil,
78 streamclone,
77 streamclone,
79 tags as tagsmod,
78 tags as tagsmod,
80 templater,
79 templater,
81 treediscovery,
80 treediscovery,
82 upgrade,
81 upgrade,
83 url as urlmod,
82 url as urlmod,
84 util,
83 util,
85 vfs as vfsmod,
84 vfs as vfsmod,
86 wireprotoframing,
85 wireprotoframing,
87 wireprotoserver,
86 wireprotoserver,
88 wireprotov2peer,
87 wireprotov2peer,
89 )
88 )
90 from .utils import (
89 from .utils import (
91 cborutil,
90 cborutil,
92 compression,
91 compression,
93 dateutil,
92 dateutil,
94 procutil,
93 procutil,
95 stringutil,
94 stringutil,
96 )
95 )
97
96
98 from .revlogutils import (
97 from .revlogutils import (
99 deltas as deltautil,
98 deltas as deltautil,
100 nodemap,
99 nodemap,
101 )
100 )
102
101
103 release = lockmod.release
102 release = lockmod.release
104
103
105 command = registrar.command()
104 command = registrar.command()
106
105
107
106
108 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
107 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
109 def debugancestor(ui, repo, *args):
108 def debugancestor(ui, repo, *args):
110 """find the ancestor revision of two revisions in a given index"""
109 """find the ancestor revision of two revisions in a given index"""
111 if len(args) == 3:
110 if len(args) == 3:
112 index, rev1, rev2 = args
111 index, rev1, rev2 = args
113 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
112 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
114 lookup = r.lookup
113 lookup = r.lookup
115 elif len(args) == 2:
114 elif len(args) == 2:
116 if not repo:
115 if not repo:
117 raise error.Abort(
116 raise error.Abort(
118 _(b'there is no Mercurial repository here (.hg not found)')
117 _(b'there is no Mercurial repository here (.hg not found)')
119 )
118 )
120 rev1, rev2 = args
119 rev1, rev2 = args
121 r = repo.changelog
120 r = repo.changelog
122 lookup = repo.lookup
121 lookup = repo.lookup
123 else:
122 else:
124 raise error.Abort(_(b'either two or three arguments required'))
123 raise error.Abort(_(b'either two or three arguments required'))
125 a = r.ancestor(lookup(rev1), lookup(rev2))
124 a = r.ancestor(lookup(rev1), lookup(rev2))
126 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
125 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
127
126
128
127
129 @command(b'debugapplystreamclonebundle', [], b'FILE')
128 @command(b'debugapplystreamclonebundle', [], b'FILE')
130 def debugapplystreamclonebundle(ui, repo, fname):
129 def debugapplystreamclonebundle(ui, repo, fname):
131 """apply a stream clone bundle file"""
130 """apply a stream clone bundle file"""
132 f = hg.openpath(ui, fname)
131 f = hg.openpath(ui, fname)
133 gen = exchange.readbundle(ui, f, fname)
132 gen = exchange.readbundle(ui, f, fname)
134 gen.apply(repo)
133 gen.apply(repo)
135
134
136
135
137 @command(
136 @command(
138 b'debugbuilddag',
137 b'debugbuilddag',
139 [
138 [
140 (
139 (
141 b'm',
140 b'm',
142 b'mergeable-file',
141 b'mergeable-file',
143 None,
142 None,
144 _(b'add single file mergeable changes'),
143 _(b'add single file mergeable changes'),
145 ),
144 ),
146 (
145 (
147 b'o',
146 b'o',
148 b'overwritten-file',
147 b'overwritten-file',
149 None,
148 None,
150 _(b'add single file all revs overwrite'),
149 _(b'add single file all revs overwrite'),
151 ),
150 ),
152 (b'n', b'new-file', None, _(b'add new file at each rev')),
151 (b'n', b'new-file', None, _(b'add new file at each rev')),
153 ],
152 ],
154 _(b'[OPTION]... [TEXT]'),
153 _(b'[OPTION]... [TEXT]'),
155 )
154 )
156 def debugbuilddag(
155 def debugbuilddag(
157 ui,
156 ui,
158 repo,
157 repo,
159 text=None,
158 text=None,
160 mergeable_file=False,
159 mergeable_file=False,
161 overwritten_file=False,
160 overwritten_file=False,
162 new_file=False,
161 new_file=False,
163 ):
162 ):
164 """builds a repo with a given DAG from scratch in the current empty repo
163 """builds a repo with a given DAG from scratch in the current empty repo
165
164
166 The description of the DAG is read from stdin if not given on the
165 The description of the DAG is read from stdin if not given on the
167 command line.
166 command line.
168
167
169 Elements:
168 Elements:
170
169
171 - "+n" is a linear run of n nodes based on the current default parent
170 - "+n" is a linear run of n nodes based on the current default parent
172 - "." is a single node based on the current default parent
171 - "." is a single node based on the current default parent
173 - "$" resets the default parent to null (implied at the start);
172 - "$" resets the default parent to null (implied at the start);
174 otherwise the default parent is always the last node created
173 otherwise the default parent is always the last node created
175 - "<p" sets the default parent to the backref p
174 - "<p" sets the default parent to the backref p
176 - "*p" is a fork at parent p, which is a backref
175 - "*p" is a fork at parent p, which is a backref
177 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
176 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
178 - "/p2" is a merge of the preceding node and p2
177 - "/p2" is a merge of the preceding node and p2
179 - ":tag" defines a local tag for the preceding node
178 - ":tag" defines a local tag for the preceding node
180 - "@branch" sets the named branch for subsequent nodes
179 - "@branch" sets the named branch for subsequent nodes
181 - "#...\\n" is a comment up to the end of the line
180 - "#...\\n" is a comment up to the end of the line
182
181
183 Whitespace between the above elements is ignored.
182 Whitespace between the above elements is ignored.
184
183
185 A backref is either
184 A backref is either
186
185
187 - a number n, which references the node curr-n, where curr is the current
186 - a number n, which references the node curr-n, where curr is the current
188 node, or
187 node, or
189 - the name of a local tag you placed earlier using ":tag", or
188 - the name of a local tag you placed earlier using ":tag", or
190 - empty to denote the default parent.
189 - empty to denote the default parent.
191
190
192 All string valued-elements are either strictly alphanumeric, or must
191 All string valued-elements are either strictly alphanumeric, or must
193 be enclosed in double quotes ("..."), with "\\" as escape character.
192 be enclosed in double quotes ("..."), with "\\" as escape character.
194 """
193 """
195
194
196 if text is None:
195 if text is None:
197 ui.status(_(b"reading DAG from stdin\n"))
196 ui.status(_(b"reading DAG from stdin\n"))
198 text = ui.fin.read()
197 text = ui.fin.read()
199
198
200 cl = repo.changelog
199 cl = repo.changelog
201 if len(cl) > 0:
200 if len(cl) > 0:
202 raise error.Abort(_(b'repository is not empty'))
201 raise error.Abort(_(b'repository is not empty'))
203
202
204 # determine number of revs in DAG
203 # determine number of revs in DAG
205 total = 0
204 total = 0
206 for type, data in dagparser.parsedag(text):
205 for type, data in dagparser.parsedag(text):
207 if type == b'n':
206 if type == b'n':
208 total += 1
207 total += 1
209
208
210 if mergeable_file:
209 if mergeable_file:
211 linesperrev = 2
210 linesperrev = 2
212 # make a file with k lines per rev
211 # make a file with k lines per rev
213 initialmergedlines = [
212 initialmergedlines = [
214 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
213 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
215 ]
214 ]
216 initialmergedlines.append(b"")
215 initialmergedlines.append(b"")
217
216
218 tags = []
217 tags = []
219 progress = ui.makeprogress(
218 progress = ui.makeprogress(
220 _(b'building'), unit=_(b'revisions'), total=total
219 _(b'building'), unit=_(b'revisions'), total=total
221 )
220 )
222 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
221 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
223 at = -1
222 at = -1
224 atbranch = b'default'
223 atbranch = b'default'
225 nodeids = []
224 nodeids = []
226 id = 0
225 id = 0
227 progress.update(id)
226 progress.update(id)
228 for type, data in dagparser.parsedag(text):
227 for type, data in dagparser.parsedag(text):
229 if type == b'n':
228 if type == b'n':
230 ui.note((b'node %s\n' % pycompat.bytestr(data)))
229 ui.note((b'node %s\n' % pycompat.bytestr(data)))
231 id, ps = data
230 id, ps = data
232
231
233 files = []
232 files = []
234 filecontent = {}
233 filecontent = {}
235
234
236 p2 = None
235 p2 = None
237 if mergeable_file:
236 if mergeable_file:
238 fn = b"mf"
237 fn = b"mf"
239 p1 = repo[ps[0]]
238 p1 = repo[ps[0]]
240 if len(ps) > 1:
239 if len(ps) > 1:
241 p2 = repo[ps[1]]
240 p2 = repo[ps[1]]
242 pa = p1.ancestor(p2)
241 pa = p1.ancestor(p2)
243 base, local, other = [
242 base, local, other = [
244 x[fn].data() for x in (pa, p1, p2)
243 x[fn].data() for x in (pa, p1, p2)
245 ]
244 ]
246 m3 = simplemerge.Merge3Text(base, local, other)
245 m3 = simplemerge.Merge3Text(base, local, other)
247 ml = [l.strip() for l in m3.merge_lines()]
246 ml = [l.strip() for l in m3.merge_lines()]
248 ml.append(b"")
247 ml.append(b"")
249 elif at > 0:
248 elif at > 0:
250 ml = p1[fn].data().split(b"\n")
249 ml = p1[fn].data().split(b"\n")
251 else:
250 else:
252 ml = initialmergedlines
251 ml = initialmergedlines
253 ml[id * linesperrev] += b" r%i" % id
252 ml[id * linesperrev] += b" r%i" % id
254 mergedtext = b"\n".join(ml)
253 mergedtext = b"\n".join(ml)
255 files.append(fn)
254 files.append(fn)
256 filecontent[fn] = mergedtext
255 filecontent[fn] = mergedtext
257
256
258 if overwritten_file:
257 if overwritten_file:
259 fn = b"of"
258 fn = b"of"
260 files.append(fn)
259 files.append(fn)
261 filecontent[fn] = b"r%i\n" % id
260 filecontent[fn] = b"r%i\n" % id
262
261
263 if new_file:
262 if new_file:
264 fn = b"nf%i" % id
263 fn = b"nf%i" % id
265 files.append(fn)
264 files.append(fn)
266 filecontent[fn] = b"r%i\n" % id
265 filecontent[fn] = b"r%i\n" % id
267 if len(ps) > 1:
266 if len(ps) > 1:
268 if not p2:
267 if not p2:
269 p2 = repo[ps[1]]
268 p2 = repo[ps[1]]
270 for fn in p2:
269 for fn in p2:
271 if fn.startswith(b"nf"):
270 if fn.startswith(b"nf"):
272 files.append(fn)
271 files.append(fn)
273 filecontent[fn] = p2[fn].data()
272 filecontent[fn] = p2[fn].data()
274
273
275 def fctxfn(repo, cx, path):
274 def fctxfn(repo, cx, path):
276 if path in filecontent:
275 if path in filecontent:
277 return context.memfilectx(
276 return context.memfilectx(
278 repo, cx, path, filecontent[path]
277 repo, cx, path, filecontent[path]
279 )
278 )
280 return None
279 return None
281
280
282 if len(ps) == 0 or ps[0] < 0:
281 if len(ps) == 0 or ps[0] < 0:
283 pars = [None, None]
282 pars = [None, None]
284 elif len(ps) == 1:
283 elif len(ps) == 1:
285 pars = [nodeids[ps[0]], None]
284 pars = [nodeids[ps[0]], None]
286 else:
285 else:
287 pars = [nodeids[p] for p in ps]
286 pars = [nodeids[p] for p in ps]
288 cx = context.memctx(
287 cx = context.memctx(
289 repo,
288 repo,
290 pars,
289 pars,
291 b"r%i" % id,
290 b"r%i" % id,
292 files,
291 files,
293 fctxfn,
292 fctxfn,
294 date=(id, 0),
293 date=(id, 0),
295 user=b"debugbuilddag",
294 user=b"debugbuilddag",
296 extra={b'branch': atbranch},
295 extra={b'branch': atbranch},
297 )
296 )
298 nodeid = repo.commitctx(cx)
297 nodeid = repo.commitctx(cx)
299 nodeids.append(nodeid)
298 nodeids.append(nodeid)
300 at = id
299 at = id
301 elif type == b'l':
300 elif type == b'l':
302 id, name = data
301 id, name = data
303 ui.note((b'tag %s\n' % name))
302 ui.note((b'tag %s\n' % name))
304 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
303 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
305 elif type == b'a':
304 elif type == b'a':
306 ui.note((b'branch %s\n' % data))
305 ui.note((b'branch %s\n' % data))
307 atbranch = data
306 atbranch = data
308 progress.update(id)
307 progress.update(id)
309
308
310 if tags:
309 if tags:
311 repo.vfs.write(b"localtags", b"".join(tags))
310 repo.vfs.write(b"localtags", b"".join(tags))
312
311
313
312
314 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
313 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
315 indent_string = b' ' * indent
314 indent_string = b' ' * indent
316 if all:
315 if all:
317 ui.writenoi18n(
316 ui.writenoi18n(
318 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
317 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
319 % indent_string
318 % indent_string
320 )
319 )
321
320
322 def showchunks(named):
321 def showchunks(named):
323 ui.write(b"\n%s%s\n" % (indent_string, named))
322 ui.write(b"\n%s%s\n" % (indent_string, named))
324 for deltadata in gen.deltaiter():
323 for deltadata in gen.deltaiter():
325 node, p1, p2, cs, deltabase, delta, flags = deltadata
324 node, p1, p2, cs, deltabase, delta, flags = deltadata
326 ui.write(
325 ui.write(
327 b"%s%s %s %s %s %s %d\n"
326 b"%s%s %s %s %s %s %d\n"
328 % (
327 % (
329 indent_string,
328 indent_string,
330 hex(node),
329 hex(node),
331 hex(p1),
330 hex(p1),
332 hex(p2),
331 hex(p2),
333 hex(cs),
332 hex(cs),
334 hex(deltabase),
333 hex(deltabase),
335 len(delta),
334 len(delta),
336 )
335 )
337 )
336 )
338
337
339 gen.changelogheader()
338 gen.changelogheader()
340 showchunks(b"changelog")
339 showchunks(b"changelog")
341 gen.manifestheader()
340 gen.manifestheader()
342 showchunks(b"manifest")
341 showchunks(b"manifest")
343 for chunkdata in iter(gen.filelogheader, {}):
342 for chunkdata in iter(gen.filelogheader, {}):
344 fname = chunkdata[b'filename']
343 fname = chunkdata[b'filename']
345 showchunks(fname)
344 showchunks(fname)
346 else:
345 else:
347 if isinstance(gen, bundle2.unbundle20):
346 if isinstance(gen, bundle2.unbundle20):
348 raise error.Abort(_(b'use debugbundle2 for this file'))
347 raise error.Abort(_(b'use debugbundle2 for this file'))
349 gen.changelogheader()
348 gen.changelogheader()
350 for deltadata in gen.deltaiter():
349 for deltadata in gen.deltaiter():
351 node, p1, p2, cs, deltabase, delta, flags = deltadata
350 node, p1, p2, cs, deltabase, delta, flags = deltadata
352 ui.write(b"%s%s\n" % (indent_string, hex(node)))
351 ui.write(b"%s%s\n" % (indent_string, hex(node)))
353
352
354
353
355 def _debugobsmarkers(ui, part, indent=0, **opts):
354 def _debugobsmarkers(ui, part, indent=0, **opts):
356 """display version and markers contained in 'data'"""
355 """display version and markers contained in 'data'"""
357 opts = pycompat.byteskwargs(opts)
356 opts = pycompat.byteskwargs(opts)
358 data = part.read()
357 data = part.read()
359 indent_string = b' ' * indent
358 indent_string = b' ' * indent
360 try:
359 try:
361 version, markers = obsolete._readmarkers(data)
360 version, markers = obsolete._readmarkers(data)
362 except error.UnknownVersion as exc:
361 except error.UnknownVersion as exc:
363 msg = b"%sunsupported version: %s (%d bytes)\n"
362 msg = b"%sunsupported version: %s (%d bytes)\n"
364 msg %= indent_string, exc.version, len(data)
363 msg %= indent_string, exc.version, len(data)
365 ui.write(msg)
364 ui.write(msg)
366 else:
365 else:
367 msg = b"%sversion: %d (%d bytes)\n"
366 msg = b"%sversion: %d (%d bytes)\n"
368 msg %= indent_string, version, len(data)
367 msg %= indent_string, version, len(data)
369 ui.write(msg)
368 ui.write(msg)
370 fm = ui.formatter(b'debugobsolete', opts)
369 fm = ui.formatter(b'debugobsolete', opts)
371 for rawmarker in sorted(markers):
370 for rawmarker in sorted(markers):
372 m = obsutil.marker(None, rawmarker)
371 m = obsutil.marker(None, rawmarker)
373 fm.startitem()
372 fm.startitem()
374 fm.plain(indent_string)
373 fm.plain(indent_string)
375 cmdutil.showmarker(fm, m)
374 cmdutil.showmarker(fm, m)
376 fm.end()
375 fm.end()
377
376
378
377
379 def _debugphaseheads(ui, data, indent=0):
378 def _debugphaseheads(ui, data, indent=0):
380 """display version and markers contained in 'data'"""
379 """display version and markers contained in 'data'"""
381 indent_string = b' ' * indent
380 indent_string = b' ' * indent
382 headsbyphase = phases.binarydecode(data)
381 headsbyphase = phases.binarydecode(data)
383 for phase in phases.allphases:
382 for phase in phases.allphases:
384 for head in headsbyphase[phase]:
383 for head in headsbyphase[phase]:
385 ui.write(indent_string)
384 ui.write(indent_string)
386 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
385 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
387
386
388
387
389 def _quasirepr(thing):
388 def _quasirepr(thing):
390 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
389 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
391 return b'{%s}' % (
390 return b'{%s}' % (
392 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
391 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
393 )
392 )
394 return pycompat.bytestr(repr(thing))
393 return pycompat.bytestr(repr(thing))
395
394
396
395
397 def _debugbundle2(ui, gen, all=None, **opts):
396 def _debugbundle2(ui, gen, all=None, **opts):
398 """lists the contents of a bundle2"""
397 """lists the contents of a bundle2"""
399 if not isinstance(gen, bundle2.unbundle20):
398 if not isinstance(gen, bundle2.unbundle20):
400 raise error.Abort(_(b'not a bundle2 file'))
399 raise error.Abort(_(b'not a bundle2 file'))
401 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
400 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
402 parttypes = opts.get('part_type', [])
401 parttypes = opts.get('part_type', [])
403 for part in gen.iterparts():
402 for part in gen.iterparts():
404 if parttypes and part.type not in parttypes:
403 if parttypes and part.type not in parttypes:
405 continue
404 continue
406 msg = b'%s -- %s (mandatory: %r)\n'
405 msg = b'%s -- %s (mandatory: %r)\n'
407 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
406 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
408 if part.type == b'changegroup':
407 if part.type == b'changegroup':
409 version = part.params.get(b'version', b'01')
408 version = part.params.get(b'version', b'01')
410 cg = changegroup.getunbundler(version, part, b'UN')
409 cg = changegroup.getunbundler(version, part, b'UN')
411 if not ui.quiet:
410 if not ui.quiet:
412 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
411 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
413 if part.type == b'obsmarkers':
412 if part.type == b'obsmarkers':
414 if not ui.quiet:
413 if not ui.quiet:
415 _debugobsmarkers(ui, part, indent=4, **opts)
414 _debugobsmarkers(ui, part, indent=4, **opts)
416 if part.type == b'phase-heads':
415 if part.type == b'phase-heads':
417 if not ui.quiet:
416 if not ui.quiet:
418 _debugphaseheads(ui, part, indent=4)
417 _debugphaseheads(ui, part, indent=4)
419
418
420
419
421 @command(
420 @command(
422 b'debugbundle',
421 b'debugbundle',
423 [
422 [
424 (b'a', b'all', None, _(b'show all details')),
423 (b'a', b'all', None, _(b'show all details')),
425 (b'', b'part-type', [], _(b'show only the named part type')),
424 (b'', b'part-type', [], _(b'show only the named part type')),
426 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
425 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
427 ],
426 ],
428 _(b'FILE'),
427 _(b'FILE'),
429 norepo=True,
428 norepo=True,
430 )
429 )
431 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
430 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
432 """lists the contents of a bundle"""
431 """lists the contents of a bundle"""
433 with hg.openpath(ui, bundlepath) as f:
432 with hg.openpath(ui, bundlepath) as f:
434 if spec:
433 if spec:
435 spec = exchange.getbundlespec(ui, f)
434 spec = exchange.getbundlespec(ui, f)
436 ui.write(b'%s\n' % spec)
435 ui.write(b'%s\n' % spec)
437 return
436 return
438
437
439 gen = exchange.readbundle(ui, f, bundlepath)
438 gen = exchange.readbundle(ui, f, bundlepath)
440 if isinstance(gen, bundle2.unbundle20):
439 if isinstance(gen, bundle2.unbundle20):
441 return _debugbundle2(ui, gen, all=all, **opts)
440 return _debugbundle2(ui, gen, all=all, **opts)
442 _debugchangegroup(ui, gen, all=all, **opts)
441 _debugchangegroup(ui, gen, all=all, **opts)
443
442
444
443
445 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
444 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
446 def debugcapabilities(ui, path, **opts):
445 def debugcapabilities(ui, path, **opts):
447 """lists the capabilities of a remote peer"""
446 """lists the capabilities of a remote peer"""
448 opts = pycompat.byteskwargs(opts)
447 opts = pycompat.byteskwargs(opts)
449 peer = hg.peer(ui, opts, path)
448 peer = hg.peer(ui, opts, path)
450 caps = peer.capabilities()
449 caps = peer.capabilities()
451 ui.writenoi18n(b'Main capabilities:\n')
450 ui.writenoi18n(b'Main capabilities:\n')
452 for c in sorted(caps):
451 for c in sorted(caps):
453 ui.write(b' %s\n' % c)
452 ui.write(b' %s\n' % c)
454 b2caps = bundle2.bundle2caps(peer)
453 b2caps = bundle2.bundle2caps(peer)
455 if b2caps:
454 if b2caps:
456 ui.writenoi18n(b'Bundle2 capabilities:\n')
455 ui.writenoi18n(b'Bundle2 capabilities:\n')
457 for key, values in sorted(pycompat.iteritems(b2caps)):
456 for key, values in sorted(pycompat.iteritems(b2caps)):
458 ui.write(b' %s\n' % key)
457 ui.write(b' %s\n' % key)
459 for v in values:
458 for v in values:
460 ui.write(b' %s\n' % v)
459 ui.write(b' %s\n' % v)
461
460
462
461
463 @command(b'debugcheckstate', [], b'')
462 @command(b'debugcheckstate', [], b'')
464 def debugcheckstate(ui, repo):
463 def debugcheckstate(ui, repo):
465 """validate the correctness of the current dirstate"""
464 """validate the correctness of the current dirstate"""
466 parent1, parent2 = repo.dirstate.parents()
465 parent1, parent2 = repo.dirstate.parents()
467 m1 = repo[parent1].manifest()
466 m1 = repo[parent1].manifest()
468 m2 = repo[parent2].manifest()
467 m2 = repo[parent2].manifest()
469 errors = 0
468 errors = 0
470 for f in repo.dirstate:
469 for f in repo.dirstate:
471 state = repo.dirstate[f]
470 state = repo.dirstate[f]
472 if state in b"nr" and f not in m1:
471 if state in b"nr" and f not in m1:
473 ui.warn(_(b"%s in state %s, but not in manifest1\n") % (f, state))
472 ui.warn(_(b"%s in state %s, but not in manifest1\n") % (f, state))
474 errors += 1
473 errors += 1
475 if state in b"a" and f in m1:
474 if state in b"a" and f in m1:
476 ui.warn(_(b"%s in state %s, but also in manifest1\n") % (f, state))
475 ui.warn(_(b"%s in state %s, but also in manifest1\n") % (f, state))
477 errors += 1
476 errors += 1
478 if state in b"m" and f not in m1 and f not in m2:
477 if state in b"m" and f not in m1 and f not in m2:
479 ui.warn(
478 ui.warn(
480 _(b"%s in state %s, but not in either manifest\n") % (f, state)
479 _(b"%s in state %s, but not in either manifest\n") % (f, state)
481 )
480 )
482 errors += 1
481 errors += 1
483 for f in m1:
482 for f in m1:
484 state = repo.dirstate[f]
483 state = repo.dirstate[f]
485 if state not in b"nrm":
484 if state not in b"nrm":
486 ui.warn(_(b"%s in manifest1, but listed as state %s") % (f, state))
485 ui.warn(_(b"%s in manifest1, but listed as state %s") % (f, state))
487 errors += 1
486 errors += 1
488 if errors:
487 if errors:
489 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
488 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
490 raise error.Abort(errstr)
489 raise error.Abort(errstr)
491
490
492
491
493 @command(
492 @command(
494 b'debugcolor',
493 b'debugcolor',
495 [(b'', b'style', None, _(b'show all configured styles'))],
494 [(b'', b'style', None, _(b'show all configured styles'))],
496 b'hg debugcolor',
495 b'hg debugcolor',
497 )
496 )
498 def debugcolor(ui, repo, **opts):
497 def debugcolor(ui, repo, **opts):
499 """show available color, effects or style"""
498 """show available color, effects or style"""
500 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
499 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
501 if opts.get('style'):
500 if opts.get('style'):
502 return _debugdisplaystyle(ui)
501 return _debugdisplaystyle(ui)
503 else:
502 else:
504 return _debugdisplaycolor(ui)
503 return _debugdisplaycolor(ui)
505
504
506
505
507 def _debugdisplaycolor(ui):
506 def _debugdisplaycolor(ui):
508 ui = ui.copy()
507 ui = ui.copy()
509 ui._styles.clear()
508 ui._styles.clear()
510 for effect in color._activeeffects(ui).keys():
509 for effect in color._activeeffects(ui).keys():
511 ui._styles[effect] = effect
510 ui._styles[effect] = effect
512 if ui._terminfoparams:
511 if ui._terminfoparams:
513 for k, v in ui.configitems(b'color'):
512 for k, v in ui.configitems(b'color'):
514 if k.startswith(b'color.'):
513 if k.startswith(b'color.'):
515 ui._styles[k] = k[6:]
514 ui._styles[k] = k[6:]
516 elif k.startswith(b'terminfo.'):
515 elif k.startswith(b'terminfo.'):
517 ui._styles[k] = k[9:]
516 ui._styles[k] = k[9:]
518 ui.write(_(b'available colors:\n'))
517 ui.write(_(b'available colors:\n'))
519 # sort label with a '_' after the other to group '_background' entry.
518 # sort label with a '_' after the other to group '_background' entry.
520 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
519 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
521 for colorname, label in items:
520 for colorname, label in items:
522 ui.write(b'%s\n' % colorname, label=label)
521 ui.write(b'%s\n' % colorname, label=label)
523
522
524
523
525 def _debugdisplaystyle(ui):
524 def _debugdisplaystyle(ui):
526 ui.write(_(b'available style:\n'))
525 ui.write(_(b'available style:\n'))
527 if not ui._styles:
526 if not ui._styles:
528 return
527 return
529 width = max(len(s) for s in ui._styles)
528 width = max(len(s) for s in ui._styles)
530 for label, effects in sorted(ui._styles.items()):
529 for label, effects in sorted(ui._styles.items()):
531 ui.write(b'%s' % label, label=label)
530 ui.write(b'%s' % label, label=label)
532 if effects:
531 if effects:
533 # 50
532 # 50
534 ui.write(b': ')
533 ui.write(b': ')
535 ui.write(b' ' * (max(0, width - len(label))))
534 ui.write(b' ' * (max(0, width - len(label))))
536 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
535 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
537 ui.write(b'\n')
536 ui.write(b'\n')
538
537
539
538
540 @command(b'debugcreatestreamclonebundle', [], b'FILE')
539 @command(b'debugcreatestreamclonebundle', [], b'FILE')
541 def debugcreatestreamclonebundle(ui, repo, fname):
540 def debugcreatestreamclonebundle(ui, repo, fname):
542 """create a stream clone bundle file
541 """create a stream clone bundle file
543
542
544 Stream bundles are special bundles that are essentially archives of
543 Stream bundles are special bundles that are essentially archives of
545 revlog files. They are commonly used for cloning very quickly.
544 revlog files. They are commonly used for cloning very quickly.
546 """
545 """
547 # TODO we may want to turn this into an abort when this functionality
546 # TODO we may want to turn this into an abort when this functionality
548 # is moved into `hg bundle`.
547 # is moved into `hg bundle`.
549 if phases.hassecret(repo):
548 if phases.hassecret(repo):
550 ui.warn(
549 ui.warn(
551 _(
550 _(
552 b'(warning: stream clone bundle will contain secret '
551 b'(warning: stream clone bundle will contain secret '
553 b'revisions)\n'
552 b'revisions)\n'
554 )
553 )
555 )
554 )
556
555
557 requirements, gen = streamclone.generatebundlev1(repo)
556 requirements, gen = streamclone.generatebundlev1(repo)
558 changegroup.writechunks(ui, gen, fname)
557 changegroup.writechunks(ui, gen, fname)
559
558
560 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
559 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
561
560
562
561
563 @command(
562 @command(
564 b'debugdag',
563 b'debugdag',
565 [
564 [
566 (b't', b'tags', None, _(b'use tags as labels')),
565 (b't', b'tags', None, _(b'use tags as labels')),
567 (b'b', b'branches', None, _(b'annotate with branch names')),
566 (b'b', b'branches', None, _(b'annotate with branch names')),
568 (b'', b'dots', None, _(b'use dots for runs')),
567 (b'', b'dots', None, _(b'use dots for runs')),
569 (b's', b'spaces', None, _(b'separate elements by spaces')),
568 (b's', b'spaces', None, _(b'separate elements by spaces')),
570 ],
569 ],
571 _(b'[OPTION]... [FILE [REV]...]'),
570 _(b'[OPTION]... [FILE [REV]...]'),
572 optionalrepo=True,
571 optionalrepo=True,
573 )
572 )
574 def debugdag(ui, repo, file_=None, *revs, **opts):
573 def debugdag(ui, repo, file_=None, *revs, **opts):
575 """format the changelog or an index DAG as a concise textual description
574 """format the changelog or an index DAG as a concise textual description
576
575
577 If you pass a revlog index, the revlog's DAG is emitted. If you list
576 If you pass a revlog index, the revlog's DAG is emitted. If you list
578 revision numbers, they get labeled in the output as rN.
577 revision numbers, they get labeled in the output as rN.
579
578
580 Otherwise, the changelog DAG of the current repo is emitted.
579 Otherwise, the changelog DAG of the current repo is emitted.
581 """
580 """
582 spaces = opts.get('spaces')
581 spaces = opts.get('spaces')
583 dots = opts.get('dots')
582 dots = opts.get('dots')
584 if file_:
583 if file_:
585 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
584 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
586 revs = set((int(r) for r in revs))
585 revs = set((int(r) for r in revs))
587
586
588 def events():
587 def events():
589 for r in rlog:
588 for r in rlog:
590 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
589 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
591 if r in revs:
590 if r in revs:
592 yield b'l', (r, b"r%i" % r)
591 yield b'l', (r, b"r%i" % r)
593
592
594 elif repo:
593 elif repo:
595 cl = repo.changelog
594 cl = repo.changelog
596 tags = opts.get('tags')
595 tags = opts.get('tags')
597 branches = opts.get('branches')
596 branches = opts.get('branches')
598 if tags:
597 if tags:
599 labels = {}
598 labels = {}
600 for l, n in repo.tags().items():
599 for l, n in repo.tags().items():
601 labels.setdefault(cl.rev(n), []).append(l)
600 labels.setdefault(cl.rev(n), []).append(l)
602
601
603 def events():
602 def events():
604 b = b"default"
603 b = b"default"
605 for r in cl:
604 for r in cl:
606 if branches:
605 if branches:
607 newb = cl.read(cl.node(r))[5][b'branch']
606 newb = cl.read(cl.node(r))[5][b'branch']
608 if newb != b:
607 if newb != b:
609 yield b'a', newb
608 yield b'a', newb
610 b = newb
609 b = newb
611 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
610 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
612 if tags:
611 if tags:
613 ls = labels.get(r)
612 ls = labels.get(r)
614 if ls:
613 if ls:
615 for l in ls:
614 for l in ls:
616 yield b'l', (r, l)
615 yield b'l', (r, l)
617
616
618 else:
617 else:
619 raise error.Abort(_(b'need repo for changelog dag'))
618 raise error.Abort(_(b'need repo for changelog dag'))
620
619
621 for line in dagparser.dagtextlines(
620 for line in dagparser.dagtextlines(
622 events(),
621 events(),
623 addspaces=spaces,
622 addspaces=spaces,
624 wraplabels=True,
623 wraplabels=True,
625 wrapannotations=True,
624 wrapannotations=True,
626 wrapnonlinear=dots,
625 wrapnonlinear=dots,
627 usedots=dots,
626 usedots=dots,
628 maxlinewidth=70,
627 maxlinewidth=70,
629 ):
628 ):
630 ui.write(line)
629 ui.write(line)
631 ui.write(b"\n")
630 ui.write(b"\n")
632
631
633
632
634 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
633 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
635 def debugdata(ui, repo, file_, rev=None, **opts):
634 def debugdata(ui, repo, file_, rev=None, **opts):
636 """dump the contents of a data file revision"""
635 """dump the contents of a data file revision"""
637 opts = pycompat.byteskwargs(opts)
636 opts = pycompat.byteskwargs(opts)
638 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
637 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
639 if rev is not None:
638 if rev is not None:
640 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
639 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
641 file_, rev = None, file_
640 file_, rev = None, file_
642 elif rev is None:
641 elif rev is None:
643 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
642 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
644 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
643 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
645 try:
644 try:
646 ui.write(r.rawdata(r.lookup(rev)))
645 ui.write(r.rawdata(r.lookup(rev)))
647 except KeyError:
646 except KeyError:
648 raise error.Abort(_(b'invalid revision identifier %s') % rev)
647 raise error.Abort(_(b'invalid revision identifier %s') % rev)
649
648
650
649
651 @command(
650 @command(
652 b'debugdate',
651 b'debugdate',
653 [(b'e', b'extended', None, _(b'try extended date formats'))],
652 [(b'e', b'extended', None, _(b'try extended date formats'))],
654 _(b'[-e] DATE [RANGE]'),
653 _(b'[-e] DATE [RANGE]'),
655 norepo=True,
654 norepo=True,
656 optionalrepo=True,
655 optionalrepo=True,
657 )
656 )
658 def debugdate(ui, date, range=None, **opts):
657 def debugdate(ui, date, range=None, **opts):
659 """parse and display a date"""
658 """parse and display a date"""
660 if opts["extended"]:
659 if opts["extended"]:
661 d = dateutil.parsedate(date, dateutil.extendeddateformats)
660 d = dateutil.parsedate(date, dateutil.extendeddateformats)
662 else:
661 else:
663 d = dateutil.parsedate(date)
662 d = dateutil.parsedate(date)
664 ui.writenoi18n(b"internal: %d %d\n" % d)
663 ui.writenoi18n(b"internal: %d %d\n" % d)
665 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
664 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
666 if range:
665 if range:
667 m = dateutil.matchdate(range)
666 m = dateutil.matchdate(range)
668 ui.writenoi18n(b"match: %s\n" % m(d[0]))
667 ui.writenoi18n(b"match: %s\n" % m(d[0]))
669
668
670
669
671 @command(
670 @command(
672 b'debugdeltachain',
671 b'debugdeltachain',
673 cmdutil.debugrevlogopts + cmdutil.formatteropts,
672 cmdutil.debugrevlogopts + cmdutil.formatteropts,
674 _(b'-c|-m|FILE'),
673 _(b'-c|-m|FILE'),
675 optionalrepo=True,
674 optionalrepo=True,
676 )
675 )
677 def debugdeltachain(ui, repo, file_=None, **opts):
676 def debugdeltachain(ui, repo, file_=None, **opts):
678 """dump information about delta chains in a revlog
677 """dump information about delta chains in a revlog
679
678
680 Output can be templatized. Available template keywords are:
679 Output can be templatized. Available template keywords are:
681
680
682 :``rev``: revision number
681 :``rev``: revision number
683 :``chainid``: delta chain identifier (numbered by unique base)
682 :``chainid``: delta chain identifier (numbered by unique base)
684 :``chainlen``: delta chain length to this revision
683 :``chainlen``: delta chain length to this revision
685 :``prevrev``: previous revision in delta chain
684 :``prevrev``: previous revision in delta chain
686 :``deltatype``: role of delta / how it was computed
685 :``deltatype``: role of delta / how it was computed
687 :``compsize``: compressed size of revision
686 :``compsize``: compressed size of revision
688 :``uncompsize``: uncompressed size of revision
687 :``uncompsize``: uncompressed size of revision
689 :``chainsize``: total size of compressed revisions in chain
688 :``chainsize``: total size of compressed revisions in chain
690 :``chainratio``: total chain size divided by uncompressed revision size
689 :``chainratio``: total chain size divided by uncompressed revision size
691 (new delta chains typically start at ratio 2.00)
690 (new delta chains typically start at ratio 2.00)
692 :``lindist``: linear distance from base revision in delta chain to end
691 :``lindist``: linear distance from base revision in delta chain to end
693 of this revision
692 of this revision
694 :``extradist``: total size of revisions not part of this delta chain from
693 :``extradist``: total size of revisions not part of this delta chain from
695 base of delta chain to end of this revision; a measurement
694 base of delta chain to end of this revision; a measurement
696 of how much extra data we need to read/seek across to read
695 of how much extra data we need to read/seek across to read
697 the delta chain for this revision
696 the delta chain for this revision
698 :``extraratio``: extradist divided by chainsize; another representation of
697 :``extraratio``: extradist divided by chainsize; another representation of
699 how much unrelated data is needed to load this delta chain
698 how much unrelated data is needed to load this delta chain
700
699
701 If the repository is configured to use the sparse read, additional keywords
700 If the repository is configured to use the sparse read, additional keywords
702 are available:
701 are available:
703
702
704 :``readsize``: total size of data read from the disk for a revision
703 :``readsize``: total size of data read from the disk for a revision
705 (sum of the sizes of all the blocks)
704 (sum of the sizes of all the blocks)
706 :``largestblock``: size of the largest block of data read from the disk
705 :``largestblock``: size of the largest block of data read from the disk
707 :``readdensity``: density of useful bytes in the data read from the disk
706 :``readdensity``: density of useful bytes in the data read from the disk
708 :``srchunks``: in how many data hunks the whole revision would be read
707 :``srchunks``: in how many data hunks the whole revision would be read
709
708
710 The sparse read can be enabled with experimental.sparse-read = True
709 The sparse read can be enabled with experimental.sparse-read = True
711 """
710 """
712 opts = pycompat.byteskwargs(opts)
711 opts = pycompat.byteskwargs(opts)
713 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
712 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
714 index = r.index
713 index = r.index
715 start = r.start
714 start = r.start
716 length = r.length
715 length = r.length
717 generaldelta = r.version & revlog.FLAG_GENERALDELTA
716 generaldelta = r.version & revlog.FLAG_GENERALDELTA
718 withsparseread = getattr(r, '_withsparseread', False)
717 withsparseread = getattr(r, '_withsparseread', False)
719
718
720 def revinfo(rev):
719 def revinfo(rev):
721 e = index[rev]
720 e = index[rev]
722 compsize = e[1]
721 compsize = e[1]
723 uncompsize = e[2]
722 uncompsize = e[2]
724 chainsize = 0
723 chainsize = 0
725
724
726 if generaldelta:
725 if generaldelta:
727 if e[3] == e[5]:
726 if e[3] == e[5]:
728 deltatype = b'p1'
727 deltatype = b'p1'
729 elif e[3] == e[6]:
728 elif e[3] == e[6]:
730 deltatype = b'p2'
729 deltatype = b'p2'
731 elif e[3] == rev - 1:
730 elif e[3] == rev - 1:
732 deltatype = b'prev'
731 deltatype = b'prev'
733 elif e[3] == rev:
732 elif e[3] == rev:
734 deltatype = b'base'
733 deltatype = b'base'
735 else:
734 else:
736 deltatype = b'other'
735 deltatype = b'other'
737 else:
736 else:
738 if e[3] == rev:
737 if e[3] == rev:
739 deltatype = b'base'
738 deltatype = b'base'
740 else:
739 else:
741 deltatype = b'prev'
740 deltatype = b'prev'
742
741
743 chain = r._deltachain(rev)[0]
742 chain = r._deltachain(rev)[0]
744 for iterrev in chain:
743 for iterrev in chain:
745 e = index[iterrev]
744 e = index[iterrev]
746 chainsize += e[1]
745 chainsize += e[1]
747
746
748 return compsize, uncompsize, deltatype, chain, chainsize
747 return compsize, uncompsize, deltatype, chain, chainsize
749
748
750 fm = ui.formatter(b'debugdeltachain', opts)
749 fm = ui.formatter(b'debugdeltachain', opts)
751
750
752 fm.plain(
751 fm.plain(
753 b' rev chain# chainlen prev delta '
752 b' rev chain# chainlen prev delta '
754 b'size rawsize chainsize ratio lindist extradist '
753 b'size rawsize chainsize ratio lindist extradist '
755 b'extraratio'
754 b'extraratio'
756 )
755 )
757 if withsparseread:
756 if withsparseread:
758 fm.plain(b' readsize largestblk rddensity srchunks')
757 fm.plain(b' readsize largestblk rddensity srchunks')
759 fm.plain(b'\n')
758 fm.plain(b'\n')
760
759
761 chainbases = {}
760 chainbases = {}
762 for rev in r:
761 for rev in r:
763 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
762 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
764 chainbase = chain[0]
763 chainbase = chain[0]
765 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
764 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
766 basestart = start(chainbase)
765 basestart = start(chainbase)
767 revstart = start(rev)
766 revstart = start(rev)
768 lineardist = revstart + comp - basestart
767 lineardist = revstart + comp - basestart
769 extradist = lineardist - chainsize
768 extradist = lineardist - chainsize
770 try:
769 try:
771 prevrev = chain[-2]
770 prevrev = chain[-2]
772 except IndexError:
771 except IndexError:
773 prevrev = -1
772 prevrev = -1
774
773
775 if uncomp != 0:
774 if uncomp != 0:
776 chainratio = float(chainsize) / float(uncomp)
775 chainratio = float(chainsize) / float(uncomp)
777 else:
776 else:
778 chainratio = chainsize
777 chainratio = chainsize
779
778
780 if chainsize != 0:
779 if chainsize != 0:
781 extraratio = float(extradist) / float(chainsize)
780 extraratio = float(extradist) / float(chainsize)
782 else:
781 else:
783 extraratio = extradist
782 extraratio = extradist
784
783
785 fm.startitem()
784 fm.startitem()
786 fm.write(
785 fm.write(
787 b'rev chainid chainlen prevrev deltatype compsize '
786 b'rev chainid chainlen prevrev deltatype compsize '
788 b'uncompsize chainsize chainratio lindist extradist '
787 b'uncompsize chainsize chainratio lindist extradist '
789 b'extraratio',
788 b'extraratio',
790 b'%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
789 b'%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
791 rev,
790 rev,
792 chainid,
791 chainid,
793 len(chain),
792 len(chain),
794 prevrev,
793 prevrev,
795 deltatype,
794 deltatype,
796 comp,
795 comp,
797 uncomp,
796 uncomp,
798 chainsize,
797 chainsize,
799 chainratio,
798 chainratio,
800 lineardist,
799 lineardist,
801 extradist,
800 extradist,
802 extraratio,
801 extraratio,
803 rev=rev,
802 rev=rev,
804 chainid=chainid,
803 chainid=chainid,
805 chainlen=len(chain),
804 chainlen=len(chain),
806 prevrev=prevrev,
805 prevrev=prevrev,
807 deltatype=deltatype,
806 deltatype=deltatype,
808 compsize=comp,
807 compsize=comp,
809 uncompsize=uncomp,
808 uncompsize=uncomp,
810 chainsize=chainsize,
809 chainsize=chainsize,
811 chainratio=chainratio,
810 chainratio=chainratio,
812 lindist=lineardist,
811 lindist=lineardist,
813 extradist=extradist,
812 extradist=extradist,
814 extraratio=extraratio,
813 extraratio=extraratio,
815 )
814 )
816 if withsparseread:
815 if withsparseread:
817 readsize = 0
816 readsize = 0
818 largestblock = 0
817 largestblock = 0
819 srchunks = 0
818 srchunks = 0
820
819
821 for revschunk in deltautil.slicechunk(r, chain):
820 for revschunk in deltautil.slicechunk(r, chain):
822 srchunks += 1
821 srchunks += 1
823 blkend = start(revschunk[-1]) + length(revschunk[-1])
822 blkend = start(revschunk[-1]) + length(revschunk[-1])
824 blksize = blkend - start(revschunk[0])
823 blksize = blkend - start(revschunk[0])
825
824
826 readsize += blksize
825 readsize += blksize
827 if largestblock < blksize:
826 if largestblock < blksize:
828 largestblock = blksize
827 largestblock = blksize
829
828
830 if readsize:
829 if readsize:
831 readdensity = float(chainsize) / float(readsize)
830 readdensity = float(chainsize) / float(readsize)
832 else:
831 else:
833 readdensity = 1
832 readdensity = 1
834
833
835 fm.write(
834 fm.write(
836 b'readsize largestblock readdensity srchunks',
835 b'readsize largestblock readdensity srchunks',
837 b' %10d %10d %9.5f %8d',
836 b' %10d %10d %9.5f %8d',
838 readsize,
837 readsize,
839 largestblock,
838 largestblock,
840 readdensity,
839 readdensity,
841 srchunks,
840 srchunks,
842 readsize=readsize,
841 readsize=readsize,
843 largestblock=largestblock,
842 largestblock=largestblock,
844 readdensity=readdensity,
843 readdensity=readdensity,
845 srchunks=srchunks,
844 srchunks=srchunks,
846 )
845 )
847
846
848 fm.plain(b'\n')
847 fm.plain(b'\n')
849
848
850 fm.end()
849 fm.end()
851
850
852
851
853 @command(
852 @command(
854 b'debugdirstate|debugstate',
853 b'debugdirstate|debugstate',
855 [
854 [
856 (
855 (
857 b'',
856 b'',
858 b'nodates',
857 b'nodates',
859 None,
858 None,
860 _(b'do not display the saved mtime (DEPRECATED)'),
859 _(b'do not display the saved mtime (DEPRECATED)'),
861 ),
860 ),
862 (b'', b'dates', True, _(b'display the saved mtime')),
861 (b'', b'dates', True, _(b'display the saved mtime')),
863 (b'', b'datesort', None, _(b'sort by saved mtime')),
862 (b'', b'datesort', None, _(b'sort by saved mtime')),
864 ],
863 ],
865 _(b'[OPTION]...'),
864 _(b'[OPTION]...'),
866 )
865 )
867 def debugstate(ui, repo, **opts):
866 def debugstate(ui, repo, **opts):
868 """show the contents of the current dirstate"""
867 """show the contents of the current dirstate"""
869
868
870 nodates = not opts['dates']
869 nodates = not opts['dates']
871 if opts.get('nodates') is not None:
870 if opts.get('nodates') is not None:
872 nodates = True
871 nodates = True
873 datesort = opts.get('datesort')
872 datesort = opts.get('datesort')
874
873
875 if datesort:
874 if datesort:
876 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
875 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
877 else:
876 else:
878 keyfunc = None # sort by filename
877 keyfunc = None # sort by filename
879 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
878 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
880 if ent[3] == -1:
879 if ent[3] == -1:
881 timestr = b'unset '
880 timestr = b'unset '
882 elif nodates:
881 elif nodates:
883 timestr = b'set '
882 timestr = b'set '
884 else:
883 else:
885 timestr = time.strftime(
884 timestr = time.strftime(
886 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
885 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
887 )
886 )
888 timestr = encoding.strtolocal(timestr)
887 timestr = encoding.strtolocal(timestr)
889 if ent[1] & 0o20000:
888 if ent[1] & 0o20000:
890 mode = b'lnk'
889 mode = b'lnk'
891 else:
890 else:
892 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
891 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
893 ui.write(b"%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
892 ui.write(b"%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
894 for f in repo.dirstate.copies():
893 for f in repo.dirstate.copies():
895 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
894 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
896
895
897
896
898 @command(
897 @command(
899 b'debugdiscovery',
898 b'debugdiscovery',
900 [
899 [
901 (b'', b'old', None, _(b'use old-style discovery')),
900 (b'', b'old', None, _(b'use old-style discovery')),
902 (
901 (
903 b'',
902 b'',
904 b'nonheads',
903 b'nonheads',
905 None,
904 None,
906 _(b'use old-style discovery with non-heads included'),
905 _(b'use old-style discovery with non-heads included'),
907 ),
906 ),
908 (b'', b'rev', [], b'restrict discovery to this set of revs'),
907 (b'', b'rev', [], b'restrict discovery to this set of revs'),
909 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
908 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
910 ]
909 ]
911 + cmdutil.remoteopts,
910 + cmdutil.remoteopts,
912 _(b'[--rev REV] [OTHER]'),
911 _(b'[--rev REV] [OTHER]'),
913 )
912 )
914 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
913 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
915 """runs the changeset discovery protocol in isolation"""
914 """runs the changeset discovery protocol in isolation"""
916 opts = pycompat.byteskwargs(opts)
915 opts = pycompat.byteskwargs(opts)
917 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
916 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
918 remote = hg.peer(repo, opts, remoteurl)
917 remote = hg.peer(repo, opts, remoteurl)
919 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
918 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
920
919
921 # make sure tests are repeatable
920 # make sure tests are repeatable
922 random.seed(int(opts[b'seed']))
921 random.seed(int(opts[b'seed']))
923
922
924 if opts.get(b'old'):
923 if opts.get(b'old'):
925
924
926 def doit(pushedrevs, remoteheads, remote=remote):
925 def doit(pushedrevs, remoteheads, remote=remote):
927 if not util.safehasattr(remote, b'branches'):
926 if not util.safehasattr(remote, b'branches'):
928 # enable in-client legacy support
927 # enable in-client legacy support
929 remote = localrepo.locallegacypeer(remote.local())
928 remote = localrepo.locallegacypeer(remote.local())
930 common, _in, hds = treediscovery.findcommonincoming(
929 common, _in, hds = treediscovery.findcommonincoming(
931 repo, remote, force=True
930 repo, remote, force=True
932 )
931 )
933 common = set(common)
932 common = set(common)
934 if not opts.get(b'nonheads'):
933 if not opts.get(b'nonheads'):
935 ui.writenoi18n(
934 ui.writenoi18n(
936 b"unpruned common: %s\n"
935 b"unpruned common: %s\n"
937 % b" ".join(sorted(short(n) for n in common))
936 % b" ".join(sorted(short(n) for n in common))
938 )
937 )
939
938
940 clnode = repo.changelog.node
939 clnode = repo.changelog.node
941 common = repo.revs(b'heads(::%ln)', common)
940 common = repo.revs(b'heads(::%ln)', common)
942 common = {clnode(r) for r in common}
941 common = {clnode(r) for r in common}
943 return common, hds
942 return common, hds
944
943
945 else:
944 else:
946
945
947 def doit(pushedrevs, remoteheads, remote=remote):
946 def doit(pushedrevs, remoteheads, remote=remote):
948 nodes = None
947 nodes = None
949 if pushedrevs:
948 if pushedrevs:
950 revs = scmutil.revrange(repo, pushedrevs)
949 revs = scmutil.revrange(repo, pushedrevs)
951 nodes = [repo[r].node() for r in revs]
950 nodes = [repo[r].node() for r in revs]
952 common, any, hds = setdiscovery.findcommonheads(
951 common, any, hds = setdiscovery.findcommonheads(
953 ui, repo, remote, ancestorsof=nodes
952 ui, repo, remote, ancestorsof=nodes
954 )
953 )
955 return common, hds
954 return common, hds
956
955
957 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
956 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
958 localrevs = opts[b'rev']
957 localrevs = opts[b'rev']
959 with util.timedcm('debug-discovery') as t:
958 with util.timedcm('debug-discovery') as t:
960 common, hds = doit(localrevs, remoterevs)
959 common, hds = doit(localrevs, remoterevs)
961
960
962 # compute all statistics
961 # compute all statistics
963 common = set(common)
962 common = set(common)
964 rheads = set(hds)
963 rheads = set(hds)
965 lheads = set(repo.heads())
964 lheads = set(repo.heads())
966
965
967 data = {}
966 data = {}
968 data[b'elapsed'] = t.elapsed
967 data[b'elapsed'] = t.elapsed
969 data[b'nb-common'] = len(common)
968 data[b'nb-common'] = len(common)
970 data[b'nb-common-local'] = len(common & lheads)
969 data[b'nb-common-local'] = len(common & lheads)
971 data[b'nb-common-remote'] = len(common & rheads)
970 data[b'nb-common-remote'] = len(common & rheads)
972 data[b'nb-common-both'] = len(common & rheads & lheads)
971 data[b'nb-common-both'] = len(common & rheads & lheads)
973 data[b'nb-local'] = len(lheads)
972 data[b'nb-local'] = len(lheads)
974 data[b'nb-local-missing'] = data[b'nb-local'] - data[b'nb-common-local']
973 data[b'nb-local-missing'] = data[b'nb-local'] - data[b'nb-common-local']
975 data[b'nb-remote'] = len(rheads)
974 data[b'nb-remote'] = len(rheads)
976 data[b'nb-remote-unknown'] = data[b'nb-remote'] - data[b'nb-common-remote']
975 data[b'nb-remote-unknown'] = data[b'nb-remote'] - data[b'nb-common-remote']
977 data[b'nb-revs'] = len(repo.revs(b'all()'))
976 data[b'nb-revs'] = len(repo.revs(b'all()'))
978 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
977 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
979 data[b'nb-revs-missing'] = data[b'nb-revs'] - data[b'nb-revs-common']
978 data[b'nb-revs-missing'] = data[b'nb-revs'] - data[b'nb-revs-common']
980
979
981 # display discovery summary
980 # display discovery summary
982 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
981 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
983 ui.writenoi18n(b"heads summary:\n")
982 ui.writenoi18n(b"heads summary:\n")
984 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
983 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
985 ui.writenoi18n(b" also local heads: %(nb-common-local)9d\n" % data)
984 ui.writenoi18n(b" also local heads: %(nb-common-local)9d\n" % data)
986 ui.writenoi18n(b" also remote heads: %(nb-common-remote)9d\n" % data)
985 ui.writenoi18n(b" also remote heads: %(nb-common-remote)9d\n" % data)
987 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
986 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
988 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
987 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
989 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
988 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
990 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
989 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
991 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
990 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
992 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
991 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
993 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
992 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
994 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
993 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
995 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
994 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
996 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
995 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
997
996
998 if ui.verbose:
997 if ui.verbose:
999 ui.writenoi18n(
998 ui.writenoi18n(
1000 b"common heads: %s\n" % b" ".join(sorted(short(n) for n in common))
999 b"common heads: %s\n" % b" ".join(sorted(short(n) for n in common))
1001 )
1000 )
1002
1001
1003
1002
1004 _chunksize = 4 << 10
1003 _chunksize = 4 << 10
1005
1004
1006
1005
1007 @command(
1006 @command(
1008 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1007 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1009 )
1008 )
1010 def debugdownload(ui, repo, url, output=None, **opts):
1009 def debugdownload(ui, repo, url, output=None, **opts):
1011 """download a resource using Mercurial logic and config
1010 """download a resource using Mercurial logic and config
1012 """
1011 """
1013 fh = urlmod.open(ui, url, output)
1012 fh = urlmod.open(ui, url, output)
1014
1013
1015 dest = ui
1014 dest = ui
1016 if output:
1015 if output:
1017 dest = open(output, b"wb", _chunksize)
1016 dest = open(output, b"wb", _chunksize)
1018 try:
1017 try:
1019 data = fh.read(_chunksize)
1018 data = fh.read(_chunksize)
1020 while data:
1019 while data:
1021 dest.write(data)
1020 dest.write(data)
1022 data = fh.read(_chunksize)
1021 data = fh.read(_chunksize)
1023 finally:
1022 finally:
1024 if output:
1023 if output:
1025 dest.close()
1024 dest.close()
1026
1025
1027
1026
1028 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1027 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1029 def debugextensions(ui, repo, **opts):
1028 def debugextensions(ui, repo, **opts):
1030 '''show information about active extensions'''
1029 '''show information about active extensions'''
1031 opts = pycompat.byteskwargs(opts)
1030 opts = pycompat.byteskwargs(opts)
1032 exts = extensions.extensions(ui)
1031 exts = extensions.extensions(ui)
1033 hgver = util.version()
1032 hgver = util.version()
1034 fm = ui.formatter(b'debugextensions', opts)
1033 fm = ui.formatter(b'debugextensions', opts)
1035 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1034 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1036 isinternal = extensions.ismoduleinternal(extmod)
1035 isinternal = extensions.ismoduleinternal(extmod)
1037 extsource = None
1036 extsource = None
1038
1037
1039 if util.safehasattr(extmod, '__file__'):
1038 if util.safehasattr(extmod, '__file__'):
1040 extsource = pycompat.fsencode(extmod.__file__)
1039 extsource = pycompat.fsencode(extmod.__file__)
1041 elif getattr(sys, 'oxidized', False):
1040 elif getattr(sys, 'oxidized', False):
1042 extsource = pycompat.sysexecutable
1041 extsource = pycompat.sysexecutable
1043 if isinternal:
1042 if isinternal:
1044 exttestedwith = [] # never expose magic string to users
1043 exttestedwith = [] # never expose magic string to users
1045 else:
1044 else:
1046 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1045 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1047 extbuglink = getattr(extmod, 'buglink', None)
1046 extbuglink = getattr(extmod, 'buglink', None)
1048
1047
1049 fm.startitem()
1048 fm.startitem()
1050
1049
1051 if ui.quiet or ui.verbose:
1050 if ui.quiet or ui.verbose:
1052 fm.write(b'name', b'%s\n', extname)
1051 fm.write(b'name', b'%s\n', extname)
1053 else:
1052 else:
1054 fm.write(b'name', b'%s', extname)
1053 fm.write(b'name', b'%s', extname)
1055 if isinternal or hgver in exttestedwith:
1054 if isinternal or hgver in exttestedwith:
1056 fm.plain(b'\n')
1055 fm.plain(b'\n')
1057 elif not exttestedwith:
1056 elif not exttestedwith:
1058 fm.plain(_(b' (untested!)\n'))
1057 fm.plain(_(b' (untested!)\n'))
1059 else:
1058 else:
1060 lasttestedversion = exttestedwith[-1]
1059 lasttestedversion = exttestedwith[-1]
1061 fm.plain(b' (%s!)\n' % lasttestedversion)
1060 fm.plain(b' (%s!)\n' % lasttestedversion)
1062
1061
1063 fm.condwrite(
1062 fm.condwrite(
1064 ui.verbose and extsource,
1063 ui.verbose and extsource,
1065 b'source',
1064 b'source',
1066 _(b' location: %s\n'),
1065 _(b' location: %s\n'),
1067 extsource or b"",
1066 extsource or b"",
1068 )
1067 )
1069
1068
1070 if ui.verbose:
1069 if ui.verbose:
1071 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1070 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1072 fm.data(bundled=isinternal)
1071 fm.data(bundled=isinternal)
1073
1072
1074 fm.condwrite(
1073 fm.condwrite(
1075 ui.verbose and exttestedwith,
1074 ui.verbose and exttestedwith,
1076 b'testedwith',
1075 b'testedwith',
1077 _(b' tested with: %s\n'),
1076 _(b' tested with: %s\n'),
1078 fm.formatlist(exttestedwith, name=b'ver'),
1077 fm.formatlist(exttestedwith, name=b'ver'),
1079 )
1078 )
1080
1079
1081 fm.condwrite(
1080 fm.condwrite(
1082 ui.verbose and extbuglink,
1081 ui.verbose and extbuglink,
1083 b'buglink',
1082 b'buglink',
1084 _(b' bug reporting: %s\n'),
1083 _(b' bug reporting: %s\n'),
1085 extbuglink or b"",
1084 extbuglink or b"",
1086 )
1085 )
1087
1086
1088 fm.end()
1087 fm.end()
1089
1088
1090
1089
1091 @command(
1090 @command(
1092 b'debugfileset',
1091 b'debugfileset',
1093 [
1092 [
1094 (
1093 (
1095 b'r',
1094 b'r',
1096 b'rev',
1095 b'rev',
1097 b'',
1096 b'',
1098 _(b'apply the filespec on this revision'),
1097 _(b'apply the filespec on this revision'),
1099 _(b'REV'),
1098 _(b'REV'),
1100 ),
1099 ),
1101 (
1100 (
1102 b'',
1101 b'',
1103 b'all-files',
1102 b'all-files',
1104 False,
1103 False,
1105 _(b'test files from all revisions and working directory'),
1104 _(b'test files from all revisions and working directory'),
1106 ),
1105 ),
1107 (
1106 (
1108 b's',
1107 b's',
1109 b'show-matcher',
1108 b'show-matcher',
1110 None,
1109 None,
1111 _(b'print internal representation of matcher'),
1110 _(b'print internal representation of matcher'),
1112 ),
1111 ),
1113 (
1112 (
1114 b'p',
1113 b'p',
1115 b'show-stage',
1114 b'show-stage',
1116 [],
1115 [],
1117 _(b'print parsed tree at the given stage'),
1116 _(b'print parsed tree at the given stage'),
1118 _(b'NAME'),
1117 _(b'NAME'),
1119 ),
1118 ),
1120 ],
1119 ],
1121 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1120 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1122 )
1121 )
1123 def debugfileset(ui, repo, expr, **opts):
1122 def debugfileset(ui, repo, expr, **opts):
1124 '''parse and apply a fileset specification'''
1123 '''parse and apply a fileset specification'''
1125 from . import fileset
1124 from . import fileset
1126
1125
1127 fileset.symbols # force import of fileset so we have predicates to optimize
1126 fileset.symbols # force import of fileset so we have predicates to optimize
1128 opts = pycompat.byteskwargs(opts)
1127 opts = pycompat.byteskwargs(opts)
1129 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1128 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1130
1129
1131 stages = [
1130 stages = [
1132 (b'parsed', pycompat.identity),
1131 (b'parsed', pycompat.identity),
1133 (b'analyzed', filesetlang.analyze),
1132 (b'analyzed', filesetlang.analyze),
1134 (b'optimized', filesetlang.optimize),
1133 (b'optimized', filesetlang.optimize),
1135 ]
1134 ]
1136 stagenames = set(n for n, f in stages)
1135 stagenames = set(n for n, f in stages)
1137
1136
1138 showalways = set()
1137 showalways = set()
1139 if ui.verbose and not opts[b'show_stage']:
1138 if ui.verbose and not opts[b'show_stage']:
1140 # show parsed tree by --verbose (deprecated)
1139 # show parsed tree by --verbose (deprecated)
1141 showalways.add(b'parsed')
1140 showalways.add(b'parsed')
1142 if opts[b'show_stage'] == [b'all']:
1141 if opts[b'show_stage'] == [b'all']:
1143 showalways.update(stagenames)
1142 showalways.update(stagenames)
1144 else:
1143 else:
1145 for n in opts[b'show_stage']:
1144 for n in opts[b'show_stage']:
1146 if n not in stagenames:
1145 if n not in stagenames:
1147 raise error.Abort(_(b'invalid stage name: %s') % n)
1146 raise error.Abort(_(b'invalid stage name: %s') % n)
1148 showalways.update(opts[b'show_stage'])
1147 showalways.update(opts[b'show_stage'])
1149
1148
1150 tree = filesetlang.parse(expr)
1149 tree = filesetlang.parse(expr)
1151 for n, f in stages:
1150 for n, f in stages:
1152 tree = f(tree)
1151 tree = f(tree)
1153 if n in showalways:
1152 if n in showalways:
1154 if opts[b'show_stage'] or n != b'parsed':
1153 if opts[b'show_stage'] or n != b'parsed':
1155 ui.write(b"* %s:\n" % n)
1154 ui.write(b"* %s:\n" % n)
1156 ui.write(filesetlang.prettyformat(tree), b"\n")
1155 ui.write(filesetlang.prettyformat(tree), b"\n")
1157
1156
1158 files = set()
1157 files = set()
1159 if opts[b'all_files']:
1158 if opts[b'all_files']:
1160 for r in repo:
1159 for r in repo:
1161 c = repo[r]
1160 c = repo[r]
1162 files.update(c.files())
1161 files.update(c.files())
1163 files.update(c.substate)
1162 files.update(c.substate)
1164 if opts[b'all_files'] or ctx.rev() is None:
1163 if opts[b'all_files'] or ctx.rev() is None:
1165 wctx = repo[None]
1164 wctx = repo[None]
1166 files.update(
1165 files.update(
1167 repo.dirstate.walk(
1166 repo.dirstate.walk(
1168 scmutil.matchall(repo),
1167 scmutil.matchall(repo),
1169 subrepos=list(wctx.substate),
1168 subrepos=list(wctx.substate),
1170 unknown=True,
1169 unknown=True,
1171 ignored=True,
1170 ignored=True,
1172 )
1171 )
1173 )
1172 )
1174 files.update(wctx.substate)
1173 files.update(wctx.substate)
1175 else:
1174 else:
1176 files.update(ctx.files())
1175 files.update(ctx.files())
1177 files.update(ctx.substate)
1176 files.update(ctx.substate)
1178
1177
1179 m = ctx.matchfileset(repo.getcwd(), expr)
1178 m = ctx.matchfileset(repo.getcwd(), expr)
1180 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1179 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1181 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1180 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1182 for f in sorted(files):
1181 for f in sorted(files):
1183 if not m(f):
1182 if not m(f):
1184 continue
1183 continue
1185 ui.write(b"%s\n" % f)
1184 ui.write(b"%s\n" % f)
1186
1185
1187
1186
1188 @command(b'debugformat', [] + cmdutil.formatteropts)
1187 @command(b'debugformat', [] + cmdutil.formatteropts)
1189 def debugformat(ui, repo, **opts):
1188 def debugformat(ui, repo, **opts):
1190 """display format information about the current repository
1189 """display format information about the current repository
1191
1190
1192 Use --verbose to get extra information about current config value and
1191 Use --verbose to get extra information about current config value and
1193 Mercurial default."""
1192 Mercurial default."""
1194 opts = pycompat.byteskwargs(opts)
1193 opts = pycompat.byteskwargs(opts)
1195 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1194 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1196 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1195 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1197
1196
1198 def makeformatname(name):
1197 def makeformatname(name):
1199 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1198 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1200
1199
1201 fm = ui.formatter(b'debugformat', opts)
1200 fm = ui.formatter(b'debugformat', opts)
1202 if fm.isplain():
1201 if fm.isplain():
1203
1202
1204 def formatvalue(value):
1203 def formatvalue(value):
1205 if util.safehasattr(value, b'startswith'):
1204 if util.safehasattr(value, b'startswith'):
1206 return value
1205 return value
1207 if value:
1206 if value:
1208 return b'yes'
1207 return b'yes'
1209 else:
1208 else:
1210 return b'no'
1209 return b'no'
1211
1210
1212 else:
1211 else:
1213 formatvalue = pycompat.identity
1212 formatvalue = pycompat.identity
1214
1213
1215 fm.plain(b'format-variant')
1214 fm.plain(b'format-variant')
1216 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1215 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1217 fm.plain(b' repo')
1216 fm.plain(b' repo')
1218 if ui.verbose:
1217 if ui.verbose:
1219 fm.plain(b' config default')
1218 fm.plain(b' config default')
1220 fm.plain(b'\n')
1219 fm.plain(b'\n')
1221 for fv in upgrade.allformatvariant:
1220 for fv in upgrade.allformatvariant:
1222 fm.startitem()
1221 fm.startitem()
1223 repovalue = fv.fromrepo(repo)
1222 repovalue = fv.fromrepo(repo)
1224 configvalue = fv.fromconfig(repo)
1223 configvalue = fv.fromconfig(repo)
1225
1224
1226 if repovalue != configvalue:
1225 if repovalue != configvalue:
1227 namelabel = b'formatvariant.name.mismatchconfig'
1226 namelabel = b'formatvariant.name.mismatchconfig'
1228 repolabel = b'formatvariant.repo.mismatchconfig'
1227 repolabel = b'formatvariant.repo.mismatchconfig'
1229 elif repovalue != fv.default:
1228 elif repovalue != fv.default:
1230 namelabel = b'formatvariant.name.mismatchdefault'
1229 namelabel = b'formatvariant.name.mismatchdefault'
1231 repolabel = b'formatvariant.repo.mismatchdefault'
1230 repolabel = b'formatvariant.repo.mismatchdefault'
1232 else:
1231 else:
1233 namelabel = b'formatvariant.name.uptodate'
1232 namelabel = b'formatvariant.name.uptodate'
1234 repolabel = b'formatvariant.repo.uptodate'
1233 repolabel = b'formatvariant.repo.uptodate'
1235
1234
1236 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1235 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1237 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1236 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1238 if fv.default != configvalue:
1237 if fv.default != configvalue:
1239 configlabel = b'formatvariant.config.special'
1238 configlabel = b'formatvariant.config.special'
1240 else:
1239 else:
1241 configlabel = b'formatvariant.config.default'
1240 configlabel = b'formatvariant.config.default'
1242 fm.condwrite(
1241 fm.condwrite(
1243 ui.verbose,
1242 ui.verbose,
1244 b'config',
1243 b'config',
1245 b' %6s',
1244 b' %6s',
1246 formatvalue(configvalue),
1245 formatvalue(configvalue),
1247 label=configlabel,
1246 label=configlabel,
1248 )
1247 )
1249 fm.condwrite(
1248 fm.condwrite(
1250 ui.verbose,
1249 ui.verbose,
1251 b'default',
1250 b'default',
1252 b' %7s',
1251 b' %7s',
1253 formatvalue(fv.default),
1252 formatvalue(fv.default),
1254 label=b'formatvariant.default',
1253 label=b'formatvariant.default',
1255 )
1254 )
1256 fm.plain(b'\n')
1255 fm.plain(b'\n')
1257 fm.end()
1256 fm.end()
1258
1257
1259
1258
1260 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1259 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1261 def debugfsinfo(ui, path=b"."):
1260 def debugfsinfo(ui, path=b"."):
1262 """show information detected about current filesystem"""
1261 """show information detected about current filesystem"""
1263 ui.writenoi18n(b'path: %s\n' % path)
1262 ui.writenoi18n(b'path: %s\n' % path)
1264 ui.writenoi18n(
1263 ui.writenoi18n(
1265 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1264 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1266 )
1265 )
1267 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1266 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1268 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1267 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1269 ui.writenoi18n(
1268 ui.writenoi18n(
1270 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1269 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1271 )
1270 )
1272 ui.writenoi18n(
1271 ui.writenoi18n(
1273 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1272 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1274 )
1273 )
1275 casesensitive = b'(unknown)'
1274 casesensitive = b'(unknown)'
1276 try:
1275 try:
1277 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1276 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1278 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1277 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1279 except OSError:
1278 except OSError:
1280 pass
1279 pass
1281 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1280 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1282
1281
1283
1282
1284 @command(
1283 @command(
1285 b'debuggetbundle',
1284 b'debuggetbundle',
1286 [
1285 [
1287 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1286 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1288 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1287 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1289 (
1288 (
1290 b't',
1289 b't',
1291 b'type',
1290 b'type',
1292 b'bzip2',
1291 b'bzip2',
1293 _(b'bundle compression type to use'),
1292 _(b'bundle compression type to use'),
1294 _(b'TYPE'),
1293 _(b'TYPE'),
1295 ),
1294 ),
1296 ],
1295 ],
1297 _(b'REPO FILE [-H|-C ID]...'),
1296 _(b'REPO FILE [-H|-C ID]...'),
1298 norepo=True,
1297 norepo=True,
1299 )
1298 )
1300 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1299 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1301 """retrieves a bundle from a repo
1300 """retrieves a bundle from a repo
1302
1301
1303 Every ID must be a full-length hex node id string. Saves the bundle to the
1302 Every ID must be a full-length hex node id string. Saves the bundle to the
1304 given file.
1303 given file.
1305 """
1304 """
1306 opts = pycompat.byteskwargs(opts)
1305 opts = pycompat.byteskwargs(opts)
1307 repo = hg.peer(ui, opts, repopath)
1306 repo = hg.peer(ui, opts, repopath)
1308 if not repo.capable(b'getbundle'):
1307 if not repo.capable(b'getbundle'):
1309 raise error.Abort(b"getbundle() not supported by target repository")
1308 raise error.Abort(b"getbundle() not supported by target repository")
1310 args = {}
1309 args = {}
1311 if common:
1310 if common:
1312 args['common'] = [bin(s) for s in common]
1311 args['common'] = [bin(s) for s in common]
1313 if head:
1312 if head:
1314 args['heads'] = [bin(s) for s in head]
1313 args['heads'] = [bin(s) for s in head]
1315 # TODO: get desired bundlecaps from command line.
1314 # TODO: get desired bundlecaps from command line.
1316 args['bundlecaps'] = None
1315 args['bundlecaps'] = None
1317 bundle = repo.getbundle(b'debug', **args)
1316 bundle = repo.getbundle(b'debug', **args)
1318
1317
1319 bundletype = opts.get(b'type', b'bzip2').lower()
1318 bundletype = opts.get(b'type', b'bzip2').lower()
1320 btypes = {
1319 btypes = {
1321 b'none': b'HG10UN',
1320 b'none': b'HG10UN',
1322 b'bzip2': b'HG10BZ',
1321 b'bzip2': b'HG10BZ',
1323 b'gzip': b'HG10GZ',
1322 b'gzip': b'HG10GZ',
1324 b'bundle2': b'HG20',
1323 b'bundle2': b'HG20',
1325 }
1324 }
1326 bundletype = btypes.get(bundletype)
1325 bundletype = btypes.get(bundletype)
1327 if bundletype not in bundle2.bundletypes:
1326 if bundletype not in bundle2.bundletypes:
1328 raise error.Abort(_(b'unknown bundle type specified with --type'))
1327 raise error.Abort(_(b'unknown bundle type specified with --type'))
1329 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1328 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1330
1329
1331
1330
1332 @command(b'debugignore', [], b'[FILE]')
1331 @command(b'debugignore', [], b'[FILE]')
1333 def debugignore(ui, repo, *files, **opts):
1332 def debugignore(ui, repo, *files, **opts):
1334 """display the combined ignore pattern and information about ignored files
1333 """display the combined ignore pattern and information about ignored files
1335
1334
1336 With no argument display the combined ignore pattern.
1335 With no argument display the combined ignore pattern.
1337
1336
1338 Given space separated file names, shows if the given file is ignored and
1337 Given space separated file names, shows if the given file is ignored and
1339 if so, show the ignore rule (file and line number) that matched it.
1338 if so, show the ignore rule (file and line number) that matched it.
1340 """
1339 """
1341 ignore = repo.dirstate._ignore
1340 ignore = repo.dirstate._ignore
1342 if not files:
1341 if not files:
1343 # Show all the patterns
1342 # Show all the patterns
1344 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1343 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1345 else:
1344 else:
1346 m = scmutil.match(repo[None], pats=files)
1345 m = scmutil.match(repo[None], pats=files)
1347 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1346 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1348 for f in m.files():
1347 for f in m.files():
1349 nf = util.normpath(f)
1348 nf = util.normpath(f)
1350 ignored = None
1349 ignored = None
1351 ignoredata = None
1350 ignoredata = None
1352 if nf != b'.':
1351 if nf != b'.':
1353 if ignore(nf):
1352 if ignore(nf):
1354 ignored = nf
1353 ignored = nf
1355 ignoredata = repo.dirstate._ignorefileandline(nf)
1354 ignoredata = repo.dirstate._ignorefileandline(nf)
1356 else:
1355 else:
1357 for p in pathutil.finddirs(nf):
1356 for p in pathutil.finddirs(nf):
1358 if ignore(p):
1357 if ignore(p):
1359 ignored = p
1358 ignored = p
1360 ignoredata = repo.dirstate._ignorefileandline(p)
1359 ignoredata = repo.dirstate._ignorefileandline(p)
1361 break
1360 break
1362 if ignored:
1361 if ignored:
1363 if ignored == nf:
1362 if ignored == nf:
1364 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1363 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1365 else:
1364 else:
1366 ui.write(
1365 ui.write(
1367 _(
1366 _(
1368 b"%s is ignored because of "
1367 b"%s is ignored because of "
1369 b"containing directory %s\n"
1368 b"containing directory %s\n"
1370 )
1369 )
1371 % (uipathfn(f), ignored)
1370 % (uipathfn(f), ignored)
1372 )
1371 )
1373 ignorefile, lineno, line = ignoredata
1372 ignorefile, lineno, line = ignoredata
1374 ui.write(
1373 ui.write(
1375 _(b"(ignore rule in %s, line %d: '%s')\n")
1374 _(b"(ignore rule in %s, line %d: '%s')\n")
1376 % (ignorefile, lineno, line)
1375 % (ignorefile, lineno, line)
1377 )
1376 )
1378 else:
1377 else:
1379 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1378 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1380
1379
1381
1380
1382 @command(
1381 @command(
1383 b'debugindex',
1382 b'debugindex',
1384 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1383 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1385 _(b'-c|-m|FILE'),
1384 _(b'-c|-m|FILE'),
1386 )
1385 )
1387 def debugindex(ui, repo, file_=None, **opts):
1386 def debugindex(ui, repo, file_=None, **opts):
1388 """dump index data for a storage primitive"""
1387 """dump index data for a storage primitive"""
1389 opts = pycompat.byteskwargs(opts)
1388 opts = pycompat.byteskwargs(opts)
1390 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1389 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1391
1390
1392 if ui.debugflag:
1391 if ui.debugflag:
1393 shortfn = hex
1392 shortfn = hex
1394 else:
1393 else:
1395 shortfn = short
1394 shortfn = short
1396
1395
1397 idlen = 12
1396 idlen = 12
1398 for i in store:
1397 for i in store:
1399 idlen = len(shortfn(store.node(i)))
1398 idlen = len(shortfn(store.node(i)))
1400 break
1399 break
1401
1400
1402 fm = ui.formatter(b'debugindex', opts)
1401 fm = ui.formatter(b'debugindex', opts)
1403 fm.plain(
1402 fm.plain(
1404 b' rev linkrev %s %s p2\n'
1403 b' rev linkrev %s %s p2\n'
1405 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1404 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1406 )
1405 )
1407
1406
1408 for rev in store:
1407 for rev in store:
1409 node = store.node(rev)
1408 node = store.node(rev)
1410 parents = store.parents(node)
1409 parents = store.parents(node)
1411
1410
1412 fm.startitem()
1411 fm.startitem()
1413 fm.write(b'rev', b'%6d ', rev)
1412 fm.write(b'rev', b'%6d ', rev)
1414 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1413 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1415 fm.write(b'node', b'%s ', shortfn(node))
1414 fm.write(b'node', b'%s ', shortfn(node))
1416 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1415 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1417 fm.write(b'p2', b'%s', shortfn(parents[1]))
1416 fm.write(b'p2', b'%s', shortfn(parents[1]))
1418 fm.plain(b'\n')
1417 fm.plain(b'\n')
1419
1418
1420 fm.end()
1419 fm.end()
1421
1420
1422
1421
1423 @command(
1422 @command(
1424 b'debugindexdot',
1423 b'debugindexdot',
1425 cmdutil.debugrevlogopts,
1424 cmdutil.debugrevlogopts,
1426 _(b'-c|-m|FILE'),
1425 _(b'-c|-m|FILE'),
1427 optionalrepo=True,
1426 optionalrepo=True,
1428 )
1427 )
1429 def debugindexdot(ui, repo, file_=None, **opts):
1428 def debugindexdot(ui, repo, file_=None, **opts):
1430 """dump an index DAG as a graphviz dot file"""
1429 """dump an index DAG as a graphviz dot file"""
1431 opts = pycompat.byteskwargs(opts)
1430 opts = pycompat.byteskwargs(opts)
1432 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1431 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1433 ui.writenoi18n(b"digraph G {\n")
1432 ui.writenoi18n(b"digraph G {\n")
1434 for i in r:
1433 for i in r:
1435 node = r.node(i)
1434 node = r.node(i)
1436 pp = r.parents(node)
1435 pp = r.parents(node)
1437 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1436 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1438 if pp[1] != nullid:
1437 if pp[1] != nullid:
1439 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1438 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1440 ui.write(b"}\n")
1439 ui.write(b"}\n")
1441
1440
1442
1441
1443 @command(b'debugindexstats', [])
1442 @command(b'debugindexstats', [])
1444 def debugindexstats(ui, repo):
1443 def debugindexstats(ui, repo):
1445 """show stats related to the changelog index"""
1444 """show stats related to the changelog index"""
1446 repo.changelog.shortest(nullid, 1)
1445 repo.changelog.shortest(nullid, 1)
1447 index = repo.changelog.index
1446 index = repo.changelog.index
1448 if not util.safehasattr(index, b'stats'):
1447 if not util.safehasattr(index, b'stats'):
1449 raise error.Abort(_(b'debugindexstats only works with native code'))
1448 raise error.Abort(_(b'debugindexstats only works with native code'))
1450 for k, v in sorted(index.stats().items()):
1449 for k, v in sorted(index.stats().items()):
1451 ui.write(b'%s: %d\n' % (k, v))
1450 ui.write(b'%s: %d\n' % (k, v))
1452
1451
1453
1452
1454 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1453 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1455 def debuginstall(ui, **opts):
1454 def debuginstall(ui, **opts):
1456 '''test Mercurial installation
1455 '''test Mercurial installation
1457
1456
1458 Returns 0 on success.
1457 Returns 0 on success.
1459 '''
1458 '''
1460 opts = pycompat.byteskwargs(opts)
1459 opts = pycompat.byteskwargs(opts)
1461
1460
1462 problems = 0
1461 problems = 0
1463
1462
1464 fm = ui.formatter(b'debuginstall', opts)
1463 fm = ui.formatter(b'debuginstall', opts)
1465 fm.startitem()
1464 fm.startitem()
1466
1465
1467 # encoding
1466 # encoding
1468 fm.write(b'encoding', _(b"checking encoding (%s)...\n"), encoding.encoding)
1467 fm.write(b'encoding', _(b"checking encoding (%s)...\n"), encoding.encoding)
1469 err = None
1468 err = None
1470 try:
1469 try:
1471 codecs.lookup(pycompat.sysstr(encoding.encoding))
1470 codecs.lookup(pycompat.sysstr(encoding.encoding))
1472 except LookupError as inst:
1471 except LookupError as inst:
1473 err = stringutil.forcebytestr(inst)
1472 err = stringutil.forcebytestr(inst)
1474 problems += 1
1473 problems += 1
1475 fm.condwrite(
1474 fm.condwrite(
1476 err,
1475 err,
1477 b'encodingerror',
1476 b'encodingerror',
1478 _(b" %s\n (check that your locale is properly set)\n"),
1477 _(b" %s\n (check that your locale is properly set)\n"),
1479 err,
1478 err,
1480 )
1479 )
1481
1480
1482 # Python
1481 # Python
1483 pythonlib = None
1482 pythonlib = None
1484 if util.safehasattr(os, '__file__'):
1483 if util.safehasattr(os, '__file__'):
1485 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1484 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1486 elif getattr(sys, 'oxidized', False):
1485 elif getattr(sys, 'oxidized', False):
1487 pythonlib = pycompat.sysexecutable
1486 pythonlib = pycompat.sysexecutable
1488
1487
1489 fm.write(
1488 fm.write(
1490 b'pythonexe',
1489 b'pythonexe',
1491 _(b"checking Python executable (%s)\n"),
1490 _(b"checking Python executable (%s)\n"),
1492 pycompat.sysexecutable or _(b"unknown"),
1491 pycompat.sysexecutable or _(b"unknown"),
1493 )
1492 )
1494 fm.write(
1493 fm.write(
1495 b'pythonimplementation',
1494 b'pythonimplementation',
1496 _(b"checking Python implementation (%s)\n"),
1495 _(b"checking Python implementation (%s)\n"),
1497 pycompat.sysbytes(platform.python_implementation()),
1496 pycompat.sysbytes(platform.python_implementation()),
1498 )
1497 )
1499 fm.write(
1498 fm.write(
1500 b'pythonver',
1499 b'pythonver',
1501 _(b"checking Python version (%s)\n"),
1500 _(b"checking Python version (%s)\n"),
1502 (b"%d.%d.%d" % sys.version_info[:3]),
1501 (b"%d.%d.%d" % sys.version_info[:3]),
1503 )
1502 )
1504 fm.write(
1503 fm.write(
1505 b'pythonlib',
1504 b'pythonlib',
1506 _(b"checking Python lib (%s)...\n"),
1505 _(b"checking Python lib (%s)...\n"),
1507 pythonlib or _(b"unknown"),
1506 pythonlib or _(b"unknown"),
1508 )
1507 )
1509
1508
1510 security = set(sslutil.supportedprotocols)
1509 security = set(sslutil.supportedprotocols)
1511 if sslutil.hassni:
1510 if sslutil.hassni:
1512 security.add(b'sni')
1511 security.add(b'sni')
1513
1512
1514 fm.write(
1513 fm.write(
1515 b'pythonsecurity',
1514 b'pythonsecurity',
1516 _(b"checking Python security support (%s)\n"),
1515 _(b"checking Python security support (%s)\n"),
1517 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1516 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1518 )
1517 )
1519
1518
1520 # These are warnings, not errors. So don't increment problem count. This
1519 # These are warnings, not errors. So don't increment problem count. This
1521 # may change in the future.
1520 # may change in the future.
1522 if b'tls1.2' not in security:
1521 if b'tls1.2' not in security:
1523 fm.plain(
1522 fm.plain(
1524 _(
1523 _(
1525 b' TLS 1.2 not supported by Python install; '
1524 b' TLS 1.2 not supported by Python install; '
1526 b'network connections lack modern security\n'
1525 b'network connections lack modern security\n'
1527 )
1526 )
1528 )
1527 )
1529 if b'sni' not in security:
1528 if b'sni' not in security:
1530 fm.plain(
1529 fm.plain(
1531 _(
1530 _(
1532 b' SNI not supported by Python install; may have '
1531 b' SNI not supported by Python install; may have '
1533 b'connectivity issues with some servers\n'
1532 b'connectivity issues with some servers\n'
1534 )
1533 )
1535 )
1534 )
1536
1535
1537 # TODO print CA cert info
1536 # TODO print CA cert info
1538
1537
1539 # hg version
1538 # hg version
1540 hgver = util.version()
1539 hgver = util.version()
1541 fm.write(
1540 fm.write(
1542 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1541 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1543 )
1542 )
1544 fm.write(
1543 fm.write(
1545 b'hgverextra',
1544 b'hgverextra',
1546 _(b"checking Mercurial custom build (%s)\n"),
1545 _(b"checking Mercurial custom build (%s)\n"),
1547 b'+'.join(hgver.split(b'+')[1:]),
1546 b'+'.join(hgver.split(b'+')[1:]),
1548 )
1547 )
1549
1548
1550 # compiled modules
1549 # compiled modules
1551 hgmodules = None
1550 hgmodules = None
1552 if util.safehasattr(sys.modules[__name__], '__file__'):
1551 if util.safehasattr(sys.modules[__name__], '__file__'):
1553 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1552 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1554 elif getattr(sys, 'oxidized', False):
1553 elif getattr(sys, 'oxidized', False):
1555 hgmodules = pycompat.sysexecutable
1554 hgmodules = pycompat.sysexecutable
1556
1555
1557 fm.write(
1556 fm.write(
1558 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1557 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1559 )
1558 )
1560 fm.write(
1559 fm.write(
1561 b'hgmodules',
1560 b'hgmodules',
1562 _(b"checking installed modules (%s)...\n"),
1561 _(b"checking installed modules (%s)...\n"),
1563 hgmodules or _(b"unknown"),
1562 hgmodules or _(b"unknown"),
1564 )
1563 )
1565
1564
1566 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1565 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1567 rustext = rustandc # for now, that's the only case
1566 rustext = rustandc # for now, that's the only case
1568 cext = policy.policy in (b'c', b'allow') or rustandc
1567 cext = policy.policy in (b'c', b'allow') or rustandc
1569 nopure = cext or rustext
1568 nopure = cext or rustext
1570 if nopure:
1569 if nopure:
1571 err = None
1570 err = None
1572 try:
1571 try:
1573 if cext:
1572 if cext:
1574 from .cext import ( # pytype: disable=import-error
1573 from .cext import ( # pytype: disable=import-error
1575 base85,
1574 base85,
1576 bdiff,
1575 bdiff,
1577 mpatch,
1576 mpatch,
1578 osutil,
1577 osutil,
1579 )
1578 )
1580
1579
1581 # quiet pyflakes
1580 # quiet pyflakes
1582 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1581 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1583 if rustext:
1582 if rustext:
1584 from .rustext import ( # pytype: disable=import-error
1583 from .rustext import ( # pytype: disable=import-error
1585 ancestor,
1584 ancestor,
1586 dirstate,
1585 dirstate,
1587 )
1586 )
1588
1587
1589 dir(ancestor), dir(dirstate) # quiet pyflakes
1588 dir(ancestor), dir(dirstate) # quiet pyflakes
1590 except Exception as inst:
1589 except Exception as inst:
1591 err = stringutil.forcebytestr(inst)
1590 err = stringutil.forcebytestr(inst)
1592 problems += 1
1591 problems += 1
1593 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1592 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1594
1593
1595 compengines = util.compengines._engines.values()
1594 compengines = util.compengines._engines.values()
1596 fm.write(
1595 fm.write(
1597 b'compengines',
1596 b'compengines',
1598 _(b'checking registered compression engines (%s)\n'),
1597 _(b'checking registered compression engines (%s)\n'),
1599 fm.formatlist(
1598 fm.formatlist(
1600 sorted(e.name() for e in compengines),
1599 sorted(e.name() for e in compengines),
1601 name=b'compengine',
1600 name=b'compengine',
1602 fmt=b'%s',
1601 fmt=b'%s',
1603 sep=b', ',
1602 sep=b', ',
1604 ),
1603 ),
1605 )
1604 )
1606 fm.write(
1605 fm.write(
1607 b'compenginesavail',
1606 b'compenginesavail',
1608 _(b'checking available compression engines (%s)\n'),
1607 _(b'checking available compression engines (%s)\n'),
1609 fm.formatlist(
1608 fm.formatlist(
1610 sorted(e.name() for e in compengines if e.available()),
1609 sorted(e.name() for e in compengines if e.available()),
1611 name=b'compengine',
1610 name=b'compengine',
1612 fmt=b'%s',
1611 fmt=b'%s',
1613 sep=b', ',
1612 sep=b', ',
1614 ),
1613 ),
1615 )
1614 )
1616 wirecompengines = compression.compengines.supportedwireengines(
1615 wirecompengines = compression.compengines.supportedwireengines(
1617 compression.SERVERROLE
1616 compression.SERVERROLE
1618 )
1617 )
1619 fm.write(
1618 fm.write(
1620 b'compenginesserver',
1619 b'compenginesserver',
1621 _(
1620 _(
1622 b'checking available compression engines '
1621 b'checking available compression engines '
1623 b'for wire protocol (%s)\n'
1622 b'for wire protocol (%s)\n'
1624 ),
1623 ),
1625 fm.formatlist(
1624 fm.formatlist(
1626 [e.name() for e in wirecompengines if e.wireprotosupport()],
1625 [e.name() for e in wirecompengines if e.wireprotosupport()],
1627 name=b'compengine',
1626 name=b'compengine',
1628 fmt=b'%s',
1627 fmt=b'%s',
1629 sep=b', ',
1628 sep=b', ',
1630 ),
1629 ),
1631 )
1630 )
1632 re2 = b'missing'
1631 re2 = b'missing'
1633 if util._re2:
1632 if util._re2:
1634 re2 = b'available'
1633 re2 = b'available'
1635 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1634 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1636 fm.data(re2=bool(util._re2))
1635 fm.data(re2=bool(util._re2))
1637
1636
1638 # templates
1637 # templates
1639 p = templater.templatepaths()
1638 p = templater.templatepaths()
1640 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1639 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1641 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1640 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1642 if p:
1641 if p:
1643 m = templater.templatepath(b"map-cmdline.default")
1642 m = templater.templatepath(b"map-cmdline.default")
1644 if m:
1643 if m:
1645 # template found, check if it is working
1644 # template found, check if it is working
1646 err = None
1645 err = None
1647 try:
1646 try:
1648 templater.templater.frommapfile(m)
1647 templater.templater.frommapfile(m)
1649 except Exception as inst:
1648 except Exception as inst:
1650 err = stringutil.forcebytestr(inst)
1649 err = stringutil.forcebytestr(inst)
1651 p = None
1650 p = None
1652 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1651 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1653 else:
1652 else:
1654 p = None
1653 p = None
1655 fm.condwrite(
1654 fm.condwrite(
1656 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1655 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1657 )
1656 )
1658 fm.condwrite(
1657 fm.condwrite(
1659 not m,
1658 not m,
1660 b'defaulttemplatenotfound',
1659 b'defaulttemplatenotfound',
1661 _(b" template '%s' not found\n"),
1660 _(b" template '%s' not found\n"),
1662 b"default",
1661 b"default",
1663 )
1662 )
1664 if not p:
1663 if not p:
1665 problems += 1
1664 problems += 1
1666 fm.condwrite(
1665 fm.condwrite(
1667 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1666 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1668 )
1667 )
1669
1668
1670 # editor
1669 # editor
1671 editor = ui.geteditor()
1670 editor = ui.geteditor()
1672 editor = util.expandpath(editor)
1671 editor = util.expandpath(editor)
1673 editorbin = procutil.shellsplit(editor)[0]
1672 editorbin = procutil.shellsplit(editor)[0]
1674 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1673 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1675 cmdpath = procutil.findexe(editorbin)
1674 cmdpath = procutil.findexe(editorbin)
1676 fm.condwrite(
1675 fm.condwrite(
1677 not cmdpath and editor == b'vi',
1676 not cmdpath and editor == b'vi',
1678 b'vinotfound',
1677 b'vinotfound',
1679 _(
1678 _(
1680 b" No commit editor set and can't find %s in PATH\n"
1679 b" No commit editor set and can't find %s in PATH\n"
1681 b" (specify a commit editor in your configuration"
1680 b" (specify a commit editor in your configuration"
1682 b" file)\n"
1681 b" file)\n"
1683 ),
1682 ),
1684 not cmdpath and editor == b'vi' and editorbin,
1683 not cmdpath and editor == b'vi' and editorbin,
1685 )
1684 )
1686 fm.condwrite(
1685 fm.condwrite(
1687 not cmdpath and editor != b'vi',
1686 not cmdpath and editor != b'vi',
1688 b'editornotfound',
1687 b'editornotfound',
1689 _(
1688 _(
1690 b" Can't find editor '%s' in PATH\n"
1689 b" Can't find editor '%s' in PATH\n"
1691 b" (specify a commit editor in your configuration"
1690 b" (specify a commit editor in your configuration"
1692 b" file)\n"
1691 b" file)\n"
1693 ),
1692 ),
1694 not cmdpath and editorbin,
1693 not cmdpath and editorbin,
1695 )
1694 )
1696 if not cmdpath and editor != b'vi':
1695 if not cmdpath and editor != b'vi':
1697 problems += 1
1696 problems += 1
1698
1697
1699 # check username
1698 # check username
1700 username = None
1699 username = None
1701 err = None
1700 err = None
1702 try:
1701 try:
1703 username = ui.username()
1702 username = ui.username()
1704 except error.Abort as e:
1703 except error.Abort as e:
1705 err = stringutil.forcebytestr(e)
1704 err = stringutil.forcebytestr(e)
1706 problems += 1
1705 problems += 1
1707
1706
1708 fm.condwrite(
1707 fm.condwrite(
1709 username, b'username', _(b"checking username (%s)\n"), username
1708 username, b'username', _(b"checking username (%s)\n"), username
1710 )
1709 )
1711 fm.condwrite(
1710 fm.condwrite(
1712 err,
1711 err,
1713 b'usernameerror',
1712 b'usernameerror',
1714 _(
1713 _(
1715 b"checking username...\n %s\n"
1714 b"checking username...\n %s\n"
1716 b" (specify a username in your configuration file)\n"
1715 b" (specify a username in your configuration file)\n"
1717 ),
1716 ),
1718 err,
1717 err,
1719 )
1718 )
1720
1719
1721 for name, mod in extensions.extensions():
1720 for name, mod in extensions.extensions():
1722 handler = getattr(mod, 'debuginstall', None)
1721 handler = getattr(mod, 'debuginstall', None)
1723 if handler is not None:
1722 if handler is not None:
1724 problems += handler(ui, fm)
1723 problems += handler(ui, fm)
1725
1724
1726 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1725 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1727 if not problems:
1726 if not problems:
1728 fm.data(problems=problems)
1727 fm.data(problems=problems)
1729 fm.condwrite(
1728 fm.condwrite(
1730 problems,
1729 problems,
1731 b'problems',
1730 b'problems',
1732 _(b"%d problems detected, please check your install!\n"),
1731 _(b"%d problems detected, please check your install!\n"),
1733 problems,
1732 problems,
1734 )
1733 )
1735 fm.end()
1734 fm.end()
1736
1735
1737 return problems
1736 return problems
1738
1737
1739
1738
1740 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1739 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1741 def debugknown(ui, repopath, *ids, **opts):
1740 def debugknown(ui, repopath, *ids, **opts):
1742 """test whether node ids are known to a repo
1741 """test whether node ids are known to a repo
1743
1742
1744 Every ID must be a full-length hex node id string. Returns a list of 0s
1743 Every ID must be a full-length hex node id string. Returns a list of 0s
1745 and 1s indicating unknown/known.
1744 and 1s indicating unknown/known.
1746 """
1745 """
1747 opts = pycompat.byteskwargs(opts)
1746 opts = pycompat.byteskwargs(opts)
1748 repo = hg.peer(ui, opts, repopath)
1747 repo = hg.peer(ui, opts, repopath)
1749 if not repo.capable(b'known'):
1748 if not repo.capable(b'known'):
1750 raise error.Abort(b"known() not supported by target repository")
1749 raise error.Abort(b"known() not supported by target repository")
1751 flags = repo.known([bin(s) for s in ids])
1750 flags = repo.known([bin(s) for s in ids])
1752 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1751 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1753
1752
1754
1753
1755 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1754 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1756 def debuglabelcomplete(ui, repo, *args):
1755 def debuglabelcomplete(ui, repo, *args):
1757 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1756 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1758 debugnamecomplete(ui, repo, *args)
1757 debugnamecomplete(ui, repo, *args)
1759
1758
1760
1759
1761 @command(
1760 @command(
1762 b'debuglocks',
1761 b'debuglocks',
1763 [
1762 [
1764 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1763 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1765 (
1764 (
1766 b'W',
1765 b'W',
1767 b'force-wlock',
1766 b'force-wlock',
1768 None,
1767 None,
1769 _(b'free the working state lock (DANGEROUS)'),
1768 _(b'free the working state lock (DANGEROUS)'),
1770 ),
1769 ),
1771 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1770 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1772 (
1771 (
1773 b'S',
1772 b'S',
1774 b'set-wlock',
1773 b'set-wlock',
1775 None,
1774 None,
1776 _(b'set the working state lock until stopped'),
1775 _(b'set the working state lock until stopped'),
1777 ),
1776 ),
1778 ],
1777 ],
1779 _(b'[OPTION]...'),
1778 _(b'[OPTION]...'),
1780 )
1779 )
1781 def debuglocks(ui, repo, **opts):
1780 def debuglocks(ui, repo, **opts):
1782 """show or modify state of locks
1781 """show or modify state of locks
1783
1782
1784 By default, this command will show which locks are held. This
1783 By default, this command will show which locks are held. This
1785 includes the user and process holding the lock, the amount of time
1784 includes the user and process holding the lock, the amount of time
1786 the lock has been held, and the machine name where the process is
1785 the lock has been held, and the machine name where the process is
1787 running if it's not local.
1786 running if it's not local.
1788
1787
1789 Locks protect the integrity of Mercurial's data, so should be
1788 Locks protect the integrity of Mercurial's data, so should be
1790 treated with care. System crashes or other interruptions may cause
1789 treated with care. System crashes or other interruptions may cause
1791 locks to not be properly released, though Mercurial will usually
1790 locks to not be properly released, though Mercurial will usually
1792 detect and remove such stale locks automatically.
1791 detect and remove such stale locks automatically.
1793
1792
1794 However, detecting stale locks may not always be possible (for
1793 However, detecting stale locks may not always be possible (for
1795 instance, on a shared filesystem). Removing locks may also be
1794 instance, on a shared filesystem). Removing locks may also be
1796 blocked by filesystem permissions.
1795 blocked by filesystem permissions.
1797
1796
1798 Setting a lock will prevent other commands from changing the data.
1797 Setting a lock will prevent other commands from changing the data.
1799 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1798 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1800 The set locks are removed when the command exits.
1799 The set locks are removed when the command exits.
1801
1800
1802 Returns 0 if no locks are held.
1801 Returns 0 if no locks are held.
1803
1802
1804 """
1803 """
1805
1804
1806 if opts.get('force_lock'):
1805 if opts.get('force_lock'):
1807 repo.svfs.unlink(b'lock')
1806 repo.svfs.unlink(b'lock')
1808 if opts.get('force_wlock'):
1807 if opts.get('force_wlock'):
1809 repo.vfs.unlink(b'wlock')
1808 repo.vfs.unlink(b'wlock')
1810 if opts.get('force_lock') or opts.get('force_wlock'):
1809 if opts.get('force_lock') or opts.get('force_wlock'):
1811 return 0
1810 return 0
1812
1811
1813 locks = []
1812 locks = []
1814 try:
1813 try:
1815 if opts.get('set_wlock'):
1814 if opts.get('set_wlock'):
1816 try:
1815 try:
1817 locks.append(repo.wlock(False))
1816 locks.append(repo.wlock(False))
1818 except error.LockHeld:
1817 except error.LockHeld:
1819 raise error.Abort(_(b'wlock is already held'))
1818 raise error.Abort(_(b'wlock is already held'))
1820 if opts.get('set_lock'):
1819 if opts.get('set_lock'):
1821 try:
1820 try:
1822 locks.append(repo.lock(False))
1821 locks.append(repo.lock(False))
1823 except error.LockHeld:
1822 except error.LockHeld:
1824 raise error.Abort(_(b'lock is already held'))
1823 raise error.Abort(_(b'lock is already held'))
1825 if len(locks):
1824 if len(locks):
1826 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1825 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1827 return 0
1826 return 0
1828 finally:
1827 finally:
1829 release(*locks)
1828 release(*locks)
1830
1829
1831 now = time.time()
1830 now = time.time()
1832 held = 0
1831 held = 0
1833
1832
1834 def report(vfs, name, method):
1833 def report(vfs, name, method):
1835 # this causes stale locks to get reaped for more accurate reporting
1834 # this causes stale locks to get reaped for more accurate reporting
1836 try:
1835 try:
1837 l = method(False)
1836 l = method(False)
1838 except error.LockHeld:
1837 except error.LockHeld:
1839 l = None
1838 l = None
1840
1839
1841 if l:
1840 if l:
1842 l.release()
1841 l.release()
1843 else:
1842 else:
1844 try:
1843 try:
1845 st = vfs.lstat(name)
1844 st = vfs.lstat(name)
1846 age = now - st[stat.ST_MTIME]
1845 age = now - st[stat.ST_MTIME]
1847 user = util.username(st.st_uid)
1846 user = util.username(st.st_uid)
1848 locker = vfs.readlock(name)
1847 locker = vfs.readlock(name)
1849 if b":" in locker:
1848 if b":" in locker:
1850 host, pid = locker.split(b':')
1849 host, pid = locker.split(b':')
1851 if host == socket.gethostname():
1850 if host == socket.gethostname():
1852 locker = b'user %s, process %s' % (user or b'None', pid)
1851 locker = b'user %s, process %s' % (user or b'None', pid)
1853 else:
1852 else:
1854 locker = b'user %s, process %s, host %s' % (
1853 locker = b'user %s, process %s, host %s' % (
1855 user or b'None',
1854 user or b'None',
1856 pid,
1855 pid,
1857 host,
1856 host,
1858 )
1857 )
1859 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1858 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1860 return 1
1859 return 1
1861 except OSError as e:
1860 except OSError as e:
1862 if e.errno != errno.ENOENT:
1861 if e.errno != errno.ENOENT:
1863 raise
1862 raise
1864
1863
1865 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1864 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1866 return 0
1865 return 0
1867
1866
1868 held += report(repo.svfs, b"lock", repo.lock)
1867 held += report(repo.svfs, b"lock", repo.lock)
1869 held += report(repo.vfs, b"wlock", repo.wlock)
1868 held += report(repo.vfs, b"wlock", repo.wlock)
1870
1869
1871 return held
1870 return held
1872
1871
1873
1872
1874 @command(
1873 @command(
1875 b'debugmanifestfulltextcache',
1874 b'debugmanifestfulltextcache',
1876 [
1875 [
1877 (b'', b'clear', False, _(b'clear the cache')),
1876 (b'', b'clear', False, _(b'clear the cache')),
1878 (
1877 (
1879 b'a',
1878 b'a',
1880 b'add',
1879 b'add',
1881 [],
1880 [],
1882 _(b'add the given manifest nodes to the cache'),
1881 _(b'add the given manifest nodes to the cache'),
1883 _(b'NODE'),
1882 _(b'NODE'),
1884 ),
1883 ),
1885 ],
1884 ],
1886 b'',
1885 b'',
1887 )
1886 )
1888 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1887 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1889 """show, clear or amend the contents of the manifest fulltext cache"""
1888 """show, clear or amend the contents of the manifest fulltext cache"""
1890
1889
1891 def getcache():
1890 def getcache():
1892 r = repo.manifestlog.getstorage(b'')
1891 r = repo.manifestlog.getstorage(b'')
1893 try:
1892 try:
1894 return r._fulltextcache
1893 return r._fulltextcache
1895 except AttributeError:
1894 except AttributeError:
1896 msg = _(
1895 msg = _(
1897 b"Current revlog implementation doesn't appear to have a "
1896 b"Current revlog implementation doesn't appear to have a "
1898 b"manifest fulltext cache\n"
1897 b"manifest fulltext cache\n"
1899 )
1898 )
1900 raise error.Abort(msg)
1899 raise error.Abort(msg)
1901
1900
1902 if opts.get('clear'):
1901 if opts.get('clear'):
1903 with repo.wlock():
1902 with repo.wlock():
1904 cache = getcache()
1903 cache = getcache()
1905 cache.clear(clear_persisted_data=True)
1904 cache.clear(clear_persisted_data=True)
1906 return
1905 return
1907
1906
1908 if add:
1907 if add:
1909 with repo.wlock():
1908 with repo.wlock():
1910 m = repo.manifestlog
1909 m = repo.manifestlog
1911 store = m.getstorage(b'')
1910 store = m.getstorage(b'')
1912 for n in add:
1911 for n in add:
1913 try:
1912 try:
1914 manifest = m[store.lookup(n)]
1913 manifest = m[store.lookup(n)]
1915 except error.LookupError as e:
1914 except error.LookupError as e:
1916 raise error.Abort(e, hint=b"Check your manifest node id")
1915 raise error.Abort(e, hint=b"Check your manifest node id")
1917 manifest.read() # stores revisision in cache too
1916 manifest.read() # stores revisision in cache too
1918 return
1917 return
1919
1918
1920 cache = getcache()
1919 cache = getcache()
1921 if not len(cache):
1920 if not len(cache):
1922 ui.write(_(b'cache empty\n'))
1921 ui.write(_(b'cache empty\n'))
1923 else:
1922 else:
1924 ui.write(
1923 ui.write(
1925 _(
1924 _(
1926 b'cache contains %d manifest entries, in order of most to '
1925 b'cache contains %d manifest entries, in order of most to '
1927 b'least recent:\n'
1926 b'least recent:\n'
1928 )
1927 )
1929 % (len(cache),)
1928 % (len(cache),)
1930 )
1929 )
1931 totalsize = 0
1930 totalsize = 0
1932 for nodeid in cache:
1931 for nodeid in cache:
1933 # Use cache.get to not update the LRU order
1932 # Use cache.get to not update the LRU order
1934 data = cache.peek(nodeid)
1933 data = cache.peek(nodeid)
1935 size = len(data)
1934 size = len(data)
1936 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1935 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1937 ui.write(
1936 ui.write(
1938 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1937 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1939 )
1938 )
1940 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1939 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1941 ui.write(
1940 ui.write(
1942 _(b'total cache data size %s, on-disk %s\n')
1941 _(b'total cache data size %s, on-disk %s\n')
1943 % (util.bytecount(totalsize), util.bytecount(ondisk))
1942 % (util.bytecount(totalsize), util.bytecount(ondisk))
1944 )
1943 )
1945
1944
1946
1945
1947 @command(b'debugmergestate', [], b'')
1946 @command(b'debugmergestate', [] + cmdutil.templateopts, b'')
1948 def debugmergestate(ui, repo, *args):
1947 def debugmergestate(ui, repo, *args, **opts):
1949 """print merge state
1948 """print merge state
1950
1949
1951 Use --verbose to print out information about whether v1 or v2 merge state
1950 Use --verbose to print out information about whether v1 or v2 merge state
1952 was chosen."""
1951 was chosen."""
1953
1952
1954 def _hashornull(h):
1953 if ui.verbose:
1955 if h == nullhex:
1954 ms = mergemod.mergestate(repo)
1956 return b'null'
1955
1957 else:
1956 # sort so that reasonable information is on top
1958 return h
1957 v1records = ms._readrecordsv1()
1959
1958 v2records = ms._readrecordsv2()
1960 def printrecords(version):
1959
1961 ui.writenoi18n(b'* version %d records\n' % version)
1960 if not v1records and not v2records:
1962 if version == 1:
1961 pass
1963 records = v1records
1962 elif not v2records:
1963 ui.writenoi18n(b'no version 2 merge state\n')
1964 elif ms._v1v2match(v1records, v2records):
1965 ui.writenoi18n(b'v1 and v2 states match: using v2\n')
1964 else:
1966 else:
1965 records = v2records
1967 ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
1966
1968
1967 for rtype, record in records:
1969 opts = pycompat.byteskwargs(opts)
1968 # pretty print some record types
1970 if not opts[b'template']:
1969 if rtype == b'L':
1971 opts[b'template'] = (
1970 ui.writenoi18n(b'local: %s\n' % record)
1972 b'{if(commits, "", "no merge state found\n")}'
1971 elif rtype == b'O':
1973 b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
1972 ui.writenoi18n(b'other: %s\n' % record)
1974 b'{files % "file: {path} (state \\"{state}\\")\n'
1973 elif rtype == b'm':
1975 b' local path: {local_path} (flags \\"{local_flags}\\")\n'
1974 driver, mdstate = record.split(b'\0', 1)
1976 b' ancestor path: {ancestor_path} (node {ancestor_node})\n'
1975 ui.writenoi18n(
1977 b' other path: {other_path} (node {other_node})\n'
1976 b'merge driver: %s (state "%s")\n' % (driver, mdstate)
1978 b'{extras % " extra: {key} = {value}\n"}'
1977 )
1979 b'"}'
1978 elif rtype in b'FDC':
1980 )
1979 r = record.split(b'\0')
1981
1980 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1982 ms = mergemod.mergestate.read(repo)
1981 if version == 1:
1983
1982 onode = b'not stored in v1 format'
1984 fm = ui.formatter(b'debugmergestate', opts)
1983 flags = r[7]
1985 fm.startitem()
1984 else:
1986
1985 onode, flags = r[7:9]
1987 fm_commits = fm.nested(b'commits')
1986 ui.writenoi18n(
1988 if ms.active():
1987 b'file: %s (record type "%s", state "%s", hash %s)\n'
1989 for name, node, label_index in (
1988 % (f, rtype, state, _hashornull(hash))
1990 (b'local', ms.local, 0),
1989 )
1991 (b'other', ms.other, 1),
1990 ui.writenoi18n(
1992 ):
1991 b' local path: %s (flags "%s")\n' % (lfile, flags)
1993 fm_commits.startitem()
1992 )
1994 fm_commits.data(name=name)
1993 ui.writenoi18n(
1995 fm_commits.data(node=hex(node))
1994 b' ancestor path: %s (node %s)\n'
1996 if ms._labels and len(ms._labels) > label_index:
1995 % (afile, _hashornull(anode))
1997 fm_commits.data(label=ms._labels[label_index])
1996 )
1998 fm_commits.end()
1997 ui.writenoi18n(
1999
1998 b' other path: %s (node %s)\n'
2000 fm_files = fm.nested(b'files')
1999 % (ofile, _hashornull(onode))
2001 if ms.active():
2000 )
2002 for f in ms:
2001 elif rtype == b'f':
2003 fm_files.startitem()
2002 filename, rawextras = record.split(b'\0', 1)
2004 fm_files.data(path=f)
2003 extras = rawextras.split(b'\0')
2005 state = ms._state[f]
2004 i = 0
2006 fm_files.data(state=state[0])
2005 extrastrings = []
2007 fm_files.data(local_key=state[1])
2006 while i < len(extras):
2008 fm_files.data(local_path=state[2])
2007 extrastrings.append(b'%s = %s' % (extras[i], extras[i + 1]))
2009 fm_files.data(ancestor_path=state[3])
2008 i += 2
2010 fm_files.data(ancestor_node=state[4])
2009
2011 fm_files.data(other_path=state[5])
2010 ui.writenoi18n(
2012 fm_files.data(other_node=state[6])
2011 b'file extras: %s (%s)\n'
2013 fm_files.data(local_flags=state[7])
2012 % (filename, b', '.join(extrastrings))
2014 fm_extras = fm_files.nested(b'extras')
2013 )
2015 for k, v in ms.extras(f).items():
2014 elif rtype == b'l':
2016 fm_extras.startitem()
2015 labels = record.split(b'\0', 2)
2017 fm_extras.data(key=k)
2016 labels = [l for l in labels if len(l) > 0]
2018 fm_extras.data(value=v)
2017 ui.writenoi18n(b'labels:\n')
2019 fm_extras.end()
2018 ui.write((b' local: %s\n' % labels[0]))
2020
2019 ui.write((b' other: %s\n' % labels[1]))
2021 fm_files.end()
2020 if len(labels) > 2:
2022
2021 ui.write((b' base: %s\n' % labels[2]))
2023 fm.end()
2022 else:
2023 ui.writenoi18n(
2024 b'unrecognized entry: %s\t%s\n'
2025 % (rtype, record.replace(b'\0', b'\t'))
2026 )
2027
2028 # Avoid mergestate.read() since it may raise an exception for unsupported
2029 # merge state records. We shouldn't be doing this, but this is OK since this
2030 # command is pretty low-level.
2031 ms = mergemod.mergestate(repo)
2032
2033 # sort so that reasonable information is on top
2034 v1records = ms._readrecordsv1()
2035 v2records = ms._readrecordsv2()
2036 order = b'LOml'
2037
2038 def key(r):
2039 idx = order.find(r[0])
2040 if idx == -1:
2041 return (1, r[1])
2042 else:
2043 return (0, idx)
2044
2045 v1records.sort(key=key)
2046 v2records.sort(key=key)
2047
2048 if not v1records and not v2records:
2049 ui.writenoi18n(b'no merge state found\n')
2050 elif not v2records:
2051 ui.notenoi18n(b'no version 2 merge state\n')
2052 printrecords(1)
2053 elif ms._v1v2match(v1records, v2records):
2054 ui.notenoi18n(b'v1 and v2 states match: using v2\n')
2055 printrecords(2)
2056 else:
2057 ui.notenoi18n(b'v1 and v2 states mismatch: using v1\n')
2058 printrecords(1)
2059 if ui.verbose:
2060 printrecords(2)
2061
2024
2062
2025
2063 @command(b'debugnamecomplete', [], _(b'NAME...'))
2026 @command(b'debugnamecomplete', [], _(b'NAME...'))
2064 def debugnamecomplete(ui, repo, *args):
2027 def debugnamecomplete(ui, repo, *args):
2065 '''complete "names" - tags, open branch names, bookmark names'''
2028 '''complete "names" - tags, open branch names, bookmark names'''
2066
2029
2067 names = set()
2030 names = set()
2068 # since we previously only listed open branches, we will handle that
2031 # since we previously only listed open branches, we will handle that
2069 # specially (after this for loop)
2032 # specially (after this for loop)
2070 for name, ns in pycompat.iteritems(repo.names):
2033 for name, ns in pycompat.iteritems(repo.names):
2071 if name != b'branches':
2034 if name != b'branches':
2072 names.update(ns.listnames(repo))
2035 names.update(ns.listnames(repo))
2073 names.update(
2036 names.update(
2074 tag
2037 tag
2075 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2038 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2076 if not closed
2039 if not closed
2077 )
2040 )
2078 completions = set()
2041 completions = set()
2079 if not args:
2042 if not args:
2080 args = [b'']
2043 args = [b'']
2081 for a in args:
2044 for a in args:
2082 completions.update(n for n in names if n.startswith(a))
2045 completions.update(n for n in names if n.startswith(a))
2083 ui.write(b'\n'.join(sorted(completions)))
2046 ui.write(b'\n'.join(sorted(completions)))
2084 ui.write(b'\n')
2047 ui.write(b'\n')
2085
2048
2086
2049
2087 @command(
2050 @command(
2088 b'debugnodemap',
2051 b'debugnodemap',
2089 [
2052 [
2090 (
2053 (
2091 b'',
2054 b'',
2092 b'dump-new',
2055 b'dump-new',
2093 False,
2056 False,
2094 _(b'write a (new) persistent binary nodemap on stdin'),
2057 _(b'write a (new) persistent binary nodemap on stdin'),
2095 ),
2058 ),
2096 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
2059 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
2097 (
2060 (
2098 b'',
2061 b'',
2099 b'check',
2062 b'check',
2100 False,
2063 False,
2101 _(b'check that the data on disk data are correct.'),
2064 _(b'check that the data on disk data are correct.'),
2102 ),
2065 ),
2103 (
2066 (
2104 b'',
2067 b'',
2105 b'metadata',
2068 b'metadata',
2106 False,
2069 False,
2107 _(b'display the on disk meta data for the nodemap'),
2070 _(b'display the on disk meta data for the nodemap'),
2108 ),
2071 ),
2109 ],
2072 ],
2110 )
2073 )
2111 def debugnodemap(ui, repo, **opts):
2074 def debugnodemap(ui, repo, **opts):
2112 """write and inspect on disk nodemap
2075 """write and inspect on disk nodemap
2113 """
2076 """
2114 if opts['dump_new']:
2077 if opts['dump_new']:
2115 unfi = repo.unfiltered()
2078 unfi = repo.unfiltered()
2116 cl = unfi.changelog
2079 cl = unfi.changelog
2117 data = nodemap.persistent_data(cl.index)
2080 data = nodemap.persistent_data(cl.index)
2118 ui.write(data)
2081 ui.write(data)
2119 elif opts['dump_disk']:
2082 elif opts['dump_disk']:
2120 unfi = repo.unfiltered()
2083 unfi = repo.unfiltered()
2121 cl = unfi.changelog
2084 cl = unfi.changelog
2122 nm_data = nodemap.persisted_data(cl)
2085 nm_data = nodemap.persisted_data(cl)
2123 if nm_data is not None:
2086 if nm_data is not None:
2124 docket, data = nm_data
2087 docket, data = nm_data
2125 ui.write(data)
2088 ui.write(data)
2126 elif opts['check']:
2089 elif opts['check']:
2127 unfi = repo.unfiltered()
2090 unfi = repo.unfiltered()
2128 cl = unfi.changelog
2091 cl = unfi.changelog
2129 nm_data = nodemap.persisted_data(cl)
2092 nm_data = nodemap.persisted_data(cl)
2130 if nm_data is not None:
2093 if nm_data is not None:
2131 docket, data = nm_data
2094 docket, data = nm_data
2132 return nodemap.check_data(ui, cl.index, data)
2095 return nodemap.check_data(ui, cl.index, data)
2133 elif opts['metadata']:
2096 elif opts['metadata']:
2134 unfi = repo.unfiltered()
2097 unfi = repo.unfiltered()
2135 cl = unfi.changelog
2098 cl = unfi.changelog
2136 nm_data = nodemap.persisted_data(cl)
2099 nm_data = nodemap.persisted_data(cl)
2137 if nm_data is not None:
2100 if nm_data is not None:
2138 docket, data = nm_data
2101 docket, data = nm_data
2139 ui.write((b"uid: %s\n") % docket.uid)
2102 ui.write((b"uid: %s\n") % docket.uid)
2140 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2103 ui.write((b"tip-rev: %d\n") % docket.tip_rev)
2141 ui.write((b"data-length: %d\n") % docket.data_length)
2104 ui.write((b"data-length: %d\n") % docket.data_length)
2142 ui.write((b"data-unused: %d\n") % docket.data_unused)
2105 ui.write((b"data-unused: %d\n") % docket.data_unused)
2143
2106
2144
2107
2145 @command(
2108 @command(
2146 b'debugobsolete',
2109 b'debugobsolete',
2147 [
2110 [
2148 (b'', b'flags', 0, _(b'markers flag')),
2111 (b'', b'flags', 0, _(b'markers flag')),
2149 (
2112 (
2150 b'',
2113 b'',
2151 b'record-parents',
2114 b'record-parents',
2152 False,
2115 False,
2153 _(b'record parent information for the precursor'),
2116 _(b'record parent information for the precursor'),
2154 ),
2117 ),
2155 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2118 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2156 (
2119 (
2157 b'',
2120 b'',
2158 b'exclusive',
2121 b'exclusive',
2159 False,
2122 False,
2160 _(b'restrict display to markers only relevant to REV'),
2123 _(b'restrict display to markers only relevant to REV'),
2161 ),
2124 ),
2162 (b'', b'index', False, _(b'display index of the marker')),
2125 (b'', b'index', False, _(b'display index of the marker')),
2163 (b'', b'delete', [], _(b'delete markers specified by indices')),
2126 (b'', b'delete', [], _(b'delete markers specified by indices')),
2164 ]
2127 ]
2165 + cmdutil.commitopts2
2128 + cmdutil.commitopts2
2166 + cmdutil.formatteropts,
2129 + cmdutil.formatteropts,
2167 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2130 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2168 )
2131 )
2169 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2132 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2170 """create arbitrary obsolete marker
2133 """create arbitrary obsolete marker
2171
2134
2172 With no arguments, displays the list of obsolescence markers."""
2135 With no arguments, displays the list of obsolescence markers."""
2173
2136
2174 opts = pycompat.byteskwargs(opts)
2137 opts = pycompat.byteskwargs(opts)
2175
2138
2176 def parsenodeid(s):
2139 def parsenodeid(s):
2177 try:
2140 try:
2178 # We do not use revsingle/revrange functions here to accept
2141 # We do not use revsingle/revrange functions here to accept
2179 # arbitrary node identifiers, possibly not present in the
2142 # arbitrary node identifiers, possibly not present in the
2180 # local repository.
2143 # local repository.
2181 n = bin(s)
2144 n = bin(s)
2182 if len(n) != len(nullid):
2145 if len(n) != len(nullid):
2183 raise TypeError()
2146 raise TypeError()
2184 return n
2147 return n
2185 except TypeError:
2148 except TypeError:
2186 raise error.Abort(
2149 raise error.Abort(
2187 b'changeset references must be full hexadecimal '
2150 b'changeset references must be full hexadecimal '
2188 b'node identifiers'
2151 b'node identifiers'
2189 )
2152 )
2190
2153
2191 if opts.get(b'delete'):
2154 if opts.get(b'delete'):
2192 indices = []
2155 indices = []
2193 for v in opts.get(b'delete'):
2156 for v in opts.get(b'delete'):
2194 try:
2157 try:
2195 indices.append(int(v))
2158 indices.append(int(v))
2196 except ValueError:
2159 except ValueError:
2197 raise error.Abort(
2160 raise error.Abort(
2198 _(b'invalid index value: %r') % v,
2161 _(b'invalid index value: %r') % v,
2199 hint=_(b'use integers for indices'),
2162 hint=_(b'use integers for indices'),
2200 )
2163 )
2201
2164
2202 if repo.currenttransaction():
2165 if repo.currenttransaction():
2203 raise error.Abort(
2166 raise error.Abort(
2204 _(b'cannot delete obsmarkers in the middle of transaction.')
2167 _(b'cannot delete obsmarkers in the middle of transaction.')
2205 )
2168 )
2206
2169
2207 with repo.lock():
2170 with repo.lock():
2208 n = repair.deleteobsmarkers(repo.obsstore, indices)
2171 n = repair.deleteobsmarkers(repo.obsstore, indices)
2209 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2172 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2210
2173
2211 return
2174 return
2212
2175
2213 if precursor is not None:
2176 if precursor is not None:
2214 if opts[b'rev']:
2177 if opts[b'rev']:
2215 raise error.Abort(b'cannot select revision when creating marker')
2178 raise error.Abort(b'cannot select revision when creating marker')
2216 metadata = {}
2179 metadata = {}
2217 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2180 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2218 succs = tuple(parsenodeid(succ) for succ in successors)
2181 succs = tuple(parsenodeid(succ) for succ in successors)
2219 l = repo.lock()
2182 l = repo.lock()
2220 try:
2183 try:
2221 tr = repo.transaction(b'debugobsolete')
2184 tr = repo.transaction(b'debugobsolete')
2222 try:
2185 try:
2223 date = opts.get(b'date')
2186 date = opts.get(b'date')
2224 if date:
2187 if date:
2225 date = dateutil.parsedate(date)
2188 date = dateutil.parsedate(date)
2226 else:
2189 else:
2227 date = None
2190 date = None
2228 prec = parsenodeid(precursor)
2191 prec = parsenodeid(precursor)
2229 parents = None
2192 parents = None
2230 if opts[b'record_parents']:
2193 if opts[b'record_parents']:
2231 if prec not in repo.unfiltered():
2194 if prec not in repo.unfiltered():
2232 raise error.Abort(
2195 raise error.Abort(
2233 b'cannot used --record-parents on '
2196 b'cannot used --record-parents on '
2234 b'unknown changesets'
2197 b'unknown changesets'
2235 )
2198 )
2236 parents = repo.unfiltered()[prec].parents()
2199 parents = repo.unfiltered()[prec].parents()
2237 parents = tuple(p.node() for p in parents)
2200 parents = tuple(p.node() for p in parents)
2238 repo.obsstore.create(
2201 repo.obsstore.create(
2239 tr,
2202 tr,
2240 prec,
2203 prec,
2241 succs,
2204 succs,
2242 opts[b'flags'],
2205 opts[b'flags'],
2243 parents=parents,
2206 parents=parents,
2244 date=date,
2207 date=date,
2245 metadata=metadata,
2208 metadata=metadata,
2246 ui=ui,
2209 ui=ui,
2247 )
2210 )
2248 tr.close()
2211 tr.close()
2249 except ValueError as exc:
2212 except ValueError as exc:
2250 raise error.Abort(
2213 raise error.Abort(
2251 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2214 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2252 )
2215 )
2253 finally:
2216 finally:
2254 tr.release()
2217 tr.release()
2255 finally:
2218 finally:
2256 l.release()
2219 l.release()
2257 else:
2220 else:
2258 if opts[b'rev']:
2221 if opts[b'rev']:
2259 revs = scmutil.revrange(repo, opts[b'rev'])
2222 revs = scmutil.revrange(repo, opts[b'rev'])
2260 nodes = [repo[r].node() for r in revs]
2223 nodes = [repo[r].node() for r in revs]
2261 markers = list(
2224 markers = list(
2262 obsutil.getmarkers(
2225 obsutil.getmarkers(
2263 repo, nodes=nodes, exclusive=opts[b'exclusive']
2226 repo, nodes=nodes, exclusive=opts[b'exclusive']
2264 )
2227 )
2265 )
2228 )
2266 markers.sort(key=lambda x: x._data)
2229 markers.sort(key=lambda x: x._data)
2267 else:
2230 else:
2268 markers = obsutil.getmarkers(repo)
2231 markers = obsutil.getmarkers(repo)
2269
2232
2270 markerstoiter = markers
2233 markerstoiter = markers
2271 isrelevant = lambda m: True
2234 isrelevant = lambda m: True
2272 if opts.get(b'rev') and opts.get(b'index'):
2235 if opts.get(b'rev') and opts.get(b'index'):
2273 markerstoiter = obsutil.getmarkers(repo)
2236 markerstoiter = obsutil.getmarkers(repo)
2274 markerset = set(markers)
2237 markerset = set(markers)
2275 isrelevant = lambda m: m in markerset
2238 isrelevant = lambda m: m in markerset
2276
2239
2277 fm = ui.formatter(b'debugobsolete', opts)
2240 fm = ui.formatter(b'debugobsolete', opts)
2278 for i, m in enumerate(markerstoiter):
2241 for i, m in enumerate(markerstoiter):
2279 if not isrelevant(m):
2242 if not isrelevant(m):
2280 # marker can be irrelevant when we're iterating over a set
2243 # marker can be irrelevant when we're iterating over a set
2281 # of markers (markerstoiter) which is bigger than the set
2244 # of markers (markerstoiter) which is bigger than the set
2282 # of markers we want to display (markers)
2245 # of markers we want to display (markers)
2283 # this can happen if both --index and --rev options are
2246 # this can happen if both --index and --rev options are
2284 # provided and thus we need to iterate over all of the markers
2247 # provided and thus we need to iterate over all of the markers
2285 # to get the correct indices, but only display the ones that
2248 # to get the correct indices, but only display the ones that
2286 # are relevant to --rev value
2249 # are relevant to --rev value
2287 continue
2250 continue
2288 fm.startitem()
2251 fm.startitem()
2289 ind = i if opts.get(b'index') else None
2252 ind = i if opts.get(b'index') else None
2290 cmdutil.showmarker(fm, m, index=ind)
2253 cmdutil.showmarker(fm, m, index=ind)
2291 fm.end()
2254 fm.end()
2292
2255
2293
2256
2294 @command(
2257 @command(
2295 b'debugp1copies',
2258 b'debugp1copies',
2296 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2259 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2297 _(b'[-r REV]'),
2260 _(b'[-r REV]'),
2298 )
2261 )
2299 def debugp1copies(ui, repo, **opts):
2262 def debugp1copies(ui, repo, **opts):
2300 """dump copy information compared to p1"""
2263 """dump copy information compared to p1"""
2301
2264
2302 opts = pycompat.byteskwargs(opts)
2265 opts = pycompat.byteskwargs(opts)
2303 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2266 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2304 for dst, src in ctx.p1copies().items():
2267 for dst, src in ctx.p1copies().items():
2305 ui.write(b'%s -> %s\n' % (src, dst))
2268 ui.write(b'%s -> %s\n' % (src, dst))
2306
2269
2307
2270
2308 @command(
2271 @command(
2309 b'debugp2copies',
2272 b'debugp2copies',
2310 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2273 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2311 _(b'[-r REV]'),
2274 _(b'[-r REV]'),
2312 )
2275 )
2313 def debugp1copies(ui, repo, **opts):
2276 def debugp1copies(ui, repo, **opts):
2314 """dump copy information compared to p2"""
2277 """dump copy information compared to p2"""
2315
2278
2316 opts = pycompat.byteskwargs(opts)
2279 opts = pycompat.byteskwargs(opts)
2317 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2280 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2318 for dst, src in ctx.p2copies().items():
2281 for dst, src in ctx.p2copies().items():
2319 ui.write(b'%s -> %s\n' % (src, dst))
2282 ui.write(b'%s -> %s\n' % (src, dst))
2320
2283
2321
2284
2322 @command(
2285 @command(
2323 b'debugpathcomplete',
2286 b'debugpathcomplete',
2324 [
2287 [
2325 (b'f', b'full', None, _(b'complete an entire path')),
2288 (b'f', b'full', None, _(b'complete an entire path')),
2326 (b'n', b'normal', None, _(b'show only normal files')),
2289 (b'n', b'normal', None, _(b'show only normal files')),
2327 (b'a', b'added', None, _(b'show only added files')),
2290 (b'a', b'added', None, _(b'show only added files')),
2328 (b'r', b'removed', None, _(b'show only removed files')),
2291 (b'r', b'removed', None, _(b'show only removed files')),
2329 ],
2292 ],
2330 _(b'FILESPEC...'),
2293 _(b'FILESPEC...'),
2331 )
2294 )
2332 def debugpathcomplete(ui, repo, *specs, **opts):
2295 def debugpathcomplete(ui, repo, *specs, **opts):
2333 '''complete part or all of a tracked path
2296 '''complete part or all of a tracked path
2334
2297
2335 This command supports shells that offer path name completion. It
2298 This command supports shells that offer path name completion. It
2336 currently completes only files already known to the dirstate.
2299 currently completes only files already known to the dirstate.
2337
2300
2338 Completion extends only to the next path segment unless
2301 Completion extends only to the next path segment unless
2339 --full is specified, in which case entire paths are used.'''
2302 --full is specified, in which case entire paths are used.'''
2340
2303
2341 def complete(path, acceptable):
2304 def complete(path, acceptable):
2342 dirstate = repo.dirstate
2305 dirstate = repo.dirstate
2343 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2306 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2344 rootdir = repo.root + pycompat.ossep
2307 rootdir = repo.root + pycompat.ossep
2345 if spec != repo.root and not spec.startswith(rootdir):
2308 if spec != repo.root and not spec.startswith(rootdir):
2346 return [], []
2309 return [], []
2347 if os.path.isdir(spec):
2310 if os.path.isdir(spec):
2348 spec += b'/'
2311 spec += b'/'
2349 spec = spec[len(rootdir) :]
2312 spec = spec[len(rootdir) :]
2350 fixpaths = pycompat.ossep != b'/'
2313 fixpaths = pycompat.ossep != b'/'
2351 if fixpaths:
2314 if fixpaths:
2352 spec = spec.replace(pycompat.ossep, b'/')
2315 spec = spec.replace(pycompat.ossep, b'/')
2353 speclen = len(spec)
2316 speclen = len(spec)
2354 fullpaths = opts['full']
2317 fullpaths = opts['full']
2355 files, dirs = set(), set()
2318 files, dirs = set(), set()
2356 adddir, addfile = dirs.add, files.add
2319 adddir, addfile = dirs.add, files.add
2357 for f, st in pycompat.iteritems(dirstate):
2320 for f, st in pycompat.iteritems(dirstate):
2358 if f.startswith(spec) and st[0] in acceptable:
2321 if f.startswith(spec) and st[0] in acceptable:
2359 if fixpaths:
2322 if fixpaths:
2360 f = f.replace(b'/', pycompat.ossep)
2323 f = f.replace(b'/', pycompat.ossep)
2361 if fullpaths:
2324 if fullpaths:
2362 addfile(f)
2325 addfile(f)
2363 continue
2326 continue
2364 s = f.find(pycompat.ossep, speclen)
2327 s = f.find(pycompat.ossep, speclen)
2365 if s >= 0:
2328 if s >= 0:
2366 adddir(f[:s])
2329 adddir(f[:s])
2367 else:
2330 else:
2368 addfile(f)
2331 addfile(f)
2369 return files, dirs
2332 return files, dirs
2370
2333
2371 acceptable = b''
2334 acceptable = b''
2372 if opts['normal']:
2335 if opts['normal']:
2373 acceptable += b'nm'
2336 acceptable += b'nm'
2374 if opts['added']:
2337 if opts['added']:
2375 acceptable += b'a'
2338 acceptable += b'a'
2376 if opts['removed']:
2339 if opts['removed']:
2377 acceptable += b'r'
2340 acceptable += b'r'
2378 cwd = repo.getcwd()
2341 cwd = repo.getcwd()
2379 if not specs:
2342 if not specs:
2380 specs = [b'.']
2343 specs = [b'.']
2381
2344
2382 files, dirs = set(), set()
2345 files, dirs = set(), set()
2383 for spec in specs:
2346 for spec in specs:
2384 f, d = complete(spec, acceptable or b'nmar')
2347 f, d = complete(spec, acceptable or b'nmar')
2385 files.update(f)
2348 files.update(f)
2386 dirs.update(d)
2349 dirs.update(d)
2387 files.update(dirs)
2350 files.update(dirs)
2388 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2351 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2389 ui.write(b'\n')
2352 ui.write(b'\n')
2390
2353
2391
2354
2392 @command(
2355 @command(
2393 b'debugpathcopies',
2356 b'debugpathcopies',
2394 cmdutil.walkopts,
2357 cmdutil.walkopts,
2395 b'hg debugpathcopies REV1 REV2 [FILE]',
2358 b'hg debugpathcopies REV1 REV2 [FILE]',
2396 inferrepo=True,
2359 inferrepo=True,
2397 )
2360 )
2398 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2361 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2399 """show copies between two revisions"""
2362 """show copies between two revisions"""
2400 ctx1 = scmutil.revsingle(repo, rev1)
2363 ctx1 = scmutil.revsingle(repo, rev1)
2401 ctx2 = scmutil.revsingle(repo, rev2)
2364 ctx2 = scmutil.revsingle(repo, rev2)
2402 m = scmutil.match(ctx1, pats, opts)
2365 m = scmutil.match(ctx1, pats, opts)
2403 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2366 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2404 ui.write(b'%s -> %s\n' % (src, dst))
2367 ui.write(b'%s -> %s\n' % (src, dst))
2405
2368
2406
2369
2407 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2370 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2408 def debugpeer(ui, path):
2371 def debugpeer(ui, path):
2409 """establish a connection to a peer repository"""
2372 """establish a connection to a peer repository"""
2410 # Always enable peer request logging. Requires --debug to display
2373 # Always enable peer request logging. Requires --debug to display
2411 # though.
2374 # though.
2412 overrides = {
2375 overrides = {
2413 (b'devel', b'debug.peer-request'): True,
2376 (b'devel', b'debug.peer-request'): True,
2414 }
2377 }
2415
2378
2416 with ui.configoverride(overrides):
2379 with ui.configoverride(overrides):
2417 peer = hg.peer(ui, {}, path)
2380 peer = hg.peer(ui, {}, path)
2418
2381
2419 local = peer.local() is not None
2382 local = peer.local() is not None
2420 canpush = peer.canpush()
2383 canpush = peer.canpush()
2421
2384
2422 ui.write(_(b'url: %s\n') % peer.url())
2385 ui.write(_(b'url: %s\n') % peer.url())
2423 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2386 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2424 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2387 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2425
2388
2426
2389
2427 @command(
2390 @command(
2428 b'debugpickmergetool',
2391 b'debugpickmergetool',
2429 [
2392 [
2430 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2393 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2431 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2394 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2432 ]
2395 ]
2433 + cmdutil.walkopts
2396 + cmdutil.walkopts
2434 + cmdutil.mergetoolopts,
2397 + cmdutil.mergetoolopts,
2435 _(b'[PATTERN]...'),
2398 _(b'[PATTERN]...'),
2436 inferrepo=True,
2399 inferrepo=True,
2437 )
2400 )
2438 def debugpickmergetool(ui, repo, *pats, **opts):
2401 def debugpickmergetool(ui, repo, *pats, **opts):
2439 """examine which merge tool is chosen for specified file
2402 """examine which merge tool is chosen for specified file
2440
2403
2441 As described in :hg:`help merge-tools`, Mercurial examines
2404 As described in :hg:`help merge-tools`, Mercurial examines
2442 configurations below in this order to decide which merge tool is
2405 configurations below in this order to decide which merge tool is
2443 chosen for specified file.
2406 chosen for specified file.
2444
2407
2445 1. ``--tool`` option
2408 1. ``--tool`` option
2446 2. ``HGMERGE`` environment variable
2409 2. ``HGMERGE`` environment variable
2447 3. configurations in ``merge-patterns`` section
2410 3. configurations in ``merge-patterns`` section
2448 4. configuration of ``ui.merge``
2411 4. configuration of ``ui.merge``
2449 5. configurations in ``merge-tools`` section
2412 5. configurations in ``merge-tools`` section
2450 6. ``hgmerge`` tool (for historical reason only)
2413 6. ``hgmerge`` tool (for historical reason only)
2451 7. default tool for fallback (``:merge`` or ``:prompt``)
2414 7. default tool for fallback (``:merge`` or ``:prompt``)
2452
2415
2453 This command writes out examination result in the style below::
2416 This command writes out examination result in the style below::
2454
2417
2455 FILE = MERGETOOL
2418 FILE = MERGETOOL
2456
2419
2457 By default, all files known in the first parent context of the
2420 By default, all files known in the first parent context of the
2458 working directory are examined. Use file patterns and/or -I/-X
2421 working directory are examined. Use file patterns and/or -I/-X
2459 options to limit target files. -r/--rev is also useful to examine
2422 options to limit target files. -r/--rev is also useful to examine
2460 files in another context without actual updating to it.
2423 files in another context without actual updating to it.
2461
2424
2462 With --debug, this command shows warning messages while matching
2425 With --debug, this command shows warning messages while matching
2463 against ``merge-patterns`` and so on, too. It is recommended to
2426 against ``merge-patterns`` and so on, too. It is recommended to
2464 use this option with explicit file patterns and/or -I/-X options,
2427 use this option with explicit file patterns and/or -I/-X options,
2465 because this option increases amount of output per file according
2428 because this option increases amount of output per file according
2466 to configurations in hgrc.
2429 to configurations in hgrc.
2467
2430
2468 With -v/--verbose, this command shows configurations below at
2431 With -v/--verbose, this command shows configurations below at
2469 first (only if specified).
2432 first (only if specified).
2470
2433
2471 - ``--tool`` option
2434 - ``--tool`` option
2472 - ``HGMERGE`` environment variable
2435 - ``HGMERGE`` environment variable
2473 - configuration of ``ui.merge``
2436 - configuration of ``ui.merge``
2474
2437
2475 If merge tool is chosen before matching against
2438 If merge tool is chosen before matching against
2476 ``merge-patterns``, this command can't show any helpful
2439 ``merge-patterns``, this command can't show any helpful
2477 information, even with --debug. In such case, information above is
2440 information, even with --debug. In such case, information above is
2478 useful to know why a merge tool is chosen.
2441 useful to know why a merge tool is chosen.
2479 """
2442 """
2480 opts = pycompat.byteskwargs(opts)
2443 opts = pycompat.byteskwargs(opts)
2481 overrides = {}
2444 overrides = {}
2482 if opts[b'tool']:
2445 if opts[b'tool']:
2483 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2446 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2484 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2447 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2485
2448
2486 with ui.configoverride(overrides, b'debugmergepatterns'):
2449 with ui.configoverride(overrides, b'debugmergepatterns'):
2487 hgmerge = encoding.environ.get(b"HGMERGE")
2450 hgmerge = encoding.environ.get(b"HGMERGE")
2488 if hgmerge is not None:
2451 if hgmerge is not None:
2489 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2452 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2490 uimerge = ui.config(b"ui", b"merge")
2453 uimerge = ui.config(b"ui", b"merge")
2491 if uimerge:
2454 if uimerge:
2492 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2455 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2493
2456
2494 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2457 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2495 m = scmutil.match(ctx, pats, opts)
2458 m = scmutil.match(ctx, pats, opts)
2496 changedelete = opts[b'changedelete']
2459 changedelete = opts[b'changedelete']
2497 for path in ctx.walk(m):
2460 for path in ctx.walk(m):
2498 fctx = ctx[path]
2461 fctx = ctx[path]
2499 try:
2462 try:
2500 if not ui.debugflag:
2463 if not ui.debugflag:
2501 ui.pushbuffer(error=True)
2464 ui.pushbuffer(error=True)
2502 tool, toolpath = filemerge._picktool(
2465 tool, toolpath = filemerge._picktool(
2503 repo,
2466 repo,
2504 ui,
2467 ui,
2505 path,
2468 path,
2506 fctx.isbinary(),
2469 fctx.isbinary(),
2507 b'l' in fctx.flags(),
2470 b'l' in fctx.flags(),
2508 changedelete,
2471 changedelete,
2509 )
2472 )
2510 finally:
2473 finally:
2511 if not ui.debugflag:
2474 if not ui.debugflag:
2512 ui.popbuffer()
2475 ui.popbuffer()
2513 ui.write(b'%s = %s\n' % (path, tool))
2476 ui.write(b'%s = %s\n' % (path, tool))
2514
2477
2515
2478
2516 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2479 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2517 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2480 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2518 '''access the pushkey key/value protocol
2481 '''access the pushkey key/value protocol
2519
2482
2520 With two args, list the keys in the given namespace.
2483 With two args, list the keys in the given namespace.
2521
2484
2522 With five args, set a key to new if it currently is set to old.
2485 With five args, set a key to new if it currently is set to old.
2523 Reports success or failure.
2486 Reports success or failure.
2524 '''
2487 '''
2525
2488
2526 target = hg.peer(ui, {}, repopath)
2489 target = hg.peer(ui, {}, repopath)
2527 if keyinfo:
2490 if keyinfo:
2528 key, old, new = keyinfo
2491 key, old, new = keyinfo
2529 with target.commandexecutor() as e:
2492 with target.commandexecutor() as e:
2530 r = e.callcommand(
2493 r = e.callcommand(
2531 b'pushkey',
2494 b'pushkey',
2532 {
2495 {
2533 b'namespace': namespace,
2496 b'namespace': namespace,
2534 b'key': key,
2497 b'key': key,
2535 b'old': old,
2498 b'old': old,
2536 b'new': new,
2499 b'new': new,
2537 },
2500 },
2538 ).result()
2501 ).result()
2539
2502
2540 ui.status(pycompat.bytestr(r) + b'\n')
2503 ui.status(pycompat.bytestr(r) + b'\n')
2541 return not r
2504 return not r
2542 else:
2505 else:
2543 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2506 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2544 ui.write(
2507 ui.write(
2545 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2508 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2546 )
2509 )
2547
2510
2548
2511
2549 @command(b'debugpvec', [], _(b'A B'))
2512 @command(b'debugpvec', [], _(b'A B'))
2550 def debugpvec(ui, repo, a, b=None):
2513 def debugpvec(ui, repo, a, b=None):
2551 ca = scmutil.revsingle(repo, a)
2514 ca = scmutil.revsingle(repo, a)
2552 cb = scmutil.revsingle(repo, b)
2515 cb = scmutil.revsingle(repo, b)
2553 pa = pvec.ctxpvec(ca)
2516 pa = pvec.ctxpvec(ca)
2554 pb = pvec.ctxpvec(cb)
2517 pb = pvec.ctxpvec(cb)
2555 if pa == pb:
2518 if pa == pb:
2556 rel = b"="
2519 rel = b"="
2557 elif pa > pb:
2520 elif pa > pb:
2558 rel = b">"
2521 rel = b">"
2559 elif pa < pb:
2522 elif pa < pb:
2560 rel = b"<"
2523 rel = b"<"
2561 elif pa | pb:
2524 elif pa | pb:
2562 rel = b"|"
2525 rel = b"|"
2563 ui.write(_(b"a: %s\n") % pa)
2526 ui.write(_(b"a: %s\n") % pa)
2564 ui.write(_(b"b: %s\n") % pb)
2527 ui.write(_(b"b: %s\n") % pb)
2565 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2528 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2566 ui.write(
2529 ui.write(
2567 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2530 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2568 % (
2531 % (
2569 abs(pa._depth - pb._depth),
2532 abs(pa._depth - pb._depth),
2570 pvec._hamming(pa._vec, pb._vec),
2533 pvec._hamming(pa._vec, pb._vec),
2571 pa.distance(pb),
2534 pa.distance(pb),
2572 rel,
2535 rel,
2573 )
2536 )
2574 )
2537 )
2575
2538
2576
2539
2577 @command(
2540 @command(
2578 b'debugrebuilddirstate|debugrebuildstate',
2541 b'debugrebuilddirstate|debugrebuildstate',
2579 [
2542 [
2580 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2543 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2581 (
2544 (
2582 b'',
2545 b'',
2583 b'minimal',
2546 b'minimal',
2584 None,
2547 None,
2585 _(
2548 _(
2586 b'only rebuild files that are inconsistent with '
2549 b'only rebuild files that are inconsistent with '
2587 b'the working copy parent'
2550 b'the working copy parent'
2588 ),
2551 ),
2589 ),
2552 ),
2590 ],
2553 ],
2591 _(b'[-r REV]'),
2554 _(b'[-r REV]'),
2592 )
2555 )
2593 def debugrebuilddirstate(ui, repo, rev, **opts):
2556 def debugrebuilddirstate(ui, repo, rev, **opts):
2594 """rebuild the dirstate as it would look like for the given revision
2557 """rebuild the dirstate as it would look like for the given revision
2595
2558
2596 If no revision is specified the first current parent will be used.
2559 If no revision is specified the first current parent will be used.
2597
2560
2598 The dirstate will be set to the files of the given revision.
2561 The dirstate will be set to the files of the given revision.
2599 The actual working directory content or existing dirstate
2562 The actual working directory content or existing dirstate
2600 information such as adds or removes is not considered.
2563 information such as adds or removes is not considered.
2601
2564
2602 ``minimal`` will only rebuild the dirstate status for files that claim to be
2565 ``minimal`` will only rebuild the dirstate status for files that claim to be
2603 tracked but are not in the parent manifest, or that exist in the parent
2566 tracked but are not in the parent manifest, or that exist in the parent
2604 manifest but are not in the dirstate. It will not change adds, removes, or
2567 manifest but are not in the dirstate. It will not change adds, removes, or
2605 modified files that are in the working copy parent.
2568 modified files that are in the working copy parent.
2606
2569
2607 One use of this command is to make the next :hg:`status` invocation
2570 One use of this command is to make the next :hg:`status` invocation
2608 check the actual file content.
2571 check the actual file content.
2609 """
2572 """
2610 ctx = scmutil.revsingle(repo, rev)
2573 ctx = scmutil.revsingle(repo, rev)
2611 with repo.wlock():
2574 with repo.wlock():
2612 dirstate = repo.dirstate
2575 dirstate = repo.dirstate
2613 changedfiles = None
2576 changedfiles = None
2614 # See command doc for what minimal does.
2577 # See command doc for what minimal does.
2615 if opts.get('minimal'):
2578 if opts.get('minimal'):
2616 manifestfiles = set(ctx.manifest().keys())
2579 manifestfiles = set(ctx.manifest().keys())
2617 dirstatefiles = set(dirstate)
2580 dirstatefiles = set(dirstate)
2618 manifestonly = manifestfiles - dirstatefiles
2581 manifestonly = manifestfiles - dirstatefiles
2619 dsonly = dirstatefiles - manifestfiles
2582 dsonly = dirstatefiles - manifestfiles
2620 dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
2583 dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
2621 changedfiles = manifestonly | dsnotadded
2584 changedfiles = manifestonly | dsnotadded
2622
2585
2623 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2586 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2624
2587
2625
2588
2626 @command(b'debugrebuildfncache', [], b'')
2589 @command(b'debugrebuildfncache', [], b'')
2627 def debugrebuildfncache(ui, repo):
2590 def debugrebuildfncache(ui, repo):
2628 """rebuild the fncache file"""
2591 """rebuild the fncache file"""
2629 repair.rebuildfncache(ui, repo)
2592 repair.rebuildfncache(ui, repo)
2630
2593
2631
2594
2632 @command(
2595 @command(
2633 b'debugrename',
2596 b'debugrename',
2634 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2597 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2635 _(b'[-r REV] [FILE]...'),
2598 _(b'[-r REV] [FILE]...'),
2636 )
2599 )
2637 def debugrename(ui, repo, *pats, **opts):
2600 def debugrename(ui, repo, *pats, **opts):
2638 """dump rename information"""
2601 """dump rename information"""
2639
2602
2640 opts = pycompat.byteskwargs(opts)
2603 opts = pycompat.byteskwargs(opts)
2641 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2604 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2642 m = scmutil.match(ctx, pats, opts)
2605 m = scmutil.match(ctx, pats, opts)
2643 for abs in ctx.walk(m):
2606 for abs in ctx.walk(m):
2644 fctx = ctx[abs]
2607 fctx = ctx[abs]
2645 o = fctx.filelog().renamed(fctx.filenode())
2608 o = fctx.filelog().renamed(fctx.filenode())
2646 rel = repo.pathto(abs)
2609 rel = repo.pathto(abs)
2647 if o:
2610 if o:
2648 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2611 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2649 else:
2612 else:
2650 ui.write(_(b"%s not renamed\n") % rel)
2613 ui.write(_(b"%s not renamed\n") % rel)
2651
2614
2652
2615
2653 @command(
2616 @command(
2654 b'debugrevlog',
2617 b'debugrevlog',
2655 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2618 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2656 _(b'-c|-m|FILE'),
2619 _(b'-c|-m|FILE'),
2657 optionalrepo=True,
2620 optionalrepo=True,
2658 )
2621 )
2659 def debugrevlog(ui, repo, file_=None, **opts):
2622 def debugrevlog(ui, repo, file_=None, **opts):
2660 """show data and statistics about a revlog"""
2623 """show data and statistics about a revlog"""
2661 opts = pycompat.byteskwargs(opts)
2624 opts = pycompat.byteskwargs(opts)
2662 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2625 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2663
2626
2664 if opts.get(b"dump"):
2627 if opts.get(b"dump"):
2665 numrevs = len(r)
2628 numrevs = len(r)
2666 ui.write(
2629 ui.write(
2667 (
2630 (
2668 b"# rev p1rev p2rev start end deltastart base p1 p2"
2631 b"# rev p1rev p2rev start end deltastart base p1 p2"
2669 b" rawsize totalsize compression heads chainlen\n"
2632 b" rawsize totalsize compression heads chainlen\n"
2670 )
2633 )
2671 )
2634 )
2672 ts = 0
2635 ts = 0
2673 heads = set()
2636 heads = set()
2674
2637
2675 for rev in pycompat.xrange(numrevs):
2638 for rev in pycompat.xrange(numrevs):
2676 dbase = r.deltaparent(rev)
2639 dbase = r.deltaparent(rev)
2677 if dbase == -1:
2640 if dbase == -1:
2678 dbase = rev
2641 dbase = rev
2679 cbase = r.chainbase(rev)
2642 cbase = r.chainbase(rev)
2680 clen = r.chainlen(rev)
2643 clen = r.chainlen(rev)
2681 p1, p2 = r.parentrevs(rev)
2644 p1, p2 = r.parentrevs(rev)
2682 rs = r.rawsize(rev)
2645 rs = r.rawsize(rev)
2683 ts = ts + rs
2646 ts = ts + rs
2684 heads -= set(r.parentrevs(rev))
2647 heads -= set(r.parentrevs(rev))
2685 heads.add(rev)
2648 heads.add(rev)
2686 try:
2649 try:
2687 compression = ts / r.end(rev)
2650 compression = ts / r.end(rev)
2688 except ZeroDivisionError:
2651 except ZeroDivisionError:
2689 compression = 0
2652 compression = 0
2690 ui.write(
2653 ui.write(
2691 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2654 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2692 b"%11d %5d %8d\n"
2655 b"%11d %5d %8d\n"
2693 % (
2656 % (
2694 rev,
2657 rev,
2695 p1,
2658 p1,
2696 p2,
2659 p2,
2697 r.start(rev),
2660 r.start(rev),
2698 r.end(rev),
2661 r.end(rev),
2699 r.start(dbase),
2662 r.start(dbase),
2700 r.start(cbase),
2663 r.start(cbase),
2701 r.start(p1),
2664 r.start(p1),
2702 r.start(p2),
2665 r.start(p2),
2703 rs,
2666 rs,
2704 ts,
2667 ts,
2705 compression,
2668 compression,
2706 len(heads),
2669 len(heads),
2707 clen,
2670 clen,
2708 )
2671 )
2709 )
2672 )
2710 return 0
2673 return 0
2711
2674
2712 v = r.version
2675 v = r.version
2713 format = v & 0xFFFF
2676 format = v & 0xFFFF
2714 flags = []
2677 flags = []
2715 gdelta = False
2678 gdelta = False
2716 if v & revlog.FLAG_INLINE_DATA:
2679 if v & revlog.FLAG_INLINE_DATA:
2717 flags.append(b'inline')
2680 flags.append(b'inline')
2718 if v & revlog.FLAG_GENERALDELTA:
2681 if v & revlog.FLAG_GENERALDELTA:
2719 gdelta = True
2682 gdelta = True
2720 flags.append(b'generaldelta')
2683 flags.append(b'generaldelta')
2721 if not flags:
2684 if not flags:
2722 flags = [b'(none)']
2685 flags = [b'(none)']
2723
2686
2724 ### tracks merge vs single parent
2687 ### tracks merge vs single parent
2725 nummerges = 0
2688 nummerges = 0
2726
2689
2727 ### tracks ways the "delta" are build
2690 ### tracks ways the "delta" are build
2728 # nodelta
2691 # nodelta
2729 numempty = 0
2692 numempty = 0
2730 numemptytext = 0
2693 numemptytext = 0
2731 numemptydelta = 0
2694 numemptydelta = 0
2732 # full file content
2695 # full file content
2733 numfull = 0
2696 numfull = 0
2734 # intermediate snapshot against a prior snapshot
2697 # intermediate snapshot against a prior snapshot
2735 numsemi = 0
2698 numsemi = 0
2736 # snapshot count per depth
2699 # snapshot count per depth
2737 numsnapdepth = collections.defaultdict(lambda: 0)
2700 numsnapdepth = collections.defaultdict(lambda: 0)
2738 # delta against previous revision
2701 # delta against previous revision
2739 numprev = 0
2702 numprev = 0
2740 # delta against first or second parent (not prev)
2703 # delta against first or second parent (not prev)
2741 nump1 = 0
2704 nump1 = 0
2742 nump2 = 0
2705 nump2 = 0
2743 # delta against neither prev nor parents
2706 # delta against neither prev nor parents
2744 numother = 0
2707 numother = 0
2745 # delta against prev that are also first or second parent
2708 # delta against prev that are also first or second parent
2746 # (details of `numprev`)
2709 # (details of `numprev`)
2747 nump1prev = 0
2710 nump1prev = 0
2748 nump2prev = 0
2711 nump2prev = 0
2749
2712
2750 # data about delta chain of each revs
2713 # data about delta chain of each revs
2751 chainlengths = []
2714 chainlengths = []
2752 chainbases = []
2715 chainbases = []
2753 chainspans = []
2716 chainspans = []
2754
2717
2755 # data about each revision
2718 # data about each revision
2756 datasize = [None, 0, 0]
2719 datasize = [None, 0, 0]
2757 fullsize = [None, 0, 0]
2720 fullsize = [None, 0, 0]
2758 semisize = [None, 0, 0]
2721 semisize = [None, 0, 0]
2759 # snapshot count per depth
2722 # snapshot count per depth
2760 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2723 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2761 deltasize = [None, 0, 0]
2724 deltasize = [None, 0, 0]
2762 chunktypecounts = {}
2725 chunktypecounts = {}
2763 chunktypesizes = {}
2726 chunktypesizes = {}
2764
2727
2765 def addsize(size, l):
2728 def addsize(size, l):
2766 if l[0] is None or size < l[0]:
2729 if l[0] is None or size < l[0]:
2767 l[0] = size
2730 l[0] = size
2768 if size > l[1]:
2731 if size > l[1]:
2769 l[1] = size
2732 l[1] = size
2770 l[2] += size
2733 l[2] += size
2771
2734
2772 numrevs = len(r)
2735 numrevs = len(r)
2773 for rev in pycompat.xrange(numrevs):
2736 for rev in pycompat.xrange(numrevs):
2774 p1, p2 = r.parentrevs(rev)
2737 p1, p2 = r.parentrevs(rev)
2775 delta = r.deltaparent(rev)
2738 delta = r.deltaparent(rev)
2776 if format > 0:
2739 if format > 0:
2777 addsize(r.rawsize(rev), datasize)
2740 addsize(r.rawsize(rev), datasize)
2778 if p2 != nullrev:
2741 if p2 != nullrev:
2779 nummerges += 1
2742 nummerges += 1
2780 size = r.length(rev)
2743 size = r.length(rev)
2781 if delta == nullrev:
2744 if delta == nullrev:
2782 chainlengths.append(0)
2745 chainlengths.append(0)
2783 chainbases.append(r.start(rev))
2746 chainbases.append(r.start(rev))
2784 chainspans.append(size)
2747 chainspans.append(size)
2785 if size == 0:
2748 if size == 0:
2786 numempty += 1
2749 numempty += 1
2787 numemptytext += 1
2750 numemptytext += 1
2788 else:
2751 else:
2789 numfull += 1
2752 numfull += 1
2790 numsnapdepth[0] += 1
2753 numsnapdepth[0] += 1
2791 addsize(size, fullsize)
2754 addsize(size, fullsize)
2792 addsize(size, snapsizedepth[0])
2755 addsize(size, snapsizedepth[0])
2793 else:
2756 else:
2794 chainlengths.append(chainlengths[delta] + 1)
2757 chainlengths.append(chainlengths[delta] + 1)
2795 baseaddr = chainbases[delta]
2758 baseaddr = chainbases[delta]
2796 revaddr = r.start(rev)
2759 revaddr = r.start(rev)
2797 chainbases.append(baseaddr)
2760 chainbases.append(baseaddr)
2798 chainspans.append((revaddr - baseaddr) + size)
2761 chainspans.append((revaddr - baseaddr) + size)
2799 if size == 0:
2762 if size == 0:
2800 numempty += 1
2763 numempty += 1
2801 numemptydelta += 1
2764 numemptydelta += 1
2802 elif r.issnapshot(rev):
2765 elif r.issnapshot(rev):
2803 addsize(size, semisize)
2766 addsize(size, semisize)
2804 numsemi += 1
2767 numsemi += 1
2805 depth = r.snapshotdepth(rev)
2768 depth = r.snapshotdepth(rev)
2806 numsnapdepth[depth] += 1
2769 numsnapdepth[depth] += 1
2807 addsize(size, snapsizedepth[depth])
2770 addsize(size, snapsizedepth[depth])
2808 else:
2771 else:
2809 addsize(size, deltasize)
2772 addsize(size, deltasize)
2810 if delta == rev - 1:
2773 if delta == rev - 1:
2811 numprev += 1
2774 numprev += 1
2812 if delta == p1:
2775 if delta == p1:
2813 nump1prev += 1
2776 nump1prev += 1
2814 elif delta == p2:
2777 elif delta == p2:
2815 nump2prev += 1
2778 nump2prev += 1
2816 elif delta == p1:
2779 elif delta == p1:
2817 nump1 += 1
2780 nump1 += 1
2818 elif delta == p2:
2781 elif delta == p2:
2819 nump2 += 1
2782 nump2 += 1
2820 elif delta != nullrev:
2783 elif delta != nullrev:
2821 numother += 1
2784 numother += 1
2822
2785
2823 # Obtain data on the raw chunks in the revlog.
2786 # Obtain data on the raw chunks in the revlog.
2824 if util.safehasattr(r, b'_getsegmentforrevs'):
2787 if util.safehasattr(r, b'_getsegmentforrevs'):
2825 segment = r._getsegmentforrevs(rev, rev)[1]
2788 segment = r._getsegmentforrevs(rev, rev)[1]
2826 else:
2789 else:
2827 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2790 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2828 if segment:
2791 if segment:
2829 chunktype = bytes(segment[0:1])
2792 chunktype = bytes(segment[0:1])
2830 else:
2793 else:
2831 chunktype = b'empty'
2794 chunktype = b'empty'
2832
2795
2833 if chunktype not in chunktypecounts:
2796 if chunktype not in chunktypecounts:
2834 chunktypecounts[chunktype] = 0
2797 chunktypecounts[chunktype] = 0
2835 chunktypesizes[chunktype] = 0
2798 chunktypesizes[chunktype] = 0
2836
2799
2837 chunktypecounts[chunktype] += 1
2800 chunktypecounts[chunktype] += 1
2838 chunktypesizes[chunktype] += size
2801 chunktypesizes[chunktype] += size
2839
2802
2840 # Adjust size min value for empty cases
2803 # Adjust size min value for empty cases
2841 for size in (datasize, fullsize, semisize, deltasize):
2804 for size in (datasize, fullsize, semisize, deltasize):
2842 if size[0] is None:
2805 if size[0] is None:
2843 size[0] = 0
2806 size[0] = 0
2844
2807
2845 numdeltas = numrevs - numfull - numempty - numsemi
2808 numdeltas = numrevs - numfull - numempty - numsemi
2846 numoprev = numprev - nump1prev - nump2prev
2809 numoprev = numprev - nump1prev - nump2prev
2847 totalrawsize = datasize[2]
2810 totalrawsize = datasize[2]
2848 datasize[2] /= numrevs
2811 datasize[2] /= numrevs
2849 fulltotal = fullsize[2]
2812 fulltotal = fullsize[2]
2850 if numfull == 0:
2813 if numfull == 0:
2851 fullsize[2] = 0
2814 fullsize[2] = 0
2852 else:
2815 else:
2853 fullsize[2] /= numfull
2816 fullsize[2] /= numfull
2854 semitotal = semisize[2]
2817 semitotal = semisize[2]
2855 snaptotal = {}
2818 snaptotal = {}
2856 if numsemi > 0:
2819 if numsemi > 0:
2857 semisize[2] /= numsemi
2820 semisize[2] /= numsemi
2858 for depth in snapsizedepth:
2821 for depth in snapsizedepth:
2859 snaptotal[depth] = snapsizedepth[depth][2]
2822 snaptotal[depth] = snapsizedepth[depth][2]
2860 snapsizedepth[depth][2] /= numsnapdepth[depth]
2823 snapsizedepth[depth][2] /= numsnapdepth[depth]
2861
2824
2862 deltatotal = deltasize[2]
2825 deltatotal = deltasize[2]
2863 if numdeltas > 0:
2826 if numdeltas > 0:
2864 deltasize[2] /= numdeltas
2827 deltasize[2] /= numdeltas
2865 totalsize = fulltotal + semitotal + deltatotal
2828 totalsize = fulltotal + semitotal + deltatotal
2866 avgchainlen = sum(chainlengths) / numrevs
2829 avgchainlen = sum(chainlengths) / numrevs
2867 maxchainlen = max(chainlengths)
2830 maxchainlen = max(chainlengths)
2868 maxchainspan = max(chainspans)
2831 maxchainspan = max(chainspans)
2869 compratio = 1
2832 compratio = 1
2870 if totalsize:
2833 if totalsize:
2871 compratio = totalrawsize / totalsize
2834 compratio = totalrawsize / totalsize
2872
2835
2873 basedfmtstr = b'%%%dd\n'
2836 basedfmtstr = b'%%%dd\n'
2874 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2837 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2875
2838
2876 def dfmtstr(max):
2839 def dfmtstr(max):
2877 return basedfmtstr % len(str(max))
2840 return basedfmtstr % len(str(max))
2878
2841
2879 def pcfmtstr(max, padding=0):
2842 def pcfmtstr(max, padding=0):
2880 return basepcfmtstr % (len(str(max)), b' ' * padding)
2843 return basepcfmtstr % (len(str(max)), b' ' * padding)
2881
2844
2882 def pcfmt(value, total):
2845 def pcfmt(value, total):
2883 if total:
2846 if total:
2884 return (value, 100 * float(value) / total)
2847 return (value, 100 * float(value) / total)
2885 else:
2848 else:
2886 return value, 100.0
2849 return value, 100.0
2887
2850
2888 ui.writenoi18n(b'format : %d\n' % format)
2851 ui.writenoi18n(b'format : %d\n' % format)
2889 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2852 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2890
2853
2891 ui.write(b'\n')
2854 ui.write(b'\n')
2892 fmt = pcfmtstr(totalsize)
2855 fmt = pcfmtstr(totalsize)
2893 fmt2 = dfmtstr(totalsize)
2856 fmt2 = dfmtstr(totalsize)
2894 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2857 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2895 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2858 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2896 ui.writenoi18n(
2859 ui.writenoi18n(
2897 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2860 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2898 )
2861 )
2899 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2862 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2900 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2863 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2901 ui.writenoi18n(
2864 ui.writenoi18n(
2902 b' text : '
2865 b' text : '
2903 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2866 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2904 )
2867 )
2905 ui.writenoi18n(
2868 ui.writenoi18n(
2906 b' delta : '
2869 b' delta : '
2907 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2870 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2908 )
2871 )
2909 ui.writenoi18n(
2872 ui.writenoi18n(
2910 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2873 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2911 )
2874 )
2912 for depth in sorted(numsnapdepth):
2875 for depth in sorted(numsnapdepth):
2913 ui.write(
2876 ui.write(
2914 (b' lvl-%-3d : ' % depth)
2877 (b' lvl-%-3d : ' % depth)
2915 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2878 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2916 )
2879 )
2917 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2880 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2918 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2881 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2919 ui.writenoi18n(
2882 ui.writenoi18n(
2920 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2883 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2921 )
2884 )
2922 for depth in sorted(numsnapdepth):
2885 for depth in sorted(numsnapdepth):
2923 ui.write(
2886 ui.write(
2924 (b' lvl-%-3d : ' % depth)
2887 (b' lvl-%-3d : ' % depth)
2925 + fmt % pcfmt(snaptotal[depth], totalsize)
2888 + fmt % pcfmt(snaptotal[depth], totalsize)
2926 )
2889 )
2927 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2890 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2928
2891
2929 def fmtchunktype(chunktype):
2892 def fmtchunktype(chunktype):
2930 if chunktype == b'empty':
2893 if chunktype == b'empty':
2931 return b' %s : ' % chunktype
2894 return b' %s : ' % chunktype
2932 elif chunktype in pycompat.bytestr(string.ascii_letters):
2895 elif chunktype in pycompat.bytestr(string.ascii_letters):
2933 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2896 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2934 else:
2897 else:
2935 return b' 0x%s : ' % hex(chunktype)
2898 return b' 0x%s : ' % hex(chunktype)
2936
2899
2937 ui.write(b'\n')
2900 ui.write(b'\n')
2938 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2901 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2939 for chunktype in sorted(chunktypecounts):
2902 for chunktype in sorted(chunktypecounts):
2940 ui.write(fmtchunktype(chunktype))
2903 ui.write(fmtchunktype(chunktype))
2941 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2904 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2942 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2905 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2943 for chunktype in sorted(chunktypecounts):
2906 for chunktype in sorted(chunktypecounts):
2944 ui.write(fmtchunktype(chunktype))
2907 ui.write(fmtchunktype(chunktype))
2945 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2908 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2946
2909
2947 ui.write(b'\n')
2910 ui.write(b'\n')
2948 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2911 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2949 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2912 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2950 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2913 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2951 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2914 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2952 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2915 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2953
2916
2954 if format > 0:
2917 if format > 0:
2955 ui.write(b'\n')
2918 ui.write(b'\n')
2956 ui.writenoi18n(
2919 ui.writenoi18n(
2957 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2920 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2958 % tuple(datasize)
2921 % tuple(datasize)
2959 )
2922 )
2960 ui.writenoi18n(
2923 ui.writenoi18n(
2961 b'full revision size (min/max/avg) : %d / %d / %d\n'
2924 b'full revision size (min/max/avg) : %d / %d / %d\n'
2962 % tuple(fullsize)
2925 % tuple(fullsize)
2963 )
2926 )
2964 ui.writenoi18n(
2927 ui.writenoi18n(
2965 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2928 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2966 % tuple(semisize)
2929 % tuple(semisize)
2967 )
2930 )
2968 for depth in sorted(snapsizedepth):
2931 for depth in sorted(snapsizedepth):
2969 if depth == 0:
2932 if depth == 0:
2970 continue
2933 continue
2971 ui.writenoi18n(
2934 ui.writenoi18n(
2972 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2935 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2973 % ((depth,) + tuple(snapsizedepth[depth]))
2936 % ((depth,) + tuple(snapsizedepth[depth]))
2974 )
2937 )
2975 ui.writenoi18n(
2938 ui.writenoi18n(
2976 b'delta size (min/max/avg) : %d / %d / %d\n'
2939 b'delta size (min/max/avg) : %d / %d / %d\n'
2977 % tuple(deltasize)
2940 % tuple(deltasize)
2978 )
2941 )
2979
2942
2980 if numdeltas > 0:
2943 if numdeltas > 0:
2981 ui.write(b'\n')
2944 ui.write(b'\n')
2982 fmt = pcfmtstr(numdeltas)
2945 fmt = pcfmtstr(numdeltas)
2983 fmt2 = pcfmtstr(numdeltas, 4)
2946 fmt2 = pcfmtstr(numdeltas, 4)
2984 ui.writenoi18n(
2947 ui.writenoi18n(
2985 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2948 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2986 )
2949 )
2987 if numprev > 0:
2950 if numprev > 0:
2988 ui.writenoi18n(
2951 ui.writenoi18n(
2989 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2952 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2990 )
2953 )
2991 ui.writenoi18n(
2954 ui.writenoi18n(
2992 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2955 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2993 )
2956 )
2994 ui.writenoi18n(
2957 ui.writenoi18n(
2995 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2958 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2996 )
2959 )
2997 if gdelta:
2960 if gdelta:
2998 ui.writenoi18n(
2961 ui.writenoi18n(
2999 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
2962 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
3000 )
2963 )
3001 ui.writenoi18n(
2964 ui.writenoi18n(
3002 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
2965 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
3003 )
2966 )
3004 ui.writenoi18n(
2967 ui.writenoi18n(
3005 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
2968 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
3006 )
2969 )
3007
2970
3008
2971
3009 @command(
2972 @command(
3010 b'debugrevlogindex',
2973 b'debugrevlogindex',
3011 cmdutil.debugrevlogopts
2974 cmdutil.debugrevlogopts
3012 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
2975 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
3013 _(b'[-f FORMAT] -c|-m|FILE'),
2976 _(b'[-f FORMAT] -c|-m|FILE'),
3014 optionalrepo=True,
2977 optionalrepo=True,
3015 )
2978 )
3016 def debugrevlogindex(ui, repo, file_=None, **opts):
2979 def debugrevlogindex(ui, repo, file_=None, **opts):
3017 """dump the contents of a revlog index"""
2980 """dump the contents of a revlog index"""
3018 opts = pycompat.byteskwargs(opts)
2981 opts = pycompat.byteskwargs(opts)
3019 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
2982 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
3020 format = opts.get(b'format', 0)
2983 format = opts.get(b'format', 0)
3021 if format not in (0, 1):
2984 if format not in (0, 1):
3022 raise error.Abort(_(b"unknown format %d") % format)
2985 raise error.Abort(_(b"unknown format %d") % format)
3023
2986
3024 if ui.debugflag:
2987 if ui.debugflag:
3025 shortfn = hex
2988 shortfn = hex
3026 else:
2989 else:
3027 shortfn = short
2990 shortfn = short
3028
2991
3029 # There might not be anything in r, so have a sane default
2992 # There might not be anything in r, so have a sane default
3030 idlen = 12
2993 idlen = 12
3031 for i in r:
2994 for i in r:
3032 idlen = len(shortfn(r.node(i)))
2995 idlen = len(shortfn(r.node(i)))
3033 break
2996 break
3034
2997
3035 if format == 0:
2998 if format == 0:
3036 if ui.verbose:
2999 if ui.verbose:
3037 ui.writenoi18n(
3000 ui.writenoi18n(
3038 b" rev offset length linkrev %s %s p2\n"
3001 b" rev offset length linkrev %s %s p2\n"
3039 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3002 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3040 )
3003 )
3041 else:
3004 else:
3042 ui.writenoi18n(
3005 ui.writenoi18n(
3043 b" rev linkrev %s %s p2\n"
3006 b" rev linkrev %s %s p2\n"
3044 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3007 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
3045 )
3008 )
3046 elif format == 1:
3009 elif format == 1:
3047 if ui.verbose:
3010 if ui.verbose:
3048 ui.writenoi18n(
3011 ui.writenoi18n(
3049 (
3012 (
3050 b" rev flag offset length size link p1"
3013 b" rev flag offset length size link p1"
3051 b" p2 %s\n"
3014 b" p2 %s\n"
3052 )
3015 )
3053 % b"nodeid".rjust(idlen)
3016 % b"nodeid".rjust(idlen)
3054 )
3017 )
3055 else:
3018 else:
3056 ui.writenoi18n(
3019 ui.writenoi18n(
3057 b" rev flag size link p1 p2 %s\n"
3020 b" rev flag size link p1 p2 %s\n"
3058 % b"nodeid".rjust(idlen)
3021 % b"nodeid".rjust(idlen)
3059 )
3022 )
3060
3023
3061 for i in r:
3024 for i in r:
3062 node = r.node(i)
3025 node = r.node(i)
3063 if format == 0:
3026 if format == 0:
3064 try:
3027 try:
3065 pp = r.parents(node)
3028 pp = r.parents(node)
3066 except Exception:
3029 except Exception:
3067 pp = [nullid, nullid]
3030 pp = [nullid, nullid]
3068 if ui.verbose:
3031 if ui.verbose:
3069 ui.write(
3032 ui.write(
3070 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3033 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3071 % (
3034 % (
3072 i,
3035 i,
3073 r.start(i),
3036 r.start(i),
3074 r.length(i),
3037 r.length(i),
3075 r.linkrev(i),
3038 r.linkrev(i),
3076 shortfn(node),
3039 shortfn(node),
3077 shortfn(pp[0]),
3040 shortfn(pp[0]),
3078 shortfn(pp[1]),
3041 shortfn(pp[1]),
3079 )
3042 )
3080 )
3043 )
3081 else:
3044 else:
3082 ui.write(
3045 ui.write(
3083 b"% 6d % 7d %s %s %s\n"
3046 b"% 6d % 7d %s %s %s\n"
3084 % (
3047 % (
3085 i,
3048 i,
3086 r.linkrev(i),
3049 r.linkrev(i),
3087 shortfn(node),
3050 shortfn(node),
3088 shortfn(pp[0]),
3051 shortfn(pp[0]),
3089 shortfn(pp[1]),
3052 shortfn(pp[1]),
3090 )
3053 )
3091 )
3054 )
3092 elif format == 1:
3055 elif format == 1:
3093 pr = r.parentrevs(i)
3056 pr = r.parentrevs(i)
3094 if ui.verbose:
3057 if ui.verbose:
3095 ui.write(
3058 ui.write(
3096 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3059 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3097 % (
3060 % (
3098 i,
3061 i,
3099 r.flags(i),
3062 r.flags(i),
3100 r.start(i),
3063 r.start(i),
3101 r.length(i),
3064 r.length(i),
3102 r.rawsize(i),
3065 r.rawsize(i),
3103 r.linkrev(i),
3066 r.linkrev(i),
3104 pr[0],
3067 pr[0],
3105 pr[1],
3068 pr[1],
3106 shortfn(node),
3069 shortfn(node),
3107 )
3070 )
3108 )
3071 )
3109 else:
3072 else:
3110 ui.write(
3073 ui.write(
3111 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3074 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3112 % (
3075 % (
3113 i,
3076 i,
3114 r.flags(i),
3077 r.flags(i),
3115 r.rawsize(i),
3078 r.rawsize(i),
3116 r.linkrev(i),
3079 r.linkrev(i),
3117 pr[0],
3080 pr[0],
3118 pr[1],
3081 pr[1],
3119 shortfn(node),
3082 shortfn(node),
3120 )
3083 )
3121 )
3084 )
3122
3085
3123
3086
3124 @command(
3087 @command(
3125 b'debugrevspec',
3088 b'debugrevspec',
3126 [
3089 [
3127 (
3090 (
3128 b'',
3091 b'',
3129 b'optimize',
3092 b'optimize',
3130 None,
3093 None,
3131 _(b'print parsed tree after optimizing (DEPRECATED)'),
3094 _(b'print parsed tree after optimizing (DEPRECATED)'),
3132 ),
3095 ),
3133 (
3096 (
3134 b'',
3097 b'',
3135 b'show-revs',
3098 b'show-revs',
3136 True,
3099 True,
3137 _(b'print list of result revisions (default)'),
3100 _(b'print list of result revisions (default)'),
3138 ),
3101 ),
3139 (
3102 (
3140 b's',
3103 b's',
3141 b'show-set',
3104 b'show-set',
3142 None,
3105 None,
3143 _(b'print internal representation of result set'),
3106 _(b'print internal representation of result set'),
3144 ),
3107 ),
3145 (
3108 (
3146 b'p',
3109 b'p',
3147 b'show-stage',
3110 b'show-stage',
3148 [],
3111 [],
3149 _(b'print parsed tree at the given stage'),
3112 _(b'print parsed tree at the given stage'),
3150 _(b'NAME'),
3113 _(b'NAME'),
3151 ),
3114 ),
3152 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3115 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3153 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3116 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3154 ],
3117 ],
3155 b'REVSPEC',
3118 b'REVSPEC',
3156 )
3119 )
3157 def debugrevspec(ui, repo, expr, **opts):
3120 def debugrevspec(ui, repo, expr, **opts):
3158 """parse and apply a revision specification
3121 """parse and apply a revision specification
3159
3122
3160 Use -p/--show-stage option to print the parsed tree at the given stages.
3123 Use -p/--show-stage option to print the parsed tree at the given stages.
3161 Use -p all to print tree at every stage.
3124 Use -p all to print tree at every stage.
3162
3125
3163 Use --no-show-revs option with -s or -p to print only the set
3126 Use --no-show-revs option with -s or -p to print only the set
3164 representation or the parsed tree respectively.
3127 representation or the parsed tree respectively.
3165
3128
3166 Use --verify-optimized to compare the optimized result with the unoptimized
3129 Use --verify-optimized to compare the optimized result with the unoptimized
3167 one. Returns 1 if the optimized result differs.
3130 one. Returns 1 if the optimized result differs.
3168 """
3131 """
3169 opts = pycompat.byteskwargs(opts)
3132 opts = pycompat.byteskwargs(opts)
3170 aliases = ui.configitems(b'revsetalias')
3133 aliases = ui.configitems(b'revsetalias')
3171 stages = [
3134 stages = [
3172 (b'parsed', lambda tree: tree),
3135 (b'parsed', lambda tree: tree),
3173 (
3136 (
3174 b'expanded',
3137 b'expanded',
3175 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3138 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3176 ),
3139 ),
3177 (b'concatenated', revsetlang.foldconcat),
3140 (b'concatenated', revsetlang.foldconcat),
3178 (b'analyzed', revsetlang.analyze),
3141 (b'analyzed', revsetlang.analyze),
3179 (b'optimized', revsetlang.optimize),
3142 (b'optimized', revsetlang.optimize),
3180 ]
3143 ]
3181 if opts[b'no_optimized']:
3144 if opts[b'no_optimized']:
3182 stages = stages[:-1]
3145 stages = stages[:-1]
3183 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3146 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3184 raise error.Abort(
3147 raise error.Abort(
3185 _(b'cannot use --verify-optimized with --no-optimized')
3148 _(b'cannot use --verify-optimized with --no-optimized')
3186 )
3149 )
3187 stagenames = set(n for n, f in stages)
3150 stagenames = set(n for n, f in stages)
3188
3151
3189 showalways = set()
3152 showalways = set()
3190 showchanged = set()
3153 showchanged = set()
3191 if ui.verbose and not opts[b'show_stage']:
3154 if ui.verbose and not opts[b'show_stage']:
3192 # show parsed tree by --verbose (deprecated)
3155 # show parsed tree by --verbose (deprecated)
3193 showalways.add(b'parsed')
3156 showalways.add(b'parsed')
3194 showchanged.update([b'expanded', b'concatenated'])
3157 showchanged.update([b'expanded', b'concatenated'])
3195 if opts[b'optimize']:
3158 if opts[b'optimize']:
3196 showalways.add(b'optimized')
3159 showalways.add(b'optimized')
3197 if opts[b'show_stage'] and opts[b'optimize']:
3160 if opts[b'show_stage'] and opts[b'optimize']:
3198 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3161 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3199 if opts[b'show_stage'] == [b'all']:
3162 if opts[b'show_stage'] == [b'all']:
3200 showalways.update(stagenames)
3163 showalways.update(stagenames)
3201 else:
3164 else:
3202 for n in opts[b'show_stage']:
3165 for n in opts[b'show_stage']:
3203 if n not in stagenames:
3166 if n not in stagenames:
3204 raise error.Abort(_(b'invalid stage name: %s') % n)
3167 raise error.Abort(_(b'invalid stage name: %s') % n)
3205 showalways.update(opts[b'show_stage'])
3168 showalways.update(opts[b'show_stage'])
3206
3169
3207 treebystage = {}
3170 treebystage = {}
3208 printedtree = None
3171 printedtree = None
3209 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3172 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3210 for n, f in stages:
3173 for n, f in stages:
3211 treebystage[n] = tree = f(tree)
3174 treebystage[n] = tree = f(tree)
3212 if n in showalways or (n in showchanged and tree != printedtree):
3175 if n in showalways or (n in showchanged and tree != printedtree):
3213 if opts[b'show_stage'] or n != b'parsed':
3176 if opts[b'show_stage'] or n != b'parsed':
3214 ui.write(b"* %s:\n" % n)
3177 ui.write(b"* %s:\n" % n)
3215 ui.write(revsetlang.prettyformat(tree), b"\n")
3178 ui.write(revsetlang.prettyformat(tree), b"\n")
3216 printedtree = tree
3179 printedtree = tree
3217
3180
3218 if opts[b'verify_optimized']:
3181 if opts[b'verify_optimized']:
3219 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3182 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3220 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3183 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3221 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3184 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3222 ui.writenoi18n(
3185 ui.writenoi18n(
3223 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3186 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3224 )
3187 )
3225 ui.writenoi18n(
3188 ui.writenoi18n(
3226 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3189 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3227 )
3190 )
3228 arevs = list(arevs)
3191 arevs = list(arevs)
3229 brevs = list(brevs)
3192 brevs = list(brevs)
3230 if arevs == brevs:
3193 if arevs == brevs:
3231 return 0
3194 return 0
3232 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3195 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3233 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3196 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3234 sm = difflib.SequenceMatcher(None, arevs, brevs)
3197 sm = difflib.SequenceMatcher(None, arevs, brevs)
3235 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3198 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3236 if tag in ('delete', 'replace'):
3199 if tag in ('delete', 'replace'):
3237 for c in arevs[alo:ahi]:
3200 for c in arevs[alo:ahi]:
3238 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3201 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3239 if tag in ('insert', 'replace'):
3202 if tag in ('insert', 'replace'):
3240 for c in brevs[blo:bhi]:
3203 for c in brevs[blo:bhi]:
3241 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3204 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3242 if tag == 'equal':
3205 if tag == 'equal':
3243 for c in arevs[alo:ahi]:
3206 for c in arevs[alo:ahi]:
3244 ui.write(b' %d\n' % c)
3207 ui.write(b' %d\n' % c)
3245 return 1
3208 return 1
3246
3209
3247 func = revset.makematcher(tree)
3210 func = revset.makematcher(tree)
3248 revs = func(repo)
3211 revs = func(repo)
3249 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3212 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3250 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3213 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3251 if not opts[b'show_revs']:
3214 if not opts[b'show_revs']:
3252 return
3215 return
3253 for c in revs:
3216 for c in revs:
3254 ui.write(b"%d\n" % c)
3217 ui.write(b"%d\n" % c)
3255
3218
3256
3219
3257 @command(
3220 @command(
3258 b'debugserve',
3221 b'debugserve',
3259 [
3222 [
3260 (
3223 (
3261 b'',
3224 b'',
3262 b'sshstdio',
3225 b'sshstdio',
3263 False,
3226 False,
3264 _(b'run an SSH server bound to process handles'),
3227 _(b'run an SSH server bound to process handles'),
3265 ),
3228 ),
3266 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3229 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3267 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3230 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3268 ],
3231 ],
3269 b'',
3232 b'',
3270 )
3233 )
3271 def debugserve(ui, repo, **opts):
3234 def debugserve(ui, repo, **opts):
3272 """run a server with advanced settings
3235 """run a server with advanced settings
3273
3236
3274 This command is similar to :hg:`serve`. It exists partially as a
3237 This command is similar to :hg:`serve`. It exists partially as a
3275 workaround to the fact that ``hg serve --stdio`` must have specific
3238 workaround to the fact that ``hg serve --stdio`` must have specific
3276 arguments for security reasons.
3239 arguments for security reasons.
3277 """
3240 """
3278 opts = pycompat.byteskwargs(opts)
3241 opts = pycompat.byteskwargs(opts)
3279
3242
3280 if not opts[b'sshstdio']:
3243 if not opts[b'sshstdio']:
3281 raise error.Abort(_(b'only --sshstdio is currently supported'))
3244 raise error.Abort(_(b'only --sshstdio is currently supported'))
3282
3245
3283 logfh = None
3246 logfh = None
3284
3247
3285 if opts[b'logiofd'] and opts[b'logiofile']:
3248 if opts[b'logiofd'] and opts[b'logiofile']:
3286 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3249 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3287
3250
3288 if opts[b'logiofd']:
3251 if opts[b'logiofd']:
3289 # Ideally we would be line buffered. But line buffering in binary
3252 # Ideally we would be line buffered. But line buffering in binary
3290 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3253 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3291 # buffering could have performance impacts. But since this isn't
3254 # buffering could have performance impacts. But since this isn't
3292 # performance critical code, it should be fine.
3255 # performance critical code, it should be fine.
3293 try:
3256 try:
3294 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3257 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3295 except OSError as e:
3258 except OSError as e:
3296 if e.errno != errno.ESPIPE:
3259 if e.errno != errno.ESPIPE:
3297 raise
3260 raise
3298 # can't seek a pipe, so `ab` mode fails on py3
3261 # can't seek a pipe, so `ab` mode fails on py3
3299 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3262 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3300 elif opts[b'logiofile']:
3263 elif opts[b'logiofile']:
3301 logfh = open(opts[b'logiofile'], b'ab', 0)
3264 logfh = open(opts[b'logiofile'], b'ab', 0)
3302
3265
3303 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3266 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3304 s.serve_forever()
3267 s.serve_forever()
3305
3268
3306
3269
3307 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3270 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3308 def debugsetparents(ui, repo, rev1, rev2=None):
3271 def debugsetparents(ui, repo, rev1, rev2=None):
3309 """manually set the parents of the current working directory
3272 """manually set the parents of the current working directory
3310
3273
3311 This is useful for writing repository conversion tools, but should
3274 This is useful for writing repository conversion tools, but should
3312 be used with care. For example, neither the working directory nor the
3275 be used with care. For example, neither the working directory nor the
3313 dirstate is updated, so file status may be incorrect after running this
3276 dirstate is updated, so file status may be incorrect after running this
3314 command.
3277 command.
3315
3278
3316 Returns 0 on success.
3279 Returns 0 on success.
3317 """
3280 """
3318
3281
3319 node1 = scmutil.revsingle(repo, rev1).node()
3282 node1 = scmutil.revsingle(repo, rev1).node()
3320 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3283 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3321
3284
3322 with repo.wlock():
3285 with repo.wlock():
3323 repo.setparents(node1, node2)
3286 repo.setparents(node1, node2)
3324
3287
3325
3288
3326 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3289 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3327 def debugsidedata(ui, repo, file_, rev=None, **opts):
3290 def debugsidedata(ui, repo, file_, rev=None, **opts):
3328 """dump the side data for a cl/manifest/file revision
3291 """dump the side data for a cl/manifest/file revision
3329
3292
3330 Use --verbose to dump the sidedata content."""
3293 Use --verbose to dump the sidedata content."""
3331 opts = pycompat.byteskwargs(opts)
3294 opts = pycompat.byteskwargs(opts)
3332 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3295 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3333 if rev is not None:
3296 if rev is not None:
3334 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3297 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3335 file_, rev = None, file_
3298 file_, rev = None, file_
3336 elif rev is None:
3299 elif rev is None:
3337 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3300 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3338 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3301 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3339 r = getattr(r, '_revlog', r)
3302 r = getattr(r, '_revlog', r)
3340 try:
3303 try:
3341 sidedata = r.sidedata(r.lookup(rev))
3304 sidedata = r.sidedata(r.lookup(rev))
3342 except KeyError:
3305 except KeyError:
3343 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3306 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3344 if sidedata:
3307 if sidedata:
3345 sidedata = list(sidedata.items())
3308 sidedata = list(sidedata.items())
3346 sidedata.sort()
3309 sidedata.sort()
3347 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3310 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3348 for key, value in sidedata:
3311 for key, value in sidedata:
3349 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3312 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3350 if ui.verbose:
3313 if ui.verbose:
3351 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3314 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3352
3315
3353
3316
3354 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3317 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3355 def debugssl(ui, repo, source=None, **opts):
3318 def debugssl(ui, repo, source=None, **opts):
3356 '''test a secure connection to a server
3319 '''test a secure connection to a server
3357
3320
3358 This builds the certificate chain for the server on Windows, installing the
3321 This builds the certificate chain for the server on Windows, installing the
3359 missing intermediates and trusted root via Windows Update if necessary. It
3322 missing intermediates and trusted root via Windows Update if necessary. It
3360 does nothing on other platforms.
3323 does nothing on other platforms.
3361
3324
3362 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3325 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3363 that server is used. See :hg:`help urls` for more information.
3326 that server is used. See :hg:`help urls` for more information.
3364
3327
3365 If the update succeeds, retry the original operation. Otherwise, the cause
3328 If the update succeeds, retry the original operation. Otherwise, the cause
3366 of the SSL error is likely another issue.
3329 of the SSL error is likely another issue.
3367 '''
3330 '''
3368 if not pycompat.iswindows:
3331 if not pycompat.iswindows:
3369 raise error.Abort(
3332 raise error.Abort(
3370 _(b'certificate chain building is only possible on Windows')
3333 _(b'certificate chain building is only possible on Windows')
3371 )
3334 )
3372
3335
3373 if not source:
3336 if not source:
3374 if not repo:
3337 if not repo:
3375 raise error.Abort(
3338 raise error.Abort(
3376 _(
3339 _(
3377 b"there is no Mercurial repository here, and no "
3340 b"there is no Mercurial repository here, and no "
3378 b"server specified"
3341 b"server specified"
3379 )
3342 )
3380 )
3343 )
3381 source = b"default"
3344 source = b"default"
3382
3345
3383 source, branches = hg.parseurl(ui.expandpath(source))
3346 source, branches = hg.parseurl(ui.expandpath(source))
3384 url = util.url(source)
3347 url = util.url(source)
3385
3348
3386 defaultport = {b'https': 443, b'ssh': 22}
3349 defaultport = {b'https': 443, b'ssh': 22}
3387 if url.scheme in defaultport:
3350 if url.scheme in defaultport:
3388 try:
3351 try:
3389 addr = (url.host, int(url.port or defaultport[url.scheme]))
3352 addr = (url.host, int(url.port or defaultport[url.scheme]))
3390 except ValueError:
3353 except ValueError:
3391 raise error.Abort(_(b"malformed port number in URL"))
3354 raise error.Abort(_(b"malformed port number in URL"))
3392 else:
3355 else:
3393 raise error.Abort(_(b"only https and ssh connections are supported"))
3356 raise error.Abort(_(b"only https and ssh connections are supported"))
3394
3357
3395 from . import win32
3358 from . import win32
3396
3359
3397 s = ssl.wrap_socket(
3360 s = ssl.wrap_socket(
3398 socket.socket(),
3361 socket.socket(),
3399 ssl_version=ssl.PROTOCOL_TLS,
3362 ssl_version=ssl.PROTOCOL_TLS,
3400 cert_reqs=ssl.CERT_NONE,
3363 cert_reqs=ssl.CERT_NONE,
3401 ca_certs=None,
3364 ca_certs=None,
3402 )
3365 )
3403
3366
3404 try:
3367 try:
3405 s.connect(addr)
3368 s.connect(addr)
3406 cert = s.getpeercert(True)
3369 cert = s.getpeercert(True)
3407
3370
3408 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3371 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3409
3372
3410 complete = win32.checkcertificatechain(cert, build=False)
3373 complete = win32.checkcertificatechain(cert, build=False)
3411
3374
3412 if not complete:
3375 if not complete:
3413 ui.status(_(b'certificate chain is incomplete, updating... '))
3376 ui.status(_(b'certificate chain is incomplete, updating... '))
3414
3377
3415 if not win32.checkcertificatechain(cert):
3378 if not win32.checkcertificatechain(cert):
3416 ui.status(_(b'failed.\n'))
3379 ui.status(_(b'failed.\n'))
3417 else:
3380 else:
3418 ui.status(_(b'done.\n'))
3381 ui.status(_(b'done.\n'))
3419 else:
3382 else:
3420 ui.status(_(b'full certificate chain is available\n'))
3383 ui.status(_(b'full certificate chain is available\n'))
3421 finally:
3384 finally:
3422 s.close()
3385 s.close()
3423
3386
3424
3387
3425 @command(
3388 @command(
3426 b'debugsub',
3389 b'debugsub',
3427 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3390 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3428 _(b'[-r REV] [REV]'),
3391 _(b'[-r REV] [REV]'),
3429 )
3392 )
3430 def debugsub(ui, repo, rev=None):
3393 def debugsub(ui, repo, rev=None):
3431 ctx = scmutil.revsingle(repo, rev, None)
3394 ctx = scmutil.revsingle(repo, rev, None)
3432 for k, v in sorted(ctx.substate.items()):
3395 for k, v in sorted(ctx.substate.items()):
3433 ui.writenoi18n(b'path %s\n' % k)
3396 ui.writenoi18n(b'path %s\n' % k)
3434 ui.writenoi18n(b' source %s\n' % v[0])
3397 ui.writenoi18n(b' source %s\n' % v[0])
3435 ui.writenoi18n(b' revision %s\n' % v[1])
3398 ui.writenoi18n(b' revision %s\n' % v[1])
3436
3399
3437
3400
3438 @command(
3401 @command(
3439 b'debugsuccessorssets',
3402 b'debugsuccessorssets',
3440 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3403 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3441 _(b'[REV]'),
3404 _(b'[REV]'),
3442 )
3405 )
3443 def debugsuccessorssets(ui, repo, *revs, **opts):
3406 def debugsuccessorssets(ui, repo, *revs, **opts):
3444 """show set of successors for revision
3407 """show set of successors for revision
3445
3408
3446 A successors set of changeset A is a consistent group of revisions that
3409 A successors set of changeset A is a consistent group of revisions that
3447 succeed A. It contains non-obsolete changesets only unless closests
3410 succeed A. It contains non-obsolete changesets only unless closests
3448 successors set is set.
3411 successors set is set.
3449
3412
3450 In most cases a changeset A has a single successors set containing a single
3413 In most cases a changeset A has a single successors set containing a single
3451 successor (changeset A replaced by A').
3414 successor (changeset A replaced by A').
3452
3415
3453 A changeset that is made obsolete with no successors are called "pruned".
3416 A changeset that is made obsolete with no successors are called "pruned".
3454 Such changesets have no successors sets at all.
3417 Such changesets have no successors sets at all.
3455
3418
3456 A changeset that has been "split" will have a successors set containing
3419 A changeset that has been "split" will have a successors set containing
3457 more than one successor.
3420 more than one successor.
3458
3421
3459 A changeset that has been rewritten in multiple different ways is called
3422 A changeset that has been rewritten in multiple different ways is called
3460 "divergent". Such changesets have multiple successor sets (each of which
3423 "divergent". Such changesets have multiple successor sets (each of which
3461 may also be split, i.e. have multiple successors).
3424 may also be split, i.e. have multiple successors).
3462
3425
3463 Results are displayed as follows::
3426 Results are displayed as follows::
3464
3427
3465 <rev1>
3428 <rev1>
3466 <successors-1A>
3429 <successors-1A>
3467 <rev2>
3430 <rev2>
3468 <successors-2A>
3431 <successors-2A>
3469 <successors-2B1> <successors-2B2> <successors-2B3>
3432 <successors-2B1> <successors-2B2> <successors-2B3>
3470
3433
3471 Here rev2 has two possible (i.e. divergent) successors sets. The first
3434 Here rev2 has two possible (i.e. divergent) successors sets. The first
3472 holds one element, whereas the second holds three (i.e. the changeset has
3435 holds one element, whereas the second holds three (i.e. the changeset has
3473 been split).
3436 been split).
3474 """
3437 """
3475 # passed to successorssets caching computation from one call to another
3438 # passed to successorssets caching computation from one call to another
3476 cache = {}
3439 cache = {}
3477 ctx2str = bytes
3440 ctx2str = bytes
3478 node2str = short
3441 node2str = short
3479 for rev in scmutil.revrange(repo, revs):
3442 for rev in scmutil.revrange(repo, revs):
3480 ctx = repo[rev]
3443 ctx = repo[rev]
3481 ui.write(b'%s\n' % ctx2str(ctx))
3444 ui.write(b'%s\n' % ctx2str(ctx))
3482 for succsset in obsutil.successorssets(
3445 for succsset in obsutil.successorssets(
3483 repo, ctx.node(), closest=opts['closest'], cache=cache
3446 repo, ctx.node(), closest=opts['closest'], cache=cache
3484 ):
3447 ):
3485 if succsset:
3448 if succsset:
3486 ui.write(b' ')
3449 ui.write(b' ')
3487 ui.write(node2str(succsset[0]))
3450 ui.write(node2str(succsset[0]))
3488 for node in succsset[1:]:
3451 for node in succsset[1:]:
3489 ui.write(b' ')
3452 ui.write(b' ')
3490 ui.write(node2str(node))
3453 ui.write(node2str(node))
3491 ui.write(b'\n')
3454 ui.write(b'\n')
3492
3455
3493
3456
3494 @command(b'debugtagscache', [])
3457 @command(b'debugtagscache', [])
3495 def debugtagscache(ui, repo):
3458 def debugtagscache(ui, repo):
3496 """display the contents of .hg/cache/hgtagsfnodes1"""
3459 """display the contents of .hg/cache/hgtagsfnodes1"""
3497 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3460 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3498 for r in repo:
3461 for r in repo:
3499 node = repo[r].node()
3462 node = repo[r].node()
3500 tagsnode = cache.getfnode(node, computemissing=False)
3463 tagsnode = cache.getfnode(node, computemissing=False)
3501 tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
3464 tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
3502 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
3465 ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
3503
3466
3504
3467
3505 @command(
3468 @command(
3506 b'debugtemplate',
3469 b'debugtemplate',
3507 [
3470 [
3508 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3471 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3509 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3472 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3510 ],
3473 ],
3511 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3474 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3512 optionalrepo=True,
3475 optionalrepo=True,
3513 )
3476 )
3514 def debugtemplate(ui, repo, tmpl, **opts):
3477 def debugtemplate(ui, repo, tmpl, **opts):
3515 """parse and apply a template
3478 """parse and apply a template
3516
3479
3517 If -r/--rev is given, the template is processed as a log template and
3480 If -r/--rev is given, the template is processed as a log template and
3518 applied to the given changesets. Otherwise, it is processed as a generic
3481 applied to the given changesets. Otherwise, it is processed as a generic
3519 template.
3482 template.
3520
3483
3521 Use --verbose to print the parsed tree.
3484 Use --verbose to print the parsed tree.
3522 """
3485 """
3523 revs = None
3486 revs = None
3524 if opts['rev']:
3487 if opts['rev']:
3525 if repo is None:
3488 if repo is None:
3526 raise error.RepoError(
3489 raise error.RepoError(
3527 _(b'there is no Mercurial repository here (.hg not found)')
3490 _(b'there is no Mercurial repository here (.hg not found)')
3528 )
3491 )
3529 revs = scmutil.revrange(repo, opts['rev'])
3492 revs = scmutil.revrange(repo, opts['rev'])
3530
3493
3531 props = {}
3494 props = {}
3532 for d in opts['define']:
3495 for d in opts['define']:
3533 try:
3496 try:
3534 k, v = (e.strip() for e in d.split(b'=', 1))
3497 k, v = (e.strip() for e in d.split(b'=', 1))
3535 if not k or k == b'ui':
3498 if not k or k == b'ui':
3536 raise ValueError
3499 raise ValueError
3537 props[k] = v
3500 props[k] = v
3538 except ValueError:
3501 except ValueError:
3539 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3502 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3540
3503
3541 if ui.verbose:
3504 if ui.verbose:
3542 aliases = ui.configitems(b'templatealias')
3505 aliases = ui.configitems(b'templatealias')
3543 tree = templater.parse(tmpl)
3506 tree = templater.parse(tmpl)
3544 ui.note(templater.prettyformat(tree), b'\n')
3507 ui.note(templater.prettyformat(tree), b'\n')
3545 newtree = templater.expandaliases(tree, aliases)
3508 newtree = templater.expandaliases(tree, aliases)
3546 if newtree != tree:
3509 if newtree != tree:
3547 ui.notenoi18n(
3510 ui.notenoi18n(
3548 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3511 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3549 )
3512 )
3550
3513
3551 if revs is None:
3514 if revs is None:
3552 tres = formatter.templateresources(ui, repo)
3515 tres = formatter.templateresources(ui, repo)
3553 t = formatter.maketemplater(ui, tmpl, resources=tres)
3516 t = formatter.maketemplater(ui, tmpl, resources=tres)
3554 if ui.verbose:
3517 if ui.verbose:
3555 kwds, funcs = t.symbolsuseddefault()
3518 kwds, funcs = t.symbolsuseddefault()
3556 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3519 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3557 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3520 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3558 ui.write(t.renderdefault(props))
3521 ui.write(t.renderdefault(props))
3559 else:
3522 else:
3560 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3523 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3561 if ui.verbose:
3524 if ui.verbose:
3562 kwds, funcs = displayer.t.symbolsuseddefault()
3525 kwds, funcs = displayer.t.symbolsuseddefault()
3563 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3526 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3564 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3527 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3565 for r in revs:
3528 for r in revs:
3566 displayer.show(repo[r], **pycompat.strkwargs(props))
3529 displayer.show(repo[r], **pycompat.strkwargs(props))
3567 displayer.close()
3530 displayer.close()
3568
3531
3569
3532
3570 @command(
3533 @command(
3571 b'debuguigetpass',
3534 b'debuguigetpass',
3572 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3535 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3573 _(b'[-p TEXT]'),
3536 _(b'[-p TEXT]'),
3574 norepo=True,
3537 norepo=True,
3575 )
3538 )
3576 def debuguigetpass(ui, prompt=b''):
3539 def debuguigetpass(ui, prompt=b''):
3577 """show prompt to type password"""
3540 """show prompt to type password"""
3578 r = ui.getpass(prompt)
3541 r = ui.getpass(prompt)
3579 ui.writenoi18n(b'respose: %s\n' % r)
3542 ui.writenoi18n(b'respose: %s\n' % r)
3580
3543
3581
3544
3582 @command(
3545 @command(
3583 b'debuguiprompt',
3546 b'debuguiprompt',
3584 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3547 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3585 _(b'[-p TEXT]'),
3548 _(b'[-p TEXT]'),
3586 norepo=True,
3549 norepo=True,
3587 )
3550 )
3588 def debuguiprompt(ui, prompt=b''):
3551 def debuguiprompt(ui, prompt=b''):
3589 """show plain prompt"""
3552 """show plain prompt"""
3590 r = ui.prompt(prompt)
3553 r = ui.prompt(prompt)
3591 ui.writenoi18n(b'response: %s\n' % r)
3554 ui.writenoi18n(b'response: %s\n' % r)
3592
3555
3593
3556
3594 @command(b'debugupdatecaches', [])
3557 @command(b'debugupdatecaches', [])
3595 def debugupdatecaches(ui, repo, *pats, **opts):
3558 def debugupdatecaches(ui, repo, *pats, **opts):
3596 """warm all known caches in the repository"""
3559 """warm all known caches in the repository"""
3597 with repo.wlock(), repo.lock():
3560 with repo.wlock(), repo.lock():
3598 repo.updatecaches(full=True)
3561 repo.updatecaches(full=True)
3599
3562
3600
3563
3601 @command(
3564 @command(
3602 b'debugupgraderepo',
3565 b'debugupgraderepo',
3603 [
3566 [
3604 (
3567 (
3605 b'o',
3568 b'o',
3606 b'optimize',
3569 b'optimize',
3607 [],
3570 [],
3608 _(b'extra optimization to perform'),
3571 _(b'extra optimization to perform'),
3609 _(b'NAME'),
3572 _(b'NAME'),
3610 ),
3573 ),
3611 (b'', b'run', False, _(b'performs an upgrade')),
3574 (b'', b'run', False, _(b'performs an upgrade')),
3612 (b'', b'backup', True, _(b'keep the old repository content around')),
3575 (b'', b'backup', True, _(b'keep the old repository content around')),
3613 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3576 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3614 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3577 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3615 ],
3578 ],
3616 )
3579 )
3617 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3580 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3618 """upgrade a repository to use different features
3581 """upgrade a repository to use different features
3619
3582
3620 If no arguments are specified, the repository is evaluated for upgrade
3583 If no arguments are specified, the repository is evaluated for upgrade
3621 and a list of problems and potential optimizations is printed.
3584 and a list of problems and potential optimizations is printed.
3622
3585
3623 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3586 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3624 can be influenced via additional arguments. More details will be provided
3587 can be influenced via additional arguments. More details will be provided
3625 by the command output when run without ``--run``.
3588 by the command output when run without ``--run``.
3626
3589
3627 During the upgrade, the repository will be locked and no writes will be
3590 During the upgrade, the repository will be locked and no writes will be
3628 allowed.
3591 allowed.
3629
3592
3630 At the end of the upgrade, the repository may not be readable while new
3593 At the end of the upgrade, the repository may not be readable while new
3631 repository data is swapped in. This window will be as long as it takes to
3594 repository data is swapped in. This window will be as long as it takes to
3632 rename some directories inside the ``.hg`` directory. On most machines, this
3595 rename some directories inside the ``.hg`` directory. On most machines, this
3633 should complete almost instantaneously and the chances of a consumer being
3596 should complete almost instantaneously and the chances of a consumer being
3634 unable to access the repository should be low.
3597 unable to access the repository should be low.
3635
3598
3636 By default, all revlog will be upgraded. You can restrict this using flag
3599 By default, all revlog will be upgraded. You can restrict this using flag
3637 such as `--manifest`:
3600 such as `--manifest`:
3638
3601
3639 * `--manifest`: only optimize the manifest
3602 * `--manifest`: only optimize the manifest
3640 * `--no-manifest`: optimize all revlog but the manifest
3603 * `--no-manifest`: optimize all revlog but the manifest
3641 * `--changelog`: optimize the changelog only
3604 * `--changelog`: optimize the changelog only
3642 * `--no-changelog --no-manifest`: optimize filelogs only
3605 * `--no-changelog --no-manifest`: optimize filelogs only
3643 """
3606 """
3644 return upgrade.upgraderepo(
3607 return upgrade.upgraderepo(
3645 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3608 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3646 )
3609 )
3647
3610
3648
3611
3649 @command(
3612 @command(
3650 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3613 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3651 )
3614 )
3652 def debugwalk(ui, repo, *pats, **opts):
3615 def debugwalk(ui, repo, *pats, **opts):
3653 """show how files match on given patterns"""
3616 """show how files match on given patterns"""
3654 opts = pycompat.byteskwargs(opts)
3617 opts = pycompat.byteskwargs(opts)
3655 m = scmutil.match(repo[None], pats, opts)
3618 m = scmutil.match(repo[None], pats, opts)
3656 if ui.verbose:
3619 if ui.verbose:
3657 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3620 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3658 items = list(repo[None].walk(m))
3621 items = list(repo[None].walk(m))
3659 if not items:
3622 if not items:
3660 return
3623 return
3661 f = lambda fn: fn
3624 f = lambda fn: fn
3662 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3625 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3663 f = lambda fn: util.normpath(fn)
3626 f = lambda fn: util.normpath(fn)
3664 fmt = b'f %%-%ds %%-%ds %%s' % (
3627 fmt = b'f %%-%ds %%-%ds %%s' % (
3665 max([len(abs) for abs in items]),
3628 max([len(abs) for abs in items]),
3666 max([len(repo.pathto(abs)) for abs in items]),
3629 max([len(repo.pathto(abs)) for abs in items]),
3667 )
3630 )
3668 for abs in items:
3631 for abs in items:
3669 line = fmt % (
3632 line = fmt % (
3670 abs,
3633 abs,
3671 f(repo.pathto(abs)),
3634 f(repo.pathto(abs)),
3672 m.exact(abs) and b'exact' or b'',
3635 m.exact(abs) and b'exact' or b'',
3673 )
3636 )
3674 ui.write(b"%s\n" % line.rstrip())
3637 ui.write(b"%s\n" % line.rstrip())
3675
3638
3676
3639
3677 @command(b'debugwhyunstable', [], _(b'REV'))
3640 @command(b'debugwhyunstable', [], _(b'REV'))
3678 def debugwhyunstable(ui, repo, rev):
3641 def debugwhyunstable(ui, repo, rev):
3679 """explain instabilities of a changeset"""
3642 """explain instabilities of a changeset"""
3680 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3643 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3681 dnodes = b''
3644 dnodes = b''
3682 if entry.get(b'divergentnodes'):
3645 if entry.get(b'divergentnodes'):
3683 dnodes = (
3646 dnodes = (
3684 b' '.join(
3647 b' '.join(
3685 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3648 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3686 for ctx in entry[b'divergentnodes']
3649 for ctx in entry[b'divergentnodes']
3687 )
3650 )
3688 + b' '
3651 + b' '
3689 )
3652 )
3690 ui.write(
3653 ui.write(
3691 b'%s: %s%s %s\n'
3654 b'%s: %s%s %s\n'
3692 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3655 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3693 )
3656 )
3694
3657
3695
3658
3696 @command(
3659 @command(
3697 b'debugwireargs',
3660 b'debugwireargs',
3698 [
3661 [
3699 (b'', b'three', b'', b'three'),
3662 (b'', b'three', b'', b'three'),
3700 (b'', b'four', b'', b'four'),
3663 (b'', b'four', b'', b'four'),
3701 (b'', b'five', b'', b'five'),
3664 (b'', b'five', b'', b'five'),
3702 ]
3665 ]
3703 + cmdutil.remoteopts,
3666 + cmdutil.remoteopts,
3704 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3667 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3705 norepo=True,
3668 norepo=True,
3706 )
3669 )
3707 def debugwireargs(ui, repopath, *vals, **opts):
3670 def debugwireargs(ui, repopath, *vals, **opts):
3708 opts = pycompat.byteskwargs(opts)
3671 opts = pycompat.byteskwargs(opts)
3709 repo = hg.peer(ui, opts, repopath)
3672 repo = hg.peer(ui, opts, repopath)
3710 for opt in cmdutil.remoteopts:
3673 for opt in cmdutil.remoteopts:
3711 del opts[opt[1]]
3674 del opts[opt[1]]
3712 args = {}
3675 args = {}
3713 for k, v in pycompat.iteritems(opts):
3676 for k, v in pycompat.iteritems(opts):
3714 if v:
3677 if v:
3715 args[k] = v
3678 args[k] = v
3716 args = pycompat.strkwargs(args)
3679 args = pycompat.strkwargs(args)
3717 # run twice to check that we don't mess up the stream for the next command
3680 # run twice to check that we don't mess up the stream for the next command
3718 res1 = repo.debugwireargs(*vals, **args)
3681 res1 = repo.debugwireargs(*vals, **args)
3719 res2 = repo.debugwireargs(*vals, **args)
3682 res2 = repo.debugwireargs(*vals, **args)
3720 ui.write(b"%s\n" % res1)
3683 ui.write(b"%s\n" % res1)
3721 if res1 != res2:
3684 if res1 != res2:
3722 ui.warn(b"%s\n" % res2)
3685 ui.warn(b"%s\n" % res2)
3723
3686
3724
3687
3725 def _parsewirelangblocks(fh):
3688 def _parsewirelangblocks(fh):
3726 activeaction = None
3689 activeaction = None
3727 blocklines = []
3690 blocklines = []
3728 lastindent = 0
3691 lastindent = 0
3729
3692
3730 for line in fh:
3693 for line in fh:
3731 line = line.rstrip()
3694 line = line.rstrip()
3732 if not line:
3695 if not line:
3733 continue
3696 continue
3734
3697
3735 if line.startswith(b'#'):
3698 if line.startswith(b'#'):
3736 continue
3699 continue
3737
3700
3738 if not line.startswith(b' '):
3701 if not line.startswith(b' '):
3739 # New block. Flush previous one.
3702 # New block. Flush previous one.
3740 if activeaction:
3703 if activeaction:
3741 yield activeaction, blocklines
3704 yield activeaction, blocklines
3742
3705
3743 activeaction = line
3706 activeaction = line
3744 blocklines = []
3707 blocklines = []
3745 lastindent = 0
3708 lastindent = 0
3746 continue
3709 continue
3747
3710
3748 # Else we start with an indent.
3711 # Else we start with an indent.
3749
3712
3750 if not activeaction:
3713 if not activeaction:
3751 raise error.Abort(_(b'indented line outside of block'))
3714 raise error.Abort(_(b'indented line outside of block'))
3752
3715
3753 indent = len(line) - len(line.lstrip())
3716 indent = len(line) - len(line.lstrip())
3754
3717
3755 # If this line is indented more than the last line, concatenate it.
3718 # If this line is indented more than the last line, concatenate it.
3756 if indent > lastindent and blocklines:
3719 if indent > lastindent and blocklines:
3757 blocklines[-1] += line.lstrip()
3720 blocklines[-1] += line.lstrip()
3758 else:
3721 else:
3759 blocklines.append(line)
3722 blocklines.append(line)
3760 lastindent = indent
3723 lastindent = indent
3761
3724
3762 # Flush last block.
3725 # Flush last block.
3763 if activeaction:
3726 if activeaction:
3764 yield activeaction, blocklines
3727 yield activeaction, blocklines
3765
3728
3766
3729
3767 @command(
3730 @command(
3768 b'debugwireproto',
3731 b'debugwireproto',
3769 [
3732 [
3770 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3733 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3771 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3734 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3772 (
3735 (
3773 b'',
3736 b'',
3774 b'noreadstderr',
3737 b'noreadstderr',
3775 False,
3738 False,
3776 _(b'do not read from stderr of the remote'),
3739 _(b'do not read from stderr of the remote'),
3777 ),
3740 ),
3778 (
3741 (
3779 b'',
3742 b'',
3780 b'nologhandshake',
3743 b'nologhandshake',
3781 False,
3744 False,
3782 _(b'do not log I/O related to the peer handshake'),
3745 _(b'do not log I/O related to the peer handshake'),
3783 ),
3746 ),
3784 ]
3747 ]
3785 + cmdutil.remoteopts,
3748 + cmdutil.remoteopts,
3786 _(b'[PATH]'),
3749 _(b'[PATH]'),
3787 optionalrepo=True,
3750 optionalrepo=True,
3788 )
3751 )
3789 def debugwireproto(ui, repo, path=None, **opts):
3752 def debugwireproto(ui, repo, path=None, **opts):
3790 """send wire protocol commands to a server
3753 """send wire protocol commands to a server
3791
3754
3792 This command can be used to issue wire protocol commands to remote
3755 This command can be used to issue wire protocol commands to remote
3793 peers and to debug the raw data being exchanged.
3756 peers and to debug the raw data being exchanged.
3794
3757
3795 ``--localssh`` will start an SSH server against the current repository
3758 ``--localssh`` will start an SSH server against the current repository
3796 and connect to that. By default, the connection will perform a handshake
3759 and connect to that. By default, the connection will perform a handshake
3797 and establish an appropriate peer instance.
3760 and establish an appropriate peer instance.
3798
3761
3799 ``--peer`` can be used to bypass the handshake protocol and construct a
3762 ``--peer`` can be used to bypass the handshake protocol and construct a
3800 peer instance using the specified class type. Valid values are ``raw``,
3763 peer instance using the specified class type. Valid values are ``raw``,
3801 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3764 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3802 raw data payloads and don't support higher-level command actions.
3765 raw data payloads and don't support higher-level command actions.
3803
3766
3804 ``--noreadstderr`` can be used to disable automatic reading from stderr
3767 ``--noreadstderr`` can be used to disable automatic reading from stderr
3805 of the peer (for SSH connections only). Disabling automatic reading of
3768 of the peer (for SSH connections only). Disabling automatic reading of
3806 stderr is useful for making output more deterministic.
3769 stderr is useful for making output more deterministic.
3807
3770
3808 Commands are issued via a mini language which is specified via stdin.
3771 Commands are issued via a mini language which is specified via stdin.
3809 The language consists of individual actions to perform. An action is
3772 The language consists of individual actions to perform. An action is
3810 defined by a block. A block is defined as a line with no leading
3773 defined by a block. A block is defined as a line with no leading
3811 space followed by 0 or more lines with leading space. Blocks are
3774 space followed by 0 or more lines with leading space. Blocks are
3812 effectively a high-level command with additional metadata.
3775 effectively a high-level command with additional metadata.
3813
3776
3814 Lines beginning with ``#`` are ignored.
3777 Lines beginning with ``#`` are ignored.
3815
3778
3816 The following sections denote available actions.
3779 The following sections denote available actions.
3817
3780
3818 raw
3781 raw
3819 ---
3782 ---
3820
3783
3821 Send raw data to the server.
3784 Send raw data to the server.
3822
3785
3823 The block payload contains the raw data to send as one atomic send
3786 The block payload contains the raw data to send as one atomic send
3824 operation. The data may not actually be delivered in a single system
3787 operation. The data may not actually be delivered in a single system
3825 call: it depends on the abilities of the transport being used.
3788 call: it depends on the abilities of the transport being used.
3826
3789
3827 Each line in the block is de-indented and concatenated. Then, that
3790 Each line in the block is de-indented and concatenated. Then, that
3828 value is evaluated as a Python b'' literal. This allows the use of
3791 value is evaluated as a Python b'' literal. This allows the use of
3829 backslash escaping, etc.
3792 backslash escaping, etc.
3830
3793
3831 raw+
3794 raw+
3832 ----
3795 ----
3833
3796
3834 Behaves like ``raw`` except flushes output afterwards.
3797 Behaves like ``raw`` except flushes output afterwards.
3835
3798
3836 command <X>
3799 command <X>
3837 -----------
3800 -----------
3838
3801
3839 Send a request to run a named command, whose name follows the ``command``
3802 Send a request to run a named command, whose name follows the ``command``
3840 string.
3803 string.
3841
3804
3842 Arguments to the command are defined as lines in this block. The format of
3805 Arguments to the command are defined as lines in this block. The format of
3843 each line is ``<key> <value>``. e.g.::
3806 each line is ``<key> <value>``. e.g.::
3844
3807
3845 command listkeys
3808 command listkeys
3846 namespace bookmarks
3809 namespace bookmarks
3847
3810
3848 If the value begins with ``eval:``, it will be interpreted as a Python
3811 If the value begins with ``eval:``, it will be interpreted as a Python
3849 literal expression. Otherwise values are interpreted as Python b'' literals.
3812 literal expression. Otherwise values are interpreted as Python b'' literals.
3850 This allows sending complex types and encoding special byte sequences via
3813 This allows sending complex types and encoding special byte sequences via
3851 backslash escaping.
3814 backslash escaping.
3852
3815
3853 The following arguments have special meaning:
3816 The following arguments have special meaning:
3854
3817
3855 ``PUSHFILE``
3818 ``PUSHFILE``
3856 When defined, the *push* mechanism of the peer will be used instead
3819 When defined, the *push* mechanism of the peer will be used instead
3857 of the static request-response mechanism and the content of the
3820 of the static request-response mechanism and the content of the
3858 file specified in the value of this argument will be sent as the
3821 file specified in the value of this argument will be sent as the
3859 command payload.
3822 command payload.
3860
3823
3861 This can be used to submit a local bundle file to the remote.
3824 This can be used to submit a local bundle file to the remote.
3862
3825
3863 batchbegin
3826 batchbegin
3864 ----------
3827 ----------
3865
3828
3866 Instruct the peer to begin a batched send.
3829 Instruct the peer to begin a batched send.
3867
3830
3868 All ``command`` blocks are queued for execution until the next
3831 All ``command`` blocks are queued for execution until the next
3869 ``batchsubmit`` block.
3832 ``batchsubmit`` block.
3870
3833
3871 batchsubmit
3834 batchsubmit
3872 -----------
3835 -----------
3873
3836
3874 Submit previously queued ``command`` blocks as a batch request.
3837 Submit previously queued ``command`` blocks as a batch request.
3875
3838
3876 This action MUST be paired with a ``batchbegin`` action.
3839 This action MUST be paired with a ``batchbegin`` action.
3877
3840
3878 httprequest <method> <path>
3841 httprequest <method> <path>
3879 ---------------------------
3842 ---------------------------
3880
3843
3881 (HTTP peer only)
3844 (HTTP peer only)
3882
3845
3883 Send an HTTP request to the peer.
3846 Send an HTTP request to the peer.
3884
3847
3885 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
3848 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
3886
3849
3887 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
3850 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
3888 headers to add to the request. e.g. ``Accept: foo``.
3851 headers to add to the request. e.g. ``Accept: foo``.
3889
3852
3890 The following arguments are special:
3853 The following arguments are special:
3891
3854
3892 ``BODYFILE``
3855 ``BODYFILE``
3893 The content of the file defined as the value to this argument will be
3856 The content of the file defined as the value to this argument will be
3894 transferred verbatim as the HTTP request body.
3857 transferred verbatim as the HTTP request body.
3895
3858
3896 ``frame <type> <flags> <payload>``
3859 ``frame <type> <flags> <payload>``
3897 Send a unified protocol frame as part of the request body.
3860 Send a unified protocol frame as part of the request body.
3898
3861
3899 All frames will be collected and sent as the body to the HTTP
3862 All frames will be collected and sent as the body to the HTTP
3900 request.
3863 request.
3901
3864
3902 close
3865 close
3903 -----
3866 -----
3904
3867
3905 Close the connection to the server.
3868 Close the connection to the server.
3906
3869
3907 flush
3870 flush
3908 -----
3871 -----
3909
3872
3910 Flush data written to the server.
3873 Flush data written to the server.
3911
3874
3912 readavailable
3875 readavailable
3913 -------------
3876 -------------
3914
3877
3915 Close the write end of the connection and read all available data from
3878 Close the write end of the connection and read all available data from
3916 the server.
3879 the server.
3917
3880
3918 If the connection to the server encompasses multiple pipes, we poll both
3881 If the connection to the server encompasses multiple pipes, we poll both
3919 pipes and read available data.
3882 pipes and read available data.
3920
3883
3921 readline
3884 readline
3922 --------
3885 --------
3923
3886
3924 Read a line of output from the server. If there are multiple output
3887 Read a line of output from the server. If there are multiple output
3925 pipes, reads only the main pipe.
3888 pipes, reads only the main pipe.
3926
3889
3927 ereadline
3890 ereadline
3928 ---------
3891 ---------
3929
3892
3930 Like ``readline``, but read from the stderr pipe, if available.
3893 Like ``readline``, but read from the stderr pipe, if available.
3931
3894
3932 read <X>
3895 read <X>
3933 --------
3896 --------
3934
3897
3935 ``read()`` N bytes from the server's main output pipe.
3898 ``read()`` N bytes from the server's main output pipe.
3936
3899
3937 eread <X>
3900 eread <X>
3938 ---------
3901 ---------
3939
3902
3940 ``read()`` N bytes from the server's stderr pipe, if available.
3903 ``read()`` N bytes from the server's stderr pipe, if available.
3941
3904
3942 Specifying Unified Frame-Based Protocol Frames
3905 Specifying Unified Frame-Based Protocol Frames
3943 ----------------------------------------------
3906 ----------------------------------------------
3944
3907
3945 It is possible to emit a *Unified Frame-Based Protocol* by using special
3908 It is possible to emit a *Unified Frame-Based Protocol* by using special
3946 syntax.
3909 syntax.
3947
3910
3948 A frame is composed as a type, flags, and payload. These can be parsed
3911 A frame is composed as a type, flags, and payload. These can be parsed
3949 from a string of the form:
3912 from a string of the form:
3950
3913
3951 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3914 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3952
3915
3953 ``request-id`` and ``stream-id`` are integers defining the request and
3916 ``request-id`` and ``stream-id`` are integers defining the request and
3954 stream identifiers.
3917 stream identifiers.
3955
3918
3956 ``type`` can be an integer value for the frame type or the string name
3919 ``type`` can be an integer value for the frame type or the string name
3957 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3920 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3958 ``command-name``.
3921 ``command-name``.
3959
3922
3960 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3923 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3961 components. Each component (and there can be just one) can be an integer
3924 components. Each component (and there can be just one) can be an integer
3962 or a flag name for stream flags or frame flags, respectively. Values are
3925 or a flag name for stream flags or frame flags, respectively. Values are
3963 resolved to integers and then bitwise OR'd together.
3926 resolved to integers and then bitwise OR'd together.
3964
3927
3965 ``payload`` represents the raw frame payload. If it begins with
3928 ``payload`` represents the raw frame payload. If it begins with
3966 ``cbor:``, the following string is evaluated as Python code and the
3929 ``cbor:``, the following string is evaluated as Python code and the
3967 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3930 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3968 as a Python byte string literal.
3931 as a Python byte string literal.
3969 """
3932 """
3970 opts = pycompat.byteskwargs(opts)
3933 opts = pycompat.byteskwargs(opts)
3971
3934
3972 if opts[b'localssh'] and not repo:
3935 if opts[b'localssh'] and not repo:
3973 raise error.Abort(_(b'--localssh requires a repository'))
3936 raise error.Abort(_(b'--localssh requires a repository'))
3974
3937
3975 if opts[b'peer'] and opts[b'peer'] not in (
3938 if opts[b'peer'] and opts[b'peer'] not in (
3976 b'raw',
3939 b'raw',
3977 b'http2',
3940 b'http2',
3978 b'ssh1',
3941 b'ssh1',
3979 b'ssh2',
3942 b'ssh2',
3980 ):
3943 ):
3981 raise error.Abort(
3944 raise error.Abort(
3982 _(b'invalid value for --peer'),
3945 _(b'invalid value for --peer'),
3983 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
3946 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
3984 )
3947 )
3985
3948
3986 if path and opts[b'localssh']:
3949 if path and opts[b'localssh']:
3987 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
3950 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
3988
3951
3989 if ui.interactive():
3952 if ui.interactive():
3990 ui.write(_(b'(waiting for commands on stdin)\n'))
3953 ui.write(_(b'(waiting for commands on stdin)\n'))
3991
3954
3992 blocks = list(_parsewirelangblocks(ui.fin))
3955 blocks = list(_parsewirelangblocks(ui.fin))
3993
3956
3994 proc = None
3957 proc = None
3995 stdin = None
3958 stdin = None
3996 stdout = None
3959 stdout = None
3997 stderr = None
3960 stderr = None
3998 opener = None
3961 opener = None
3999
3962
4000 if opts[b'localssh']:
3963 if opts[b'localssh']:
4001 # We start the SSH server in its own process so there is process
3964 # We start the SSH server in its own process so there is process
4002 # separation. This prevents a whole class of potential bugs around
3965 # separation. This prevents a whole class of potential bugs around
4003 # shared state from interfering with server operation.
3966 # shared state from interfering with server operation.
4004 args = procutil.hgcmd() + [
3967 args = procutil.hgcmd() + [
4005 b'-R',
3968 b'-R',
4006 repo.root,
3969 repo.root,
4007 b'debugserve',
3970 b'debugserve',
4008 b'--sshstdio',
3971 b'--sshstdio',
4009 ]
3972 ]
4010 proc = subprocess.Popen(
3973 proc = subprocess.Popen(
4011 pycompat.rapply(procutil.tonativestr, args),
3974 pycompat.rapply(procutil.tonativestr, args),
4012 stdin=subprocess.PIPE,
3975 stdin=subprocess.PIPE,
4013 stdout=subprocess.PIPE,
3976 stdout=subprocess.PIPE,
4014 stderr=subprocess.PIPE,
3977 stderr=subprocess.PIPE,
4015 bufsize=0,
3978 bufsize=0,
4016 )
3979 )
4017
3980
4018 stdin = proc.stdin
3981 stdin = proc.stdin
4019 stdout = proc.stdout
3982 stdout = proc.stdout
4020 stderr = proc.stderr
3983 stderr = proc.stderr
4021
3984
4022 # We turn the pipes into observers so we can log I/O.
3985 # We turn the pipes into observers so we can log I/O.
4023 if ui.verbose or opts[b'peer'] == b'raw':
3986 if ui.verbose or opts[b'peer'] == b'raw':
4024 stdin = util.makeloggingfileobject(
3987 stdin = util.makeloggingfileobject(
4025 ui, proc.stdin, b'i', logdata=True
3988 ui, proc.stdin, b'i', logdata=True
4026 )
3989 )
4027 stdout = util.makeloggingfileobject(
3990 stdout = util.makeloggingfileobject(
4028 ui, proc.stdout, b'o', logdata=True
3991 ui, proc.stdout, b'o', logdata=True
4029 )
3992 )
4030 stderr = util.makeloggingfileobject(
3993 stderr = util.makeloggingfileobject(
4031 ui, proc.stderr, b'e', logdata=True
3994 ui, proc.stderr, b'e', logdata=True
4032 )
3995 )
4033
3996
4034 # --localssh also implies the peer connection settings.
3997 # --localssh also implies the peer connection settings.
4035
3998
4036 url = b'ssh://localserver'
3999 url = b'ssh://localserver'
4037 autoreadstderr = not opts[b'noreadstderr']
4000 autoreadstderr = not opts[b'noreadstderr']
4038
4001
4039 if opts[b'peer'] == b'ssh1':
4002 if opts[b'peer'] == b'ssh1':
4040 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4003 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
4041 peer = sshpeer.sshv1peer(
4004 peer = sshpeer.sshv1peer(
4042 ui,
4005 ui,
4043 url,
4006 url,
4044 proc,
4007 proc,
4045 stdin,
4008 stdin,
4046 stdout,
4009 stdout,
4047 stderr,
4010 stderr,
4048 None,
4011 None,
4049 autoreadstderr=autoreadstderr,
4012 autoreadstderr=autoreadstderr,
4050 )
4013 )
4051 elif opts[b'peer'] == b'ssh2':
4014 elif opts[b'peer'] == b'ssh2':
4052 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
4015 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
4053 peer = sshpeer.sshv2peer(
4016 peer = sshpeer.sshv2peer(
4054 ui,
4017 ui,
4055 url,
4018 url,
4056 proc,
4019 proc,
4057 stdin,
4020 stdin,
4058 stdout,
4021 stdout,
4059 stderr,
4022 stderr,
4060 None,
4023 None,
4061 autoreadstderr=autoreadstderr,
4024 autoreadstderr=autoreadstderr,
4062 )
4025 )
4063 elif opts[b'peer'] == b'raw':
4026 elif opts[b'peer'] == b'raw':
4064 ui.write(_(b'using raw connection to peer\n'))
4027 ui.write(_(b'using raw connection to peer\n'))
4065 peer = None
4028 peer = None
4066 else:
4029 else:
4067 ui.write(_(b'creating ssh peer from handshake results\n'))
4030 ui.write(_(b'creating ssh peer from handshake results\n'))
4068 peer = sshpeer.makepeer(
4031 peer = sshpeer.makepeer(
4069 ui,
4032 ui,
4070 url,
4033 url,
4071 proc,
4034 proc,
4072 stdin,
4035 stdin,
4073 stdout,
4036 stdout,
4074 stderr,
4037 stderr,
4075 autoreadstderr=autoreadstderr,
4038 autoreadstderr=autoreadstderr,
4076 )
4039 )
4077
4040
4078 elif path:
4041 elif path:
4079 # We bypass hg.peer() so we can proxy the sockets.
4042 # We bypass hg.peer() so we can proxy the sockets.
4080 # TODO consider not doing this because we skip
4043 # TODO consider not doing this because we skip
4081 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4044 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4082 u = util.url(path)
4045 u = util.url(path)
4083 if u.scheme != b'http':
4046 if u.scheme != b'http':
4084 raise error.Abort(_(b'only http:// paths are currently supported'))
4047 raise error.Abort(_(b'only http:// paths are currently supported'))
4085
4048
4086 url, authinfo = u.authinfo()
4049 url, authinfo = u.authinfo()
4087 openerargs = {
4050 openerargs = {
4088 'useragent': b'Mercurial debugwireproto',
4051 'useragent': b'Mercurial debugwireproto',
4089 }
4052 }
4090
4053
4091 # Turn pipes/sockets into observers so we can log I/O.
4054 # Turn pipes/sockets into observers so we can log I/O.
4092 if ui.verbose:
4055 if ui.verbose:
4093 openerargs.update(
4056 openerargs.update(
4094 {
4057 {
4095 'loggingfh': ui,
4058 'loggingfh': ui,
4096 'loggingname': b's',
4059 'loggingname': b's',
4097 'loggingopts': {'logdata': True, 'logdataapis': False,},
4060 'loggingopts': {'logdata': True, 'logdataapis': False,},
4098 }
4061 }
4099 )
4062 )
4100
4063
4101 if ui.debugflag:
4064 if ui.debugflag:
4102 openerargs['loggingopts']['logdataapis'] = True
4065 openerargs['loggingopts']['logdataapis'] = True
4103
4066
4104 # Don't send default headers when in raw mode. This allows us to
4067 # Don't send default headers when in raw mode. This allows us to
4105 # bypass most of the behavior of our URL handling code so we can
4068 # bypass most of the behavior of our URL handling code so we can
4106 # have near complete control over what's sent on the wire.
4069 # have near complete control over what's sent on the wire.
4107 if opts[b'peer'] == b'raw':
4070 if opts[b'peer'] == b'raw':
4108 openerargs['sendaccept'] = False
4071 openerargs['sendaccept'] = False
4109
4072
4110 opener = urlmod.opener(ui, authinfo, **openerargs)
4073 opener = urlmod.opener(ui, authinfo, **openerargs)
4111
4074
4112 if opts[b'peer'] == b'http2':
4075 if opts[b'peer'] == b'http2':
4113 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4076 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4114 # We go through makepeer() because we need an API descriptor for
4077 # We go through makepeer() because we need an API descriptor for
4115 # the peer instance to be useful.
4078 # the peer instance to be useful.
4116 with ui.configoverride(
4079 with ui.configoverride(
4117 {(b'experimental', b'httppeer.advertise-v2'): True}
4080 {(b'experimental', b'httppeer.advertise-v2'): True}
4118 ):
4081 ):
4119 if opts[b'nologhandshake']:
4082 if opts[b'nologhandshake']:
4120 ui.pushbuffer()
4083 ui.pushbuffer()
4121
4084
4122 peer = httppeer.makepeer(ui, path, opener=opener)
4085 peer = httppeer.makepeer(ui, path, opener=opener)
4123
4086
4124 if opts[b'nologhandshake']:
4087 if opts[b'nologhandshake']:
4125 ui.popbuffer()
4088 ui.popbuffer()
4126
4089
4127 if not isinstance(peer, httppeer.httpv2peer):
4090 if not isinstance(peer, httppeer.httpv2peer):
4128 raise error.Abort(
4091 raise error.Abort(
4129 _(
4092 _(
4130 b'could not instantiate HTTP peer for '
4093 b'could not instantiate HTTP peer for '
4131 b'wire protocol version 2'
4094 b'wire protocol version 2'
4132 ),
4095 ),
4133 hint=_(
4096 hint=_(
4134 b'the server may not have the feature '
4097 b'the server may not have the feature '
4135 b'enabled or is not allowing this '
4098 b'enabled or is not allowing this '
4136 b'client version'
4099 b'client version'
4137 ),
4100 ),
4138 )
4101 )
4139
4102
4140 elif opts[b'peer'] == b'raw':
4103 elif opts[b'peer'] == b'raw':
4141 ui.write(_(b'using raw connection to peer\n'))
4104 ui.write(_(b'using raw connection to peer\n'))
4142 peer = None
4105 peer = None
4143 elif opts[b'peer']:
4106 elif opts[b'peer']:
4144 raise error.Abort(
4107 raise error.Abort(
4145 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4108 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4146 )
4109 )
4147 else:
4110 else:
4148 peer = httppeer.makepeer(ui, path, opener=opener)
4111 peer = httppeer.makepeer(ui, path, opener=opener)
4149
4112
4150 # We /could/ populate stdin/stdout with sock.makefile()...
4113 # We /could/ populate stdin/stdout with sock.makefile()...
4151 else:
4114 else:
4152 raise error.Abort(_(b'unsupported connection configuration'))
4115 raise error.Abort(_(b'unsupported connection configuration'))
4153
4116
4154 batchedcommands = None
4117 batchedcommands = None
4155
4118
4156 # Now perform actions based on the parsed wire language instructions.
4119 # Now perform actions based on the parsed wire language instructions.
4157 for action, lines in blocks:
4120 for action, lines in blocks:
4158 if action in (b'raw', b'raw+'):
4121 if action in (b'raw', b'raw+'):
4159 if not stdin:
4122 if not stdin:
4160 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4123 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4161
4124
4162 # Concatenate the data together.
4125 # Concatenate the data together.
4163 data = b''.join(l.lstrip() for l in lines)
4126 data = b''.join(l.lstrip() for l in lines)
4164 data = stringutil.unescapestr(data)
4127 data = stringutil.unescapestr(data)
4165 stdin.write(data)
4128 stdin.write(data)
4166
4129
4167 if action == b'raw+':
4130 if action == b'raw+':
4168 stdin.flush()
4131 stdin.flush()
4169 elif action == b'flush':
4132 elif action == b'flush':
4170 if not stdin:
4133 if not stdin:
4171 raise error.Abort(_(b'cannot call flush on this peer'))
4134 raise error.Abort(_(b'cannot call flush on this peer'))
4172 stdin.flush()
4135 stdin.flush()
4173 elif action.startswith(b'command'):
4136 elif action.startswith(b'command'):
4174 if not peer:
4137 if not peer:
4175 raise error.Abort(
4138 raise error.Abort(
4176 _(
4139 _(
4177 b'cannot send commands unless peer instance '
4140 b'cannot send commands unless peer instance '
4178 b'is available'
4141 b'is available'
4179 )
4142 )
4180 )
4143 )
4181
4144
4182 command = action.split(b' ', 1)[1]
4145 command = action.split(b' ', 1)[1]
4183
4146
4184 args = {}
4147 args = {}
4185 for line in lines:
4148 for line in lines:
4186 # We need to allow empty values.
4149 # We need to allow empty values.
4187 fields = line.lstrip().split(b' ', 1)
4150 fields = line.lstrip().split(b' ', 1)
4188 if len(fields) == 1:
4151 if len(fields) == 1:
4189 key = fields[0]
4152 key = fields[0]
4190 value = b''
4153 value = b''
4191 else:
4154 else:
4192 key, value = fields
4155 key, value = fields
4193
4156
4194 if value.startswith(b'eval:'):
4157 if value.startswith(b'eval:'):
4195 value = stringutil.evalpythonliteral(value[5:])
4158 value = stringutil.evalpythonliteral(value[5:])
4196 else:
4159 else:
4197 value = stringutil.unescapestr(value)
4160 value = stringutil.unescapestr(value)
4198
4161
4199 args[key] = value
4162 args[key] = value
4200
4163
4201 if batchedcommands is not None:
4164 if batchedcommands is not None:
4202 batchedcommands.append((command, args))
4165 batchedcommands.append((command, args))
4203 continue
4166 continue
4204
4167
4205 ui.status(_(b'sending %s command\n') % command)
4168 ui.status(_(b'sending %s command\n') % command)
4206
4169
4207 if b'PUSHFILE' in args:
4170 if b'PUSHFILE' in args:
4208 with open(args[b'PUSHFILE'], 'rb') as fh:
4171 with open(args[b'PUSHFILE'], 'rb') as fh:
4209 del args[b'PUSHFILE']
4172 del args[b'PUSHFILE']
4210 res, output = peer._callpush(
4173 res, output = peer._callpush(
4211 command, fh, **pycompat.strkwargs(args)
4174 command, fh, **pycompat.strkwargs(args)
4212 )
4175 )
4213 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4176 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4214 ui.status(
4177 ui.status(
4215 _(b'remote output: %s\n') % stringutil.escapestr(output)
4178 _(b'remote output: %s\n') % stringutil.escapestr(output)
4216 )
4179 )
4217 else:
4180 else:
4218 with peer.commandexecutor() as e:
4181 with peer.commandexecutor() as e:
4219 res = e.callcommand(command, args).result()
4182 res = e.callcommand(command, args).result()
4220
4183
4221 if isinstance(res, wireprotov2peer.commandresponse):
4184 if isinstance(res, wireprotov2peer.commandresponse):
4222 val = res.objects()
4185 val = res.objects()
4223 ui.status(
4186 ui.status(
4224 _(b'response: %s\n')
4187 _(b'response: %s\n')
4225 % stringutil.pprint(val, bprefix=True, indent=2)
4188 % stringutil.pprint(val, bprefix=True, indent=2)
4226 )
4189 )
4227 else:
4190 else:
4228 ui.status(
4191 ui.status(
4229 _(b'response: %s\n')
4192 _(b'response: %s\n')
4230 % stringutil.pprint(res, bprefix=True, indent=2)
4193 % stringutil.pprint(res, bprefix=True, indent=2)
4231 )
4194 )
4232
4195
4233 elif action == b'batchbegin':
4196 elif action == b'batchbegin':
4234 if batchedcommands is not None:
4197 if batchedcommands is not None:
4235 raise error.Abort(_(b'nested batchbegin not allowed'))
4198 raise error.Abort(_(b'nested batchbegin not allowed'))
4236
4199
4237 batchedcommands = []
4200 batchedcommands = []
4238 elif action == b'batchsubmit':
4201 elif action == b'batchsubmit':
4239 # There is a batching API we could go through. But it would be
4202 # There is a batching API we could go through. But it would be
4240 # difficult to normalize requests into function calls. It is easier
4203 # difficult to normalize requests into function calls. It is easier
4241 # to bypass this layer and normalize to commands + args.
4204 # to bypass this layer and normalize to commands + args.
4242 ui.status(
4205 ui.status(
4243 _(b'sending batch with %d sub-commands\n')
4206 _(b'sending batch with %d sub-commands\n')
4244 % len(batchedcommands)
4207 % len(batchedcommands)
4245 )
4208 )
4246 assert peer is not None
4209 assert peer is not None
4247 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4210 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4248 ui.status(
4211 ui.status(
4249 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4212 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4250 )
4213 )
4251
4214
4252 batchedcommands = None
4215 batchedcommands = None
4253
4216
4254 elif action.startswith(b'httprequest '):
4217 elif action.startswith(b'httprequest '):
4255 if not opener:
4218 if not opener:
4256 raise error.Abort(
4219 raise error.Abort(
4257 _(b'cannot use httprequest without an HTTP peer')
4220 _(b'cannot use httprequest without an HTTP peer')
4258 )
4221 )
4259
4222
4260 request = action.split(b' ', 2)
4223 request = action.split(b' ', 2)
4261 if len(request) != 3:
4224 if len(request) != 3:
4262 raise error.Abort(
4225 raise error.Abort(
4263 _(
4226 _(
4264 b'invalid httprequest: expected format is '
4227 b'invalid httprequest: expected format is '
4265 b'"httprequest <method> <path>'
4228 b'"httprequest <method> <path>'
4266 )
4229 )
4267 )
4230 )
4268
4231
4269 method, httppath = request[1:]
4232 method, httppath = request[1:]
4270 headers = {}
4233 headers = {}
4271 body = None
4234 body = None
4272 frames = []
4235 frames = []
4273 for line in lines:
4236 for line in lines:
4274 line = line.lstrip()
4237 line = line.lstrip()
4275 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4238 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4276 if m:
4239 if m:
4277 # Headers need to use native strings.
4240 # Headers need to use native strings.
4278 key = pycompat.strurl(m.group(1))
4241 key = pycompat.strurl(m.group(1))
4279 value = pycompat.strurl(m.group(2))
4242 value = pycompat.strurl(m.group(2))
4280 headers[key] = value
4243 headers[key] = value
4281 continue
4244 continue
4282
4245
4283 if line.startswith(b'BODYFILE '):
4246 if line.startswith(b'BODYFILE '):
4284 with open(line.split(b' ', 1), b'rb') as fh:
4247 with open(line.split(b' ', 1), b'rb') as fh:
4285 body = fh.read()
4248 body = fh.read()
4286 elif line.startswith(b'frame '):
4249 elif line.startswith(b'frame '):
4287 frame = wireprotoframing.makeframefromhumanstring(
4250 frame = wireprotoframing.makeframefromhumanstring(
4288 line[len(b'frame ') :]
4251 line[len(b'frame ') :]
4289 )
4252 )
4290
4253
4291 frames.append(frame)
4254 frames.append(frame)
4292 else:
4255 else:
4293 raise error.Abort(
4256 raise error.Abort(
4294 _(b'unknown argument to httprequest: %s') % line
4257 _(b'unknown argument to httprequest: %s') % line
4295 )
4258 )
4296
4259
4297 url = path + httppath
4260 url = path + httppath
4298
4261
4299 if frames:
4262 if frames:
4300 body = b''.join(bytes(f) for f in frames)
4263 body = b''.join(bytes(f) for f in frames)
4301
4264
4302 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4265 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4303
4266
4304 # urllib.Request insists on using has_data() as a proxy for
4267 # urllib.Request insists on using has_data() as a proxy for
4305 # determining the request method. Override that to use our
4268 # determining the request method. Override that to use our
4306 # explicitly requested method.
4269 # explicitly requested method.
4307 req.get_method = lambda: pycompat.sysstr(method)
4270 req.get_method = lambda: pycompat.sysstr(method)
4308
4271
4309 try:
4272 try:
4310 res = opener.open(req)
4273 res = opener.open(req)
4311 body = res.read()
4274 body = res.read()
4312 except util.urlerr.urlerror as e:
4275 except util.urlerr.urlerror as e:
4313 # read() method must be called, but only exists in Python 2
4276 # read() method must be called, but only exists in Python 2
4314 getattr(e, 'read', lambda: None)()
4277 getattr(e, 'read', lambda: None)()
4315 continue
4278 continue
4316
4279
4317 ct = res.headers.get('Content-Type')
4280 ct = res.headers.get('Content-Type')
4318 if ct == 'application/mercurial-cbor':
4281 if ct == 'application/mercurial-cbor':
4319 ui.write(
4282 ui.write(
4320 _(b'cbor> %s\n')
4283 _(b'cbor> %s\n')
4321 % stringutil.pprint(
4284 % stringutil.pprint(
4322 cborutil.decodeall(body), bprefix=True, indent=2
4285 cborutil.decodeall(body), bprefix=True, indent=2
4323 )
4286 )
4324 )
4287 )
4325
4288
4326 elif action == b'close':
4289 elif action == b'close':
4327 assert peer is not None
4290 assert peer is not None
4328 peer.close()
4291 peer.close()
4329 elif action == b'readavailable':
4292 elif action == b'readavailable':
4330 if not stdout or not stderr:
4293 if not stdout or not stderr:
4331 raise error.Abort(
4294 raise error.Abort(
4332 _(b'readavailable not available on this peer')
4295 _(b'readavailable not available on this peer')
4333 )
4296 )
4334
4297
4335 stdin.close()
4298 stdin.close()
4336 stdout.read()
4299 stdout.read()
4337 stderr.read()
4300 stderr.read()
4338
4301
4339 elif action == b'readline':
4302 elif action == b'readline':
4340 if not stdout:
4303 if not stdout:
4341 raise error.Abort(_(b'readline not available on this peer'))
4304 raise error.Abort(_(b'readline not available on this peer'))
4342 stdout.readline()
4305 stdout.readline()
4343 elif action == b'ereadline':
4306 elif action == b'ereadline':
4344 if not stderr:
4307 if not stderr:
4345 raise error.Abort(_(b'ereadline not available on this peer'))
4308 raise error.Abort(_(b'ereadline not available on this peer'))
4346 stderr.readline()
4309 stderr.readline()
4347 elif action.startswith(b'read '):
4310 elif action.startswith(b'read '):
4348 count = int(action.split(b' ', 1)[1])
4311 count = int(action.split(b' ', 1)[1])
4349 if not stdout:
4312 if not stdout:
4350 raise error.Abort(_(b'read not available on this peer'))
4313 raise error.Abort(_(b'read not available on this peer'))
4351 stdout.read(count)
4314 stdout.read(count)
4352 elif action.startswith(b'eread '):
4315 elif action.startswith(b'eread '):
4353 count = int(action.split(b' ', 1)[1])
4316 count = int(action.split(b' ', 1)[1])
4354 if not stderr:
4317 if not stderr:
4355 raise error.Abort(_(b'eread not available on this peer'))
4318 raise error.Abort(_(b'eread not available on this peer'))
4356 stderr.read(count)
4319 stderr.read(count)
4357 else:
4320 else:
4358 raise error.Abort(_(b'unknown action: %s') % action)
4321 raise error.Abort(_(b'unknown action: %s') % action)
4359
4322
4360 if batchedcommands is not None:
4323 if batchedcommands is not None:
4361 raise error.Abort(_(b'unclosed "batchbegin" request'))
4324 raise error.Abort(_(b'unclosed "batchbegin" request'))
4362
4325
4363 if peer:
4326 if peer:
4364 peer.close()
4327 peer.close()
4365
4328
4366 if proc:
4329 if proc:
4367 proc.kill()
4330 proc.kill()
@@ -1,39 +1,45 b''
1 == New Features ==
1 == New Features ==
2
2
3 * `hg purge`/`hg clean` can now delete ignored files instead of
3 * `hg purge`/`hg clean` can now delete ignored files instead of
4 untracked files, with the new -i flag.
4 untracked files, with the new -i flag.
5
5
6 * `hg log` now defaults to using an '%' symbol for commits involved
6 * `hg log` now defaults to using an '%' symbol for commits involved
7 in unresolved merge conflicts. That includes unresolved conflicts
7 in unresolved merge conflicts. That includes unresolved conflicts
8 caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
8 caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
9 precedence, so what used to be marked '@' still is.
9 precedence, so what used to be marked '@' still is.
10
10
11 * New `conflictlocal()` and `conflictother()` revsets return the
11 * New `conflictlocal()` and `conflictother()` revsets return the
12 commits that are being merged, when there are conflicts. Also works
12 commits that are being merged, when there are conflicts. Also works
13 for conflicts caused by e.g. `hg graft`.
13 for conflicts caused by e.g. `hg graft`.
14
14
15 * `hg debugmergestate` output is now templated, which may be useful
16 e.g. for IDEs that want to help the user resolve merge conflicts.
17
15
18
16 == New Experimental Features ==
19 == New Experimental Features ==
17
20
18
21
19 == Bug Fixes ==
22 == Bug Fixes ==
20
23
21
24
22 == Backwards Compatibility Changes ==
25 == Backwards Compatibility Changes ==
23
26
24 * When `hg rebase` pauses for merge conflict resolution, the working
27 * When `hg rebase` pauses for merge conflict resolution, the working
25 copy will no longer have the rebased node as a second parent. You
28 copy will no longer have the rebased node as a second parent. You
26 can use the new `conflictparents()` revset for finding the other
29 can use the new `conflictparents()` revset for finding the other
27 parent during a conflict.
30 parent during a conflict.
28
31
32 * `hg debugmergestate` output format changed. Let us know if that is
33 causing you problems and we'll roll it back.
34
29
35
30 == Internal API Changes ==
36 == Internal API Changes ==
31
37
32 * The deprecated `ui.progress()` has now been deleted. Please use
38 * The deprecated `ui.progress()` has now been deleted. Please use
33 `ui.makeprogress()` instead.
39 `ui.makeprogress()` instead.
34
40
35 * `hg.merge()` has lost its `abort` argument. Please call
41 * `hg.merge()` has lost its `abort` argument. Please call
36 `hg.abortmerge()` directly instead.
42 `hg.abortmerge()` directly instead.
37
43
38 * The `*others` argument of `cmdutil.check_incompatible_arguments()`
44 * The `*others` argument of `cmdutil.check_incompatible_arguments()`
39 changed from being varargs argument to being a single collection.
45 changed from being varargs argument to being a single collection.
@@ -1,807 +1,806 b''
1 $ hg init basic
1 $ hg init basic
2 $ cd basic
2 $ cd basic
3
3
4 should complain
4 should complain
5
5
6 $ hg backout
6 $ hg backout
7 abort: please specify a revision to backout
7 abort: please specify a revision to backout
8 [255]
8 [255]
9 $ hg backout -r 0 0
9 $ hg backout -r 0 0
10 abort: please specify just one revision
10 abort: please specify just one revision
11 [255]
11 [255]
12
12
13 basic operation
13 basic operation
14 (this also tests that editor is invoked if the commit message is not
14 (this also tests that editor is invoked if the commit message is not
15 specified explicitly)
15 specified explicitly)
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg commit -d '0 0' -A -m a
18 $ hg commit -d '0 0' -A -m a
19 adding a
19 adding a
20 $ echo b >> a
20 $ echo b >> a
21 $ hg commit -d '1 0' -m b
21 $ hg commit -d '1 0' -m b
22
22
23 $ hg status --rev tip --rev "tip^1"
23 $ hg status --rev tip --rev "tip^1"
24 M a
24 M a
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
26 reverting a
26 reverting a
27 Backed out changeset a820f4f40a57
27 Backed out changeset a820f4f40a57
28
28
29
29
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
31 HG: Leave message empty to abort commit.
31 HG: Leave message empty to abort commit.
32 HG: --
32 HG: --
33 HG: user: test
33 HG: user: test
34 HG: branch 'default'
34 HG: branch 'default'
35 HG: changed a
35 HG: changed a
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
37 $ cat a
37 $ cat a
38 a
38 a
39 $ hg summary
39 $ hg summary
40 parent: 2:2929462c3dff tip
40 parent: 2:2929462c3dff tip
41 Backed out changeset a820f4f40a57
41 Backed out changeset a820f4f40a57
42 branch: default
42 branch: default
43 commit: (clean)
43 commit: (clean)
44 update: (current)
44 update: (current)
45 phases: 3 draft
45 phases: 3 draft
46
46
47 commit option
47 commit option
48
48
49 $ cd ..
49 $ cd ..
50 $ hg init commit
50 $ hg init commit
51 $ cd commit
51 $ cd commit
52
52
53 $ echo tomatoes > a
53 $ echo tomatoes > a
54 $ hg add a
54 $ hg add a
55 $ hg commit -d '0 0' -m tomatoes
55 $ hg commit -d '0 0' -m tomatoes
56
56
57 $ echo chair > b
57 $ echo chair > b
58 $ hg add b
58 $ hg add b
59 $ hg commit -d '1 0' -m chair
59 $ hg commit -d '1 0' -m chair
60
60
61 $ echo grapes >> a
61 $ echo grapes >> a
62 $ hg commit -d '2 0' -m grapes
62 $ hg commit -d '2 0' -m grapes
63
63
64 $ hg backout -d '4 0' 1 --tool=:fail
64 $ hg backout -d '4 0' 1 --tool=:fail
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
67 $ hg summary
67 $ hg summary
68 parent: 3:1c2161e97c0a tip
68 parent: 3:1c2161e97c0a tip
69 Backed out changeset 22cb4f70d813
69 Backed out changeset 22cb4f70d813
70 branch: default
70 branch: default
71 commit: (clean)
71 commit: (clean)
72 update: (current)
72 update: (current)
73 phases: 4 draft
73 phases: 4 draft
74
74
75 $ echo ypples > a
75 $ echo ypples > a
76 $ hg commit -d '5 0' -m ypples
76 $ hg commit -d '5 0' -m ypples
77
77
78 $ hg backout -d '6 0' 2 --tool=:fail
78 $ hg backout -d '6 0' 2 --tool=:fail
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
80 use 'hg resolve' to retry unresolved file merges
80 use 'hg resolve' to retry unresolved file merges
81 [1]
81 [1]
82 $ hg summary
82 $ hg summary
83 parent: 4:ed99997b793d tip
83 parent: 4:ed99997b793d tip
84 ypples
84 ypples
85 branch: default
85 branch: default
86 commit: 1 unresolved (clean)
86 commit: 1 unresolved (clean)
87 update: (current)
87 update: (current)
88 phases: 5 draft
88 phases: 5 draft
89 $ hg log -G
89 $ hg log -G
90 @ changeset: 4:ed99997b793d
90 @ changeset: 4:ed99997b793d
91 | tag: tip
91 | tag: tip
92 | user: test
92 | user: test
93 | date: Thu Jan 01 00:00:05 1970 +0000
93 | date: Thu Jan 01 00:00:05 1970 +0000
94 | summary: ypples
94 | summary: ypples
95 |
95 |
96 o changeset: 3:1c2161e97c0a
96 o changeset: 3:1c2161e97c0a
97 | user: test
97 | user: test
98 | date: Thu Jan 01 00:00:04 1970 +0000
98 | date: Thu Jan 01 00:00:04 1970 +0000
99 | summary: Backed out changeset 22cb4f70d813
99 | summary: Backed out changeset 22cb4f70d813
100 |
100 |
101 o changeset: 2:a8c6e511cfee
101 o changeset: 2:a8c6e511cfee
102 | user: test
102 | user: test
103 | date: Thu Jan 01 00:00:02 1970 +0000
103 | date: Thu Jan 01 00:00:02 1970 +0000
104 | summary: grapes
104 | summary: grapes
105 |
105 |
106 % changeset: 1:22cb4f70d813
106 % changeset: 1:22cb4f70d813
107 | user: test
107 | user: test
108 | date: Thu Jan 01 00:00:01 1970 +0000
108 | date: Thu Jan 01 00:00:01 1970 +0000
109 | summary: chair
109 | summary: chair
110 |
110 |
111 o changeset: 0:a5cb2dde5805
111 o changeset: 0:a5cb2dde5805
112 user: test
112 user: test
113 date: Thu Jan 01 00:00:00 1970 +0000
113 date: Thu Jan 01 00:00:00 1970 +0000
114 summary: tomatoes
114 summary: tomatoes
115
115
116
116
117 file that was removed is recreated
117 file that was removed is recreated
118 (this also tests that editor is not invoked if the commit message is
118 (this also tests that editor is not invoked if the commit message is
119 specified explicitly)
119 specified explicitly)
120
120
121 $ cd ..
121 $ cd ..
122 $ hg init remove
122 $ hg init remove
123 $ cd remove
123 $ cd remove
124
124
125 $ echo content > a
125 $ echo content > a
126 $ hg commit -d '0 0' -A -m a
126 $ hg commit -d '0 0' -A -m a
127 adding a
127 adding a
128
128
129 $ hg rm a
129 $ hg rm a
130 $ hg commit -d '1 0' -m b
130 $ hg commit -d '1 0' -m b
131
131
132 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
132 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
133 adding a
133 adding a
134 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
134 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
135 $ cat a
135 $ cat a
136 content
136 content
137 $ hg summary
137 $ hg summary
138 parent: 2:de31bdc76c0d tip
138 parent: 2:de31bdc76c0d tip
139 Backed out changeset 76862dcce372
139 Backed out changeset 76862dcce372
140 branch: default
140 branch: default
141 commit: (clean)
141 commit: (clean)
142 update: (current)
142 update: (current)
143 phases: 3 draft
143 phases: 3 draft
144
144
145 backout of backout is as if nothing happened
145 backout of backout is as if nothing happened
146
146
147 $ hg backout -d '3 0' --merge tip --tool=true
147 $ hg backout -d '3 0' --merge tip --tool=true
148 removing a
148 removing a
149 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
149 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
150 $ test -f a
150 $ test -f a
151 [1]
151 [1]
152 $ hg summary
152 $ hg summary
153 parent: 3:7f6d0f120113 tip
153 parent: 3:7f6d0f120113 tip
154 Backed out changeset de31bdc76c0d
154 Backed out changeset de31bdc76c0d
155 branch: default
155 branch: default
156 commit: (clean)
156 commit: (clean)
157 update: (current)
157 update: (current)
158 phases: 4 draft
158 phases: 4 draft
159
159
160 Test that 'hg rollback' restores dirstate just before opening
160 Test that 'hg rollback' restores dirstate just before opening
161 transaction: in-memory dirstate changes should be written into
161 transaction: in-memory dirstate changes should be written into
162 '.hg/journal.dirstate' as expected.
162 '.hg/journal.dirstate' as expected.
163
163
164 $ echo 'removed soon' > b
164 $ echo 'removed soon' > b
165 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
165 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
166 adding b
166 adding b
167 $ echo 'newly added' > c
167 $ echo 'newly added' > c
168 $ hg add c
168 $ hg add c
169 $ hg remove b
169 $ hg remove b
170 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
170 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
171 $ touch -t 200001010000 c
171 $ touch -t 200001010000 c
172 $ hg status -A
172 $ hg status -A
173 C c
173 C c
174 $ hg debugstate --no-dates
174 $ hg debugstate --no-dates
175 n 644 12 set c
175 n 644 12 set c
176 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
176 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
177 removing c
177 removing c
178 adding b
178 adding b
179 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
179 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
180 $ hg rollback -q
180 $ hg rollback -q
181 $ hg status -A
181 $ hg status -A
182 A b
182 A b
183 R c
183 R c
184 $ hg debugstate --no-dates
184 $ hg debugstate --no-dates
185 a 0 -1 unset b
185 a 0 -1 unset b
186 r 0 0 set c
186 r 0 0 set c
187
187
188 across branch
188 across branch
189
189
190 $ cd ..
190 $ cd ..
191 $ hg init branch
191 $ hg init branch
192 $ cd branch
192 $ cd branch
193 $ echo a > a
193 $ echo a > a
194 $ hg ci -Am0
194 $ hg ci -Am0
195 adding a
195 adding a
196 $ echo b > b
196 $ echo b > b
197 $ hg ci -Am1
197 $ hg ci -Am1
198 adding b
198 adding b
199 $ hg co -C 0
199 $ hg co -C 0
200 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
200 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
201 $ hg summary
201 $ hg summary
202 parent: 0:f7b1eb17ad24
202 parent: 0:f7b1eb17ad24
203 0
203 0
204 branch: default
204 branch: default
205 commit: (clean)
205 commit: (clean)
206 update: 1 new changesets (update)
206 update: 1 new changesets (update)
207 phases: 2 draft
207 phases: 2 draft
208
208
209 should fail
209 should fail
210
210
211 $ hg backout 1
211 $ hg backout 1
212 abort: cannot backout change that is not an ancestor
212 abort: cannot backout change that is not an ancestor
213 [255]
213 [255]
214 $ echo c > c
214 $ echo c > c
215 $ hg ci -Am2
215 $ hg ci -Am2
216 adding c
216 adding c
217 created new head
217 created new head
218 $ hg summary
218 $ hg summary
219 parent: 2:db815d6d32e6 tip
219 parent: 2:db815d6d32e6 tip
220 2
220 2
221 branch: default
221 branch: default
222 commit: (clean)
222 commit: (clean)
223 update: 1 new changesets, 2 branch heads (merge)
223 update: 1 new changesets, 2 branch heads (merge)
224 phases: 3 draft
224 phases: 3 draft
225
225
226 should fail
226 should fail
227
227
228 $ hg backout 1
228 $ hg backout 1
229 abort: cannot backout change that is not an ancestor
229 abort: cannot backout change that is not an ancestor
230 [255]
230 [255]
231 $ hg summary
231 $ hg summary
232 parent: 2:db815d6d32e6 tip
232 parent: 2:db815d6d32e6 tip
233 2
233 2
234 branch: default
234 branch: default
235 commit: (clean)
235 commit: (clean)
236 update: 1 new changesets, 2 branch heads (merge)
236 update: 1 new changesets, 2 branch heads (merge)
237 phases: 3 draft
237 phases: 3 draft
238
238
239 backout with merge
239 backout with merge
240
240
241 $ cd ..
241 $ cd ..
242 $ hg init merge
242 $ hg init merge
243 $ cd merge
243 $ cd merge
244
244
245 $ echo line 1 > a
245 $ echo line 1 > a
246 $ echo line 2 >> a
246 $ echo line 2 >> a
247 $ hg commit -d '0 0' -A -m a
247 $ hg commit -d '0 0' -A -m a
248 adding a
248 adding a
249 $ hg summary
249 $ hg summary
250 parent: 0:59395513a13a tip
250 parent: 0:59395513a13a tip
251 a
251 a
252 branch: default
252 branch: default
253 commit: (clean)
253 commit: (clean)
254 update: (current)
254 update: (current)
255 phases: 1 draft
255 phases: 1 draft
256
256
257 remove line 1
257 remove line 1
258
258
259 $ echo line 2 > a
259 $ echo line 2 > a
260 $ hg commit -d '1 0' -m b
260 $ hg commit -d '1 0' -m b
261
261
262 $ echo line 3 >> a
262 $ echo line 3 >> a
263 $ hg commit -d '2 0' -m c
263 $ hg commit -d '2 0' -m c
264
264
265 $ hg backout --merge -d '3 0' 1 --tool=true
265 $ hg backout --merge -d '3 0' 1 --tool=true
266 reverting a
266 reverting a
267 created new head
267 created new head
268 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
268 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
269 merging with changeset 3:26b8ccb9ad91
269 merging with changeset 3:26b8ccb9ad91
270 merging a
270 merging a
271 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
271 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
272 (branch merge, don't forget to commit)
272 (branch merge, don't forget to commit)
273 $ hg commit -d '4 0' -m d
273 $ hg commit -d '4 0' -m d
274 $ hg summary
274 $ hg summary
275 parent: 4:c7df5e0b9c09 tip
275 parent: 4:c7df5e0b9c09 tip
276 d
276 d
277 branch: default
277 branch: default
278 commit: (clean)
278 commit: (clean)
279 update: (current)
279 update: (current)
280 phases: 5 draft
280 phases: 5 draft
281
281
282 check line 1 is back
282 check line 1 is back
283
283
284 $ cat a
284 $ cat a
285 line 1
285 line 1
286 line 2
286 line 2
287 line 3
287 line 3
288
288
289 Test visibility of in-memory dirstate changes outside transaction to
289 Test visibility of in-memory dirstate changes outside transaction to
290 external hook process
290 external hook process
291
291
292 $ cat > $TESTTMP/checkvisibility.sh <<EOF
292 $ cat > $TESTTMP/checkvisibility.sh <<EOF
293 > echo "==== \$1:"
293 > echo "==== \$1:"
294 > hg parents --template "{rev}:{node|short}\n"
294 > hg parents --template "{rev}:{node|short}\n"
295 > echo "===="
295 > echo "===="
296 > EOF
296 > EOF
297
297
298 "hg backout --merge REV1" at REV2 below implies steps below:
298 "hg backout --merge REV1" at REV2 below implies steps below:
299
299
300 (1) update to REV1 (REV2 => REV1)
300 (1) update to REV1 (REV2 => REV1)
301 (2) revert by REV1^1
301 (2) revert by REV1^1
302 (3) commit backing out revision (REV3)
302 (3) commit backing out revision (REV3)
303 (4) update to REV2 (REV3 => REV2)
303 (4) update to REV2 (REV3 => REV2)
304 (5) merge with REV3 (REV2 => REV2, REV3)
304 (5) merge with REV3 (REV2 => REV2, REV3)
305
305
306 == test visibility to external preupdate hook
306 == test visibility to external preupdate hook
307
307
308 $ hg update -q -C 2
308 $ hg update -q -C 2
309 $ hg --config extensions.strip= strip 3
309 $ hg --config extensions.strip= strip 3
310 saved backup bundle to * (glob)
310 saved backup bundle to * (glob)
311
311
312 $ cat >> .hg/hgrc <<EOF
312 $ cat >> .hg/hgrc <<EOF
313 > [hooks]
313 > [hooks]
314 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
314 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
315 > EOF
315 > EOF
316
316
317 ("-m" is needed to avoid writing dirstate changes out at other than
317 ("-m" is needed to avoid writing dirstate changes out at other than
318 invocation of the hook to be examined)
318 invocation of the hook to be examined)
319
319
320 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
320 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
321 ==== preupdate:
321 ==== preupdate:
322 2:6ea3f2a197a2
322 2:6ea3f2a197a2
323 ====
323 ====
324 reverting a
324 reverting a
325 created new head
325 created new head
326 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
326 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
327 ==== preupdate:
327 ==== preupdate:
328 3:d92a3f57f067
328 3:d92a3f57f067
329 ====
329 ====
330 merging with changeset 3:d92a3f57f067
330 merging with changeset 3:d92a3f57f067
331 ==== preupdate:
331 ==== preupdate:
332 2:6ea3f2a197a2
332 2:6ea3f2a197a2
333 ====
333 ====
334 merging a
334 merging a
335 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
335 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
336 (branch merge, don't forget to commit)
336 (branch merge, don't forget to commit)
337
337
338 $ cat >> .hg/hgrc <<EOF
338 $ cat >> .hg/hgrc <<EOF
339 > [hooks]
339 > [hooks]
340 > preupdate.visibility =
340 > preupdate.visibility =
341 > EOF
341 > EOF
342
342
343 == test visibility to external update hook
343 == test visibility to external update hook
344
344
345 $ hg update -q -C 2
345 $ hg update -q -C 2
346 $ hg --config extensions.strip= strip 3
346 $ hg --config extensions.strip= strip 3
347 saved backup bundle to * (glob)
347 saved backup bundle to * (glob)
348
348
349 $ cat >> .hg/hgrc <<EOF
349 $ cat >> .hg/hgrc <<EOF
350 > [hooks]
350 > [hooks]
351 > update.visibility = sh $TESTTMP/checkvisibility.sh update
351 > update.visibility = sh $TESTTMP/checkvisibility.sh update
352 > EOF
352 > EOF
353
353
354 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
354 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
355 ==== update:
355 ==== update:
356 1:5a50a024c182
356 1:5a50a024c182
357 ====
357 ====
358 reverting a
358 reverting a
359 created new head
359 created new head
360 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
360 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
361 ==== update:
361 ==== update:
362 2:6ea3f2a197a2
362 2:6ea3f2a197a2
363 ====
363 ====
364 merging with changeset 3:d92a3f57f067
364 merging with changeset 3:d92a3f57f067
365 merging a
365 merging a
366 ==== update:
366 ==== update:
367 2:6ea3f2a197a2
367 2:6ea3f2a197a2
368 3:d92a3f57f067
368 3:d92a3f57f067
369 ====
369 ====
370 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
370 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
371 (branch merge, don't forget to commit)
371 (branch merge, don't forget to commit)
372
372
373 $ cat >> .hg/hgrc <<EOF
373 $ cat >> .hg/hgrc <<EOF
374 > [hooks]
374 > [hooks]
375 > update.visibility =
375 > update.visibility =
376 > EOF
376 > EOF
377
377
378 $ cd ..
378 $ cd ..
379
379
380 backout should not back out subsequent changesets
380 backout should not back out subsequent changesets
381
381
382 $ hg init onecs
382 $ hg init onecs
383 $ cd onecs
383 $ cd onecs
384 $ echo 1 > a
384 $ echo 1 > a
385 $ hg commit -d '0 0' -A -m a
385 $ hg commit -d '0 0' -A -m a
386 adding a
386 adding a
387 $ echo 2 >> a
387 $ echo 2 >> a
388 $ hg commit -d '1 0' -m b
388 $ hg commit -d '1 0' -m b
389 $ echo 1 > b
389 $ echo 1 > b
390 $ hg commit -d '2 0' -A -m c
390 $ hg commit -d '2 0' -A -m c
391 adding b
391 adding b
392 $ hg summary
392 $ hg summary
393 parent: 2:882396649954 tip
393 parent: 2:882396649954 tip
394 c
394 c
395 branch: default
395 branch: default
396 commit: (clean)
396 commit: (clean)
397 update: (current)
397 update: (current)
398 phases: 3 draft
398 phases: 3 draft
399
399
400 without --merge
400 without --merge
401 $ hg backout --no-commit -d '3 0' 1 --tool=true
401 $ hg backout --no-commit -d '3 0' 1 --tool=true
402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
403 changeset 22bca4c721e5 backed out, don't forget to commit.
403 changeset 22bca4c721e5 backed out, don't forget to commit.
404 $ hg locate b
404 $ hg locate b
405 b
405 b
406 $ hg update -C tip
406 $ hg update -C tip
407 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 $ hg locate b
408 $ hg locate b
409 b
409 b
410 $ hg summary
410 $ hg summary
411 parent: 2:882396649954 tip
411 parent: 2:882396649954 tip
412 c
412 c
413 branch: default
413 branch: default
414 commit: (clean)
414 commit: (clean)
415 update: (current)
415 update: (current)
416 phases: 3 draft
416 phases: 3 draft
417
417
418 with --merge
418 with --merge
419 $ hg backout --merge -d '3 0' 1 --tool=true
419 $ hg backout --merge -d '3 0' 1 --tool=true
420 reverting a
420 reverting a
421 created new head
421 created new head
422 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
422 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
423 merging with changeset 3:3202beb76721
423 merging with changeset 3:3202beb76721
424 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
424 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 (branch merge, don't forget to commit)
425 (branch merge, don't forget to commit)
426 $ hg locate b
426 $ hg locate b
427 b
427 b
428 $ hg update -C tip
428 $ hg update -C tip
429 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
429 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
430 $ hg locate b
430 $ hg locate b
431 [1]
431 [1]
432
432
433 $ cd ..
433 $ cd ..
434 $ hg init m
434 $ hg init m
435 $ cd m
435 $ cd m
436 $ echo a > a
436 $ echo a > a
437 $ hg commit -d '0 0' -A -m a
437 $ hg commit -d '0 0' -A -m a
438 adding a
438 adding a
439 $ echo b > b
439 $ echo b > b
440 $ hg commit -d '1 0' -A -m b
440 $ hg commit -d '1 0' -A -m b
441 adding b
441 adding b
442 $ echo c > c
442 $ echo c > c
443 $ hg commit -d '2 0' -A -m b
443 $ hg commit -d '2 0' -A -m b
444 adding c
444 adding c
445 $ hg update 1
445 $ hg update 1
446 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
446 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
447 $ echo d > d
447 $ echo d > d
448 $ hg commit -d '3 0' -A -m c
448 $ hg commit -d '3 0' -A -m c
449 adding d
449 adding d
450 created new head
450 created new head
451 $ hg merge 2
451 $ hg merge 2
452 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
452 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
453 (branch merge, don't forget to commit)
453 (branch merge, don't forget to commit)
454 $ hg commit -d '4 0' -A -m d
454 $ hg commit -d '4 0' -A -m d
455 $ hg summary
455 $ hg summary
456 parent: 4:b2f3bb92043e tip
456 parent: 4:b2f3bb92043e tip
457 d
457 d
458 branch: default
458 branch: default
459 commit: (clean)
459 commit: (clean)
460 update: (current)
460 update: (current)
461 phases: 5 draft
461 phases: 5 draft
462
462
463 backout of merge should fail
463 backout of merge should fail
464
464
465 $ hg backout 4
465 $ hg backout 4
466 abort: cannot backout a merge changeset
466 abort: cannot backout a merge changeset
467 [255]
467 [255]
468
468
469 backout of merge with bad parent should fail
469 backout of merge with bad parent should fail
470
470
471 $ hg backout --parent 0 4
471 $ hg backout --parent 0 4
472 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
472 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
473 [255]
473 [255]
474
474
475 backout of non-merge with parent should fail
475 backout of non-merge with parent should fail
476
476
477 $ hg backout --parent 0 3
477 $ hg backout --parent 0 3
478 abort: cannot use --parent on non-merge changeset
478 abort: cannot use --parent on non-merge changeset
479 [255]
479 [255]
480
480
481 backout with valid parent should be ok
481 backout with valid parent should be ok
482
482
483 $ hg backout -d '5 0' --parent 2 4 --tool=true
483 $ hg backout -d '5 0' --parent 2 4 --tool=true
484 removing d
484 removing d
485 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
485 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
486 $ hg summary
486 $ hg summary
487 parent: 5:10e5328c8435 tip
487 parent: 5:10e5328c8435 tip
488 Backed out changeset b2f3bb92043e
488 Backed out changeset b2f3bb92043e
489 branch: default
489 branch: default
490 commit: (clean)
490 commit: (clean)
491 update: (current)
491 update: (current)
492 phases: 6 draft
492 phases: 6 draft
493
493
494 $ hg rollback
494 $ hg rollback
495 repository tip rolled back to revision 4 (undo commit)
495 repository tip rolled back to revision 4 (undo commit)
496 working directory now based on revision 4
496 working directory now based on revision 4
497 $ hg update -C
497 $ hg update -C
498 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 $ hg summary
499 $ hg summary
500 parent: 4:b2f3bb92043e tip
500 parent: 4:b2f3bb92043e tip
501 d
501 d
502 branch: default
502 branch: default
503 commit: (clean)
503 commit: (clean)
504 update: (current)
504 update: (current)
505 phases: 5 draft
505 phases: 5 draft
506
506
507 $ hg backout -d '6 0' --parent 3 4 --tool=true
507 $ hg backout -d '6 0' --parent 3 4 --tool=true
508 removing c
508 removing c
509 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
509 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
510 $ hg summary
510 $ hg summary
511 parent: 5:033590168430 tip
511 parent: 5:033590168430 tip
512 Backed out changeset b2f3bb92043e
512 Backed out changeset b2f3bb92043e
513 branch: default
513 branch: default
514 commit: (clean)
514 commit: (clean)
515 update: (current)
515 update: (current)
516 phases: 6 draft
516 phases: 6 draft
517
517
518 $ cd ..
518 $ cd ..
519
519
520 named branches
520 named branches
521
521
522 $ hg init named_branches
522 $ hg init named_branches
523 $ cd named_branches
523 $ cd named_branches
524
524
525 $ echo default > default
525 $ echo default > default
526 $ hg ci -d '0 0' -Am default
526 $ hg ci -d '0 0' -Am default
527 adding default
527 adding default
528 $ hg branch branch1
528 $ hg branch branch1
529 marked working directory as branch branch1
529 marked working directory as branch branch1
530 (branches are permanent and global, did you want a bookmark?)
530 (branches are permanent and global, did you want a bookmark?)
531 $ echo branch1 > file1
531 $ echo branch1 > file1
532 $ hg ci -d '1 0' -Am file1
532 $ hg ci -d '1 0' -Am file1
533 adding file1
533 adding file1
534 $ hg branch branch2
534 $ hg branch branch2
535 marked working directory as branch branch2
535 marked working directory as branch branch2
536 $ echo branch2 > file2
536 $ echo branch2 > file2
537 $ hg ci -d '2 0' -Am file2
537 $ hg ci -d '2 0' -Am file2
538 adding file2
538 adding file2
539
539
540 without --merge
540 without --merge
541 $ hg backout --no-commit -r 1 --tool=true
541 $ hg backout --no-commit -r 1 --tool=true
542 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
542 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
543 changeset bf1602f437f3 backed out, don't forget to commit.
543 changeset bf1602f437f3 backed out, don't forget to commit.
544 $ hg branch
544 $ hg branch
545 branch2
545 branch2
546 $ hg status -A
546 $ hg status -A
547 R file1
547 R file1
548 C default
548 C default
549 C file2
549 C file2
550 $ hg summary
550 $ hg summary
551 parent: 2:45bbcd363bf0 tip
551 parent: 2:45bbcd363bf0 tip
552 file2
552 file2
553 branch: branch2
553 branch: branch2
554 commit: 1 removed
554 commit: 1 removed
555 update: (current)
555 update: (current)
556 phases: 3 draft
556 phases: 3 draft
557
557
558 with --merge
558 with --merge
559 (this also tests that editor is invoked if '--edit' is specified
559 (this also tests that editor is invoked if '--edit' is specified
560 explicitly regardless of '--message')
560 explicitly regardless of '--message')
561
561
562 $ hg update -qC
562 $ hg update -qC
563 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
563 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
564 removing file1
564 removing file1
565 backout on branch1
565 backout on branch1
566
566
567
567
568 HG: Enter commit message. Lines beginning with 'HG:' are removed.
568 HG: Enter commit message. Lines beginning with 'HG:' are removed.
569 HG: Leave message empty to abort commit.
569 HG: Leave message empty to abort commit.
570 HG: --
570 HG: --
571 HG: user: test
571 HG: user: test
572 HG: branch 'branch2'
572 HG: branch 'branch2'
573 HG: removed file1
573 HG: removed file1
574 created new head
574 created new head
575 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
575 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
576 merging with changeset 3:d4e8f6db59fb
576 merging with changeset 3:d4e8f6db59fb
577 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
577 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
578 (branch merge, don't forget to commit)
578 (branch merge, don't forget to commit)
579 $ hg summary
579 $ hg summary
580 parent: 2:45bbcd363bf0
580 parent: 2:45bbcd363bf0
581 file2
581 file2
582 parent: 3:d4e8f6db59fb tip
582 parent: 3:d4e8f6db59fb tip
583 backout on branch1
583 backout on branch1
584 branch: branch2
584 branch: branch2
585 commit: 1 removed (merge)
585 commit: 1 removed (merge)
586 update: (current)
586 update: (current)
587 phases: 4 draft
587 phases: 4 draft
588 $ hg update -q -C 2
588 $ hg update -q -C 2
589
589
590 on branch2 with branch1 not merged, so file1 should still exist:
590 on branch2 with branch1 not merged, so file1 should still exist:
591
591
592 $ hg id
592 $ hg id
593 45bbcd363bf0 (branch2)
593 45bbcd363bf0 (branch2)
594 $ hg st -A
594 $ hg st -A
595 C default
595 C default
596 C file1
596 C file1
597 C file2
597 C file2
598 $ hg summary
598 $ hg summary
599 parent: 2:45bbcd363bf0
599 parent: 2:45bbcd363bf0
600 file2
600 file2
601 branch: branch2
601 branch: branch2
602 commit: (clean)
602 commit: (clean)
603 update: 1 new changesets, 2 branch heads (merge)
603 update: 1 new changesets, 2 branch heads (merge)
604 phases: 4 draft
604 phases: 4 draft
605
605
606 on branch2 with branch1 merged, so file1 should be gone:
606 on branch2 with branch1 merged, so file1 should be gone:
607
607
608 $ hg merge
608 $ hg merge
609 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
609 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
610 (branch merge, don't forget to commit)
610 (branch merge, don't forget to commit)
611 $ hg ci -d '4 0' -m 'merge backout of branch1'
611 $ hg ci -d '4 0' -m 'merge backout of branch1'
612 $ hg id
612 $ hg id
613 d97a8500a969 (branch2) tip
613 d97a8500a969 (branch2) tip
614 $ hg st -A
614 $ hg st -A
615 C default
615 C default
616 C file2
616 C file2
617 $ hg summary
617 $ hg summary
618 parent: 4:d97a8500a969 tip
618 parent: 4:d97a8500a969 tip
619 merge backout of branch1
619 merge backout of branch1
620 branch: branch2
620 branch: branch2
621 commit: (clean)
621 commit: (clean)
622 update: (current)
622 update: (current)
623 phases: 5 draft
623 phases: 5 draft
624
624
625 on branch1, so no file1 and file2:
625 on branch1, so no file1 and file2:
626
626
627 $ hg co -C branch1
627 $ hg co -C branch1
628 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
628 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
629 $ hg id
629 $ hg id
630 bf1602f437f3 (branch1)
630 bf1602f437f3 (branch1)
631 $ hg st -A
631 $ hg st -A
632 C default
632 C default
633 C file1
633 C file1
634 $ hg summary
634 $ hg summary
635 parent: 1:bf1602f437f3
635 parent: 1:bf1602f437f3
636 file1
636 file1
637 branch: branch1
637 branch: branch1
638 commit: (clean)
638 commit: (clean)
639 update: (current)
639 update: (current)
640 phases: 5 draft
640 phases: 5 draft
641
641
642 $ cd ..
642 $ cd ..
643
643
644 backout of empty changeset (issue4190)
644 backout of empty changeset (issue4190)
645
645
646 $ hg init emptycommit
646 $ hg init emptycommit
647 $ cd emptycommit
647 $ cd emptycommit
648
648
649 $ touch file1
649 $ touch file1
650 $ hg ci -Aqm file1
650 $ hg ci -Aqm file1
651 $ hg branch -q branch1
651 $ hg branch -q branch1
652 $ hg ci -qm branch1
652 $ hg ci -qm branch1
653 $ hg backout -v 1
653 $ hg backout -v 1
654 resolving manifests
654 resolving manifests
655 nothing changed
655 nothing changed
656 [1]
656 [1]
657
657
658 $ cd ..
658 $ cd ..
659
659
660
660
661 Test usage of `hg resolve` in case of conflict
661 Test usage of `hg resolve` in case of conflict
662 (issue4163)
662 (issue4163)
663
663
664 $ hg init issue4163
664 $ hg init issue4163
665 $ cd issue4163
665 $ cd issue4163
666 $ touch foo
666 $ touch foo
667 $ hg add foo
667 $ hg add foo
668 $ cat > foo << EOF
668 $ cat > foo << EOF
669 > one
669 > one
670 > two
670 > two
671 > three
671 > three
672 > four
672 > four
673 > five
673 > five
674 > six
674 > six
675 > seven
675 > seven
676 > height
676 > height
677 > nine
677 > nine
678 > ten
678 > ten
679 > EOF
679 > EOF
680 $ hg ci -m 'initial'
680 $ hg ci -m 'initial'
681 $ cat > foo << EOF
681 $ cat > foo << EOF
682 > one
682 > one
683 > two
683 > two
684 > THREE
684 > THREE
685 > four
685 > four
686 > five
686 > five
687 > six
687 > six
688 > seven
688 > seven
689 > height
689 > height
690 > nine
690 > nine
691 > ten
691 > ten
692 > EOF
692 > EOF
693 $ hg ci -m 'capital three'
693 $ hg ci -m 'capital three'
694 $ cat > foo << EOF
694 $ cat > foo << EOF
695 > one
695 > one
696 > two
696 > two
697 > THREE
697 > THREE
698 > four
698 > four
699 > five
699 > five
700 > six
700 > six
701 > seven
701 > seven
702 > height
702 > height
703 > nine
703 > nine
704 > TEN
704 > TEN
705 > EOF
705 > EOF
706 $ hg ci -m 'capital ten'
706 $ hg ci -m 'capital ten'
707 $ hg backout -r 'desc("capital three")' --tool internal:fail
707 $ hg backout -r 'desc("capital three")' --tool internal:fail
708 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
708 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
709 use 'hg resolve' to retry unresolved file merges
709 use 'hg resolve' to retry unresolved file merges
710 [1]
710 [1]
711 $ hg status
711 $ hg status
712 $ hg debugmergestate
712 $ hg debugmergestate
713 * version 2 records
714 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
713 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
715 other: a30dd8addae3ce71b8667868478542bc417439e6
714 other: a30dd8addae3ce71b8667868478542bc417439e6
716 file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
715 file: foo (state "u")
717 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
718 local path: foo (flags "")
716 local path: foo (flags "")
719 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
717 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
720 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
718 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
719 extra: ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553
721 $ mv .hg/merge/state2 .hg/merge/state2-moved
720 $ mv .hg/merge/state2 .hg/merge/state2-moved
722 $ hg debugmergestate
721 $ hg debugmergestate
723 * version 1 records
724 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
722 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
725 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
723 other: b71750c4b0fdf719734971e3ef90dbeab5919a2d
724 file: foo (state "u")
726 local path: foo (flags "")
725 local path: foo (flags "")
727 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
726 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
728 other path: foo (node not stored in v1 format)
727 other path: (node foo)
729 $ mv .hg/merge/state2-moved .hg/merge/state2
728 $ mv .hg/merge/state2-moved .hg/merge/state2
730 $ hg resolve -l # still unresolved
729 $ hg resolve -l # still unresolved
731 U foo
730 U foo
732 $ hg summary
731 $ hg summary
733 parent: 2:b71750c4b0fd tip
732 parent: 2:b71750c4b0fd tip
734 capital ten
733 capital ten
735 branch: default
734 branch: default
736 commit: 1 unresolved (clean)
735 commit: 1 unresolved (clean)
737 update: (current)
736 update: (current)
738 phases: 3 draft
737 phases: 3 draft
739 $ hg log -G
738 $ hg log -G
740 @ changeset: 2:b71750c4b0fd
739 @ changeset: 2:b71750c4b0fd
741 | tag: tip
740 | tag: tip
742 | user: test
741 | user: test
743 | date: Thu Jan 01 00:00:00 1970 +0000
742 | date: Thu Jan 01 00:00:00 1970 +0000
744 | summary: capital ten
743 | summary: capital ten
745 |
744 |
746 o changeset: 1:913609522437
745 o changeset: 1:913609522437
747 | user: test
746 | user: test
748 | date: Thu Jan 01 00:00:00 1970 +0000
747 | date: Thu Jan 01 00:00:00 1970 +0000
749 | summary: capital three
748 | summary: capital three
750 |
749 |
751 % changeset: 0:a30dd8addae3
750 % changeset: 0:a30dd8addae3
752 user: test
751 user: test
753 date: Thu Jan 01 00:00:00 1970 +0000
752 date: Thu Jan 01 00:00:00 1970 +0000
754 summary: initial
753 summary: initial
755
754
756 $ hg resolve --all --debug
755 $ hg resolve --all --debug
757 picked tool ':merge' for foo (binary False symlink False changedelete False)
756 picked tool ':merge' for foo (binary False symlink False changedelete False)
758 merging foo
757 merging foo
759 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
758 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
760 premerge successful
759 premerge successful
761 (no more unresolved files)
760 (no more unresolved files)
762 continue: hg commit
761 continue: hg commit
763 $ hg status
762 $ hg status
764 M foo
763 M foo
765 ? foo.orig
764 ? foo.orig
766 $ hg resolve -l
765 $ hg resolve -l
767 R foo
766 R foo
768 $ hg summary
767 $ hg summary
769 parent: 2:b71750c4b0fd tip
768 parent: 2:b71750c4b0fd tip
770 capital ten
769 capital ten
771 branch: default
770 branch: default
772 commit: 1 modified, 1 unknown
771 commit: 1 modified, 1 unknown
773 update: (current)
772 update: (current)
774 phases: 3 draft
773 phases: 3 draft
775 $ cat foo
774 $ cat foo
776 one
775 one
777 two
776 two
778 three
777 three
779 four
778 four
780 five
779 five
781 six
780 six
782 seven
781 seven
783 height
782 height
784 nine
783 nine
785 TEN
784 TEN
786
785
787 --no-commit shouldn't commit
786 --no-commit shouldn't commit
788
787
789 $ hg init a
788 $ hg init a
790 $ cd a
789 $ cd a
791 $ for i in 1 2 3; do
790 $ for i in 1 2 3; do
792 > touch $i
791 > touch $i
793 > hg ci -Am $i
792 > hg ci -Am $i
794 > done
793 > done
795 adding 1
794 adding 1
796 adding 2
795 adding 2
797 adding 3
796 adding 3
798 $ hg backout --no-commit .
797 $ hg backout --no-commit .
799 removing 3
798 removing 3
800 changeset cccc23d9d68f backed out, don't forget to commit.
799 changeset cccc23d9d68f backed out, don't forget to commit.
801 $ hg revert -aq
800 $ hg revert -aq
802
801
803 --no-commit can't be used with --merge
802 --no-commit can't be used with --merge
804
803
805 $ hg backout --merge --no-commit 2
804 $ hg backout --merge --no-commit 2
806 abort: cannot use --merge with --no-commit
805 abort: cannot use --merge with --no-commit
807 [255]
806 [255]
@@ -1,429 +1,429 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 abort
4 add
4 add
5 addremove
5 addremove
6 annotate
6 annotate
7 archive
7 archive
8 backout
8 backout
9 bisect
9 bisect
10 bookmarks
10 bookmarks
11 branch
11 branch
12 branches
12 branches
13 bundle
13 bundle
14 cat
14 cat
15 clone
15 clone
16 commit
16 commit
17 config
17 config
18 continue
18 continue
19 copy
19 copy
20 diff
20 diff
21 export
21 export
22 files
22 files
23 forget
23 forget
24 graft
24 graft
25 grep
25 grep
26 heads
26 heads
27 help
27 help
28 identify
28 identify
29 import
29 import
30 incoming
30 incoming
31 init
31 init
32 locate
32 locate
33 log
33 log
34 manifest
34 manifest
35 merge
35 merge
36 outgoing
36 outgoing
37 parents
37 parents
38 paths
38 paths
39 phase
39 phase
40 pull
40 pull
41 push
41 push
42 recover
42 recover
43 remove
43 remove
44 rename
44 rename
45 resolve
45 resolve
46 revert
46 revert
47 rollback
47 rollback
48 root
48 root
49 serve
49 serve
50 shelve
50 shelve
51 status
51 status
52 summary
52 summary
53 tag
53 tag
54 tags
54 tags
55 tip
55 tip
56 unbundle
56 unbundle
57 unshelve
57 unshelve
58 update
58 update
59 verify
59 verify
60 version
60 version
61
61
62 Show all commands that start with "a"
62 Show all commands that start with "a"
63 $ hg debugcomplete a
63 $ hg debugcomplete a
64 abort
64 abort
65 add
65 add
66 addremove
66 addremove
67 annotate
67 annotate
68 archive
68 archive
69
69
70 Do not show debug commands if there are other candidates
70 Do not show debug commands if there are other candidates
71 $ hg debugcomplete d
71 $ hg debugcomplete d
72 diff
72 diff
73
73
74 Show debug commands if there are no other candidates
74 Show debug commands if there are no other candidates
75 $ hg debugcomplete debug
75 $ hg debugcomplete debug
76 debugancestor
76 debugancestor
77 debugapplystreamclonebundle
77 debugapplystreamclonebundle
78 debugbuilddag
78 debugbuilddag
79 debugbundle
79 debugbundle
80 debugcapabilities
80 debugcapabilities
81 debugcheckstate
81 debugcheckstate
82 debugcolor
82 debugcolor
83 debugcommands
83 debugcommands
84 debugcomplete
84 debugcomplete
85 debugconfig
85 debugconfig
86 debugcreatestreamclonebundle
86 debugcreatestreamclonebundle
87 debugdag
87 debugdag
88 debugdata
88 debugdata
89 debugdate
89 debugdate
90 debugdeltachain
90 debugdeltachain
91 debugdirstate
91 debugdirstate
92 debugdiscovery
92 debugdiscovery
93 debugdownload
93 debugdownload
94 debugextensions
94 debugextensions
95 debugfileset
95 debugfileset
96 debugformat
96 debugformat
97 debugfsinfo
97 debugfsinfo
98 debuggetbundle
98 debuggetbundle
99 debugignore
99 debugignore
100 debugindex
100 debugindex
101 debugindexdot
101 debugindexdot
102 debugindexstats
102 debugindexstats
103 debuginstall
103 debuginstall
104 debugknown
104 debugknown
105 debuglabelcomplete
105 debuglabelcomplete
106 debuglocks
106 debuglocks
107 debugmanifestfulltextcache
107 debugmanifestfulltextcache
108 debugmergestate
108 debugmergestate
109 debugnamecomplete
109 debugnamecomplete
110 debugnodemap
110 debugnodemap
111 debugobsolete
111 debugobsolete
112 debugp1copies
112 debugp1copies
113 debugp2copies
113 debugp2copies
114 debugpathcomplete
114 debugpathcomplete
115 debugpathcopies
115 debugpathcopies
116 debugpeer
116 debugpeer
117 debugpickmergetool
117 debugpickmergetool
118 debugpushkey
118 debugpushkey
119 debugpvec
119 debugpvec
120 debugrebuilddirstate
120 debugrebuilddirstate
121 debugrebuildfncache
121 debugrebuildfncache
122 debugrename
122 debugrename
123 debugrevlog
123 debugrevlog
124 debugrevlogindex
124 debugrevlogindex
125 debugrevspec
125 debugrevspec
126 debugserve
126 debugserve
127 debugsetparents
127 debugsetparents
128 debugsidedata
128 debugsidedata
129 debugssl
129 debugssl
130 debugsub
130 debugsub
131 debugsuccessorssets
131 debugsuccessorssets
132 debugtagscache
132 debugtagscache
133 debugtemplate
133 debugtemplate
134 debuguigetpass
134 debuguigetpass
135 debuguiprompt
135 debuguiprompt
136 debugupdatecaches
136 debugupdatecaches
137 debugupgraderepo
137 debugupgraderepo
138 debugwalk
138 debugwalk
139 debugwhyunstable
139 debugwhyunstable
140 debugwireargs
140 debugwireargs
141 debugwireproto
141 debugwireproto
142
142
143 Do not show the alias of a debug command if there are other candidates
143 Do not show the alias of a debug command if there are other candidates
144 (this should hide rawcommit)
144 (this should hide rawcommit)
145 $ hg debugcomplete r
145 $ hg debugcomplete r
146 recover
146 recover
147 remove
147 remove
148 rename
148 rename
149 resolve
149 resolve
150 revert
150 revert
151 rollback
151 rollback
152 root
152 root
153 Show the alias of a debug command if there are no other candidates
153 Show the alias of a debug command if there are no other candidates
154 $ hg debugcomplete rawc
154 $ hg debugcomplete rawc
155
155
156
156
157 Show the global options
157 Show the global options
158 $ hg debugcomplete --options | sort
158 $ hg debugcomplete --options | sort
159 --color
159 --color
160 --config
160 --config
161 --cwd
161 --cwd
162 --debug
162 --debug
163 --debugger
163 --debugger
164 --encoding
164 --encoding
165 --encodingmode
165 --encodingmode
166 --help
166 --help
167 --hidden
167 --hidden
168 --noninteractive
168 --noninteractive
169 --pager
169 --pager
170 --profile
170 --profile
171 --quiet
171 --quiet
172 --repository
172 --repository
173 --time
173 --time
174 --traceback
174 --traceback
175 --verbose
175 --verbose
176 --version
176 --version
177 -R
177 -R
178 -h
178 -h
179 -q
179 -q
180 -v
180 -v
181 -y
181 -y
182
182
183 Show the options for the "serve" command
183 Show the options for the "serve" command
184 $ hg debugcomplete --options serve | sort
184 $ hg debugcomplete --options serve | sort
185 --accesslog
185 --accesslog
186 --address
186 --address
187 --certificate
187 --certificate
188 --cmdserver
188 --cmdserver
189 --color
189 --color
190 --config
190 --config
191 --cwd
191 --cwd
192 --daemon
192 --daemon
193 --daemon-postexec
193 --daemon-postexec
194 --debug
194 --debug
195 --debugger
195 --debugger
196 --encoding
196 --encoding
197 --encodingmode
197 --encodingmode
198 --errorlog
198 --errorlog
199 --help
199 --help
200 --hidden
200 --hidden
201 --ipv6
201 --ipv6
202 --name
202 --name
203 --noninteractive
203 --noninteractive
204 --pager
204 --pager
205 --pid-file
205 --pid-file
206 --port
206 --port
207 --prefix
207 --prefix
208 --print-url
208 --print-url
209 --profile
209 --profile
210 --quiet
210 --quiet
211 --repository
211 --repository
212 --stdio
212 --stdio
213 --style
213 --style
214 --subrepos
214 --subrepos
215 --templates
215 --templates
216 --time
216 --time
217 --traceback
217 --traceback
218 --verbose
218 --verbose
219 --version
219 --version
220 --web-conf
220 --web-conf
221 -6
221 -6
222 -A
222 -A
223 -E
223 -E
224 -R
224 -R
225 -S
225 -S
226 -a
226 -a
227 -d
227 -d
228 -h
228 -h
229 -n
229 -n
230 -p
230 -p
231 -q
231 -q
232 -t
232 -t
233 -v
233 -v
234 -y
234 -y
235
235
236 Show an error if we use --options with an ambiguous abbreviation
236 Show an error if we use --options with an ambiguous abbreviation
237 $ hg debugcomplete --options s
237 $ hg debugcomplete --options s
238 hg: command 's' is ambiguous:
238 hg: command 's' is ambiguous:
239 serve shelve showconfig status summary
239 serve shelve showconfig status summary
240 [255]
240 [255]
241
241
242 Show all commands + options
242 Show all commands + options
243 $ hg debugcommands
243 $ hg debugcommands
244 abort: dry-run
244 abort: dry-run
245 add: include, exclude, subrepos, dry-run
245 add: include, exclude, subrepos, dry-run
246 addremove: similarity, subrepos, include, exclude, dry-run
246 addremove: similarity, subrepos, include, exclude, dry-run
247 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
247 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
248 archive: no-decode, prefix, rev, type, subrepos, include, exclude
248 archive: no-decode, prefix, rev, type, subrepos, include, exclude
249 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
249 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
250 bisect: reset, good, bad, skip, extend, command, noupdate
250 bisect: reset, good, bad, skip, extend, command, noupdate
251 bookmarks: force, rev, delete, rename, inactive, list, template
251 bookmarks: force, rev, delete, rename, inactive, list, template
252 branch: force, clean, rev
252 branch: force, clean, rev
253 branches: active, closed, rev, template
253 branches: active, closed, rev, template
254 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
254 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
255 cat: output, rev, decode, include, exclude, template
255 cat: output, rev, decode, include, exclude, template
256 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
256 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
257 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
257 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
258 config: untrusted, edit, local, global, template
258 config: untrusted, edit, local, global, template
259 continue: dry-run
259 continue: dry-run
260 copy: after, force, include, exclude, dry-run
260 copy: after, force, include, exclude, dry-run
261 debugancestor:
261 debugancestor:
262 debugapplystreamclonebundle:
262 debugapplystreamclonebundle:
263 debugbuilddag: mergeable-file, overwritten-file, new-file
263 debugbuilddag: mergeable-file, overwritten-file, new-file
264 debugbundle: all, part-type, spec
264 debugbundle: all, part-type, spec
265 debugcapabilities:
265 debugcapabilities:
266 debugcheckstate:
266 debugcheckstate:
267 debugcolor: style
267 debugcolor: style
268 debugcommands:
268 debugcommands:
269 debugcomplete: options
269 debugcomplete: options
270 debugcreatestreamclonebundle:
270 debugcreatestreamclonebundle:
271 debugdag: tags, branches, dots, spaces
271 debugdag: tags, branches, dots, spaces
272 debugdata: changelog, manifest, dir
272 debugdata: changelog, manifest, dir
273 debugdate: extended
273 debugdate: extended
274 debugdeltachain: changelog, manifest, dir, template
274 debugdeltachain: changelog, manifest, dir, template
275 debugdirstate: nodates, dates, datesort
275 debugdirstate: nodates, dates, datesort
276 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
276 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
277 debugdownload: output
277 debugdownload: output
278 debugextensions: template
278 debugextensions: template
279 debugfileset: rev, all-files, show-matcher, show-stage
279 debugfileset: rev, all-files, show-matcher, show-stage
280 debugformat: template
280 debugformat: template
281 debugfsinfo:
281 debugfsinfo:
282 debuggetbundle: head, common, type
282 debuggetbundle: head, common, type
283 debugignore:
283 debugignore:
284 debugindex: changelog, manifest, dir, template
284 debugindex: changelog, manifest, dir, template
285 debugindexdot: changelog, manifest, dir
285 debugindexdot: changelog, manifest, dir
286 debugindexstats:
286 debugindexstats:
287 debuginstall: template
287 debuginstall: template
288 debugknown:
288 debugknown:
289 debuglabelcomplete:
289 debuglabelcomplete:
290 debuglocks: force-lock, force-wlock, set-lock, set-wlock
290 debuglocks: force-lock, force-wlock, set-lock, set-wlock
291 debugmanifestfulltextcache: clear, add
291 debugmanifestfulltextcache: clear, add
292 debugmergestate:
292 debugmergestate: style, template
293 debugnamecomplete:
293 debugnamecomplete:
294 debugnodemap: dump-new, dump-disk, check, metadata
294 debugnodemap: dump-new, dump-disk, check, metadata
295 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
295 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
296 debugp1copies: rev
296 debugp1copies: rev
297 debugp2copies: rev
297 debugp2copies: rev
298 debugpathcomplete: full, normal, added, removed
298 debugpathcomplete: full, normal, added, removed
299 debugpathcopies: include, exclude
299 debugpathcopies: include, exclude
300 debugpeer:
300 debugpeer:
301 debugpickmergetool: rev, changedelete, include, exclude, tool
301 debugpickmergetool: rev, changedelete, include, exclude, tool
302 debugpushkey:
302 debugpushkey:
303 debugpvec:
303 debugpvec:
304 debugrebuilddirstate: rev, minimal
304 debugrebuilddirstate: rev, minimal
305 debugrebuildfncache:
305 debugrebuildfncache:
306 debugrename: rev
306 debugrename: rev
307 debugrevlog: changelog, manifest, dir, dump
307 debugrevlog: changelog, manifest, dir, dump
308 debugrevlogindex: changelog, manifest, dir, format
308 debugrevlogindex: changelog, manifest, dir, format
309 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
309 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
310 debugserve: sshstdio, logiofd, logiofile
310 debugserve: sshstdio, logiofd, logiofile
311 debugsetparents:
311 debugsetparents:
312 debugsidedata: changelog, manifest, dir
312 debugsidedata: changelog, manifest, dir
313 debugssl:
313 debugssl:
314 debugsub: rev
314 debugsub: rev
315 debugsuccessorssets: closest
315 debugsuccessorssets: closest
316 debugtagscache:
316 debugtagscache:
317 debugtemplate: rev, define
317 debugtemplate: rev, define
318 debuguigetpass: prompt
318 debuguigetpass: prompt
319 debuguiprompt: prompt
319 debuguiprompt: prompt
320 debugupdatecaches:
320 debugupdatecaches:
321 debugupgraderepo: optimize, run, backup, changelog, manifest
321 debugupgraderepo: optimize, run, backup, changelog, manifest
322 debugwalk: include, exclude
322 debugwalk: include, exclude
323 debugwhyunstable:
323 debugwhyunstable:
324 debugwireargs: three, four, five, ssh, remotecmd, insecure
324 debugwireargs: three, four, five, ssh, remotecmd, insecure
325 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
325 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
326 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
326 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
327 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
327 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
328 files: rev, print0, include, exclude, template, subrepos
328 files: rev, print0, include, exclude, template, subrepos
329 forget: interactive, include, exclude, dry-run
329 forget: interactive, include, exclude, dry-run
330 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
330 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
331 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
331 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
332 heads: rev, topo, active, closed, style, template
332 heads: rev, topo, active, closed, style, template
333 help: extension, command, keyword, system
333 help: extension, command, keyword, system
334 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
334 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
335 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
335 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
336 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
336 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
337 init: ssh, remotecmd, insecure
337 init: ssh, remotecmd, insecure
338 locate: rev, print0, fullpath, include, exclude
338 locate: rev, print0, fullpath, include, exclude
339 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
339 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
340 manifest: rev, all, template
340 manifest: rev, all, template
341 merge: force, rev, preview, abort, tool
341 merge: force, rev, preview, abort, tool
342 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
342 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
343 parents: rev, style, template
343 parents: rev, style, template
344 paths: template
344 paths: template
345 phase: public, draft, secret, force, rev
345 phase: public, draft, secret, force, rev
346 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
346 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
347 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
347 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
348 recover: verify
348 recover: verify
349 remove: after, force, subrepos, include, exclude, dry-run
349 remove: after, force, subrepos, include, exclude, dry-run
350 rename: after, force, include, exclude, dry-run
350 rename: after, force, include, exclude, dry-run
351 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
351 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
352 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
352 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
353 rollback: dry-run, force
353 rollback: dry-run, force
354 root: template
354 root: template
355 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
355 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
356 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
356 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
357 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
357 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
358 summary: remote
358 summary: remote
359 tag: force, local, rev, remove, edit, message, date, user
359 tag: force, local, rev, remove, edit, message, date, user
360 tags: template
360 tags: template
361 tip: patch, git, style, template
361 tip: patch, git, style, template
362 unbundle: update
362 unbundle: update
363 unshelve: abort, continue, interactive, keep, name, tool, date
363 unshelve: abort, continue, interactive, keep, name, tool, date
364 update: clean, check, merge, date, rev, tool
364 update: clean, check, merge, date, rev, tool
365 verify: full
365 verify: full
366 version: template
366 version: template
367
367
368 $ hg init a
368 $ hg init a
369 $ cd a
369 $ cd a
370 $ echo fee > fee
370 $ echo fee > fee
371 $ hg ci -q -Amfee
371 $ hg ci -q -Amfee
372 $ hg tag fee
372 $ hg tag fee
373 $ mkdir fie
373 $ mkdir fie
374 $ echo dead > fie/dead
374 $ echo dead > fie/dead
375 $ echo live > fie/live
375 $ echo live > fie/live
376 $ hg bookmark fo
376 $ hg bookmark fo
377 $ hg branch -q fie
377 $ hg branch -q fie
378 $ hg ci -q -Amfie
378 $ hg ci -q -Amfie
379 $ echo fo > fo
379 $ echo fo > fo
380 $ hg branch -qf default
380 $ hg branch -qf default
381 $ hg ci -q -Amfo
381 $ hg ci -q -Amfo
382 $ echo Fum > Fum
382 $ echo Fum > Fum
383 $ hg ci -q -AmFum
383 $ hg ci -q -AmFum
384 $ hg bookmark Fum
384 $ hg bookmark Fum
385
385
386 Test debugpathcomplete
386 Test debugpathcomplete
387
387
388 $ hg debugpathcomplete f
388 $ hg debugpathcomplete f
389 fee
389 fee
390 fie
390 fie
391 fo
391 fo
392 $ hg debugpathcomplete -f f
392 $ hg debugpathcomplete -f f
393 fee
393 fee
394 fie/dead
394 fie/dead
395 fie/live
395 fie/live
396 fo
396 fo
397
397
398 $ hg rm Fum
398 $ hg rm Fum
399 $ hg debugpathcomplete -r F
399 $ hg debugpathcomplete -r F
400 Fum
400 Fum
401
401
402 Test debugnamecomplete
402 Test debugnamecomplete
403
403
404 $ hg debugnamecomplete
404 $ hg debugnamecomplete
405 Fum
405 Fum
406 default
406 default
407 fee
407 fee
408 fie
408 fie
409 fo
409 fo
410 tip
410 tip
411 $ hg debugnamecomplete f
411 $ hg debugnamecomplete f
412 fee
412 fee
413 fie
413 fie
414 fo
414 fo
415
415
416 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
416 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
417 used for completions in some shells.
417 used for completions in some shells.
418
418
419 $ hg debuglabelcomplete
419 $ hg debuglabelcomplete
420 Fum
420 Fum
421 default
421 default
422 fee
422 fee
423 fie
423 fie
424 fo
424 fo
425 tip
425 tip
426 $ hg debuglabelcomplete f
426 $ hg debuglabelcomplete f
427 fee
427 fee
428 fie
428 fie
429 fo
429 fo
@@ -1,187 +1,173 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > histedit=
5 > histedit=
6 > EOF
6 > EOF
7
7
8 $ initrepo ()
8 $ initrepo ()
9 > {
9 > {
10 > hg init r
10 > hg init r
11 > cd r
11 > cd r
12 > for x in a b c d e f ; do
12 > for x in a b c d e f ; do
13 > echo $x > $x
13 > echo $x > $x
14 > hg add $x
14 > hg add $x
15 > hg ci -m $x
15 > hg ci -m $x
16 > done
16 > done
17 > echo a >> e
17 > echo a >> e
18 > hg ci -m 'does not commute with e'
18 > hg ci -m 'does not commute with e'
19 > cd ..
19 > cd ..
20 > }
20 > }
21
21
22 $ initrepo
22 $ initrepo
23 $ cd r
23 $ cd r
24
24
25 log before edit
25 log before edit
26 $ hg log --graph
26 $ hg log --graph
27 @ changeset: 6:bfa474341cc9
27 @ changeset: 6:bfa474341cc9
28 | tag: tip
28 | tag: tip
29 | user: test
29 | user: test
30 | date: Thu Jan 01 00:00:00 1970 +0000
30 | date: Thu Jan 01 00:00:00 1970 +0000
31 | summary: does not commute with e
31 | summary: does not commute with e
32 |
32 |
33 o changeset: 5:652413bf663e
33 o changeset: 5:652413bf663e
34 | user: test
34 | user: test
35 | date: Thu Jan 01 00:00:00 1970 +0000
35 | date: Thu Jan 01 00:00:00 1970 +0000
36 | summary: f
36 | summary: f
37 |
37 |
38 o changeset: 4:e860deea161a
38 o changeset: 4:e860deea161a
39 | user: test
39 | user: test
40 | date: Thu Jan 01 00:00:00 1970 +0000
40 | date: Thu Jan 01 00:00:00 1970 +0000
41 | summary: e
41 | summary: e
42 |
42 |
43 o changeset: 3:055a42cdd887
43 o changeset: 3:055a42cdd887
44 | user: test
44 | user: test
45 | date: Thu Jan 01 00:00:00 1970 +0000
45 | date: Thu Jan 01 00:00:00 1970 +0000
46 | summary: d
46 | summary: d
47 |
47 |
48 o changeset: 2:177f92b77385
48 o changeset: 2:177f92b77385
49 | user: test
49 | user: test
50 | date: Thu Jan 01 00:00:00 1970 +0000
50 | date: Thu Jan 01 00:00:00 1970 +0000
51 | summary: c
51 | summary: c
52 |
52 |
53 o changeset: 1:d2ae7f538514
53 o changeset: 1:d2ae7f538514
54 | user: test
54 | user: test
55 | date: Thu Jan 01 00:00:00 1970 +0000
55 | date: Thu Jan 01 00:00:00 1970 +0000
56 | summary: b
56 | summary: b
57 |
57 |
58 o changeset: 0:cb9a9f314b8b
58 o changeset: 0:cb9a9f314b8b
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: a
61 summary: a
62
62
63
63
64 edit the history
64 edit the history
65 $ hg histedit 177f92b77385 --commands - 2>&1 <<EOF | fixbundle
65 $ hg histedit 177f92b77385 --commands - 2>&1 <<EOF | fixbundle
66 > pick 177f92b77385 c
66 > pick 177f92b77385 c
67 > pick 055a42cdd887 d
67 > pick 055a42cdd887 d
68 > pick bfa474341cc9 does not commute with e
68 > pick bfa474341cc9 does not commute with e
69 > pick e860deea161a e
69 > pick e860deea161a e
70 > pick 652413bf663e f
70 > pick 652413bf663e f
71 > EOF
71 > EOF
72 merging e
72 merging e
73 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
73 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
74 Fix up the change (pick e860deea161a)
74 Fix up the change (pick e860deea161a)
75 (hg histedit --continue to resume)
75 (hg histedit --continue to resume)
76
76
77 insert unsupported advisory merge record
77 insert unsupported advisory merge record
78 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
78 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
79 $ hg debugmergestate
79 $ hg debugmergestate
80 * version 2 records
80 local (local): 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
81 local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
81 other (histedit): e860deea161a2f77de56603b340ebbb4536308ae
82 other: e860deea161a2f77de56603b340ebbb4536308ae
82 file: e (state "u")
83 labels:
84 local: local
85 other: histedit
86 unrecognized entry: x advisory record
87 file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
88 file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
89 local path: e (flags "")
83 local path: e (flags "")
90 ancestor path: e (node null)
84 ancestor path: e (node 0000000000000000000000000000000000000000)
91 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
85 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
86 extra: ancestorlinknode = 0000000000000000000000000000000000000000
92 $ hg resolve -l
87 $ hg resolve -l
93 U e
88 U e
94
89
95 insert unsupported mandatory merge record
90 insert unsupported mandatory merge record
96 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
91 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
97 $ hg debugmergestate
92 $ hg debugmergestate
98 * version 2 records
93 abort: unsupported merge state records: X
99 local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
94 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
100 other: e860deea161a2f77de56603b340ebbb4536308ae
95 [255]
101 labels:
102 local: local
103 other: histedit
104 file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
105 file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
106 local path: e (flags "")
107 ancestor path: e (node null)
108 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
109 unrecognized entry: X mandatory record
110 $ hg resolve -l
96 $ hg resolve -l
111 abort: unsupported merge state records: X
97 abort: unsupported merge state records: X
112 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
98 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
113 [255]
99 [255]
114 $ hg resolve -ma
100 $ hg resolve -ma
115 abort: unsupported merge state records: X
101 abort: unsupported merge state records: X
116 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
102 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
117 [255]
103 [255]
118
104
119 abort the edit (should clear out merge state)
105 abort the edit (should clear out merge state)
120 $ hg histedit --abort 2>&1 | fixbundle
106 $ hg histedit --abort 2>&1 | fixbundle
121 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 $ hg debugmergestate
108 $ hg debugmergestate
123 no merge state found
109 no merge state found
124
110
125 log after abort
111 log after abort
126 $ hg resolve -l
112 $ hg resolve -l
127 $ hg log --graph
113 $ hg log --graph
128 @ changeset: 6:bfa474341cc9
114 @ changeset: 6:bfa474341cc9
129 | tag: tip
115 | tag: tip
130 | user: test
116 | user: test
131 | date: Thu Jan 01 00:00:00 1970 +0000
117 | date: Thu Jan 01 00:00:00 1970 +0000
132 | summary: does not commute with e
118 | summary: does not commute with e
133 |
119 |
134 o changeset: 5:652413bf663e
120 o changeset: 5:652413bf663e
135 | user: test
121 | user: test
136 | date: Thu Jan 01 00:00:00 1970 +0000
122 | date: Thu Jan 01 00:00:00 1970 +0000
137 | summary: f
123 | summary: f
138 |
124 |
139 o changeset: 4:e860deea161a
125 o changeset: 4:e860deea161a
140 | user: test
126 | user: test
141 | date: Thu Jan 01 00:00:00 1970 +0000
127 | date: Thu Jan 01 00:00:00 1970 +0000
142 | summary: e
128 | summary: e
143 |
129 |
144 o changeset: 3:055a42cdd887
130 o changeset: 3:055a42cdd887
145 | user: test
131 | user: test
146 | date: Thu Jan 01 00:00:00 1970 +0000
132 | date: Thu Jan 01 00:00:00 1970 +0000
147 | summary: d
133 | summary: d
148 |
134 |
149 o changeset: 2:177f92b77385
135 o changeset: 2:177f92b77385
150 | user: test
136 | user: test
151 | date: Thu Jan 01 00:00:00 1970 +0000
137 | date: Thu Jan 01 00:00:00 1970 +0000
152 | summary: c
138 | summary: c
153 |
139 |
154 o changeset: 1:d2ae7f538514
140 o changeset: 1:d2ae7f538514
155 | user: test
141 | user: test
156 | date: Thu Jan 01 00:00:00 1970 +0000
142 | date: Thu Jan 01 00:00:00 1970 +0000
157 | summary: b
143 | summary: b
158 |
144 |
159 o changeset: 0:cb9a9f314b8b
145 o changeset: 0:cb9a9f314b8b
160 user: test
146 user: test
161 date: Thu Jan 01 00:00:00 1970 +0000
147 date: Thu Jan 01 00:00:00 1970 +0000
162 summary: a
148 summary: a
163
149
164
150
165 Early tree conflict doesn't leave histedit in a wedged state. Note
151 Early tree conflict doesn't leave histedit in a wedged state. Note
166 that we don't specify --commands here: we catch the problem before we
152 that we don't specify --commands here: we catch the problem before we
167 even prompt the user for rules, sidestepping any dataloss issues.
153 even prompt the user for rules, sidestepping any dataloss issues.
168
154
169 $ hg rm c
155 $ hg rm c
170 $ hg ci -m 'remove c'
156 $ hg ci -m 'remove c'
171 $ echo collision > c
157 $ echo collision > c
172
158
173 $ hg histedit e860deea161a
159 $ hg histedit e860deea161a
174 c: untracked file differs
160 c: untracked file differs
175 abort: untracked files in working directory conflict with files in 055a42cdd887
161 abort: untracked files in working directory conflict with files in 055a42cdd887
176 [255]
162 [255]
177
163
178 We should have detected the collision early enough we're not in a
164 We should have detected the collision early enough we're not in a
179 histedit state, and p1 is unchanged.
165 histedit state, and p1 is unchanged.
180
166
181 $ hg log -r 'p1()' -T'{node}\n'
167 $ hg log -r 'p1()' -T'{node}\n'
182 1b0954ff00fccb15a37b679e4a35e9b01dfe685e
168 1b0954ff00fccb15a37b679e4a35e9b01dfe685e
183 $ hg status --config ui.tweakdefaults=yes
169 $ hg status --config ui.tweakdefaults=yes
184 ? c
170 ? c
185 ? e.orig
171 ? e.orig
186
172
187 $ cd ..
173 $ cd ..
@@ -1,1140 +1,1076 b''
1 Tests for change/delete conflicts, including:
1 Tests for change/delete conflicts, including:
2 b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
2 b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
3 (issue897)
3 (issue897)
4
4
5 840e2b315c1f: Fix misleading error and prompts during update/merge
5 840e2b315c1f: Fix misleading error and prompts during update/merge
6 (issue556)
6 (issue556)
7
7
8 Make sure HGMERGE doesn't interfere with the test
8 Make sure HGMERGE doesn't interfere with the test
9 $ unset HGMERGE
9 $ unset HGMERGE
10
10
11 $ status() {
11 $ status() {
12 > echo "--- status ---"
12 > echo "--- status ---"
13 > hg st -A file1 file2 file3
13 > hg st -A file1 file2 file3
14 > echo "--- resolve --list ---"
14 > echo "--- resolve --list ---"
15 > hg resolve --list file1 file2 file3
15 > hg resolve --list file1 file2 file3
16 > echo "--- debugmergestate ---"
16 > echo "--- debugmergestate ---"
17 > hg debugmergestate
17 > hg debugmergestate
18 > for file in file1 file2 file3; do
18 > for file in file1 file2 file3; do
19 > if [ -f $file ]; then
19 > if [ -f $file ]; then
20 > echo "--- $file ---"
20 > echo "--- $file ---"
21 > cat $file
21 > cat $file
22 > else
22 > else
23 > echo "*** $file does not exist"
23 > echo "*** $file does not exist"
24 > fi
24 > fi
25 > done
25 > done
26 > }
26 > }
27
27
28 $ hg init repo
28 $ hg init repo
29 $ cd repo
29 $ cd repo
30
30
31 $ echo 1 > file1
31 $ echo 1 > file1
32 $ echo 2 > file2
32 $ echo 2 > file2
33 $ echo 3 > file3
33 $ echo 3 > file3
34 $ hg ci -Am 'added files'
34 $ hg ci -Am 'added files'
35 adding file1
35 adding file1
36 adding file2
36 adding file2
37 adding file3
37 adding file3
38
38
39 $ hg rm file1
39 $ hg rm file1
40 $ echo changed >> file2
40 $ echo changed >> file2
41 $ echo changed1 >> file3
41 $ echo changed1 >> file3
42 $ hg ci -m 'removed file1, changed file2, changed file3'
42 $ hg ci -m 'removed file1, changed file2, changed file3'
43
43
44 $ hg co 0
44 $ hg co 0
45 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
46
46
47 $ echo changed >> file1
47 $ echo changed >> file1
48 $ hg rm file2
48 $ hg rm file2
49 $ echo changed2 >> file3
49 $ echo changed2 >> file3
50 $ hg ci -m 'changed file1, removed file2, changed file3'
50 $ hg ci -m 'changed file1, removed file2, changed file3'
51 created new head
51 created new head
52
52
53
53
54 Non-interactive merge:
54 Non-interactive merge:
55
55
56 $ hg merge -y
56 $ hg merge -y
57 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
57 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
58 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
58 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
59 What do you want to do? u
59 What do you want to do? u
60 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
60 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
61 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
61 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
62 What do you want to do? u
62 What do you want to do? u
63 merging file3
63 merging file3
64 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
64 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
65 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
65 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
66 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
66 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
67 [1]
67 [1]
68
68
69 $ status
69 $ status
70 --- status ---
70 --- status ---
71 M file2
71 M file2
72 M file3
72 M file3
73 C file1
73 C file1
74 --- resolve --list ---
74 --- resolve --list ---
75 U file1
75 U file1
76 U file2
76 U file2
77 U file3
77 U file3
78 --- debugmergestate ---
78 --- debugmergestate ---
79 * version 2 records
79 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
80 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
80 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
81 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
81 file: file1 (state "u")
82 labels:
83 local: working copy
84 other: merge rev
85 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
86 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
87 local path: file1 (flags "")
82 local path: file1 (flags "")
88 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
83 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
89 other path: file1 (node null)
84 other path: file1 (node 0000000000000000000000000000000000000000)
90 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
85 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
91 file: file2 (record type "C", state "u", hash null)
86 file: file2 (state "u")
92 local path: file2 (flags "")
87 local path: file2 (flags "")
93 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
88 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
94 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
89 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
95 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
90 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
96 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
91 file: file3 (state "u")
97 local path: file3 (flags "")
92 local path: file3 (flags "")
98 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
93 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
99 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
94 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
95 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
100 --- file1 ---
96 --- file1 ---
101 1
97 1
102 changed
98 changed
103 --- file2 ---
99 --- file2 ---
104 2
100 2
105 changed
101 changed
106 --- file3 ---
102 --- file3 ---
107 3
103 3
108 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
104 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
109 changed2
105 changed2
110 =======
106 =======
111 changed1
107 changed1
112 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
108 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
113
109
114
110
115 Interactive merge:
111 Interactive merge:
116
112
117 $ hg co -C
113 $ hg co -C
118 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
114 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
119 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
115 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
120 1 other heads for branch "default"
116 1 other heads for branch "default"
121
117
122 $ hg merge --config ui.interactive=true <<EOF
118 $ hg merge --config ui.interactive=true <<EOF
123 > c
119 > c
124 > d
120 > d
125 > EOF
121 > EOF
126 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
122 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
127 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
123 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
128 What do you want to do? c
124 What do you want to do? c
129 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
125 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
130 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
126 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
131 What do you want to do? d
127 What do you want to do? d
132 merging file3
128 merging file3
133 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
129 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
134 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
130 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
135 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
131 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
136 [1]
132 [1]
137
133
138 $ status
134 $ status
139 --- status ---
135 --- status ---
140 file2: * (glob)
136 file2: * (glob)
141 M file3
137 M file3
142 C file1
138 C file1
143 --- resolve --list ---
139 --- resolve --list ---
144 R file1
140 R file1
145 R file2
141 R file2
146 U file3
142 U file3
147 --- debugmergestate ---
143 --- debugmergestate ---
148 * version 2 records
144 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
149 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
145 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
150 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
146 file: file1 (state "r")
151 labels:
152 local: working copy
153 other: merge rev
154 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
155 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
156 local path: file1 (flags "")
147 local path: file1 (flags "")
157 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
148 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
158 other path: file1 (node null)
149 other path: file1 (node 0000000000000000000000000000000000000000)
159 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
150 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
160 file: file2 (record type "C", state "r", hash null)
151 file: file2 (state "r")
161 local path: file2 (flags "")
152 local path: file2 (flags "")
162 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
153 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
163 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
154 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
164 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
155 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
165 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
156 file: file3 (state "u")
166 local path: file3 (flags "")
157 local path: file3 (flags "")
167 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
158 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
168 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
159 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
160 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
169 --- file1 ---
161 --- file1 ---
170 1
162 1
171 changed
163 changed
172 *** file2 does not exist
164 *** file2 does not exist
173 --- file3 ---
165 --- file3 ---
174 3
166 3
175 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
167 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
176 changed2
168 changed2
177 =======
169 =======
178 changed1
170 changed1
179 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
171 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
180
172
181
173
182 Interactive merge with bad input:
174 Interactive merge with bad input:
183
175
184 $ hg co -C
176 $ hg co -C
185 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
186 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
178 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
187 1 other heads for branch "default"
179 1 other heads for branch "default"
188
180
189 $ hg merge --config ui.interactive=true <<EOF
181 $ hg merge --config ui.interactive=true <<EOF
190 > foo
182 > foo
191 > bar
183 > bar
192 > d
184 > d
193 > baz
185 > baz
194 > c
186 > c
195 > EOF
187 > EOF
196 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
188 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
197 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
189 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
198 What do you want to do? foo
190 What do you want to do? foo
199 unrecognized response
191 unrecognized response
200 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
192 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
201 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
193 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
202 What do you want to do? bar
194 What do you want to do? bar
203 unrecognized response
195 unrecognized response
204 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
196 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
205 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
197 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
206 What do you want to do? d
198 What do you want to do? d
207 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
199 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
208 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
200 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
209 What do you want to do? baz
201 What do you want to do? baz
210 unrecognized response
202 unrecognized response
211 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
203 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
212 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
204 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
213 What do you want to do? c
205 What do you want to do? c
214 merging file3
206 merging file3
215 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
207 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
216 0 files updated, 1 files merged, 1 files removed, 1 files unresolved
208 0 files updated, 1 files merged, 1 files removed, 1 files unresolved
217 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
209 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
218 [1]
210 [1]
219
211
220 $ status
212 $ status
221 --- status ---
213 --- status ---
222 M file2
214 M file2
223 M file3
215 M file3
224 R file1
216 R file1
225 --- resolve --list ---
217 --- resolve --list ---
226 R file1
218 R file1
227 R file2
219 R file2
228 U file3
220 U file3
229 --- debugmergestate ---
221 --- debugmergestate ---
230 * version 2 records
222 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
231 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
223 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
232 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
224 file: file1 (state "r")
233 labels:
234 local: working copy
235 other: merge rev
236 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
237 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
238 local path: file1 (flags "")
225 local path: file1 (flags "")
239 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
226 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
240 other path: file1 (node null)
227 other path: file1 (node 0000000000000000000000000000000000000000)
241 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
228 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
242 file: file2 (record type "C", state "r", hash null)
229 file: file2 (state "r")
243 local path: file2 (flags "")
230 local path: file2 (flags "")
244 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
231 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
245 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
232 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
246 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
233 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
247 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
234 file: file3 (state "u")
248 local path: file3 (flags "")
235 local path: file3 (flags "")
249 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
236 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
250 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
237 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
238 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
251 *** file1 does not exist
239 *** file1 does not exist
252 --- file2 ---
240 --- file2 ---
253 2
241 2
254 changed
242 changed
255 --- file3 ---
243 --- file3 ---
256 3
244 3
257 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
245 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
258 changed2
246 changed2
259 =======
247 =======
260 changed1
248 changed1
261 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
249 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
262
250
263
251
264 Interactive merge with not enough input:
252 Interactive merge with not enough input:
265
253
266 $ hg co -C
254 $ hg co -C
267 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
255 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
268 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
256 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
269 1 other heads for branch "default"
257 1 other heads for branch "default"
270
258
271 $ hg merge --config ui.interactive=true <<EOF
259 $ hg merge --config ui.interactive=true <<EOF
272 > d
260 > d
273 > EOF
261 > EOF
274 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
262 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
275 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
263 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
276 What do you want to do? d
264 What do you want to do? d
277 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
265 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
278 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
266 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
279 What do you want to do?
267 What do you want to do?
280 merging file3
268 merging file3
281 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
269 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
282 0 files updated, 0 files merged, 1 files removed, 2 files unresolved
270 0 files updated, 0 files merged, 1 files removed, 2 files unresolved
283 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
271 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
284 [1]
272 [1]
285
273
286 $ status
274 $ status
287 --- status ---
275 --- status ---
288 M file2
276 M file2
289 M file3
277 M file3
290 R file1
278 R file1
291 --- resolve --list ---
279 --- resolve --list ---
292 R file1
280 R file1
293 U file2
281 U file2
294 U file3
282 U file3
295 --- debugmergestate ---
283 --- debugmergestate ---
296 * version 2 records
284 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
297 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
285 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
298 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
286 file: file1 (state "r")
299 labels:
300 local: working copy
301 other: merge rev
302 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
303 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
304 local path: file1 (flags "")
287 local path: file1 (flags "")
305 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
288 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
306 other path: file1 (node null)
289 other path: file1 (node 0000000000000000000000000000000000000000)
307 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
290 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
308 file: file2 (record type "C", state "u", hash null)
291 file: file2 (state "u")
309 local path: file2 (flags "")
292 local path: file2 (flags "")
310 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
293 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
311 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
294 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
312 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
295 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
313 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
296 file: file3 (state "u")
314 local path: file3 (flags "")
297 local path: file3 (flags "")
315 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
298 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
316 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
299 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
300 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
317 *** file1 does not exist
301 *** file1 does not exist
318 --- file2 ---
302 --- file2 ---
319 2
303 2
320 changed
304 changed
321 --- file3 ---
305 --- file3 ---
322 3
306 3
323 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
307 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
324 changed2
308 changed2
325 =======
309 =======
326 changed1
310 changed1
327 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
311 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
328
312
329 Choose local versions of files
313 Choose local versions of files
330
314
331 $ hg co -C
315 $ hg co -C
332 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
316 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
333 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
317 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
334 1 other heads for branch "default"
318 1 other heads for branch "default"
335
319
336 $ hg merge --tool :local
320 $ hg merge --tool :local
337 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
321 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
338 (branch merge, don't forget to commit)
322 (branch merge, don't forget to commit)
339 $ status 2>&1 | tee $TESTTMP/local.status
323 $ status 2>&1 | tee $TESTTMP/local.status
340 --- status ---
324 --- status ---
341 file2: * (glob)
325 file2: * (glob)
342 M file3
326 M file3
343 C file1
327 C file1
344 --- resolve --list ---
328 --- resolve --list ---
345 R file1
329 R file1
346 R file2
330 R file2
347 R file3
331 R file3
348 --- debugmergestate ---
332 --- debugmergestate ---
349 * version 2 records
333 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
350 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
334 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
351 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
335 file: file1 (state "r")
352 labels:
353 local: working copy
354 other: merge rev
355 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
356 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
357 local path: file1 (flags "")
336 local path: file1 (flags "")
358 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
337 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
359 other path: file1 (node null)
338 other path: file1 (node 0000000000000000000000000000000000000000)
360 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
339 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
361 file: file2 (record type "C", state "r", hash null)
340 file: file2 (state "r")
362 local path: file2 (flags "")
341 local path: file2 (flags "")
363 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
342 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
364 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
343 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
365 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
344 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
366 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
345 file: file3 (state "r")
367 local path: file3 (flags "")
346 local path: file3 (flags "")
368 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
347 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
369 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
348 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
349 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
370 --- file1 ---
350 --- file1 ---
371 1
351 1
372 changed
352 changed
373 *** file2 does not exist
353 *** file2 does not exist
374 --- file3 ---
354 --- file3 ---
375 3
355 3
376 changed2
356 changed2
377
357
378 Choose other versions of files
358 Choose other versions of files
379
359
380 $ hg co -C
360 $ hg co -C
381 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
361 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
362 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
383 1 other heads for branch "default"
363 1 other heads for branch "default"
384
364
385 $ hg merge --tool :other
365 $ hg merge --tool :other
386 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
366 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
387 (branch merge, don't forget to commit)
367 (branch merge, don't forget to commit)
388 $ status 2>&1 | tee $TESTTMP/other.status
368 $ status 2>&1 | tee $TESTTMP/other.status
389 --- status ---
369 --- status ---
390 M file2
370 M file2
391 M file3
371 M file3
392 R file1
372 R file1
393 --- resolve --list ---
373 --- resolve --list ---
394 R file1
374 R file1
395 R file2
375 R file2
396 R file3
376 R file3
397 --- debugmergestate ---
377 --- debugmergestate ---
398 * version 2 records
378 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
399 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
379 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
400 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
380 file: file1 (state "r")
401 labels:
402 local: working copy
403 other: merge rev
404 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
405 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
406 local path: file1 (flags "")
381 local path: file1 (flags "")
407 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
382 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
408 other path: file1 (node null)
383 other path: file1 (node 0000000000000000000000000000000000000000)
409 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
384 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
410 file: file2 (record type "C", state "r", hash null)
385 file: file2 (state "r")
411 local path: file2 (flags "")
386 local path: file2 (flags "")
412 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
387 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
413 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
388 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
414 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
389 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
415 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
390 file: file3 (state "r")
416 local path: file3 (flags "")
391 local path: file3 (flags "")
417 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
392 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
418 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
393 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
394 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
419 *** file1 does not exist
395 *** file1 does not exist
420 --- file2 ---
396 --- file2 ---
421 2
397 2
422 changed
398 changed
423 --- file3 ---
399 --- file3 ---
424 3
400 3
425 changed1
401 changed1
426
402
427 Fail
403 Fail
428
404
429 $ hg co -C
405 $ hg co -C
430 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
406 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
431 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
407 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
432 1 other heads for branch "default"
408 1 other heads for branch "default"
433
409
434 $ hg merge --tool :fail
410 $ hg merge --tool :fail
435 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
411 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
436 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
412 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
437 [1]
413 [1]
438 $ status 2>&1 | tee $TESTTMP/fail.status
414 $ status 2>&1 | tee $TESTTMP/fail.status
439 --- status ---
415 --- status ---
440 M file2
416 M file2
441 M file3
417 M file3
442 C file1
418 C file1
443 --- resolve --list ---
419 --- resolve --list ---
444 U file1
420 U file1
445 U file2
421 U file2
446 U file3
422 U file3
447 --- debugmergestate ---
423 --- debugmergestate ---
448 * version 2 records
424 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
449 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
425 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
450 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
426 file: file1 (state "u")
451 labels:
452 local: working copy
453 other: merge rev
454 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
455 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
456 local path: file1 (flags "")
427 local path: file1 (flags "")
457 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
428 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
458 other path: file1 (node null)
429 other path: file1 (node 0000000000000000000000000000000000000000)
459 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
430 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
460 file: file2 (record type "C", state "u", hash null)
431 file: file2 (state "u")
461 local path: file2 (flags "")
432 local path: file2 (flags "")
462 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
433 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
463 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
434 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
464 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
435 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
465 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
436 file: file3 (state "u")
466 local path: file3 (flags "")
437 local path: file3 (flags "")
467 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
438 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
468 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
439 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
440 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
469 --- file1 ---
441 --- file1 ---
470 1
442 1
471 changed
443 changed
472 --- file2 ---
444 --- file2 ---
473 2
445 2
474 changed
446 changed
475 --- file3 ---
447 --- file3 ---
476 3
448 3
477 changed2
449 changed2
478
450
479 Force prompts with no input (should be similar to :fail)
451 Force prompts with no input (should be similar to :fail)
480
452
481 $ hg co -C
453 $ hg co -C
482 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
454 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
483 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
455 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
484 1 other heads for branch "default"
456 1 other heads for branch "default"
485
457
486 $ hg merge --config ui.interactive=True --tool :prompt
458 $ hg merge --config ui.interactive=True --tool :prompt
487 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
459 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
488 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
460 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
489 What do you want to do?
461 What do you want to do?
490 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
462 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
491 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
463 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
492 What do you want to do?
464 What do you want to do?
493 file 'file3' needs to be resolved.
465 file 'file3' needs to be resolved.
494 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
466 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
495 What do you want to do?
467 What do you want to do?
496 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
468 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
497 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
469 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
498 [1]
470 [1]
499 $ status 2>&1 | tee $TESTTMP/prompt.status
471 $ status 2>&1 | tee $TESTTMP/prompt.status
500 --- status ---
472 --- status ---
501 M file2
473 M file2
502 M file3
474 M file3
503 C file1
475 C file1
504 --- resolve --list ---
476 --- resolve --list ---
505 U file1
477 U file1
506 U file2
478 U file2
507 U file3
479 U file3
508 --- debugmergestate ---
480 --- debugmergestate ---
509 * version 2 records
481 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
510 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
482 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
511 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
483 file: file1 (state "u")
512 labels:
513 local: working copy
514 other: merge rev
515 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
516 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
517 local path: file1 (flags "")
484 local path: file1 (flags "")
518 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
485 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
519 other path: file1 (node null)
486 other path: file1 (node 0000000000000000000000000000000000000000)
520 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
487 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
521 file: file2 (record type "C", state "u", hash null)
488 file: file2 (state "u")
522 local path: file2 (flags "")
489 local path: file2 (flags "")
523 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
490 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
524 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
491 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
525 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
492 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
526 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
493 file: file3 (state "u")
527 local path: file3 (flags "")
494 local path: file3 (flags "")
528 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
495 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
529 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
496 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
497 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
530 --- file1 ---
498 --- file1 ---
531 1
499 1
532 changed
500 changed
533 --- file2 ---
501 --- file2 ---
534 2
502 2
535 changed
503 changed
536 --- file3 ---
504 --- file3 ---
537 3
505 3
538 changed2
506 changed2
539 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
507 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
540
508
541
509
542 Force prompts
510 Force prompts
543
511
544 $ hg co -C
512 $ hg co -C
545 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
513 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
546 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
514 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
547 1 other heads for branch "default"
515 1 other heads for branch "default"
548
516
549 $ hg merge --tool :prompt
517 $ hg merge --tool :prompt
550 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
518 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
551 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
519 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
552 What do you want to do? u
520 What do you want to do? u
553 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
521 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
554 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
522 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
555 What do you want to do? u
523 What do you want to do? u
556 file 'file3' needs to be resolved.
524 file 'file3' needs to be resolved.
557 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
525 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
558 What do you want to do? u
526 What do you want to do? u
559 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
527 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
560 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
528 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
561 [1]
529 [1]
562 $ status
530 $ status
563 --- status ---
531 --- status ---
564 M file2
532 M file2
565 M file3
533 M file3
566 C file1
534 C file1
567 --- resolve --list ---
535 --- resolve --list ---
568 U file1
536 U file1
569 U file2
537 U file2
570 U file3
538 U file3
571 --- debugmergestate ---
539 --- debugmergestate ---
572 * version 2 records
540 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
573 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
541 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
574 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
542 file: file1 (state "u")
575 labels:
576 local: working copy
577 other: merge rev
578 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
579 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
580 local path: file1 (flags "")
543 local path: file1 (flags "")
581 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
544 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
582 other path: file1 (node null)
545 other path: file1 (node 0000000000000000000000000000000000000000)
583 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
546 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
584 file: file2 (record type "C", state "u", hash null)
547 file: file2 (state "u")
585 local path: file2 (flags "")
548 local path: file2 (flags "")
586 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
549 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
587 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
550 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
588 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
551 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
589 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
552 file: file3 (state "u")
590 local path: file3 (flags "")
553 local path: file3 (flags "")
591 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
554 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
592 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
555 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
556 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
593 --- file1 ---
557 --- file1 ---
594 1
558 1
595 changed
559 changed
596 --- file2 ---
560 --- file2 ---
597 2
561 2
598 changed
562 changed
599 --- file3 ---
563 --- file3 ---
600 3
564 3
601 changed2
565 changed2
602
566
603 Choose to merge all files
567 Choose to merge all files
604
568
605 $ hg co -C
569 $ hg co -C
606 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
570 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
607 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
571 updated to "13910f48cf7b: changed file1, removed file2, changed file3"
608 1 other heads for branch "default"
572 1 other heads for branch "default"
609
573
610 $ hg merge --tool :merge3
574 $ hg merge --tool :merge3
611 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
575 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
612 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
576 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
613 What do you want to do? u
577 What do you want to do? u
614 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
578 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
615 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
579 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
616 What do you want to do? u
580 What do you want to do? u
617 merging file3
581 merging file3
618 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
582 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
619 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
583 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
620 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
584 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
621 [1]
585 [1]
622 $ status
586 $ status
623 --- status ---
587 --- status ---
624 M file2
588 M file2
625 M file3
589 M file3
626 C file1
590 C file1
627 --- resolve --list ---
591 --- resolve --list ---
628 U file1
592 U file1
629 U file2
593 U file2
630 U file3
594 U file3
631 --- debugmergestate ---
595 --- debugmergestate ---
632 * version 2 records
596 local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
633 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
597 other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
634 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
598 file: file1 (state "u")
635 labels:
636 local: working copy
637 other: merge rev
638 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
639 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
640 local path: file1 (flags "")
599 local path: file1 (flags "")
641 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
600 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
642 other path: file1 (node null)
601 other path: file1 (node 0000000000000000000000000000000000000000)
643 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
602 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
644 file: file2 (record type "C", state "u", hash null)
603 file: file2 (state "u")
645 local path: file2 (flags "")
604 local path: file2 (flags "")
646 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
605 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
647 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
606 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
648 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
607 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
649 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
608 file: file3 (state "u")
650 local path: file3 (flags "")
609 local path: file3 (flags "")
651 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
610 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
652 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
611 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
612 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
653 --- file1 ---
613 --- file1 ---
654 1
614 1
655 changed
615 changed
656 --- file2 ---
616 --- file2 ---
657 2
617 2
658 changed
618 changed
659 --- file3 ---
619 --- file3 ---
660 3
620 3
661 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
621 <<<<<<< working copy: 13910f48cf7b - test: changed file1, removed file2, chan...
662 changed2
622 changed2
663 ||||||| base
623 ||||||| base
664 =======
624 =======
665 changed1
625 changed1
666 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
626 >>>>>>> merge rev: 10f9a0a634e8 - test: removed file1, changed file2, chan...
667
627
668 Exercise transitions between local, other, fail and prompt, and make sure the
628 Exercise transitions between local, other, fail and prompt, and make sure the
669 dirstate stays consistent. (Compare with each other and to the above
629 dirstate stays consistent. (Compare with each other and to the above
670 invocations.)
630 invocations.)
671
631
672 $ testtransitions() {
632 $ testtransitions() {
673 > # this traversal order covers every transition
633 > # this traversal order covers every transition
674 > tools="local other prompt local fail other local prompt other fail prompt fail local"
634 > tools="local other prompt local fail other local prompt other fail prompt fail local"
675 > lasttool="merge3"
635 > lasttool="merge3"
676 > for tool in $tools; do
636 > for tool in $tools; do
677 > echo "=== :$lasttool -> :$tool ==="
637 > echo "=== :$lasttool -> :$tool ==="
678 > ref="$TESTTMP/$tool.status"
638 > ref="$TESTTMP/$tool.status"
679 > hg resolve --unmark --all
639 > hg resolve --unmark --all
680 > hg resolve --tool ":$tool" --all --config ui.interactive=True
640 > hg resolve --tool ":$tool" --all --config ui.interactive=True
681 > status > "$TESTTMP/compare.status" 2>&1
641 > status > "$TESTTMP/compare.status" 2>&1
682 > echo '--- diff of status ---'
642 > echo '--- diff of status ---'
683 > if cmp "$TESTTMP/$tool.status" "$TESTTMP/compare.status" || diff -U8 "$TESTTMP/$tool.status" "$TESTTMP/compare.status"; then
643 > if cmp "$TESTTMP/$tool.status" "$TESTTMP/compare.status" || diff -U8 "$TESTTMP/$tool.status" "$TESTTMP/compare.status"; then
684 > echo '(status identical)'
644 > echo '(status identical)'
685 > fi
645 > fi
686 > lasttool="$tool"
646 > lasttool="$tool"
687 > echo
647 > echo
688 > done
648 > done
689 > }
649 > }
690
650
691 $ testtransitions
651 $ testtransitions
692 === :merge3 -> :local ===
652 === :merge3 -> :local ===
693 (no more unresolved files)
653 (no more unresolved files)
694 --- diff of status ---
654 --- diff of status ---
695 (status identical)
655 (status identical)
696
656
697 === :local -> :other ===
657 === :local -> :other ===
698 (no more unresolved files)
658 (no more unresolved files)
699 --- diff of status ---
659 --- diff of status ---
700 (status identical)
660 (status identical)
701
661
702 === :other -> :prompt ===
662 === :other -> :prompt ===
703 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
663 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
704 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
664 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
705 What do you want to do?
665 What do you want to do?
706 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
666 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
707 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
667 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
708 What do you want to do?
668 What do you want to do?
709 file 'file3' needs to be resolved.
669 file 'file3' needs to be resolved.
710 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
670 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
711 What do you want to do?
671 What do you want to do?
712 --- diff of status ---
672 --- diff of status ---
713 (status identical)
673 (status identical)
714
674
715 === :prompt -> :local ===
675 === :prompt -> :local ===
716 (no more unresolved files)
676 (no more unresolved files)
717 --- diff of status ---
677 --- diff of status ---
718 (status identical)
678 (status identical)
719
679
720 === :local -> :fail ===
680 === :local -> :fail ===
721 --- diff of status ---
681 --- diff of status ---
722 (status identical)
682 (status identical)
723
683
724 === :fail -> :other ===
684 === :fail -> :other ===
725 (no more unresolved files)
685 (no more unresolved files)
726 --- diff of status ---
686 --- diff of status ---
727 (status identical)
687 (status identical)
728
688
729 === :other -> :local ===
689 === :other -> :local ===
730 (no more unresolved files)
690 (no more unresolved files)
731 --- diff of status ---
691 --- diff of status ---
732 (status identical)
692 (status identical)
733
693
734 === :local -> :prompt ===
694 === :local -> :prompt ===
735 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
695 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
736 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
696 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
737 What do you want to do?
697 What do you want to do?
738 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
698 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
739 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
699 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
740 What do you want to do?
700 What do you want to do?
741 file 'file3' needs to be resolved.
701 file 'file3' needs to be resolved.
742 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
702 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
743 What do you want to do?
703 What do you want to do?
744 --- diff of status ---
704 --- diff of status ---
745 (status identical)
705 (status identical)
746
706
747 === :prompt -> :other ===
707 === :prompt -> :other ===
748 (no more unresolved files)
708 (no more unresolved files)
749 --- diff of status ---
709 --- diff of status ---
750 (status identical)
710 (status identical)
751
711
752 === :other -> :fail ===
712 === :other -> :fail ===
753 --- diff of status ---
713 --- diff of status ---
754 (status identical)
714 (status identical)
755
715
756 === :fail -> :prompt ===
716 === :fail -> :prompt ===
757 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
717 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
758 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
718 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
759 What do you want to do?
719 What do you want to do?
760 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
720 file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
761 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
721 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
762 What do you want to do?
722 What do you want to do?
763 file 'file3' needs to be resolved.
723 file 'file3' needs to be resolved.
764 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
724 You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
765 What do you want to do?
725 What do you want to do?
766 --- diff of status ---
726 --- diff of status ---
767 (status identical)
727 (status identical)
768
728
769 === :prompt -> :fail ===
729 === :prompt -> :fail ===
770 --- diff of status ---
730 --- diff of status ---
771 (status identical)
731 (status identical)
772
732
773 === :fail -> :local ===
733 === :fail -> :local ===
774 (no more unresolved files)
734 (no more unresolved files)
775 --- diff of status ---
735 --- diff of status ---
776 (status identical)
736 (status identical)
777
737
778
738
779
739
780 Non-interactive linear update
740 Non-interactive linear update
781
741
782 $ hg co -C 0
742 $ hg co -C 0
783 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
743 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
784 $ echo changed >> file1
744 $ echo changed >> file1
785 $ hg rm file2
745 $ hg rm file2
786 $ hg update 1 -y
746 $ hg update 1 -y
787 file 'file1' was deleted in other [destination] but was modified in local [working copy].
747 file 'file1' was deleted in other [destination] but was modified in local [working copy].
788 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
748 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
789 What do you want to do? u
749 What do you want to do? u
790 file 'file2' was deleted in local [working copy] but was modified in other [destination].
750 file 'file2' was deleted in local [working copy] but was modified in other [destination].
791 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
751 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
792 What do you want to do? u
752 What do you want to do? u
793 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
753 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
794 use 'hg resolve' to retry unresolved file merges
754 use 'hg resolve' to retry unresolved file merges
795 [1]
755 [1]
796 $ status
756 $ status
797 --- status ---
757 --- status ---
798 A file1
758 A file1
799 C file2
759 C file2
800 C file3
760 C file3
801 --- resolve --list ---
761 --- resolve --list ---
802 U file1
762 U file1
803 U file2
763 U file2
804 --- debugmergestate ---
764 --- debugmergestate ---
805 * version 2 records
765 local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
806 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
766 other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
807 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
767 file: file1 (state "u")
808 labels:
809 local: working copy
810 other: destination
811 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
812 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
813 local path: file1 (flags "")
768 local path: file1 (flags "")
814 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
769 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
815 other path: file1 (node null)
770 other path: file1 (node 0000000000000000000000000000000000000000)
816 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
771 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
817 file: file2 (record type "C", state "u", hash null)
772 file: file2 (state "u")
818 local path: file2 (flags "")
773 local path: file2 (flags "")
819 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
774 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
820 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
775 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
776 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
821 --- file1 ---
777 --- file1 ---
822 1
778 1
823 changed
779 changed
824 --- file2 ---
780 --- file2 ---
825 2
781 2
826 changed
782 changed
827 --- file3 ---
783 --- file3 ---
828 3
784 3
829 changed1
785 changed1
830
786
831 Choose local versions of files
787 Choose local versions of files
832
788
833 $ hg co -C 0
789 $ hg co -C 0
834 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
790 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
835 $ echo changed >> file1
791 $ echo changed >> file1
836 $ hg rm file2
792 $ hg rm file2
837 $ hg update 1 --tool :local
793 $ hg update 1 --tool :local
838 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
794 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
839 $ status 2>&1 | tee $TESTTMP/local.status
795 $ status 2>&1 | tee $TESTTMP/local.status
840 --- status ---
796 --- status ---
841 file2: * (glob)
797 file2: * (glob)
842 A file1
798 A file1
843 C file3
799 C file3
844 --- resolve --list ---
800 --- resolve --list ---
845 R file1
801 R file1
846 R file2
802 R file2
847 --- debugmergestate ---
803 --- debugmergestate ---
848 * version 2 records
804 local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
849 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
805 other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
850 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
806 file: file1 (state "r")
851 labels:
852 local: working copy
853 other: destination
854 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
855 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
856 local path: file1 (flags "")
807 local path: file1 (flags "")
857 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
808 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
858 other path: file1 (node null)
809 other path: file1 (node 0000000000000000000000000000000000000000)
859 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
810 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
860 file: file2 (record type "C", state "r", hash null)
811 file: file2 (state "r")
861 local path: file2 (flags "")
812 local path: file2 (flags "")
862 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
813 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
863 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
814 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
815 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
864 --- file1 ---
816 --- file1 ---
865 1
817 1
866 changed
818 changed
867 *** file2 does not exist
819 *** file2 does not exist
868 --- file3 ---
820 --- file3 ---
869 3
821 3
870 changed1
822 changed1
871
823
872 Choose other versions of files
824 Choose other versions of files
873
825
874 $ hg co -C 0
826 $ hg co -C 0
875 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
827 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 $ echo changed >> file1
828 $ echo changed >> file1
877 $ hg rm file2
829 $ hg rm file2
878 $ hg update 1 --tool :other
830 $ hg update 1 --tool :other
879 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
831 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
880 $ status 2>&1 | tee $TESTTMP/other.status
832 $ status 2>&1 | tee $TESTTMP/other.status
881 --- status ---
833 --- status ---
882 file1: * (glob)
834 file1: * (glob)
883 C file2
835 C file2
884 C file3
836 C file3
885 --- resolve --list ---
837 --- resolve --list ---
886 R file1
838 R file1
887 R file2
839 R file2
888 --- debugmergestate ---
840 --- debugmergestate ---
889 * version 2 records
841 local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
890 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
842 other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
891 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
843 file: file1 (state "r")
892 labels:
893 local: working copy
894 other: destination
895 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
896 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
897 local path: file1 (flags "")
844 local path: file1 (flags "")
898 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
845 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
899 other path: file1 (node null)
846 other path: file1 (node 0000000000000000000000000000000000000000)
900 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
847 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
901 file: file2 (record type "C", state "r", hash null)
848 file: file2 (state "r")
902 local path: file2 (flags "")
849 local path: file2 (flags "")
903 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
850 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
904 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
851 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
852 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
905 *** file1 does not exist
853 *** file1 does not exist
906 --- file2 ---
854 --- file2 ---
907 2
855 2
908 changed
856 changed
909 --- file3 ---
857 --- file3 ---
910 3
858 3
911 changed1
859 changed1
912
860
913 Fail
861 Fail
914
862
915 $ hg co -C 0
863 $ hg co -C 0
916 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
864 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
917 $ echo changed >> file1
865 $ echo changed >> file1
918 $ hg rm file2
866 $ hg rm file2
919 $ hg update 1 --tool :fail
867 $ hg update 1 --tool :fail
920 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
868 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
921 use 'hg resolve' to retry unresolved file merges
869 use 'hg resolve' to retry unresolved file merges
922 [1]
870 [1]
923 $ status 2>&1 | tee $TESTTMP/fail.status
871 $ status 2>&1 | tee $TESTTMP/fail.status
924 --- status ---
872 --- status ---
925 A file1
873 A file1
926 C file2
874 C file2
927 C file3
875 C file3
928 --- resolve --list ---
876 --- resolve --list ---
929 U file1
877 U file1
930 U file2
878 U file2
931 --- debugmergestate ---
879 --- debugmergestate ---
932 * version 2 records
880 local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
933 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
881 other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
934 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
882 file: file1 (state "u")
935 labels:
936 local: working copy
937 other: destination
938 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
939 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
940 local path: file1 (flags "")
883 local path: file1 (flags "")
941 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
884 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
942 other path: file1 (node null)
885 other path: file1 (node 0000000000000000000000000000000000000000)
943 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
886 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
944 file: file2 (record type "C", state "u", hash null)
887 file: file2 (state "u")
945 local path: file2 (flags "")
888 local path: file2 (flags "")
946 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
889 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
947 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
890 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
891 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
948 --- file1 ---
892 --- file1 ---
949 1
893 1
950 changed
894 changed
951 --- file2 ---
895 --- file2 ---
952 2
896 2
953 changed
897 changed
954 --- file3 ---
898 --- file3 ---
955 3
899 3
956 changed1
900 changed1
957
901
958 Force prompts with no input
902 Force prompts with no input
959
903
960 $ hg co -C 0
904 $ hg co -C 0
961 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
905 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
962 $ echo changed >> file1
906 $ echo changed >> file1
963 $ hg rm file2
907 $ hg rm file2
964 $ hg update 1 --config ui.interactive=True --tool :prompt
908 $ hg update 1 --config ui.interactive=True --tool :prompt
965 file 'file1' was deleted in other [destination] but was modified in local [working copy].
909 file 'file1' was deleted in other [destination] but was modified in local [working copy].
966 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
910 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
967 What do you want to do?
911 What do you want to do?
968 file 'file2' was deleted in local [working copy] but was modified in other [destination].
912 file 'file2' was deleted in local [working copy] but was modified in other [destination].
969 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
913 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
970 What do you want to do?
914 What do you want to do?
971 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
915 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
972 use 'hg resolve' to retry unresolved file merges
916 use 'hg resolve' to retry unresolved file merges
973 [1]
917 [1]
974 $ status 2>&1 | tee $TESTTMP/prompt.status
918 $ status 2>&1 | tee $TESTTMP/prompt.status
975 --- status ---
919 --- status ---
976 A file1
920 A file1
977 C file2
921 C file2
978 C file3
922 C file3
979 --- resolve --list ---
923 --- resolve --list ---
980 U file1
924 U file1
981 U file2
925 U file2
982 --- debugmergestate ---
926 --- debugmergestate ---
983 * version 2 records
927 local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
984 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
928 other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
985 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
929 file: file1 (state "u")
986 labels:
987 local: working copy
988 other: destination
989 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
990 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
991 local path: file1 (flags "")
930 local path: file1 (flags "")
992 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
931 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
993 other path: file1 (node null)
932 other path: file1 (node 0000000000000000000000000000000000000000)
994 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
933 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
995 file: file2 (record type "C", state "u", hash null)
934 file: file2 (state "u")
996 local path: file2 (flags "")
935 local path: file2 (flags "")
997 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
936 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
998 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
937 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
938 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
999 --- file1 ---
939 --- file1 ---
1000 1
940 1
1001 changed
941 changed
1002 --- file2 ---
942 --- file2 ---
1003 2
943 2
1004 changed
944 changed
1005 --- file3 ---
945 --- file3 ---
1006 3
946 3
1007 changed1
947 changed1
1008 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
948 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
1009
949
1010 Choose to merge all files
950 Choose to merge all files
1011
951
1012 $ hg co -C 0
952 $ hg co -C 0
1013 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
953 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1014 $ echo changed >> file1
954 $ echo changed >> file1
1015 $ hg rm file2
955 $ hg rm file2
1016 $ hg update 1 --tool :merge3
956 $ hg update 1 --tool :merge3
1017 file 'file1' was deleted in other [destination] but was modified in local [working copy].
957 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1018 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
958 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1019 What do you want to do? u
959 What do you want to do? u
1020 file 'file2' was deleted in local [working copy] but was modified in other [destination].
960 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1021 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
961 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1022 What do you want to do? u
962 What do you want to do? u
1023 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
963 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
1024 use 'hg resolve' to retry unresolved file merges
964 use 'hg resolve' to retry unresolved file merges
1025 [1]
965 [1]
1026 $ status
966 $ status
1027 --- status ---
967 --- status ---
1028 A file1
968 A file1
1029 C file2
969 C file2
1030 C file3
970 C file3
1031 --- resolve --list ---
971 --- resolve --list ---
1032 U file1
972 U file1
1033 U file2
973 U file2
1034 --- debugmergestate ---
974 --- debugmergestate ---
1035 * version 2 records
975 local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
1036 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
976 other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
1037 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
977 file: file1 (state "u")
1038 labels:
1039 local: working copy
1040 other: destination
1041 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
1042 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
1043 local path: file1 (flags "")
978 local path: file1 (flags "")
1044 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
979 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
1045 other path: file1 (node null)
980 other path: file1 (node 0000000000000000000000000000000000000000)
1046 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
981 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
1047 file: file2 (record type "C", state "u", hash null)
982 file: file2 (state "u")
1048 local path: file2 (flags "")
983 local path: file2 (flags "")
1049 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
984 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
1050 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
985 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
986 extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
1051 --- file1 ---
987 --- file1 ---
1052 1
988 1
1053 changed
989 changed
1054 --- file2 ---
990 --- file2 ---
1055 2
991 2
1056 changed
992 changed
1057 --- file3 ---
993 --- file3 ---
1058 3
994 3
1059 changed1
995 changed1
1060
996
1061 Test transitions between different merge tools
997 Test transitions between different merge tools
1062
998
1063 $ testtransitions
999 $ testtransitions
1064 === :merge3 -> :local ===
1000 === :merge3 -> :local ===
1065 (no more unresolved files)
1001 (no more unresolved files)
1066 --- diff of status ---
1002 --- diff of status ---
1067 (status identical)
1003 (status identical)
1068
1004
1069 === :local -> :other ===
1005 === :local -> :other ===
1070 (no more unresolved files)
1006 (no more unresolved files)
1071 --- diff of status ---
1007 --- diff of status ---
1072 (status identical)
1008 (status identical)
1073
1009
1074 === :other -> :prompt ===
1010 === :other -> :prompt ===
1075 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1011 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1076 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1012 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1077 What do you want to do?
1013 What do you want to do?
1078 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1014 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1079 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1015 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1080 What do you want to do?
1016 What do you want to do?
1081 --- diff of status ---
1017 --- diff of status ---
1082 (status identical)
1018 (status identical)
1083
1019
1084 === :prompt -> :local ===
1020 === :prompt -> :local ===
1085 (no more unresolved files)
1021 (no more unresolved files)
1086 --- diff of status ---
1022 --- diff of status ---
1087 (status identical)
1023 (status identical)
1088
1024
1089 === :local -> :fail ===
1025 === :local -> :fail ===
1090 --- diff of status ---
1026 --- diff of status ---
1091 (status identical)
1027 (status identical)
1092
1028
1093 === :fail -> :other ===
1029 === :fail -> :other ===
1094 (no more unresolved files)
1030 (no more unresolved files)
1095 --- diff of status ---
1031 --- diff of status ---
1096 (status identical)
1032 (status identical)
1097
1033
1098 === :other -> :local ===
1034 === :other -> :local ===
1099 (no more unresolved files)
1035 (no more unresolved files)
1100 --- diff of status ---
1036 --- diff of status ---
1101 (status identical)
1037 (status identical)
1102
1038
1103 === :local -> :prompt ===
1039 === :local -> :prompt ===
1104 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1040 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1105 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1041 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1106 What do you want to do?
1042 What do you want to do?
1107 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1043 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1108 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1044 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1109 What do you want to do?
1045 What do you want to do?
1110 --- diff of status ---
1046 --- diff of status ---
1111 (status identical)
1047 (status identical)
1112
1048
1113 === :prompt -> :other ===
1049 === :prompt -> :other ===
1114 (no more unresolved files)
1050 (no more unresolved files)
1115 --- diff of status ---
1051 --- diff of status ---
1116 (status identical)
1052 (status identical)
1117
1053
1118 === :other -> :fail ===
1054 === :other -> :fail ===
1119 --- diff of status ---
1055 --- diff of status ---
1120 (status identical)
1056 (status identical)
1121
1057
1122 === :fail -> :prompt ===
1058 === :fail -> :prompt ===
1123 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1059 file 'file1' was deleted in other [destination] but was modified in local [working copy].
1124 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1060 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
1125 What do you want to do?
1061 What do you want to do?
1126 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1062 file 'file2' was deleted in local [working copy] but was modified in other [destination].
1127 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1063 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
1128 What do you want to do?
1064 What do you want to do?
1129 --- diff of status ---
1065 --- diff of status ---
1130 (status identical)
1066 (status identical)
1131
1067
1132 === :prompt -> :fail ===
1068 === :prompt -> :fail ===
1133 --- diff of status ---
1069 --- diff of status ---
1134 (status identical)
1070 (status identical)
1135
1071
1136 === :fail -> :local ===
1072 === :fail -> :local ===
1137 (no more unresolved files)
1073 (no more unresolved files)
1138 --- diff of status ---
1074 --- diff of status ---
1139 (status identical)
1075 (status identical)
1140
1076
@@ -1,525 +1,511 b''
1 #testcases abortcommand abortflag
1 #testcases abortcommand abortflag
2 #testcases continuecommand continueflag
2 #testcases continuecommand continueflag
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > rebase=
6 > rebase=
7 >
7 >
8 > [phases]
8 > [phases]
9 > publish=False
9 > publish=False
10 >
10 >
11 > [alias]
11 > [alias]
12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
13 > EOF
13 > EOF
14
14
15 #if abortflag
15 #if abortflag
16 $ cat >> $HGRCPATH <<EOF
16 $ cat >> $HGRCPATH <<EOF
17 > [alias]
17 > [alias]
18 > abort = rebase --abort
18 > abort = rebase --abort
19 > EOF
19 > EOF
20 #endif
20 #endif
21
21
22 #if continueflag
22 #if continueflag
23 $ cat >> $HGRCPATH <<EOF
23 $ cat >> $HGRCPATH <<EOF
24 > [alias]
24 > [alias]
25 > continue = rebase --continue
25 > continue = rebase --continue
26 > EOF
26 > EOF
27 #endif
27 #endif
28
28
29 $ hg init a
29 $ hg init a
30 $ cd a
30 $ cd a
31
31
32 $ touch .hg/rebasestate
32 $ touch .hg/rebasestate
33 $ hg sum
33 $ hg sum
34 parent: -1:000000000000 tip (empty repository)
34 parent: -1:000000000000 tip (empty repository)
35 branch: default
35 branch: default
36 commit: (clean)
36 commit: (clean)
37 update: (current)
37 update: (current)
38 abort: .hg/rebasestate is incomplete
38 abort: .hg/rebasestate is incomplete
39 [255]
39 [255]
40 $ rm .hg/rebasestate
40 $ rm .hg/rebasestate
41
41
42 $ echo c1 > common
42 $ echo c1 > common
43 $ hg add common
43 $ hg add common
44 $ hg ci -m C1
44 $ hg ci -m C1
45
45
46 $ echo c2 >> common
46 $ echo c2 >> common
47 $ hg ci -m C2
47 $ hg ci -m C2
48
48
49 $ echo c3 >> common
49 $ echo c3 >> common
50 $ hg ci -m C3
50 $ hg ci -m C3
51
51
52 $ hg up -q -C 1
52 $ hg up -q -C 1
53
53
54 $ echo l1 >> extra
54 $ echo l1 >> extra
55 $ hg add extra
55 $ hg add extra
56 $ hg ci -m L1
56 $ hg ci -m L1
57 created new head
57 created new head
58
58
59 $ sed -e 's/c2/l2/' common > common.new
59 $ sed -e 's/c2/l2/' common > common.new
60 $ mv common.new common
60 $ mv common.new common
61 $ hg ci -m L2
61 $ hg ci -m L2
62
62
63 $ hg phase --force --secret 2
63 $ hg phase --force --secret 2
64
64
65 $ hg tglog
65 $ hg tglog
66 @ 4:draft 'L2'
66 @ 4:draft 'L2'
67 |
67 |
68 o 3:draft 'L1'
68 o 3:draft 'L1'
69 |
69 |
70 | o 2:secret 'C3'
70 | o 2:secret 'C3'
71 |/
71 |/
72 o 1:draft 'C2'
72 o 1:draft 'C2'
73 |
73 |
74 o 0:draft 'C1'
74 o 0:draft 'C1'
75
75
76
76
77 Conflicting rebase:
77 Conflicting rebase:
78
78
79 $ hg rebase -s 3 -d 2
79 $ hg rebase -s 3 -d 2
80 rebasing 3:3163e20567cc "L1"
80 rebasing 3:3163e20567cc "L1"
81 rebasing 4:46f0b057b5c0 "L2" (tip)
81 rebasing 4:46f0b057b5c0 "L2" (tip)
82 merging common
82 merging common
83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
84 unresolved conflicts (see hg resolve, then hg rebase --continue)
84 unresolved conflicts (see hg resolve, then hg rebase --continue)
85 [1]
85 [1]
86
86
87 Insert unsupported advisory merge record:
87 Insert unsupported advisory merge record:
88
88
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
90 $ hg debugmergestate
90 $ hg debugmergestate
91 * version 2 records
91 local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 other (source): 46f0b057b5c061d276b91491c22151f78698abd2
93 other: 46f0b057b5c061d276b91491c22151f78698abd2
93 file: common (state "u")
94 labels:
95 local: dest
96 other: source
97 unrecognized entry: x advisory record
98 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
99 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
100 local path: common (flags "")
94 local path: common (flags "")
101 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
95 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
102 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
96 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
97 extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
103 $ hg resolve -l
98 $ hg resolve -l
104 U common
99 U common
105
100
106 Insert unsupported mandatory merge record:
101 Insert unsupported mandatory merge record:
107
102
108 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
103 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
109 $ hg debugmergestate
104 $ hg debugmergestate
110 * version 2 records
105 abort: unsupported merge state records: X
111 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
106 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
112 other: 46f0b057b5c061d276b91491c22151f78698abd2
107 [255]
113 labels:
114 local: dest
115 other: source
116 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
117 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
118 local path: common (flags "")
119 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
120 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
121 unrecognized entry: X mandatory record
122 $ hg resolve -l
108 $ hg resolve -l
123 abort: unsupported merge state records: X
109 abort: unsupported merge state records: X
124 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
110 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
125 [255]
111 [255]
126 $ hg resolve -ma
112 $ hg resolve -ma
127 abort: unsupported merge state records: X
113 abort: unsupported merge state records: X
128 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
114 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
129 [255]
115 [255]
130
116
131 Abort (should clear out unsupported merge state):
117 Abort (should clear out unsupported merge state):
132
118
133 #if abortcommand
119 #if abortcommand
134 when in dry-run mode
120 when in dry-run mode
135 $ hg abort --dry-run
121 $ hg abort --dry-run
136 rebase in progress, will be aborted
122 rebase in progress, will be aborted
137 #endif
123 #endif
138
124
139 $ hg abort
125 $ hg abort
140 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
126 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
141 rebase aborted
127 rebase aborted
142 $ hg debugmergestate
128 $ hg debugmergestate
143 no merge state found
129 no merge state found
144
130
145 $ hg tglog
131 $ hg tglog
146 @ 4:draft 'L2'
132 @ 4:draft 'L2'
147 |
133 |
148 o 3:draft 'L1'
134 o 3:draft 'L1'
149 |
135 |
150 | o 2:secret 'C3'
136 | o 2:secret 'C3'
151 |/
137 |/
152 o 1:draft 'C2'
138 o 1:draft 'C2'
153 |
139 |
154 o 0:draft 'C1'
140 o 0:draft 'C1'
155
141
156 Test safety for inconsistent rebase state, which may be created (and
142 Test safety for inconsistent rebase state, which may be created (and
157 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
143 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
158 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
144 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
159
145
160 $ hg rebase -s 3 -d 2
146 $ hg rebase -s 3 -d 2
161 rebasing 3:3163e20567cc "L1"
147 rebasing 3:3163e20567cc "L1"
162 rebasing 4:46f0b057b5c0 "L2" (tip)
148 rebasing 4:46f0b057b5c0 "L2" (tip)
163 merging common
149 merging common
164 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
150 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
165 unresolved conflicts (see hg resolve, then hg rebase --continue)
151 unresolved conflicts (see hg resolve, then hg rebase --continue)
166 [1]
152 [1]
167
153
168 $ mv .hg/rebasestate .hg/rebasestate.back
154 $ mv .hg/rebasestate .hg/rebasestate.back
169 $ hg update --quiet --clean 2
155 $ hg update --quiet --clean 2
170 $ hg --config extensions.mq= strip --quiet "destination()"
156 $ hg --config extensions.mq= strip --quiet "destination()"
171 $ mv .hg/rebasestate.back .hg/rebasestate
157 $ mv .hg/rebasestate.back .hg/rebasestate
172
158
173 $ hg continue
159 $ hg continue
174 abort: cannot continue inconsistent rebase
160 abort: cannot continue inconsistent rebase
175 (use "hg rebase --abort" to clear broken state)
161 (use "hg rebase --abort" to clear broken state)
176 [255]
162 [255]
177 $ hg summary | grep '^rebase: '
163 $ hg summary | grep '^rebase: '
178 rebase: (use "hg rebase --abort" to clear broken state)
164 rebase: (use "hg rebase --abort" to clear broken state)
179 $ hg abort
165 $ hg abort
180 rebase aborted (no revision is removed, only broken state is cleared)
166 rebase aborted (no revision is removed, only broken state is cleared)
181
167
182 $ cd ..
168 $ cd ..
183
169
184
170
185 Construct new repo:
171 Construct new repo:
186
172
187 $ hg init b
173 $ hg init b
188 $ cd b
174 $ cd b
189
175
190 $ echo a > a
176 $ echo a > a
191 $ hg ci -Am A
177 $ hg ci -Am A
192 adding a
178 adding a
193
179
194 $ echo b > b
180 $ echo b > b
195 $ hg ci -Am B
181 $ hg ci -Am B
196 adding b
182 adding b
197
183
198 $ echo c > c
184 $ echo c > c
199 $ hg ci -Am C
185 $ hg ci -Am C
200 adding c
186 adding c
201
187
202 $ hg up -q 0
188 $ hg up -q 0
203
189
204 $ echo b > b
190 $ echo b > b
205 $ hg ci -Am 'B bis'
191 $ hg ci -Am 'B bis'
206 adding b
192 adding b
207 created new head
193 created new head
208
194
209 $ echo c1 > c
195 $ echo c1 > c
210 $ hg ci -Am C1
196 $ hg ci -Am C1
211 adding c
197 adding c
212
198
213 $ hg phase --force --secret 1
199 $ hg phase --force --secret 1
214 $ hg phase --public 1
200 $ hg phase --public 1
215
201
216 Rebase and abort without generating new changesets:
202 Rebase and abort without generating new changesets:
217
203
218 $ hg tglog
204 $ hg tglog
219 @ 4:draft 'C1'
205 @ 4:draft 'C1'
220 |
206 |
221 o 3:draft 'B bis'
207 o 3:draft 'B bis'
222 |
208 |
223 | o 2:secret 'C'
209 | o 2:secret 'C'
224 | |
210 | |
225 | o 1:public 'B'
211 | o 1:public 'B'
226 |/
212 |/
227 o 0:public 'A'
213 o 0:public 'A'
228
214
229 $ hg rebase -b 4 -d 2
215 $ hg rebase -b 4 -d 2
230 rebasing 3:a6484957d6b9 "B bis"
216 rebasing 3:a6484957d6b9 "B bis"
231 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
217 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
232 rebasing 4:145842775fec "C1" (tip)
218 rebasing 4:145842775fec "C1" (tip)
233 merging c
219 merging c
234 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
220 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
235 unresolved conflicts (see hg resolve, then hg rebase --continue)
221 unresolved conflicts (see hg resolve, then hg rebase --continue)
236 [1]
222 [1]
237
223
238 $ hg tglog
224 $ hg tglog
239 % 4:draft 'C1'
225 % 4:draft 'C1'
240 |
226 |
241 o 3:draft 'B bis'
227 o 3:draft 'B bis'
242 |
228 |
243 | @ 2:secret 'C'
229 | @ 2:secret 'C'
244 | |
230 | |
245 | o 1:public 'B'
231 | o 1:public 'B'
246 |/
232 |/
247 o 0:public 'A'
233 o 0:public 'A'
248
234
249 $ hg rebase -a
235 $ hg rebase -a
250 rebase aborted
236 rebase aborted
251
237
252 $ hg tglog
238 $ hg tglog
253 @ 4:draft 'C1'
239 @ 4:draft 'C1'
254 |
240 |
255 o 3:draft 'B bis'
241 o 3:draft 'B bis'
256 |
242 |
257 | o 2:secret 'C'
243 | o 2:secret 'C'
258 | |
244 | |
259 | o 1:public 'B'
245 | o 1:public 'B'
260 |/
246 |/
261 o 0:public 'A'
247 o 0:public 'A'
262
248
263
249
264 $ cd ..
250 $ cd ..
265
251
266 rebase abort should not leave working copy in a merge state if tip-1 is public
252 rebase abort should not leave working copy in a merge state if tip-1 is public
267 (issue4082)
253 (issue4082)
268
254
269 $ hg init abortpublic
255 $ hg init abortpublic
270 $ cd abortpublic
256 $ cd abortpublic
271 $ echo a > a && hg ci -Aqm a
257 $ echo a > a && hg ci -Aqm a
272 $ hg book master
258 $ hg book master
273 $ hg book foo
259 $ hg book foo
274 $ echo b > b && hg ci -Aqm b
260 $ echo b > b && hg ci -Aqm b
275 $ hg up -q master
261 $ hg up -q master
276 $ echo c > c && hg ci -Aqm c
262 $ echo c > c && hg ci -Aqm c
277 $ hg phase -p -r .
263 $ hg phase -p -r .
278 $ hg up -q foo
264 $ hg up -q foo
279 $ echo C > c && hg ci -Aqm C
265 $ echo C > c && hg ci -Aqm C
280 $ hg log -G --template "{rev} {desc} {bookmarks}"
266 $ hg log -G --template "{rev} {desc} {bookmarks}"
281 @ 3 C foo
267 @ 3 C foo
282 |
268 |
283 | o 2 c master
269 | o 2 c master
284 | |
270 | |
285 o | 1 b
271 o | 1 b
286 |/
272 |/
287 o 0 a
273 o 0 a
288
274
289
275
290 $ hg rebase -d master -r foo
276 $ hg rebase -d master -r foo
291 rebasing 3:6c0f977a22d8 "C" (foo tip)
277 rebasing 3:6c0f977a22d8 "C" (foo tip)
292 merging c
278 merging c
293 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
279 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
294 unresolved conflicts (see hg resolve, then hg rebase --continue)
280 unresolved conflicts (see hg resolve, then hg rebase --continue)
295 [1]
281 [1]
296 $ hg abort
282 $ hg abort
297 rebase aborted
283 rebase aborted
298 $ hg log -G --template "{rev} {desc} {bookmarks}"
284 $ hg log -G --template "{rev} {desc} {bookmarks}"
299 @ 3 C foo
285 @ 3 C foo
300 |
286 |
301 | o 2 c master
287 | o 2 c master
302 | |
288 | |
303 o | 1 b
289 o | 1 b
304 |/
290 |/
305 o 0 a
291 o 0 a
306
292
307 $ cd ..
293 $ cd ..
308
294
309 Make sure we don't clobber changes in the working directory when the
295 Make sure we don't clobber changes in the working directory when the
310 user has somehow managed to update to a different revision (issue4009)
296 user has somehow managed to update to a different revision (issue4009)
311
297
312 $ hg init noupdate
298 $ hg init noupdate
313 $ cd noupdate
299 $ cd noupdate
314 $ hg book @
300 $ hg book @
315 $ echo original > a
301 $ echo original > a
316 $ hg add a
302 $ hg add a
317 $ hg commit -m a
303 $ hg commit -m a
318 $ echo x > b
304 $ echo x > b
319 $ hg add b
305 $ hg add b
320 $ hg commit -m b1
306 $ hg commit -m b1
321 $ hg up 0
307 $ hg up 0
322 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
308 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 (leaving bookmark @)
309 (leaving bookmark @)
324 $ hg book foo
310 $ hg book foo
325 $ echo y > b
311 $ echo y > b
326 $ hg add b
312 $ hg add b
327 $ hg commit -m b2
313 $ hg commit -m b2
328 created new head
314 created new head
329
315
330 $ hg rebase -d @ -b foo --tool=internal:fail
316 $ hg rebase -d @ -b foo --tool=internal:fail
331 rebasing 2:070cf4580bb5 "b2" (foo tip)
317 rebasing 2:070cf4580bb5 "b2" (foo tip)
332 unresolved conflicts (see hg resolve, then hg rebase --continue)
318 unresolved conflicts (see hg resolve, then hg rebase --continue)
333 [1]
319 [1]
334
320
335 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
321 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
336 $ hg up -C 0 # user does other stuff in the repo
322 $ hg up -C 0 # user does other stuff in the repo
337 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
338
324
339 $ mv rebasestate .hg/ # user upgrades to 2.7
325 $ mv rebasestate .hg/ # user upgrades to 2.7
340
326
341 $ echo new > a
327 $ echo new > a
342 $ hg up 1 # user gets an error saying to run hg rebase --abort
328 $ hg up 1 # user gets an error saying to run hg rebase --abort
343 abort: rebase in progress
329 abort: rebase in progress
344 (use 'hg rebase --continue' or 'hg rebase --abort')
330 (use 'hg rebase --continue' or 'hg rebase --abort')
345 [255]
331 [255]
346
332
347 $ cat a
333 $ cat a
348 new
334 new
349 $ hg abort
335 $ hg abort
350 rebase aborted
336 rebase aborted
351 $ cat a
337 $ cat a
352 new
338 new
353
339
354 $ cd ..
340 $ cd ..
355
341
356 test aborting an interrupted series (issue5084)
342 test aborting an interrupted series (issue5084)
357 $ hg init interrupted
343 $ hg init interrupted
358 $ cd interrupted
344 $ cd interrupted
359 $ touch base
345 $ touch base
360 $ hg add base
346 $ hg add base
361 $ hg commit -m base
347 $ hg commit -m base
362 $ touch a
348 $ touch a
363 $ hg add a
349 $ hg add a
364 $ hg commit -m a
350 $ hg commit -m a
365 $ echo 1 > a
351 $ echo 1 > a
366 $ hg commit -m 1
352 $ hg commit -m 1
367 $ touch b
353 $ touch b
368 $ hg add b
354 $ hg add b
369 $ hg commit -m b
355 $ hg commit -m b
370 $ echo 2 >> a
356 $ echo 2 >> a
371 $ hg commit -m c
357 $ hg commit -m c
372 $ touch d
358 $ touch d
373 $ hg add d
359 $ hg add d
374 $ hg commit -m d
360 $ hg commit -m d
375 $ hg co -q 1
361 $ hg co -q 1
376 $ hg rm a
362 $ hg rm a
377 $ hg commit -m no-a
363 $ hg commit -m no-a
378 created new head
364 created new head
379 $ hg co 0
365 $ hg co 0
380 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
366 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 $ hg log -G --template "{rev} {desc} {bookmarks}"
367 $ hg log -G --template "{rev} {desc} {bookmarks}"
382 o 6 no-a
368 o 6 no-a
383 |
369 |
384 | o 5 d
370 | o 5 d
385 | |
371 | |
386 | o 4 c
372 | o 4 c
387 | |
373 | |
388 | o 3 b
374 | o 3 b
389 | |
375 | |
390 | o 2 1
376 | o 2 1
391 |/
377 |/
392 o 1 a
378 o 1 a
393 |
379 |
394 @ 0 base
380 @ 0 base
395
381
396 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
382 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
397 rebasing 3:3a71550954f1 "b"
383 rebasing 3:3a71550954f1 "b"
398 rebasing 4:e80b69427d80 "c"
384 rebasing 4:e80b69427d80 "c"
399 abort: ^C
385 abort: ^C
400 [255]
386 [255]
401
387
402 New operations are blocked with the correct state message
388 New operations are blocked with the correct state message
403
389
404 $ find .hg -name '*state' -prune | sort
390 $ find .hg -name '*state' -prune | sort
405 .hg/dirstate
391 .hg/dirstate
406 .hg/merge/state
392 .hg/merge/state
407 .hg/rebasestate
393 .hg/rebasestate
408 .hg/undo.backup.dirstate
394 .hg/undo.backup.dirstate
409 .hg/undo.dirstate
395 .hg/undo.dirstate
410 .hg/updatestate
396 .hg/updatestate
411
397
412 $ hg rebase -s 3 -d tip
398 $ hg rebase -s 3 -d tip
413 abort: rebase in progress
399 abort: rebase in progress
414 (use 'hg rebase --continue' or 'hg rebase --abort')
400 (use 'hg rebase --continue' or 'hg rebase --abort')
415 [255]
401 [255]
416 $ hg up .
402 $ hg up .
417 abort: rebase in progress
403 abort: rebase in progress
418 (use 'hg rebase --continue' or 'hg rebase --abort')
404 (use 'hg rebase --continue' or 'hg rebase --abort')
419 [255]
405 [255]
420 $ hg up -C .
406 $ hg up -C .
421 abort: rebase in progress
407 abort: rebase in progress
422 (use 'hg rebase --continue' or 'hg rebase --abort')
408 (use 'hg rebase --continue' or 'hg rebase --abort')
423 [255]
409 [255]
424
410
425 $ hg graft 3
411 $ hg graft 3
426 abort: rebase in progress
412 abort: rebase in progress
427 (use 'hg rebase --continue' or 'hg rebase --abort')
413 (use 'hg rebase --continue' or 'hg rebase --abort')
428 [255]
414 [255]
429
415
430 $ hg abort
416 $ hg abort
431 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
417 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
432 rebase aborted
418 rebase aborted
433 $ hg log -G --template "{rev} {desc} {bookmarks}"
419 $ hg log -G --template "{rev} {desc} {bookmarks}"
434 o 6 no-a
420 o 6 no-a
435 |
421 |
436 | o 5 d
422 | o 5 d
437 | |
423 | |
438 | o 4 c
424 | o 4 c
439 | |
425 | |
440 | o 3 b
426 | o 3 b
441 | |
427 | |
442 | o 2 1
428 | o 2 1
443 |/
429 |/
444 o 1 a
430 o 1 a
445 |
431 |
446 @ 0 base
432 @ 0 base
447
433
448 $ hg summary
434 $ hg summary
449 parent: 0:df4f53cec30a
435 parent: 0:df4f53cec30a
450 base
436 base
451 branch: default
437 branch: default
452 commit: (clean)
438 commit: (clean)
453 update: 6 new changesets (update)
439 update: 6 new changesets (update)
454 phases: 7 draft
440 phases: 7 draft
455
441
456 $ cd ..
442 $ cd ..
457 On the other hand, make sure we *do* clobber changes whenever we
443 On the other hand, make sure we *do* clobber changes whenever we
458 haven't somehow managed to update the repo to a different revision
444 haven't somehow managed to update the repo to a different revision
459 during a rebase (issue4661)
445 during a rebase (issue4661)
460
446
461 $ hg ini yesupdate
447 $ hg ini yesupdate
462 $ cd yesupdate
448 $ cd yesupdate
463 $ echo "initial data" > foo.txt
449 $ echo "initial data" > foo.txt
464 $ hg add
450 $ hg add
465 adding foo.txt
451 adding foo.txt
466 $ hg ci -m "initial checkin"
452 $ hg ci -m "initial checkin"
467 $ echo "change 1" > foo.txt
453 $ echo "change 1" > foo.txt
468 $ hg ci -m "change 1"
454 $ hg ci -m "change 1"
469 $ hg up 0
455 $ hg up 0
470 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 $ echo "conflicting change 1" > foo.txt
457 $ echo "conflicting change 1" > foo.txt
472 $ hg ci -m "conflicting 1"
458 $ hg ci -m "conflicting 1"
473 created new head
459 created new head
474 $ echo "conflicting change 2" > foo.txt
460 $ echo "conflicting change 2" > foo.txt
475 $ hg ci -m "conflicting 2"
461 $ hg ci -m "conflicting 2"
476
462
477 $ hg rebase -d 1 --tool 'internal:fail'
463 $ hg rebase -d 1 --tool 'internal:fail'
478 rebasing 2:e4ea5cdc9789 "conflicting 1"
464 rebasing 2:e4ea5cdc9789 "conflicting 1"
479 unresolved conflicts (see hg resolve, then hg rebase --continue)
465 unresolved conflicts (see hg resolve, then hg rebase --continue)
480 [1]
466 [1]
481 $ hg abort
467 $ hg abort
482 rebase aborted
468 rebase aborted
483 $ hg summary
469 $ hg summary
484 parent: 3:b16646383533 tip
470 parent: 3:b16646383533 tip
485 conflicting 2
471 conflicting 2
486 branch: default
472 branch: default
487 commit: (clean)
473 commit: (clean)
488 update: 1 new changesets, 2 branch heads (merge)
474 update: 1 new changesets, 2 branch heads (merge)
489 phases: 4 draft
475 phases: 4 draft
490 $ cd ..
476 $ cd ..
491
477
492 test aborting a rebase succeeds after rebasing with skipped commits onto a
478 test aborting a rebase succeeds after rebasing with skipped commits onto a
493 public changeset (issue4896)
479 public changeset (issue4896)
494
480
495 $ hg init succeedonpublic
481 $ hg init succeedonpublic
496 $ cd succeedonpublic
482 $ cd succeedonpublic
497 $ echo 'content' > root
483 $ echo 'content' > root
498 $ hg commit -A -m 'root' -q
484 $ hg commit -A -m 'root' -q
499
485
500 set up public branch
486 set up public branch
501 $ echo 'content' > disappear
487 $ echo 'content' > disappear
502 $ hg commit -A -m 'disappear public' -q
488 $ hg commit -A -m 'disappear public' -q
503 commit will cause merge conflict on rebase
489 commit will cause merge conflict on rebase
504 $ echo '' > root
490 $ echo '' > root
505 $ hg commit -m 'remove content public' -q
491 $ hg commit -m 'remove content public' -q
506 $ hg phase --public
492 $ hg phase --public
507
493
508 setup the draft branch that will be rebased onto public commit
494 setup the draft branch that will be rebased onto public commit
509 $ hg up -r 0 -q
495 $ hg up -r 0 -q
510 $ echo 'content' > disappear
496 $ echo 'content' > disappear
511 commit will disappear
497 commit will disappear
512 $ hg commit -A -m 'disappear draft' -q
498 $ hg commit -A -m 'disappear draft' -q
513 $ echo 'addedcontADDEDentadded' > root
499 $ echo 'addedcontADDEDentadded' > root
514 commit will cause merge conflict on rebase
500 commit will cause merge conflict on rebase
515 $ hg commit -m 'add content draft' -q
501 $ hg commit -m 'add content draft' -q
516
502
517 $ hg rebase -d 'public()' --tool :merge -q
503 $ hg rebase -d 'public()' --tool :merge -q
518 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
504 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
519 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
505 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
520 unresolved conflicts (see hg resolve, then hg rebase --continue)
506 unresolved conflicts (see hg resolve, then hg rebase --continue)
521 [1]
507 [1]
522 $ hg abort
508 $ hg abort
523 rebase aborted
509 rebase aborted
524 $ cd ..
510 $ cd ..
525
511
@@ -1,803 +1,795 b''
1 test that a commit clears the merge state.
1 test that a commit clears the merge state.
2
2
3 $ hg init repo
3 $ hg init repo
4 $ cd repo
4 $ cd repo
5
5
6 $ echo foo > file1
6 $ echo foo > file1
7 $ echo foo > file2
7 $ echo foo > file2
8 $ hg commit -Am 'add files'
8 $ hg commit -Am 'add files'
9 adding file1
9 adding file1
10 adding file2
10 adding file2
11
11
12 $ echo bar >> file1
12 $ echo bar >> file1
13 $ echo bar >> file2
13 $ echo bar >> file2
14 $ hg commit -Am 'append bar to files'
14 $ hg commit -Am 'append bar to files'
15
15
16 create a second head with conflicting edits
16 create a second head with conflicting edits
17
17
18 $ hg up -C 0
18 $ hg up -C 0
19 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ echo baz >> file1
20 $ echo baz >> file1
21 $ echo baz >> file2
21 $ echo baz >> file2
22 $ hg commit -Am 'append baz to files'
22 $ hg commit -Am 'append baz to files'
23 created new head
23 created new head
24
24
25 create a third head with no conflicting edits
25 create a third head with no conflicting edits
26 $ hg up -qC 0
26 $ hg up -qC 0
27 $ echo foo > file3
27 $ echo foo > file3
28 $ hg commit -Am 'add non-conflicting file'
28 $ hg commit -Am 'add non-conflicting file'
29 adding file3
29 adding file3
30 created new head
30 created new head
31
31
32 failing merge
32 failing merge
33
33
34 $ hg up -qC 2
34 $ hg up -qC 2
35 $ hg merge --tool=internal:fail 1
35 $ hg merge --tool=internal:fail 1
36 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
36 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
37 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
37 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
38 [1]
38 [1]
39
39
40 resolve -l should contain unresolved entries
40 resolve -l should contain unresolved entries
41
41
42 $ hg resolve -l
42 $ hg resolve -l
43 U file1
43 U file1
44 U file2
44 U file2
45
45
46 $ hg resolve -l --no-status
46 $ hg resolve -l --no-status
47 file1
47 file1
48 file2
48 file2
49
49
50 resolving an unknown path should emit a warning, but not for -l
50 resolving an unknown path should emit a warning, but not for -l
51
51
52 $ hg resolve -m does-not-exist
52 $ hg resolve -m does-not-exist
53 arguments do not match paths that need resolving
53 arguments do not match paths that need resolving
54 $ hg resolve -l does-not-exist
54 $ hg resolve -l does-not-exist
55
55
56 tell users how they could have used resolve
56 tell users how they could have used resolve
57
57
58 $ mkdir nested
58 $ mkdir nested
59 $ cd nested
59 $ cd nested
60 $ hg resolve -m file1
60 $ hg resolve -m file1
61 arguments do not match paths that need resolving
61 arguments do not match paths that need resolving
62 (try: hg resolve -m path:file1)
62 (try: hg resolve -m path:file1)
63 $ hg resolve -m file1 filez
63 $ hg resolve -m file1 filez
64 arguments do not match paths that need resolving
64 arguments do not match paths that need resolving
65 (try: hg resolve -m path:file1 path:filez)
65 (try: hg resolve -m path:file1 path:filez)
66 $ hg resolve -m path:file1 path:filez
66 $ hg resolve -m path:file1 path:filez
67 $ hg resolve -l
67 $ hg resolve -l
68 R file1
68 R file1
69 U file2
69 U file2
70 $ hg resolve -l --config ui.relative-paths=yes
70 $ hg resolve -l --config ui.relative-paths=yes
71 R ../file1
71 R ../file1
72 U ../file2
72 U ../file2
73 $ hg resolve --re-merge filez file2
73 $ hg resolve --re-merge filez file2
74 arguments do not match paths that need resolving
74 arguments do not match paths that need resolving
75 (try: hg resolve --re-merge path:filez path:file2)
75 (try: hg resolve --re-merge path:filez path:file2)
76 $ hg resolve -m filez file2
76 $ hg resolve -m filez file2
77 arguments do not match paths that need resolving
77 arguments do not match paths that need resolving
78 (try: hg resolve -m path:filez path:file2)
78 (try: hg resolve -m path:filez path:file2)
79 $ hg resolve -m path:filez path:file2
79 $ hg resolve -m path:filez path:file2
80 (no more unresolved files)
80 (no more unresolved files)
81 $ hg resolve -l
81 $ hg resolve -l
82 R file1
82 R file1
83 R file2
83 R file2
84
84
85 cleanup
85 cleanup
86 $ hg resolve -u
86 $ hg resolve -u
87 $ cd ..
87 $ cd ..
88 $ rmdir nested
88 $ rmdir nested
89
89
90 don't allow marking or unmarking driver-resolved files
90 don't allow marking or unmarking driver-resolved files
91
91
92 $ cat > $TESTTMP/markdriver.py << EOF
92 $ cat > $TESTTMP/markdriver.py << EOF
93 > '''mark and unmark files as driver-resolved'''
93 > '''mark and unmark files as driver-resolved'''
94 > from mercurial import (
94 > from mercurial import (
95 > merge,
95 > merge,
96 > pycompat,
96 > pycompat,
97 > registrar,
97 > registrar,
98 > scmutil,
98 > scmutil,
99 > )
99 > )
100 > cmdtable = {}
100 > cmdtable = {}
101 > command = registrar.command(cmdtable)
101 > command = registrar.command(cmdtable)
102 > @command(b'markdriver',
102 > @command(b'markdriver',
103 > [(b'u', b'unmark', None, b'')],
103 > [(b'u', b'unmark', None, b'')],
104 > b'FILE...')
104 > b'FILE...')
105 > def markdriver(ui, repo, *pats, **opts):
105 > def markdriver(ui, repo, *pats, **opts):
106 > wlock = repo.wlock()
106 > wlock = repo.wlock()
107 > opts = pycompat.byteskwargs(opts)
107 > opts = pycompat.byteskwargs(opts)
108 > try:
108 > try:
109 > ms = merge.mergestate.read(repo)
109 > ms = merge.mergestate.read(repo)
110 > m = scmutil.match(repo[None], pats, opts)
110 > m = scmutil.match(repo[None], pats, opts)
111 > for f in ms:
111 > for f in ms:
112 > if not m(f):
112 > if not m(f):
113 > continue
113 > continue
114 > if not opts[b'unmark']:
114 > if not opts[b'unmark']:
115 > ms.mark(f, b'd')
115 > ms.mark(f, b'd')
116 > else:
116 > else:
117 > ms.mark(f, b'u')
117 > ms.mark(f, b'u')
118 > ms.commit()
118 > ms.commit()
119 > finally:
119 > finally:
120 > wlock.release()
120 > wlock.release()
121 > EOF
121 > EOF
122 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver file1
122 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver file1
123 $ hg resolve --list
123 $ hg resolve --list
124 D file1
124 D file1
125 U file2
125 U file2
126 $ hg resolve --mark file1
126 $ hg resolve --mark file1
127 not marking file1 as it is driver-resolved
127 not marking file1 as it is driver-resolved
128 this should not print out file1
128 this should not print out file1
129 $ hg resolve --mark --all
129 $ hg resolve --mark --all
130 (no more unresolved files -- run "hg resolve --all" to conclude)
130 (no more unresolved files -- run "hg resolve --all" to conclude)
131 $ hg resolve --mark 'glob:file*'
131 $ hg resolve --mark 'glob:file*'
132 (no more unresolved files -- run "hg resolve --all" to conclude)
132 (no more unresolved files -- run "hg resolve --all" to conclude)
133 $ hg resolve --list
133 $ hg resolve --list
134 D file1
134 D file1
135 R file2
135 R file2
136 $ hg resolve --unmark file1
136 $ hg resolve --unmark file1
137 not unmarking file1 as it is driver-resolved
137 not unmarking file1 as it is driver-resolved
138 (no more unresolved files -- run "hg resolve --all" to conclude)
138 (no more unresolved files -- run "hg resolve --all" to conclude)
139 $ hg resolve --unmark --all
139 $ hg resolve --unmark --all
140 $ hg resolve --list
140 $ hg resolve --list
141 D file1
141 D file1
142 U file2
142 U file2
143 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver --unmark file1
143 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver --unmark file1
144 $ hg resolve --list
144 $ hg resolve --list
145 U file1
145 U file1
146 U file2
146 U file2
147
147
148 resolve the failure
148 resolve the failure
149
149
150 $ echo resolved > file1
150 $ echo resolved > file1
151 $ hg resolve -m file1
151 $ hg resolve -m file1
152
152
153 resolve -l should show resolved file as resolved
153 resolve -l should show resolved file as resolved
154
154
155 $ hg resolve -l
155 $ hg resolve -l
156 R file1
156 R file1
157 U file2
157 U file2
158
158
159 $ hg resolve -l -Tjson
159 $ hg resolve -l -Tjson
160 [
160 [
161 {
161 {
162 "mergestatus": "R",
162 "mergestatus": "R",
163 "path": "file1"
163 "path": "file1"
164 },
164 },
165 {
165 {
166 "mergestatus": "U",
166 "mergestatus": "U",
167 "path": "file2"
167 "path": "file2"
168 }
168 }
169 ]
169 ]
170
170
171 $ hg resolve -l -T '{path} {mergestatus} {status} {p1rev} {p2rev}\n'
171 $ hg resolve -l -T '{path} {mergestatus} {status} {p1rev} {p2rev}\n'
172 file1 R M 2 1
172 file1 R M 2 1
173 file2 U M 2 1
173 file2 U M 2 1
174
174
175 resolve -m without paths should mark all resolved
175 resolve -m without paths should mark all resolved
176
176
177 $ hg resolve -m
177 $ hg resolve -m
178 (no more unresolved files)
178 (no more unresolved files)
179 $ hg commit -m 'resolved'
179 $ hg commit -m 'resolved'
180
180
181 resolve -l should be empty after commit
181 resolve -l should be empty after commit
182
182
183 $ hg resolve -l
183 $ hg resolve -l
184
184
185 $ hg resolve -l -Tjson
185 $ hg resolve -l -Tjson
186 [
186 [
187 ]
187 ]
188
188
189 resolve --all should abort when no merge in progress
189 resolve --all should abort when no merge in progress
190
190
191 $ hg resolve --all
191 $ hg resolve --all
192 abort: resolve command not applicable when not merging
192 abort: resolve command not applicable when not merging
193 [255]
193 [255]
194
194
195 resolve -m should abort when no merge in progress
195 resolve -m should abort when no merge in progress
196
196
197 $ hg resolve -m
197 $ hg resolve -m
198 abort: resolve command not applicable when not merging
198 abort: resolve command not applicable when not merging
199 [255]
199 [255]
200
200
201 can not update or merge when there are unresolved conflicts
201 can not update or merge when there are unresolved conflicts
202
202
203 $ hg up -qC 0
203 $ hg up -qC 0
204 $ echo quux >> file1
204 $ echo quux >> file1
205 $ hg up 1
205 $ hg up 1
206 merging file1
206 merging file1
207 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
207 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
208 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
208 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
209 use 'hg resolve' to retry unresolved file merges
209 use 'hg resolve' to retry unresolved file merges
210 [1]
210 [1]
211 $ hg up 0
211 $ hg up 0
212 abort: outstanding merge conflicts
212 abort: outstanding merge conflicts
213 (use 'hg resolve' to resolve)
213 (use 'hg resolve' to resolve)
214 [255]
214 [255]
215 $ hg merge 2
215 $ hg merge 2
216 abort: outstanding merge conflicts
216 abort: outstanding merge conflicts
217 (use 'hg resolve' to resolve)
217 (use 'hg resolve' to resolve)
218 [255]
218 [255]
219 $ hg merge --force 2
219 $ hg merge --force 2
220 abort: outstanding merge conflicts
220 abort: outstanding merge conflicts
221 (use 'hg resolve' to resolve)
221 (use 'hg resolve' to resolve)
222 [255]
222 [255]
223
223
224 set up conflict-free merge
224 set up conflict-free merge
225
225
226 $ hg up -qC 3
226 $ hg up -qC 3
227 $ hg merge 1
227 $ hg merge 1
228 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
229 (branch merge, don't forget to commit)
229 (branch merge, don't forget to commit)
230
230
231 resolve --all should do nothing in merge without conflicts
231 resolve --all should do nothing in merge without conflicts
232 $ hg resolve --all
232 $ hg resolve --all
233 (no more unresolved files)
233 (no more unresolved files)
234
234
235 resolve -m should do nothing in merge without conflicts
235 resolve -m should do nothing in merge without conflicts
236
236
237 $ hg resolve -m
237 $ hg resolve -m
238 (no more unresolved files)
238 (no more unresolved files)
239
239
240 get back to conflicting state
240 get back to conflicting state
241
241
242 $ hg up -qC 2
242 $ hg up -qC 2
243 $ hg merge --tool=internal:fail 1
243 $ hg merge --tool=internal:fail 1
244 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
244 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
245 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
245 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
246 [1]
246 [1]
247
247
248 resolve without arguments should suggest --all
248 resolve without arguments should suggest --all
249 $ hg resolve
249 $ hg resolve
250 abort: no files or directories specified
250 abort: no files or directories specified
251 (use --all to re-merge all unresolved files)
251 (use --all to re-merge all unresolved files)
252 [255]
252 [255]
253
253
254 resolve --all should re-merge all unresolved files
254 resolve --all should re-merge all unresolved files
255 $ hg resolve --all
255 $ hg resolve --all
256 merging file1
256 merging file1
257 merging file2
257 merging file2
258 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
258 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
259 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
259 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
260 [1]
260 [1]
261 $ cat file1.orig
261 $ cat file1.orig
262 foo
262 foo
263 baz
263 baz
264 $ cat file2.orig
264 $ cat file2.orig
265 foo
265 foo
266 baz
266 baz
267
267
268 .orig files should exists where specified
268 .orig files should exists where specified
269 $ hg resolve --all --verbose --config 'ui.origbackuppath=.hg/origbackups'
269 $ hg resolve --all --verbose --config 'ui.origbackuppath=.hg/origbackups'
270 merging file1
270 merging file1
271 creating directory: $TESTTMP/repo/.hg/origbackups
271 creating directory: $TESTTMP/repo/.hg/origbackups
272 merging file2
272 merging file2
273 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
273 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
274 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
274 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
275 [1]
275 [1]
276 $ ls .hg/origbackups
276 $ ls .hg/origbackups
277 file1
277 file1
278 file2
278 file2
279 $ grep '<<<' file1 > /dev/null
279 $ grep '<<<' file1 > /dev/null
280 $ grep '<<<' file2 > /dev/null
280 $ grep '<<<' file2 > /dev/null
281
281
282 resolve <file> should re-merge file
282 resolve <file> should re-merge file
283 $ echo resolved > file1
283 $ echo resolved > file1
284 $ hg resolve -q file1
284 $ hg resolve -q file1
285 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
285 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
286 [1]
286 [1]
287 $ grep '<<<' file1 > /dev/null
287 $ grep '<<<' file1 > /dev/null
288
288
289 test .orig behavior with resolve
289 test .orig behavior with resolve
290
290
291 $ hg resolve -q file1 --tool "sh -c 'f --dump \"$TESTTMP/repo/file1.orig\"'"
291 $ hg resolve -q file1 --tool "sh -c 'f --dump \"$TESTTMP/repo/file1.orig\"'"
292 $TESTTMP/repo/file1.orig:
292 $TESTTMP/repo/file1.orig:
293 >>>
293 >>>
294 foo
294 foo
295 baz
295 baz
296 <<<
296 <<<
297
297
298 resolve <file> should do nothing if 'file' was marked resolved
298 resolve <file> should do nothing if 'file' was marked resolved
299 $ echo resolved > file1
299 $ echo resolved > file1
300 $ hg resolve -m file1
300 $ hg resolve -m file1
301 $ hg resolve -q file1
301 $ hg resolve -q file1
302 $ cat file1
302 $ cat file1
303 resolved
303 resolved
304
304
305 insert unsupported advisory merge record
305 insert unsupported advisory merge record
306
306
307 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
307 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
308 $ hg debugmergestate
308 $ hg debugmergestate
309 * version 2 records
309 local (working copy): 57653b9f834a4493f7240b0681efcb9ae7cab745
310 local: 57653b9f834a4493f7240b0681efcb9ae7cab745
310 other (merge rev): dc77451844e37f03f5c559e3b8529b2b48d381d1
311 other: dc77451844e37f03f5c559e3b8529b2b48d381d1
311 file: file1 (state "r")
312 labels:
313 local: working copy
314 other: merge rev
315 unrecognized entry: x advisory record
316 file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
317 file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
318 local path: file1 (flags "")
312 local path: file1 (flags "")
319 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
313 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
320 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
314 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
321 file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
315 extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
322 file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
316 file: file2 (state "u")
323 local path: file2 (flags "")
317 local path: file2 (flags "")
324 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
318 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
325 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
319 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
320 extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
326 $ hg resolve -l
321 $ hg resolve -l
327 R file1
322 R file1
328 U file2
323 U file2
329
324
325 test json output
326
327 $ hg debugmergestate -T json
328 [
329 {
330 "commits": [{"label": "working copy", "name": "local", "node": "57653b9f834a4493f7240b0681efcb9ae7cab745"}, {"label": "merge rev", "name": "other", "node": "dc77451844e37f03f5c559e3b8529b2b48d381d1"}],
331 "files": [{"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file1", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "60b27f004e454aca81b0480209cce5081ec52390", "local_path": "file1", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file1", "path": "file1", "state": "r"}, {"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file2", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523", "local_path": "file2", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file2", "path": "file2", "state": "u"}]
332 }
333 ]
334
335
330 insert unsupported mandatory merge record
336 insert unsupported mandatory merge record
331
337
332 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
338 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
333 $ hg debugmergestate
339 $ hg debugmergestate
334 * version 2 records
340 abort: unsupported merge state records: X
335 local: 57653b9f834a4493f7240b0681efcb9ae7cab745
341 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
336 other: dc77451844e37f03f5c559e3b8529b2b48d381d1
342 [255]
337 labels:
338 local: working copy
339 other: merge rev
340 file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
341 file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
342 local path: file1 (flags "")
343 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
344 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
345 file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
346 file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
347 local path: file2 (flags "")
348 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
349 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
350 unrecognized entry: X mandatory record
351 $ hg resolve -l
343 $ hg resolve -l
352 abort: unsupported merge state records: X
344 abort: unsupported merge state records: X
353 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
345 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
354 [255]
346 [255]
355 $ hg resolve -ma
347 $ hg resolve -ma
356 abort: unsupported merge state records: X
348 abort: unsupported merge state records: X
357 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
349 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
358 [255]
350 [255]
359 $ hg summary
351 $ hg summary
360 warning: merge state has unsupported record types: X
352 warning: merge state has unsupported record types: X
361 parent: 2:57653b9f834a
353 parent: 2:57653b9f834a
362 append baz to files
354 append baz to files
363 parent: 1:dc77451844e3
355 parent: 1:dc77451844e3
364 append bar to files
356 append bar to files
365 branch: default
357 branch: default
366 commit: 2 modified, 2 unknown (merge)
358 commit: 2 modified, 2 unknown (merge)
367 update: 2 new changesets (update)
359 update: 2 new changesets (update)
368 phases: 5 draft
360 phases: 5 draft
369
361
370 update --clean shouldn't abort on unsupported records
362 update --clean shouldn't abort on unsupported records
371
363
372 $ hg up -qC 1
364 $ hg up -qC 1
373 $ hg debugmergestate
365 $ hg debugmergestate
374 no merge state found
366 no merge state found
375
367
376 test crashed merge with empty mergestate
368 test crashed merge with empty mergestate
377
369
378 $ mkdir .hg/merge
370 $ mkdir .hg/merge
379 $ touch .hg/merge/state
371 $ touch .hg/merge/state
380
372
381 resolve -l should be empty
373 resolve -l should be empty
382
374
383 $ hg resolve -l
375 $ hg resolve -l
384
376
385 resolve -m can be configured to look for remaining conflict markers
377 resolve -m can be configured to look for remaining conflict markers
386 $ hg up -qC 2
378 $ hg up -qC 2
387 $ hg merge -q --tool=internal:merge 1
379 $ hg merge -q --tool=internal:merge 1
388 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
380 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
389 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
381 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
390 [1]
382 [1]
391 $ hg resolve -l
383 $ hg resolve -l
392 U file1
384 U file1
393 U file2
385 U file2
394 $ echo 'remove markers' > file1
386 $ echo 'remove markers' > file1
395 $ hg --config commands.resolve.mark-check=abort resolve -m
387 $ hg --config commands.resolve.mark-check=abort resolve -m
396 warning: the following files still have conflict markers:
388 warning: the following files still have conflict markers:
397 file2
389 file2
398 abort: conflict markers detected
390 abort: conflict markers detected
399 (use --all to mark anyway)
391 (use --all to mark anyway)
400 [255]
392 [255]
401 $ hg resolve -l
393 $ hg resolve -l
402 U file1
394 U file1
403 U file2
395 U file2
404 Try with --all from the hint
396 Try with --all from the hint
405 $ hg --config commands.resolve.mark-check=abort resolve -m --all
397 $ hg --config commands.resolve.mark-check=abort resolve -m --all
406 warning: the following files still have conflict markers:
398 warning: the following files still have conflict markers:
407 file2
399 file2
408 (no more unresolved files)
400 (no more unresolved files)
409 $ hg resolve -l
401 $ hg resolve -l
410 R file1
402 R file1
411 R file2
403 R file2
412 Test option value 'warn'
404 Test option value 'warn'
413 $ hg resolve --unmark
405 $ hg resolve --unmark
414 $ hg resolve -l
406 $ hg resolve -l
415 U file1
407 U file1
416 U file2
408 U file2
417 $ hg --config commands.resolve.mark-check=warn resolve -m
409 $ hg --config commands.resolve.mark-check=warn resolve -m
418 warning: the following files still have conflict markers:
410 warning: the following files still have conflict markers:
419 file2
411 file2
420 (no more unresolved files)
412 (no more unresolved files)
421 $ hg resolve -l
413 $ hg resolve -l
422 R file1
414 R file1
423 R file2
415 R file2
424 If the file is already marked as resolved, we don't warn about it
416 If the file is already marked as resolved, we don't warn about it
425 $ hg resolve --unmark file1
417 $ hg resolve --unmark file1
426 $ hg resolve -l
418 $ hg resolve -l
427 U file1
419 U file1
428 R file2
420 R file2
429 $ hg --config commands.resolve.mark-check=warn resolve -m
421 $ hg --config commands.resolve.mark-check=warn resolve -m
430 (no more unresolved files)
422 (no more unresolved files)
431 $ hg resolve -l
423 $ hg resolve -l
432 R file1
424 R file1
433 R file2
425 R file2
434 If the user passes an invalid value, we treat it as 'none'.
426 If the user passes an invalid value, we treat it as 'none'.
435 $ hg resolve --unmark
427 $ hg resolve --unmark
436 $ hg resolve -l
428 $ hg resolve -l
437 U file1
429 U file1
438 U file2
430 U file2
439 $ hg --config commands.resolve.mark-check=nope resolve -m
431 $ hg --config commands.resolve.mark-check=nope resolve -m
440 (no more unresolved files)
432 (no more unresolved files)
441 $ hg resolve -l
433 $ hg resolve -l
442 R file1
434 R file1
443 R file2
435 R file2
444 Test explicitly setting the option to 'none'
436 Test explicitly setting the option to 'none'
445 $ hg resolve --unmark
437 $ hg resolve --unmark
446 $ hg resolve -l
438 $ hg resolve -l
447 U file1
439 U file1
448 U file2
440 U file2
449 $ hg --config commands.resolve.mark-check=none resolve -m
441 $ hg --config commands.resolve.mark-check=none resolve -m
450 (no more unresolved files)
442 (no more unresolved files)
451 $ hg resolve -l
443 $ hg resolve -l
452 R file1
444 R file1
453 R file2
445 R file2
454 Test with marking an explicit file as resolved, this should not abort (since
446 Test with marking an explicit file as resolved, this should not abort (since
455 there's no --force flag, we have no way of combining --all with a filename)
447 there's no --force flag, we have no way of combining --all with a filename)
456 $ hg resolve --unmark
448 $ hg resolve --unmark
457 $ hg resolve -l
449 $ hg resolve -l
458 U file1
450 U file1
459 U file2
451 U file2
460 (This downgrades to a warning since an explicit file was specified).
452 (This downgrades to a warning since an explicit file was specified).
461 $ hg --config commands.resolve.mark-check=abort resolve -m file2
453 $ hg --config commands.resolve.mark-check=abort resolve -m file2
462 warning: the following files still have conflict markers:
454 warning: the following files still have conflict markers:
463 file2
455 file2
464 $ hg resolve -l
456 $ hg resolve -l
465 U file1
457 U file1
466 R file2
458 R file2
467 Testing the --re-merge flag
459 Testing the --re-merge flag
468 $ hg resolve --unmark file1
460 $ hg resolve --unmark file1
469 $ hg resolve -l
461 $ hg resolve -l
470 U file1
462 U file1
471 R file2
463 R file2
472 $ hg resolve --mark --re-merge
464 $ hg resolve --mark --re-merge
473 abort: too many actions specified
465 abort: too many actions specified
474 [255]
466 [255]
475 $ hg resolve --re-merge --all
467 $ hg resolve --re-merge --all
476 merging file1
468 merging file1
477 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
469 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
478 [1]
470 [1]
479 Explicit re-merge
471 Explicit re-merge
480 $ hg resolve --unmark file1
472 $ hg resolve --unmark file1
481 $ hg resolve --config commands.resolve.explicit-re-merge=1 --all
473 $ hg resolve --config commands.resolve.explicit-re-merge=1 --all
482 abort: no action specified
474 abort: no action specified
483 (use --mark, --unmark, --list or --re-merge)
475 (use --mark, --unmark, --list or --re-merge)
484 [255]
476 [255]
485 $ hg resolve --config commands.resolve.explicit-re-merge=1 --re-merge --all
477 $ hg resolve --config commands.resolve.explicit-re-merge=1 --re-merge --all
486 merging file1
478 merging file1
487 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
479 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
488 [1]
480 [1]
489
481
490 $ cd ..
482 $ cd ..
491
483
492 ======================================================
484 ======================================================
493 Test 'hg resolve' confirm config option functionality |
485 Test 'hg resolve' confirm config option functionality |
494 ======================================================
486 ======================================================
495 $ cat >> $HGRCPATH << EOF
487 $ cat >> $HGRCPATH << EOF
496 > [extensions]
488 > [extensions]
497 > rebase=
489 > rebase=
498 > EOF
490 > EOF
499
491
500 $ hg init repo2
492 $ hg init repo2
501 $ cd repo2
493 $ cd repo2
502
494
503 $ echo boss > boss
495 $ echo boss > boss
504 $ hg ci -Am "add boss"
496 $ hg ci -Am "add boss"
505 adding boss
497 adding boss
506
498
507 $ for emp in emp1 emp2 emp3; do echo work > $emp; done;
499 $ for emp in emp1 emp2 emp3; do echo work > $emp; done;
508 $ hg ci -Aqm "added emp1 emp2 emp3"
500 $ hg ci -Aqm "added emp1 emp2 emp3"
509
501
510 $ hg up 0
502 $ hg up 0
511 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
503 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
512
504
513 $ for emp in emp1 emp2 emp3; do echo nowork > $emp; done;
505 $ for emp in emp1 emp2 emp3; do echo nowork > $emp; done;
514 $ hg ci -Aqm "added lazy emp1 emp2 emp3"
506 $ hg ci -Aqm "added lazy emp1 emp2 emp3"
515
507
516 $ hg log -GT "{rev} {node|short} {firstline(desc)}\n"
508 $ hg log -GT "{rev} {node|short} {firstline(desc)}\n"
517 @ 2 0acfd4a49af0 added lazy emp1 emp2 emp3
509 @ 2 0acfd4a49af0 added lazy emp1 emp2 emp3
518 |
510 |
519 | o 1 f30f98a8181f added emp1 emp2 emp3
511 | o 1 f30f98a8181f added emp1 emp2 emp3
520 |/
512 |/
521 o 0 88660038d466 add boss
513 o 0 88660038d466 add boss
522
514
523 $ hg rebase -s 1 -d 2
515 $ hg rebase -s 1 -d 2
524 rebasing 1:f30f98a8181f "added emp1 emp2 emp3"
516 rebasing 1:f30f98a8181f "added emp1 emp2 emp3"
525 merging emp1
517 merging emp1
526 merging emp2
518 merging emp2
527 merging emp3
519 merging emp3
528 warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark')
520 warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark')
529 warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark')
521 warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark')
530 warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark')
522 warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark')
531 unresolved conflicts (see hg resolve, then hg rebase --continue)
523 unresolved conflicts (see hg resolve, then hg rebase --continue)
532 [1]
524 [1]
533
525
534 Test when commands.resolve.confirm config option is not set:
526 Test when commands.resolve.confirm config option is not set:
535 ===========================================================
527 ===========================================================
536 $ hg resolve --all
528 $ hg resolve --all
537 merging emp1
529 merging emp1
538 merging emp2
530 merging emp2
539 merging emp3
531 merging emp3
540 warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark')
532 warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark')
541 warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark')
533 warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark')
542 warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark')
534 warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark')
543 [1]
535 [1]
544
536
545 Test when config option is set:
537 Test when config option is set:
546 ==============================
538 ==============================
547 $ cat >> .hg/hgrc << EOF
539 $ cat >> .hg/hgrc << EOF
548 > [ui]
540 > [ui]
549 > interactive = True
541 > interactive = True
550 > [commands]
542 > [commands]
551 > resolve.confirm = True
543 > resolve.confirm = True
552 > EOF
544 > EOF
553
545
554 $ hg resolve
546 $ hg resolve
555 abort: no files or directories specified
547 abort: no files or directories specified
556 (use --all to re-merge all unresolved files)
548 (use --all to re-merge all unresolved files)
557 [255]
549 [255]
558 $ hg resolve --all << EOF
550 $ hg resolve --all << EOF
559 > n
551 > n
560 > EOF
552 > EOF
561 re-merge all unresolved files (yn)? n
553 re-merge all unresolved files (yn)? n
562 abort: user quit
554 abort: user quit
563 [255]
555 [255]
564
556
565 $ hg resolve --all << EOF
557 $ hg resolve --all << EOF
566 > y
558 > y
567 > EOF
559 > EOF
568 re-merge all unresolved files (yn)? y
560 re-merge all unresolved files (yn)? y
569 merging emp1
561 merging emp1
570 merging emp2
562 merging emp2
571 merging emp3
563 merging emp3
572 warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark')
564 warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark')
573 warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark')
565 warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark')
574 warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark')
566 warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark')
575 [1]
567 [1]
576
568
577 Test that commands.resolve.confirm respect --mark option (only when no patterns args are given):
569 Test that commands.resolve.confirm respect --mark option (only when no patterns args are given):
578 ===============================================================================================
570 ===============================================================================================
579
571
580 $ hg resolve -m emp1
572 $ hg resolve -m emp1
581 $ hg resolve -l
573 $ hg resolve -l
582 R emp1
574 R emp1
583 U emp2
575 U emp2
584 U emp3
576 U emp3
585
577
586 $ hg resolve -m << EOF
578 $ hg resolve -m << EOF
587 > n
579 > n
588 > EOF
580 > EOF
589 mark all unresolved files as resolved (yn)? n
581 mark all unresolved files as resolved (yn)? n
590 abort: user quit
582 abort: user quit
591 [255]
583 [255]
592
584
593 $ hg resolve -m << EOF
585 $ hg resolve -m << EOF
594 > y
586 > y
595 > EOF
587 > EOF
596 mark all unresolved files as resolved (yn)? y
588 mark all unresolved files as resolved (yn)? y
597 (no more unresolved files)
589 (no more unresolved files)
598 continue: hg rebase --continue
590 continue: hg rebase --continue
599 $ hg resolve -l
591 $ hg resolve -l
600 R emp1
592 R emp1
601 R emp2
593 R emp2
602 R emp3
594 R emp3
603
595
604 Test that commands.resolve.confirm respect --unmark option (only when no patterns args are given):
596 Test that commands.resolve.confirm respect --unmark option (only when no patterns args are given):
605 =================================================================================================
597 =================================================================================================
606
598
607 $ hg resolve -u emp1
599 $ hg resolve -u emp1
608
600
609 $ hg resolve -l
601 $ hg resolve -l
610 U emp1
602 U emp1
611 R emp2
603 R emp2
612 R emp3
604 R emp3
613
605
614 $ hg resolve -u << EOF
606 $ hg resolve -u << EOF
615 > n
607 > n
616 > EOF
608 > EOF
617 mark all resolved files as unresolved (yn)? n
609 mark all resolved files as unresolved (yn)? n
618 abort: user quit
610 abort: user quit
619 [255]
611 [255]
620
612
621 $ hg resolve -m << EOF
613 $ hg resolve -m << EOF
622 > y
614 > y
623 > EOF
615 > EOF
624 mark all unresolved files as resolved (yn)? y
616 mark all unresolved files as resolved (yn)? y
625 (no more unresolved files)
617 (no more unresolved files)
626 continue: hg rebase --continue
618 continue: hg rebase --continue
627
619
628 $ hg resolve -l
620 $ hg resolve -l
629 R emp1
621 R emp1
630 R emp2
622 R emp2
631 R emp3
623 R emp3
632
624
633 $ hg rebase --abort
625 $ hg rebase --abort
634 rebase aborted
626 rebase aborted
635
627
636 Done with commands.resolve.confirm tests:
628 Done with commands.resolve.confirm tests:
637 $ cd ..
629 $ cd ..
638
630
639 Test that commands.resolve.mark-check works even if there are deleted files:
631 Test that commands.resolve.mark-check works even if there are deleted files:
640 $ hg init resolve-deleted
632 $ hg init resolve-deleted
641 $ cd resolve-deleted
633 $ cd resolve-deleted
642 $ echo r0 > file1
634 $ echo r0 > file1
643 $ hg ci -qAm r0
635 $ hg ci -qAm r0
644 $ echo r1 > file1
636 $ echo r1 > file1
645 $ hg ci -qm r1
637 $ hg ci -qm r1
646 $ hg co -qr 0
638 $ hg co -qr 0
647 $ hg rm file1
639 $ hg rm file1
648 $ hg ci -qm "r2 (delete file1)"
640 $ hg ci -qm "r2 (delete file1)"
649
641
650 (At this point we have r0 creating file1, and sibling commits r1 and r2, which
642 (At this point we have r0 creating file1, and sibling commits r1 and r2, which
651 modify and delete file1, respectively)
643 modify and delete file1, respectively)
652
644
653 $ hg merge -r 1
645 $ hg merge -r 1
654 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
646 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
655 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
647 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
656 What do you want to do? u
648 What do you want to do? u
657 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
649 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
658 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
650 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
659 [1]
651 [1]
660 $ hg resolve --list
652 $ hg resolve --list
661 U file1
653 U file1
662 Because we left it as 'unresolved' the file should still exist.
654 Because we left it as 'unresolved' the file should still exist.
663 $ [ -f file1 ] || echo "File does not exist?"
655 $ [ -f file1 ] || echo "File does not exist?"
664 BC behavior: `hg resolve --mark` accepts that the file is still there, and
656 BC behavior: `hg resolve --mark` accepts that the file is still there, and
665 doesn't have a problem with this situation.
657 doesn't have a problem with this situation.
666 $ hg resolve --mark --config commands.resolve.mark-check=abort
658 $ hg resolve --mark --config commands.resolve.mark-check=abort
667 (no more unresolved files)
659 (no more unresolved files)
668 $ hg resolve --list
660 $ hg resolve --list
669 R file1
661 R file1
670 The file is still there:
662 The file is still there:
671 $ [ -f file1 ] || echo "File does not exist?"
663 $ [ -f file1 ] || echo "File does not exist?"
672 Let's check mark-check=warn:
664 Let's check mark-check=warn:
673 $ hg resolve --unmark file1
665 $ hg resolve --unmark file1
674 $ hg resolve --mark --config commands.resolve.mark-check=warn
666 $ hg resolve --mark --config commands.resolve.mark-check=warn
675 (no more unresolved files)
667 (no more unresolved files)
676 $ hg resolve --list
668 $ hg resolve --list
677 R file1
669 R file1
678 The file is still there:
670 The file is still there:
679 $ [ -f file1 ] || echo "File does not exist?"
671 $ [ -f file1 ] || echo "File does not exist?"
680 Let's resolve the issue by deleting the file via `hg resolve`
672 Let's resolve the issue by deleting the file via `hg resolve`
681 $ hg resolve --unmark file1
673 $ hg resolve --unmark file1
682 $ echo 'd' | hg resolve file1 --config ui.interactive=1
674 $ echo 'd' | hg resolve file1 --config ui.interactive=1
683 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
675 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
684 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
676 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
685 What do you want to do? d
677 What do you want to do? d
686 (no more unresolved files)
678 (no more unresolved files)
687 $ hg resolve --list
679 $ hg resolve --list
688 R file1
680 R file1
689 The file is deleted:
681 The file is deleted:
690 $ [ -f file1 ] && echo "File still exists?" || true
682 $ [ -f file1 ] && echo "File still exists?" || true
691 Doing `hg resolve --mark` doesn't break now that the file is missing:
683 Doing `hg resolve --mark` doesn't break now that the file is missing:
692 $ hg resolve --mark --config commands.resolve.mark-check=abort
684 $ hg resolve --mark --config commands.resolve.mark-check=abort
693 (no more unresolved files)
685 (no more unresolved files)
694 $ hg resolve --mark --config commands.resolve.mark-check=warn
686 $ hg resolve --mark --config commands.resolve.mark-check=warn
695 (no more unresolved files)
687 (no more unresolved files)
696 Resurrect the file, and delete it outside of hg:
688 Resurrect the file, and delete it outside of hg:
697 $ hg resolve --unmark file1
689 $ hg resolve --unmark file1
698 $ hg resolve file1
690 $ hg resolve file1
699 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
691 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
700 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
692 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
701 What do you want to do? u
693 What do you want to do? u
702 [1]
694 [1]
703 $ [ -f file1 ] || echo "File does not exist?"
695 $ [ -f file1 ] || echo "File does not exist?"
704 $ hg resolve --list
696 $ hg resolve --list
705 U file1
697 U file1
706 $ rm file1
698 $ rm file1
707 $ hg resolve --mark --config commands.resolve.mark-check=abort
699 $ hg resolve --mark --config commands.resolve.mark-check=abort
708 (no more unresolved files)
700 (no more unresolved files)
709 $ hg resolve --list
701 $ hg resolve --list
710 R file1
702 R file1
711 $ hg resolve --unmark file1
703 $ hg resolve --unmark file1
712 $ hg resolve file1
704 $ hg resolve file1
713 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
705 file 'file1' was deleted in local [working copy] but was modified in other [merge rev].
714 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
706 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
715 What do you want to do? u
707 What do you want to do? u
716 [1]
708 [1]
717 $ [ -f file1 ] || echo "File does not exist?"
709 $ [ -f file1 ] || echo "File does not exist?"
718 $ hg resolve --list
710 $ hg resolve --list
719 U file1
711 U file1
720 $ rm file1
712 $ rm file1
721 $ hg resolve --mark --config commands.resolve.mark-check=warn
713 $ hg resolve --mark --config commands.resolve.mark-check=warn
722 (no more unresolved files)
714 (no more unresolved files)
723 $ hg resolve --list
715 $ hg resolve --list
724 R file1
716 R file1
725
717
726
718
727 For completeness, let's try that in the opposite direction (merging r2 into r1,
719 For completeness, let's try that in the opposite direction (merging r2 into r1,
728 instead of r1 into r2):
720 instead of r1 into r2):
729 $ hg update -qCr 1
721 $ hg update -qCr 1
730 $ hg merge -r 2
722 $ hg merge -r 2
731 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
723 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
732 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
724 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
733 What do you want to do? u
725 What do you want to do? u
734 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
726 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
735 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
727 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
736 [1]
728 [1]
737 $ hg resolve --list
729 $ hg resolve --list
738 U file1
730 U file1
739 Because we left it as 'unresolved' the file should still exist.
731 Because we left it as 'unresolved' the file should still exist.
740 $ [ -f file1 ] || echo "File does not exist?"
732 $ [ -f file1 ] || echo "File does not exist?"
741 BC behavior: `hg resolve --mark` accepts that the file is still there, and
733 BC behavior: `hg resolve --mark` accepts that the file is still there, and
742 doesn't have a problem with this situation.
734 doesn't have a problem with this situation.
743 $ hg resolve --mark --config commands.resolve.mark-check=abort
735 $ hg resolve --mark --config commands.resolve.mark-check=abort
744 (no more unresolved files)
736 (no more unresolved files)
745 $ hg resolve --list
737 $ hg resolve --list
746 R file1
738 R file1
747 The file is still there:
739 The file is still there:
748 $ [ -f file1 ] || echo "File does not exist?"
740 $ [ -f file1 ] || echo "File does not exist?"
749 Let's check mark-check=warn:
741 Let's check mark-check=warn:
750 $ hg resolve --unmark file1
742 $ hg resolve --unmark file1
751 $ hg resolve --mark --config commands.resolve.mark-check=warn
743 $ hg resolve --mark --config commands.resolve.mark-check=warn
752 (no more unresolved files)
744 (no more unresolved files)
753 $ hg resolve --list
745 $ hg resolve --list
754 R file1
746 R file1
755 The file is still there:
747 The file is still there:
756 $ [ -f file1 ] || echo "File does not exist?"
748 $ [ -f file1 ] || echo "File does not exist?"
757 Let's resolve the issue by deleting the file via `hg resolve`
749 Let's resolve the issue by deleting the file via `hg resolve`
758 $ hg resolve --unmark file1
750 $ hg resolve --unmark file1
759 $ echo 'd' | hg resolve file1 --config ui.interactive=1
751 $ echo 'd' | hg resolve file1 --config ui.interactive=1
760 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
752 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
761 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
753 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
762 What do you want to do? d
754 What do you want to do? d
763 (no more unresolved files)
755 (no more unresolved files)
764 $ hg resolve --list
756 $ hg resolve --list
765 R file1
757 R file1
766 The file is deleted:
758 The file is deleted:
767 $ [ -f file1 ] && echo "File still exists?" || true
759 $ [ -f file1 ] && echo "File still exists?" || true
768 Doing `hg resolve --mark` doesn't break now that the file is missing:
760 Doing `hg resolve --mark` doesn't break now that the file is missing:
769 $ hg resolve --mark --config commands.resolve.mark-check=abort
761 $ hg resolve --mark --config commands.resolve.mark-check=abort
770 (no more unresolved files)
762 (no more unresolved files)
771 $ hg resolve --mark --config commands.resolve.mark-check=warn
763 $ hg resolve --mark --config commands.resolve.mark-check=warn
772 (no more unresolved files)
764 (no more unresolved files)
773 Resurrect the file, and delete it outside of hg:
765 Resurrect the file, and delete it outside of hg:
774 $ hg resolve --unmark file1
766 $ hg resolve --unmark file1
775 $ hg resolve file1
767 $ hg resolve file1
776 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
768 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
777 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
769 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
778 What do you want to do? u
770 What do you want to do? u
779 [1]
771 [1]
780 $ [ -f file1 ] || echo "File does not exist?"
772 $ [ -f file1 ] || echo "File does not exist?"
781 $ hg resolve --list
773 $ hg resolve --list
782 U file1
774 U file1
783 $ rm file1
775 $ rm file1
784 $ hg resolve --mark --config commands.resolve.mark-check=abort
776 $ hg resolve --mark --config commands.resolve.mark-check=abort
785 (no more unresolved files)
777 (no more unresolved files)
786 $ hg resolve --list
778 $ hg resolve --list
787 R file1
779 R file1
788 $ hg resolve --unmark file1
780 $ hg resolve --unmark file1
789 $ hg resolve file1
781 $ hg resolve file1
790 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
782 file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
791 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
783 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
792 What do you want to do? u
784 What do you want to do? u
793 [1]
785 [1]
794 $ [ -f file1 ] || echo "File does not exist?"
786 $ [ -f file1 ] || echo "File does not exist?"
795 $ hg resolve --list
787 $ hg resolve --list
796 U file1
788 U file1
797 $ rm file1
789 $ rm file1
798 $ hg resolve --mark --config commands.resolve.mark-check=warn
790 $ hg resolve --mark --config commands.resolve.mark-check=warn
799 (no more unresolved files)
791 (no more unresolved files)
800 $ hg resolve --list
792 $ hg resolve --list
801 R file1
793 R file1
802
794
803 $ cd ..
795 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now