##// END OF EJS Templates
debugwalk: also print matcher representation...
Martin von Zweigbergk -
r32453:2def402b default
parent child Browse files
Show More
@@ -1,2161 +1,2162 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 difflib
10 import difflib
11 import errno
11 import errno
12 import operator
12 import operator
13 import os
13 import os
14 import random
14 import random
15 import socket
15 import socket
16 import string
16 import string
17 import sys
17 import sys
18 import tempfile
18 import tempfile
19 import time
19 import time
20
20
21 from .i18n import _
21 from .i18n import _
22 from .node import (
22 from .node import (
23 bin,
23 bin,
24 hex,
24 hex,
25 nullhex,
25 nullhex,
26 nullid,
26 nullid,
27 nullrev,
27 nullrev,
28 short,
28 short,
29 )
29 )
30 from . import (
30 from . import (
31 bundle2,
31 bundle2,
32 changegroup,
32 changegroup,
33 cmdutil,
33 cmdutil,
34 color,
34 color,
35 context,
35 context,
36 dagparser,
36 dagparser,
37 dagutil,
37 dagutil,
38 encoding,
38 encoding,
39 error,
39 error,
40 exchange,
40 exchange,
41 extensions,
41 extensions,
42 filemerge,
42 filemerge,
43 fileset,
43 fileset,
44 formatter,
44 formatter,
45 hg,
45 hg,
46 localrepo,
46 localrepo,
47 lock as lockmod,
47 lock as lockmod,
48 merge as mergemod,
48 merge as mergemod,
49 obsolete,
49 obsolete,
50 policy,
50 policy,
51 pvec,
51 pvec,
52 pycompat,
52 pycompat,
53 registrar,
53 registrar,
54 repair,
54 repair,
55 revlog,
55 revlog,
56 revset,
56 revset,
57 revsetlang,
57 revsetlang,
58 scmutil,
58 scmutil,
59 setdiscovery,
59 setdiscovery,
60 simplemerge,
60 simplemerge,
61 smartset,
61 smartset,
62 sslutil,
62 sslutil,
63 streamclone,
63 streamclone,
64 templater,
64 templater,
65 treediscovery,
65 treediscovery,
66 upgrade,
66 upgrade,
67 util,
67 util,
68 vfs as vfsmod,
68 vfs as vfsmod,
69 )
69 )
70
70
71 release = lockmod.release
71 release = lockmod.release
72
72
73 command = registrar.command()
73 command = registrar.command()
74
74
75 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
75 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
76 def debugancestor(ui, repo, *args):
76 def debugancestor(ui, repo, *args):
77 """find the ancestor revision of two revisions in a given index"""
77 """find the ancestor revision of two revisions in a given index"""
78 if len(args) == 3:
78 if len(args) == 3:
79 index, rev1, rev2 = args
79 index, rev1, rev2 = args
80 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
80 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
81 lookup = r.lookup
81 lookup = r.lookup
82 elif len(args) == 2:
82 elif len(args) == 2:
83 if not repo:
83 if not repo:
84 raise error.Abort(_('there is no Mercurial repository here '
84 raise error.Abort(_('there is no Mercurial repository here '
85 '(.hg not found)'))
85 '(.hg not found)'))
86 rev1, rev2 = args
86 rev1, rev2 = args
87 r = repo.changelog
87 r = repo.changelog
88 lookup = repo.lookup
88 lookup = repo.lookup
89 else:
89 else:
90 raise error.Abort(_('either two or three arguments required'))
90 raise error.Abort(_('either two or three arguments required'))
91 a = r.ancestor(lookup(rev1), lookup(rev2))
91 a = r.ancestor(lookup(rev1), lookup(rev2))
92 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
92 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
93
93
94 @command('debugapplystreamclonebundle', [], 'FILE')
94 @command('debugapplystreamclonebundle', [], 'FILE')
95 def debugapplystreamclonebundle(ui, repo, fname):
95 def debugapplystreamclonebundle(ui, repo, fname):
96 """apply a stream clone bundle file"""
96 """apply a stream clone bundle file"""
97 f = hg.openpath(ui, fname)
97 f = hg.openpath(ui, fname)
98 gen = exchange.readbundle(ui, f, fname)
98 gen = exchange.readbundle(ui, f, fname)
99 gen.apply(repo)
99 gen.apply(repo)
100
100
101 @command('debugbuilddag',
101 @command('debugbuilddag',
102 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
102 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
103 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
103 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
104 ('n', 'new-file', None, _('add new file at each rev'))],
104 ('n', 'new-file', None, _('add new file at each rev'))],
105 _('[OPTION]... [TEXT]'))
105 _('[OPTION]... [TEXT]'))
106 def debugbuilddag(ui, repo, text=None,
106 def debugbuilddag(ui, repo, text=None,
107 mergeable_file=False,
107 mergeable_file=False,
108 overwritten_file=False,
108 overwritten_file=False,
109 new_file=False):
109 new_file=False):
110 """builds a repo with a given DAG from scratch in the current empty repo
110 """builds a repo with a given DAG from scratch in the current empty repo
111
111
112 The description of the DAG is read from stdin if not given on the
112 The description of the DAG is read from stdin if not given on the
113 command line.
113 command line.
114
114
115 Elements:
115 Elements:
116
116
117 - "+n" is a linear run of n nodes based on the current default parent
117 - "+n" is a linear run of n nodes based on the current default parent
118 - "." is a single node based on the current default parent
118 - "." is a single node based on the current default parent
119 - "$" resets the default parent to null (implied at the start);
119 - "$" resets the default parent to null (implied at the start);
120 otherwise the default parent is always the last node created
120 otherwise the default parent is always the last node created
121 - "<p" sets the default parent to the backref p
121 - "<p" sets the default parent to the backref p
122 - "*p" is a fork at parent p, which is a backref
122 - "*p" is a fork at parent p, which is a backref
123 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
123 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
124 - "/p2" is a merge of the preceding node and p2
124 - "/p2" is a merge of the preceding node and p2
125 - ":tag" defines a local tag for the preceding node
125 - ":tag" defines a local tag for the preceding node
126 - "@branch" sets the named branch for subsequent nodes
126 - "@branch" sets the named branch for subsequent nodes
127 - "#...\\n" is a comment up to the end of the line
127 - "#...\\n" is a comment up to the end of the line
128
128
129 Whitespace between the above elements is ignored.
129 Whitespace between the above elements is ignored.
130
130
131 A backref is either
131 A backref is either
132
132
133 - a number n, which references the node curr-n, where curr is the current
133 - a number n, which references the node curr-n, where curr is the current
134 node, or
134 node, or
135 - the name of a local tag you placed earlier using ":tag", or
135 - the name of a local tag you placed earlier using ":tag", or
136 - empty to denote the default parent.
136 - empty to denote the default parent.
137
137
138 All string valued-elements are either strictly alphanumeric, or must
138 All string valued-elements are either strictly alphanumeric, or must
139 be enclosed in double quotes ("..."), with "\\" as escape character.
139 be enclosed in double quotes ("..."), with "\\" as escape character.
140 """
140 """
141
141
142 if text is None:
142 if text is None:
143 ui.status(_("reading DAG from stdin\n"))
143 ui.status(_("reading DAG from stdin\n"))
144 text = ui.fin.read()
144 text = ui.fin.read()
145
145
146 cl = repo.changelog
146 cl = repo.changelog
147 if len(cl) > 0:
147 if len(cl) > 0:
148 raise error.Abort(_('repository is not empty'))
148 raise error.Abort(_('repository is not empty'))
149
149
150 # determine number of revs in DAG
150 # determine number of revs in DAG
151 total = 0
151 total = 0
152 for type, data in dagparser.parsedag(text):
152 for type, data in dagparser.parsedag(text):
153 if type == 'n':
153 if type == 'n':
154 total += 1
154 total += 1
155
155
156 if mergeable_file:
156 if mergeable_file:
157 linesperrev = 2
157 linesperrev = 2
158 # make a file with k lines per rev
158 # make a file with k lines per rev
159 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
159 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
160 initialmergedlines.append("")
160 initialmergedlines.append("")
161
161
162 tags = []
162 tags = []
163
163
164 wlock = lock = tr = None
164 wlock = lock = tr = None
165 try:
165 try:
166 wlock = repo.wlock()
166 wlock = repo.wlock()
167 lock = repo.lock()
167 lock = repo.lock()
168 tr = repo.transaction("builddag")
168 tr = repo.transaction("builddag")
169
169
170 at = -1
170 at = -1
171 atbranch = 'default'
171 atbranch = 'default'
172 nodeids = []
172 nodeids = []
173 id = 0
173 id = 0
174 ui.progress(_('building'), id, unit=_('revisions'), total=total)
174 ui.progress(_('building'), id, unit=_('revisions'), total=total)
175 for type, data in dagparser.parsedag(text):
175 for type, data in dagparser.parsedag(text):
176 if type == 'n':
176 if type == 'n':
177 ui.note(('node %s\n' % str(data)))
177 ui.note(('node %s\n' % str(data)))
178 id, ps = data
178 id, ps = data
179
179
180 files = []
180 files = []
181 fctxs = {}
181 fctxs = {}
182
182
183 p2 = None
183 p2 = None
184 if mergeable_file:
184 if mergeable_file:
185 fn = "mf"
185 fn = "mf"
186 p1 = repo[ps[0]]
186 p1 = repo[ps[0]]
187 if len(ps) > 1:
187 if len(ps) > 1:
188 p2 = repo[ps[1]]
188 p2 = repo[ps[1]]
189 pa = p1.ancestor(p2)
189 pa = p1.ancestor(p2)
190 base, local, other = [x[fn].data() for x in (pa, p1,
190 base, local, other = [x[fn].data() for x in (pa, p1,
191 p2)]
191 p2)]
192 m3 = simplemerge.Merge3Text(base, local, other)
192 m3 = simplemerge.Merge3Text(base, local, other)
193 ml = [l.strip() for l in m3.merge_lines()]
193 ml = [l.strip() for l in m3.merge_lines()]
194 ml.append("")
194 ml.append("")
195 elif at > 0:
195 elif at > 0:
196 ml = p1[fn].data().split("\n")
196 ml = p1[fn].data().split("\n")
197 else:
197 else:
198 ml = initialmergedlines
198 ml = initialmergedlines
199 ml[id * linesperrev] += " r%i" % id
199 ml[id * linesperrev] += " r%i" % id
200 mergedtext = "\n".join(ml)
200 mergedtext = "\n".join(ml)
201 files.append(fn)
201 files.append(fn)
202 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
202 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
203
203
204 if overwritten_file:
204 if overwritten_file:
205 fn = "of"
205 fn = "of"
206 files.append(fn)
206 files.append(fn)
207 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
207 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
208
208
209 if new_file:
209 if new_file:
210 fn = "nf%i" % id
210 fn = "nf%i" % id
211 files.append(fn)
211 files.append(fn)
212 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
212 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
213 if len(ps) > 1:
213 if len(ps) > 1:
214 if not p2:
214 if not p2:
215 p2 = repo[ps[1]]
215 p2 = repo[ps[1]]
216 for fn in p2:
216 for fn in p2:
217 if fn.startswith("nf"):
217 if fn.startswith("nf"):
218 files.append(fn)
218 files.append(fn)
219 fctxs[fn] = p2[fn]
219 fctxs[fn] = p2[fn]
220
220
221 def fctxfn(repo, cx, path):
221 def fctxfn(repo, cx, path):
222 return fctxs.get(path)
222 return fctxs.get(path)
223
223
224 if len(ps) == 0 or ps[0] < 0:
224 if len(ps) == 0 or ps[0] < 0:
225 pars = [None, None]
225 pars = [None, None]
226 elif len(ps) == 1:
226 elif len(ps) == 1:
227 pars = [nodeids[ps[0]], None]
227 pars = [nodeids[ps[0]], None]
228 else:
228 else:
229 pars = [nodeids[p] for p in ps]
229 pars = [nodeids[p] for p in ps]
230 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
230 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
231 date=(id, 0),
231 date=(id, 0),
232 user="debugbuilddag",
232 user="debugbuilddag",
233 extra={'branch': atbranch})
233 extra={'branch': atbranch})
234 nodeid = repo.commitctx(cx)
234 nodeid = repo.commitctx(cx)
235 nodeids.append(nodeid)
235 nodeids.append(nodeid)
236 at = id
236 at = id
237 elif type == 'l':
237 elif type == 'l':
238 id, name = data
238 id, name = data
239 ui.note(('tag %s\n' % name))
239 ui.note(('tag %s\n' % name))
240 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
240 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
241 elif type == 'a':
241 elif type == 'a':
242 ui.note(('branch %s\n' % data))
242 ui.note(('branch %s\n' % data))
243 atbranch = data
243 atbranch = data
244 ui.progress(_('building'), id, unit=_('revisions'), total=total)
244 ui.progress(_('building'), id, unit=_('revisions'), total=total)
245 tr.close()
245 tr.close()
246
246
247 if tags:
247 if tags:
248 repo.vfs.write("localtags", "".join(tags))
248 repo.vfs.write("localtags", "".join(tags))
249 finally:
249 finally:
250 ui.progress(_('building'), None)
250 ui.progress(_('building'), None)
251 release(tr, lock, wlock)
251 release(tr, lock, wlock)
252
252
253 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
253 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
254 indent_string = ' ' * indent
254 indent_string = ' ' * indent
255 if all:
255 if all:
256 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
256 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
257 % indent_string)
257 % indent_string)
258
258
259 def showchunks(named):
259 def showchunks(named):
260 ui.write("\n%s%s\n" % (indent_string, named))
260 ui.write("\n%s%s\n" % (indent_string, named))
261 chain = None
261 chain = None
262 for chunkdata in iter(lambda: gen.deltachunk(chain), {}):
262 for chunkdata in iter(lambda: gen.deltachunk(chain), {}):
263 node = chunkdata['node']
263 node = chunkdata['node']
264 p1 = chunkdata['p1']
264 p1 = chunkdata['p1']
265 p2 = chunkdata['p2']
265 p2 = chunkdata['p2']
266 cs = chunkdata['cs']
266 cs = chunkdata['cs']
267 deltabase = chunkdata['deltabase']
267 deltabase = chunkdata['deltabase']
268 delta = chunkdata['delta']
268 delta = chunkdata['delta']
269 ui.write("%s%s %s %s %s %s %s\n" %
269 ui.write("%s%s %s %s %s %s %s\n" %
270 (indent_string, hex(node), hex(p1), hex(p2),
270 (indent_string, hex(node), hex(p1), hex(p2),
271 hex(cs), hex(deltabase), len(delta)))
271 hex(cs), hex(deltabase), len(delta)))
272 chain = node
272 chain = node
273
273
274 chunkdata = gen.changelogheader()
274 chunkdata = gen.changelogheader()
275 showchunks("changelog")
275 showchunks("changelog")
276 chunkdata = gen.manifestheader()
276 chunkdata = gen.manifestheader()
277 showchunks("manifest")
277 showchunks("manifest")
278 for chunkdata in iter(gen.filelogheader, {}):
278 for chunkdata in iter(gen.filelogheader, {}):
279 fname = chunkdata['filename']
279 fname = chunkdata['filename']
280 showchunks(fname)
280 showchunks(fname)
281 else:
281 else:
282 if isinstance(gen, bundle2.unbundle20):
282 if isinstance(gen, bundle2.unbundle20):
283 raise error.Abort(_('use debugbundle2 for this file'))
283 raise error.Abort(_('use debugbundle2 for this file'))
284 chunkdata = gen.changelogheader()
284 chunkdata = gen.changelogheader()
285 chain = None
285 chain = None
286 for chunkdata in iter(lambda: gen.deltachunk(chain), {}):
286 for chunkdata in iter(lambda: gen.deltachunk(chain), {}):
287 node = chunkdata['node']
287 node = chunkdata['node']
288 ui.write("%s%s\n" % (indent_string, hex(node)))
288 ui.write("%s%s\n" % (indent_string, hex(node)))
289 chain = node
289 chain = node
290
290
291 def _debugbundle2(ui, gen, all=None, **opts):
291 def _debugbundle2(ui, gen, all=None, **opts):
292 """lists the contents of a bundle2"""
292 """lists the contents of a bundle2"""
293 if not isinstance(gen, bundle2.unbundle20):
293 if not isinstance(gen, bundle2.unbundle20):
294 raise error.Abort(_('not a bundle2 file'))
294 raise error.Abort(_('not a bundle2 file'))
295 ui.write(('Stream params: %s\n' % repr(gen.params)))
295 ui.write(('Stream params: %s\n' % repr(gen.params)))
296 for part in gen.iterparts():
296 for part in gen.iterparts():
297 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
297 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
298 if part.type == 'changegroup':
298 if part.type == 'changegroup':
299 version = part.params.get('version', '01')
299 version = part.params.get('version', '01')
300 cg = changegroup.getunbundler(version, part, 'UN')
300 cg = changegroup.getunbundler(version, part, 'UN')
301 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
301 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
302
302
303 @command('debugbundle',
303 @command('debugbundle',
304 [('a', 'all', None, _('show all details')),
304 [('a', 'all', None, _('show all details')),
305 ('', 'spec', None, _('print the bundlespec of the bundle'))],
305 ('', 'spec', None, _('print the bundlespec of the bundle'))],
306 _('FILE'),
306 _('FILE'),
307 norepo=True)
307 norepo=True)
308 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
308 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
309 """lists the contents of a bundle"""
309 """lists the contents of a bundle"""
310 with hg.openpath(ui, bundlepath) as f:
310 with hg.openpath(ui, bundlepath) as f:
311 if spec:
311 if spec:
312 spec = exchange.getbundlespec(ui, f)
312 spec = exchange.getbundlespec(ui, f)
313 ui.write('%s\n' % spec)
313 ui.write('%s\n' % spec)
314 return
314 return
315
315
316 gen = exchange.readbundle(ui, f, bundlepath)
316 gen = exchange.readbundle(ui, f, bundlepath)
317 if isinstance(gen, bundle2.unbundle20):
317 if isinstance(gen, bundle2.unbundle20):
318 return _debugbundle2(ui, gen, all=all, **opts)
318 return _debugbundle2(ui, gen, all=all, **opts)
319 _debugchangegroup(ui, gen, all=all, **opts)
319 _debugchangegroup(ui, gen, all=all, **opts)
320
320
321 @command('debugcheckstate', [], '')
321 @command('debugcheckstate', [], '')
322 def debugcheckstate(ui, repo):
322 def debugcheckstate(ui, repo):
323 """validate the correctness of the current dirstate"""
323 """validate the correctness of the current dirstate"""
324 parent1, parent2 = repo.dirstate.parents()
324 parent1, parent2 = repo.dirstate.parents()
325 m1 = repo[parent1].manifest()
325 m1 = repo[parent1].manifest()
326 m2 = repo[parent2].manifest()
326 m2 = repo[parent2].manifest()
327 errors = 0
327 errors = 0
328 for f in repo.dirstate:
328 for f in repo.dirstate:
329 state = repo.dirstate[f]
329 state = repo.dirstate[f]
330 if state in "nr" and f not in m1:
330 if state in "nr" and f not in m1:
331 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
331 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
332 errors += 1
332 errors += 1
333 if state in "a" and f in m1:
333 if state in "a" and f in m1:
334 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
334 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
335 errors += 1
335 errors += 1
336 if state in "m" and f not in m1 and f not in m2:
336 if state in "m" and f not in m1 and f not in m2:
337 ui.warn(_("%s in state %s, but not in either manifest\n") %
337 ui.warn(_("%s in state %s, but not in either manifest\n") %
338 (f, state))
338 (f, state))
339 errors += 1
339 errors += 1
340 for f in m1:
340 for f in m1:
341 state = repo.dirstate[f]
341 state = repo.dirstate[f]
342 if state not in "nrm":
342 if state not in "nrm":
343 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
343 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
344 errors += 1
344 errors += 1
345 if errors:
345 if errors:
346 error = _(".hg/dirstate inconsistent with current parent's manifest")
346 error = _(".hg/dirstate inconsistent with current parent's manifest")
347 raise error.Abort(error)
347 raise error.Abort(error)
348
348
349 @command('debugcolor',
349 @command('debugcolor',
350 [('', 'style', None, _('show all configured styles'))],
350 [('', 'style', None, _('show all configured styles'))],
351 'hg debugcolor')
351 'hg debugcolor')
352 def debugcolor(ui, repo, **opts):
352 def debugcolor(ui, repo, **opts):
353 """show available color, effects or style"""
353 """show available color, effects or style"""
354 ui.write(('color mode: %s\n') % ui._colormode)
354 ui.write(('color mode: %s\n') % ui._colormode)
355 if opts.get('style'):
355 if opts.get('style'):
356 return _debugdisplaystyle(ui)
356 return _debugdisplaystyle(ui)
357 else:
357 else:
358 return _debugdisplaycolor(ui)
358 return _debugdisplaycolor(ui)
359
359
360 def _debugdisplaycolor(ui):
360 def _debugdisplaycolor(ui):
361 ui = ui.copy()
361 ui = ui.copy()
362 ui._styles.clear()
362 ui._styles.clear()
363 for effect in color._activeeffects(ui).keys():
363 for effect in color._activeeffects(ui).keys():
364 ui._styles[effect] = effect
364 ui._styles[effect] = effect
365 if ui._terminfoparams:
365 if ui._terminfoparams:
366 for k, v in ui.configitems('color'):
366 for k, v in ui.configitems('color'):
367 if k.startswith('color.'):
367 if k.startswith('color.'):
368 ui._styles[k] = k[6:]
368 ui._styles[k] = k[6:]
369 elif k.startswith('terminfo.'):
369 elif k.startswith('terminfo.'):
370 ui._styles[k] = k[9:]
370 ui._styles[k] = k[9:]
371 ui.write(_('available colors:\n'))
371 ui.write(_('available colors:\n'))
372 # sort label with a '_' after the other to group '_background' entry.
372 # sort label with a '_' after the other to group '_background' entry.
373 items = sorted(ui._styles.items(),
373 items = sorted(ui._styles.items(),
374 key=lambda i: ('_' in i[0], i[0], i[1]))
374 key=lambda i: ('_' in i[0], i[0], i[1]))
375 for colorname, label in items:
375 for colorname, label in items:
376 ui.write(('%s\n') % colorname, label=label)
376 ui.write(('%s\n') % colorname, label=label)
377
377
378 def _debugdisplaystyle(ui):
378 def _debugdisplaystyle(ui):
379 ui.write(_('available style:\n'))
379 ui.write(_('available style:\n'))
380 width = max(len(s) for s in ui._styles)
380 width = max(len(s) for s in ui._styles)
381 for label, effects in sorted(ui._styles.items()):
381 for label, effects in sorted(ui._styles.items()):
382 ui.write('%s' % label, label=label)
382 ui.write('%s' % label, label=label)
383 if effects:
383 if effects:
384 # 50
384 # 50
385 ui.write(': ')
385 ui.write(': ')
386 ui.write(' ' * (max(0, width - len(label))))
386 ui.write(' ' * (max(0, width - len(label))))
387 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
387 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
388 ui.write('\n')
388 ui.write('\n')
389
389
390 @command('debugcreatestreamclonebundle', [], 'FILE')
390 @command('debugcreatestreamclonebundle', [], 'FILE')
391 def debugcreatestreamclonebundle(ui, repo, fname):
391 def debugcreatestreamclonebundle(ui, repo, fname):
392 """create a stream clone bundle file
392 """create a stream clone bundle file
393
393
394 Stream bundles are special bundles that are essentially archives of
394 Stream bundles are special bundles that are essentially archives of
395 revlog files. They are commonly used for cloning very quickly.
395 revlog files. They are commonly used for cloning very quickly.
396 """
396 """
397 requirements, gen = streamclone.generatebundlev1(repo)
397 requirements, gen = streamclone.generatebundlev1(repo)
398 changegroup.writechunks(ui, gen, fname)
398 changegroup.writechunks(ui, gen, fname)
399
399
400 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
400 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
401
401
402 @command('debugdag',
402 @command('debugdag',
403 [('t', 'tags', None, _('use tags as labels')),
403 [('t', 'tags', None, _('use tags as labels')),
404 ('b', 'branches', None, _('annotate with branch names')),
404 ('b', 'branches', None, _('annotate with branch names')),
405 ('', 'dots', None, _('use dots for runs')),
405 ('', 'dots', None, _('use dots for runs')),
406 ('s', 'spaces', None, _('separate elements by spaces'))],
406 ('s', 'spaces', None, _('separate elements by spaces'))],
407 _('[OPTION]... [FILE [REV]...]'),
407 _('[OPTION]... [FILE [REV]...]'),
408 optionalrepo=True)
408 optionalrepo=True)
409 def debugdag(ui, repo, file_=None, *revs, **opts):
409 def debugdag(ui, repo, file_=None, *revs, **opts):
410 """format the changelog or an index DAG as a concise textual description
410 """format the changelog or an index DAG as a concise textual description
411
411
412 If you pass a revlog index, the revlog's DAG is emitted. If you list
412 If you pass a revlog index, the revlog's DAG is emitted. If you list
413 revision numbers, they get labeled in the output as rN.
413 revision numbers, they get labeled in the output as rN.
414
414
415 Otherwise, the changelog DAG of the current repo is emitted.
415 Otherwise, the changelog DAG of the current repo is emitted.
416 """
416 """
417 spaces = opts.get('spaces')
417 spaces = opts.get('spaces')
418 dots = opts.get('dots')
418 dots = opts.get('dots')
419 if file_:
419 if file_:
420 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
420 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
421 file_)
421 file_)
422 revs = set((int(r) for r in revs))
422 revs = set((int(r) for r in revs))
423 def events():
423 def events():
424 for r in rlog:
424 for r in rlog:
425 yield 'n', (r, list(p for p in rlog.parentrevs(r)
425 yield 'n', (r, list(p for p in rlog.parentrevs(r)
426 if p != -1))
426 if p != -1))
427 if r in revs:
427 if r in revs:
428 yield 'l', (r, "r%i" % r)
428 yield 'l', (r, "r%i" % r)
429 elif repo:
429 elif repo:
430 cl = repo.changelog
430 cl = repo.changelog
431 tags = opts.get('tags')
431 tags = opts.get('tags')
432 branches = opts.get('branches')
432 branches = opts.get('branches')
433 if tags:
433 if tags:
434 labels = {}
434 labels = {}
435 for l, n in repo.tags().items():
435 for l, n in repo.tags().items():
436 labels.setdefault(cl.rev(n), []).append(l)
436 labels.setdefault(cl.rev(n), []).append(l)
437 def events():
437 def events():
438 b = "default"
438 b = "default"
439 for r in cl:
439 for r in cl:
440 if branches:
440 if branches:
441 newb = cl.read(cl.node(r))[5]['branch']
441 newb = cl.read(cl.node(r))[5]['branch']
442 if newb != b:
442 if newb != b:
443 yield 'a', newb
443 yield 'a', newb
444 b = newb
444 b = newb
445 yield 'n', (r, list(p for p in cl.parentrevs(r)
445 yield 'n', (r, list(p for p in cl.parentrevs(r)
446 if p != -1))
446 if p != -1))
447 if tags:
447 if tags:
448 ls = labels.get(r)
448 ls = labels.get(r)
449 if ls:
449 if ls:
450 for l in ls:
450 for l in ls:
451 yield 'l', (r, l)
451 yield 'l', (r, l)
452 else:
452 else:
453 raise error.Abort(_('need repo for changelog dag'))
453 raise error.Abort(_('need repo for changelog dag'))
454
454
455 for line in dagparser.dagtextlines(events(),
455 for line in dagparser.dagtextlines(events(),
456 addspaces=spaces,
456 addspaces=spaces,
457 wraplabels=True,
457 wraplabels=True,
458 wrapannotations=True,
458 wrapannotations=True,
459 wrapnonlinear=dots,
459 wrapnonlinear=dots,
460 usedots=dots,
460 usedots=dots,
461 maxlinewidth=70):
461 maxlinewidth=70):
462 ui.write(line)
462 ui.write(line)
463 ui.write("\n")
463 ui.write("\n")
464
464
465 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
465 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
466 def debugdata(ui, repo, file_, rev=None, **opts):
466 def debugdata(ui, repo, file_, rev=None, **opts):
467 """dump the contents of a data file revision"""
467 """dump the contents of a data file revision"""
468 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
468 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
469 if rev is not None:
469 if rev is not None:
470 raise error.CommandError('debugdata', _('invalid arguments'))
470 raise error.CommandError('debugdata', _('invalid arguments'))
471 file_, rev = None, file_
471 file_, rev = None, file_
472 elif rev is None:
472 elif rev is None:
473 raise error.CommandError('debugdata', _('invalid arguments'))
473 raise error.CommandError('debugdata', _('invalid arguments'))
474 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
474 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
475 try:
475 try:
476 ui.write(r.revision(r.lookup(rev), raw=True))
476 ui.write(r.revision(r.lookup(rev), raw=True))
477 except KeyError:
477 except KeyError:
478 raise error.Abort(_('invalid revision identifier %s') % rev)
478 raise error.Abort(_('invalid revision identifier %s') % rev)
479
479
480 @command('debugdate',
480 @command('debugdate',
481 [('e', 'extended', None, _('try extended date formats'))],
481 [('e', 'extended', None, _('try extended date formats'))],
482 _('[-e] DATE [RANGE]'),
482 _('[-e] DATE [RANGE]'),
483 norepo=True, optionalrepo=True)
483 norepo=True, optionalrepo=True)
484 def debugdate(ui, date, range=None, **opts):
484 def debugdate(ui, date, range=None, **opts):
485 """parse and display a date"""
485 """parse and display a date"""
486 if opts["extended"]:
486 if opts["extended"]:
487 d = util.parsedate(date, util.extendeddateformats)
487 d = util.parsedate(date, util.extendeddateformats)
488 else:
488 else:
489 d = util.parsedate(date)
489 d = util.parsedate(date)
490 ui.write(("internal: %s %s\n") % d)
490 ui.write(("internal: %s %s\n") % d)
491 ui.write(("standard: %s\n") % util.datestr(d))
491 ui.write(("standard: %s\n") % util.datestr(d))
492 if range:
492 if range:
493 m = util.matchdate(range)
493 m = util.matchdate(range)
494 ui.write(("match: %s\n") % m(d[0]))
494 ui.write(("match: %s\n") % m(d[0]))
495
495
496 @command('debugdeltachain',
496 @command('debugdeltachain',
497 cmdutil.debugrevlogopts + cmdutil.formatteropts,
497 cmdutil.debugrevlogopts + cmdutil.formatteropts,
498 _('-c|-m|FILE'),
498 _('-c|-m|FILE'),
499 optionalrepo=True)
499 optionalrepo=True)
500 def debugdeltachain(ui, repo, file_=None, **opts):
500 def debugdeltachain(ui, repo, file_=None, **opts):
501 """dump information about delta chains in a revlog
501 """dump information about delta chains in a revlog
502
502
503 Output can be templatized. Available template keywords are:
503 Output can be templatized. Available template keywords are:
504
504
505 :``rev``: revision number
505 :``rev``: revision number
506 :``chainid``: delta chain identifier (numbered by unique base)
506 :``chainid``: delta chain identifier (numbered by unique base)
507 :``chainlen``: delta chain length to this revision
507 :``chainlen``: delta chain length to this revision
508 :``prevrev``: previous revision in delta chain
508 :``prevrev``: previous revision in delta chain
509 :``deltatype``: role of delta / how it was computed
509 :``deltatype``: role of delta / how it was computed
510 :``compsize``: compressed size of revision
510 :``compsize``: compressed size of revision
511 :``uncompsize``: uncompressed size of revision
511 :``uncompsize``: uncompressed size of revision
512 :``chainsize``: total size of compressed revisions in chain
512 :``chainsize``: total size of compressed revisions in chain
513 :``chainratio``: total chain size divided by uncompressed revision size
513 :``chainratio``: total chain size divided by uncompressed revision size
514 (new delta chains typically start at ratio 2.00)
514 (new delta chains typically start at ratio 2.00)
515 :``lindist``: linear distance from base revision in delta chain to end
515 :``lindist``: linear distance from base revision in delta chain to end
516 of this revision
516 of this revision
517 :``extradist``: total size of revisions not part of this delta chain from
517 :``extradist``: total size of revisions not part of this delta chain from
518 base of delta chain to end of this revision; a measurement
518 base of delta chain to end of this revision; a measurement
519 of how much extra data we need to read/seek across to read
519 of how much extra data we need to read/seek across to read
520 the delta chain for this revision
520 the delta chain for this revision
521 :``extraratio``: extradist divided by chainsize; another representation of
521 :``extraratio``: extradist divided by chainsize; another representation of
522 how much unrelated data is needed to load this delta chain
522 how much unrelated data is needed to load this delta chain
523 """
523 """
524 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
524 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
525 index = r.index
525 index = r.index
526 generaldelta = r.version & revlog.FLAG_GENERALDELTA
526 generaldelta = r.version & revlog.FLAG_GENERALDELTA
527
527
528 def revinfo(rev):
528 def revinfo(rev):
529 e = index[rev]
529 e = index[rev]
530 compsize = e[1]
530 compsize = e[1]
531 uncompsize = e[2]
531 uncompsize = e[2]
532 chainsize = 0
532 chainsize = 0
533
533
534 if generaldelta:
534 if generaldelta:
535 if e[3] == e[5]:
535 if e[3] == e[5]:
536 deltatype = 'p1'
536 deltatype = 'p1'
537 elif e[3] == e[6]:
537 elif e[3] == e[6]:
538 deltatype = 'p2'
538 deltatype = 'p2'
539 elif e[3] == rev - 1:
539 elif e[3] == rev - 1:
540 deltatype = 'prev'
540 deltatype = 'prev'
541 elif e[3] == rev:
541 elif e[3] == rev:
542 deltatype = 'base'
542 deltatype = 'base'
543 else:
543 else:
544 deltatype = 'other'
544 deltatype = 'other'
545 else:
545 else:
546 if e[3] == rev:
546 if e[3] == rev:
547 deltatype = 'base'
547 deltatype = 'base'
548 else:
548 else:
549 deltatype = 'prev'
549 deltatype = 'prev'
550
550
551 chain = r._deltachain(rev)[0]
551 chain = r._deltachain(rev)[0]
552 for iterrev in chain:
552 for iterrev in chain:
553 e = index[iterrev]
553 e = index[iterrev]
554 chainsize += e[1]
554 chainsize += e[1]
555
555
556 return compsize, uncompsize, deltatype, chain, chainsize
556 return compsize, uncompsize, deltatype, chain, chainsize
557
557
558 fm = ui.formatter('debugdeltachain', opts)
558 fm = ui.formatter('debugdeltachain', opts)
559
559
560 fm.plain(' rev chain# chainlen prev delta '
560 fm.plain(' rev chain# chainlen prev delta '
561 'size rawsize chainsize ratio lindist extradist '
561 'size rawsize chainsize ratio lindist extradist '
562 'extraratio\n')
562 'extraratio\n')
563
563
564 chainbases = {}
564 chainbases = {}
565 for rev in r:
565 for rev in r:
566 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
566 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
567 chainbase = chain[0]
567 chainbase = chain[0]
568 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
568 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
569 basestart = r.start(chainbase)
569 basestart = r.start(chainbase)
570 revstart = r.start(rev)
570 revstart = r.start(rev)
571 lineardist = revstart + comp - basestart
571 lineardist = revstart + comp - basestart
572 extradist = lineardist - chainsize
572 extradist = lineardist - chainsize
573 try:
573 try:
574 prevrev = chain[-2]
574 prevrev = chain[-2]
575 except IndexError:
575 except IndexError:
576 prevrev = -1
576 prevrev = -1
577
577
578 chainratio = float(chainsize) / float(uncomp)
578 chainratio = float(chainsize) / float(uncomp)
579 extraratio = float(extradist) / float(chainsize)
579 extraratio = float(extradist) / float(chainsize)
580
580
581 fm.startitem()
581 fm.startitem()
582 fm.write('rev chainid chainlen prevrev deltatype compsize '
582 fm.write('rev chainid chainlen prevrev deltatype compsize '
583 'uncompsize chainsize chainratio lindist extradist '
583 'uncompsize chainsize chainratio lindist extradist '
584 'extraratio',
584 'extraratio',
585 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f\n',
585 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f\n',
586 rev, chainid, len(chain), prevrev, deltatype, comp,
586 rev, chainid, len(chain), prevrev, deltatype, comp,
587 uncomp, chainsize, chainratio, lineardist, extradist,
587 uncomp, chainsize, chainratio, lineardist, extradist,
588 extraratio,
588 extraratio,
589 rev=rev, chainid=chainid, chainlen=len(chain),
589 rev=rev, chainid=chainid, chainlen=len(chain),
590 prevrev=prevrev, deltatype=deltatype, compsize=comp,
590 prevrev=prevrev, deltatype=deltatype, compsize=comp,
591 uncompsize=uncomp, chainsize=chainsize,
591 uncompsize=uncomp, chainsize=chainsize,
592 chainratio=chainratio, lindist=lineardist,
592 chainratio=chainratio, lindist=lineardist,
593 extradist=extradist, extraratio=extraratio)
593 extradist=extradist, extraratio=extraratio)
594
594
595 fm.end()
595 fm.end()
596
596
597 @command('debugdirstate|debugstate',
597 @command('debugdirstate|debugstate',
598 [('', 'nodates', None, _('do not display the saved mtime')),
598 [('', 'nodates', None, _('do not display the saved mtime')),
599 ('', 'datesort', None, _('sort by saved mtime'))],
599 ('', 'datesort', None, _('sort by saved mtime'))],
600 _('[OPTION]...'))
600 _('[OPTION]...'))
601 def debugstate(ui, repo, **opts):
601 def debugstate(ui, repo, **opts):
602 """show the contents of the current dirstate"""
602 """show the contents of the current dirstate"""
603
603
604 nodates = opts.get('nodates')
604 nodates = opts.get('nodates')
605 datesort = opts.get('datesort')
605 datesort = opts.get('datesort')
606
606
607 timestr = ""
607 timestr = ""
608 if datesort:
608 if datesort:
609 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
609 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
610 else:
610 else:
611 keyfunc = None # sort by filename
611 keyfunc = None # sort by filename
612 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
612 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
613 if ent[3] == -1:
613 if ent[3] == -1:
614 timestr = 'unset '
614 timestr = 'unset '
615 elif nodates:
615 elif nodates:
616 timestr = 'set '
616 timestr = 'set '
617 else:
617 else:
618 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
618 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
619 time.localtime(ent[3]))
619 time.localtime(ent[3]))
620 if ent[1] & 0o20000:
620 if ent[1] & 0o20000:
621 mode = 'lnk'
621 mode = 'lnk'
622 else:
622 else:
623 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
623 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
624 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
624 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
625 for f in repo.dirstate.copies():
625 for f in repo.dirstate.copies():
626 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
626 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
627
627
628 @command('debugdiscovery',
628 @command('debugdiscovery',
629 [('', 'old', None, _('use old-style discovery')),
629 [('', 'old', None, _('use old-style discovery')),
630 ('', 'nonheads', None,
630 ('', 'nonheads', None,
631 _('use old-style discovery with non-heads included')),
631 _('use old-style discovery with non-heads included')),
632 ] + cmdutil.remoteopts,
632 ] + cmdutil.remoteopts,
633 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
633 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
634 def debugdiscovery(ui, repo, remoteurl="default", **opts):
634 def debugdiscovery(ui, repo, remoteurl="default", **opts):
635 """runs the changeset discovery protocol in isolation"""
635 """runs the changeset discovery protocol in isolation"""
636 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
636 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
637 opts.get('branch'))
637 opts.get('branch'))
638 remote = hg.peer(repo, opts, remoteurl)
638 remote = hg.peer(repo, opts, remoteurl)
639 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
639 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
640
640
641 # make sure tests are repeatable
641 # make sure tests are repeatable
642 random.seed(12323)
642 random.seed(12323)
643
643
644 def doit(localheads, remoteheads, remote=remote):
644 def doit(localheads, remoteheads, remote=remote):
645 if opts.get('old'):
645 if opts.get('old'):
646 if localheads:
646 if localheads:
647 raise error.Abort('cannot use localheads with old style '
647 raise error.Abort('cannot use localheads with old style '
648 'discovery')
648 'discovery')
649 if not util.safehasattr(remote, 'branches'):
649 if not util.safehasattr(remote, 'branches'):
650 # enable in-client legacy support
650 # enable in-client legacy support
651 remote = localrepo.locallegacypeer(remote.local())
651 remote = localrepo.locallegacypeer(remote.local())
652 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
652 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
653 force=True)
653 force=True)
654 common = set(common)
654 common = set(common)
655 if not opts.get('nonheads'):
655 if not opts.get('nonheads'):
656 ui.write(("unpruned common: %s\n") %
656 ui.write(("unpruned common: %s\n") %
657 " ".join(sorted(short(n) for n in common)))
657 " ".join(sorted(short(n) for n in common)))
658 dag = dagutil.revlogdag(repo.changelog)
658 dag = dagutil.revlogdag(repo.changelog)
659 all = dag.ancestorset(dag.internalizeall(common))
659 all = dag.ancestorset(dag.internalizeall(common))
660 common = dag.externalizeall(dag.headsetofconnecteds(all))
660 common = dag.externalizeall(dag.headsetofconnecteds(all))
661 else:
661 else:
662 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
662 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
663 common = set(common)
663 common = set(common)
664 rheads = set(hds)
664 rheads = set(hds)
665 lheads = set(repo.heads())
665 lheads = set(repo.heads())
666 ui.write(("common heads: %s\n") %
666 ui.write(("common heads: %s\n") %
667 " ".join(sorted(short(n) for n in common)))
667 " ".join(sorted(short(n) for n in common)))
668 if lheads <= common:
668 if lheads <= common:
669 ui.write(("local is subset\n"))
669 ui.write(("local is subset\n"))
670 elif rheads <= common:
670 elif rheads <= common:
671 ui.write(("remote is subset\n"))
671 ui.write(("remote is subset\n"))
672
672
673 serverlogs = opts.get('serverlog')
673 serverlogs = opts.get('serverlog')
674 if serverlogs:
674 if serverlogs:
675 for filename in serverlogs:
675 for filename in serverlogs:
676 with open(filename, 'r') as logfile:
676 with open(filename, 'r') as logfile:
677 line = logfile.readline()
677 line = logfile.readline()
678 while line:
678 while line:
679 parts = line.strip().split(';')
679 parts = line.strip().split(';')
680 op = parts[1]
680 op = parts[1]
681 if op == 'cg':
681 if op == 'cg':
682 pass
682 pass
683 elif op == 'cgss':
683 elif op == 'cgss':
684 doit(parts[2].split(' '), parts[3].split(' '))
684 doit(parts[2].split(' '), parts[3].split(' '))
685 elif op == 'unb':
685 elif op == 'unb':
686 doit(parts[3].split(' '), parts[2].split(' '))
686 doit(parts[3].split(' '), parts[2].split(' '))
687 line = logfile.readline()
687 line = logfile.readline()
688 else:
688 else:
689 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
689 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
690 opts.get('remote_head'))
690 opts.get('remote_head'))
691 localrevs = opts.get('local_head')
691 localrevs = opts.get('local_head')
692 doit(localrevs, remoterevs)
692 doit(localrevs, remoterevs)
693
693
694 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
694 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
695 def debugextensions(ui, **opts):
695 def debugextensions(ui, **opts):
696 '''show information about active extensions'''
696 '''show information about active extensions'''
697 exts = extensions.extensions(ui)
697 exts = extensions.extensions(ui)
698 hgver = util.version()
698 hgver = util.version()
699 fm = ui.formatter('debugextensions', opts)
699 fm = ui.formatter('debugextensions', opts)
700 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
700 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
701 isinternal = extensions.ismoduleinternal(extmod)
701 isinternal = extensions.ismoduleinternal(extmod)
702 extsource = pycompat.fsencode(extmod.__file__)
702 extsource = pycompat.fsencode(extmod.__file__)
703 if isinternal:
703 if isinternal:
704 exttestedwith = [] # never expose magic string to users
704 exttestedwith = [] # never expose magic string to users
705 else:
705 else:
706 exttestedwith = getattr(extmod, 'testedwith', '').split()
706 exttestedwith = getattr(extmod, 'testedwith', '').split()
707 extbuglink = getattr(extmod, 'buglink', None)
707 extbuglink = getattr(extmod, 'buglink', None)
708
708
709 fm.startitem()
709 fm.startitem()
710
710
711 if ui.quiet or ui.verbose:
711 if ui.quiet or ui.verbose:
712 fm.write('name', '%s\n', extname)
712 fm.write('name', '%s\n', extname)
713 else:
713 else:
714 fm.write('name', '%s', extname)
714 fm.write('name', '%s', extname)
715 if isinternal or hgver in exttestedwith:
715 if isinternal or hgver in exttestedwith:
716 fm.plain('\n')
716 fm.plain('\n')
717 elif not exttestedwith:
717 elif not exttestedwith:
718 fm.plain(_(' (untested!)\n'))
718 fm.plain(_(' (untested!)\n'))
719 else:
719 else:
720 lasttestedversion = exttestedwith[-1]
720 lasttestedversion = exttestedwith[-1]
721 fm.plain(' (%s!)\n' % lasttestedversion)
721 fm.plain(' (%s!)\n' % lasttestedversion)
722
722
723 fm.condwrite(ui.verbose and extsource, 'source',
723 fm.condwrite(ui.verbose and extsource, 'source',
724 _(' location: %s\n'), extsource or "")
724 _(' location: %s\n'), extsource or "")
725
725
726 if ui.verbose:
726 if ui.verbose:
727 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
727 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
728 fm.data(bundled=isinternal)
728 fm.data(bundled=isinternal)
729
729
730 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
730 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
731 _(' tested with: %s\n'),
731 _(' tested with: %s\n'),
732 fm.formatlist(exttestedwith, name='ver'))
732 fm.formatlist(exttestedwith, name='ver'))
733
733
734 fm.condwrite(ui.verbose and extbuglink, 'buglink',
734 fm.condwrite(ui.verbose and extbuglink, 'buglink',
735 _(' bug reporting: %s\n'), extbuglink or "")
735 _(' bug reporting: %s\n'), extbuglink or "")
736
736
737 fm.end()
737 fm.end()
738
738
739 @command('debugfileset',
739 @command('debugfileset',
740 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
740 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
741 _('[-r REV] FILESPEC'))
741 _('[-r REV] FILESPEC'))
742 def debugfileset(ui, repo, expr, **opts):
742 def debugfileset(ui, repo, expr, **opts):
743 '''parse and apply a fileset specification'''
743 '''parse and apply a fileset specification'''
744 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
744 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
745 if ui.verbose:
745 if ui.verbose:
746 tree = fileset.parse(expr)
746 tree = fileset.parse(expr)
747 ui.note(fileset.prettyformat(tree), "\n")
747 ui.note(fileset.prettyformat(tree), "\n")
748
748
749 for f in ctx.getfileset(expr):
749 for f in ctx.getfileset(expr):
750 ui.write("%s\n" % f)
750 ui.write("%s\n" % f)
751
751
752 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
752 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
753 def debugfsinfo(ui, path="."):
753 def debugfsinfo(ui, path="."):
754 """show information detected about current filesystem"""
754 """show information detected about current filesystem"""
755 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
755 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
756 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
756 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
757 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
757 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
758 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
758 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
759 casesensitive = '(unknown)'
759 casesensitive = '(unknown)'
760 try:
760 try:
761 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
761 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
762 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
762 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
763 except OSError:
763 except OSError:
764 pass
764 pass
765 ui.write(('case-sensitive: %s\n') % casesensitive)
765 ui.write(('case-sensitive: %s\n') % casesensitive)
766
766
767 @command('debuggetbundle',
767 @command('debuggetbundle',
768 [('H', 'head', [], _('id of head node'), _('ID')),
768 [('H', 'head', [], _('id of head node'), _('ID')),
769 ('C', 'common', [], _('id of common node'), _('ID')),
769 ('C', 'common', [], _('id of common node'), _('ID')),
770 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
770 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
771 _('REPO FILE [-H|-C ID]...'),
771 _('REPO FILE [-H|-C ID]...'),
772 norepo=True)
772 norepo=True)
773 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
773 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
774 """retrieves a bundle from a repo
774 """retrieves a bundle from a repo
775
775
776 Every ID must be a full-length hex node id string. Saves the bundle to the
776 Every ID must be a full-length hex node id string. Saves the bundle to the
777 given file.
777 given file.
778 """
778 """
779 repo = hg.peer(ui, opts, repopath)
779 repo = hg.peer(ui, opts, repopath)
780 if not repo.capable('getbundle'):
780 if not repo.capable('getbundle'):
781 raise error.Abort("getbundle() not supported by target repository")
781 raise error.Abort("getbundle() not supported by target repository")
782 args = {}
782 args = {}
783 if common:
783 if common:
784 args['common'] = [bin(s) for s in common]
784 args['common'] = [bin(s) for s in common]
785 if head:
785 if head:
786 args['heads'] = [bin(s) for s in head]
786 args['heads'] = [bin(s) for s in head]
787 # TODO: get desired bundlecaps from command line.
787 # TODO: get desired bundlecaps from command line.
788 args['bundlecaps'] = None
788 args['bundlecaps'] = None
789 bundle = repo.getbundle('debug', **args)
789 bundle = repo.getbundle('debug', **args)
790
790
791 bundletype = opts.get('type', 'bzip2').lower()
791 bundletype = opts.get('type', 'bzip2').lower()
792 btypes = {'none': 'HG10UN',
792 btypes = {'none': 'HG10UN',
793 'bzip2': 'HG10BZ',
793 'bzip2': 'HG10BZ',
794 'gzip': 'HG10GZ',
794 'gzip': 'HG10GZ',
795 'bundle2': 'HG20'}
795 'bundle2': 'HG20'}
796 bundletype = btypes.get(bundletype)
796 bundletype = btypes.get(bundletype)
797 if bundletype not in bundle2.bundletypes:
797 if bundletype not in bundle2.bundletypes:
798 raise error.Abort(_('unknown bundle type specified with --type'))
798 raise error.Abort(_('unknown bundle type specified with --type'))
799 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
799 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
800
800
801 @command('debugignore', [], '[FILE]')
801 @command('debugignore', [], '[FILE]')
802 def debugignore(ui, repo, *files, **opts):
802 def debugignore(ui, repo, *files, **opts):
803 """display the combined ignore pattern and information about ignored files
803 """display the combined ignore pattern and information about ignored files
804
804
805 With no argument display the combined ignore pattern.
805 With no argument display the combined ignore pattern.
806
806
807 Given space separated file names, shows if the given file is ignored and
807 Given space separated file names, shows if the given file is ignored and
808 if so, show the ignore rule (file and line number) that matched it.
808 if so, show the ignore rule (file and line number) that matched it.
809 """
809 """
810 ignore = repo.dirstate._ignore
810 ignore = repo.dirstate._ignore
811 if not files:
811 if not files:
812 # Show all the patterns
812 # Show all the patterns
813 ui.write("%s\n" % repr(ignore))
813 ui.write("%s\n" % repr(ignore))
814 else:
814 else:
815 for f in files:
815 for f in files:
816 nf = util.normpath(f)
816 nf = util.normpath(f)
817 ignored = None
817 ignored = None
818 ignoredata = None
818 ignoredata = None
819 if nf != '.':
819 if nf != '.':
820 if ignore(nf):
820 if ignore(nf):
821 ignored = nf
821 ignored = nf
822 ignoredata = repo.dirstate._ignorefileandline(nf)
822 ignoredata = repo.dirstate._ignorefileandline(nf)
823 else:
823 else:
824 for p in util.finddirs(nf):
824 for p in util.finddirs(nf):
825 if ignore(p):
825 if ignore(p):
826 ignored = p
826 ignored = p
827 ignoredata = repo.dirstate._ignorefileandline(p)
827 ignoredata = repo.dirstate._ignorefileandline(p)
828 break
828 break
829 if ignored:
829 if ignored:
830 if ignored == nf:
830 if ignored == nf:
831 ui.write(_("%s is ignored\n") % f)
831 ui.write(_("%s is ignored\n") % f)
832 else:
832 else:
833 ui.write(_("%s is ignored because of "
833 ui.write(_("%s is ignored because of "
834 "containing folder %s\n")
834 "containing folder %s\n")
835 % (f, ignored))
835 % (f, ignored))
836 ignorefile, lineno, line = ignoredata
836 ignorefile, lineno, line = ignoredata
837 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
837 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
838 % (ignorefile, lineno, line))
838 % (ignorefile, lineno, line))
839 else:
839 else:
840 ui.write(_("%s is not ignored\n") % f)
840 ui.write(_("%s is not ignored\n") % f)
841
841
842 @command('debugindex', cmdutil.debugrevlogopts +
842 @command('debugindex', cmdutil.debugrevlogopts +
843 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
843 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
844 _('[-f FORMAT] -c|-m|FILE'),
844 _('[-f FORMAT] -c|-m|FILE'),
845 optionalrepo=True)
845 optionalrepo=True)
846 def debugindex(ui, repo, file_=None, **opts):
846 def debugindex(ui, repo, file_=None, **opts):
847 """dump the contents of an index file"""
847 """dump the contents of an index file"""
848 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
848 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
849 format = opts.get('format', 0)
849 format = opts.get('format', 0)
850 if format not in (0, 1):
850 if format not in (0, 1):
851 raise error.Abort(_("unknown format %d") % format)
851 raise error.Abort(_("unknown format %d") % format)
852
852
853 generaldelta = r.version & revlog.FLAG_GENERALDELTA
853 generaldelta = r.version & revlog.FLAG_GENERALDELTA
854 if generaldelta:
854 if generaldelta:
855 basehdr = ' delta'
855 basehdr = ' delta'
856 else:
856 else:
857 basehdr = ' base'
857 basehdr = ' base'
858
858
859 if ui.debugflag:
859 if ui.debugflag:
860 shortfn = hex
860 shortfn = hex
861 else:
861 else:
862 shortfn = short
862 shortfn = short
863
863
864 # There might not be anything in r, so have a sane default
864 # There might not be anything in r, so have a sane default
865 idlen = 12
865 idlen = 12
866 for i in r:
866 for i in r:
867 idlen = len(shortfn(r.node(i)))
867 idlen = len(shortfn(r.node(i)))
868 break
868 break
869
869
870 if format == 0:
870 if format == 0:
871 ui.write((" rev offset length " + basehdr + " linkrev"
871 ui.write((" rev offset length " + basehdr + " linkrev"
872 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
872 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
873 elif format == 1:
873 elif format == 1:
874 ui.write((" rev flag offset length"
874 ui.write((" rev flag offset length"
875 " size " + basehdr + " link p1 p2"
875 " size " + basehdr + " link p1 p2"
876 " %s\n") % "nodeid".rjust(idlen))
876 " %s\n") % "nodeid".rjust(idlen))
877
877
878 for i in r:
878 for i in r:
879 node = r.node(i)
879 node = r.node(i)
880 if generaldelta:
880 if generaldelta:
881 base = r.deltaparent(i)
881 base = r.deltaparent(i)
882 else:
882 else:
883 base = r.chainbase(i)
883 base = r.chainbase(i)
884 if format == 0:
884 if format == 0:
885 try:
885 try:
886 pp = r.parents(node)
886 pp = r.parents(node)
887 except Exception:
887 except Exception:
888 pp = [nullid, nullid]
888 pp = [nullid, nullid]
889 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
889 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
890 i, r.start(i), r.length(i), base, r.linkrev(i),
890 i, r.start(i), r.length(i), base, r.linkrev(i),
891 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
891 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
892 elif format == 1:
892 elif format == 1:
893 pr = r.parentrevs(i)
893 pr = r.parentrevs(i)
894 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
894 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
895 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
895 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
896 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
896 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
897
897
898 @command('debugindexdot', cmdutil.debugrevlogopts,
898 @command('debugindexdot', cmdutil.debugrevlogopts,
899 _('-c|-m|FILE'), optionalrepo=True)
899 _('-c|-m|FILE'), optionalrepo=True)
900 def debugindexdot(ui, repo, file_=None, **opts):
900 def debugindexdot(ui, repo, file_=None, **opts):
901 """dump an index DAG as a graphviz dot file"""
901 """dump an index DAG as a graphviz dot file"""
902 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
902 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
903 ui.write(("digraph G {\n"))
903 ui.write(("digraph G {\n"))
904 for i in r:
904 for i in r:
905 node = r.node(i)
905 node = r.node(i)
906 pp = r.parents(node)
906 pp = r.parents(node)
907 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
907 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
908 if pp[1] != nullid:
908 if pp[1] != nullid:
909 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
909 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
910 ui.write("}\n")
910 ui.write("}\n")
911
911
912 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
912 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
913 def debuginstall(ui, **opts):
913 def debuginstall(ui, **opts):
914 '''test Mercurial installation
914 '''test Mercurial installation
915
915
916 Returns 0 on success.
916 Returns 0 on success.
917 '''
917 '''
918
918
919 def writetemp(contents):
919 def writetemp(contents):
920 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
920 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
921 f = os.fdopen(fd, pycompat.sysstr("wb"))
921 f = os.fdopen(fd, pycompat.sysstr("wb"))
922 f.write(contents)
922 f.write(contents)
923 f.close()
923 f.close()
924 return name
924 return name
925
925
926 problems = 0
926 problems = 0
927
927
928 fm = ui.formatter('debuginstall', opts)
928 fm = ui.formatter('debuginstall', opts)
929 fm.startitem()
929 fm.startitem()
930
930
931 # encoding
931 # encoding
932 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
932 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
933 err = None
933 err = None
934 try:
934 try:
935 encoding.fromlocal("test")
935 encoding.fromlocal("test")
936 except error.Abort as inst:
936 except error.Abort as inst:
937 err = inst
937 err = inst
938 problems += 1
938 problems += 1
939 fm.condwrite(err, 'encodingerror', _(" %s\n"
939 fm.condwrite(err, 'encodingerror', _(" %s\n"
940 " (check that your locale is properly set)\n"), err)
940 " (check that your locale is properly set)\n"), err)
941
941
942 # Python
942 # Python
943 fm.write('pythonexe', _("checking Python executable (%s)\n"),
943 fm.write('pythonexe', _("checking Python executable (%s)\n"),
944 pycompat.sysexecutable)
944 pycompat.sysexecutable)
945 fm.write('pythonver', _("checking Python version (%s)\n"),
945 fm.write('pythonver', _("checking Python version (%s)\n"),
946 ("%d.%d.%d" % sys.version_info[:3]))
946 ("%d.%d.%d" % sys.version_info[:3]))
947 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
947 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
948 os.path.dirname(pycompat.fsencode(os.__file__)))
948 os.path.dirname(pycompat.fsencode(os.__file__)))
949
949
950 security = set(sslutil.supportedprotocols)
950 security = set(sslutil.supportedprotocols)
951 if sslutil.hassni:
951 if sslutil.hassni:
952 security.add('sni')
952 security.add('sni')
953
953
954 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
954 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
955 fm.formatlist(sorted(security), name='protocol',
955 fm.formatlist(sorted(security), name='protocol',
956 fmt='%s', sep=','))
956 fmt='%s', sep=','))
957
957
958 # These are warnings, not errors. So don't increment problem count. This
958 # These are warnings, not errors. So don't increment problem count. This
959 # may change in the future.
959 # may change in the future.
960 if 'tls1.2' not in security:
960 if 'tls1.2' not in security:
961 fm.plain(_(' TLS 1.2 not supported by Python install; '
961 fm.plain(_(' TLS 1.2 not supported by Python install; '
962 'network connections lack modern security\n'))
962 'network connections lack modern security\n'))
963 if 'sni' not in security:
963 if 'sni' not in security:
964 fm.plain(_(' SNI not supported by Python install; may have '
964 fm.plain(_(' SNI not supported by Python install; may have '
965 'connectivity issues with some servers\n'))
965 'connectivity issues with some servers\n'))
966
966
967 # TODO print CA cert info
967 # TODO print CA cert info
968
968
969 # hg version
969 # hg version
970 hgver = util.version()
970 hgver = util.version()
971 fm.write('hgver', _("checking Mercurial version (%s)\n"),
971 fm.write('hgver', _("checking Mercurial version (%s)\n"),
972 hgver.split('+')[0])
972 hgver.split('+')[0])
973 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
973 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
974 '+'.join(hgver.split('+')[1:]))
974 '+'.join(hgver.split('+')[1:]))
975
975
976 # compiled modules
976 # compiled modules
977 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
977 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
978 policy.policy)
978 policy.policy)
979 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
979 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
980 os.path.dirname(pycompat.fsencode(__file__)))
980 os.path.dirname(pycompat.fsencode(__file__)))
981
981
982 if policy.policy in ('c', 'allow'):
982 if policy.policy in ('c', 'allow'):
983 err = None
983 err = None
984 try:
984 try:
985 from .cext import (
985 from .cext import (
986 base85,
986 base85,
987 bdiff,
987 bdiff,
988 mpatch,
988 mpatch,
989 osutil,
989 osutil,
990 )
990 )
991 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
991 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
992 except Exception as inst:
992 except Exception as inst:
993 err = inst
993 err = inst
994 problems += 1
994 problems += 1
995 fm.condwrite(err, 'extensionserror', " %s\n", err)
995 fm.condwrite(err, 'extensionserror', " %s\n", err)
996
996
997 compengines = util.compengines._engines.values()
997 compengines = util.compengines._engines.values()
998 fm.write('compengines', _('checking registered compression engines (%s)\n'),
998 fm.write('compengines', _('checking registered compression engines (%s)\n'),
999 fm.formatlist(sorted(e.name() for e in compengines),
999 fm.formatlist(sorted(e.name() for e in compengines),
1000 name='compengine', fmt='%s', sep=', '))
1000 name='compengine', fmt='%s', sep=', '))
1001 fm.write('compenginesavail', _('checking available compression engines '
1001 fm.write('compenginesavail', _('checking available compression engines '
1002 '(%s)\n'),
1002 '(%s)\n'),
1003 fm.formatlist(sorted(e.name() for e in compengines
1003 fm.formatlist(sorted(e.name() for e in compengines
1004 if e.available()),
1004 if e.available()),
1005 name='compengine', fmt='%s', sep=', '))
1005 name='compengine', fmt='%s', sep=', '))
1006 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1006 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1007 fm.write('compenginesserver', _('checking available compression engines '
1007 fm.write('compenginesserver', _('checking available compression engines '
1008 'for wire protocol (%s)\n'),
1008 'for wire protocol (%s)\n'),
1009 fm.formatlist([e.name() for e in wirecompengines
1009 fm.formatlist([e.name() for e in wirecompengines
1010 if e.wireprotosupport()],
1010 if e.wireprotosupport()],
1011 name='compengine', fmt='%s', sep=', '))
1011 name='compengine', fmt='%s', sep=', '))
1012
1012
1013 # templates
1013 # templates
1014 p = templater.templatepaths()
1014 p = templater.templatepaths()
1015 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1015 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1016 fm.condwrite(not p, '', _(" no template directories found\n"))
1016 fm.condwrite(not p, '', _(" no template directories found\n"))
1017 if p:
1017 if p:
1018 m = templater.templatepath("map-cmdline.default")
1018 m = templater.templatepath("map-cmdline.default")
1019 if m:
1019 if m:
1020 # template found, check if it is working
1020 # template found, check if it is working
1021 err = None
1021 err = None
1022 try:
1022 try:
1023 templater.templater.frommapfile(m)
1023 templater.templater.frommapfile(m)
1024 except Exception as inst:
1024 except Exception as inst:
1025 err = inst
1025 err = inst
1026 p = None
1026 p = None
1027 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1027 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1028 else:
1028 else:
1029 p = None
1029 p = None
1030 fm.condwrite(p, 'defaulttemplate',
1030 fm.condwrite(p, 'defaulttemplate',
1031 _("checking default template (%s)\n"), m)
1031 _("checking default template (%s)\n"), m)
1032 fm.condwrite(not m, 'defaulttemplatenotfound',
1032 fm.condwrite(not m, 'defaulttemplatenotfound',
1033 _(" template '%s' not found\n"), "default")
1033 _(" template '%s' not found\n"), "default")
1034 if not p:
1034 if not p:
1035 problems += 1
1035 problems += 1
1036 fm.condwrite(not p, '',
1036 fm.condwrite(not p, '',
1037 _(" (templates seem to have been installed incorrectly)\n"))
1037 _(" (templates seem to have been installed incorrectly)\n"))
1038
1038
1039 # editor
1039 # editor
1040 editor = ui.geteditor()
1040 editor = ui.geteditor()
1041 editor = util.expandpath(editor)
1041 editor = util.expandpath(editor)
1042 fm.write('editor', _("checking commit editor... (%s)\n"), editor)
1042 fm.write('editor', _("checking commit editor... (%s)\n"), editor)
1043 cmdpath = util.findexe(pycompat.shlexsplit(editor)[0])
1043 cmdpath = util.findexe(pycompat.shlexsplit(editor)[0])
1044 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1044 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1045 _(" No commit editor set and can't find %s in PATH\n"
1045 _(" No commit editor set and can't find %s in PATH\n"
1046 " (specify a commit editor in your configuration"
1046 " (specify a commit editor in your configuration"
1047 " file)\n"), not cmdpath and editor == 'vi' and editor)
1047 " file)\n"), not cmdpath and editor == 'vi' and editor)
1048 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1048 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1049 _(" Can't find editor '%s' in PATH\n"
1049 _(" Can't find editor '%s' in PATH\n"
1050 " (specify a commit editor in your configuration"
1050 " (specify a commit editor in your configuration"
1051 " file)\n"), not cmdpath and editor)
1051 " file)\n"), not cmdpath and editor)
1052 if not cmdpath and editor != 'vi':
1052 if not cmdpath and editor != 'vi':
1053 problems += 1
1053 problems += 1
1054
1054
1055 # check username
1055 # check username
1056 username = None
1056 username = None
1057 err = None
1057 err = None
1058 try:
1058 try:
1059 username = ui.username()
1059 username = ui.username()
1060 except error.Abort as e:
1060 except error.Abort as e:
1061 err = e
1061 err = e
1062 problems += 1
1062 problems += 1
1063
1063
1064 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1064 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1065 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1065 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1066 " (specify a username in your configuration file)\n"), err)
1066 " (specify a username in your configuration file)\n"), err)
1067
1067
1068 fm.condwrite(not problems, '',
1068 fm.condwrite(not problems, '',
1069 _("no problems detected\n"))
1069 _("no problems detected\n"))
1070 if not problems:
1070 if not problems:
1071 fm.data(problems=problems)
1071 fm.data(problems=problems)
1072 fm.condwrite(problems, 'problems',
1072 fm.condwrite(problems, 'problems',
1073 _("%d problems detected,"
1073 _("%d problems detected,"
1074 " please check your install!\n"), problems)
1074 " please check your install!\n"), problems)
1075 fm.end()
1075 fm.end()
1076
1076
1077 return problems
1077 return problems
1078
1078
1079 @command('debugknown', [], _('REPO ID...'), norepo=True)
1079 @command('debugknown', [], _('REPO ID...'), norepo=True)
1080 def debugknown(ui, repopath, *ids, **opts):
1080 def debugknown(ui, repopath, *ids, **opts):
1081 """test whether node ids are known to a repo
1081 """test whether node ids are known to a repo
1082
1082
1083 Every ID must be a full-length hex node id string. Returns a list of 0s
1083 Every ID must be a full-length hex node id string. Returns a list of 0s
1084 and 1s indicating unknown/known.
1084 and 1s indicating unknown/known.
1085 """
1085 """
1086 repo = hg.peer(ui, opts, repopath)
1086 repo = hg.peer(ui, opts, repopath)
1087 if not repo.capable('known'):
1087 if not repo.capable('known'):
1088 raise error.Abort("known() not supported by target repository")
1088 raise error.Abort("known() not supported by target repository")
1089 flags = repo.known([bin(s) for s in ids])
1089 flags = repo.known([bin(s) for s in ids])
1090 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1090 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1091
1091
1092 @command('debuglabelcomplete', [], _('LABEL...'))
1092 @command('debuglabelcomplete', [], _('LABEL...'))
1093 def debuglabelcomplete(ui, repo, *args):
1093 def debuglabelcomplete(ui, repo, *args):
1094 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1094 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1095 debugnamecomplete(ui, repo, *args)
1095 debugnamecomplete(ui, repo, *args)
1096
1096
1097 @command('debuglocks',
1097 @command('debuglocks',
1098 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1098 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1099 ('W', 'force-wlock', None,
1099 ('W', 'force-wlock', None,
1100 _('free the working state lock (DANGEROUS)'))],
1100 _('free the working state lock (DANGEROUS)'))],
1101 _('[OPTION]...'))
1101 _('[OPTION]...'))
1102 def debuglocks(ui, repo, **opts):
1102 def debuglocks(ui, repo, **opts):
1103 """show or modify state of locks
1103 """show or modify state of locks
1104
1104
1105 By default, this command will show which locks are held. This
1105 By default, this command will show which locks are held. This
1106 includes the user and process holding the lock, the amount of time
1106 includes the user and process holding the lock, the amount of time
1107 the lock has been held, and the machine name where the process is
1107 the lock has been held, and the machine name where the process is
1108 running if it's not local.
1108 running if it's not local.
1109
1109
1110 Locks protect the integrity of Mercurial's data, so should be
1110 Locks protect the integrity of Mercurial's data, so should be
1111 treated with care. System crashes or other interruptions may cause
1111 treated with care. System crashes or other interruptions may cause
1112 locks to not be properly released, though Mercurial will usually
1112 locks to not be properly released, though Mercurial will usually
1113 detect and remove such stale locks automatically.
1113 detect and remove such stale locks automatically.
1114
1114
1115 However, detecting stale locks may not always be possible (for
1115 However, detecting stale locks may not always be possible (for
1116 instance, on a shared filesystem). Removing locks may also be
1116 instance, on a shared filesystem). Removing locks may also be
1117 blocked by filesystem permissions.
1117 blocked by filesystem permissions.
1118
1118
1119 Returns 0 if no locks are held.
1119 Returns 0 if no locks are held.
1120
1120
1121 """
1121 """
1122
1122
1123 if opts.get('force_lock'):
1123 if opts.get('force_lock'):
1124 repo.svfs.unlink('lock')
1124 repo.svfs.unlink('lock')
1125 if opts.get('force_wlock'):
1125 if opts.get('force_wlock'):
1126 repo.vfs.unlink('wlock')
1126 repo.vfs.unlink('wlock')
1127 if opts.get('force_lock') or opts.get('force_lock'):
1127 if opts.get('force_lock') or opts.get('force_lock'):
1128 return 0
1128 return 0
1129
1129
1130 now = time.time()
1130 now = time.time()
1131 held = 0
1131 held = 0
1132
1132
1133 def report(vfs, name, method):
1133 def report(vfs, name, method):
1134 # this causes stale locks to get reaped for more accurate reporting
1134 # this causes stale locks to get reaped for more accurate reporting
1135 try:
1135 try:
1136 l = method(False)
1136 l = method(False)
1137 except error.LockHeld:
1137 except error.LockHeld:
1138 l = None
1138 l = None
1139
1139
1140 if l:
1140 if l:
1141 l.release()
1141 l.release()
1142 else:
1142 else:
1143 try:
1143 try:
1144 stat = vfs.lstat(name)
1144 stat = vfs.lstat(name)
1145 age = now - stat.st_mtime
1145 age = now - stat.st_mtime
1146 user = util.username(stat.st_uid)
1146 user = util.username(stat.st_uid)
1147 locker = vfs.readlock(name)
1147 locker = vfs.readlock(name)
1148 if ":" in locker:
1148 if ":" in locker:
1149 host, pid = locker.split(':')
1149 host, pid = locker.split(':')
1150 if host == socket.gethostname():
1150 if host == socket.gethostname():
1151 locker = 'user %s, process %s' % (user, pid)
1151 locker = 'user %s, process %s' % (user, pid)
1152 else:
1152 else:
1153 locker = 'user %s, process %s, host %s' \
1153 locker = 'user %s, process %s, host %s' \
1154 % (user, pid, host)
1154 % (user, pid, host)
1155 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1155 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1156 return 1
1156 return 1
1157 except OSError as e:
1157 except OSError as e:
1158 if e.errno != errno.ENOENT:
1158 if e.errno != errno.ENOENT:
1159 raise
1159 raise
1160
1160
1161 ui.write(("%-6s free\n") % (name + ":"))
1161 ui.write(("%-6s free\n") % (name + ":"))
1162 return 0
1162 return 0
1163
1163
1164 held += report(repo.svfs, "lock", repo.lock)
1164 held += report(repo.svfs, "lock", repo.lock)
1165 held += report(repo.vfs, "wlock", repo.wlock)
1165 held += report(repo.vfs, "wlock", repo.wlock)
1166
1166
1167 return held
1167 return held
1168
1168
1169 @command('debugmergestate', [], '')
1169 @command('debugmergestate', [], '')
1170 def debugmergestate(ui, repo, *args):
1170 def debugmergestate(ui, repo, *args):
1171 """print merge state
1171 """print merge state
1172
1172
1173 Use --verbose to print out information about whether v1 or v2 merge state
1173 Use --verbose to print out information about whether v1 or v2 merge state
1174 was chosen."""
1174 was chosen."""
1175 def _hashornull(h):
1175 def _hashornull(h):
1176 if h == nullhex:
1176 if h == nullhex:
1177 return 'null'
1177 return 'null'
1178 else:
1178 else:
1179 return h
1179 return h
1180
1180
1181 def printrecords(version):
1181 def printrecords(version):
1182 ui.write(('* version %s records\n') % version)
1182 ui.write(('* version %s records\n') % version)
1183 if version == 1:
1183 if version == 1:
1184 records = v1records
1184 records = v1records
1185 else:
1185 else:
1186 records = v2records
1186 records = v2records
1187
1187
1188 for rtype, record in records:
1188 for rtype, record in records:
1189 # pretty print some record types
1189 # pretty print some record types
1190 if rtype == 'L':
1190 if rtype == 'L':
1191 ui.write(('local: %s\n') % record)
1191 ui.write(('local: %s\n') % record)
1192 elif rtype == 'O':
1192 elif rtype == 'O':
1193 ui.write(('other: %s\n') % record)
1193 ui.write(('other: %s\n') % record)
1194 elif rtype == 'm':
1194 elif rtype == 'm':
1195 driver, mdstate = record.split('\0', 1)
1195 driver, mdstate = record.split('\0', 1)
1196 ui.write(('merge driver: %s (state "%s")\n')
1196 ui.write(('merge driver: %s (state "%s")\n')
1197 % (driver, mdstate))
1197 % (driver, mdstate))
1198 elif rtype in 'FDC':
1198 elif rtype in 'FDC':
1199 r = record.split('\0')
1199 r = record.split('\0')
1200 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1200 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1201 if version == 1:
1201 if version == 1:
1202 onode = 'not stored in v1 format'
1202 onode = 'not stored in v1 format'
1203 flags = r[7]
1203 flags = r[7]
1204 else:
1204 else:
1205 onode, flags = r[7:9]
1205 onode, flags = r[7:9]
1206 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1206 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1207 % (f, rtype, state, _hashornull(hash)))
1207 % (f, rtype, state, _hashornull(hash)))
1208 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1208 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1209 ui.write((' ancestor path: %s (node %s)\n')
1209 ui.write((' ancestor path: %s (node %s)\n')
1210 % (afile, _hashornull(anode)))
1210 % (afile, _hashornull(anode)))
1211 ui.write((' other path: %s (node %s)\n')
1211 ui.write((' other path: %s (node %s)\n')
1212 % (ofile, _hashornull(onode)))
1212 % (ofile, _hashornull(onode)))
1213 elif rtype == 'f':
1213 elif rtype == 'f':
1214 filename, rawextras = record.split('\0', 1)
1214 filename, rawextras = record.split('\0', 1)
1215 extras = rawextras.split('\0')
1215 extras = rawextras.split('\0')
1216 i = 0
1216 i = 0
1217 extrastrings = []
1217 extrastrings = []
1218 while i < len(extras):
1218 while i < len(extras):
1219 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1219 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1220 i += 2
1220 i += 2
1221
1221
1222 ui.write(('file extras: %s (%s)\n')
1222 ui.write(('file extras: %s (%s)\n')
1223 % (filename, ', '.join(extrastrings)))
1223 % (filename, ', '.join(extrastrings)))
1224 elif rtype == 'l':
1224 elif rtype == 'l':
1225 labels = record.split('\0', 2)
1225 labels = record.split('\0', 2)
1226 labels = [l for l in labels if len(l) > 0]
1226 labels = [l for l in labels if len(l) > 0]
1227 ui.write(('labels:\n'))
1227 ui.write(('labels:\n'))
1228 ui.write((' local: %s\n' % labels[0]))
1228 ui.write((' local: %s\n' % labels[0]))
1229 ui.write((' other: %s\n' % labels[1]))
1229 ui.write((' other: %s\n' % labels[1]))
1230 if len(labels) > 2:
1230 if len(labels) > 2:
1231 ui.write((' base: %s\n' % labels[2]))
1231 ui.write((' base: %s\n' % labels[2]))
1232 else:
1232 else:
1233 ui.write(('unrecognized entry: %s\t%s\n')
1233 ui.write(('unrecognized entry: %s\t%s\n')
1234 % (rtype, record.replace('\0', '\t')))
1234 % (rtype, record.replace('\0', '\t')))
1235
1235
1236 # Avoid mergestate.read() since it may raise an exception for unsupported
1236 # Avoid mergestate.read() since it may raise an exception for unsupported
1237 # merge state records. We shouldn't be doing this, but this is OK since this
1237 # merge state records. We shouldn't be doing this, but this is OK since this
1238 # command is pretty low-level.
1238 # command is pretty low-level.
1239 ms = mergemod.mergestate(repo)
1239 ms = mergemod.mergestate(repo)
1240
1240
1241 # sort so that reasonable information is on top
1241 # sort so that reasonable information is on top
1242 v1records = ms._readrecordsv1()
1242 v1records = ms._readrecordsv1()
1243 v2records = ms._readrecordsv2()
1243 v2records = ms._readrecordsv2()
1244 order = 'LOml'
1244 order = 'LOml'
1245 def key(r):
1245 def key(r):
1246 idx = order.find(r[0])
1246 idx = order.find(r[0])
1247 if idx == -1:
1247 if idx == -1:
1248 return (1, r[1])
1248 return (1, r[1])
1249 else:
1249 else:
1250 return (0, idx)
1250 return (0, idx)
1251 v1records.sort(key=key)
1251 v1records.sort(key=key)
1252 v2records.sort(key=key)
1252 v2records.sort(key=key)
1253
1253
1254 if not v1records and not v2records:
1254 if not v1records and not v2records:
1255 ui.write(('no merge state found\n'))
1255 ui.write(('no merge state found\n'))
1256 elif not v2records:
1256 elif not v2records:
1257 ui.note(('no version 2 merge state\n'))
1257 ui.note(('no version 2 merge state\n'))
1258 printrecords(1)
1258 printrecords(1)
1259 elif ms._v1v2match(v1records, v2records):
1259 elif ms._v1v2match(v1records, v2records):
1260 ui.note(('v1 and v2 states match: using v2\n'))
1260 ui.note(('v1 and v2 states match: using v2\n'))
1261 printrecords(2)
1261 printrecords(2)
1262 else:
1262 else:
1263 ui.note(('v1 and v2 states mismatch: using v1\n'))
1263 ui.note(('v1 and v2 states mismatch: using v1\n'))
1264 printrecords(1)
1264 printrecords(1)
1265 if ui.verbose:
1265 if ui.verbose:
1266 printrecords(2)
1266 printrecords(2)
1267
1267
1268 @command('debugnamecomplete', [], _('NAME...'))
1268 @command('debugnamecomplete', [], _('NAME...'))
1269 def debugnamecomplete(ui, repo, *args):
1269 def debugnamecomplete(ui, repo, *args):
1270 '''complete "names" - tags, open branch names, bookmark names'''
1270 '''complete "names" - tags, open branch names, bookmark names'''
1271
1271
1272 names = set()
1272 names = set()
1273 # since we previously only listed open branches, we will handle that
1273 # since we previously only listed open branches, we will handle that
1274 # specially (after this for loop)
1274 # specially (after this for loop)
1275 for name, ns in repo.names.iteritems():
1275 for name, ns in repo.names.iteritems():
1276 if name != 'branches':
1276 if name != 'branches':
1277 names.update(ns.listnames(repo))
1277 names.update(ns.listnames(repo))
1278 names.update(tag for (tag, heads, tip, closed)
1278 names.update(tag for (tag, heads, tip, closed)
1279 in repo.branchmap().iterbranches() if not closed)
1279 in repo.branchmap().iterbranches() if not closed)
1280 completions = set()
1280 completions = set()
1281 if not args:
1281 if not args:
1282 args = ['']
1282 args = ['']
1283 for a in args:
1283 for a in args:
1284 completions.update(n for n in names if n.startswith(a))
1284 completions.update(n for n in names if n.startswith(a))
1285 ui.write('\n'.join(sorted(completions)))
1285 ui.write('\n'.join(sorted(completions)))
1286 ui.write('\n')
1286 ui.write('\n')
1287
1287
1288 @command('debugobsolete',
1288 @command('debugobsolete',
1289 [('', 'flags', 0, _('markers flag')),
1289 [('', 'flags', 0, _('markers flag')),
1290 ('', 'record-parents', False,
1290 ('', 'record-parents', False,
1291 _('record parent information for the precursor')),
1291 _('record parent information for the precursor')),
1292 ('r', 'rev', [], _('display markers relevant to REV')),
1292 ('r', 'rev', [], _('display markers relevant to REV')),
1293 ('', 'index', False, _('display index of the marker')),
1293 ('', 'index', False, _('display index of the marker')),
1294 ('', 'delete', [], _('delete markers specified by indices')),
1294 ('', 'delete', [], _('delete markers specified by indices')),
1295 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1295 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1296 _('[OBSOLETED [REPLACEMENT ...]]'))
1296 _('[OBSOLETED [REPLACEMENT ...]]'))
1297 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1297 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1298 """create arbitrary obsolete marker
1298 """create arbitrary obsolete marker
1299
1299
1300 With no arguments, displays the list of obsolescence markers."""
1300 With no arguments, displays the list of obsolescence markers."""
1301
1301
1302 def parsenodeid(s):
1302 def parsenodeid(s):
1303 try:
1303 try:
1304 # We do not use revsingle/revrange functions here to accept
1304 # We do not use revsingle/revrange functions here to accept
1305 # arbitrary node identifiers, possibly not present in the
1305 # arbitrary node identifiers, possibly not present in the
1306 # local repository.
1306 # local repository.
1307 n = bin(s)
1307 n = bin(s)
1308 if len(n) != len(nullid):
1308 if len(n) != len(nullid):
1309 raise TypeError()
1309 raise TypeError()
1310 return n
1310 return n
1311 except TypeError:
1311 except TypeError:
1312 raise error.Abort('changeset references must be full hexadecimal '
1312 raise error.Abort('changeset references must be full hexadecimal '
1313 'node identifiers')
1313 'node identifiers')
1314
1314
1315 if opts.get('delete'):
1315 if opts.get('delete'):
1316 indices = []
1316 indices = []
1317 for v in opts.get('delete'):
1317 for v in opts.get('delete'):
1318 try:
1318 try:
1319 indices.append(int(v))
1319 indices.append(int(v))
1320 except ValueError:
1320 except ValueError:
1321 raise error.Abort(_('invalid index value: %r') % v,
1321 raise error.Abort(_('invalid index value: %r') % v,
1322 hint=_('use integers for indices'))
1322 hint=_('use integers for indices'))
1323
1323
1324 if repo.currenttransaction():
1324 if repo.currenttransaction():
1325 raise error.Abort(_('cannot delete obsmarkers in the middle '
1325 raise error.Abort(_('cannot delete obsmarkers in the middle '
1326 'of transaction.'))
1326 'of transaction.'))
1327
1327
1328 with repo.lock():
1328 with repo.lock():
1329 n = repair.deleteobsmarkers(repo.obsstore, indices)
1329 n = repair.deleteobsmarkers(repo.obsstore, indices)
1330 ui.write(_('deleted %i obsolescence markers\n') % n)
1330 ui.write(_('deleted %i obsolescence markers\n') % n)
1331
1331
1332 return
1332 return
1333
1333
1334 if precursor is not None:
1334 if precursor is not None:
1335 if opts['rev']:
1335 if opts['rev']:
1336 raise error.Abort('cannot select revision when creating marker')
1336 raise error.Abort('cannot select revision when creating marker')
1337 metadata = {}
1337 metadata = {}
1338 metadata['user'] = opts['user'] or ui.username()
1338 metadata['user'] = opts['user'] or ui.username()
1339 succs = tuple(parsenodeid(succ) for succ in successors)
1339 succs = tuple(parsenodeid(succ) for succ in successors)
1340 l = repo.lock()
1340 l = repo.lock()
1341 try:
1341 try:
1342 tr = repo.transaction('debugobsolete')
1342 tr = repo.transaction('debugobsolete')
1343 try:
1343 try:
1344 date = opts.get('date')
1344 date = opts.get('date')
1345 if date:
1345 if date:
1346 date = util.parsedate(date)
1346 date = util.parsedate(date)
1347 else:
1347 else:
1348 date = None
1348 date = None
1349 prec = parsenodeid(precursor)
1349 prec = parsenodeid(precursor)
1350 parents = None
1350 parents = None
1351 if opts['record_parents']:
1351 if opts['record_parents']:
1352 if prec not in repo.unfiltered():
1352 if prec not in repo.unfiltered():
1353 raise error.Abort('cannot used --record-parents on '
1353 raise error.Abort('cannot used --record-parents on '
1354 'unknown changesets')
1354 'unknown changesets')
1355 parents = repo.unfiltered()[prec].parents()
1355 parents = repo.unfiltered()[prec].parents()
1356 parents = tuple(p.node() for p in parents)
1356 parents = tuple(p.node() for p in parents)
1357 repo.obsstore.create(tr, prec, succs, opts['flags'],
1357 repo.obsstore.create(tr, prec, succs, opts['flags'],
1358 parents=parents, date=date,
1358 parents=parents, date=date,
1359 metadata=metadata, ui=ui)
1359 metadata=metadata, ui=ui)
1360 tr.close()
1360 tr.close()
1361 except ValueError as exc:
1361 except ValueError as exc:
1362 raise error.Abort(_('bad obsmarker input: %s') % exc)
1362 raise error.Abort(_('bad obsmarker input: %s') % exc)
1363 finally:
1363 finally:
1364 tr.release()
1364 tr.release()
1365 finally:
1365 finally:
1366 l.release()
1366 l.release()
1367 else:
1367 else:
1368 if opts['rev']:
1368 if opts['rev']:
1369 revs = scmutil.revrange(repo, opts['rev'])
1369 revs = scmutil.revrange(repo, opts['rev'])
1370 nodes = [repo[r].node() for r in revs]
1370 nodes = [repo[r].node() for r in revs]
1371 markers = list(obsolete.getmarkers(repo, nodes=nodes))
1371 markers = list(obsolete.getmarkers(repo, nodes=nodes))
1372 markers.sort(key=lambda x: x._data)
1372 markers.sort(key=lambda x: x._data)
1373 else:
1373 else:
1374 markers = obsolete.getmarkers(repo)
1374 markers = obsolete.getmarkers(repo)
1375
1375
1376 markerstoiter = markers
1376 markerstoiter = markers
1377 isrelevant = lambda m: True
1377 isrelevant = lambda m: True
1378 if opts.get('rev') and opts.get('index'):
1378 if opts.get('rev') and opts.get('index'):
1379 markerstoiter = obsolete.getmarkers(repo)
1379 markerstoiter = obsolete.getmarkers(repo)
1380 markerset = set(markers)
1380 markerset = set(markers)
1381 isrelevant = lambda m: m in markerset
1381 isrelevant = lambda m: m in markerset
1382
1382
1383 fm = ui.formatter('debugobsolete', opts)
1383 fm = ui.formatter('debugobsolete', opts)
1384 for i, m in enumerate(markerstoiter):
1384 for i, m in enumerate(markerstoiter):
1385 if not isrelevant(m):
1385 if not isrelevant(m):
1386 # marker can be irrelevant when we're iterating over a set
1386 # marker can be irrelevant when we're iterating over a set
1387 # of markers (markerstoiter) which is bigger than the set
1387 # of markers (markerstoiter) which is bigger than the set
1388 # of markers we want to display (markers)
1388 # of markers we want to display (markers)
1389 # this can happen if both --index and --rev options are
1389 # this can happen if both --index and --rev options are
1390 # provided and thus we need to iterate over all of the markers
1390 # provided and thus we need to iterate over all of the markers
1391 # to get the correct indices, but only display the ones that
1391 # to get the correct indices, but only display the ones that
1392 # are relevant to --rev value
1392 # are relevant to --rev value
1393 continue
1393 continue
1394 fm.startitem()
1394 fm.startitem()
1395 ind = i if opts.get('index') else None
1395 ind = i if opts.get('index') else None
1396 cmdutil.showmarker(fm, m, index=ind)
1396 cmdutil.showmarker(fm, m, index=ind)
1397 fm.end()
1397 fm.end()
1398
1398
1399 @command('debugpathcomplete',
1399 @command('debugpathcomplete',
1400 [('f', 'full', None, _('complete an entire path')),
1400 [('f', 'full', None, _('complete an entire path')),
1401 ('n', 'normal', None, _('show only normal files')),
1401 ('n', 'normal', None, _('show only normal files')),
1402 ('a', 'added', None, _('show only added files')),
1402 ('a', 'added', None, _('show only added files')),
1403 ('r', 'removed', None, _('show only removed files'))],
1403 ('r', 'removed', None, _('show only removed files'))],
1404 _('FILESPEC...'))
1404 _('FILESPEC...'))
1405 def debugpathcomplete(ui, repo, *specs, **opts):
1405 def debugpathcomplete(ui, repo, *specs, **opts):
1406 '''complete part or all of a tracked path
1406 '''complete part or all of a tracked path
1407
1407
1408 This command supports shells that offer path name completion. It
1408 This command supports shells that offer path name completion. It
1409 currently completes only files already known to the dirstate.
1409 currently completes only files already known to the dirstate.
1410
1410
1411 Completion extends only to the next path segment unless
1411 Completion extends only to the next path segment unless
1412 --full is specified, in which case entire paths are used.'''
1412 --full is specified, in which case entire paths are used.'''
1413
1413
1414 def complete(path, acceptable):
1414 def complete(path, acceptable):
1415 dirstate = repo.dirstate
1415 dirstate = repo.dirstate
1416 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1416 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1417 rootdir = repo.root + pycompat.ossep
1417 rootdir = repo.root + pycompat.ossep
1418 if spec != repo.root and not spec.startswith(rootdir):
1418 if spec != repo.root and not spec.startswith(rootdir):
1419 return [], []
1419 return [], []
1420 if os.path.isdir(spec):
1420 if os.path.isdir(spec):
1421 spec += '/'
1421 spec += '/'
1422 spec = spec[len(rootdir):]
1422 spec = spec[len(rootdir):]
1423 fixpaths = pycompat.ossep != '/'
1423 fixpaths = pycompat.ossep != '/'
1424 if fixpaths:
1424 if fixpaths:
1425 spec = spec.replace(pycompat.ossep, '/')
1425 spec = spec.replace(pycompat.ossep, '/')
1426 speclen = len(spec)
1426 speclen = len(spec)
1427 fullpaths = opts['full']
1427 fullpaths = opts['full']
1428 files, dirs = set(), set()
1428 files, dirs = set(), set()
1429 adddir, addfile = dirs.add, files.add
1429 adddir, addfile = dirs.add, files.add
1430 for f, st in dirstate.iteritems():
1430 for f, st in dirstate.iteritems():
1431 if f.startswith(spec) and st[0] in acceptable:
1431 if f.startswith(spec) and st[0] in acceptable:
1432 if fixpaths:
1432 if fixpaths:
1433 f = f.replace('/', pycompat.ossep)
1433 f = f.replace('/', pycompat.ossep)
1434 if fullpaths:
1434 if fullpaths:
1435 addfile(f)
1435 addfile(f)
1436 continue
1436 continue
1437 s = f.find(pycompat.ossep, speclen)
1437 s = f.find(pycompat.ossep, speclen)
1438 if s >= 0:
1438 if s >= 0:
1439 adddir(f[:s])
1439 adddir(f[:s])
1440 else:
1440 else:
1441 addfile(f)
1441 addfile(f)
1442 return files, dirs
1442 return files, dirs
1443
1443
1444 acceptable = ''
1444 acceptable = ''
1445 if opts['normal']:
1445 if opts['normal']:
1446 acceptable += 'nm'
1446 acceptable += 'nm'
1447 if opts['added']:
1447 if opts['added']:
1448 acceptable += 'a'
1448 acceptable += 'a'
1449 if opts['removed']:
1449 if opts['removed']:
1450 acceptable += 'r'
1450 acceptable += 'r'
1451 cwd = repo.getcwd()
1451 cwd = repo.getcwd()
1452 if not specs:
1452 if not specs:
1453 specs = ['.']
1453 specs = ['.']
1454
1454
1455 files, dirs = set(), set()
1455 files, dirs = set(), set()
1456 for spec in specs:
1456 for spec in specs:
1457 f, d = complete(spec, acceptable or 'nmar')
1457 f, d = complete(spec, acceptable or 'nmar')
1458 files.update(f)
1458 files.update(f)
1459 dirs.update(d)
1459 dirs.update(d)
1460 files.update(dirs)
1460 files.update(dirs)
1461 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1461 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1462 ui.write('\n')
1462 ui.write('\n')
1463
1463
1464 @command('debugpickmergetool',
1464 @command('debugpickmergetool',
1465 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1465 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1466 ('', 'changedelete', None, _('emulate merging change and delete')),
1466 ('', 'changedelete', None, _('emulate merging change and delete')),
1467 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1467 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1468 _('[PATTERN]...'),
1468 _('[PATTERN]...'),
1469 inferrepo=True)
1469 inferrepo=True)
1470 def debugpickmergetool(ui, repo, *pats, **opts):
1470 def debugpickmergetool(ui, repo, *pats, **opts):
1471 """examine which merge tool is chosen for specified file
1471 """examine which merge tool is chosen for specified file
1472
1472
1473 As described in :hg:`help merge-tools`, Mercurial examines
1473 As described in :hg:`help merge-tools`, Mercurial examines
1474 configurations below in this order to decide which merge tool is
1474 configurations below in this order to decide which merge tool is
1475 chosen for specified file.
1475 chosen for specified file.
1476
1476
1477 1. ``--tool`` option
1477 1. ``--tool`` option
1478 2. ``HGMERGE`` environment variable
1478 2. ``HGMERGE`` environment variable
1479 3. configurations in ``merge-patterns`` section
1479 3. configurations in ``merge-patterns`` section
1480 4. configuration of ``ui.merge``
1480 4. configuration of ``ui.merge``
1481 5. configurations in ``merge-tools`` section
1481 5. configurations in ``merge-tools`` section
1482 6. ``hgmerge`` tool (for historical reason only)
1482 6. ``hgmerge`` tool (for historical reason only)
1483 7. default tool for fallback (``:merge`` or ``:prompt``)
1483 7. default tool for fallback (``:merge`` or ``:prompt``)
1484
1484
1485 This command writes out examination result in the style below::
1485 This command writes out examination result in the style below::
1486
1486
1487 FILE = MERGETOOL
1487 FILE = MERGETOOL
1488
1488
1489 By default, all files known in the first parent context of the
1489 By default, all files known in the first parent context of the
1490 working directory are examined. Use file patterns and/or -I/-X
1490 working directory are examined. Use file patterns and/or -I/-X
1491 options to limit target files. -r/--rev is also useful to examine
1491 options to limit target files. -r/--rev is also useful to examine
1492 files in another context without actual updating to it.
1492 files in another context without actual updating to it.
1493
1493
1494 With --debug, this command shows warning messages while matching
1494 With --debug, this command shows warning messages while matching
1495 against ``merge-patterns`` and so on, too. It is recommended to
1495 against ``merge-patterns`` and so on, too. It is recommended to
1496 use this option with explicit file patterns and/or -I/-X options,
1496 use this option with explicit file patterns and/or -I/-X options,
1497 because this option increases amount of output per file according
1497 because this option increases amount of output per file according
1498 to configurations in hgrc.
1498 to configurations in hgrc.
1499
1499
1500 With -v/--verbose, this command shows configurations below at
1500 With -v/--verbose, this command shows configurations below at
1501 first (only if specified).
1501 first (only if specified).
1502
1502
1503 - ``--tool`` option
1503 - ``--tool`` option
1504 - ``HGMERGE`` environment variable
1504 - ``HGMERGE`` environment variable
1505 - configuration of ``ui.merge``
1505 - configuration of ``ui.merge``
1506
1506
1507 If merge tool is chosen before matching against
1507 If merge tool is chosen before matching against
1508 ``merge-patterns``, this command can't show any helpful
1508 ``merge-patterns``, this command can't show any helpful
1509 information, even with --debug. In such case, information above is
1509 information, even with --debug. In such case, information above is
1510 useful to know why a merge tool is chosen.
1510 useful to know why a merge tool is chosen.
1511 """
1511 """
1512 overrides = {}
1512 overrides = {}
1513 if opts['tool']:
1513 if opts['tool']:
1514 overrides[('ui', 'forcemerge')] = opts['tool']
1514 overrides[('ui', 'forcemerge')] = opts['tool']
1515 ui.note(('with --tool %r\n') % (opts['tool']))
1515 ui.note(('with --tool %r\n') % (opts['tool']))
1516
1516
1517 with ui.configoverride(overrides, 'debugmergepatterns'):
1517 with ui.configoverride(overrides, 'debugmergepatterns'):
1518 hgmerge = encoding.environ.get("HGMERGE")
1518 hgmerge = encoding.environ.get("HGMERGE")
1519 if hgmerge is not None:
1519 if hgmerge is not None:
1520 ui.note(('with HGMERGE=%r\n') % (hgmerge))
1520 ui.note(('with HGMERGE=%r\n') % (hgmerge))
1521 uimerge = ui.config("ui", "merge")
1521 uimerge = ui.config("ui", "merge")
1522 if uimerge:
1522 if uimerge:
1523 ui.note(('with ui.merge=%r\n') % (uimerge))
1523 ui.note(('with ui.merge=%r\n') % (uimerge))
1524
1524
1525 ctx = scmutil.revsingle(repo, opts.get('rev'))
1525 ctx = scmutil.revsingle(repo, opts.get('rev'))
1526 m = scmutil.match(ctx, pats, opts)
1526 m = scmutil.match(ctx, pats, opts)
1527 changedelete = opts['changedelete']
1527 changedelete = opts['changedelete']
1528 for path in ctx.walk(m):
1528 for path in ctx.walk(m):
1529 fctx = ctx[path]
1529 fctx = ctx[path]
1530 try:
1530 try:
1531 if not ui.debugflag:
1531 if not ui.debugflag:
1532 ui.pushbuffer(error=True)
1532 ui.pushbuffer(error=True)
1533 tool, toolpath = filemerge._picktool(repo, ui, path,
1533 tool, toolpath = filemerge._picktool(repo, ui, path,
1534 fctx.isbinary(),
1534 fctx.isbinary(),
1535 'l' in fctx.flags(),
1535 'l' in fctx.flags(),
1536 changedelete)
1536 changedelete)
1537 finally:
1537 finally:
1538 if not ui.debugflag:
1538 if not ui.debugflag:
1539 ui.popbuffer()
1539 ui.popbuffer()
1540 ui.write(('%s = %s\n') % (path, tool))
1540 ui.write(('%s = %s\n') % (path, tool))
1541
1541
1542 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1542 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1543 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1543 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1544 '''access the pushkey key/value protocol
1544 '''access the pushkey key/value protocol
1545
1545
1546 With two args, list the keys in the given namespace.
1546 With two args, list the keys in the given namespace.
1547
1547
1548 With five args, set a key to new if it currently is set to old.
1548 With five args, set a key to new if it currently is set to old.
1549 Reports success or failure.
1549 Reports success or failure.
1550 '''
1550 '''
1551
1551
1552 target = hg.peer(ui, {}, repopath)
1552 target = hg.peer(ui, {}, repopath)
1553 if keyinfo:
1553 if keyinfo:
1554 key, old, new = keyinfo
1554 key, old, new = keyinfo
1555 r = target.pushkey(namespace, key, old, new)
1555 r = target.pushkey(namespace, key, old, new)
1556 ui.status(str(r) + '\n')
1556 ui.status(str(r) + '\n')
1557 return not r
1557 return not r
1558 else:
1558 else:
1559 for k, v in sorted(target.listkeys(namespace).iteritems()):
1559 for k, v in sorted(target.listkeys(namespace).iteritems()):
1560 ui.write("%s\t%s\n" % (util.escapestr(k),
1560 ui.write("%s\t%s\n" % (util.escapestr(k),
1561 util.escapestr(v)))
1561 util.escapestr(v)))
1562
1562
1563 @command('debugpvec', [], _('A B'))
1563 @command('debugpvec', [], _('A B'))
1564 def debugpvec(ui, repo, a, b=None):
1564 def debugpvec(ui, repo, a, b=None):
1565 ca = scmutil.revsingle(repo, a)
1565 ca = scmutil.revsingle(repo, a)
1566 cb = scmutil.revsingle(repo, b)
1566 cb = scmutil.revsingle(repo, b)
1567 pa = pvec.ctxpvec(ca)
1567 pa = pvec.ctxpvec(ca)
1568 pb = pvec.ctxpvec(cb)
1568 pb = pvec.ctxpvec(cb)
1569 if pa == pb:
1569 if pa == pb:
1570 rel = "="
1570 rel = "="
1571 elif pa > pb:
1571 elif pa > pb:
1572 rel = ">"
1572 rel = ">"
1573 elif pa < pb:
1573 elif pa < pb:
1574 rel = "<"
1574 rel = "<"
1575 elif pa | pb:
1575 elif pa | pb:
1576 rel = "|"
1576 rel = "|"
1577 ui.write(_("a: %s\n") % pa)
1577 ui.write(_("a: %s\n") % pa)
1578 ui.write(_("b: %s\n") % pb)
1578 ui.write(_("b: %s\n") % pb)
1579 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1579 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1580 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1580 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1581 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1581 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1582 pa.distance(pb), rel))
1582 pa.distance(pb), rel))
1583
1583
1584 @command('debugrebuilddirstate|debugrebuildstate',
1584 @command('debugrebuilddirstate|debugrebuildstate',
1585 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1585 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1586 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1586 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1587 'the working copy parent')),
1587 'the working copy parent')),
1588 ],
1588 ],
1589 _('[-r REV]'))
1589 _('[-r REV]'))
1590 def debugrebuilddirstate(ui, repo, rev, **opts):
1590 def debugrebuilddirstate(ui, repo, rev, **opts):
1591 """rebuild the dirstate as it would look like for the given revision
1591 """rebuild the dirstate as it would look like for the given revision
1592
1592
1593 If no revision is specified the first current parent will be used.
1593 If no revision is specified the first current parent will be used.
1594
1594
1595 The dirstate will be set to the files of the given revision.
1595 The dirstate will be set to the files of the given revision.
1596 The actual working directory content or existing dirstate
1596 The actual working directory content or existing dirstate
1597 information such as adds or removes is not considered.
1597 information such as adds or removes is not considered.
1598
1598
1599 ``minimal`` will only rebuild the dirstate status for files that claim to be
1599 ``minimal`` will only rebuild the dirstate status for files that claim to be
1600 tracked but are not in the parent manifest, or that exist in the parent
1600 tracked but are not in the parent manifest, or that exist in the parent
1601 manifest but are not in the dirstate. It will not change adds, removes, or
1601 manifest but are not in the dirstate. It will not change adds, removes, or
1602 modified files that are in the working copy parent.
1602 modified files that are in the working copy parent.
1603
1603
1604 One use of this command is to make the next :hg:`status` invocation
1604 One use of this command is to make the next :hg:`status` invocation
1605 check the actual file content.
1605 check the actual file content.
1606 """
1606 """
1607 ctx = scmutil.revsingle(repo, rev)
1607 ctx = scmutil.revsingle(repo, rev)
1608 with repo.wlock():
1608 with repo.wlock():
1609 dirstate = repo.dirstate
1609 dirstate = repo.dirstate
1610 changedfiles = None
1610 changedfiles = None
1611 # See command doc for what minimal does.
1611 # See command doc for what minimal does.
1612 if opts.get('minimal'):
1612 if opts.get('minimal'):
1613 manifestfiles = set(ctx.manifest().keys())
1613 manifestfiles = set(ctx.manifest().keys())
1614 dirstatefiles = set(dirstate)
1614 dirstatefiles = set(dirstate)
1615 manifestonly = manifestfiles - dirstatefiles
1615 manifestonly = manifestfiles - dirstatefiles
1616 dsonly = dirstatefiles - manifestfiles
1616 dsonly = dirstatefiles - manifestfiles
1617 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1617 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1618 changedfiles = manifestonly | dsnotadded
1618 changedfiles = manifestonly | dsnotadded
1619
1619
1620 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1620 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1621
1621
1622 @command('debugrebuildfncache', [], '')
1622 @command('debugrebuildfncache', [], '')
1623 def debugrebuildfncache(ui, repo):
1623 def debugrebuildfncache(ui, repo):
1624 """rebuild the fncache file"""
1624 """rebuild the fncache file"""
1625 repair.rebuildfncache(ui, repo)
1625 repair.rebuildfncache(ui, repo)
1626
1626
1627 @command('debugrename',
1627 @command('debugrename',
1628 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1628 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1629 _('[-r REV] FILE'))
1629 _('[-r REV] FILE'))
1630 def debugrename(ui, repo, file1, *pats, **opts):
1630 def debugrename(ui, repo, file1, *pats, **opts):
1631 """dump rename information"""
1631 """dump rename information"""
1632
1632
1633 ctx = scmutil.revsingle(repo, opts.get('rev'))
1633 ctx = scmutil.revsingle(repo, opts.get('rev'))
1634 m = scmutil.match(ctx, (file1,) + pats, opts)
1634 m = scmutil.match(ctx, (file1,) + pats, opts)
1635 for abs in ctx.walk(m):
1635 for abs in ctx.walk(m):
1636 fctx = ctx[abs]
1636 fctx = ctx[abs]
1637 o = fctx.filelog().renamed(fctx.filenode())
1637 o = fctx.filelog().renamed(fctx.filenode())
1638 rel = m.rel(abs)
1638 rel = m.rel(abs)
1639 if o:
1639 if o:
1640 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1640 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1641 else:
1641 else:
1642 ui.write(_("%s not renamed\n") % rel)
1642 ui.write(_("%s not renamed\n") % rel)
1643
1643
1644 @command('debugrevlog', cmdutil.debugrevlogopts +
1644 @command('debugrevlog', cmdutil.debugrevlogopts +
1645 [('d', 'dump', False, _('dump index data'))],
1645 [('d', 'dump', False, _('dump index data'))],
1646 _('-c|-m|FILE'),
1646 _('-c|-m|FILE'),
1647 optionalrepo=True)
1647 optionalrepo=True)
1648 def debugrevlog(ui, repo, file_=None, **opts):
1648 def debugrevlog(ui, repo, file_=None, **opts):
1649 """show data and statistics about a revlog"""
1649 """show data and statistics about a revlog"""
1650 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1650 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1651
1651
1652 if opts.get("dump"):
1652 if opts.get("dump"):
1653 numrevs = len(r)
1653 numrevs = len(r)
1654 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1654 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1655 " rawsize totalsize compression heads chainlen\n"))
1655 " rawsize totalsize compression heads chainlen\n"))
1656 ts = 0
1656 ts = 0
1657 heads = set()
1657 heads = set()
1658
1658
1659 for rev in xrange(numrevs):
1659 for rev in xrange(numrevs):
1660 dbase = r.deltaparent(rev)
1660 dbase = r.deltaparent(rev)
1661 if dbase == -1:
1661 if dbase == -1:
1662 dbase = rev
1662 dbase = rev
1663 cbase = r.chainbase(rev)
1663 cbase = r.chainbase(rev)
1664 clen = r.chainlen(rev)
1664 clen = r.chainlen(rev)
1665 p1, p2 = r.parentrevs(rev)
1665 p1, p2 = r.parentrevs(rev)
1666 rs = r.rawsize(rev)
1666 rs = r.rawsize(rev)
1667 ts = ts + rs
1667 ts = ts + rs
1668 heads -= set(r.parentrevs(rev))
1668 heads -= set(r.parentrevs(rev))
1669 heads.add(rev)
1669 heads.add(rev)
1670 try:
1670 try:
1671 compression = ts / r.end(rev)
1671 compression = ts / r.end(rev)
1672 except ZeroDivisionError:
1672 except ZeroDivisionError:
1673 compression = 0
1673 compression = 0
1674 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1674 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1675 "%11d %5d %8d\n" %
1675 "%11d %5d %8d\n" %
1676 (rev, p1, p2, r.start(rev), r.end(rev),
1676 (rev, p1, p2, r.start(rev), r.end(rev),
1677 r.start(dbase), r.start(cbase),
1677 r.start(dbase), r.start(cbase),
1678 r.start(p1), r.start(p2),
1678 r.start(p1), r.start(p2),
1679 rs, ts, compression, len(heads), clen))
1679 rs, ts, compression, len(heads), clen))
1680 return 0
1680 return 0
1681
1681
1682 v = r.version
1682 v = r.version
1683 format = v & 0xFFFF
1683 format = v & 0xFFFF
1684 flags = []
1684 flags = []
1685 gdelta = False
1685 gdelta = False
1686 if v & revlog.FLAG_INLINE_DATA:
1686 if v & revlog.FLAG_INLINE_DATA:
1687 flags.append('inline')
1687 flags.append('inline')
1688 if v & revlog.FLAG_GENERALDELTA:
1688 if v & revlog.FLAG_GENERALDELTA:
1689 gdelta = True
1689 gdelta = True
1690 flags.append('generaldelta')
1690 flags.append('generaldelta')
1691 if not flags:
1691 if not flags:
1692 flags = ['(none)']
1692 flags = ['(none)']
1693
1693
1694 nummerges = 0
1694 nummerges = 0
1695 numfull = 0
1695 numfull = 0
1696 numprev = 0
1696 numprev = 0
1697 nump1 = 0
1697 nump1 = 0
1698 nump2 = 0
1698 nump2 = 0
1699 numother = 0
1699 numother = 0
1700 nump1prev = 0
1700 nump1prev = 0
1701 nump2prev = 0
1701 nump2prev = 0
1702 chainlengths = []
1702 chainlengths = []
1703
1703
1704 datasize = [None, 0, 0]
1704 datasize = [None, 0, 0]
1705 fullsize = [None, 0, 0]
1705 fullsize = [None, 0, 0]
1706 deltasize = [None, 0, 0]
1706 deltasize = [None, 0, 0]
1707 chunktypecounts = {}
1707 chunktypecounts = {}
1708 chunktypesizes = {}
1708 chunktypesizes = {}
1709
1709
1710 def addsize(size, l):
1710 def addsize(size, l):
1711 if l[0] is None or size < l[0]:
1711 if l[0] is None or size < l[0]:
1712 l[0] = size
1712 l[0] = size
1713 if size > l[1]:
1713 if size > l[1]:
1714 l[1] = size
1714 l[1] = size
1715 l[2] += size
1715 l[2] += size
1716
1716
1717 numrevs = len(r)
1717 numrevs = len(r)
1718 for rev in xrange(numrevs):
1718 for rev in xrange(numrevs):
1719 p1, p2 = r.parentrevs(rev)
1719 p1, p2 = r.parentrevs(rev)
1720 delta = r.deltaparent(rev)
1720 delta = r.deltaparent(rev)
1721 if format > 0:
1721 if format > 0:
1722 addsize(r.rawsize(rev), datasize)
1722 addsize(r.rawsize(rev), datasize)
1723 if p2 != nullrev:
1723 if p2 != nullrev:
1724 nummerges += 1
1724 nummerges += 1
1725 size = r.length(rev)
1725 size = r.length(rev)
1726 if delta == nullrev:
1726 if delta == nullrev:
1727 chainlengths.append(0)
1727 chainlengths.append(0)
1728 numfull += 1
1728 numfull += 1
1729 addsize(size, fullsize)
1729 addsize(size, fullsize)
1730 else:
1730 else:
1731 chainlengths.append(chainlengths[delta] + 1)
1731 chainlengths.append(chainlengths[delta] + 1)
1732 addsize(size, deltasize)
1732 addsize(size, deltasize)
1733 if delta == rev - 1:
1733 if delta == rev - 1:
1734 numprev += 1
1734 numprev += 1
1735 if delta == p1:
1735 if delta == p1:
1736 nump1prev += 1
1736 nump1prev += 1
1737 elif delta == p2:
1737 elif delta == p2:
1738 nump2prev += 1
1738 nump2prev += 1
1739 elif delta == p1:
1739 elif delta == p1:
1740 nump1 += 1
1740 nump1 += 1
1741 elif delta == p2:
1741 elif delta == p2:
1742 nump2 += 1
1742 nump2 += 1
1743 elif delta != nullrev:
1743 elif delta != nullrev:
1744 numother += 1
1744 numother += 1
1745
1745
1746 # Obtain data on the raw chunks in the revlog.
1746 # Obtain data on the raw chunks in the revlog.
1747 segment = r._getsegmentforrevs(rev, rev)[1]
1747 segment = r._getsegmentforrevs(rev, rev)[1]
1748 if segment:
1748 if segment:
1749 chunktype = segment[0]
1749 chunktype = segment[0]
1750 else:
1750 else:
1751 chunktype = 'empty'
1751 chunktype = 'empty'
1752
1752
1753 if chunktype not in chunktypecounts:
1753 if chunktype not in chunktypecounts:
1754 chunktypecounts[chunktype] = 0
1754 chunktypecounts[chunktype] = 0
1755 chunktypesizes[chunktype] = 0
1755 chunktypesizes[chunktype] = 0
1756
1756
1757 chunktypecounts[chunktype] += 1
1757 chunktypecounts[chunktype] += 1
1758 chunktypesizes[chunktype] += size
1758 chunktypesizes[chunktype] += size
1759
1759
1760 # Adjust size min value for empty cases
1760 # Adjust size min value for empty cases
1761 for size in (datasize, fullsize, deltasize):
1761 for size in (datasize, fullsize, deltasize):
1762 if size[0] is None:
1762 if size[0] is None:
1763 size[0] = 0
1763 size[0] = 0
1764
1764
1765 numdeltas = numrevs - numfull
1765 numdeltas = numrevs - numfull
1766 numoprev = numprev - nump1prev - nump2prev
1766 numoprev = numprev - nump1prev - nump2prev
1767 totalrawsize = datasize[2]
1767 totalrawsize = datasize[2]
1768 datasize[2] /= numrevs
1768 datasize[2] /= numrevs
1769 fulltotal = fullsize[2]
1769 fulltotal = fullsize[2]
1770 fullsize[2] /= numfull
1770 fullsize[2] /= numfull
1771 deltatotal = deltasize[2]
1771 deltatotal = deltasize[2]
1772 if numrevs - numfull > 0:
1772 if numrevs - numfull > 0:
1773 deltasize[2] /= numrevs - numfull
1773 deltasize[2] /= numrevs - numfull
1774 totalsize = fulltotal + deltatotal
1774 totalsize = fulltotal + deltatotal
1775 avgchainlen = sum(chainlengths) / numrevs
1775 avgchainlen = sum(chainlengths) / numrevs
1776 maxchainlen = max(chainlengths)
1776 maxchainlen = max(chainlengths)
1777 compratio = 1
1777 compratio = 1
1778 if totalsize:
1778 if totalsize:
1779 compratio = totalrawsize / totalsize
1779 compratio = totalrawsize / totalsize
1780
1780
1781 basedfmtstr = '%%%dd\n'
1781 basedfmtstr = '%%%dd\n'
1782 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
1782 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
1783
1783
1784 def dfmtstr(max):
1784 def dfmtstr(max):
1785 return basedfmtstr % len(str(max))
1785 return basedfmtstr % len(str(max))
1786 def pcfmtstr(max, padding=0):
1786 def pcfmtstr(max, padding=0):
1787 return basepcfmtstr % (len(str(max)), ' ' * padding)
1787 return basepcfmtstr % (len(str(max)), ' ' * padding)
1788
1788
1789 def pcfmt(value, total):
1789 def pcfmt(value, total):
1790 if total:
1790 if total:
1791 return (value, 100 * float(value) / total)
1791 return (value, 100 * float(value) / total)
1792 else:
1792 else:
1793 return value, 100.0
1793 return value, 100.0
1794
1794
1795 ui.write(('format : %d\n') % format)
1795 ui.write(('format : %d\n') % format)
1796 ui.write(('flags : %s\n') % ', '.join(flags))
1796 ui.write(('flags : %s\n') % ', '.join(flags))
1797
1797
1798 ui.write('\n')
1798 ui.write('\n')
1799 fmt = pcfmtstr(totalsize)
1799 fmt = pcfmtstr(totalsize)
1800 fmt2 = dfmtstr(totalsize)
1800 fmt2 = dfmtstr(totalsize)
1801 ui.write(('revisions : ') + fmt2 % numrevs)
1801 ui.write(('revisions : ') + fmt2 % numrevs)
1802 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
1802 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
1803 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
1803 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
1804 ui.write(('revisions : ') + fmt2 % numrevs)
1804 ui.write(('revisions : ') + fmt2 % numrevs)
1805 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
1805 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
1806 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
1806 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
1807 ui.write(('revision size : ') + fmt2 % totalsize)
1807 ui.write(('revision size : ') + fmt2 % totalsize)
1808 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
1808 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
1809 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
1809 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
1810
1810
1811 def fmtchunktype(chunktype):
1811 def fmtchunktype(chunktype):
1812 if chunktype == 'empty':
1812 if chunktype == 'empty':
1813 return ' %s : ' % chunktype
1813 return ' %s : ' % chunktype
1814 elif chunktype in string.ascii_letters:
1814 elif chunktype in string.ascii_letters:
1815 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
1815 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
1816 else:
1816 else:
1817 return ' 0x%s : ' % hex(chunktype)
1817 return ' 0x%s : ' % hex(chunktype)
1818
1818
1819 ui.write('\n')
1819 ui.write('\n')
1820 ui.write(('chunks : ') + fmt2 % numrevs)
1820 ui.write(('chunks : ') + fmt2 % numrevs)
1821 for chunktype in sorted(chunktypecounts):
1821 for chunktype in sorted(chunktypecounts):
1822 ui.write(fmtchunktype(chunktype))
1822 ui.write(fmtchunktype(chunktype))
1823 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
1823 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
1824 ui.write(('chunks size : ') + fmt2 % totalsize)
1824 ui.write(('chunks size : ') + fmt2 % totalsize)
1825 for chunktype in sorted(chunktypecounts):
1825 for chunktype in sorted(chunktypecounts):
1826 ui.write(fmtchunktype(chunktype))
1826 ui.write(fmtchunktype(chunktype))
1827 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
1827 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
1828
1828
1829 ui.write('\n')
1829 ui.write('\n')
1830 fmt = dfmtstr(max(avgchainlen, compratio))
1830 fmt = dfmtstr(max(avgchainlen, compratio))
1831 ui.write(('avg chain length : ') + fmt % avgchainlen)
1831 ui.write(('avg chain length : ') + fmt % avgchainlen)
1832 ui.write(('max chain length : ') + fmt % maxchainlen)
1832 ui.write(('max chain length : ') + fmt % maxchainlen)
1833 ui.write(('compression ratio : ') + fmt % compratio)
1833 ui.write(('compression ratio : ') + fmt % compratio)
1834
1834
1835 if format > 0:
1835 if format > 0:
1836 ui.write('\n')
1836 ui.write('\n')
1837 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
1837 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
1838 % tuple(datasize))
1838 % tuple(datasize))
1839 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
1839 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
1840 % tuple(fullsize))
1840 % tuple(fullsize))
1841 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
1841 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
1842 % tuple(deltasize))
1842 % tuple(deltasize))
1843
1843
1844 if numdeltas > 0:
1844 if numdeltas > 0:
1845 ui.write('\n')
1845 ui.write('\n')
1846 fmt = pcfmtstr(numdeltas)
1846 fmt = pcfmtstr(numdeltas)
1847 fmt2 = pcfmtstr(numdeltas, 4)
1847 fmt2 = pcfmtstr(numdeltas, 4)
1848 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
1848 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
1849 if numprev > 0:
1849 if numprev > 0:
1850 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
1850 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
1851 numprev))
1851 numprev))
1852 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
1852 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
1853 numprev))
1853 numprev))
1854 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
1854 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
1855 numprev))
1855 numprev))
1856 if gdelta:
1856 if gdelta:
1857 ui.write(('deltas against p1 : ')
1857 ui.write(('deltas against p1 : ')
1858 + fmt % pcfmt(nump1, numdeltas))
1858 + fmt % pcfmt(nump1, numdeltas))
1859 ui.write(('deltas against p2 : ')
1859 ui.write(('deltas against p2 : ')
1860 + fmt % pcfmt(nump2, numdeltas))
1860 + fmt % pcfmt(nump2, numdeltas))
1861 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
1861 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
1862 numdeltas))
1862 numdeltas))
1863
1863
1864 @command('debugrevspec',
1864 @command('debugrevspec',
1865 [('', 'optimize', None,
1865 [('', 'optimize', None,
1866 _('print parsed tree after optimizing (DEPRECATED)')),
1866 _('print parsed tree after optimizing (DEPRECATED)')),
1867 ('p', 'show-stage', [],
1867 ('p', 'show-stage', [],
1868 _('print parsed tree at the given stage'), _('NAME')),
1868 _('print parsed tree at the given stage'), _('NAME')),
1869 ('', 'no-optimized', False, _('evaluate tree without optimization')),
1869 ('', 'no-optimized', False, _('evaluate tree without optimization')),
1870 ('', 'verify-optimized', False, _('verify optimized result')),
1870 ('', 'verify-optimized', False, _('verify optimized result')),
1871 ],
1871 ],
1872 ('REVSPEC'))
1872 ('REVSPEC'))
1873 def debugrevspec(ui, repo, expr, **opts):
1873 def debugrevspec(ui, repo, expr, **opts):
1874 """parse and apply a revision specification
1874 """parse and apply a revision specification
1875
1875
1876 Use -p/--show-stage option to print the parsed tree at the given stages.
1876 Use -p/--show-stage option to print the parsed tree at the given stages.
1877 Use -p all to print tree at every stage.
1877 Use -p all to print tree at every stage.
1878
1878
1879 Use --verify-optimized to compare the optimized result with the unoptimized
1879 Use --verify-optimized to compare the optimized result with the unoptimized
1880 one. Returns 1 if the optimized result differs.
1880 one. Returns 1 if the optimized result differs.
1881 """
1881 """
1882 stages = [
1882 stages = [
1883 ('parsed', lambda tree: tree),
1883 ('parsed', lambda tree: tree),
1884 ('expanded', lambda tree: revsetlang.expandaliases(ui, tree)),
1884 ('expanded', lambda tree: revsetlang.expandaliases(ui, tree)),
1885 ('concatenated', revsetlang.foldconcat),
1885 ('concatenated', revsetlang.foldconcat),
1886 ('analyzed', revsetlang.analyze),
1886 ('analyzed', revsetlang.analyze),
1887 ('optimized', revsetlang.optimize),
1887 ('optimized', revsetlang.optimize),
1888 ]
1888 ]
1889 if opts['no_optimized']:
1889 if opts['no_optimized']:
1890 stages = stages[:-1]
1890 stages = stages[:-1]
1891 if opts['verify_optimized'] and opts['no_optimized']:
1891 if opts['verify_optimized'] and opts['no_optimized']:
1892 raise error.Abort(_('cannot use --verify-optimized with '
1892 raise error.Abort(_('cannot use --verify-optimized with '
1893 '--no-optimized'))
1893 '--no-optimized'))
1894 stagenames = set(n for n, f in stages)
1894 stagenames = set(n for n, f in stages)
1895
1895
1896 showalways = set()
1896 showalways = set()
1897 showchanged = set()
1897 showchanged = set()
1898 if ui.verbose and not opts['show_stage']:
1898 if ui.verbose and not opts['show_stage']:
1899 # show parsed tree by --verbose (deprecated)
1899 # show parsed tree by --verbose (deprecated)
1900 showalways.add('parsed')
1900 showalways.add('parsed')
1901 showchanged.update(['expanded', 'concatenated'])
1901 showchanged.update(['expanded', 'concatenated'])
1902 if opts['optimize']:
1902 if opts['optimize']:
1903 showalways.add('optimized')
1903 showalways.add('optimized')
1904 if opts['show_stage'] and opts['optimize']:
1904 if opts['show_stage'] and opts['optimize']:
1905 raise error.Abort(_('cannot use --optimize with --show-stage'))
1905 raise error.Abort(_('cannot use --optimize with --show-stage'))
1906 if opts['show_stage'] == ['all']:
1906 if opts['show_stage'] == ['all']:
1907 showalways.update(stagenames)
1907 showalways.update(stagenames)
1908 else:
1908 else:
1909 for n in opts['show_stage']:
1909 for n in opts['show_stage']:
1910 if n not in stagenames:
1910 if n not in stagenames:
1911 raise error.Abort(_('invalid stage name: %s') % n)
1911 raise error.Abort(_('invalid stage name: %s') % n)
1912 showalways.update(opts['show_stage'])
1912 showalways.update(opts['show_stage'])
1913
1913
1914 treebystage = {}
1914 treebystage = {}
1915 printedtree = None
1915 printedtree = None
1916 tree = revsetlang.parse(expr, lookup=repo.__contains__)
1916 tree = revsetlang.parse(expr, lookup=repo.__contains__)
1917 for n, f in stages:
1917 for n, f in stages:
1918 treebystage[n] = tree = f(tree)
1918 treebystage[n] = tree = f(tree)
1919 if n in showalways or (n in showchanged and tree != printedtree):
1919 if n in showalways or (n in showchanged and tree != printedtree):
1920 if opts['show_stage'] or n != 'parsed':
1920 if opts['show_stage'] or n != 'parsed':
1921 ui.write(("* %s:\n") % n)
1921 ui.write(("* %s:\n") % n)
1922 ui.write(revsetlang.prettyformat(tree), "\n")
1922 ui.write(revsetlang.prettyformat(tree), "\n")
1923 printedtree = tree
1923 printedtree = tree
1924
1924
1925 if opts['verify_optimized']:
1925 if opts['verify_optimized']:
1926 arevs = revset.makematcher(treebystage['analyzed'])(repo)
1926 arevs = revset.makematcher(treebystage['analyzed'])(repo)
1927 brevs = revset.makematcher(treebystage['optimized'])(repo)
1927 brevs = revset.makematcher(treebystage['optimized'])(repo)
1928 if ui.verbose:
1928 if ui.verbose:
1929 ui.note(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
1929 ui.note(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
1930 ui.note(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
1930 ui.note(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
1931 arevs = list(arevs)
1931 arevs = list(arevs)
1932 brevs = list(brevs)
1932 brevs = list(brevs)
1933 if arevs == brevs:
1933 if arevs == brevs:
1934 return 0
1934 return 0
1935 ui.write(('--- analyzed\n'), label='diff.file_a')
1935 ui.write(('--- analyzed\n'), label='diff.file_a')
1936 ui.write(('+++ optimized\n'), label='diff.file_b')
1936 ui.write(('+++ optimized\n'), label='diff.file_b')
1937 sm = difflib.SequenceMatcher(None, arevs, brevs)
1937 sm = difflib.SequenceMatcher(None, arevs, brevs)
1938 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1938 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1939 if tag in ('delete', 'replace'):
1939 if tag in ('delete', 'replace'):
1940 for c in arevs[alo:ahi]:
1940 for c in arevs[alo:ahi]:
1941 ui.write('-%s\n' % c, label='diff.deleted')
1941 ui.write('-%s\n' % c, label='diff.deleted')
1942 if tag in ('insert', 'replace'):
1942 if tag in ('insert', 'replace'):
1943 for c in brevs[blo:bhi]:
1943 for c in brevs[blo:bhi]:
1944 ui.write('+%s\n' % c, label='diff.inserted')
1944 ui.write('+%s\n' % c, label='diff.inserted')
1945 if tag == 'equal':
1945 if tag == 'equal':
1946 for c in arevs[alo:ahi]:
1946 for c in arevs[alo:ahi]:
1947 ui.write(' %s\n' % c)
1947 ui.write(' %s\n' % c)
1948 return 1
1948 return 1
1949
1949
1950 func = revset.makematcher(tree)
1950 func = revset.makematcher(tree)
1951 revs = func(repo)
1951 revs = func(repo)
1952 if ui.verbose:
1952 if ui.verbose:
1953 ui.note(("* set:\n"), smartset.prettyformat(revs), "\n")
1953 ui.note(("* set:\n"), smartset.prettyformat(revs), "\n")
1954 for c in revs:
1954 for c in revs:
1955 ui.write("%s\n" % c)
1955 ui.write("%s\n" % c)
1956
1956
1957 @command('debugsetparents', [], _('REV1 [REV2]'))
1957 @command('debugsetparents', [], _('REV1 [REV2]'))
1958 def debugsetparents(ui, repo, rev1, rev2=None):
1958 def debugsetparents(ui, repo, rev1, rev2=None):
1959 """manually set the parents of the current working directory
1959 """manually set the parents of the current working directory
1960
1960
1961 This is useful for writing repository conversion tools, but should
1961 This is useful for writing repository conversion tools, but should
1962 be used with care. For example, neither the working directory nor the
1962 be used with care. For example, neither the working directory nor the
1963 dirstate is updated, so file status may be incorrect after running this
1963 dirstate is updated, so file status may be incorrect after running this
1964 command.
1964 command.
1965
1965
1966 Returns 0 on success.
1966 Returns 0 on success.
1967 """
1967 """
1968
1968
1969 r1 = scmutil.revsingle(repo, rev1).node()
1969 r1 = scmutil.revsingle(repo, rev1).node()
1970 r2 = scmutil.revsingle(repo, rev2, 'null').node()
1970 r2 = scmutil.revsingle(repo, rev2, 'null').node()
1971
1971
1972 with repo.wlock():
1972 with repo.wlock():
1973 repo.setparents(r1, r2)
1973 repo.setparents(r1, r2)
1974
1974
1975 @command('debugsub',
1975 @command('debugsub',
1976 [('r', 'rev', '',
1976 [('r', 'rev', '',
1977 _('revision to check'), _('REV'))],
1977 _('revision to check'), _('REV'))],
1978 _('[-r REV] [REV]'))
1978 _('[-r REV] [REV]'))
1979 def debugsub(ui, repo, rev=None):
1979 def debugsub(ui, repo, rev=None):
1980 ctx = scmutil.revsingle(repo, rev, None)
1980 ctx = scmutil.revsingle(repo, rev, None)
1981 for k, v in sorted(ctx.substate.items()):
1981 for k, v in sorted(ctx.substate.items()):
1982 ui.write(('path %s\n') % k)
1982 ui.write(('path %s\n') % k)
1983 ui.write((' source %s\n') % v[0])
1983 ui.write((' source %s\n') % v[0])
1984 ui.write((' revision %s\n') % v[1])
1984 ui.write((' revision %s\n') % v[1])
1985
1985
1986 @command('debugsuccessorssets',
1986 @command('debugsuccessorssets',
1987 [],
1987 [],
1988 _('[REV]'))
1988 _('[REV]'))
1989 def debugsuccessorssets(ui, repo, *revs):
1989 def debugsuccessorssets(ui, repo, *revs):
1990 """show set of successors for revision
1990 """show set of successors for revision
1991
1991
1992 A successors set of changeset A is a consistent group of revisions that
1992 A successors set of changeset A is a consistent group of revisions that
1993 succeed A. It contains non-obsolete changesets only.
1993 succeed A. It contains non-obsolete changesets only.
1994
1994
1995 In most cases a changeset A has a single successors set containing a single
1995 In most cases a changeset A has a single successors set containing a single
1996 successor (changeset A replaced by A').
1996 successor (changeset A replaced by A').
1997
1997
1998 A changeset that is made obsolete with no successors are called "pruned".
1998 A changeset that is made obsolete with no successors are called "pruned".
1999 Such changesets have no successors sets at all.
1999 Such changesets have no successors sets at all.
2000
2000
2001 A changeset that has been "split" will have a successors set containing
2001 A changeset that has been "split" will have a successors set containing
2002 more than one successor.
2002 more than one successor.
2003
2003
2004 A changeset that has been rewritten in multiple different ways is called
2004 A changeset that has been rewritten in multiple different ways is called
2005 "divergent". Such changesets have multiple successor sets (each of which
2005 "divergent". Such changesets have multiple successor sets (each of which
2006 may also be split, i.e. have multiple successors).
2006 may also be split, i.e. have multiple successors).
2007
2007
2008 Results are displayed as follows::
2008 Results are displayed as follows::
2009
2009
2010 <rev1>
2010 <rev1>
2011 <successors-1A>
2011 <successors-1A>
2012 <rev2>
2012 <rev2>
2013 <successors-2A>
2013 <successors-2A>
2014 <successors-2B1> <successors-2B2> <successors-2B3>
2014 <successors-2B1> <successors-2B2> <successors-2B3>
2015
2015
2016 Here rev2 has two possible (i.e. divergent) successors sets. The first
2016 Here rev2 has two possible (i.e. divergent) successors sets. The first
2017 holds one element, whereas the second holds three (i.e. the changeset has
2017 holds one element, whereas the second holds three (i.e. the changeset has
2018 been split).
2018 been split).
2019 """
2019 """
2020 # passed to successorssets caching computation from one call to another
2020 # passed to successorssets caching computation from one call to another
2021 cache = {}
2021 cache = {}
2022 ctx2str = str
2022 ctx2str = str
2023 node2str = short
2023 node2str = short
2024 if ui.debug():
2024 if ui.debug():
2025 def ctx2str(ctx):
2025 def ctx2str(ctx):
2026 return ctx.hex()
2026 return ctx.hex()
2027 node2str = hex
2027 node2str = hex
2028 for rev in scmutil.revrange(repo, revs):
2028 for rev in scmutil.revrange(repo, revs):
2029 ctx = repo[rev]
2029 ctx = repo[rev]
2030 ui.write('%s\n'% ctx2str(ctx))
2030 ui.write('%s\n'% ctx2str(ctx))
2031 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2031 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2032 if succsset:
2032 if succsset:
2033 ui.write(' ')
2033 ui.write(' ')
2034 ui.write(node2str(succsset[0]))
2034 ui.write(node2str(succsset[0]))
2035 for node in succsset[1:]:
2035 for node in succsset[1:]:
2036 ui.write(' ')
2036 ui.write(' ')
2037 ui.write(node2str(node))
2037 ui.write(node2str(node))
2038 ui.write('\n')
2038 ui.write('\n')
2039
2039
2040 @command('debugtemplate',
2040 @command('debugtemplate',
2041 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2041 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2042 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2042 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2043 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2043 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2044 optionalrepo=True)
2044 optionalrepo=True)
2045 def debugtemplate(ui, repo, tmpl, **opts):
2045 def debugtemplate(ui, repo, tmpl, **opts):
2046 """parse and apply a template
2046 """parse and apply a template
2047
2047
2048 If -r/--rev is given, the template is processed as a log template and
2048 If -r/--rev is given, the template is processed as a log template and
2049 applied to the given changesets. Otherwise, it is processed as a generic
2049 applied to the given changesets. Otherwise, it is processed as a generic
2050 template.
2050 template.
2051
2051
2052 Use --verbose to print the parsed tree.
2052 Use --verbose to print the parsed tree.
2053 """
2053 """
2054 revs = None
2054 revs = None
2055 if opts['rev']:
2055 if opts['rev']:
2056 if repo is None:
2056 if repo is None:
2057 raise error.RepoError(_('there is no Mercurial repository here '
2057 raise error.RepoError(_('there is no Mercurial repository here '
2058 '(.hg not found)'))
2058 '(.hg not found)'))
2059 revs = scmutil.revrange(repo, opts['rev'])
2059 revs = scmutil.revrange(repo, opts['rev'])
2060
2060
2061 props = {}
2061 props = {}
2062 for d in opts['define']:
2062 for d in opts['define']:
2063 try:
2063 try:
2064 k, v = (e.strip() for e in d.split('=', 1))
2064 k, v = (e.strip() for e in d.split('=', 1))
2065 if not k or k == 'ui':
2065 if not k or k == 'ui':
2066 raise ValueError
2066 raise ValueError
2067 props[k] = v
2067 props[k] = v
2068 except ValueError:
2068 except ValueError:
2069 raise error.Abort(_('malformed keyword definition: %s') % d)
2069 raise error.Abort(_('malformed keyword definition: %s') % d)
2070
2070
2071 if ui.verbose:
2071 if ui.verbose:
2072 aliases = ui.configitems('templatealias')
2072 aliases = ui.configitems('templatealias')
2073 tree = templater.parse(tmpl)
2073 tree = templater.parse(tmpl)
2074 ui.note(templater.prettyformat(tree), '\n')
2074 ui.note(templater.prettyformat(tree), '\n')
2075 newtree = templater.expandaliases(tree, aliases)
2075 newtree = templater.expandaliases(tree, aliases)
2076 if newtree != tree:
2076 if newtree != tree:
2077 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2077 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2078
2078
2079 mapfile = None
2079 mapfile = None
2080 if revs is None:
2080 if revs is None:
2081 k = 'debugtemplate'
2081 k = 'debugtemplate'
2082 t = formatter.maketemplater(ui, k, tmpl)
2082 t = formatter.maketemplater(ui, k, tmpl)
2083 ui.write(templater.stringify(t(k, ui=ui, **props)))
2083 ui.write(templater.stringify(t(k, ui=ui, **props)))
2084 else:
2084 else:
2085 displayer = cmdutil.changeset_templater(ui, repo, None, opts, tmpl,
2085 displayer = cmdutil.changeset_templater(ui, repo, None, opts, tmpl,
2086 mapfile, buffered=False)
2086 mapfile, buffered=False)
2087 for r in revs:
2087 for r in revs:
2088 displayer.show(repo[r], **props)
2088 displayer.show(repo[r], **props)
2089 displayer.close()
2089 displayer.close()
2090
2090
2091 @command('debugupdatecaches', [])
2091 @command('debugupdatecaches', [])
2092 def debugupdatecaches(ui, repo, *pats, **opts):
2092 def debugupdatecaches(ui, repo, *pats, **opts):
2093 """warm all known caches in the repository"""
2093 """warm all known caches in the repository"""
2094 with repo.wlock():
2094 with repo.wlock():
2095 with repo.lock():
2095 with repo.lock():
2096 repo.updatecaches()
2096 repo.updatecaches()
2097
2097
2098 @command('debugupgraderepo', [
2098 @command('debugupgraderepo', [
2099 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2099 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2100 ('', 'run', False, _('performs an upgrade')),
2100 ('', 'run', False, _('performs an upgrade')),
2101 ])
2101 ])
2102 def debugupgraderepo(ui, repo, run=False, optimize=None):
2102 def debugupgraderepo(ui, repo, run=False, optimize=None):
2103 """upgrade a repository to use different features
2103 """upgrade a repository to use different features
2104
2104
2105 If no arguments are specified, the repository is evaluated for upgrade
2105 If no arguments are specified, the repository is evaluated for upgrade
2106 and a list of problems and potential optimizations is printed.
2106 and a list of problems and potential optimizations is printed.
2107
2107
2108 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2108 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2109 can be influenced via additional arguments. More details will be provided
2109 can be influenced via additional arguments. More details will be provided
2110 by the command output when run without ``--run``.
2110 by the command output when run without ``--run``.
2111
2111
2112 During the upgrade, the repository will be locked and no writes will be
2112 During the upgrade, the repository will be locked and no writes will be
2113 allowed.
2113 allowed.
2114
2114
2115 At the end of the upgrade, the repository may not be readable while new
2115 At the end of the upgrade, the repository may not be readable while new
2116 repository data is swapped in. This window will be as long as it takes to
2116 repository data is swapped in. This window will be as long as it takes to
2117 rename some directories inside the ``.hg`` directory. On most machines, this
2117 rename some directories inside the ``.hg`` directory. On most machines, this
2118 should complete almost instantaneously and the chances of a consumer being
2118 should complete almost instantaneously and the chances of a consumer being
2119 unable to access the repository should be low.
2119 unable to access the repository should be low.
2120 """
2120 """
2121 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2121 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2122
2122
2123 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2123 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2124 inferrepo=True)
2124 inferrepo=True)
2125 def debugwalk(ui, repo, *pats, **opts):
2125 def debugwalk(ui, repo, *pats, **opts):
2126 """show how files match on given patterns"""
2126 """show how files match on given patterns"""
2127 m = scmutil.match(repo[None], pats, opts)
2127 m = scmutil.match(repo[None], pats, opts)
2128 ui.write(('matcher: %r\n' % m))
2128 items = list(repo[None].walk(m))
2129 items = list(repo[None].walk(m))
2129 if not items:
2130 if not items:
2130 return
2131 return
2131 f = lambda fn: fn
2132 f = lambda fn: fn
2132 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2133 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2133 f = lambda fn: util.normpath(fn)
2134 f = lambda fn: util.normpath(fn)
2134 fmt = 'f %%-%ds %%-%ds %%s' % (
2135 fmt = 'f %%-%ds %%-%ds %%s' % (
2135 max([len(abs) for abs in items]),
2136 max([len(abs) for abs in items]),
2136 max([len(m.rel(abs)) for abs in items]))
2137 max([len(m.rel(abs)) for abs in items]))
2137 for abs in items:
2138 for abs in items:
2138 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2139 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2139 ui.write("%s\n" % line.rstrip())
2140 ui.write("%s\n" % line.rstrip())
2140
2141
2141 @command('debugwireargs',
2142 @command('debugwireargs',
2142 [('', 'three', '', 'three'),
2143 [('', 'three', '', 'three'),
2143 ('', 'four', '', 'four'),
2144 ('', 'four', '', 'four'),
2144 ('', 'five', '', 'five'),
2145 ('', 'five', '', 'five'),
2145 ] + cmdutil.remoteopts,
2146 ] + cmdutil.remoteopts,
2146 _('REPO [OPTIONS]... [ONE [TWO]]'),
2147 _('REPO [OPTIONS]... [ONE [TWO]]'),
2147 norepo=True)
2148 norepo=True)
2148 def debugwireargs(ui, repopath, *vals, **opts):
2149 def debugwireargs(ui, repopath, *vals, **opts):
2149 repo = hg.peer(ui, opts, repopath)
2150 repo = hg.peer(ui, opts, repopath)
2150 for opt in cmdutil.remoteopts:
2151 for opt in cmdutil.remoteopts:
2151 del opts[opt[1]]
2152 del opts[opt[1]]
2152 args = {}
2153 args = {}
2153 for k, v in opts.iteritems():
2154 for k, v in opts.iteritems():
2154 if v:
2155 if v:
2155 args[k] = v
2156 args[k] = v
2156 # run twice to check that we don't mess up the stream for the next command
2157 # run twice to check that we don't mess up the stream for the next command
2157 res1 = repo.debugwireargs(*vals, **args)
2158 res1 = repo.debugwireargs(*vals, **args)
2158 res2 = repo.debugwireargs(*vals, **args)
2159 res2 = repo.debugwireargs(*vals, **args)
2159 ui.write("%s\n" % res1)
2160 ui.write("%s\n" % res1)
2160 if res1 != res2:
2161 if res1 != res2:
2161 ui.warn("%s\n" % res2)
2162 ui.warn("%s\n" % res2)
@@ -1,78 +1,79 b''
1 #require eol-in-paths
1 #require eol-in-paths
2
2
3 https://bz.mercurial-scm.org/352
3 https://bz.mercurial-scm.org/352
4
4
5 test issue352
5 test issue352
6
6
7 $ hg init foo
7 $ hg init foo
8 $ cd foo
8 $ cd foo
9 $ A=`printf 'he\rllo'`
9 $ A=`printf 'he\rllo'`
10 $ echo foo > "$A"
10 $ echo foo > "$A"
11 $ hg add
11 $ hg add
12 adding he\r (no-eol) (esc)
12 adding he\r (no-eol) (esc)
13 llo
13 llo
14 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
14 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
15 [255]
15 [255]
16 $ hg ci -A -m m
16 $ hg ci -A -m m
17 adding he\r (no-eol) (esc)
17 adding he\r (no-eol) (esc)
18 llo
18 llo
19 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
19 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
20 [255]
20 [255]
21 $ rm "$A"
21 $ rm "$A"
22 $ echo foo > "hell
22 $ echo foo > "hell
23 > o"
23 > o"
24 $ hg add
24 $ hg add
25 adding hell
25 adding hell
26 o
26 o
27 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
27 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
28 [255]
28 [255]
29 $ hg ci -A -m m
29 $ hg ci -A -m m
30 adding hell
30 adding hell
31 o
31 o
32 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
32 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
33 [255]
33 [255]
34 $ echo foo > "$A"
34 $ echo foo > "$A"
35 $ hg debugwalk
35 $ hg debugwalk
36 matcher: <matcher files=[], patterns=None, includes=None, excludes=None>
36 f he\r (no-eol) (esc)
37 f he\r (no-eol) (esc)
37 llo he\r (no-eol) (esc)
38 llo he\r (no-eol) (esc)
38 llo
39 llo
39 f hell
40 f hell
40 o hell
41 o hell
41 o
42 o
42
43
43 $ echo bla > quickfox
44 $ echo bla > quickfox
44 $ hg add quickfox
45 $ hg add quickfox
45 $ hg ci -m 2
46 $ hg ci -m 2
46 $ A=`printf 'quick\rfox'`
47 $ A=`printf 'quick\rfox'`
47 $ hg cp quickfox "$A"
48 $ hg cp quickfox "$A"
48 abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
49 abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
49 [255]
50 [255]
50 $ hg mv quickfox "$A"
51 $ hg mv quickfox "$A"
51 abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
52 abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
52 [255]
53 [255]
53
54
54 https://bz.mercurial-scm.org/2036
55 https://bz.mercurial-scm.org/2036
55
56
56 $ cd ..
57 $ cd ..
57
58
58 test issue2039
59 test issue2039
59
60
60 $ hg init bar
61 $ hg init bar
61 $ cd bar
62 $ cd bar
62 $ cat <<EOF >> $HGRCPATH
63 $ cat <<EOF >> $HGRCPATH
63 > [extensions]
64 > [extensions]
64 > color =
65 > color =
65 > [color]
66 > [color]
66 > mode = ansi
67 > mode = ansi
67 > EOF
68 > EOF
68 $ A=`printf 'foo\nbar'`
69 $ A=`printf 'foo\nbar'`
69 $ B=`printf 'foo\nbar.baz'`
70 $ B=`printf 'foo\nbar.baz'`
70 $ touch "$A"
71 $ touch "$A"
71 $ touch "$B"
72 $ touch "$B"
72 $ hg status --color=always
73 $ hg status --color=always
73 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mfoo\x1b[0m (esc)
74 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mfoo\x1b[0m (esc)
74 \x1b[0;35;1;4mbar\x1b[0m (esc)
75 \x1b[0;35;1;4mbar\x1b[0m (esc)
75 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mfoo\x1b[0m (esc)
76 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mfoo\x1b[0m (esc)
76 \x1b[0;35;1;4mbar.baz\x1b[0m (esc)
77 \x1b[0;35;1;4mbar.baz\x1b[0m (esc)
77
78
78 $ cd ..
79 $ cd ..
@@ -1,438 +1,518 b''
1 $ hg init t
1 $ hg init t
2 $ cd t
2 $ cd t
3 $ mkdir -p beans
3 $ mkdir -p beans
4 $ for b in kidney navy turtle borlotti black pinto; do
4 $ for b in kidney navy turtle borlotti black pinto; do
5 > echo $b > beans/$b
5 > echo $b > beans/$b
6 > done
6 > done
7 $ mkdir -p mammals/Procyonidae
7 $ mkdir -p mammals/Procyonidae
8 $ for m in cacomistle coatimundi raccoon; do
8 $ for m in cacomistle coatimundi raccoon; do
9 > echo $m > mammals/Procyonidae/$m
9 > echo $m > mammals/Procyonidae/$m
10 > done
10 > done
11 $ echo skunk > mammals/skunk
11 $ echo skunk > mammals/skunk
12 $ echo fennel > fennel
12 $ echo fennel > fennel
13 $ echo fenugreek > fenugreek
13 $ echo fenugreek > fenugreek
14 $ echo fiddlehead > fiddlehead
14 $ echo fiddlehead > fiddlehead
15 $ hg addremove
15 $ hg addremove
16 adding beans/black
16 adding beans/black
17 adding beans/borlotti
17 adding beans/borlotti
18 adding beans/kidney
18 adding beans/kidney
19 adding beans/navy
19 adding beans/navy
20 adding beans/pinto
20 adding beans/pinto
21 adding beans/turtle
21 adding beans/turtle
22 adding fennel
22 adding fennel
23 adding fenugreek
23 adding fenugreek
24 adding fiddlehead
24 adding fiddlehead
25 adding mammals/Procyonidae/cacomistle
25 adding mammals/Procyonidae/cacomistle
26 adding mammals/Procyonidae/coatimundi
26 adding mammals/Procyonidae/coatimundi
27 adding mammals/Procyonidae/raccoon
27 adding mammals/Procyonidae/raccoon
28 adding mammals/skunk
28 adding mammals/skunk
29 $ hg commit -m "commit #0"
29 $ hg commit -m "commit #0"
30
30
31 $ hg debugwalk
31 $ hg debugwalk
32 matcher: <matcher files=[], patterns=None, includes=None, excludes=None>
32 f beans/black beans/black
33 f beans/black beans/black
33 f beans/borlotti beans/borlotti
34 f beans/borlotti beans/borlotti
34 f beans/kidney beans/kidney
35 f beans/kidney beans/kidney
35 f beans/navy beans/navy
36 f beans/navy beans/navy
36 f beans/pinto beans/pinto
37 f beans/pinto beans/pinto
37 f beans/turtle beans/turtle
38 f beans/turtle beans/turtle
38 f fennel fennel
39 f fennel fennel
39 f fenugreek fenugreek
40 f fenugreek fenugreek
40 f fiddlehead fiddlehead
41 f fiddlehead fiddlehead
41 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
42 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
42 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
43 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
43 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
44 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
44 f mammals/skunk mammals/skunk
45 f mammals/skunk mammals/skunk
45 $ hg debugwalk -I.
46 $ hg debugwalk -I.
47 matcher: <matcher files=[], patterns=None, includes='(?:)', excludes=None>
46 f beans/black beans/black
48 f beans/black beans/black
47 f beans/borlotti beans/borlotti
49 f beans/borlotti beans/borlotti
48 f beans/kidney beans/kidney
50 f beans/kidney beans/kidney
49 f beans/navy beans/navy
51 f beans/navy beans/navy
50 f beans/pinto beans/pinto
52 f beans/pinto beans/pinto
51 f beans/turtle beans/turtle
53 f beans/turtle beans/turtle
52 f fennel fennel
54 f fennel fennel
53 f fenugreek fenugreek
55 f fenugreek fenugreek
54 f fiddlehead fiddlehead
56 f fiddlehead fiddlehead
55 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
57 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
56 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
58 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
57 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
59 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
58 f mammals/skunk mammals/skunk
60 f mammals/skunk mammals/skunk
59
61
60 $ cd mammals
62 $ cd mammals
61 $ hg debugwalk
63 $ hg debugwalk
64 matcher: <matcher files=[], patterns=None, includes=None, excludes=None>
62 f beans/black ../beans/black
65 f beans/black ../beans/black
63 f beans/borlotti ../beans/borlotti
66 f beans/borlotti ../beans/borlotti
64 f beans/kidney ../beans/kidney
67 f beans/kidney ../beans/kidney
65 f beans/navy ../beans/navy
68 f beans/navy ../beans/navy
66 f beans/pinto ../beans/pinto
69 f beans/pinto ../beans/pinto
67 f beans/turtle ../beans/turtle
70 f beans/turtle ../beans/turtle
68 f fennel ../fennel
71 f fennel ../fennel
69 f fenugreek ../fenugreek
72 f fenugreek ../fenugreek
70 f fiddlehead ../fiddlehead
73 f fiddlehead ../fiddlehead
71 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
74 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
72 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
75 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
73 f mammals/Procyonidae/raccoon Procyonidae/raccoon
76 f mammals/Procyonidae/raccoon Procyonidae/raccoon
74 f mammals/skunk skunk
77 f mammals/skunk skunk
75 $ hg debugwalk -X ../beans
78 $ hg debugwalk -X ../beans
79 matcher: <matcher files=[], patterns=None, includes=None, excludes='(?:beans(?:/|$))'>
76 f fennel ../fennel
80 f fennel ../fennel
77 f fenugreek ../fenugreek
81 f fenugreek ../fenugreek
78 f fiddlehead ../fiddlehead
82 f fiddlehead ../fiddlehead
79 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
83 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
80 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
84 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
81 f mammals/Procyonidae/raccoon Procyonidae/raccoon
85 f mammals/Procyonidae/raccoon Procyonidae/raccoon
82 f mammals/skunk skunk
86 f mammals/skunk skunk
83 $ hg debugwalk -I '*k'
87 $ hg debugwalk -I '*k'
88 matcher: <matcher files=[], patterns=None, includes='(?:mammals\\/[^/]*k(?:/|$))', excludes=None>
84 f mammals/skunk skunk
89 f mammals/skunk skunk
85 $ hg debugwalk -I 'glob:*k'
90 $ hg debugwalk -I 'glob:*k'
91 matcher: <matcher files=[], patterns=None, includes='(?:mammals\\/[^/]*k(?:/|$))', excludes=None>
86 f mammals/skunk skunk
92 f mammals/skunk skunk
87 $ hg debugwalk -I 'relglob:*k'
93 $ hg debugwalk -I 'relglob:*k'
94 matcher: <matcher files=[], patterns=None, includes='(?:(?:|.*/)[^/]*k(?:/|$))', excludes=None>
88 f beans/black ../beans/black
95 f beans/black ../beans/black
89 f fenugreek ../fenugreek
96 f fenugreek ../fenugreek
90 f mammals/skunk skunk
97 f mammals/skunk skunk
91 $ hg debugwalk -I 'relglob:*k' .
98 $ hg debugwalk -I 'relglob:*k' .
99 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes='(?:(?:|.*/)[^/]*k(?:/|$))', excludes=None>
92 f mammals/skunk skunk
100 f mammals/skunk skunk
93 $ hg debugwalk -I 're:.*k$'
101 $ hg debugwalk -I 're:.*k$'
102 matcher: <matcher files=[], patterns=None, includes='(?:.*k$)', excludes=None>
94 f beans/black ../beans/black
103 f beans/black ../beans/black
95 f fenugreek ../fenugreek
104 f fenugreek ../fenugreek
96 f mammals/skunk skunk
105 f mammals/skunk skunk
97 $ hg debugwalk -I 'relre:.*k$'
106 $ hg debugwalk -I 'relre:.*k$'
107 matcher: <matcher files=[], patterns=None, includes='(?:.*.*k$)', excludes=None>
98 f beans/black ../beans/black
108 f beans/black ../beans/black
99 f fenugreek ../fenugreek
109 f fenugreek ../fenugreek
100 f mammals/skunk skunk
110 f mammals/skunk skunk
101 $ hg debugwalk -I 'path:beans'
111 $ hg debugwalk -I 'path:beans'
112 matcher: <matcher files=[], patterns=None, includes='(?:^beans(?:/|$))', excludes=None>
102 f beans/black ../beans/black
113 f beans/black ../beans/black
103 f beans/borlotti ../beans/borlotti
114 f beans/borlotti ../beans/borlotti
104 f beans/kidney ../beans/kidney
115 f beans/kidney ../beans/kidney
105 f beans/navy ../beans/navy
116 f beans/navy ../beans/navy
106 f beans/pinto ../beans/pinto
117 f beans/pinto ../beans/pinto
107 f beans/turtle ../beans/turtle
118 f beans/turtle ../beans/turtle
108 $ hg debugwalk -I 'relpath:detour/../../beans'
119 $ hg debugwalk -I 'relpath:detour/../../beans'
120 matcher: <matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes=None>
109 f beans/black ../beans/black
121 f beans/black ../beans/black
110 f beans/borlotti ../beans/borlotti
122 f beans/borlotti ../beans/borlotti
111 f beans/kidney ../beans/kidney
123 f beans/kidney ../beans/kidney
112 f beans/navy ../beans/navy
124 f beans/navy ../beans/navy
113 f beans/pinto ../beans/pinto
125 f beans/pinto ../beans/pinto
114 f beans/turtle ../beans/turtle
126 f beans/turtle ../beans/turtle
115
127
116 $ hg debugwalk 'rootfilesin:'
128 $ hg debugwalk 'rootfilesin:'
129 matcher: <matcher files=[], patterns='(?:^[^/]+$)', includes=None, excludes=None>
117 f fennel ../fennel
130 f fennel ../fennel
118 f fenugreek ../fenugreek
131 f fenugreek ../fenugreek
119 f fiddlehead ../fiddlehead
132 f fiddlehead ../fiddlehead
120 $ hg debugwalk -I 'rootfilesin:'
133 $ hg debugwalk -I 'rootfilesin:'
134 matcher: <matcher files=[], patterns=None, includes='(?:^[^/]+$)', excludes=None>
121 f fennel ../fennel
135 f fennel ../fennel
122 f fenugreek ../fenugreek
136 f fenugreek ../fenugreek
123 f fiddlehead ../fiddlehead
137 f fiddlehead ../fiddlehead
124 $ hg debugwalk 'rootfilesin:.'
138 $ hg debugwalk 'rootfilesin:.'
139 matcher: <matcher files=[], patterns='(?:^[^/]+$)', includes=None, excludes=None>
125 f fennel ../fennel
140 f fennel ../fennel
126 f fenugreek ../fenugreek
141 f fenugreek ../fenugreek
127 f fiddlehead ../fiddlehead
142 f fiddlehead ../fiddlehead
128 $ hg debugwalk -I 'rootfilesin:.'
143 $ hg debugwalk -I 'rootfilesin:.'
144 matcher: <matcher files=[], patterns=None, includes='(?:^[^/]+$)', excludes=None>
129 f fennel ../fennel
145 f fennel ../fennel
130 f fenugreek ../fenugreek
146 f fenugreek ../fenugreek
131 f fiddlehead ../fiddlehead
147 f fiddlehead ../fiddlehead
132 $ hg debugwalk -X 'rootfilesin:'
148 $ hg debugwalk -X 'rootfilesin:'
149 matcher: <matcher files=[], patterns=None, includes=None, excludes='(?:^[^/]+$)'>
133 f beans/black ../beans/black
150 f beans/black ../beans/black
134 f beans/borlotti ../beans/borlotti
151 f beans/borlotti ../beans/borlotti
135 f beans/kidney ../beans/kidney
152 f beans/kidney ../beans/kidney
136 f beans/navy ../beans/navy
153 f beans/navy ../beans/navy
137 f beans/pinto ../beans/pinto
154 f beans/pinto ../beans/pinto
138 f beans/turtle ../beans/turtle
155 f beans/turtle ../beans/turtle
139 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
156 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
140 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
157 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
141 f mammals/Procyonidae/raccoon Procyonidae/raccoon
158 f mammals/Procyonidae/raccoon Procyonidae/raccoon
142 f mammals/skunk skunk
159 f mammals/skunk skunk
143 $ hg debugwalk 'rootfilesin:fennel'
160 $ hg debugwalk 'rootfilesin:fennel'
161 matcher: <matcher files=[], patterns='(?:^fennel/[^/]+$)', includes=None, excludes=None>
144 $ hg debugwalk -I 'rootfilesin:fennel'
162 $ hg debugwalk -I 'rootfilesin:fennel'
163 matcher: <matcher files=[], patterns=None, includes='(?:^fennel/[^/]+$)', excludes=None>
145 $ hg debugwalk 'rootfilesin:skunk'
164 $ hg debugwalk 'rootfilesin:skunk'
165 matcher: <matcher files=[], patterns='(?:^skunk/[^/]+$)', includes=None, excludes=None>
146 $ hg debugwalk -I 'rootfilesin:skunk'
166 $ hg debugwalk -I 'rootfilesin:skunk'
167 matcher: <matcher files=[], patterns=None, includes='(?:^skunk/[^/]+$)', excludes=None>
147 $ hg debugwalk 'rootfilesin:beans'
168 $ hg debugwalk 'rootfilesin:beans'
169 matcher: <matcher files=[], patterns='(?:^beans/[^/]+$)', includes=None, excludes=None>
148 f beans/black ../beans/black
170 f beans/black ../beans/black
149 f beans/borlotti ../beans/borlotti
171 f beans/borlotti ../beans/borlotti
150 f beans/kidney ../beans/kidney
172 f beans/kidney ../beans/kidney
151 f beans/navy ../beans/navy
173 f beans/navy ../beans/navy
152 f beans/pinto ../beans/pinto
174 f beans/pinto ../beans/pinto
153 f beans/turtle ../beans/turtle
175 f beans/turtle ../beans/turtle
154 $ hg debugwalk -I 'rootfilesin:beans'
176 $ hg debugwalk -I 'rootfilesin:beans'
177 matcher: <matcher files=[], patterns=None, includes='(?:^beans/[^/]+$)', excludes=None>
155 f beans/black ../beans/black
178 f beans/black ../beans/black
156 f beans/borlotti ../beans/borlotti
179 f beans/borlotti ../beans/borlotti
157 f beans/kidney ../beans/kidney
180 f beans/kidney ../beans/kidney
158 f beans/navy ../beans/navy
181 f beans/navy ../beans/navy
159 f beans/pinto ../beans/pinto
182 f beans/pinto ../beans/pinto
160 f beans/turtle ../beans/turtle
183 f beans/turtle ../beans/turtle
161 $ hg debugwalk 'rootfilesin:mammals'
184 $ hg debugwalk 'rootfilesin:mammals'
185 matcher: <matcher files=[], patterns='(?:^mammals/[^/]+$)', includes=None, excludes=None>
162 f mammals/skunk skunk
186 f mammals/skunk skunk
163 $ hg debugwalk -I 'rootfilesin:mammals'
187 $ hg debugwalk -I 'rootfilesin:mammals'
188 matcher: <matcher files=[], patterns=None, includes='(?:^mammals/[^/]+$)', excludes=None>
164 f mammals/skunk skunk
189 f mammals/skunk skunk
165 $ hg debugwalk 'rootfilesin:mammals/'
190 $ hg debugwalk 'rootfilesin:mammals/'
191 matcher: <matcher files=[], patterns='(?:^mammals/[^/]+$)', includes=None, excludes=None>
166 f mammals/skunk skunk
192 f mammals/skunk skunk
167 $ hg debugwalk -I 'rootfilesin:mammals/'
193 $ hg debugwalk -I 'rootfilesin:mammals/'
194 matcher: <matcher files=[], patterns=None, includes='(?:^mammals/[^/]+$)', excludes=None>
168 f mammals/skunk skunk
195 f mammals/skunk skunk
169 $ hg debugwalk -X 'rootfilesin:mammals'
196 $ hg debugwalk -X 'rootfilesin:mammals'
197 matcher: <matcher files=[], patterns=None, includes=None, excludes='(?:^mammals/[^/]+$)'>
170 f beans/black ../beans/black
198 f beans/black ../beans/black
171 f beans/borlotti ../beans/borlotti
199 f beans/borlotti ../beans/borlotti
172 f beans/kidney ../beans/kidney
200 f beans/kidney ../beans/kidney
173 f beans/navy ../beans/navy
201 f beans/navy ../beans/navy
174 f beans/pinto ../beans/pinto
202 f beans/pinto ../beans/pinto
175 f beans/turtle ../beans/turtle
203 f beans/turtle ../beans/turtle
176 f fennel ../fennel
204 f fennel ../fennel
177 f fenugreek ../fenugreek
205 f fenugreek ../fenugreek
178 f fiddlehead ../fiddlehead
206 f fiddlehead ../fiddlehead
179 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
207 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
180 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
208 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
181 f mammals/Procyonidae/raccoon Procyonidae/raccoon
209 f mammals/Procyonidae/raccoon Procyonidae/raccoon
182
210
183 $ hg debugwalk .
211 $ hg debugwalk .
212 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None, excludes=None>
184 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
213 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
185 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
214 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
186 f mammals/Procyonidae/raccoon Procyonidae/raccoon
215 f mammals/Procyonidae/raccoon Procyonidae/raccoon
187 f mammals/skunk skunk
216 f mammals/skunk skunk
188 $ hg debugwalk -I.
217 $ hg debugwalk -I.
218 matcher: <matcher files=[], patterns=None, includes='(?:mammals(?:/|$))', excludes=None>
189 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
219 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
190 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
220 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
191 f mammals/Procyonidae/raccoon Procyonidae/raccoon
221 f mammals/Procyonidae/raccoon Procyonidae/raccoon
192 f mammals/skunk skunk
222 f mammals/skunk skunk
193 $ hg debugwalk Procyonidae
223 $ hg debugwalk Procyonidae
224 matcher: <matcher files=['mammals/Procyonidae'], patterns='(?:mammals\\/Procyonidae(?:/|$))', includes=None, excludes=None>
194 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
225 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
195 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
226 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
196 f mammals/Procyonidae/raccoon Procyonidae/raccoon
227 f mammals/Procyonidae/raccoon Procyonidae/raccoon
197
228
198 $ cd Procyonidae
229 $ cd Procyonidae
199 $ hg debugwalk .
230 $ hg debugwalk .
231 matcher: <matcher files=['mammals/Procyonidae'], patterns='(?:mammals\\/Procyonidae(?:/|$))', includes=None, excludes=None>
200 f mammals/Procyonidae/cacomistle cacomistle
232 f mammals/Procyonidae/cacomistle cacomistle
201 f mammals/Procyonidae/coatimundi coatimundi
233 f mammals/Procyonidae/coatimundi coatimundi
202 f mammals/Procyonidae/raccoon raccoon
234 f mammals/Procyonidae/raccoon raccoon
203 $ hg debugwalk ..
235 $ hg debugwalk ..
236 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None, excludes=None>
204 f mammals/Procyonidae/cacomistle cacomistle
237 f mammals/Procyonidae/cacomistle cacomistle
205 f mammals/Procyonidae/coatimundi coatimundi
238 f mammals/Procyonidae/coatimundi coatimundi
206 f mammals/Procyonidae/raccoon raccoon
239 f mammals/Procyonidae/raccoon raccoon
207 f mammals/skunk ../skunk
240 f mammals/skunk ../skunk
208 $ cd ..
241 $ cd ..
209
242
210 $ hg debugwalk ../beans
243 $ hg debugwalk ../beans
244 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None, excludes=None>
211 f beans/black ../beans/black
245 f beans/black ../beans/black
212 f beans/borlotti ../beans/borlotti
246 f beans/borlotti ../beans/borlotti
213 f beans/kidney ../beans/kidney
247 f beans/kidney ../beans/kidney
214 f beans/navy ../beans/navy
248 f beans/navy ../beans/navy
215 f beans/pinto ../beans/pinto
249 f beans/pinto ../beans/pinto
216 f beans/turtle ../beans/turtle
250 f beans/turtle ../beans/turtle
217 $ hg debugwalk .
251 $ hg debugwalk .
252 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None, excludes=None>
218 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
253 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
219 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
254 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
220 f mammals/Procyonidae/raccoon Procyonidae/raccoon
255 f mammals/Procyonidae/raccoon Procyonidae/raccoon
221 f mammals/skunk skunk
256 f mammals/skunk skunk
222 $ hg debugwalk .hg
257 $ hg debugwalk .hg
223 abort: path 'mammals/.hg' is inside nested repo 'mammals' (glob)
258 abort: path 'mammals/.hg' is inside nested repo 'mammals' (glob)
224 [255]
259 [255]
225 $ hg debugwalk ../.hg
260 $ hg debugwalk ../.hg
226 abort: path contains illegal component: .hg
261 abort: path contains illegal component: .hg
227 [255]
262 [255]
228 $ cd ..
263 $ cd ..
229
264
230 $ hg debugwalk -Ibeans
265 $ hg debugwalk -Ibeans
266 matcher: <matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes=None>
231 f beans/black beans/black
267 f beans/black beans/black
232 f beans/borlotti beans/borlotti
268 f beans/borlotti beans/borlotti
233 f beans/kidney beans/kidney
269 f beans/kidney beans/kidney
234 f beans/navy beans/navy
270 f beans/navy beans/navy
235 f beans/pinto beans/pinto
271 f beans/pinto beans/pinto
236 f beans/turtle beans/turtle
272 f beans/turtle beans/turtle
237 $ hg debugwalk -I '{*,{b,m}*/*}k'
273 $ hg debugwalk -I '{*,{b,m}*/*}k'
274 matcher: <matcher files=[], patterns=None, includes='(?:(?:[^/]*|(?:b|m)[^/]*\\/[^/]*)k(?:/|$))', excludes=None>
238 f beans/black beans/black
275 f beans/black beans/black
239 f fenugreek fenugreek
276 f fenugreek fenugreek
240 f mammals/skunk mammals/skunk
277 f mammals/skunk mammals/skunk
241 $ hg debugwalk -Ibeans mammals
278 $ hg debugwalk -Ibeans mammals
279 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes='(?:beans(?:/|$))', excludes=None>
242 $ hg debugwalk -Inon-existent
280 $ hg debugwalk -Inon-existent
281 matcher: <matcher files=[], patterns=None, includes='(?:non\\-existent(?:/|$))', excludes=None>
243 $ hg debugwalk -Inon-existent -Ibeans/black
282 $ hg debugwalk -Inon-existent -Ibeans/black
283 matcher: <matcher files=[], patterns=None, includes='(?:non\\-existent(?:/|$)|beans\\/black(?:/|$))', excludes=None>
244 f beans/black beans/black
284 f beans/black beans/black
245 $ hg debugwalk -Ibeans beans/black
285 $ hg debugwalk -Ibeans beans/black
286 matcher: <matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes='(?:beans(?:/|$))', excludes=None>
246 f beans/black beans/black exact
287 f beans/black beans/black exact
247 $ hg debugwalk -Ibeans/black beans
288 $ hg debugwalk -Ibeans/black beans
289 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes='(?:beans\\/black(?:/|$))', excludes=None>
248 f beans/black beans/black
290 f beans/black beans/black
249 $ hg debugwalk -Xbeans/black beans
291 $ hg debugwalk -Xbeans/black beans
292 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None, excludes='(?:beans\\/black(?:/|$))'>
250 f beans/borlotti beans/borlotti
293 f beans/borlotti beans/borlotti
251 f beans/kidney beans/kidney
294 f beans/kidney beans/kidney
252 f beans/navy beans/navy
295 f beans/navy beans/navy
253 f beans/pinto beans/pinto
296 f beans/pinto beans/pinto
254 f beans/turtle beans/turtle
297 f beans/turtle beans/turtle
255 $ hg debugwalk -Xbeans/black -Ibeans
298 $ hg debugwalk -Xbeans/black -Ibeans
299 matcher: <matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes='(?:beans\\/black(?:/|$))'>
256 f beans/borlotti beans/borlotti
300 f beans/borlotti beans/borlotti
257 f beans/kidney beans/kidney
301 f beans/kidney beans/kidney
258 f beans/navy beans/navy
302 f beans/navy beans/navy
259 f beans/pinto beans/pinto
303 f beans/pinto beans/pinto
260 f beans/turtle beans/turtle
304 f beans/turtle beans/turtle
261 $ hg debugwalk -Xbeans/black beans/black
305 $ hg debugwalk -Xbeans/black beans/black
306 matcher: <matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None, excludes='(?:beans\\/black(?:/|$))'>
262 f beans/black beans/black exact
307 f beans/black beans/black exact
263 $ hg debugwalk -Xbeans/black -Ibeans/black
308 $ hg debugwalk -Xbeans/black -Ibeans/black
309 matcher: <matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes='(?:beans\\/black(?:/|$))'>
264 $ hg debugwalk -Xbeans beans/black
310 $ hg debugwalk -Xbeans beans/black
311 matcher: <matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None, excludes='(?:beans(?:/|$))'>
265 f beans/black beans/black exact
312 f beans/black beans/black exact
266 $ hg debugwalk -Xbeans -Ibeans/black
313 $ hg debugwalk -Xbeans -Ibeans/black
314 matcher: <matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes='(?:beans(?:/|$))'>
267 $ hg debugwalk 'glob:mammals/../beans/b*'
315 $ hg debugwalk 'glob:mammals/../beans/b*'
316 matcher: <matcher files=['beans'], patterns='(?:beans\\/b[^/]*$)', includes=None, excludes=None>
268 f beans/black beans/black
317 f beans/black beans/black
269 f beans/borlotti beans/borlotti
318 f beans/borlotti beans/borlotti
270 $ hg debugwalk '-X*/Procyonidae' mammals
319 $ hg debugwalk '-X*/Procyonidae' mammals
320 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None, excludes='(?:[^/]*\\/Procyonidae(?:/|$))'>
271 f mammals/skunk mammals/skunk
321 f mammals/skunk mammals/skunk
272 $ hg debugwalk path:mammals
322 $ hg debugwalk path:mammals
323 matcher: <matcher files=['mammals'], patterns='(?:^mammals(?:/|$))', includes=None, excludes=None>
273 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
324 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
274 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
325 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
275 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
326 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
276 f mammals/skunk mammals/skunk
327 f mammals/skunk mammals/skunk
277 $ hg debugwalk ..
328 $ hg debugwalk ..
278 abort: .. not under root '$TESTTMP/t' (glob)
329 abort: .. not under root '$TESTTMP/t' (glob)
279 [255]
330 [255]
280 $ hg debugwalk beans/../..
331 $ hg debugwalk beans/../..
281 abort: beans/../.. not under root '$TESTTMP/t' (glob)
332 abort: beans/../.. not under root '$TESTTMP/t' (glob)
282 [255]
333 [255]
283 $ hg debugwalk .hg
334 $ hg debugwalk .hg
284 abort: path contains illegal component: .hg
335 abort: path contains illegal component: .hg
285 [255]
336 [255]
286 $ hg debugwalk beans/../.hg
337 $ hg debugwalk beans/../.hg
287 abort: path contains illegal component: .hg
338 abort: path contains illegal component: .hg
288 [255]
339 [255]
289 $ hg debugwalk beans/../.hg/data
340 $ hg debugwalk beans/../.hg/data
290 abort: path contains illegal component: .hg/data (glob)
341 abort: path contains illegal component: .hg/data (glob)
291 [255]
342 [255]
292 $ hg debugwalk beans/.hg
343 $ hg debugwalk beans/.hg
293 abort: path 'beans/.hg' is inside nested repo 'beans' (glob)
344 abort: path 'beans/.hg' is inside nested repo 'beans' (glob)
294 [255]
345 [255]
295
346
296 Test absolute paths:
347 Test absolute paths:
297
348
298 $ hg debugwalk `pwd`/beans
349 $ hg debugwalk `pwd`/beans
350 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None, excludes=None>
299 f beans/black beans/black
351 f beans/black beans/black
300 f beans/borlotti beans/borlotti
352 f beans/borlotti beans/borlotti
301 f beans/kidney beans/kidney
353 f beans/kidney beans/kidney
302 f beans/navy beans/navy
354 f beans/navy beans/navy
303 f beans/pinto beans/pinto
355 f beans/pinto beans/pinto
304 f beans/turtle beans/turtle
356 f beans/turtle beans/turtle
305 $ hg debugwalk `pwd`/..
357 $ hg debugwalk `pwd`/..
306 abort: $TESTTMP/t/.. not under root '$TESTTMP/t' (glob)
358 abort: $TESTTMP/t/.. not under root '$TESTTMP/t' (glob)
307 [255]
359 [255]
308
360
309 Test patterns:
361 Test patterns:
310
362
311 $ hg debugwalk glob:\*
363 $ hg debugwalk glob:\*
364 matcher: <matcher files=['.'], patterns='(?:[^/]*$)', includes=None, excludes=None>
312 f fennel fennel
365 f fennel fennel
313 f fenugreek fenugreek
366 f fenugreek fenugreek
314 f fiddlehead fiddlehead
367 f fiddlehead fiddlehead
315 #if eol-in-paths
368 #if eol-in-paths
316 $ echo glob:glob > glob:glob
369 $ echo glob:glob > glob:glob
317 $ hg addremove
370 $ hg addremove
318 adding glob:glob
371 adding glob:glob
319 warning: filename contains ':', which is reserved on Windows: 'glob:glob'
372 warning: filename contains ':', which is reserved on Windows: 'glob:glob'
320 $ hg debugwalk glob:\*
373 $ hg debugwalk glob:\*
374 matcher: <matcher files=['.'], patterns='(?:[^/]*$)', includes=None, excludes=None>
321 f fennel fennel
375 f fennel fennel
322 f fenugreek fenugreek
376 f fenugreek fenugreek
323 f fiddlehead fiddlehead
377 f fiddlehead fiddlehead
324 f glob:glob glob:glob
378 f glob:glob glob:glob
325 $ hg debugwalk glob:glob
379 $ hg debugwalk glob:glob
380 matcher: <matcher files=['glob'], patterns='(?:glob$)', includes=None, excludes=None>
326 glob: No such file or directory
381 glob: No such file or directory
327 $ hg debugwalk glob:glob:glob
382 $ hg debugwalk glob:glob:glob
383 matcher: <matcher files=['glob:glob'], patterns='(?:glob\\:glob$)', includes=None, excludes=None>
328 f glob:glob glob:glob exact
384 f glob:glob glob:glob exact
329 $ hg debugwalk path:glob:glob
385 $ hg debugwalk path:glob:glob
386 matcher: <matcher files=['glob:glob'], patterns='(?:^glob\\:glob(?:/|$))', includes=None, excludes=None>
330 f glob:glob glob:glob exact
387 f glob:glob glob:glob exact
331 $ rm glob:glob
388 $ rm glob:glob
332 $ hg addremove
389 $ hg addremove
333 removing glob:glob
390 removing glob:glob
334 #endif
391 #endif
335
392
336 $ hg debugwalk 'glob:**e'
393 $ hg debugwalk 'glob:**e'
394 matcher: <matcher files=['.'], patterns='(?:.*e$)', includes=None, excludes=None>
337 f beans/turtle beans/turtle
395 f beans/turtle beans/turtle
338 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
396 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
339
397
340 $ hg debugwalk 're:.*[kb]$'
398 $ hg debugwalk 're:.*[kb]$'
399 matcher: <matcher files=['.'], patterns='(?:.*[kb]$)', includes=None, excludes=None>
341 f beans/black beans/black
400 f beans/black beans/black
342 f fenugreek fenugreek
401 f fenugreek fenugreek
343 f mammals/skunk mammals/skunk
402 f mammals/skunk mammals/skunk
344
403
345 $ hg debugwalk path:beans/black
404 $ hg debugwalk path:beans/black
405 matcher: <matcher files=['beans/black'], patterns='(?:^beans\\/black(?:/|$))', includes=None, excludes=None>
346 f beans/black beans/black exact
406 f beans/black beans/black exact
347 $ hg debugwalk path:beans//black
407 $ hg debugwalk path:beans//black
408 matcher: <matcher files=['beans/black'], patterns='(?:^beans\\/black(?:/|$))', includes=None, excludes=None>
348 f beans/black beans/black exact
409 f beans/black beans/black exact
349
410
350 $ hg debugwalk relglob:Procyonidae
411 $ hg debugwalk relglob:Procyonidae
412 matcher: <matcher files=['.'], patterns='(?:(?:|.*/)Procyonidae$)', includes=None, excludes=None>
351 $ hg debugwalk 'relglob:Procyonidae/**'
413 $ hg debugwalk 'relglob:Procyonidae/**'
414 matcher: <matcher files=['.'], patterns='(?:(?:|.*/)Procyonidae\\/.*$)', includes=None, excludes=None>
352 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
415 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
353 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
416 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
354 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
417 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
355 $ hg debugwalk 'relglob:Procyonidae/**' fennel
418 $ hg debugwalk 'relglob:Procyonidae/**' fennel
419 matcher: <matcher files=['.', 'fennel'], patterns='(?:(?:|.*/)Procyonidae\\/.*$|fennel(?:/|$))', includes=None, excludes=None>
356 f fennel fennel exact
420 f fennel fennel exact
357 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
421 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
358 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
422 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
359 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
423 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
360 $ hg debugwalk beans 'glob:beans/*'
424 $ hg debugwalk beans 'glob:beans/*'
425 matcher: <matcher files=['beans', 'beans'], patterns='(?:beans(?:/|$)|beans\\/[^/]*$)', includes=None, excludes=None>
361 f beans/black beans/black
426 f beans/black beans/black
362 f beans/borlotti beans/borlotti
427 f beans/borlotti beans/borlotti
363 f beans/kidney beans/kidney
428 f beans/kidney beans/kidney
364 f beans/navy beans/navy
429 f beans/navy beans/navy
365 f beans/pinto beans/pinto
430 f beans/pinto beans/pinto
366 f beans/turtle beans/turtle
431 f beans/turtle beans/turtle
367 $ hg debugwalk 'glob:mamm**'
432 $ hg debugwalk 'glob:mamm**'
433 matcher: <matcher files=['.'], patterns='(?:mamm.*$)', includes=None, excludes=None>
368 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
434 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
369 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
435 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
370 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
436 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
371 f mammals/skunk mammals/skunk
437 f mammals/skunk mammals/skunk
372 $ hg debugwalk 'glob:mamm**' fennel
438 $ hg debugwalk 'glob:mamm**' fennel
439 matcher: <matcher files=['.', 'fennel'], patterns='(?:mamm.*$|fennel(?:/|$))', includes=None, excludes=None>
373 f fennel fennel exact
440 f fennel fennel exact
374 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
441 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
375 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
442 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
376 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
443 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
377 f mammals/skunk mammals/skunk
444 f mammals/skunk mammals/skunk
378 $ hg debugwalk 'glob:j*'
445 $ hg debugwalk 'glob:j*'
446 matcher: <matcher files=['.'], patterns='(?:j[^/]*$)', includes=None, excludes=None>
379 $ hg debugwalk NOEXIST
447 $ hg debugwalk NOEXIST
448 matcher: <matcher files=['NOEXIST'], patterns='(?:NOEXIST(?:/|$))', includes=None, excludes=None>
380 NOEXIST: * (glob)
449 NOEXIST: * (glob)
381
450
382 #if fifo
451 #if fifo
383 $ mkfifo fifo
452 $ mkfifo fifo
384 $ hg debugwalk fifo
453 $ hg debugwalk fifo
454 matcher: <matcher files=['fifo'], patterns='(?:fifo(?:/|$))', includes=None, excludes=None>
385 fifo: unsupported file type (type is fifo)
455 fifo: unsupported file type (type is fifo)
386 #endif
456 #endif
387
457
388 $ rm fenugreek
458 $ rm fenugreek
389 $ hg debugwalk fenugreek
459 $ hg debugwalk fenugreek
460 matcher: <matcher files=['fenugreek'], patterns='(?:fenugreek(?:/|$))', includes=None, excludes=None>
390 f fenugreek fenugreek exact
461 f fenugreek fenugreek exact
391 $ hg rm fenugreek
462 $ hg rm fenugreek
392 $ hg debugwalk fenugreek
463 $ hg debugwalk fenugreek
464 matcher: <matcher files=['fenugreek'], patterns='(?:fenugreek(?:/|$))', includes=None, excludes=None>
393 f fenugreek fenugreek exact
465 f fenugreek fenugreek exact
394 $ touch new
466 $ touch new
395 $ hg debugwalk new
467 $ hg debugwalk new
468 matcher: <matcher files=['new'], patterns='(?:new(?:/|$))', includes=None, excludes=None>
396 f new new exact
469 f new new exact
397
470
398 $ mkdir ignored
471 $ mkdir ignored
399 $ touch ignored/file
472 $ touch ignored/file
400 $ echo '^ignored$' > .hgignore
473 $ echo '^ignored$' > .hgignore
401 $ hg debugwalk ignored
474 $ hg debugwalk ignored
475 matcher: <matcher files=['ignored'], patterns='(?:ignored(?:/|$))', includes=None, excludes=None>
402 $ hg debugwalk ignored/file
476 $ hg debugwalk ignored/file
477 matcher: <matcher files=['ignored/file'], patterns='(?:ignored\\/file(?:/|$))', includes=None, excludes=None>
403 f ignored/file ignored/file exact
478 f ignored/file ignored/file exact
404
479
405 Test listfile and listfile0
480 Test listfile and listfile0
406
481
407 $ $PYTHON -c "file('listfile0', 'wb').write('fenugreek\0new\0')"
482 $ $PYTHON -c "file('listfile0', 'wb').write('fenugreek\0new\0')"
408 $ hg debugwalk -I 'listfile0:listfile0'
483 $ hg debugwalk -I 'listfile0:listfile0'
484 matcher: <matcher files=[], patterns=None, includes='(?:fenugreek(?:/|$)|new(?:/|$))', excludes=None>
409 f fenugreek fenugreek
485 f fenugreek fenugreek
410 f new new
486 f new new
411 $ $PYTHON -c "file('listfile', 'wb').write('fenugreek\nnew\r\nmammals/skunk\n')"
487 $ $PYTHON -c "file('listfile', 'wb').write('fenugreek\nnew\r\nmammals/skunk\n')"
412 $ hg debugwalk -I 'listfile:listfile'
488 $ hg debugwalk -I 'listfile:listfile'
489 matcher: <matcher files=[], patterns=None, includes='(?:fenugreek(?:/|$)|new(?:/|$)|mammals\\/skunk(?:/|$))', excludes=None>
413 f fenugreek fenugreek
490 f fenugreek fenugreek
414 f mammals/skunk mammals/skunk
491 f mammals/skunk mammals/skunk
415 f new new
492 f new new
416
493
417 $ cd ..
494 $ cd ..
418 $ hg debugwalk -R t t/mammals/skunk
495 $ hg debugwalk -R t t/mammals/skunk
496 matcher: <matcher files=['mammals/skunk'], patterns='(?:mammals\\/skunk(?:/|$))', includes=None, excludes=None>
419 f mammals/skunk t/mammals/skunk exact
497 f mammals/skunk t/mammals/skunk exact
420 $ mkdir t2
498 $ mkdir t2
421 $ cd t2
499 $ cd t2
422 $ hg debugwalk -R ../t ../t/mammals/skunk
500 $ hg debugwalk -R ../t ../t/mammals/skunk
501 matcher: <matcher files=['mammals/skunk'], patterns='(?:mammals\\/skunk(?:/|$))', includes=None, excludes=None>
423 f mammals/skunk ../t/mammals/skunk exact
502 f mammals/skunk ../t/mammals/skunk exact
424 $ hg debugwalk --cwd ../t mammals/skunk
503 $ hg debugwalk --cwd ../t mammals/skunk
504 matcher: <matcher files=['mammals/skunk'], patterns='(?:mammals\\/skunk(?:/|$))', includes=None, excludes=None>
425 f mammals/skunk mammals/skunk exact
505 f mammals/skunk mammals/skunk exact
426
506
427 $ cd ..
507 $ cd ..
428
508
429 Test split patterns on overflow
509 Test split patterns on overflow
430
510
431 $ cd t
511 $ cd t
432 $ echo fennel > overflow.list
512 $ echo fennel > overflow.list
433 $ $PYTHON -c "for i in xrange(20000 / 100): print 'x' * 100" >> overflow.list
513 $ $PYTHON -c "for i in xrange(20000 / 100): print 'x' * 100" >> overflow.list
434 $ echo fenugreek >> overflow.list
514 $ echo fenugreek >> overflow.list
435 $ hg debugwalk 'listfile:overflow.list' 2>&1 | grep -v '^xxx'
515 $ hg debugwalk 'listfile:overflow.list' 2>&1 | egrep -v '(^matcher: |^xxx)'
436 f fennel fennel exact
516 f fennel fennel exact
437 f fenugreek fenugreek exact
517 f fenugreek fenugreek exact
438 $ cd ..
518 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now