##// END OF EJS Templates
debugcommands: drop offset and length from debugindex by default...
Gregory Szorc -
r37301:d4e62df1 default
parent child Browse files
Show More
@@ -1,3056 +1,3075 b''
1 # debugcommands.py - command processing for debug* commands
1 # debugcommands.py - command processing for debug* commands
2 #
2 #
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import codecs
10 import codecs
11 import collections
11 import collections
12 import difflib
12 import difflib
13 import errno
13 import errno
14 import operator
14 import operator
15 import os
15 import os
16 import random
16 import random
17 import re
17 import re
18 import socket
18 import socket
19 import ssl
19 import ssl
20 import stat
20 import stat
21 import string
21 import string
22 import subprocess
22 import subprocess
23 import sys
23 import sys
24 import tempfile
24 import tempfile
25 import time
25 import time
26
26
27 from .i18n import _
27 from .i18n import _
28 from .node import (
28 from .node import (
29 bin,
29 bin,
30 hex,
30 hex,
31 nullhex,
31 nullhex,
32 nullid,
32 nullid,
33 nullrev,
33 nullrev,
34 short,
34 short,
35 )
35 )
36 from . import (
36 from . import (
37 bundle2,
37 bundle2,
38 changegroup,
38 changegroup,
39 cmdutil,
39 cmdutil,
40 color,
40 color,
41 context,
41 context,
42 dagparser,
42 dagparser,
43 dagutil,
43 dagutil,
44 encoding,
44 encoding,
45 error,
45 error,
46 exchange,
46 exchange,
47 extensions,
47 extensions,
48 filemerge,
48 filemerge,
49 fileset,
49 fileset,
50 formatter,
50 formatter,
51 hg,
51 hg,
52 httppeer,
52 httppeer,
53 localrepo,
53 localrepo,
54 lock as lockmod,
54 lock as lockmod,
55 logcmdutil,
55 logcmdutil,
56 merge as mergemod,
56 merge as mergemod,
57 obsolete,
57 obsolete,
58 obsutil,
58 obsutil,
59 phases,
59 phases,
60 policy,
60 policy,
61 pvec,
61 pvec,
62 pycompat,
62 pycompat,
63 registrar,
63 registrar,
64 repair,
64 repair,
65 revlog,
65 revlog,
66 revset,
66 revset,
67 revsetlang,
67 revsetlang,
68 scmutil,
68 scmutil,
69 setdiscovery,
69 setdiscovery,
70 simplemerge,
70 simplemerge,
71 smartset,
71 smartset,
72 sshpeer,
72 sshpeer,
73 sslutil,
73 sslutil,
74 streamclone,
74 streamclone,
75 templater,
75 templater,
76 treediscovery,
76 treediscovery,
77 upgrade,
77 upgrade,
78 url as urlmod,
78 url as urlmod,
79 util,
79 util,
80 vfs as vfsmod,
80 vfs as vfsmod,
81 wireprotoframing,
81 wireprotoframing,
82 wireprotoserver,
82 wireprotoserver,
83 )
83 )
84 from .utils import (
84 from .utils import (
85 dateutil,
85 dateutil,
86 procutil,
86 procutil,
87 stringutil,
87 stringutil,
88 )
88 )
89
89
90 release = lockmod.release
90 release = lockmod.release
91
91
92 command = registrar.command()
92 command = registrar.command()
93
93
94 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
94 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
95 def debugancestor(ui, repo, *args):
95 def debugancestor(ui, repo, *args):
96 """find the ancestor revision of two revisions in a given index"""
96 """find the ancestor revision of two revisions in a given index"""
97 if len(args) == 3:
97 if len(args) == 3:
98 index, rev1, rev2 = args
98 index, rev1, rev2 = args
99 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
99 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
100 lookup = r.lookup
100 lookup = r.lookup
101 elif len(args) == 2:
101 elif len(args) == 2:
102 if not repo:
102 if not repo:
103 raise error.Abort(_('there is no Mercurial repository here '
103 raise error.Abort(_('there is no Mercurial repository here '
104 '(.hg not found)'))
104 '(.hg not found)'))
105 rev1, rev2 = args
105 rev1, rev2 = args
106 r = repo.changelog
106 r = repo.changelog
107 lookup = repo.lookup
107 lookup = repo.lookup
108 else:
108 else:
109 raise error.Abort(_('either two or three arguments required'))
109 raise error.Abort(_('either two or three arguments required'))
110 a = r.ancestor(lookup(rev1), lookup(rev2))
110 a = r.ancestor(lookup(rev1), lookup(rev2))
111 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
111 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
112
112
113 @command('debugapplystreamclonebundle', [], 'FILE')
113 @command('debugapplystreamclonebundle', [], 'FILE')
114 def debugapplystreamclonebundle(ui, repo, fname):
114 def debugapplystreamclonebundle(ui, repo, fname):
115 """apply a stream clone bundle file"""
115 """apply a stream clone bundle file"""
116 f = hg.openpath(ui, fname)
116 f = hg.openpath(ui, fname)
117 gen = exchange.readbundle(ui, f, fname)
117 gen = exchange.readbundle(ui, f, fname)
118 gen.apply(repo)
118 gen.apply(repo)
119
119
120 @command('debugbuilddag',
120 @command('debugbuilddag',
121 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
121 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
122 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
122 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
123 ('n', 'new-file', None, _('add new file at each rev'))],
123 ('n', 'new-file', None, _('add new file at each rev'))],
124 _('[OPTION]... [TEXT]'))
124 _('[OPTION]... [TEXT]'))
125 def debugbuilddag(ui, repo, text=None,
125 def debugbuilddag(ui, repo, text=None,
126 mergeable_file=False,
126 mergeable_file=False,
127 overwritten_file=False,
127 overwritten_file=False,
128 new_file=False):
128 new_file=False):
129 """builds a repo with a given DAG from scratch in the current empty repo
129 """builds a repo with a given DAG from scratch in the current empty repo
130
130
131 The description of the DAG is read from stdin if not given on the
131 The description of the DAG is read from stdin if not given on the
132 command line.
132 command line.
133
133
134 Elements:
134 Elements:
135
135
136 - "+n" is a linear run of n nodes based on the current default parent
136 - "+n" is a linear run of n nodes based on the current default parent
137 - "." is a single node based on the current default parent
137 - "." is a single node based on the current default parent
138 - "$" resets the default parent to null (implied at the start);
138 - "$" resets the default parent to null (implied at the start);
139 otherwise the default parent is always the last node created
139 otherwise the default parent is always the last node created
140 - "<p" sets the default parent to the backref p
140 - "<p" sets the default parent to the backref p
141 - "*p" is a fork at parent p, which is a backref
141 - "*p" is a fork at parent p, which is a backref
142 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
142 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
143 - "/p2" is a merge of the preceding node and p2
143 - "/p2" is a merge of the preceding node and p2
144 - ":tag" defines a local tag for the preceding node
144 - ":tag" defines a local tag for the preceding node
145 - "@branch" sets the named branch for subsequent nodes
145 - "@branch" sets the named branch for subsequent nodes
146 - "#...\\n" is a comment up to the end of the line
146 - "#...\\n" is a comment up to the end of the line
147
147
148 Whitespace between the above elements is ignored.
148 Whitespace between the above elements is ignored.
149
149
150 A backref is either
150 A backref is either
151
151
152 - a number n, which references the node curr-n, where curr is the current
152 - a number n, which references the node curr-n, where curr is the current
153 node, or
153 node, or
154 - the name of a local tag you placed earlier using ":tag", or
154 - the name of a local tag you placed earlier using ":tag", or
155 - empty to denote the default parent.
155 - empty to denote the default parent.
156
156
157 All string valued-elements are either strictly alphanumeric, or must
157 All string valued-elements are either strictly alphanumeric, or must
158 be enclosed in double quotes ("..."), with "\\" as escape character.
158 be enclosed in double quotes ("..."), with "\\" as escape character.
159 """
159 """
160
160
161 if text is None:
161 if text is None:
162 ui.status(_("reading DAG from stdin\n"))
162 ui.status(_("reading DAG from stdin\n"))
163 text = ui.fin.read()
163 text = ui.fin.read()
164
164
165 cl = repo.changelog
165 cl = repo.changelog
166 if len(cl) > 0:
166 if len(cl) > 0:
167 raise error.Abort(_('repository is not empty'))
167 raise error.Abort(_('repository is not empty'))
168
168
169 # determine number of revs in DAG
169 # determine number of revs in DAG
170 total = 0
170 total = 0
171 for type, data in dagparser.parsedag(text):
171 for type, data in dagparser.parsedag(text):
172 if type == 'n':
172 if type == 'n':
173 total += 1
173 total += 1
174
174
175 if mergeable_file:
175 if mergeable_file:
176 linesperrev = 2
176 linesperrev = 2
177 # make a file with k lines per rev
177 # make a file with k lines per rev
178 initialmergedlines = ['%d' % i for i in xrange(0, total * linesperrev)]
178 initialmergedlines = ['%d' % i for i in xrange(0, total * linesperrev)]
179 initialmergedlines.append("")
179 initialmergedlines.append("")
180
180
181 tags = []
181 tags = []
182
182
183 wlock = lock = tr = None
183 wlock = lock = tr = None
184 try:
184 try:
185 wlock = repo.wlock()
185 wlock = repo.wlock()
186 lock = repo.lock()
186 lock = repo.lock()
187 tr = repo.transaction("builddag")
187 tr = repo.transaction("builddag")
188
188
189 at = -1
189 at = -1
190 atbranch = 'default'
190 atbranch = 'default'
191 nodeids = []
191 nodeids = []
192 id = 0
192 id = 0
193 ui.progress(_('building'), id, unit=_('revisions'), total=total)
193 ui.progress(_('building'), id, unit=_('revisions'), total=total)
194 for type, data in dagparser.parsedag(text):
194 for type, data in dagparser.parsedag(text):
195 if type == 'n':
195 if type == 'n':
196 ui.note(('node %s\n' % pycompat.bytestr(data)))
196 ui.note(('node %s\n' % pycompat.bytestr(data)))
197 id, ps = data
197 id, ps = data
198
198
199 files = []
199 files = []
200 filecontent = {}
200 filecontent = {}
201
201
202 p2 = None
202 p2 = None
203 if mergeable_file:
203 if mergeable_file:
204 fn = "mf"
204 fn = "mf"
205 p1 = repo[ps[0]]
205 p1 = repo[ps[0]]
206 if len(ps) > 1:
206 if len(ps) > 1:
207 p2 = repo[ps[1]]
207 p2 = repo[ps[1]]
208 pa = p1.ancestor(p2)
208 pa = p1.ancestor(p2)
209 base, local, other = [x[fn].data() for x in (pa, p1,
209 base, local, other = [x[fn].data() for x in (pa, p1,
210 p2)]
210 p2)]
211 m3 = simplemerge.Merge3Text(base, local, other)
211 m3 = simplemerge.Merge3Text(base, local, other)
212 ml = [l.strip() for l in m3.merge_lines()]
212 ml = [l.strip() for l in m3.merge_lines()]
213 ml.append("")
213 ml.append("")
214 elif at > 0:
214 elif at > 0:
215 ml = p1[fn].data().split("\n")
215 ml = p1[fn].data().split("\n")
216 else:
216 else:
217 ml = initialmergedlines
217 ml = initialmergedlines
218 ml[id * linesperrev] += " r%i" % id
218 ml[id * linesperrev] += " r%i" % id
219 mergedtext = "\n".join(ml)
219 mergedtext = "\n".join(ml)
220 files.append(fn)
220 files.append(fn)
221 filecontent[fn] = mergedtext
221 filecontent[fn] = mergedtext
222
222
223 if overwritten_file:
223 if overwritten_file:
224 fn = "of"
224 fn = "of"
225 files.append(fn)
225 files.append(fn)
226 filecontent[fn] = "r%i\n" % id
226 filecontent[fn] = "r%i\n" % id
227
227
228 if new_file:
228 if new_file:
229 fn = "nf%i" % id
229 fn = "nf%i" % id
230 files.append(fn)
230 files.append(fn)
231 filecontent[fn] = "r%i\n" % id
231 filecontent[fn] = "r%i\n" % id
232 if len(ps) > 1:
232 if len(ps) > 1:
233 if not p2:
233 if not p2:
234 p2 = repo[ps[1]]
234 p2 = repo[ps[1]]
235 for fn in p2:
235 for fn in p2:
236 if fn.startswith("nf"):
236 if fn.startswith("nf"):
237 files.append(fn)
237 files.append(fn)
238 filecontent[fn] = p2[fn].data()
238 filecontent[fn] = p2[fn].data()
239
239
240 def fctxfn(repo, cx, path):
240 def fctxfn(repo, cx, path):
241 if path in filecontent:
241 if path in filecontent:
242 return context.memfilectx(repo, cx, path,
242 return context.memfilectx(repo, cx, path,
243 filecontent[path])
243 filecontent[path])
244 return None
244 return None
245
245
246 if len(ps) == 0 or ps[0] < 0:
246 if len(ps) == 0 or ps[0] < 0:
247 pars = [None, None]
247 pars = [None, None]
248 elif len(ps) == 1:
248 elif len(ps) == 1:
249 pars = [nodeids[ps[0]], None]
249 pars = [nodeids[ps[0]], None]
250 else:
250 else:
251 pars = [nodeids[p] for p in ps]
251 pars = [nodeids[p] for p in ps]
252 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
252 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
253 date=(id, 0),
253 date=(id, 0),
254 user="debugbuilddag",
254 user="debugbuilddag",
255 extra={'branch': atbranch})
255 extra={'branch': atbranch})
256 nodeid = repo.commitctx(cx)
256 nodeid = repo.commitctx(cx)
257 nodeids.append(nodeid)
257 nodeids.append(nodeid)
258 at = id
258 at = id
259 elif type == 'l':
259 elif type == 'l':
260 id, name = data
260 id, name = data
261 ui.note(('tag %s\n' % name))
261 ui.note(('tag %s\n' % name))
262 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
262 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
263 elif type == 'a':
263 elif type == 'a':
264 ui.note(('branch %s\n' % data))
264 ui.note(('branch %s\n' % data))
265 atbranch = data
265 atbranch = data
266 ui.progress(_('building'), id, unit=_('revisions'), total=total)
266 ui.progress(_('building'), id, unit=_('revisions'), total=total)
267 tr.close()
267 tr.close()
268
268
269 if tags:
269 if tags:
270 repo.vfs.write("localtags", "".join(tags))
270 repo.vfs.write("localtags", "".join(tags))
271 finally:
271 finally:
272 ui.progress(_('building'), None)
272 ui.progress(_('building'), None)
273 release(tr, lock, wlock)
273 release(tr, lock, wlock)
274
274
275 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
275 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
276 indent_string = ' ' * indent
276 indent_string = ' ' * indent
277 if all:
277 if all:
278 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
278 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
279 % indent_string)
279 % indent_string)
280
280
281 def showchunks(named):
281 def showchunks(named):
282 ui.write("\n%s%s\n" % (indent_string, named))
282 ui.write("\n%s%s\n" % (indent_string, named))
283 for deltadata in gen.deltaiter():
283 for deltadata in gen.deltaiter():
284 node, p1, p2, cs, deltabase, delta, flags = deltadata
284 node, p1, p2, cs, deltabase, delta, flags = deltadata
285 ui.write("%s%s %s %s %s %s %d\n" %
285 ui.write("%s%s %s %s %s %s %d\n" %
286 (indent_string, hex(node), hex(p1), hex(p2),
286 (indent_string, hex(node), hex(p1), hex(p2),
287 hex(cs), hex(deltabase), len(delta)))
287 hex(cs), hex(deltabase), len(delta)))
288
288
289 chunkdata = gen.changelogheader()
289 chunkdata = gen.changelogheader()
290 showchunks("changelog")
290 showchunks("changelog")
291 chunkdata = gen.manifestheader()
291 chunkdata = gen.manifestheader()
292 showchunks("manifest")
292 showchunks("manifest")
293 for chunkdata in iter(gen.filelogheader, {}):
293 for chunkdata in iter(gen.filelogheader, {}):
294 fname = chunkdata['filename']
294 fname = chunkdata['filename']
295 showchunks(fname)
295 showchunks(fname)
296 else:
296 else:
297 if isinstance(gen, bundle2.unbundle20):
297 if isinstance(gen, bundle2.unbundle20):
298 raise error.Abort(_('use debugbundle2 for this file'))
298 raise error.Abort(_('use debugbundle2 for this file'))
299 chunkdata = gen.changelogheader()
299 chunkdata = gen.changelogheader()
300 for deltadata in gen.deltaiter():
300 for deltadata in gen.deltaiter():
301 node, p1, p2, cs, deltabase, delta, flags = deltadata
301 node, p1, p2, cs, deltabase, delta, flags = deltadata
302 ui.write("%s%s\n" % (indent_string, hex(node)))
302 ui.write("%s%s\n" % (indent_string, hex(node)))
303
303
304 def _debugobsmarkers(ui, part, indent=0, **opts):
304 def _debugobsmarkers(ui, part, indent=0, **opts):
305 """display version and markers contained in 'data'"""
305 """display version and markers contained in 'data'"""
306 opts = pycompat.byteskwargs(opts)
306 opts = pycompat.byteskwargs(opts)
307 data = part.read()
307 data = part.read()
308 indent_string = ' ' * indent
308 indent_string = ' ' * indent
309 try:
309 try:
310 version, markers = obsolete._readmarkers(data)
310 version, markers = obsolete._readmarkers(data)
311 except error.UnknownVersion as exc:
311 except error.UnknownVersion as exc:
312 msg = "%sunsupported version: %s (%d bytes)\n"
312 msg = "%sunsupported version: %s (%d bytes)\n"
313 msg %= indent_string, exc.version, len(data)
313 msg %= indent_string, exc.version, len(data)
314 ui.write(msg)
314 ui.write(msg)
315 else:
315 else:
316 msg = "%sversion: %d (%d bytes)\n"
316 msg = "%sversion: %d (%d bytes)\n"
317 msg %= indent_string, version, len(data)
317 msg %= indent_string, version, len(data)
318 ui.write(msg)
318 ui.write(msg)
319 fm = ui.formatter('debugobsolete', opts)
319 fm = ui.formatter('debugobsolete', opts)
320 for rawmarker in sorted(markers):
320 for rawmarker in sorted(markers):
321 m = obsutil.marker(None, rawmarker)
321 m = obsutil.marker(None, rawmarker)
322 fm.startitem()
322 fm.startitem()
323 fm.plain(indent_string)
323 fm.plain(indent_string)
324 cmdutil.showmarker(fm, m)
324 cmdutil.showmarker(fm, m)
325 fm.end()
325 fm.end()
326
326
327 def _debugphaseheads(ui, data, indent=0):
327 def _debugphaseheads(ui, data, indent=0):
328 """display version and markers contained in 'data'"""
328 """display version and markers contained in 'data'"""
329 indent_string = ' ' * indent
329 indent_string = ' ' * indent
330 headsbyphase = phases.binarydecode(data)
330 headsbyphase = phases.binarydecode(data)
331 for phase in phases.allphases:
331 for phase in phases.allphases:
332 for head in headsbyphase[phase]:
332 for head in headsbyphase[phase]:
333 ui.write(indent_string)
333 ui.write(indent_string)
334 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
334 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
335
335
336 def _quasirepr(thing):
336 def _quasirepr(thing):
337 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
337 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
338 return '{%s}' % (
338 return '{%s}' % (
339 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
339 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
340 return pycompat.bytestr(repr(thing))
340 return pycompat.bytestr(repr(thing))
341
341
342 def _debugbundle2(ui, gen, all=None, **opts):
342 def _debugbundle2(ui, gen, all=None, **opts):
343 """lists the contents of a bundle2"""
343 """lists the contents of a bundle2"""
344 if not isinstance(gen, bundle2.unbundle20):
344 if not isinstance(gen, bundle2.unbundle20):
345 raise error.Abort(_('not a bundle2 file'))
345 raise error.Abort(_('not a bundle2 file'))
346 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
346 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
347 parttypes = opts.get(r'part_type', [])
347 parttypes = opts.get(r'part_type', [])
348 for part in gen.iterparts():
348 for part in gen.iterparts():
349 if parttypes and part.type not in parttypes:
349 if parttypes and part.type not in parttypes:
350 continue
350 continue
351 ui.write('%s -- %s\n' % (part.type, _quasirepr(part.params)))
351 ui.write('%s -- %s\n' % (part.type, _quasirepr(part.params)))
352 if part.type == 'changegroup':
352 if part.type == 'changegroup':
353 version = part.params.get('version', '01')
353 version = part.params.get('version', '01')
354 cg = changegroup.getunbundler(version, part, 'UN')
354 cg = changegroup.getunbundler(version, part, 'UN')
355 if not ui.quiet:
355 if not ui.quiet:
356 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
356 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
357 if part.type == 'obsmarkers':
357 if part.type == 'obsmarkers':
358 if not ui.quiet:
358 if not ui.quiet:
359 _debugobsmarkers(ui, part, indent=4, **opts)
359 _debugobsmarkers(ui, part, indent=4, **opts)
360 if part.type == 'phase-heads':
360 if part.type == 'phase-heads':
361 if not ui.quiet:
361 if not ui.quiet:
362 _debugphaseheads(ui, part, indent=4)
362 _debugphaseheads(ui, part, indent=4)
363
363
364 @command('debugbundle',
364 @command('debugbundle',
365 [('a', 'all', None, _('show all details')),
365 [('a', 'all', None, _('show all details')),
366 ('', 'part-type', [], _('show only the named part type')),
366 ('', 'part-type', [], _('show only the named part type')),
367 ('', 'spec', None, _('print the bundlespec of the bundle'))],
367 ('', 'spec', None, _('print the bundlespec of the bundle'))],
368 _('FILE'),
368 _('FILE'),
369 norepo=True)
369 norepo=True)
370 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
370 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
371 """lists the contents of a bundle"""
371 """lists the contents of a bundle"""
372 with hg.openpath(ui, bundlepath) as f:
372 with hg.openpath(ui, bundlepath) as f:
373 if spec:
373 if spec:
374 spec = exchange.getbundlespec(ui, f)
374 spec = exchange.getbundlespec(ui, f)
375 ui.write('%s\n' % spec)
375 ui.write('%s\n' % spec)
376 return
376 return
377
377
378 gen = exchange.readbundle(ui, f, bundlepath)
378 gen = exchange.readbundle(ui, f, bundlepath)
379 if isinstance(gen, bundle2.unbundle20):
379 if isinstance(gen, bundle2.unbundle20):
380 return _debugbundle2(ui, gen, all=all, **opts)
380 return _debugbundle2(ui, gen, all=all, **opts)
381 _debugchangegroup(ui, gen, all=all, **opts)
381 _debugchangegroup(ui, gen, all=all, **opts)
382
382
383 @command('debugcapabilities',
383 @command('debugcapabilities',
384 [], _('PATH'),
384 [], _('PATH'),
385 norepo=True)
385 norepo=True)
386 def debugcapabilities(ui, path, **opts):
386 def debugcapabilities(ui, path, **opts):
387 """lists the capabilities of a remote peer"""
387 """lists the capabilities of a remote peer"""
388 opts = pycompat.byteskwargs(opts)
388 opts = pycompat.byteskwargs(opts)
389 peer = hg.peer(ui, opts, path)
389 peer = hg.peer(ui, opts, path)
390 caps = peer.capabilities()
390 caps = peer.capabilities()
391 ui.write(('Main capabilities:\n'))
391 ui.write(('Main capabilities:\n'))
392 for c in sorted(caps):
392 for c in sorted(caps):
393 ui.write((' %s\n') % c)
393 ui.write((' %s\n') % c)
394 b2caps = bundle2.bundle2caps(peer)
394 b2caps = bundle2.bundle2caps(peer)
395 if b2caps:
395 if b2caps:
396 ui.write(('Bundle2 capabilities:\n'))
396 ui.write(('Bundle2 capabilities:\n'))
397 for key, values in sorted(b2caps.iteritems()):
397 for key, values in sorted(b2caps.iteritems()):
398 ui.write((' %s\n') % key)
398 ui.write((' %s\n') % key)
399 for v in values:
399 for v in values:
400 ui.write((' %s\n') % v)
400 ui.write((' %s\n') % v)
401
401
402 @command('debugcheckstate', [], '')
402 @command('debugcheckstate', [], '')
403 def debugcheckstate(ui, repo):
403 def debugcheckstate(ui, repo):
404 """validate the correctness of the current dirstate"""
404 """validate the correctness of the current dirstate"""
405 parent1, parent2 = repo.dirstate.parents()
405 parent1, parent2 = repo.dirstate.parents()
406 m1 = repo[parent1].manifest()
406 m1 = repo[parent1].manifest()
407 m2 = repo[parent2].manifest()
407 m2 = repo[parent2].manifest()
408 errors = 0
408 errors = 0
409 for f in repo.dirstate:
409 for f in repo.dirstate:
410 state = repo.dirstate[f]
410 state = repo.dirstate[f]
411 if state in "nr" and f not in m1:
411 if state in "nr" and f not in m1:
412 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
412 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
413 errors += 1
413 errors += 1
414 if state in "a" and f in m1:
414 if state in "a" and f in m1:
415 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
415 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
416 errors += 1
416 errors += 1
417 if state in "m" and f not in m1 and f not in m2:
417 if state in "m" and f not in m1 and f not in m2:
418 ui.warn(_("%s in state %s, but not in either manifest\n") %
418 ui.warn(_("%s in state %s, but not in either manifest\n") %
419 (f, state))
419 (f, state))
420 errors += 1
420 errors += 1
421 for f in m1:
421 for f in m1:
422 state = repo.dirstate[f]
422 state = repo.dirstate[f]
423 if state not in "nrm":
423 if state not in "nrm":
424 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
424 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
425 errors += 1
425 errors += 1
426 if errors:
426 if errors:
427 error = _(".hg/dirstate inconsistent with current parent's manifest")
427 error = _(".hg/dirstate inconsistent with current parent's manifest")
428 raise error.Abort(error)
428 raise error.Abort(error)
429
429
430 @command('debugcolor',
430 @command('debugcolor',
431 [('', 'style', None, _('show all configured styles'))],
431 [('', 'style', None, _('show all configured styles'))],
432 'hg debugcolor')
432 'hg debugcolor')
433 def debugcolor(ui, repo, **opts):
433 def debugcolor(ui, repo, **opts):
434 """show available color, effects or style"""
434 """show available color, effects or style"""
435 ui.write(('color mode: %s\n') % ui._colormode)
435 ui.write(('color mode: %s\n') % ui._colormode)
436 if opts.get(r'style'):
436 if opts.get(r'style'):
437 return _debugdisplaystyle(ui)
437 return _debugdisplaystyle(ui)
438 else:
438 else:
439 return _debugdisplaycolor(ui)
439 return _debugdisplaycolor(ui)
440
440
441 def _debugdisplaycolor(ui):
441 def _debugdisplaycolor(ui):
442 ui = ui.copy()
442 ui = ui.copy()
443 ui._styles.clear()
443 ui._styles.clear()
444 for effect in color._activeeffects(ui).keys():
444 for effect in color._activeeffects(ui).keys():
445 ui._styles[effect] = effect
445 ui._styles[effect] = effect
446 if ui._terminfoparams:
446 if ui._terminfoparams:
447 for k, v in ui.configitems('color'):
447 for k, v in ui.configitems('color'):
448 if k.startswith('color.'):
448 if k.startswith('color.'):
449 ui._styles[k] = k[6:]
449 ui._styles[k] = k[6:]
450 elif k.startswith('terminfo.'):
450 elif k.startswith('terminfo.'):
451 ui._styles[k] = k[9:]
451 ui._styles[k] = k[9:]
452 ui.write(_('available colors:\n'))
452 ui.write(_('available colors:\n'))
453 # sort label with a '_' after the other to group '_background' entry.
453 # sort label with a '_' after the other to group '_background' entry.
454 items = sorted(ui._styles.items(),
454 items = sorted(ui._styles.items(),
455 key=lambda i: ('_' in i[0], i[0], i[1]))
455 key=lambda i: ('_' in i[0], i[0], i[1]))
456 for colorname, label in items:
456 for colorname, label in items:
457 ui.write(('%s\n') % colorname, label=label)
457 ui.write(('%s\n') % colorname, label=label)
458
458
459 def _debugdisplaystyle(ui):
459 def _debugdisplaystyle(ui):
460 ui.write(_('available style:\n'))
460 ui.write(_('available style:\n'))
461 width = max(len(s) for s in ui._styles)
461 width = max(len(s) for s in ui._styles)
462 for label, effects in sorted(ui._styles.items()):
462 for label, effects in sorted(ui._styles.items()):
463 ui.write('%s' % label, label=label)
463 ui.write('%s' % label, label=label)
464 if effects:
464 if effects:
465 # 50
465 # 50
466 ui.write(': ')
466 ui.write(': ')
467 ui.write(' ' * (max(0, width - len(label))))
467 ui.write(' ' * (max(0, width - len(label))))
468 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
468 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
469 ui.write('\n')
469 ui.write('\n')
470
470
471 @command('debugcreatestreamclonebundle', [], 'FILE')
471 @command('debugcreatestreamclonebundle', [], 'FILE')
472 def debugcreatestreamclonebundle(ui, repo, fname):
472 def debugcreatestreamclonebundle(ui, repo, fname):
473 """create a stream clone bundle file
473 """create a stream clone bundle file
474
474
475 Stream bundles are special bundles that are essentially archives of
475 Stream bundles are special bundles that are essentially archives of
476 revlog files. They are commonly used for cloning very quickly.
476 revlog files. They are commonly used for cloning very quickly.
477 """
477 """
478 # TODO we may want to turn this into an abort when this functionality
478 # TODO we may want to turn this into an abort when this functionality
479 # is moved into `hg bundle`.
479 # is moved into `hg bundle`.
480 if phases.hassecret(repo):
480 if phases.hassecret(repo):
481 ui.warn(_('(warning: stream clone bundle will contain secret '
481 ui.warn(_('(warning: stream clone bundle will contain secret '
482 'revisions)\n'))
482 'revisions)\n'))
483
483
484 requirements, gen = streamclone.generatebundlev1(repo)
484 requirements, gen = streamclone.generatebundlev1(repo)
485 changegroup.writechunks(ui, gen, fname)
485 changegroup.writechunks(ui, gen, fname)
486
486
487 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
487 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
488
488
489 @command('debugdag',
489 @command('debugdag',
490 [('t', 'tags', None, _('use tags as labels')),
490 [('t', 'tags', None, _('use tags as labels')),
491 ('b', 'branches', None, _('annotate with branch names')),
491 ('b', 'branches', None, _('annotate with branch names')),
492 ('', 'dots', None, _('use dots for runs')),
492 ('', 'dots', None, _('use dots for runs')),
493 ('s', 'spaces', None, _('separate elements by spaces'))],
493 ('s', 'spaces', None, _('separate elements by spaces'))],
494 _('[OPTION]... [FILE [REV]...]'),
494 _('[OPTION]... [FILE [REV]...]'),
495 optionalrepo=True)
495 optionalrepo=True)
496 def debugdag(ui, repo, file_=None, *revs, **opts):
496 def debugdag(ui, repo, file_=None, *revs, **opts):
497 """format the changelog or an index DAG as a concise textual description
497 """format the changelog or an index DAG as a concise textual description
498
498
499 If you pass a revlog index, the revlog's DAG is emitted. If you list
499 If you pass a revlog index, the revlog's DAG is emitted. If you list
500 revision numbers, they get labeled in the output as rN.
500 revision numbers, they get labeled in the output as rN.
501
501
502 Otherwise, the changelog DAG of the current repo is emitted.
502 Otherwise, the changelog DAG of the current repo is emitted.
503 """
503 """
504 spaces = opts.get(r'spaces')
504 spaces = opts.get(r'spaces')
505 dots = opts.get(r'dots')
505 dots = opts.get(r'dots')
506 if file_:
506 if file_:
507 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
507 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
508 file_)
508 file_)
509 revs = set((int(r) for r in revs))
509 revs = set((int(r) for r in revs))
510 def events():
510 def events():
511 for r in rlog:
511 for r in rlog:
512 yield 'n', (r, list(p for p in rlog.parentrevs(r)
512 yield 'n', (r, list(p for p in rlog.parentrevs(r)
513 if p != -1))
513 if p != -1))
514 if r in revs:
514 if r in revs:
515 yield 'l', (r, "r%i" % r)
515 yield 'l', (r, "r%i" % r)
516 elif repo:
516 elif repo:
517 cl = repo.changelog
517 cl = repo.changelog
518 tags = opts.get(r'tags')
518 tags = opts.get(r'tags')
519 branches = opts.get(r'branches')
519 branches = opts.get(r'branches')
520 if tags:
520 if tags:
521 labels = {}
521 labels = {}
522 for l, n in repo.tags().items():
522 for l, n in repo.tags().items():
523 labels.setdefault(cl.rev(n), []).append(l)
523 labels.setdefault(cl.rev(n), []).append(l)
524 def events():
524 def events():
525 b = "default"
525 b = "default"
526 for r in cl:
526 for r in cl:
527 if branches:
527 if branches:
528 newb = cl.read(cl.node(r))[5]['branch']
528 newb = cl.read(cl.node(r))[5]['branch']
529 if newb != b:
529 if newb != b:
530 yield 'a', newb
530 yield 'a', newb
531 b = newb
531 b = newb
532 yield 'n', (r, list(p for p in cl.parentrevs(r)
532 yield 'n', (r, list(p for p in cl.parentrevs(r)
533 if p != -1))
533 if p != -1))
534 if tags:
534 if tags:
535 ls = labels.get(r)
535 ls = labels.get(r)
536 if ls:
536 if ls:
537 for l in ls:
537 for l in ls:
538 yield 'l', (r, l)
538 yield 'l', (r, l)
539 else:
539 else:
540 raise error.Abort(_('need repo for changelog dag'))
540 raise error.Abort(_('need repo for changelog dag'))
541
541
542 for line in dagparser.dagtextlines(events(),
542 for line in dagparser.dagtextlines(events(),
543 addspaces=spaces,
543 addspaces=spaces,
544 wraplabels=True,
544 wraplabels=True,
545 wrapannotations=True,
545 wrapannotations=True,
546 wrapnonlinear=dots,
546 wrapnonlinear=dots,
547 usedots=dots,
547 usedots=dots,
548 maxlinewidth=70):
548 maxlinewidth=70):
549 ui.write(line)
549 ui.write(line)
550 ui.write("\n")
550 ui.write("\n")
551
551
552 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
552 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
553 def debugdata(ui, repo, file_, rev=None, **opts):
553 def debugdata(ui, repo, file_, rev=None, **opts):
554 """dump the contents of a data file revision"""
554 """dump the contents of a data file revision"""
555 opts = pycompat.byteskwargs(opts)
555 opts = pycompat.byteskwargs(opts)
556 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
556 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
557 if rev is not None:
557 if rev is not None:
558 raise error.CommandError('debugdata', _('invalid arguments'))
558 raise error.CommandError('debugdata', _('invalid arguments'))
559 file_, rev = None, file_
559 file_, rev = None, file_
560 elif rev is None:
560 elif rev is None:
561 raise error.CommandError('debugdata', _('invalid arguments'))
561 raise error.CommandError('debugdata', _('invalid arguments'))
562 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
562 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
563 try:
563 try:
564 ui.write(r.revision(r.lookup(rev), raw=True))
564 ui.write(r.revision(r.lookup(rev), raw=True))
565 except KeyError:
565 except KeyError:
566 raise error.Abort(_('invalid revision identifier %s') % rev)
566 raise error.Abort(_('invalid revision identifier %s') % rev)
567
567
568 @command('debugdate',
568 @command('debugdate',
569 [('e', 'extended', None, _('try extended date formats'))],
569 [('e', 'extended', None, _('try extended date formats'))],
570 _('[-e] DATE [RANGE]'),
570 _('[-e] DATE [RANGE]'),
571 norepo=True, optionalrepo=True)
571 norepo=True, optionalrepo=True)
572 def debugdate(ui, date, range=None, **opts):
572 def debugdate(ui, date, range=None, **opts):
573 """parse and display a date"""
573 """parse and display a date"""
574 if opts[r"extended"]:
574 if opts[r"extended"]:
575 d = dateutil.parsedate(date, util.extendeddateformats)
575 d = dateutil.parsedate(date, util.extendeddateformats)
576 else:
576 else:
577 d = dateutil.parsedate(date)
577 d = dateutil.parsedate(date)
578 ui.write(("internal: %d %d\n") % d)
578 ui.write(("internal: %d %d\n") % d)
579 ui.write(("standard: %s\n") % dateutil.datestr(d))
579 ui.write(("standard: %s\n") % dateutil.datestr(d))
580 if range:
580 if range:
581 m = dateutil.matchdate(range)
581 m = dateutil.matchdate(range)
582 ui.write(("match: %s\n") % m(d[0]))
582 ui.write(("match: %s\n") % m(d[0]))
583
583
584 @command('debugdeltachain',
584 @command('debugdeltachain',
585 cmdutil.debugrevlogopts + cmdutil.formatteropts,
585 cmdutil.debugrevlogopts + cmdutil.formatteropts,
586 _('-c|-m|FILE'),
586 _('-c|-m|FILE'),
587 optionalrepo=True)
587 optionalrepo=True)
588 def debugdeltachain(ui, repo, file_=None, **opts):
588 def debugdeltachain(ui, repo, file_=None, **opts):
589 """dump information about delta chains in a revlog
589 """dump information about delta chains in a revlog
590
590
591 Output can be templatized. Available template keywords are:
591 Output can be templatized. Available template keywords are:
592
592
593 :``rev``: revision number
593 :``rev``: revision number
594 :``chainid``: delta chain identifier (numbered by unique base)
594 :``chainid``: delta chain identifier (numbered by unique base)
595 :``chainlen``: delta chain length to this revision
595 :``chainlen``: delta chain length to this revision
596 :``prevrev``: previous revision in delta chain
596 :``prevrev``: previous revision in delta chain
597 :``deltatype``: role of delta / how it was computed
597 :``deltatype``: role of delta / how it was computed
598 :``compsize``: compressed size of revision
598 :``compsize``: compressed size of revision
599 :``uncompsize``: uncompressed size of revision
599 :``uncompsize``: uncompressed size of revision
600 :``chainsize``: total size of compressed revisions in chain
600 :``chainsize``: total size of compressed revisions in chain
601 :``chainratio``: total chain size divided by uncompressed revision size
601 :``chainratio``: total chain size divided by uncompressed revision size
602 (new delta chains typically start at ratio 2.00)
602 (new delta chains typically start at ratio 2.00)
603 :``lindist``: linear distance from base revision in delta chain to end
603 :``lindist``: linear distance from base revision in delta chain to end
604 of this revision
604 of this revision
605 :``extradist``: total size of revisions not part of this delta chain from
605 :``extradist``: total size of revisions not part of this delta chain from
606 base of delta chain to end of this revision; a measurement
606 base of delta chain to end of this revision; a measurement
607 of how much extra data we need to read/seek across to read
607 of how much extra data we need to read/seek across to read
608 the delta chain for this revision
608 the delta chain for this revision
609 :``extraratio``: extradist divided by chainsize; another representation of
609 :``extraratio``: extradist divided by chainsize; another representation of
610 how much unrelated data is needed to load this delta chain
610 how much unrelated data is needed to load this delta chain
611
611
612 If the repository is configured to use the sparse read, additional keywords
612 If the repository is configured to use the sparse read, additional keywords
613 are available:
613 are available:
614
614
615 :``readsize``: total size of data read from the disk for a revision
615 :``readsize``: total size of data read from the disk for a revision
616 (sum of the sizes of all the blocks)
616 (sum of the sizes of all the blocks)
617 :``largestblock``: size of the largest block of data read from the disk
617 :``largestblock``: size of the largest block of data read from the disk
618 :``readdensity``: density of useful bytes in the data read from the disk
618 :``readdensity``: density of useful bytes in the data read from the disk
619 :``srchunks``: in how many data hunks the whole revision would be read
619 :``srchunks``: in how many data hunks the whole revision would be read
620
620
621 The sparse read can be enabled with experimental.sparse-read = True
621 The sparse read can be enabled with experimental.sparse-read = True
622 """
622 """
623 opts = pycompat.byteskwargs(opts)
623 opts = pycompat.byteskwargs(opts)
624 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
624 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
625 index = r.index
625 index = r.index
626 generaldelta = r.version & revlog.FLAG_GENERALDELTA
626 generaldelta = r.version & revlog.FLAG_GENERALDELTA
627 withsparseread = getattr(r, '_withsparseread', False)
627 withsparseread = getattr(r, '_withsparseread', False)
628
628
629 def revinfo(rev):
629 def revinfo(rev):
630 e = index[rev]
630 e = index[rev]
631 compsize = e[1]
631 compsize = e[1]
632 uncompsize = e[2]
632 uncompsize = e[2]
633 chainsize = 0
633 chainsize = 0
634
634
635 if generaldelta:
635 if generaldelta:
636 if e[3] == e[5]:
636 if e[3] == e[5]:
637 deltatype = 'p1'
637 deltatype = 'p1'
638 elif e[3] == e[6]:
638 elif e[3] == e[6]:
639 deltatype = 'p2'
639 deltatype = 'p2'
640 elif e[3] == rev - 1:
640 elif e[3] == rev - 1:
641 deltatype = 'prev'
641 deltatype = 'prev'
642 elif e[3] == rev:
642 elif e[3] == rev:
643 deltatype = 'base'
643 deltatype = 'base'
644 else:
644 else:
645 deltatype = 'other'
645 deltatype = 'other'
646 else:
646 else:
647 if e[3] == rev:
647 if e[3] == rev:
648 deltatype = 'base'
648 deltatype = 'base'
649 else:
649 else:
650 deltatype = 'prev'
650 deltatype = 'prev'
651
651
652 chain = r._deltachain(rev)[0]
652 chain = r._deltachain(rev)[0]
653 for iterrev in chain:
653 for iterrev in chain:
654 e = index[iterrev]
654 e = index[iterrev]
655 chainsize += e[1]
655 chainsize += e[1]
656
656
657 return compsize, uncompsize, deltatype, chain, chainsize
657 return compsize, uncompsize, deltatype, chain, chainsize
658
658
659 fm = ui.formatter('debugdeltachain', opts)
659 fm = ui.formatter('debugdeltachain', opts)
660
660
661 fm.plain(' rev chain# chainlen prev delta '
661 fm.plain(' rev chain# chainlen prev delta '
662 'size rawsize chainsize ratio lindist extradist '
662 'size rawsize chainsize ratio lindist extradist '
663 'extraratio')
663 'extraratio')
664 if withsparseread:
664 if withsparseread:
665 fm.plain(' readsize largestblk rddensity srchunks')
665 fm.plain(' readsize largestblk rddensity srchunks')
666 fm.plain('\n')
666 fm.plain('\n')
667
667
668 chainbases = {}
668 chainbases = {}
669 for rev in r:
669 for rev in r:
670 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
670 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
671 chainbase = chain[0]
671 chainbase = chain[0]
672 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
672 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
673 start = r.start
673 start = r.start
674 length = r.length
674 length = r.length
675 basestart = start(chainbase)
675 basestart = start(chainbase)
676 revstart = start(rev)
676 revstart = start(rev)
677 lineardist = revstart + comp - basestart
677 lineardist = revstart + comp - basestart
678 extradist = lineardist - chainsize
678 extradist = lineardist - chainsize
679 try:
679 try:
680 prevrev = chain[-2]
680 prevrev = chain[-2]
681 except IndexError:
681 except IndexError:
682 prevrev = -1
682 prevrev = -1
683
683
684 chainratio = float(chainsize) / float(uncomp)
684 chainratio = float(chainsize) / float(uncomp)
685 extraratio = float(extradist) / float(chainsize)
685 extraratio = float(extradist) / float(chainsize)
686
686
687 fm.startitem()
687 fm.startitem()
688 fm.write('rev chainid chainlen prevrev deltatype compsize '
688 fm.write('rev chainid chainlen prevrev deltatype compsize '
689 'uncompsize chainsize chainratio lindist extradist '
689 'uncompsize chainsize chainratio lindist extradist '
690 'extraratio',
690 'extraratio',
691 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
691 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
692 rev, chainid, len(chain), prevrev, deltatype, comp,
692 rev, chainid, len(chain), prevrev, deltatype, comp,
693 uncomp, chainsize, chainratio, lineardist, extradist,
693 uncomp, chainsize, chainratio, lineardist, extradist,
694 extraratio,
694 extraratio,
695 rev=rev, chainid=chainid, chainlen=len(chain),
695 rev=rev, chainid=chainid, chainlen=len(chain),
696 prevrev=prevrev, deltatype=deltatype, compsize=comp,
696 prevrev=prevrev, deltatype=deltatype, compsize=comp,
697 uncompsize=uncomp, chainsize=chainsize,
697 uncompsize=uncomp, chainsize=chainsize,
698 chainratio=chainratio, lindist=lineardist,
698 chainratio=chainratio, lindist=lineardist,
699 extradist=extradist, extraratio=extraratio)
699 extradist=extradist, extraratio=extraratio)
700 if withsparseread:
700 if withsparseread:
701 readsize = 0
701 readsize = 0
702 largestblock = 0
702 largestblock = 0
703 srchunks = 0
703 srchunks = 0
704
704
705 for revschunk in revlog._slicechunk(r, chain):
705 for revschunk in revlog._slicechunk(r, chain):
706 srchunks += 1
706 srchunks += 1
707 blkend = start(revschunk[-1]) + length(revschunk[-1])
707 blkend = start(revschunk[-1]) + length(revschunk[-1])
708 blksize = blkend - start(revschunk[0])
708 blksize = blkend - start(revschunk[0])
709
709
710 readsize += blksize
710 readsize += blksize
711 if largestblock < blksize:
711 if largestblock < blksize:
712 largestblock = blksize
712 largestblock = blksize
713
713
714 readdensity = float(chainsize) / float(readsize)
714 readdensity = float(chainsize) / float(readsize)
715
715
716 fm.write('readsize largestblock readdensity srchunks',
716 fm.write('readsize largestblock readdensity srchunks',
717 ' %10d %10d %9.5f %8d',
717 ' %10d %10d %9.5f %8d',
718 readsize, largestblock, readdensity, srchunks,
718 readsize, largestblock, readdensity, srchunks,
719 readsize=readsize, largestblock=largestblock,
719 readsize=readsize, largestblock=largestblock,
720 readdensity=readdensity, srchunks=srchunks)
720 readdensity=readdensity, srchunks=srchunks)
721
721
722 fm.plain('\n')
722 fm.plain('\n')
723
723
724 fm.end()
724 fm.end()
725
725
726 @command('debugdirstate|debugstate',
726 @command('debugdirstate|debugstate',
727 [('', 'nodates', None, _('do not display the saved mtime')),
727 [('', 'nodates', None, _('do not display the saved mtime')),
728 ('', 'datesort', None, _('sort by saved mtime'))],
728 ('', 'datesort', None, _('sort by saved mtime'))],
729 _('[OPTION]...'))
729 _('[OPTION]...'))
730 def debugstate(ui, repo, **opts):
730 def debugstate(ui, repo, **opts):
731 """show the contents of the current dirstate"""
731 """show the contents of the current dirstate"""
732
732
733 nodates = opts.get(r'nodates')
733 nodates = opts.get(r'nodates')
734 datesort = opts.get(r'datesort')
734 datesort = opts.get(r'datesort')
735
735
736 timestr = ""
736 timestr = ""
737 if datesort:
737 if datesort:
738 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
738 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
739 else:
739 else:
740 keyfunc = None # sort by filename
740 keyfunc = None # sort by filename
741 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
741 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
742 if ent[3] == -1:
742 if ent[3] == -1:
743 timestr = 'unset '
743 timestr = 'unset '
744 elif nodates:
744 elif nodates:
745 timestr = 'set '
745 timestr = 'set '
746 else:
746 else:
747 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
747 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
748 time.localtime(ent[3]))
748 time.localtime(ent[3]))
749 timestr = encoding.strtolocal(timestr)
749 timestr = encoding.strtolocal(timestr)
750 if ent[1] & 0o20000:
750 if ent[1] & 0o20000:
751 mode = 'lnk'
751 mode = 'lnk'
752 else:
752 else:
753 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
753 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
754 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
754 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
755 for f in repo.dirstate.copies():
755 for f in repo.dirstate.copies():
756 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
756 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
757
757
758 @command('debugdiscovery',
758 @command('debugdiscovery',
759 [('', 'old', None, _('use old-style discovery')),
759 [('', 'old', None, _('use old-style discovery')),
760 ('', 'nonheads', None,
760 ('', 'nonheads', None,
761 _('use old-style discovery with non-heads included')),
761 _('use old-style discovery with non-heads included')),
762 ('', 'rev', [], 'restrict discovery to this set of revs'),
762 ('', 'rev', [], 'restrict discovery to this set of revs'),
763 ] + cmdutil.remoteopts,
763 ] + cmdutil.remoteopts,
764 _('[--rev REV] [OTHER]'))
764 _('[--rev REV] [OTHER]'))
765 def debugdiscovery(ui, repo, remoteurl="default", **opts):
765 def debugdiscovery(ui, repo, remoteurl="default", **opts):
766 """runs the changeset discovery protocol in isolation"""
766 """runs the changeset discovery protocol in isolation"""
767 opts = pycompat.byteskwargs(opts)
767 opts = pycompat.byteskwargs(opts)
768 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
768 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
769 remote = hg.peer(repo, opts, remoteurl)
769 remote = hg.peer(repo, opts, remoteurl)
770 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
770 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
771
771
772 # make sure tests are repeatable
772 # make sure tests are repeatable
773 random.seed(12323)
773 random.seed(12323)
774
774
775 def doit(pushedrevs, remoteheads, remote=remote):
775 def doit(pushedrevs, remoteheads, remote=remote):
776 if opts.get('old'):
776 if opts.get('old'):
777 if not util.safehasattr(remote, 'branches'):
777 if not util.safehasattr(remote, 'branches'):
778 # enable in-client legacy support
778 # enable in-client legacy support
779 remote = localrepo.locallegacypeer(remote.local())
779 remote = localrepo.locallegacypeer(remote.local())
780 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
780 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
781 force=True)
781 force=True)
782 common = set(common)
782 common = set(common)
783 if not opts.get('nonheads'):
783 if not opts.get('nonheads'):
784 ui.write(("unpruned common: %s\n") %
784 ui.write(("unpruned common: %s\n") %
785 " ".join(sorted(short(n) for n in common)))
785 " ".join(sorted(short(n) for n in common)))
786 dag = dagutil.revlogdag(repo.changelog)
786 dag = dagutil.revlogdag(repo.changelog)
787 all = dag.ancestorset(dag.internalizeall(common))
787 all = dag.ancestorset(dag.internalizeall(common))
788 common = dag.externalizeall(dag.headsetofconnecteds(all))
788 common = dag.externalizeall(dag.headsetofconnecteds(all))
789 else:
789 else:
790 nodes = None
790 nodes = None
791 if pushedrevs:
791 if pushedrevs:
792 revs = scmutil.revrange(repo, pushedrevs)
792 revs = scmutil.revrange(repo, pushedrevs)
793 nodes = [repo[r].node() for r in revs]
793 nodes = [repo[r].node() for r in revs]
794 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
794 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
795 ancestorsof=nodes)
795 ancestorsof=nodes)
796 common = set(common)
796 common = set(common)
797 rheads = set(hds)
797 rheads = set(hds)
798 lheads = set(repo.heads())
798 lheads = set(repo.heads())
799 ui.write(("common heads: %s\n") %
799 ui.write(("common heads: %s\n") %
800 " ".join(sorted(short(n) for n in common)))
800 " ".join(sorted(short(n) for n in common)))
801 if lheads <= common:
801 if lheads <= common:
802 ui.write(("local is subset\n"))
802 ui.write(("local is subset\n"))
803 elif rheads <= common:
803 elif rheads <= common:
804 ui.write(("remote is subset\n"))
804 ui.write(("remote is subset\n"))
805
805
806 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
806 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
807 localrevs = opts['rev']
807 localrevs = opts['rev']
808 doit(localrevs, remoterevs)
808 doit(localrevs, remoterevs)
809
809
810 _chunksize = 4 << 10
810 _chunksize = 4 << 10
811
811
812 @command('debugdownload',
812 @command('debugdownload',
813 [
813 [
814 ('o', 'output', '', _('path')),
814 ('o', 'output', '', _('path')),
815 ],
815 ],
816 optionalrepo=True)
816 optionalrepo=True)
817 def debugdownload(ui, repo, url, output=None, **opts):
817 def debugdownload(ui, repo, url, output=None, **opts):
818 """download a resource using Mercurial logic and config
818 """download a resource using Mercurial logic and config
819 """
819 """
820 fh = urlmod.open(ui, url, output)
820 fh = urlmod.open(ui, url, output)
821
821
822 dest = ui
822 dest = ui
823 if output:
823 if output:
824 dest = open(output, "wb", _chunksize)
824 dest = open(output, "wb", _chunksize)
825 try:
825 try:
826 data = fh.read(_chunksize)
826 data = fh.read(_chunksize)
827 while data:
827 while data:
828 dest.write(data)
828 dest.write(data)
829 data = fh.read(_chunksize)
829 data = fh.read(_chunksize)
830 finally:
830 finally:
831 if output:
831 if output:
832 dest.close()
832 dest.close()
833
833
834 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
834 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
835 def debugextensions(ui, **opts):
835 def debugextensions(ui, **opts):
836 '''show information about active extensions'''
836 '''show information about active extensions'''
837 opts = pycompat.byteskwargs(opts)
837 opts = pycompat.byteskwargs(opts)
838 exts = extensions.extensions(ui)
838 exts = extensions.extensions(ui)
839 hgver = util.version()
839 hgver = util.version()
840 fm = ui.formatter('debugextensions', opts)
840 fm = ui.formatter('debugextensions', opts)
841 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
841 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
842 isinternal = extensions.ismoduleinternal(extmod)
842 isinternal = extensions.ismoduleinternal(extmod)
843 extsource = pycompat.fsencode(extmod.__file__)
843 extsource = pycompat.fsencode(extmod.__file__)
844 if isinternal:
844 if isinternal:
845 exttestedwith = [] # never expose magic string to users
845 exttestedwith = [] # never expose magic string to users
846 else:
846 else:
847 exttestedwith = getattr(extmod, 'testedwith', '').split()
847 exttestedwith = getattr(extmod, 'testedwith', '').split()
848 extbuglink = getattr(extmod, 'buglink', None)
848 extbuglink = getattr(extmod, 'buglink', None)
849
849
850 fm.startitem()
850 fm.startitem()
851
851
852 if ui.quiet or ui.verbose:
852 if ui.quiet or ui.verbose:
853 fm.write('name', '%s\n', extname)
853 fm.write('name', '%s\n', extname)
854 else:
854 else:
855 fm.write('name', '%s', extname)
855 fm.write('name', '%s', extname)
856 if isinternal or hgver in exttestedwith:
856 if isinternal or hgver in exttestedwith:
857 fm.plain('\n')
857 fm.plain('\n')
858 elif not exttestedwith:
858 elif not exttestedwith:
859 fm.plain(_(' (untested!)\n'))
859 fm.plain(_(' (untested!)\n'))
860 else:
860 else:
861 lasttestedversion = exttestedwith[-1]
861 lasttestedversion = exttestedwith[-1]
862 fm.plain(' (%s!)\n' % lasttestedversion)
862 fm.plain(' (%s!)\n' % lasttestedversion)
863
863
864 fm.condwrite(ui.verbose and extsource, 'source',
864 fm.condwrite(ui.verbose and extsource, 'source',
865 _(' location: %s\n'), extsource or "")
865 _(' location: %s\n'), extsource or "")
866
866
867 if ui.verbose:
867 if ui.verbose:
868 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
868 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
869 fm.data(bundled=isinternal)
869 fm.data(bundled=isinternal)
870
870
871 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
871 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
872 _(' tested with: %s\n'),
872 _(' tested with: %s\n'),
873 fm.formatlist(exttestedwith, name='ver'))
873 fm.formatlist(exttestedwith, name='ver'))
874
874
875 fm.condwrite(ui.verbose and extbuglink, 'buglink',
875 fm.condwrite(ui.verbose and extbuglink, 'buglink',
876 _(' bug reporting: %s\n'), extbuglink or "")
876 _(' bug reporting: %s\n'), extbuglink or "")
877
877
878 fm.end()
878 fm.end()
879
879
880 @command('debugfileset',
880 @command('debugfileset',
881 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
881 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
882 _('[-r REV] FILESPEC'))
882 _('[-r REV] FILESPEC'))
883 def debugfileset(ui, repo, expr, **opts):
883 def debugfileset(ui, repo, expr, **opts):
884 '''parse and apply a fileset specification'''
884 '''parse and apply a fileset specification'''
885 ctx = scmutil.revsingle(repo, opts.get(r'rev'), None)
885 ctx = scmutil.revsingle(repo, opts.get(r'rev'), None)
886 if ui.verbose:
886 if ui.verbose:
887 tree = fileset.parse(expr)
887 tree = fileset.parse(expr)
888 ui.note(fileset.prettyformat(tree), "\n")
888 ui.note(fileset.prettyformat(tree), "\n")
889
889
890 for f in ctx.getfileset(expr):
890 for f in ctx.getfileset(expr):
891 ui.write("%s\n" % f)
891 ui.write("%s\n" % f)
892
892
893 @command('debugformat',
893 @command('debugformat',
894 [] + cmdutil.formatteropts,
894 [] + cmdutil.formatteropts,
895 _(''))
895 _(''))
896 def debugformat(ui, repo, **opts):
896 def debugformat(ui, repo, **opts):
897 """display format information about the current repository
897 """display format information about the current repository
898
898
899 Use --verbose to get extra information about current config value and
899 Use --verbose to get extra information about current config value and
900 Mercurial default."""
900 Mercurial default."""
901 opts = pycompat.byteskwargs(opts)
901 opts = pycompat.byteskwargs(opts)
902 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
902 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
903 maxvariantlength = max(len('format-variant'), maxvariantlength)
903 maxvariantlength = max(len('format-variant'), maxvariantlength)
904
904
905 def makeformatname(name):
905 def makeformatname(name):
906 return '%s:' + (' ' * (maxvariantlength - len(name)))
906 return '%s:' + (' ' * (maxvariantlength - len(name)))
907
907
908 fm = ui.formatter('debugformat', opts)
908 fm = ui.formatter('debugformat', opts)
909 if fm.isplain():
909 if fm.isplain():
910 def formatvalue(value):
910 def formatvalue(value):
911 if util.safehasattr(value, 'startswith'):
911 if util.safehasattr(value, 'startswith'):
912 return value
912 return value
913 if value:
913 if value:
914 return 'yes'
914 return 'yes'
915 else:
915 else:
916 return 'no'
916 return 'no'
917 else:
917 else:
918 formatvalue = pycompat.identity
918 formatvalue = pycompat.identity
919
919
920 fm.plain('format-variant')
920 fm.plain('format-variant')
921 fm.plain(' ' * (maxvariantlength - len('format-variant')))
921 fm.plain(' ' * (maxvariantlength - len('format-variant')))
922 fm.plain(' repo')
922 fm.plain(' repo')
923 if ui.verbose:
923 if ui.verbose:
924 fm.plain(' config default')
924 fm.plain(' config default')
925 fm.plain('\n')
925 fm.plain('\n')
926 for fv in upgrade.allformatvariant:
926 for fv in upgrade.allformatvariant:
927 fm.startitem()
927 fm.startitem()
928 repovalue = fv.fromrepo(repo)
928 repovalue = fv.fromrepo(repo)
929 configvalue = fv.fromconfig(repo)
929 configvalue = fv.fromconfig(repo)
930
930
931 if repovalue != configvalue:
931 if repovalue != configvalue:
932 namelabel = 'formatvariant.name.mismatchconfig'
932 namelabel = 'formatvariant.name.mismatchconfig'
933 repolabel = 'formatvariant.repo.mismatchconfig'
933 repolabel = 'formatvariant.repo.mismatchconfig'
934 elif repovalue != fv.default:
934 elif repovalue != fv.default:
935 namelabel = 'formatvariant.name.mismatchdefault'
935 namelabel = 'formatvariant.name.mismatchdefault'
936 repolabel = 'formatvariant.repo.mismatchdefault'
936 repolabel = 'formatvariant.repo.mismatchdefault'
937 else:
937 else:
938 namelabel = 'formatvariant.name.uptodate'
938 namelabel = 'formatvariant.name.uptodate'
939 repolabel = 'formatvariant.repo.uptodate'
939 repolabel = 'formatvariant.repo.uptodate'
940
940
941 fm.write('name', makeformatname(fv.name), fv.name,
941 fm.write('name', makeformatname(fv.name), fv.name,
942 label=namelabel)
942 label=namelabel)
943 fm.write('repo', ' %3s', formatvalue(repovalue),
943 fm.write('repo', ' %3s', formatvalue(repovalue),
944 label=repolabel)
944 label=repolabel)
945 if fv.default != configvalue:
945 if fv.default != configvalue:
946 configlabel = 'formatvariant.config.special'
946 configlabel = 'formatvariant.config.special'
947 else:
947 else:
948 configlabel = 'formatvariant.config.default'
948 configlabel = 'formatvariant.config.default'
949 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
949 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
950 label=configlabel)
950 label=configlabel)
951 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
951 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
952 label='formatvariant.default')
952 label='formatvariant.default')
953 fm.plain('\n')
953 fm.plain('\n')
954 fm.end()
954 fm.end()
955
955
956 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
956 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
957 def debugfsinfo(ui, path="."):
957 def debugfsinfo(ui, path="."):
958 """show information detected about current filesystem"""
958 """show information detected about current filesystem"""
959 ui.write(('path: %s\n') % path)
959 ui.write(('path: %s\n') % path)
960 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
960 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
961 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
961 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
962 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
962 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
963 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
963 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
964 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
964 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
965 casesensitive = '(unknown)'
965 casesensitive = '(unknown)'
966 try:
966 try:
967 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
967 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
968 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
968 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
969 except OSError:
969 except OSError:
970 pass
970 pass
971 ui.write(('case-sensitive: %s\n') % casesensitive)
971 ui.write(('case-sensitive: %s\n') % casesensitive)
972
972
973 @command('debuggetbundle',
973 @command('debuggetbundle',
974 [('H', 'head', [], _('id of head node'), _('ID')),
974 [('H', 'head', [], _('id of head node'), _('ID')),
975 ('C', 'common', [], _('id of common node'), _('ID')),
975 ('C', 'common', [], _('id of common node'), _('ID')),
976 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
976 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
977 _('REPO FILE [-H|-C ID]...'),
977 _('REPO FILE [-H|-C ID]...'),
978 norepo=True)
978 norepo=True)
979 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
979 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
980 """retrieves a bundle from a repo
980 """retrieves a bundle from a repo
981
981
982 Every ID must be a full-length hex node id string. Saves the bundle to the
982 Every ID must be a full-length hex node id string. Saves the bundle to the
983 given file.
983 given file.
984 """
984 """
985 opts = pycompat.byteskwargs(opts)
985 opts = pycompat.byteskwargs(opts)
986 repo = hg.peer(ui, opts, repopath)
986 repo = hg.peer(ui, opts, repopath)
987 if not repo.capable('getbundle'):
987 if not repo.capable('getbundle'):
988 raise error.Abort("getbundle() not supported by target repository")
988 raise error.Abort("getbundle() not supported by target repository")
989 args = {}
989 args = {}
990 if common:
990 if common:
991 args[r'common'] = [bin(s) for s in common]
991 args[r'common'] = [bin(s) for s in common]
992 if head:
992 if head:
993 args[r'heads'] = [bin(s) for s in head]
993 args[r'heads'] = [bin(s) for s in head]
994 # TODO: get desired bundlecaps from command line.
994 # TODO: get desired bundlecaps from command line.
995 args[r'bundlecaps'] = None
995 args[r'bundlecaps'] = None
996 bundle = repo.getbundle('debug', **args)
996 bundle = repo.getbundle('debug', **args)
997
997
998 bundletype = opts.get('type', 'bzip2').lower()
998 bundletype = opts.get('type', 'bzip2').lower()
999 btypes = {'none': 'HG10UN',
999 btypes = {'none': 'HG10UN',
1000 'bzip2': 'HG10BZ',
1000 'bzip2': 'HG10BZ',
1001 'gzip': 'HG10GZ',
1001 'gzip': 'HG10GZ',
1002 'bundle2': 'HG20'}
1002 'bundle2': 'HG20'}
1003 bundletype = btypes.get(bundletype)
1003 bundletype = btypes.get(bundletype)
1004 if bundletype not in bundle2.bundletypes:
1004 if bundletype not in bundle2.bundletypes:
1005 raise error.Abort(_('unknown bundle type specified with --type'))
1005 raise error.Abort(_('unknown bundle type specified with --type'))
1006 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1006 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1007
1007
1008 @command('debugignore', [], '[FILE]')
1008 @command('debugignore', [], '[FILE]')
1009 def debugignore(ui, repo, *files, **opts):
1009 def debugignore(ui, repo, *files, **opts):
1010 """display the combined ignore pattern and information about ignored files
1010 """display the combined ignore pattern and information about ignored files
1011
1011
1012 With no argument display the combined ignore pattern.
1012 With no argument display the combined ignore pattern.
1013
1013
1014 Given space separated file names, shows if the given file is ignored and
1014 Given space separated file names, shows if the given file is ignored and
1015 if so, show the ignore rule (file and line number) that matched it.
1015 if so, show the ignore rule (file and line number) that matched it.
1016 """
1016 """
1017 ignore = repo.dirstate._ignore
1017 ignore = repo.dirstate._ignore
1018 if not files:
1018 if not files:
1019 # Show all the patterns
1019 # Show all the patterns
1020 ui.write("%s\n" % pycompat.byterepr(ignore))
1020 ui.write("%s\n" % pycompat.byterepr(ignore))
1021 else:
1021 else:
1022 m = scmutil.match(repo[None], pats=files)
1022 m = scmutil.match(repo[None], pats=files)
1023 for f in m.files():
1023 for f in m.files():
1024 nf = util.normpath(f)
1024 nf = util.normpath(f)
1025 ignored = None
1025 ignored = None
1026 ignoredata = None
1026 ignoredata = None
1027 if nf != '.':
1027 if nf != '.':
1028 if ignore(nf):
1028 if ignore(nf):
1029 ignored = nf
1029 ignored = nf
1030 ignoredata = repo.dirstate._ignorefileandline(nf)
1030 ignoredata = repo.dirstate._ignorefileandline(nf)
1031 else:
1031 else:
1032 for p in util.finddirs(nf):
1032 for p in util.finddirs(nf):
1033 if ignore(p):
1033 if ignore(p):
1034 ignored = p
1034 ignored = p
1035 ignoredata = repo.dirstate._ignorefileandline(p)
1035 ignoredata = repo.dirstate._ignorefileandline(p)
1036 break
1036 break
1037 if ignored:
1037 if ignored:
1038 if ignored == nf:
1038 if ignored == nf:
1039 ui.write(_("%s is ignored\n") % m.uipath(f))
1039 ui.write(_("%s is ignored\n") % m.uipath(f))
1040 else:
1040 else:
1041 ui.write(_("%s is ignored because of "
1041 ui.write(_("%s is ignored because of "
1042 "containing folder %s\n")
1042 "containing folder %s\n")
1043 % (m.uipath(f), ignored))
1043 % (m.uipath(f), ignored))
1044 ignorefile, lineno, line = ignoredata
1044 ignorefile, lineno, line = ignoredata
1045 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1045 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1046 % (ignorefile, lineno, line))
1046 % (ignorefile, lineno, line))
1047 else:
1047 else:
1048 ui.write(_("%s is not ignored\n") % m.uipath(f))
1048 ui.write(_("%s is not ignored\n") % m.uipath(f))
1049
1049
1050 @command('debugindex', cmdutil.debugrevlogopts +
1050 @command('debugindex', cmdutil.debugrevlogopts +
1051 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1051 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1052 _('[-f FORMAT] -c|-m|FILE'),
1052 _('[-f FORMAT] -c|-m|FILE'),
1053 optionalrepo=True)
1053 optionalrepo=True)
1054 def debugindex(ui, repo, file_=None, **opts):
1054 def debugindex(ui, repo, file_=None, **opts):
1055 """dump the contents of an index file"""
1055 """dump the contents of an index file"""
1056 opts = pycompat.byteskwargs(opts)
1056 opts = pycompat.byteskwargs(opts)
1057 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1057 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1058 format = opts.get('format', 0)
1058 format = opts.get('format', 0)
1059 if format not in (0, 1):
1059 if format not in (0, 1):
1060 raise error.Abort(_("unknown format %d") % format)
1060 raise error.Abort(_("unknown format %d") % format)
1061
1061
1062 if ui.debugflag:
1062 if ui.debugflag:
1063 shortfn = hex
1063 shortfn = hex
1064 else:
1064 else:
1065 shortfn = short
1065 shortfn = short
1066
1066
1067 # There might not be anything in r, so have a sane default
1067 # There might not be anything in r, so have a sane default
1068 idlen = 12
1068 idlen = 12
1069 for i in r:
1069 for i in r:
1070 idlen = len(shortfn(r.node(i)))
1070 idlen = len(shortfn(r.node(i)))
1071 break
1071 break
1072
1072
1073 if format == 0:
1073 if format == 0:
1074 ui.write((" rev offset length linkrev"
1074 if ui.verbose:
1075 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
1075 ui.write((" rev offset length linkrev"
1076 " %s %s p2\n") % ("nodeid".ljust(idlen),
1077 "p1".ljust(idlen)))
1078 else:
1079 ui.write((" rev linkrev %s %s p2\n") % (
1080 "nodeid".ljust(idlen), "p1".ljust(idlen)))
1076 elif format == 1:
1081 elif format == 1:
1077 ui.write((" rev flag offset length size link p1 p2"
1082 if ui.verbose:
1078 " %s\n") % "nodeid".rjust(idlen))
1083 ui.write((" rev flag offset length size link p1"
1084 " p2 %s\n") % "nodeid".rjust(idlen))
1085 else:
1086 ui.write((" rev flag size link p1 p2 %s\n") %
1087 "nodeid".rjust(idlen))
1079
1088
1080 for i in r:
1089 for i in r:
1081 node = r.node(i)
1090 node = r.node(i)
1082 if format == 0:
1091 if format == 0:
1083 try:
1092 try:
1084 pp = r.parents(node)
1093 pp = r.parents(node)
1085 except Exception:
1094 except Exception:
1086 pp = [nullid, nullid]
1095 pp = [nullid, nullid]
1087 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
1096 if ui.verbose:
1088 i, r.start(i), r.length(i), r.linkrev(i),
1097 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
1089 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1098 i, r.start(i), r.length(i), r.linkrev(i),
1099 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1100 else:
1101 ui.write("% 6d % 7d %s %s %s\n" % (
1102 i, r.linkrev(i), shortfn(node), shortfn(pp[0]),
1103 shortfn(pp[1])))
1090 elif format == 1:
1104 elif format == 1:
1091 pr = r.parentrevs(i)
1105 pr = r.parentrevs(i)
1092 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
1106 if ui.verbose:
1093 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1107 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
1094 r.linkrev(i), pr[0], pr[1], shortfn(node)))
1108 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1109 r.linkrev(i), pr[0], pr[1], shortfn(node)))
1110 else:
1111 ui.write("% 6d %04x % 8d % 6d % 6d % 6d %s\n" % (
1112 i, r.flags(i), r.rawsize(i), r.linkrev(i), pr[0], pr[1],
1113 shortfn(node)))
1095
1114
1096 @command('debugindexdot', cmdutil.debugrevlogopts,
1115 @command('debugindexdot', cmdutil.debugrevlogopts,
1097 _('-c|-m|FILE'), optionalrepo=True)
1116 _('-c|-m|FILE'), optionalrepo=True)
1098 def debugindexdot(ui, repo, file_=None, **opts):
1117 def debugindexdot(ui, repo, file_=None, **opts):
1099 """dump an index DAG as a graphviz dot file"""
1118 """dump an index DAG as a graphviz dot file"""
1100 opts = pycompat.byteskwargs(opts)
1119 opts = pycompat.byteskwargs(opts)
1101 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1120 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1102 ui.write(("digraph G {\n"))
1121 ui.write(("digraph G {\n"))
1103 for i in r:
1122 for i in r:
1104 node = r.node(i)
1123 node = r.node(i)
1105 pp = r.parents(node)
1124 pp = r.parents(node)
1106 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1125 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1107 if pp[1] != nullid:
1126 if pp[1] != nullid:
1108 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1127 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1109 ui.write("}\n")
1128 ui.write("}\n")
1110
1129
1111 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1130 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1112 def debuginstall(ui, **opts):
1131 def debuginstall(ui, **opts):
1113 '''test Mercurial installation
1132 '''test Mercurial installation
1114
1133
1115 Returns 0 on success.
1134 Returns 0 on success.
1116 '''
1135 '''
1117 opts = pycompat.byteskwargs(opts)
1136 opts = pycompat.byteskwargs(opts)
1118
1137
1119 def writetemp(contents):
1138 def writetemp(contents):
1120 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1139 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1121 f = os.fdopen(fd, r"wb")
1140 f = os.fdopen(fd, r"wb")
1122 f.write(contents)
1141 f.write(contents)
1123 f.close()
1142 f.close()
1124 return name
1143 return name
1125
1144
1126 problems = 0
1145 problems = 0
1127
1146
1128 fm = ui.formatter('debuginstall', opts)
1147 fm = ui.formatter('debuginstall', opts)
1129 fm.startitem()
1148 fm.startitem()
1130
1149
1131 # encoding
1150 # encoding
1132 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1151 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1133 err = None
1152 err = None
1134 try:
1153 try:
1135 codecs.lookup(pycompat.sysstr(encoding.encoding))
1154 codecs.lookup(pycompat.sysstr(encoding.encoding))
1136 except LookupError as inst:
1155 except LookupError as inst:
1137 err = stringutil.forcebytestr(inst)
1156 err = stringutil.forcebytestr(inst)
1138 problems += 1
1157 problems += 1
1139 fm.condwrite(err, 'encodingerror', _(" %s\n"
1158 fm.condwrite(err, 'encodingerror', _(" %s\n"
1140 " (check that your locale is properly set)\n"), err)
1159 " (check that your locale is properly set)\n"), err)
1141
1160
1142 # Python
1161 # Python
1143 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1162 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1144 pycompat.sysexecutable)
1163 pycompat.sysexecutable)
1145 fm.write('pythonver', _("checking Python version (%s)\n"),
1164 fm.write('pythonver', _("checking Python version (%s)\n"),
1146 ("%d.%d.%d" % sys.version_info[:3]))
1165 ("%d.%d.%d" % sys.version_info[:3]))
1147 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1166 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1148 os.path.dirname(pycompat.fsencode(os.__file__)))
1167 os.path.dirname(pycompat.fsencode(os.__file__)))
1149
1168
1150 security = set(sslutil.supportedprotocols)
1169 security = set(sslutil.supportedprotocols)
1151 if sslutil.hassni:
1170 if sslutil.hassni:
1152 security.add('sni')
1171 security.add('sni')
1153
1172
1154 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1173 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1155 fm.formatlist(sorted(security), name='protocol',
1174 fm.formatlist(sorted(security), name='protocol',
1156 fmt='%s', sep=','))
1175 fmt='%s', sep=','))
1157
1176
1158 # These are warnings, not errors. So don't increment problem count. This
1177 # These are warnings, not errors. So don't increment problem count. This
1159 # may change in the future.
1178 # may change in the future.
1160 if 'tls1.2' not in security:
1179 if 'tls1.2' not in security:
1161 fm.plain(_(' TLS 1.2 not supported by Python install; '
1180 fm.plain(_(' TLS 1.2 not supported by Python install; '
1162 'network connections lack modern security\n'))
1181 'network connections lack modern security\n'))
1163 if 'sni' not in security:
1182 if 'sni' not in security:
1164 fm.plain(_(' SNI not supported by Python install; may have '
1183 fm.plain(_(' SNI not supported by Python install; may have '
1165 'connectivity issues with some servers\n'))
1184 'connectivity issues with some servers\n'))
1166
1185
1167 # TODO print CA cert info
1186 # TODO print CA cert info
1168
1187
1169 # hg version
1188 # hg version
1170 hgver = util.version()
1189 hgver = util.version()
1171 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1190 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1172 hgver.split('+')[0])
1191 hgver.split('+')[0])
1173 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1192 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1174 '+'.join(hgver.split('+')[1:]))
1193 '+'.join(hgver.split('+')[1:]))
1175
1194
1176 # compiled modules
1195 # compiled modules
1177 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1196 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1178 policy.policy)
1197 policy.policy)
1179 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1198 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1180 os.path.dirname(pycompat.fsencode(__file__)))
1199 os.path.dirname(pycompat.fsencode(__file__)))
1181
1200
1182 if policy.policy in ('c', 'allow'):
1201 if policy.policy in ('c', 'allow'):
1183 err = None
1202 err = None
1184 try:
1203 try:
1185 from .cext import (
1204 from .cext import (
1186 base85,
1205 base85,
1187 bdiff,
1206 bdiff,
1188 mpatch,
1207 mpatch,
1189 osutil,
1208 osutil,
1190 )
1209 )
1191 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1210 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1192 except Exception as inst:
1211 except Exception as inst:
1193 err = stringutil.forcebytestr(inst)
1212 err = stringutil.forcebytestr(inst)
1194 problems += 1
1213 problems += 1
1195 fm.condwrite(err, 'extensionserror', " %s\n", err)
1214 fm.condwrite(err, 'extensionserror', " %s\n", err)
1196
1215
1197 compengines = util.compengines._engines.values()
1216 compengines = util.compengines._engines.values()
1198 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1217 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1199 fm.formatlist(sorted(e.name() for e in compengines),
1218 fm.formatlist(sorted(e.name() for e in compengines),
1200 name='compengine', fmt='%s', sep=', '))
1219 name='compengine', fmt='%s', sep=', '))
1201 fm.write('compenginesavail', _('checking available compression engines '
1220 fm.write('compenginesavail', _('checking available compression engines '
1202 '(%s)\n'),
1221 '(%s)\n'),
1203 fm.formatlist(sorted(e.name() for e in compengines
1222 fm.formatlist(sorted(e.name() for e in compengines
1204 if e.available()),
1223 if e.available()),
1205 name='compengine', fmt='%s', sep=', '))
1224 name='compengine', fmt='%s', sep=', '))
1206 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1225 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1207 fm.write('compenginesserver', _('checking available compression engines '
1226 fm.write('compenginesserver', _('checking available compression engines '
1208 'for wire protocol (%s)\n'),
1227 'for wire protocol (%s)\n'),
1209 fm.formatlist([e.name() for e in wirecompengines
1228 fm.formatlist([e.name() for e in wirecompengines
1210 if e.wireprotosupport()],
1229 if e.wireprotosupport()],
1211 name='compengine', fmt='%s', sep=', '))
1230 name='compengine', fmt='%s', sep=', '))
1212 re2 = 'missing'
1231 re2 = 'missing'
1213 if util._re2:
1232 if util._re2:
1214 re2 = 'available'
1233 re2 = 'available'
1215 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1234 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1216 fm.data(re2=bool(util._re2))
1235 fm.data(re2=bool(util._re2))
1217
1236
1218 # templates
1237 # templates
1219 p = templater.templatepaths()
1238 p = templater.templatepaths()
1220 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1239 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1221 fm.condwrite(not p, '', _(" no template directories found\n"))
1240 fm.condwrite(not p, '', _(" no template directories found\n"))
1222 if p:
1241 if p:
1223 m = templater.templatepath("map-cmdline.default")
1242 m = templater.templatepath("map-cmdline.default")
1224 if m:
1243 if m:
1225 # template found, check if it is working
1244 # template found, check if it is working
1226 err = None
1245 err = None
1227 try:
1246 try:
1228 templater.templater.frommapfile(m)
1247 templater.templater.frommapfile(m)
1229 except Exception as inst:
1248 except Exception as inst:
1230 err = stringutil.forcebytestr(inst)
1249 err = stringutil.forcebytestr(inst)
1231 p = None
1250 p = None
1232 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1251 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1233 else:
1252 else:
1234 p = None
1253 p = None
1235 fm.condwrite(p, 'defaulttemplate',
1254 fm.condwrite(p, 'defaulttemplate',
1236 _("checking default template (%s)\n"), m)
1255 _("checking default template (%s)\n"), m)
1237 fm.condwrite(not m, 'defaulttemplatenotfound',
1256 fm.condwrite(not m, 'defaulttemplatenotfound',
1238 _(" template '%s' not found\n"), "default")
1257 _(" template '%s' not found\n"), "default")
1239 if not p:
1258 if not p:
1240 problems += 1
1259 problems += 1
1241 fm.condwrite(not p, '',
1260 fm.condwrite(not p, '',
1242 _(" (templates seem to have been installed incorrectly)\n"))
1261 _(" (templates seem to have been installed incorrectly)\n"))
1243
1262
1244 # editor
1263 # editor
1245 editor = ui.geteditor()
1264 editor = ui.geteditor()
1246 editor = util.expandpath(editor)
1265 editor = util.expandpath(editor)
1247 editorbin = procutil.shellsplit(editor)[0]
1266 editorbin = procutil.shellsplit(editor)[0]
1248 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1267 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1249 cmdpath = procutil.findexe(editorbin)
1268 cmdpath = procutil.findexe(editorbin)
1250 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1269 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1251 _(" No commit editor set and can't find %s in PATH\n"
1270 _(" No commit editor set and can't find %s in PATH\n"
1252 " (specify a commit editor in your configuration"
1271 " (specify a commit editor in your configuration"
1253 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1272 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1254 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1273 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1255 _(" Can't find editor '%s' in PATH\n"
1274 _(" Can't find editor '%s' in PATH\n"
1256 " (specify a commit editor in your configuration"
1275 " (specify a commit editor in your configuration"
1257 " file)\n"), not cmdpath and editorbin)
1276 " file)\n"), not cmdpath and editorbin)
1258 if not cmdpath and editor != 'vi':
1277 if not cmdpath and editor != 'vi':
1259 problems += 1
1278 problems += 1
1260
1279
1261 # check username
1280 # check username
1262 username = None
1281 username = None
1263 err = None
1282 err = None
1264 try:
1283 try:
1265 username = ui.username()
1284 username = ui.username()
1266 except error.Abort as e:
1285 except error.Abort as e:
1267 err = stringutil.forcebytestr(e)
1286 err = stringutil.forcebytestr(e)
1268 problems += 1
1287 problems += 1
1269
1288
1270 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1289 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1271 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1290 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1272 " (specify a username in your configuration file)\n"), err)
1291 " (specify a username in your configuration file)\n"), err)
1273
1292
1274 fm.condwrite(not problems, '',
1293 fm.condwrite(not problems, '',
1275 _("no problems detected\n"))
1294 _("no problems detected\n"))
1276 if not problems:
1295 if not problems:
1277 fm.data(problems=problems)
1296 fm.data(problems=problems)
1278 fm.condwrite(problems, 'problems',
1297 fm.condwrite(problems, 'problems',
1279 _("%d problems detected,"
1298 _("%d problems detected,"
1280 " please check your install!\n"), problems)
1299 " please check your install!\n"), problems)
1281 fm.end()
1300 fm.end()
1282
1301
1283 return problems
1302 return problems
1284
1303
1285 @command('debugknown', [], _('REPO ID...'), norepo=True)
1304 @command('debugknown', [], _('REPO ID...'), norepo=True)
1286 def debugknown(ui, repopath, *ids, **opts):
1305 def debugknown(ui, repopath, *ids, **opts):
1287 """test whether node ids are known to a repo
1306 """test whether node ids are known to a repo
1288
1307
1289 Every ID must be a full-length hex node id string. Returns a list of 0s
1308 Every ID must be a full-length hex node id string. Returns a list of 0s
1290 and 1s indicating unknown/known.
1309 and 1s indicating unknown/known.
1291 """
1310 """
1292 opts = pycompat.byteskwargs(opts)
1311 opts = pycompat.byteskwargs(opts)
1293 repo = hg.peer(ui, opts, repopath)
1312 repo = hg.peer(ui, opts, repopath)
1294 if not repo.capable('known'):
1313 if not repo.capable('known'):
1295 raise error.Abort("known() not supported by target repository")
1314 raise error.Abort("known() not supported by target repository")
1296 flags = repo.known([bin(s) for s in ids])
1315 flags = repo.known([bin(s) for s in ids])
1297 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1316 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1298
1317
1299 @command('debuglabelcomplete', [], _('LABEL...'))
1318 @command('debuglabelcomplete', [], _('LABEL...'))
1300 def debuglabelcomplete(ui, repo, *args):
1319 def debuglabelcomplete(ui, repo, *args):
1301 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1320 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1302 debugnamecomplete(ui, repo, *args)
1321 debugnamecomplete(ui, repo, *args)
1303
1322
1304 @command('debuglocks',
1323 @command('debuglocks',
1305 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1324 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1306 ('W', 'force-wlock', None,
1325 ('W', 'force-wlock', None,
1307 _('free the working state lock (DANGEROUS)')),
1326 _('free the working state lock (DANGEROUS)')),
1308 ('s', 'set-lock', None, _('set the store lock until stopped')),
1327 ('s', 'set-lock', None, _('set the store lock until stopped')),
1309 ('S', 'set-wlock', None,
1328 ('S', 'set-wlock', None,
1310 _('set the working state lock until stopped'))],
1329 _('set the working state lock until stopped'))],
1311 _('[OPTION]...'))
1330 _('[OPTION]...'))
1312 def debuglocks(ui, repo, **opts):
1331 def debuglocks(ui, repo, **opts):
1313 """show or modify state of locks
1332 """show or modify state of locks
1314
1333
1315 By default, this command will show which locks are held. This
1334 By default, this command will show which locks are held. This
1316 includes the user and process holding the lock, the amount of time
1335 includes the user and process holding the lock, the amount of time
1317 the lock has been held, and the machine name where the process is
1336 the lock has been held, and the machine name where the process is
1318 running if it's not local.
1337 running if it's not local.
1319
1338
1320 Locks protect the integrity of Mercurial's data, so should be
1339 Locks protect the integrity of Mercurial's data, so should be
1321 treated with care. System crashes or other interruptions may cause
1340 treated with care. System crashes or other interruptions may cause
1322 locks to not be properly released, though Mercurial will usually
1341 locks to not be properly released, though Mercurial will usually
1323 detect and remove such stale locks automatically.
1342 detect and remove such stale locks automatically.
1324
1343
1325 However, detecting stale locks may not always be possible (for
1344 However, detecting stale locks may not always be possible (for
1326 instance, on a shared filesystem). Removing locks may also be
1345 instance, on a shared filesystem). Removing locks may also be
1327 blocked by filesystem permissions.
1346 blocked by filesystem permissions.
1328
1347
1329 Setting a lock will prevent other commands from changing the data.
1348 Setting a lock will prevent other commands from changing the data.
1330 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1349 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1331 The set locks are removed when the command exits.
1350 The set locks are removed when the command exits.
1332
1351
1333 Returns 0 if no locks are held.
1352 Returns 0 if no locks are held.
1334
1353
1335 """
1354 """
1336
1355
1337 if opts.get(r'force_lock'):
1356 if opts.get(r'force_lock'):
1338 repo.svfs.unlink('lock')
1357 repo.svfs.unlink('lock')
1339 if opts.get(r'force_wlock'):
1358 if opts.get(r'force_wlock'):
1340 repo.vfs.unlink('wlock')
1359 repo.vfs.unlink('wlock')
1341 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1360 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1342 return 0
1361 return 0
1343
1362
1344 locks = []
1363 locks = []
1345 try:
1364 try:
1346 if opts.get(r'set_wlock'):
1365 if opts.get(r'set_wlock'):
1347 try:
1366 try:
1348 locks.append(repo.wlock(False))
1367 locks.append(repo.wlock(False))
1349 except error.LockHeld:
1368 except error.LockHeld:
1350 raise error.Abort(_('wlock is already held'))
1369 raise error.Abort(_('wlock is already held'))
1351 if opts.get(r'set_lock'):
1370 if opts.get(r'set_lock'):
1352 try:
1371 try:
1353 locks.append(repo.lock(False))
1372 locks.append(repo.lock(False))
1354 except error.LockHeld:
1373 except error.LockHeld:
1355 raise error.Abort(_('lock is already held'))
1374 raise error.Abort(_('lock is already held'))
1356 if len(locks):
1375 if len(locks):
1357 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1376 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1358 return 0
1377 return 0
1359 finally:
1378 finally:
1360 release(*locks)
1379 release(*locks)
1361
1380
1362 now = time.time()
1381 now = time.time()
1363 held = 0
1382 held = 0
1364
1383
1365 def report(vfs, name, method):
1384 def report(vfs, name, method):
1366 # this causes stale locks to get reaped for more accurate reporting
1385 # this causes stale locks to get reaped for more accurate reporting
1367 try:
1386 try:
1368 l = method(False)
1387 l = method(False)
1369 except error.LockHeld:
1388 except error.LockHeld:
1370 l = None
1389 l = None
1371
1390
1372 if l:
1391 if l:
1373 l.release()
1392 l.release()
1374 else:
1393 else:
1375 try:
1394 try:
1376 st = vfs.lstat(name)
1395 st = vfs.lstat(name)
1377 age = now - st[stat.ST_MTIME]
1396 age = now - st[stat.ST_MTIME]
1378 user = util.username(st.st_uid)
1397 user = util.username(st.st_uid)
1379 locker = vfs.readlock(name)
1398 locker = vfs.readlock(name)
1380 if ":" in locker:
1399 if ":" in locker:
1381 host, pid = locker.split(':')
1400 host, pid = locker.split(':')
1382 if host == socket.gethostname():
1401 if host == socket.gethostname():
1383 locker = 'user %s, process %s' % (user, pid)
1402 locker = 'user %s, process %s' % (user, pid)
1384 else:
1403 else:
1385 locker = 'user %s, process %s, host %s' \
1404 locker = 'user %s, process %s, host %s' \
1386 % (user, pid, host)
1405 % (user, pid, host)
1387 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1406 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1388 return 1
1407 return 1
1389 except OSError as e:
1408 except OSError as e:
1390 if e.errno != errno.ENOENT:
1409 if e.errno != errno.ENOENT:
1391 raise
1410 raise
1392
1411
1393 ui.write(("%-6s free\n") % (name + ":"))
1412 ui.write(("%-6s free\n") % (name + ":"))
1394 return 0
1413 return 0
1395
1414
1396 held += report(repo.svfs, "lock", repo.lock)
1415 held += report(repo.svfs, "lock", repo.lock)
1397 held += report(repo.vfs, "wlock", repo.wlock)
1416 held += report(repo.vfs, "wlock", repo.wlock)
1398
1417
1399 return held
1418 return held
1400
1419
1401 @command('debugmergestate', [], '')
1420 @command('debugmergestate', [], '')
1402 def debugmergestate(ui, repo, *args):
1421 def debugmergestate(ui, repo, *args):
1403 """print merge state
1422 """print merge state
1404
1423
1405 Use --verbose to print out information about whether v1 or v2 merge state
1424 Use --verbose to print out information about whether v1 or v2 merge state
1406 was chosen."""
1425 was chosen."""
1407 def _hashornull(h):
1426 def _hashornull(h):
1408 if h == nullhex:
1427 if h == nullhex:
1409 return 'null'
1428 return 'null'
1410 else:
1429 else:
1411 return h
1430 return h
1412
1431
1413 def printrecords(version):
1432 def printrecords(version):
1414 ui.write(('* version %d records\n') % version)
1433 ui.write(('* version %d records\n') % version)
1415 if version == 1:
1434 if version == 1:
1416 records = v1records
1435 records = v1records
1417 else:
1436 else:
1418 records = v2records
1437 records = v2records
1419
1438
1420 for rtype, record in records:
1439 for rtype, record in records:
1421 # pretty print some record types
1440 # pretty print some record types
1422 if rtype == 'L':
1441 if rtype == 'L':
1423 ui.write(('local: %s\n') % record)
1442 ui.write(('local: %s\n') % record)
1424 elif rtype == 'O':
1443 elif rtype == 'O':
1425 ui.write(('other: %s\n') % record)
1444 ui.write(('other: %s\n') % record)
1426 elif rtype == 'm':
1445 elif rtype == 'm':
1427 driver, mdstate = record.split('\0', 1)
1446 driver, mdstate = record.split('\0', 1)
1428 ui.write(('merge driver: %s (state "%s")\n')
1447 ui.write(('merge driver: %s (state "%s")\n')
1429 % (driver, mdstate))
1448 % (driver, mdstate))
1430 elif rtype in 'FDC':
1449 elif rtype in 'FDC':
1431 r = record.split('\0')
1450 r = record.split('\0')
1432 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1451 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1433 if version == 1:
1452 if version == 1:
1434 onode = 'not stored in v1 format'
1453 onode = 'not stored in v1 format'
1435 flags = r[7]
1454 flags = r[7]
1436 else:
1455 else:
1437 onode, flags = r[7:9]
1456 onode, flags = r[7:9]
1438 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1457 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1439 % (f, rtype, state, _hashornull(hash)))
1458 % (f, rtype, state, _hashornull(hash)))
1440 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1459 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1441 ui.write((' ancestor path: %s (node %s)\n')
1460 ui.write((' ancestor path: %s (node %s)\n')
1442 % (afile, _hashornull(anode)))
1461 % (afile, _hashornull(anode)))
1443 ui.write((' other path: %s (node %s)\n')
1462 ui.write((' other path: %s (node %s)\n')
1444 % (ofile, _hashornull(onode)))
1463 % (ofile, _hashornull(onode)))
1445 elif rtype == 'f':
1464 elif rtype == 'f':
1446 filename, rawextras = record.split('\0', 1)
1465 filename, rawextras = record.split('\0', 1)
1447 extras = rawextras.split('\0')
1466 extras = rawextras.split('\0')
1448 i = 0
1467 i = 0
1449 extrastrings = []
1468 extrastrings = []
1450 while i < len(extras):
1469 while i < len(extras):
1451 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1470 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1452 i += 2
1471 i += 2
1453
1472
1454 ui.write(('file extras: %s (%s)\n')
1473 ui.write(('file extras: %s (%s)\n')
1455 % (filename, ', '.join(extrastrings)))
1474 % (filename, ', '.join(extrastrings)))
1456 elif rtype == 'l':
1475 elif rtype == 'l':
1457 labels = record.split('\0', 2)
1476 labels = record.split('\0', 2)
1458 labels = [l for l in labels if len(l) > 0]
1477 labels = [l for l in labels if len(l) > 0]
1459 ui.write(('labels:\n'))
1478 ui.write(('labels:\n'))
1460 ui.write((' local: %s\n' % labels[0]))
1479 ui.write((' local: %s\n' % labels[0]))
1461 ui.write((' other: %s\n' % labels[1]))
1480 ui.write((' other: %s\n' % labels[1]))
1462 if len(labels) > 2:
1481 if len(labels) > 2:
1463 ui.write((' base: %s\n' % labels[2]))
1482 ui.write((' base: %s\n' % labels[2]))
1464 else:
1483 else:
1465 ui.write(('unrecognized entry: %s\t%s\n')
1484 ui.write(('unrecognized entry: %s\t%s\n')
1466 % (rtype, record.replace('\0', '\t')))
1485 % (rtype, record.replace('\0', '\t')))
1467
1486
1468 # Avoid mergestate.read() since it may raise an exception for unsupported
1487 # Avoid mergestate.read() since it may raise an exception for unsupported
1469 # merge state records. We shouldn't be doing this, but this is OK since this
1488 # merge state records. We shouldn't be doing this, but this is OK since this
1470 # command is pretty low-level.
1489 # command is pretty low-level.
1471 ms = mergemod.mergestate(repo)
1490 ms = mergemod.mergestate(repo)
1472
1491
1473 # sort so that reasonable information is on top
1492 # sort so that reasonable information is on top
1474 v1records = ms._readrecordsv1()
1493 v1records = ms._readrecordsv1()
1475 v2records = ms._readrecordsv2()
1494 v2records = ms._readrecordsv2()
1476 order = 'LOml'
1495 order = 'LOml'
1477 def key(r):
1496 def key(r):
1478 idx = order.find(r[0])
1497 idx = order.find(r[0])
1479 if idx == -1:
1498 if idx == -1:
1480 return (1, r[1])
1499 return (1, r[1])
1481 else:
1500 else:
1482 return (0, idx)
1501 return (0, idx)
1483 v1records.sort(key=key)
1502 v1records.sort(key=key)
1484 v2records.sort(key=key)
1503 v2records.sort(key=key)
1485
1504
1486 if not v1records and not v2records:
1505 if not v1records and not v2records:
1487 ui.write(('no merge state found\n'))
1506 ui.write(('no merge state found\n'))
1488 elif not v2records:
1507 elif not v2records:
1489 ui.note(('no version 2 merge state\n'))
1508 ui.note(('no version 2 merge state\n'))
1490 printrecords(1)
1509 printrecords(1)
1491 elif ms._v1v2match(v1records, v2records):
1510 elif ms._v1v2match(v1records, v2records):
1492 ui.note(('v1 and v2 states match: using v2\n'))
1511 ui.note(('v1 and v2 states match: using v2\n'))
1493 printrecords(2)
1512 printrecords(2)
1494 else:
1513 else:
1495 ui.note(('v1 and v2 states mismatch: using v1\n'))
1514 ui.note(('v1 and v2 states mismatch: using v1\n'))
1496 printrecords(1)
1515 printrecords(1)
1497 if ui.verbose:
1516 if ui.verbose:
1498 printrecords(2)
1517 printrecords(2)
1499
1518
1500 @command('debugnamecomplete', [], _('NAME...'))
1519 @command('debugnamecomplete', [], _('NAME...'))
1501 def debugnamecomplete(ui, repo, *args):
1520 def debugnamecomplete(ui, repo, *args):
1502 '''complete "names" - tags, open branch names, bookmark names'''
1521 '''complete "names" - tags, open branch names, bookmark names'''
1503
1522
1504 names = set()
1523 names = set()
1505 # since we previously only listed open branches, we will handle that
1524 # since we previously only listed open branches, we will handle that
1506 # specially (after this for loop)
1525 # specially (after this for loop)
1507 for name, ns in repo.names.iteritems():
1526 for name, ns in repo.names.iteritems():
1508 if name != 'branches':
1527 if name != 'branches':
1509 names.update(ns.listnames(repo))
1528 names.update(ns.listnames(repo))
1510 names.update(tag for (tag, heads, tip, closed)
1529 names.update(tag for (tag, heads, tip, closed)
1511 in repo.branchmap().iterbranches() if not closed)
1530 in repo.branchmap().iterbranches() if not closed)
1512 completions = set()
1531 completions = set()
1513 if not args:
1532 if not args:
1514 args = ['']
1533 args = ['']
1515 for a in args:
1534 for a in args:
1516 completions.update(n for n in names if n.startswith(a))
1535 completions.update(n for n in names if n.startswith(a))
1517 ui.write('\n'.join(sorted(completions)))
1536 ui.write('\n'.join(sorted(completions)))
1518 ui.write('\n')
1537 ui.write('\n')
1519
1538
1520 @command('debugobsolete',
1539 @command('debugobsolete',
1521 [('', 'flags', 0, _('markers flag')),
1540 [('', 'flags', 0, _('markers flag')),
1522 ('', 'record-parents', False,
1541 ('', 'record-parents', False,
1523 _('record parent information for the precursor')),
1542 _('record parent information for the precursor')),
1524 ('r', 'rev', [], _('display markers relevant to REV')),
1543 ('r', 'rev', [], _('display markers relevant to REV')),
1525 ('', 'exclusive', False, _('restrict display to markers only '
1544 ('', 'exclusive', False, _('restrict display to markers only '
1526 'relevant to REV')),
1545 'relevant to REV')),
1527 ('', 'index', False, _('display index of the marker')),
1546 ('', 'index', False, _('display index of the marker')),
1528 ('', 'delete', [], _('delete markers specified by indices')),
1547 ('', 'delete', [], _('delete markers specified by indices')),
1529 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1548 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1530 _('[OBSOLETED [REPLACEMENT ...]]'))
1549 _('[OBSOLETED [REPLACEMENT ...]]'))
1531 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1550 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1532 """create arbitrary obsolete marker
1551 """create arbitrary obsolete marker
1533
1552
1534 With no arguments, displays the list of obsolescence markers."""
1553 With no arguments, displays the list of obsolescence markers."""
1535
1554
1536 opts = pycompat.byteskwargs(opts)
1555 opts = pycompat.byteskwargs(opts)
1537
1556
1538 def parsenodeid(s):
1557 def parsenodeid(s):
1539 try:
1558 try:
1540 # We do not use revsingle/revrange functions here to accept
1559 # We do not use revsingle/revrange functions here to accept
1541 # arbitrary node identifiers, possibly not present in the
1560 # arbitrary node identifiers, possibly not present in the
1542 # local repository.
1561 # local repository.
1543 n = bin(s)
1562 n = bin(s)
1544 if len(n) != len(nullid):
1563 if len(n) != len(nullid):
1545 raise TypeError()
1564 raise TypeError()
1546 return n
1565 return n
1547 except TypeError:
1566 except TypeError:
1548 raise error.Abort('changeset references must be full hexadecimal '
1567 raise error.Abort('changeset references must be full hexadecimal '
1549 'node identifiers')
1568 'node identifiers')
1550
1569
1551 if opts.get('delete'):
1570 if opts.get('delete'):
1552 indices = []
1571 indices = []
1553 for v in opts.get('delete'):
1572 for v in opts.get('delete'):
1554 try:
1573 try:
1555 indices.append(int(v))
1574 indices.append(int(v))
1556 except ValueError:
1575 except ValueError:
1557 raise error.Abort(_('invalid index value: %r') % v,
1576 raise error.Abort(_('invalid index value: %r') % v,
1558 hint=_('use integers for indices'))
1577 hint=_('use integers for indices'))
1559
1578
1560 if repo.currenttransaction():
1579 if repo.currenttransaction():
1561 raise error.Abort(_('cannot delete obsmarkers in the middle '
1580 raise error.Abort(_('cannot delete obsmarkers in the middle '
1562 'of transaction.'))
1581 'of transaction.'))
1563
1582
1564 with repo.lock():
1583 with repo.lock():
1565 n = repair.deleteobsmarkers(repo.obsstore, indices)
1584 n = repair.deleteobsmarkers(repo.obsstore, indices)
1566 ui.write(_('deleted %i obsolescence markers\n') % n)
1585 ui.write(_('deleted %i obsolescence markers\n') % n)
1567
1586
1568 return
1587 return
1569
1588
1570 if precursor is not None:
1589 if precursor is not None:
1571 if opts['rev']:
1590 if opts['rev']:
1572 raise error.Abort('cannot select revision when creating marker')
1591 raise error.Abort('cannot select revision when creating marker')
1573 metadata = {}
1592 metadata = {}
1574 metadata['user'] = opts['user'] or ui.username()
1593 metadata['user'] = opts['user'] or ui.username()
1575 succs = tuple(parsenodeid(succ) for succ in successors)
1594 succs = tuple(parsenodeid(succ) for succ in successors)
1576 l = repo.lock()
1595 l = repo.lock()
1577 try:
1596 try:
1578 tr = repo.transaction('debugobsolete')
1597 tr = repo.transaction('debugobsolete')
1579 try:
1598 try:
1580 date = opts.get('date')
1599 date = opts.get('date')
1581 if date:
1600 if date:
1582 date = dateutil.parsedate(date)
1601 date = dateutil.parsedate(date)
1583 else:
1602 else:
1584 date = None
1603 date = None
1585 prec = parsenodeid(precursor)
1604 prec = parsenodeid(precursor)
1586 parents = None
1605 parents = None
1587 if opts['record_parents']:
1606 if opts['record_parents']:
1588 if prec not in repo.unfiltered():
1607 if prec not in repo.unfiltered():
1589 raise error.Abort('cannot used --record-parents on '
1608 raise error.Abort('cannot used --record-parents on '
1590 'unknown changesets')
1609 'unknown changesets')
1591 parents = repo.unfiltered()[prec].parents()
1610 parents = repo.unfiltered()[prec].parents()
1592 parents = tuple(p.node() for p in parents)
1611 parents = tuple(p.node() for p in parents)
1593 repo.obsstore.create(tr, prec, succs, opts['flags'],
1612 repo.obsstore.create(tr, prec, succs, opts['flags'],
1594 parents=parents, date=date,
1613 parents=parents, date=date,
1595 metadata=metadata, ui=ui)
1614 metadata=metadata, ui=ui)
1596 tr.close()
1615 tr.close()
1597 except ValueError as exc:
1616 except ValueError as exc:
1598 raise error.Abort(_('bad obsmarker input: %s') %
1617 raise error.Abort(_('bad obsmarker input: %s') %
1599 pycompat.bytestr(exc))
1618 pycompat.bytestr(exc))
1600 finally:
1619 finally:
1601 tr.release()
1620 tr.release()
1602 finally:
1621 finally:
1603 l.release()
1622 l.release()
1604 else:
1623 else:
1605 if opts['rev']:
1624 if opts['rev']:
1606 revs = scmutil.revrange(repo, opts['rev'])
1625 revs = scmutil.revrange(repo, opts['rev'])
1607 nodes = [repo[r].node() for r in revs]
1626 nodes = [repo[r].node() for r in revs]
1608 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1627 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1609 exclusive=opts['exclusive']))
1628 exclusive=opts['exclusive']))
1610 markers.sort(key=lambda x: x._data)
1629 markers.sort(key=lambda x: x._data)
1611 else:
1630 else:
1612 markers = obsutil.getmarkers(repo)
1631 markers = obsutil.getmarkers(repo)
1613
1632
1614 markerstoiter = markers
1633 markerstoiter = markers
1615 isrelevant = lambda m: True
1634 isrelevant = lambda m: True
1616 if opts.get('rev') and opts.get('index'):
1635 if opts.get('rev') and opts.get('index'):
1617 markerstoiter = obsutil.getmarkers(repo)
1636 markerstoiter = obsutil.getmarkers(repo)
1618 markerset = set(markers)
1637 markerset = set(markers)
1619 isrelevant = lambda m: m in markerset
1638 isrelevant = lambda m: m in markerset
1620
1639
1621 fm = ui.formatter('debugobsolete', opts)
1640 fm = ui.formatter('debugobsolete', opts)
1622 for i, m in enumerate(markerstoiter):
1641 for i, m in enumerate(markerstoiter):
1623 if not isrelevant(m):
1642 if not isrelevant(m):
1624 # marker can be irrelevant when we're iterating over a set
1643 # marker can be irrelevant when we're iterating over a set
1625 # of markers (markerstoiter) which is bigger than the set
1644 # of markers (markerstoiter) which is bigger than the set
1626 # of markers we want to display (markers)
1645 # of markers we want to display (markers)
1627 # this can happen if both --index and --rev options are
1646 # this can happen if both --index and --rev options are
1628 # provided and thus we need to iterate over all of the markers
1647 # provided and thus we need to iterate over all of the markers
1629 # to get the correct indices, but only display the ones that
1648 # to get the correct indices, but only display the ones that
1630 # are relevant to --rev value
1649 # are relevant to --rev value
1631 continue
1650 continue
1632 fm.startitem()
1651 fm.startitem()
1633 ind = i if opts.get('index') else None
1652 ind = i if opts.get('index') else None
1634 cmdutil.showmarker(fm, m, index=ind)
1653 cmdutil.showmarker(fm, m, index=ind)
1635 fm.end()
1654 fm.end()
1636
1655
1637 @command('debugpathcomplete',
1656 @command('debugpathcomplete',
1638 [('f', 'full', None, _('complete an entire path')),
1657 [('f', 'full', None, _('complete an entire path')),
1639 ('n', 'normal', None, _('show only normal files')),
1658 ('n', 'normal', None, _('show only normal files')),
1640 ('a', 'added', None, _('show only added files')),
1659 ('a', 'added', None, _('show only added files')),
1641 ('r', 'removed', None, _('show only removed files'))],
1660 ('r', 'removed', None, _('show only removed files'))],
1642 _('FILESPEC...'))
1661 _('FILESPEC...'))
1643 def debugpathcomplete(ui, repo, *specs, **opts):
1662 def debugpathcomplete(ui, repo, *specs, **opts):
1644 '''complete part or all of a tracked path
1663 '''complete part or all of a tracked path
1645
1664
1646 This command supports shells that offer path name completion. It
1665 This command supports shells that offer path name completion. It
1647 currently completes only files already known to the dirstate.
1666 currently completes only files already known to the dirstate.
1648
1667
1649 Completion extends only to the next path segment unless
1668 Completion extends only to the next path segment unless
1650 --full is specified, in which case entire paths are used.'''
1669 --full is specified, in which case entire paths are used.'''
1651
1670
1652 def complete(path, acceptable):
1671 def complete(path, acceptable):
1653 dirstate = repo.dirstate
1672 dirstate = repo.dirstate
1654 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1673 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1655 rootdir = repo.root + pycompat.ossep
1674 rootdir = repo.root + pycompat.ossep
1656 if spec != repo.root and not spec.startswith(rootdir):
1675 if spec != repo.root and not spec.startswith(rootdir):
1657 return [], []
1676 return [], []
1658 if os.path.isdir(spec):
1677 if os.path.isdir(spec):
1659 spec += '/'
1678 spec += '/'
1660 spec = spec[len(rootdir):]
1679 spec = spec[len(rootdir):]
1661 fixpaths = pycompat.ossep != '/'
1680 fixpaths = pycompat.ossep != '/'
1662 if fixpaths:
1681 if fixpaths:
1663 spec = spec.replace(pycompat.ossep, '/')
1682 spec = spec.replace(pycompat.ossep, '/')
1664 speclen = len(spec)
1683 speclen = len(spec)
1665 fullpaths = opts[r'full']
1684 fullpaths = opts[r'full']
1666 files, dirs = set(), set()
1685 files, dirs = set(), set()
1667 adddir, addfile = dirs.add, files.add
1686 adddir, addfile = dirs.add, files.add
1668 for f, st in dirstate.iteritems():
1687 for f, st in dirstate.iteritems():
1669 if f.startswith(spec) and st[0] in acceptable:
1688 if f.startswith(spec) and st[0] in acceptable:
1670 if fixpaths:
1689 if fixpaths:
1671 f = f.replace('/', pycompat.ossep)
1690 f = f.replace('/', pycompat.ossep)
1672 if fullpaths:
1691 if fullpaths:
1673 addfile(f)
1692 addfile(f)
1674 continue
1693 continue
1675 s = f.find(pycompat.ossep, speclen)
1694 s = f.find(pycompat.ossep, speclen)
1676 if s >= 0:
1695 if s >= 0:
1677 adddir(f[:s])
1696 adddir(f[:s])
1678 else:
1697 else:
1679 addfile(f)
1698 addfile(f)
1680 return files, dirs
1699 return files, dirs
1681
1700
1682 acceptable = ''
1701 acceptable = ''
1683 if opts[r'normal']:
1702 if opts[r'normal']:
1684 acceptable += 'nm'
1703 acceptable += 'nm'
1685 if opts[r'added']:
1704 if opts[r'added']:
1686 acceptable += 'a'
1705 acceptable += 'a'
1687 if opts[r'removed']:
1706 if opts[r'removed']:
1688 acceptable += 'r'
1707 acceptable += 'r'
1689 cwd = repo.getcwd()
1708 cwd = repo.getcwd()
1690 if not specs:
1709 if not specs:
1691 specs = ['.']
1710 specs = ['.']
1692
1711
1693 files, dirs = set(), set()
1712 files, dirs = set(), set()
1694 for spec in specs:
1713 for spec in specs:
1695 f, d = complete(spec, acceptable or 'nmar')
1714 f, d = complete(spec, acceptable or 'nmar')
1696 files.update(f)
1715 files.update(f)
1697 dirs.update(d)
1716 dirs.update(d)
1698 files.update(dirs)
1717 files.update(dirs)
1699 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1718 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1700 ui.write('\n')
1719 ui.write('\n')
1701
1720
1702 @command('debugpeer', [], _('PATH'), norepo=True)
1721 @command('debugpeer', [], _('PATH'), norepo=True)
1703 def debugpeer(ui, path):
1722 def debugpeer(ui, path):
1704 """establish a connection to a peer repository"""
1723 """establish a connection to a peer repository"""
1705 # Always enable peer request logging. Requires --debug to display
1724 # Always enable peer request logging. Requires --debug to display
1706 # though.
1725 # though.
1707 overrides = {
1726 overrides = {
1708 ('devel', 'debug.peer-request'): True,
1727 ('devel', 'debug.peer-request'): True,
1709 }
1728 }
1710
1729
1711 with ui.configoverride(overrides):
1730 with ui.configoverride(overrides):
1712 peer = hg.peer(ui, {}, path)
1731 peer = hg.peer(ui, {}, path)
1713
1732
1714 local = peer.local() is not None
1733 local = peer.local() is not None
1715 canpush = peer.canpush()
1734 canpush = peer.canpush()
1716
1735
1717 ui.write(_('url: %s\n') % peer.url())
1736 ui.write(_('url: %s\n') % peer.url())
1718 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1737 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1719 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1738 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1720
1739
1721 @command('debugpickmergetool',
1740 @command('debugpickmergetool',
1722 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1741 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1723 ('', 'changedelete', None, _('emulate merging change and delete')),
1742 ('', 'changedelete', None, _('emulate merging change and delete')),
1724 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1743 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1725 _('[PATTERN]...'),
1744 _('[PATTERN]...'),
1726 inferrepo=True)
1745 inferrepo=True)
1727 def debugpickmergetool(ui, repo, *pats, **opts):
1746 def debugpickmergetool(ui, repo, *pats, **opts):
1728 """examine which merge tool is chosen for specified file
1747 """examine which merge tool is chosen for specified file
1729
1748
1730 As described in :hg:`help merge-tools`, Mercurial examines
1749 As described in :hg:`help merge-tools`, Mercurial examines
1731 configurations below in this order to decide which merge tool is
1750 configurations below in this order to decide which merge tool is
1732 chosen for specified file.
1751 chosen for specified file.
1733
1752
1734 1. ``--tool`` option
1753 1. ``--tool`` option
1735 2. ``HGMERGE`` environment variable
1754 2. ``HGMERGE`` environment variable
1736 3. configurations in ``merge-patterns`` section
1755 3. configurations in ``merge-patterns`` section
1737 4. configuration of ``ui.merge``
1756 4. configuration of ``ui.merge``
1738 5. configurations in ``merge-tools`` section
1757 5. configurations in ``merge-tools`` section
1739 6. ``hgmerge`` tool (for historical reason only)
1758 6. ``hgmerge`` tool (for historical reason only)
1740 7. default tool for fallback (``:merge`` or ``:prompt``)
1759 7. default tool for fallback (``:merge`` or ``:prompt``)
1741
1760
1742 This command writes out examination result in the style below::
1761 This command writes out examination result in the style below::
1743
1762
1744 FILE = MERGETOOL
1763 FILE = MERGETOOL
1745
1764
1746 By default, all files known in the first parent context of the
1765 By default, all files known in the first parent context of the
1747 working directory are examined. Use file patterns and/or -I/-X
1766 working directory are examined. Use file patterns and/or -I/-X
1748 options to limit target files. -r/--rev is also useful to examine
1767 options to limit target files. -r/--rev is also useful to examine
1749 files in another context without actual updating to it.
1768 files in another context without actual updating to it.
1750
1769
1751 With --debug, this command shows warning messages while matching
1770 With --debug, this command shows warning messages while matching
1752 against ``merge-patterns`` and so on, too. It is recommended to
1771 against ``merge-patterns`` and so on, too. It is recommended to
1753 use this option with explicit file patterns and/or -I/-X options,
1772 use this option with explicit file patterns and/or -I/-X options,
1754 because this option increases amount of output per file according
1773 because this option increases amount of output per file according
1755 to configurations in hgrc.
1774 to configurations in hgrc.
1756
1775
1757 With -v/--verbose, this command shows configurations below at
1776 With -v/--verbose, this command shows configurations below at
1758 first (only if specified).
1777 first (only if specified).
1759
1778
1760 - ``--tool`` option
1779 - ``--tool`` option
1761 - ``HGMERGE`` environment variable
1780 - ``HGMERGE`` environment variable
1762 - configuration of ``ui.merge``
1781 - configuration of ``ui.merge``
1763
1782
1764 If merge tool is chosen before matching against
1783 If merge tool is chosen before matching against
1765 ``merge-patterns``, this command can't show any helpful
1784 ``merge-patterns``, this command can't show any helpful
1766 information, even with --debug. In such case, information above is
1785 information, even with --debug. In such case, information above is
1767 useful to know why a merge tool is chosen.
1786 useful to know why a merge tool is chosen.
1768 """
1787 """
1769 opts = pycompat.byteskwargs(opts)
1788 opts = pycompat.byteskwargs(opts)
1770 overrides = {}
1789 overrides = {}
1771 if opts['tool']:
1790 if opts['tool']:
1772 overrides[('ui', 'forcemerge')] = opts['tool']
1791 overrides[('ui', 'forcemerge')] = opts['tool']
1773 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1792 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1774
1793
1775 with ui.configoverride(overrides, 'debugmergepatterns'):
1794 with ui.configoverride(overrides, 'debugmergepatterns'):
1776 hgmerge = encoding.environ.get("HGMERGE")
1795 hgmerge = encoding.environ.get("HGMERGE")
1777 if hgmerge is not None:
1796 if hgmerge is not None:
1778 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1797 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1779 uimerge = ui.config("ui", "merge")
1798 uimerge = ui.config("ui", "merge")
1780 if uimerge:
1799 if uimerge:
1781 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1800 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1782
1801
1783 ctx = scmutil.revsingle(repo, opts.get('rev'))
1802 ctx = scmutil.revsingle(repo, opts.get('rev'))
1784 m = scmutil.match(ctx, pats, opts)
1803 m = scmutil.match(ctx, pats, opts)
1785 changedelete = opts['changedelete']
1804 changedelete = opts['changedelete']
1786 for path in ctx.walk(m):
1805 for path in ctx.walk(m):
1787 fctx = ctx[path]
1806 fctx = ctx[path]
1788 try:
1807 try:
1789 if not ui.debugflag:
1808 if not ui.debugflag:
1790 ui.pushbuffer(error=True)
1809 ui.pushbuffer(error=True)
1791 tool, toolpath = filemerge._picktool(repo, ui, path,
1810 tool, toolpath = filemerge._picktool(repo, ui, path,
1792 fctx.isbinary(),
1811 fctx.isbinary(),
1793 'l' in fctx.flags(),
1812 'l' in fctx.flags(),
1794 changedelete)
1813 changedelete)
1795 finally:
1814 finally:
1796 if not ui.debugflag:
1815 if not ui.debugflag:
1797 ui.popbuffer()
1816 ui.popbuffer()
1798 ui.write(('%s = %s\n') % (path, tool))
1817 ui.write(('%s = %s\n') % (path, tool))
1799
1818
1800 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1819 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1801 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1820 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1802 '''access the pushkey key/value protocol
1821 '''access the pushkey key/value protocol
1803
1822
1804 With two args, list the keys in the given namespace.
1823 With two args, list the keys in the given namespace.
1805
1824
1806 With five args, set a key to new if it currently is set to old.
1825 With five args, set a key to new if it currently is set to old.
1807 Reports success or failure.
1826 Reports success or failure.
1808 '''
1827 '''
1809
1828
1810 target = hg.peer(ui, {}, repopath)
1829 target = hg.peer(ui, {}, repopath)
1811 if keyinfo:
1830 if keyinfo:
1812 key, old, new = keyinfo
1831 key, old, new = keyinfo
1813 r = target.pushkey(namespace, key, old, new)
1832 r = target.pushkey(namespace, key, old, new)
1814 ui.status(pycompat.bytestr(r) + '\n')
1833 ui.status(pycompat.bytestr(r) + '\n')
1815 return not r
1834 return not r
1816 else:
1835 else:
1817 for k, v in sorted(target.listkeys(namespace).iteritems()):
1836 for k, v in sorted(target.listkeys(namespace).iteritems()):
1818 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1837 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1819 stringutil.escapestr(v)))
1838 stringutil.escapestr(v)))
1820
1839
1821 @command('debugpvec', [], _('A B'))
1840 @command('debugpvec', [], _('A B'))
1822 def debugpvec(ui, repo, a, b=None):
1841 def debugpvec(ui, repo, a, b=None):
1823 ca = scmutil.revsingle(repo, a)
1842 ca = scmutil.revsingle(repo, a)
1824 cb = scmutil.revsingle(repo, b)
1843 cb = scmutil.revsingle(repo, b)
1825 pa = pvec.ctxpvec(ca)
1844 pa = pvec.ctxpvec(ca)
1826 pb = pvec.ctxpvec(cb)
1845 pb = pvec.ctxpvec(cb)
1827 if pa == pb:
1846 if pa == pb:
1828 rel = "="
1847 rel = "="
1829 elif pa > pb:
1848 elif pa > pb:
1830 rel = ">"
1849 rel = ">"
1831 elif pa < pb:
1850 elif pa < pb:
1832 rel = "<"
1851 rel = "<"
1833 elif pa | pb:
1852 elif pa | pb:
1834 rel = "|"
1853 rel = "|"
1835 ui.write(_("a: %s\n") % pa)
1854 ui.write(_("a: %s\n") % pa)
1836 ui.write(_("b: %s\n") % pb)
1855 ui.write(_("b: %s\n") % pb)
1837 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1856 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1838 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1857 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1839 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1858 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1840 pa.distance(pb), rel))
1859 pa.distance(pb), rel))
1841
1860
1842 @command('debugrebuilddirstate|debugrebuildstate',
1861 @command('debugrebuilddirstate|debugrebuildstate',
1843 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1862 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1844 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1863 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1845 'the working copy parent')),
1864 'the working copy parent')),
1846 ],
1865 ],
1847 _('[-r REV]'))
1866 _('[-r REV]'))
1848 def debugrebuilddirstate(ui, repo, rev, **opts):
1867 def debugrebuilddirstate(ui, repo, rev, **opts):
1849 """rebuild the dirstate as it would look like for the given revision
1868 """rebuild the dirstate as it would look like for the given revision
1850
1869
1851 If no revision is specified the first current parent will be used.
1870 If no revision is specified the first current parent will be used.
1852
1871
1853 The dirstate will be set to the files of the given revision.
1872 The dirstate will be set to the files of the given revision.
1854 The actual working directory content or existing dirstate
1873 The actual working directory content or existing dirstate
1855 information such as adds or removes is not considered.
1874 information such as adds or removes is not considered.
1856
1875
1857 ``minimal`` will only rebuild the dirstate status for files that claim to be
1876 ``minimal`` will only rebuild the dirstate status for files that claim to be
1858 tracked but are not in the parent manifest, or that exist in the parent
1877 tracked but are not in the parent manifest, or that exist in the parent
1859 manifest but are not in the dirstate. It will not change adds, removes, or
1878 manifest but are not in the dirstate. It will not change adds, removes, or
1860 modified files that are in the working copy parent.
1879 modified files that are in the working copy parent.
1861
1880
1862 One use of this command is to make the next :hg:`status` invocation
1881 One use of this command is to make the next :hg:`status` invocation
1863 check the actual file content.
1882 check the actual file content.
1864 """
1883 """
1865 ctx = scmutil.revsingle(repo, rev)
1884 ctx = scmutil.revsingle(repo, rev)
1866 with repo.wlock():
1885 with repo.wlock():
1867 dirstate = repo.dirstate
1886 dirstate = repo.dirstate
1868 changedfiles = None
1887 changedfiles = None
1869 # See command doc for what minimal does.
1888 # See command doc for what minimal does.
1870 if opts.get(r'minimal'):
1889 if opts.get(r'minimal'):
1871 manifestfiles = set(ctx.manifest().keys())
1890 manifestfiles = set(ctx.manifest().keys())
1872 dirstatefiles = set(dirstate)
1891 dirstatefiles = set(dirstate)
1873 manifestonly = manifestfiles - dirstatefiles
1892 manifestonly = manifestfiles - dirstatefiles
1874 dsonly = dirstatefiles - manifestfiles
1893 dsonly = dirstatefiles - manifestfiles
1875 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1894 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1876 changedfiles = manifestonly | dsnotadded
1895 changedfiles = manifestonly | dsnotadded
1877
1896
1878 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1897 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1879
1898
1880 @command('debugrebuildfncache', [], '')
1899 @command('debugrebuildfncache', [], '')
1881 def debugrebuildfncache(ui, repo):
1900 def debugrebuildfncache(ui, repo):
1882 """rebuild the fncache file"""
1901 """rebuild the fncache file"""
1883 repair.rebuildfncache(ui, repo)
1902 repair.rebuildfncache(ui, repo)
1884
1903
1885 @command('debugrename',
1904 @command('debugrename',
1886 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1905 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1887 _('[-r REV] FILE'))
1906 _('[-r REV] FILE'))
1888 def debugrename(ui, repo, file1, *pats, **opts):
1907 def debugrename(ui, repo, file1, *pats, **opts):
1889 """dump rename information"""
1908 """dump rename information"""
1890
1909
1891 opts = pycompat.byteskwargs(opts)
1910 opts = pycompat.byteskwargs(opts)
1892 ctx = scmutil.revsingle(repo, opts.get('rev'))
1911 ctx = scmutil.revsingle(repo, opts.get('rev'))
1893 m = scmutil.match(ctx, (file1,) + pats, opts)
1912 m = scmutil.match(ctx, (file1,) + pats, opts)
1894 for abs in ctx.walk(m):
1913 for abs in ctx.walk(m):
1895 fctx = ctx[abs]
1914 fctx = ctx[abs]
1896 o = fctx.filelog().renamed(fctx.filenode())
1915 o = fctx.filelog().renamed(fctx.filenode())
1897 rel = m.rel(abs)
1916 rel = m.rel(abs)
1898 if o:
1917 if o:
1899 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1918 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1900 else:
1919 else:
1901 ui.write(_("%s not renamed\n") % rel)
1920 ui.write(_("%s not renamed\n") % rel)
1902
1921
1903 @command('debugrevlog', cmdutil.debugrevlogopts +
1922 @command('debugrevlog', cmdutil.debugrevlogopts +
1904 [('d', 'dump', False, _('dump index data'))],
1923 [('d', 'dump', False, _('dump index data'))],
1905 _('-c|-m|FILE'),
1924 _('-c|-m|FILE'),
1906 optionalrepo=True)
1925 optionalrepo=True)
1907 def debugrevlog(ui, repo, file_=None, **opts):
1926 def debugrevlog(ui, repo, file_=None, **opts):
1908 """show data and statistics about a revlog"""
1927 """show data and statistics about a revlog"""
1909 opts = pycompat.byteskwargs(opts)
1928 opts = pycompat.byteskwargs(opts)
1910 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1929 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1911
1930
1912 if opts.get("dump"):
1931 if opts.get("dump"):
1913 numrevs = len(r)
1932 numrevs = len(r)
1914 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1933 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1915 " rawsize totalsize compression heads chainlen\n"))
1934 " rawsize totalsize compression heads chainlen\n"))
1916 ts = 0
1935 ts = 0
1917 heads = set()
1936 heads = set()
1918
1937
1919 for rev in xrange(numrevs):
1938 for rev in xrange(numrevs):
1920 dbase = r.deltaparent(rev)
1939 dbase = r.deltaparent(rev)
1921 if dbase == -1:
1940 if dbase == -1:
1922 dbase = rev
1941 dbase = rev
1923 cbase = r.chainbase(rev)
1942 cbase = r.chainbase(rev)
1924 clen = r.chainlen(rev)
1943 clen = r.chainlen(rev)
1925 p1, p2 = r.parentrevs(rev)
1944 p1, p2 = r.parentrevs(rev)
1926 rs = r.rawsize(rev)
1945 rs = r.rawsize(rev)
1927 ts = ts + rs
1946 ts = ts + rs
1928 heads -= set(r.parentrevs(rev))
1947 heads -= set(r.parentrevs(rev))
1929 heads.add(rev)
1948 heads.add(rev)
1930 try:
1949 try:
1931 compression = ts / r.end(rev)
1950 compression = ts / r.end(rev)
1932 except ZeroDivisionError:
1951 except ZeroDivisionError:
1933 compression = 0
1952 compression = 0
1934 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1953 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1935 "%11d %5d %8d\n" %
1954 "%11d %5d %8d\n" %
1936 (rev, p1, p2, r.start(rev), r.end(rev),
1955 (rev, p1, p2, r.start(rev), r.end(rev),
1937 r.start(dbase), r.start(cbase),
1956 r.start(dbase), r.start(cbase),
1938 r.start(p1), r.start(p2),
1957 r.start(p1), r.start(p2),
1939 rs, ts, compression, len(heads), clen))
1958 rs, ts, compression, len(heads), clen))
1940 return 0
1959 return 0
1941
1960
1942 v = r.version
1961 v = r.version
1943 format = v & 0xFFFF
1962 format = v & 0xFFFF
1944 flags = []
1963 flags = []
1945 gdelta = False
1964 gdelta = False
1946 if v & revlog.FLAG_INLINE_DATA:
1965 if v & revlog.FLAG_INLINE_DATA:
1947 flags.append('inline')
1966 flags.append('inline')
1948 if v & revlog.FLAG_GENERALDELTA:
1967 if v & revlog.FLAG_GENERALDELTA:
1949 gdelta = True
1968 gdelta = True
1950 flags.append('generaldelta')
1969 flags.append('generaldelta')
1951 if not flags:
1970 if not flags:
1952 flags = ['(none)']
1971 flags = ['(none)']
1953
1972
1954 nummerges = 0
1973 nummerges = 0
1955 numfull = 0
1974 numfull = 0
1956 numprev = 0
1975 numprev = 0
1957 nump1 = 0
1976 nump1 = 0
1958 nump2 = 0
1977 nump2 = 0
1959 numother = 0
1978 numother = 0
1960 nump1prev = 0
1979 nump1prev = 0
1961 nump2prev = 0
1980 nump2prev = 0
1962 chainlengths = []
1981 chainlengths = []
1963 chainbases = []
1982 chainbases = []
1964 chainspans = []
1983 chainspans = []
1965
1984
1966 datasize = [None, 0, 0]
1985 datasize = [None, 0, 0]
1967 fullsize = [None, 0, 0]
1986 fullsize = [None, 0, 0]
1968 deltasize = [None, 0, 0]
1987 deltasize = [None, 0, 0]
1969 chunktypecounts = {}
1988 chunktypecounts = {}
1970 chunktypesizes = {}
1989 chunktypesizes = {}
1971
1990
1972 def addsize(size, l):
1991 def addsize(size, l):
1973 if l[0] is None or size < l[0]:
1992 if l[0] is None or size < l[0]:
1974 l[0] = size
1993 l[0] = size
1975 if size > l[1]:
1994 if size > l[1]:
1976 l[1] = size
1995 l[1] = size
1977 l[2] += size
1996 l[2] += size
1978
1997
1979 numrevs = len(r)
1998 numrevs = len(r)
1980 for rev in xrange(numrevs):
1999 for rev in xrange(numrevs):
1981 p1, p2 = r.parentrevs(rev)
2000 p1, p2 = r.parentrevs(rev)
1982 delta = r.deltaparent(rev)
2001 delta = r.deltaparent(rev)
1983 if format > 0:
2002 if format > 0:
1984 addsize(r.rawsize(rev), datasize)
2003 addsize(r.rawsize(rev), datasize)
1985 if p2 != nullrev:
2004 if p2 != nullrev:
1986 nummerges += 1
2005 nummerges += 1
1987 size = r.length(rev)
2006 size = r.length(rev)
1988 if delta == nullrev:
2007 if delta == nullrev:
1989 chainlengths.append(0)
2008 chainlengths.append(0)
1990 chainbases.append(r.start(rev))
2009 chainbases.append(r.start(rev))
1991 chainspans.append(size)
2010 chainspans.append(size)
1992 numfull += 1
2011 numfull += 1
1993 addsize(size, fullsize)
2012 addsize(size, fullsize)
1994 else:
2013 else:
1995 chainlengths.append(chainlengths[delta] + 1)
2014 chainlengths.append(chainlengths[delta] + 1)
1996 baseaddr = chainbases[delta]
2015 baseaddr = chainbases[delta]
1997 revaddr = r.start(rev)
2016 revaddr = r.start(rev)
1998 chainbases.append(baseaddr)
2017 chainbases.append(baseaddr)
1999 chainspans.append((revaddr - baseaddr) + size)
2018 chainspans.append((revaddr - baseaddr) + size)
2000 addsize(size, deltasize)
2019 addsize(size, deltasize)
2001 if delta == rev - 1:
2020 if delta == rev - 1:
2002 numprev += 1
2021 numprev += 1
2003 if delta == p1:
2022 if delta == p1:
2004 nump1prev += 1
2023 nump1prev += 1
2005 elif delta == p2:
2024 elif delta == p2:
2006 nump2prev += 1
2025 nump2prev += 1
2007 elif delta == p1:
2026 elif delta == p1:
2008 nump1 += 1
2027 nump1 += 1
2009 elif delta == p2:
2028 elif delta == p2:
2010 nump2 += 1
2029 nump2 += 1
2011 elif delta != nullrev:
2030 elif delta != nullrev:
2012 numother += 1
2031 numother += 1
2013
2032
2014 # Obtain data on the raw chunks in the revlog.
2033 # Obtain data on the raw chunks in the revlog.
2015 segment = r._getsegmentforrevs(rev, rev)[1]
2034 segment = r._getsegmentforrevs(rev, rev)[1]
2016 if segment:
2035 if segment:
2017 chunktype = bytes(segment[0:1])
2036 chunktype = bytes(segment[0:1])
2018 else:
2037 else:
2019 chunktype = 'empty'
2038 chunktype = 'empty'
2020
2039
2021 if chunktype not in chunktypecounts:
2040 if chunktype not in chunktypecounts:
2022 chunktypecounts[chunktype] = 0
2041 chunktypecounts[chunktype] = 0
2023 chunktypesizes[chunktype] = 0
2042 chunktypesizes[chunktype] = 0
2024
2043
2025 chunktypecounts[chunktype] += 1
2044 chunktypecounts[chunktype] += 1
2026 chunktypesizes[chunktype] += size
2045 chunktypesizes[chunktype] += size
2027
2046
2028 # Adjust size min value for empty cases
2047 # Adjust size min value for empty cases
2029 for size in (datasize, fullsize, deltasize):
2048 for size in (datasize, fullsize, deltasize):
2030 if size[0] is None:
2049 if size[0] is None:
2031 size[0] = 0
2050 size[0] = 0
2032
2051
2033 numdeltas = numrevs - numfull
2052 numdeltas = numrevs - numfull
2034 numoprev = numprev - nump1prev - nump2prev
2053 numoprev = numprev - nump1prev - nump2prev
2035 totalrawsize = datasize[2]
2054 totalrawsize = datasize[2]
2036 datasize[2] /= numrevs
2055 datasize[2] /= numrevs
2037 fulltotal = fullsize[2]
2056 fulltotal = fullsize[2]
2038 fullsize[2] /= numfull
2057 fullsize[2] /= numfull
2039 deltatotal = deltasize[2]
2058 deltatotal = deltasize[2]
2040 if numrevs - numfull > 0:
2059 if numrevs - numfull > 0:
2041 deltasize[2] /= numrevs - numfull
2060 deltasize[2] /= numrevs - numfull
2042 totalsize = fulltotal + deltatotal
2061 totalsize = fulltotal + deltatotal
2043 avgchainlen = sum(chainlengths) / numrevs
2062 avgchainlen = sum(chainlengths) / numrevs
2044 maxchainlen = max(chainlengths)
2063 maxchainlen = max(chainlengths)
2045 maxchainspan = max(chainspans)
2064 maxchainspan = max(chainspans)
2046 compratio = 1
2065 compratio = 1
2047 if totalsize:
2066 if totalsize:
2048 compratio = totalrawsize / totalsize
2067 compratio = totalrawsize / totalsize
2049
2068
2050 basedfmtstr = '%%%dd\n'
2069 basedfmtstr = '%%%dd\n'
2051 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2070 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2052
2071
2053 def dfmtstr(max):
2072 def dfmtstr(max):
2054 return basedfmtstr % len(str(max))
2073 return basedfmtstr % len(str(max))
2055 def pcfmtstr(max, padding=0):
2074 def pcfmtstr(max, padding=0):
2056 return basepcfmtstr % (len(str(max)), ' ' * padding)
2075 return basepcfmtstr % (len(str(max)), ' ' * padding)
2057
2076
2058 def pcfmt(value, total):
2077 def pcfmt(value, total):
2059 if total:
2078 if total:
2060 return (value, 100 * float(value) / total)
2079 return (value, 100 * float(value) / total)
2061 else:
2080 else:
2062 return value, 100.0
2081 return value, 100.0
2063
2082
2064 ui.write(('format : %d\n') % format)
2083 ui.write(('format : %d\n') % format)
2065 ui.write(('flags : %s\n') % ', '.join(flags))
2084 ui.write(('flags : %s\n') % ', '.join(flags))
2066
2085
2067 ui.write('\n')
2086 ui.write('\n')
2068 fmt = pcfmtstr(totalsize)
2087 fmt = pcfmtstr(totalsize)
2069 fmt2 = dfmtstr(totalsize)
2088 fmt2 = dfmtstr(totalsize)
2070 ui.write(('revisions : ') + fmt2 % numrevs)
2089 ui.write(('revisions : ') + fmt2 % numrevs)
2071 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2090 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2072 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2091 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2073 ui.write(('revisions : ') + fmt2 % numrevs)
2092 ui.write(('revisions : ') + fmt2 % numrevs)
2074 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2093 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2075 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2094 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2076 ui.write(('revision size : ') + fmt2 % totalsize)
2095 ui.write(('revision size : ') + fmt2 % totalsize)
2077 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2096 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2078 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2097 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2079
2098
2080 def fmtchunktype(chunktype):
2099 def fmtchunktype(chunktype):
2081 if chunktype == 'empty':
2100 if chunktype == 'empty':
2082 return ' %s : ' % chunktype
2101 return ' %s : ' % chunktype
2083 elif chunktype in pycompat.bytestr(string.ascii_letters):
2102 elif chunktype in pycompat.bytestr(string.ascii_letters):
2084 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2103 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2085 else:
2104 else:
2086 return ' 0x%s : ' % hex(chunktype)
2105 return ' 0x%s : ' % hex(chunktype)
2087
2106
2088 ui.write('\n')
2107 ui.write('\n')
2089 ui.write(('chunks : ') + fmt2 % numrevs)
2108 ui.write(('chunks : ') + fmt2 % numrevs)
2090 for chunktype in sorted(chunktypecounts):
2109 for chunktype in sorted(chunktypecounts):
2091 ui.write(fmtchunktype(chunktype))
2110 ui.write(fmtchunktype(chunktype))
2092 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2111 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2093 ui.write(('chunks size : ') + fmt2 % totalsize)
2112 ui.write(('chunks size : ') + fmt2 % totalsize)
2094 for chunktype in sorted(chunktypecounts):
2113 for chunktype in sorted(chunktypecounts):
2095 ui.write(fmtchunktype(chunktype))
2114 ui.write(fmtchunktype(chunktype))
2096 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2115 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2097
2116
2098 ui.write('\n')
2117 ui.write('\n')
2099 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2118 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2100 ui.write(('avg chain length : ') + fmt % avgchainlen)
2119 ui.write(('avg chain length : ') + fmt % avgchainlen)
2101 ui.write(('max chain length : ') + fmt % maxchainlen)
2120 ui.write(('max chain length : ') + fmt % maxchainlen)
2102 ui.write(('max chain reach : ') + fmt % maxchainspan)
2121 ui.write(('max chain reach : ') + fmt % maxchainspan)
2103 ui.write(('compression ratio : ') + fmt % compratio)
2122 ui.write(('compression ratio : ') + fmt % compratio)
2104
2123
2105 if format > 0:
2124 if format > 0:
2106 ui.write('\n')
2125 ui.write('\n')
2107 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2126 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2108 % tuple(datasize))
2127 % tuple(datasize))
2109 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2128 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2110 % tuple(fullsize))
2129 % tuple(fullsize))
2111 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2130 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2112 % tuple(deltasize))
2131 % tuple(deltasize))
2113
2132
2114 if numdeltas > 0:
2133 if numdeltas > 0:
2115 ui.write('\n')
2134 ui.write('\n')
2116 fmt = pcfmtstr(numdeltas)
2135 fmt = pcfmtstr(numdeltas)
2117 fmt2 = pcfmtstr(numdeltas, 4)
2136 fmt2 = pcfmtstr(numdeltas, 4)
2118 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2137 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2119 if numprev > 0:
2138 if numprev > 0:
2120 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2139 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2121 numprev))
2140 numprev))
2122 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2141 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2123 numprev))
2142 numprev))
2124 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2143 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2125 numprev))
2144 numprev))
2126 if gdelta:
2145 if gdelta:
2127 ui.write(('deltas against p1 : ')
2146 ui.write(('deltas against p1 : ')
2128 + fmt % pcfmt(nump1, numdeltas))
2147 + fmt % pcfmt(nump1, numdeltas))
2129 ui.write(('deltas against p2 : ')
2148 ui.write(('deltas against p2 : ')
2130 + fmt % pcfmt(nump2, numdeltas))
2149 + fmt % pcfmt(nump2, numdeltas))
2131 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2150 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2132 numdeltas))
2151 numdeltas))
2133
2152
2134 @command('debugrevspec',
2153 @command('debugrevspec',
2135 [('', 'optimize', None,
2154 [('', 'optimize', None,
2136 _('print parsed tree after optimizing (DEPRECATED)')),
2155 _('print parsed tree after optimizing (DEPRECATED)')),
2137 ('', 'show-revs', True, _('print list of result revisions (default)')),
2156 ('', 'show-revs', True, _('print list of result revisions (default)')),
2138 ('s', 'show-set', None, _('print internal representation of result set')),
2157 ('s', 'show-set', None, _('print internal representation of result set')),
2139 ('p', 'show-stage', [],
2158 ('p', 'show-stage', [],
2140 _('print parsed tree at the given stage'), _('NAME')),
2159 _('print parsed tree at the given stage'), _('NAME')),
2141 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2160 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2142 ('', 'verify-optimized', False, _('verify optimized result')),
2161 ('', 'verify-optimized', False, _('verify optimized result')),
2143 ],
2162 ],
2144 ('REVSPEC'))
2163 ('REVSPEC'))
2145 def debugrevspec(ui, repo, expr, **opts):
2164 def debugrevspec(ui, repo, expr, **opts):
2146 """parse and apply a revision specification
2165 """parse and apply a revision specification
2147
2166
2148 Use -p/--show-stage option to print the parsed tree at the given stages.
2167 Use -p/--show-stage option to print the parsed tree at the given stages.
2149 Use -p all to print tree at every stage.
2168 Use -p all to print tree at every stage.
2150
2169
2151 Use --no-show-revs option with -s or -p to print only the set
2170 Use --no-show-revs option with -s or -p to print only the set
2152 representation or the parsed tree respectively.
2171 representation or the parsed tree respectively.
2153
2172
2154 Use --verify-optimized to compare the optimized result with the unoptimized
2173 Use --verify-optimized to compare the optimized result with the unoptimized
2155 one. Returns 1 if the optimized result differs.
2174 one. Returns 1 if the optimized result differs.
2156 """
2175 """
2157 opts = pycompat.byteskwargs(opts)
2176 opts = pycompat.byteskwargs(opts)
2158 aliases = ui.configitems('revsetalias')
2177 aliases = ui.configitems('revsetalias')
2159 stages = [
2178 stages = [
2160 ('parsed', lambda tree: tree),
2179 ('parsed', lambda tree: tree),
2161 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2180 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2162 ui.warn)),
2181 ui.warn)),
2163 ('concatenated', revsetlang.foldconcat),
2182 ('concatenated', revsetlang.foldconcat),
2164 ('analyzed', revsetlang.analyze),
2183 ('analyzed', revsetlang.analyze),
2165 ('optimized', revsetlang.optimize),
2184 ('optimized', revsetlang.optimize),
2166 ]
2185 ]
2167 if opts['no_optimized']:
2186 if opts['no_optimized']:
2168 stages = stages[:-1]
2187 stages = stages[:-1]
2169 if opts['verify_optimized'] and opts['no_optimized']:
2188 if opts['verify_optimized'] and opts['no_optimized']:
2170 raise error.Abort(_('cannot use --verify-optimized with '
2189 raise error.Abort(_('cannot use --verify-optimized with '
2171 '--no-optimized'))
2190 '--no-optimized'))
2172 stagenames = set(n for n, f in stages)
2191 stagenames = set(n for n, f in stages)
2173
2192
2174 showalways = set()
2193 showalways = set()
2175 showchanged = set()
2194 showchanged = set()
2176 if ui.verbose and not opts['show_stage']:
2195 if ui.verbose and not opts['show_stage']:
2177 # show parsed tree by --verbose (deprecated)
2196 # show parsed tree by --verbose (deprecated)
2178 showalways.add('parsed')
2197 showalways.add('parsed')
2179 showchanged.update(['expanded', 'concatenated'])
2198 showchanged.update(['expanded', 'concatenated'])
2180 if opts['optimize']:
2199 if opts['optimize']:
2181 showalways.add('optimized')
2200 showalways.add('optimized')
2182 if opts['show_stage'] and opts['optimize']:
2201 if opts['show_stage'] and opts['optimize']:
2183 raise error.Abort(_('cannot use --optimize with --show-stage'))
2202 raise error.Abort(_('cannot use --optimize with --show-stage'))
2184 if opts['show_stage'] == ['all']:
2203 if opts['show_stage'] == ['all']:
2185 showalways.update(stagenames)
2204 showalways.update(stagenames)
2186 else:
2205 else:
2187 for n in opts['show_stage']:
2206 for n in opts['show_stage']:
2188 if n not in stagenames:
2207 if n not in stagenames:
2189 raise error.Abort(_('invalid stage name: %s') % n)
2208 raise error.Abort(_('invalid stage name: %s') % n)
2190 showalways.update(opts['show_stage'])
2209 showalways.update(opts['show_stage'])
2191
2210
2192 treebystage = {}
2211 treebystage = {}
2193 printedtree = None
2212 printedtree = None
2194 tree = revsetlang.parse(expr, lookup=repo.__contains__)
2213 tree = revsetlang.parse(expr, lookup=repo.__contains__)
2195 for n, f in stages:
2214 for n, f in stages:
2196 treebystage[n] = tree = f(tree)
2215 treebystage[n] = tree = f(tree)
2197 if n in showalways or (n in showchanged and tree != printedtree):
2216 if n in showalways or (n in showchanged and tree != printedtree):
2198 if opts['show_stage'] or n != 'parsed':
2217 if opts['show_stage'] or n != 'parsed':
2199 ui.write(("* %s:\n") % n)
2218 ui.write(("* %s:\n") % n)
2200 ui.write(revsetlang.prettyformat(tree), "\n")
2219 ui.write(revsetlang.prettyformat(tree), "\n")
2201 printedtree = tree
2220 printedtree = tree
2202
2221
2203 if opts['verify_optimized']:
2222 if opts['verify_optimized']:
2204 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2223 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2205 brevs = revset.makematcher(treebystage['optimized'])(repo)
2224 brevs = revset.makematcher(treebystage['optimized'])(repo)
2206 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2225 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2207 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2226 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2208 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2227 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2209 arevs = list(arevs)
2228 arevs = list(arevs)
2210 brevs = list(brevs)
2229 brevs = list(brevs)
2211 if arevs == brevs:
2230 if arevs == brevs:
2212 return 0
2231 return 0
2213 ui.write(('--- analyzed\n'), label='diff.file_a')
2232 ui.write(('--- analyzed\n'), label='diff.file_a')
2214 ui.write(('+++ optimized\n'), label='diff.file_b')
2233 ui.write(('+++ optimized\n'), label='diff.file_b')
2215 sm = difflib.SequenceMatcher(None, arevs, brevs)
2234 sm = difflib.SequenceMatcher(None, arevs, brevs)
2216 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2235 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2217 if tag in ('delete', 'replace'):
2236 if tag in ('delete', 'replace'):
2218 for c in arevs[alo:ahi]:
2237 for c in arevs[alo:ahi]:
2219 ui.write('-%s\n' % c, label='diff.deleted')
2238 ui.write('-%s\n' % c, label='diff.deleted')
2220 if tag in ('insert', 'replace'):
2239 if tag in ('insert', 'replace'):
2221 for c in brevs[blo:bhi]:
2240 for c in brevs[blo:bhi]:
2222 ui.write('+%s\n' % c, label='diff.inserted')
2241 ui.write('+%s\n' % c, label='diff.inserted')
2223 if tag == 'equal':
2242 if tag == 'equal':
2224 for c in arevs[alo:ahi]:
2243 for c in arevs[alo:ahi]:
2225 ui.write(' %s\n' % c)
2244 ui.write(' %s\n' % c)
2226 return 1
2245 return 1
2227
2246
2228 func = revset.makematcher(tree)
2247 func = revset.makematcher(tree)
2229 revs = func(repo)
2248 revs = func(repo)
2230 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2249 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2231 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2250 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2232 if not opts['show_revs']:
2251 if not opts['show_revs']:
2233 return
2252 return
2234 for c in revs:
2253 for c in revs:
2235 ui.write("%d\n" % c)
2254 ui.write("%d\n" % c)
2236
2255
2237 @command('debugserve', [
2256 @command('debugserve', [
2238 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2257 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2239 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2258 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2240 ('', 'logiofile', '', _('file to log server I/O to')),
2259 ('', 'logiofile', '', _('file to log server I/O to')),
2241 ], '')
2260 ], '')
2242 def debugserve(ui, repo, **opts):
2261 def debugserve(ui, repo, **opts):
2243 """run a server with advanced settings
2262 """run a server with advanced settings
2244
2263
2245 This command is similar to :hg:`serve`. It exists partially as a
2264 This command is similar to :hg:`serve`. It exists partially as a
2246 workaround to the fact that ``hg serve --stdio`` must have specific
2265 workaround to the fact that ``hg serve --stdio`` must have specific
2247 arguments for security reasons.
2266 arguments for security reasons.
2248 """
2267 """
2249 opts = pycompat.byteskwargs(opts)
2268 opts = pycompat.byteskwargs(opts)
2250
2269
2251 if not opts['sshstdio']:
2270 if not opts['sshstdio']:
2252 raise error.Abort(_('only --sshstdio is currently supported'))
2271 raise error.Abort(_('only --sshstdio is currently supported'))
2253
2272
2254 logfh = None
2273 logfh = None
2255
2274
2256 if opts['logiofd'] and opts['logiofile']:
2275 if opts['logiofd'] and opts['logiofile']:
2257 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2276 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2258
2277
2259 if opts['logiofd']:
2278 if opts['logiofd']:
2260 # Line buffered because output is line based.
2279 # Line buffered because output is line based.
2261 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2280 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2262 elif opts['logiofile']:
2281 elif opts['logiofile']:
2263 logfh = open(opts['logiofile'], 'ab', 1)
2282 logfh = open(opts['logiofile'], 'ab', 1)
2264
2283
2265 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2284 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2266 s.serve_forever()
2285 s.serve_forever()
2267
2286
2268 @command('debugsetparents', [], _('REV1 [REV2]'))
2287 @command('debugsetparents', [], _('REV1 [REV2]'))
2269 def debugsetparents(ui, repo, rev1, rev2=None):
2288 def debugsetparents(ui, repo, rev1, rev2=None):
2270 """manually set the parents of the current working directory
2289 """manually set the parents of the current working directory
2271
2290
2272 This is useful for writing repository conversion tools, but should
2291 This is useful for writing repository conversion tools, but should
2273 be used with care. For example, neither the working directory nor the
2292 be used with care. For example, neither the working directory nor the
2274 dirstate is updated, so file status may be incorrect after running this
2293 dirstate is updated, so file status may be incorrect after running this
2275 command.
2294 command.
2276
2295
2277 Returns 0 on success.
2296 Returns 0 on success.
2278 """
2297 """
2279
2298
2280 node1 = scmutil.revsingle(repo, rev1).node()
2299 node1 = scmutil.revsingle(repo, rev1).node()
2281 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2300 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2282
2301
2283 with repo.wlock():
2302 with repo.wlock():
2284 repo.setparents(node1, node2)
2303 repo.setparents(node1, node2)
2285
2304
2286 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2305 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2287 def debugssl(ui, repo, source=None, **opts):
2306 def debugssl(ui, repo, source=None, **opts):
2288 '''test a secure connection to a server
2307 '''test a secure connection to a server
2289
2308
2290 This builds the certificate chain for the server on Windows, installing the
2309 This builds the certificate chain for the server on Windows, installing the
2291 missing intermediates and trusted root via Windows Update if necessary. It
2310 missing intermediates and trusted root via Windows Update if necessary. It
2292 does nothing on other platforms.
2311 does nothing on other platforms.
2293
2312
2294 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2313 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2295 that server is used. See :hg:`help urls` for more information.
2314 that server is used. See :hg:`help urls` for more information.
2296
2315
2297 If the update succeeds, retry the original operation. Otherwise, the cause
2316 If the update succeeds, retry the original operation. Otherwise, the cause
2298 of the SSL error is likely another issue.
2317 of the SSL error is likely another issue.
2299 '''
2318 '''
2300 if not pycompat.iswindows:
2319 if not pycompat.iswindows:
2301 raise error.Abort(_('certificate chain building is only possible on '
2320 raise error.Abort(_('certificate chain building is only possible on '
2302 'Windows'))
2321 'Windows'))
2303
2322
2304 if not source:
2323 if not source:
2305 if not repo:
2324 if not repo:
2306 raise error.Abort(_("there is no Mercurial repository here, and no "
2325 raise error.Abort(_("there is no Mercurial repository here, and no "
2307 "server specified"))
2326 "server specified"))
2308 source = "default"
2327 source = "default"
2309
2328
2310 source, branches = hg.parseurl(ui.expandpath(source))
2329 source, branches = hg.parseurl(ui.expandpath(source))
2311 url = util.url(source)
2330 url = util.url(source)
2312 addr = None
2331 addr = None
2313
2332
2314 defaultport = {'https': 443, 'ssh': 22}
2333 defaultport = {'https': 443, 'ssh': 22}
2315 if url.scheme in defaultport:
2334 if url.scheme in defaultport:
2316 try:
2335 try:
2317 addr = (url.host, int(url.port or defaultport[url.scheme]))
2336 addr = (url.host, int(url.port or defaultport[url.scheme]))
2318 except ValueError:
2337 except ValueError:
2319 raise error.Abort(_("malformed port number in URL"))
2338 raise error.Abort(_("malformed port number in URL"))
2320 else:
2339 else:
2321 raise error.Abort(_("only https and ssh connections are supported"))
2340 raise error.Abort(_("only https and ssh connections are supported"))
2322
2341
2323 from . import win32
2342 from . import win32
2324
2343
2325 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2344 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2326 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2345 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2327
2346
2328 try:
2347 try:
2329 s.connect(addr)
2348 s.connect(addr)
2330 cert = s.getpeercert(True)
2349 cert = s.getpeercert(True)
2331
2350
2332 ui.status(_('checking the certificate chain for %s\n') % url.host)
2351 ui.status(_('checking the certificate chain for %s\n') % url.host)
2333
2352
2334 complete = win32.checkcertificatechain(cert, build=False)
2353 complete = win32.checkcertificatechain(cert, build=False)
2335
2354
2336 if not complete:
2355 if not complete:
2337 ui.status(_('certificate chain is incomplete, updating... '))
2356 ui.status(_('certificate chain is incomplete, updating... '))
2338
2357
2339 if not win32.checkcertificatechain(cert):
2358 if not win32.checkcertificatechain(cert):
2340 ui.status(_('failed.\n'))
2359 ui.status(_('failed.\n'))
2341 else:
2360 else:
2342 ui.status(_('done.\n'))
2361 ui.status(_('done.\n'))
2343 else:
2362 else:
2344 ui.status(_('full certificate chain is available\n'))
2363 ui.status(_('full certificate chain is available\n'))
2345 finally:
2364 finally:
2346 s.close()
2365 s.close()
2347
2366
2348 @command('debugsub',
2367 @command('debugsub',
2349 [('r', 'rev', '',
2368 [('r', 'rev', '',
2350 _('revision to check'), _('REV'))],
2369 _('revision to check'), _('REV'))],
2351 _('[-r REV] [REV]'))
2370 _('[-r REV] [REV]'))
2352 def debugsub(ui, repo, rev=None):
2371 def debugsub(ui, repo, rev=None):
2353 ctx = scmutil.revsingle(repo, rev, None)
2372 ctx = scmutil.revsingle(repo, rev, None)
2354 for k, v in sorted(ctx.substate.items()):
2373 for k, v in sorted(ctx.substate.items()):
2355 ui.write(('path %s\n') % k)
2374 ui.write(('path %s\n') % k)
2356 ui.write((' source %s\n') % v[0])
2375 ui.write((' source %s\n') % v[0])
2357 ui.write((' revision %s\n') % v[1])
2376 ui.write((' revision %s\n') % v[1])
2358
2377
2359 @command('debugsuccessorssets',
2378 @command('debugsuccessorssets',
2360 [('', 'closest', False, _('return closest successors sets only'))],
2379 [('', 'closest', False, _('return closest successors sets only'))],
2361 _('[REV]'))
2380 _('[REV]'))
2362 def debugsuccessorssets(ui, repo, *revs, **opts):
2381 def debugsuccessorssets(ui, repo, *revs, **opts):
2363 """show set of successors for revision
2382 """show set of successors for revision
2364
2383
2365 A successors set of changeset A is a consistent group of revisions that
2384 A successors set of changeset A is a consistent group of revisions that
2366 succeed A. It contains non-obsolete changesets only unless closests
2385 succeed A. It contains non-obsolete changesets only unless closests
2367 successors set is set.
2386 successors set is set.
2368
2387
2369 In most cases a changeset A has a single successors set containing a single
2388 In most cases a changeset A has a single successors set containing a single
2370 successor (changeset A replaced by A').
2389 successor (changeset A replaced by A').
2371
2390
2372 A changeset that is made obsolete with no successors are called "pruned".
2391 A changeset that is made obsolete with no successors are called "pruned".
2373 Such changesets have no successors sets at all.
2392 Such changesets have no successors sets at all.
2374
2393
2375 A changeset that has been "split" will have a successors set containing
2394 A changeset that has been "split" will have a successors set containing
2376 more than one successor.
2395 more than one successor.
2377
2396
2378 A changeset that has been rewritten in multiple different ways is called
2397 A changeset that has been rewritten in multiple different ways is called
2379 "divergent". Such changesets have multiple successor sets (each of which
2398 "divergent". Such changesets have multiple successor sets (each of which
2380 may also be split, i.e. have multiple successors).
2399 may also be split, i.e. have multiple successors).
2381
2400
2382 Results are displayed as follows::
2401 Results are displayed as follows::
2383
2402
2384 <rev1>
2403 <rev1>
2385 <successors-1A>
2404 <successors-1A>
2386 <rev2>
2405 <rev2>
2387 <successors-2A>
2406 <successors-2A>
2388 <successors-2B1> <successors-2B2> <successors-2B3>
2407 <successors-2B1> <successors-2B2> <successors-2B3>
2389
2408
2390 Here rev2 has two possible (i.e. divergent) successors sets. The first
2409 Here rev2 has two possible (i.e. divergent) successors sets. The first
2391 holds one element, whereas the second holds three (i.e. the changeset has
2410 holds one element, whereas the second holds three (i.e. the changeset has
2392 been split).
2411 been split).
2393 """
2412 """
2394 # passed to successorssets caching computation from one call to another
2413 # passed to successorssets caching computation from one call to another
2395 cache = {}
2414 cache = {}
2396 ctx2str = bytes
2415 ctx2str = bytes
2397 node2str = short
2416 node2str = short
2398 for rev in scmutil.revrange(repo, revs):
2417 for rev in scmutil.revrange(repo, revs):
2399 ctx = repo[rev]
2418 ctx = repo[rev]
2400 ui.write('%s\n'% ctx2str(ctx))
2419 ui.write('%s\n'% ctx2str(ctx))
2401 for succsset in obsutil.successorssets(repo, ctx.node(),
2420 for succsset in obsutil.successorssets(repo, ctx.node(),
2402 closest=opts[r'closest'],
2421 closest=opts[r'closest'],
2403 cache=cache):
2422 cache=cache):
2404 if succsset:
2423 if succsset:
2405 ui.write(' ')
2424 ui.write(' ')
2406 ui.write(node2str(succsset[0]))
2425 ui.write(node2str(succsset[0]))
2407 for node in succsset[1:]:
2426 for node in succsset[1:]:
2408 ui.write(' ')
2427 ui.write(' ')
2409 ui.write(node2str(node))
2428 ui.write(node2str(node))
2410 ui.write('\n')
2429 ui.write('\n')
2411
2430
2412 @command('debugtemplate',
2431 @command('debugtemplate',
2413 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2432 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2414 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2433 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2415 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2434 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2416 optionalrepo=True)
2435 optionalrepo=True)
2417 def debugtemplate(ui, repo, tmpl, **opts):
2436 def debugtemplate(ui, repo, tmpl, **opts):
2418 """parse and apply a template
2437 """parse and apply a template
2419
2438
2420 If -r/--rev is given, the template is processed as a log template and
2439 If -r/--rev is given, the template is processed as a log template and
2421 applied to the given changesets. Otherwise, it is processed as a generic
2440 applied to the given changesets. Otherwise, it is processed as a generic
2422 template.
2441 template.
2423
2442
2424 Use --verbose to print the parsed tree.
2443 Use --verbose to print the parsed tree.
2425 """
2444 """
2426 revs = None
2445 revs = None
2427 if opts[r'rev']:
2446 if opts[r'rev']:
2428 if repo is None:
2447 if repo is None:
2429 raise error.RepoError(_('there is no Mercurial repository here '
2448 raise error.RepoError(_('there is no Mercurial repository here '
2430 '(.hg not found)'))
2449 '(.hg not found)'))
2431 revs = scmutil.revrange(repo, opts[r'rev'])
2450 revs = scmutil.revrange(repo, opts[r'rev'])
2432
2451
2433 props = {}
2452 props = {}
2434 for d in opts[r'define']:
2453 for d in opts[r'define']:
2435 try:
2454 try:
2436 k, v = (e.strip() for e in d.split('=', 1))
2455 k, v = (e.strip() for e in d.split('=', 1))
2437 if not k or k == 'ui':
2456 if not k or k == 'ui':
2438 raise ValueError
2457 raise ValueError
2439 props[k] = v
2458 props[k] = v
2440 except ValueError:
2459 except ValueError:
2441 raise error.Abort(_('malformed keyword definition: %s') % d)
2460 raise error.Abort(_('malformed keyword definition: %s') % d)
2442
2461
2443 if ui.verbose:
2462 if ui.verbose:
2444 aliases = ui.configitems('templatealias')
2463 aliases = ui.configitems('templatealias')
2445 tree = templater.parse(tmpl)
2464 tree = templater.parse(tmpl)
2446 ui.note(templater.prettyformat(tree), '\n')
2465 ui.note(templater.prettyformat(tree), '\n')
2447 newtree = templater.expandaliases(tree, aliases)
2466 newtree = templater.expandaliases(tree, aliases)
2448 if newtree != tree:
2467 if newtree != tree:
2449 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2468 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2450
2469
2451 if revs is None:
2470 if revs is None:
2452 tres = formatter.templateresources(ui, repo)
2471 tres = formatter.templateresources(ui, repo)
2453 t = formatter.maketemplater(ui, tmpl, resources=tres)
2472 t = formatter.maketemplater(ui, tmpl, resources=tres)
2454 ui.write(t.renderdefault(props))
2473 ui.write(t.renderdefault(props))
2455 else:
2474 else:
2456 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2475 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2457 for r in revs:
2476 for r in revs:
2458 displayer.show(repo[r], **pycompat.strkwargs(props))
2477 displayer.show(repo[r], **pycompat.strkwargs(props))
2459 displayer.close()
2478 displayer.close()
2460
2479
2461 @command('debuguigetpass', [
2480 @command('debuguigetpass', [
2462 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2481 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2463 ], _('[-p TEXT]'), norepo=True)
2482 ], _('[-p TEXT]'), norepo=True)
2464 def debuguigetpass(ui, prompt=''):
2483 def debuguigetpass(ui, prompt=''):
2465 """show prompt to type password"""
2484 """show prompt to type password"""
2466 r = ui.getpass(prompt)
2485 r = ui.getpass(prompt)
2467 ui.write(('respose: %s\n') % r)
2486 ui.write(('respose: %s\n') % r)
2468
2487
2469 @command('debuguiprompt', [
2488 @command('debuguiprompt', [
2470 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2489 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2471 ], _('[-p TEXT]'), norepo=True)
2490 ], _('[-p TEXT]'), norepo=True)
2472 def debuguiprompt(ui, prompt=''):
2491 def debuguiprompt(ui, prompt=''):
2473 """show plain prompt"""
2492 """show plain prompt"""
2474 r = ui.prompt(prompt)
2493 r = ui.prompt(prompt)
2475 ui.write(('response: %s\n') % r)
2494 ui.write(('response: %s\n') % r)
2476
2495
2477 @command('debugupdatecaches', [])
2496 @command('debugupdatecaches', [])
2478 def debugupdatecaches(ui, repo, *pats, **opts):
2497 def debugupdatecaches(ui, repo, *pats, **opts):
2479 """warm all known caches in the repository"""
2498 """warm all known caches in the repository"""
2480 with repo.wlock(), repo.lock():
2499 with repo.wlock(), repo.lock():
2481 repo.updatecaches(full=True)
2500 repo.updatecaches(full=True)
2482
2501
2483 @command('debugupgraderepo', [
2502 @command('debugupgraderepo', [
2484 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2503 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2485 ('', 'run', False, _('performs an upgrade')),
2504 ('', 'run', False, _('performs an upgrade')),
2486 ])
2505 ])
2487 def debugupgraderepo(ui, repo, run=False, optimize=None):
2506 def debugupgraderepo(ui, repo, run=False, optimize=None):
2488 """upgrade a repository to use different features
2507 """upgrade a repository to use different features
2489
2508
2490 If no arguments are specified, the repository is evaluated for upgrade
2509 If no arguments are specified, the repository is evaluated for upgrade
2491 and a list of problems and potential optimizations is printed.
2510 and a list of problems and potential optimizations is printed.
2492
2511
2493 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2512 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2494 can be influenced via additional arguments. More details will be provided
2513 can be influenced via additional arguments. More details will be provided
2495 by the command output when run without ``--run``.
2514 by the command output when run without ``--run``.
2496
2515
2497 During the upgrade, the repository will be locked and no writes will be
2516 During the upgrade, the repository will be locked and no writes will be
2498 allowed.
2517 allowed.
2499
2518
2500 At the end of the upgrade, the repository may not be readable while new
2519 At the end of the upgrade, the repository may not be readable while new
2501 repository data is swapped in. This window will be as long as it takes to
2520 repository data is swapped in. This window will be as long as it takes to
2502 rename some directories inside the ``.hg`` directory. On most machines, this
2521 rename some directories inside the ``.hg`` directory. On most machines, this
2503 should complete almost instantaneously and the chances of a consumer being
2522 should complete almost instantaneously and the chances of a consumer being
2504 unable to access the repository should be low.
2523 unable to access the repository should be low.
2505 """
2524 """
2506 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2525 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2507
2526
2508 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2527 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2509 inferrepo=True)
2528 inferrepo=True)
2510 def debugwalk(ui, repo, *pats, **opts):
2529 def debugwalk(ui, repo, *pats, **opts):
2511 """show how files match on given patterns"""
2530 """show how files match on given patterns"""
2512 opts = pycompat.byteskwargs(opts)
2531 opts = pycompat.byteskwargs(opts)
2513 m = scmutil.match(repo[None], pats, opts)
2532 m = scmutil.match(repo[None], pats, opts)
2514 ui.write(('matcher: %r\n' % m))
2533 ui.write(('matcher: %r\n' % m))
2515 items = list(repo[None].walk(m))
2534 items = list(repo[None].walk(m))
2516 if not items:
2535 if not items:
2517 return
2536 return
2518 f = lambda fn: fn
2537 f = lambda fn: fn
2519 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2538 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2520 f = lambda fn: util.normpath(fn)
2539 f = lambda fn: util.normpath(fn)
2521 fmt = 'f %%-%ds %%-%ds %%s' % (
2540 fmt = 'f %%-%ds %%-%ds %%s' % (
2522 max([len(abs) for abs in items]),
2541 max([len(abs) for abs in items]),
2523 max([len(m.rel(abs)) for abs in items]))
2542 max([len(m.rel(abs)) for abs in items]))
2524 for abs in items:
2543 for abs in items:
2525 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2544 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2526 ui.write("%s\n" % line.rstrip())
2545 ui.write("%s\n" % line.rstrip())
2527
2546
2528 @command('debugwhyunstable', [], _('REV'))
2547 @command('debugwhyunstable', [], _('REV'))
2529 def debugwhyunstable(ui, repo, rev):
2548 def debugwhyunstable(ui, repo, rev):
2530 """explain instabilities of a changeset"""
2549 """explain instabilities of a changeset"""
2531 for entry in obsutil.whyunstable(repo, repo[rev]):
2550 for entry in obsutil.whyunstable(repo, repo[rev]):
2532 dnodes = ''
2551 dnodes = ''
2533 if entry.get('divergentnodes'):
2552 if entry.get('divergentnodes'):
2534 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2553 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2535 for ctx in entry['divergentnodes']) + ' '
2554 for ctx in entry['divergentnodes']) + ' '
2536 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2555 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2537 entry['reason'], entry['node']))
2556 entry['reason'], entry['node']))
2538
2557
2539 @command('debugwireargs',
2558 @command('debugwireargs',
2540 [('', 'three', '', 'three'),
2559 [('', 'three', '', 'three'),
2541 ('', 'four', '', 'four'),
2560 ('', 'four', '', 'four'),
2542 ('', 'five', '', 'five'),
2561 ('', 'five', '', 'five'),
2543 ] + cmdutil.remoteopts,
2562 ] + cmdutil.remoteopts,
2544 _('REPO [OPTIONS]... [ONE [TWO]]'),
2563 _('REPO [OPTIONS]... [ONE [TWO]]'),
2545 norepo=True)
2564 norepo=True)
2546 def debugwireargs(ui, repopath, *vals, **opts):
2565 def debugwireargs(ui, repopath, *vals, **opts):
2547 opts = pycompat.byteskwargs(opts)
2566 opts = pycompat.byteskwargs(opts)
2548 repo = hg.peer(ui, opts, repopath)
2567 repo = hg.peer(ui, opts, repopath)
2549 for opt in cmdutil.remoteopts:
2568 for opt in cmdutil.remoteopts:
2550 del opts[opt[1]]
2569 del opts[opt[1]]
2551 args = {}
2570 args = {}
2552 for k, v in opts.iteritems():
2571 for k, v in opts.iteritems():
2553 if v:
2572 if v:
2554 args[k] = v
2573 args[k] = v
2555 args = pycompat.strkwargs(args)
2574 args = pycompat.strkwargs(args)
2556 # run twice to check that we don't mess up the stream for the next command
2575 # run twice to check that we don't mess up the stream for the next command
2557 res1 = repo.debugwireargs(*vals, **args)
2576 res1 = repo.debugwireargs(*vals, **args)
2558 res2 = repo.debugwireargs(*vals, **args)
2577 res2 = repo.debugwireargs(*vals, **args)
2559 ui.write("%s\n" % res1)
2578 ui.write("%s\n" % res1)
2560 if res1 != res2:
2579 if res1 != res2:
2561 ui.warn("%s\n" % res2)
2580 ui.warn("%s\n" % res2)
2562
2581
2563 def _parsewirelangblocks(fh):
2582 def _parsewirelangblocks(fh):
2564 activeaction = None
2583 activeaction = None
2565 blocklines = []
2584 blocklines = []
2566
2585
2567 for line in fh:
2586 for line in fh:
2568 line = line.rstrip()
2587 line = line.rstrip()
2569 if not line:
2588 if not line:
2570 continue
2589 continue
2571
2590
2572 if line.startswith(b'#'):
2591 if line.startswith(b'#'):
2573 continue
2592 continue
2574
2593
2575 if not line.startswith(' '):
2594 if not line.startswith(' '):
2576 # New block. Flush previous one.
2595 # New block. Flush previous one.
2577 if activeaction:
2596 if activeaction:
2578 yield activeaction, blocklines
2597 yield activeaction, blocklines
2579
2598
2580 activeaction = line
2599 activeaction = line
2581 blocklines = []
2600 blocklines = []
2582 continue
2601 continue
2583
2602
2584 # Else we start with an indent.
2603 # Else we start with an indent.
2585
2604
2586 if not activeaction:
2605 if not activeaction:
2587 raise error.Abort(_('indented line outside of block'))
2606 raise error.Abort(_('indented line outside of block'))
2588
2607
2589 blocklines.append(line)
2608 blocklines.append(line)
2590
2609
2591 # Flush last block.
2610 # Flush last block.
2592 if activeaction:
2611 if activeaction:
2593 yield activeaction, blocklines
2612 yield activeaction, blocklines
2594
2613
2595 @command('debugwireproto',
2614 @command('debugwireproto',
2596 [
2615 [
2597 ('', 'localssh', False, _('start an SSH server for this repo')),
2616 ('', 'localssh', False, _('start an SSH server for this repo')),
2598 ('', 'peer', '', _('construct a specific version of the peer')),
2617 ('', 'peer', '', _('construct a specific version of the peer')),
2599 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2618 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2600 ] + cmdutil.remoteopts,
2619 ] + cmdutil.remoteopts,
2601 _('[PATH]'),
2620 _('[PATH]'),
2602 optionalrepo=True)
2621 optionalrepo=True)
2603 def debugwireproto(ui, repo, path=None, **opts):
2622 def debugwireproto(ui, repo, path=None, **opts):
2604 """send wire protocol commands to a server
2623 """send wire protocol commands to a server
2605
2624
2606 This command can be used to issue wire protocol commands to remote
2625 This command can be used to issue wire protocol commands to remote
2607 peers and to debug the raw data being exchanged.
2626 peers and to debug the raw data being exchanged.
2608
2627
2609 ``--localssh`` will start an SSH server against the current repository
2628 ``--localssh`` will start an SSH server against the current repository
2610 and connect to that. By default, the connection will perform a handshake
2629 and connect to that. By default, the connection will perform a handshake
2611 and establish an appropriate peer instance.
2630 and establish an appropriate peer instance.
2612
2631
2613 ``--peer`` can be used to bypass the handshake protocol and construct a
2632 ``--peer`` can be used to bypass the handshake protocol and construct a
2614 peer instance using the specified class type. Valid values are ``raw``,
2633 peer instance using the specified class type. Valid values are ``raw``,
2615 ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending raw data
2634 ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending raw data
2616 payloads and don't support higher-level command actions.
2635 payloads and don't support higher-level command actions.
2617
2636
2618 ``--noreadstderr`` can be used to disable automatic reading from stderr
2637 ``--noreadstderr`` can be used to disable automatic reading from stderr
2619 of the peer (for SSH connections only). Disabling automatic reading of
2638 of the peer (for SSH connections only). Disabling automatic reading of
2620 stderr is useful for making output more deterministic.
2639 stderr is useful for making output more deterministic.
2621
2640
2622 Commands are issued via a mini language which is specified via stdin.
2641 Commands are issued via a mini language which is specified via stdin.
2623 The language consists of individual actions to perform. An action is
2642 The language consists of individual actions to perform. An action is
2624 defined by a block. A block is defined as a line with no leading
2643 defined by a block. A block is defined as a line with no leading
2625 space followed by 0 or more lines with leading space. Blocks are
2644 space followed by 0 or more lines with leading space. Blocks are
2626 effectively a high-level command with additional metadata.
2645 effectively a high-level command with additional metadata.
2627
2646
2628 Lines beginning with ``#`` are ignored.
2647 Lines beginning with ``#`` are ignored.
2629
2648
2630 The following sections denote available actions.
2649 The following sections denote available actions.
2631
2650
2632 raw
2651 raw
2633 ---
2652 ---
2634
2653
2635 Send raw data to the server.
2654 Send raw data to the server.
2636
2655
2637 The block payload contains the raw data to send as one atomic send
2656 The block payload contains the raw data to send as one atomic send
2638 operation. The data may not actually be delivered in a single system
2657 operation. The data may not actually be delivered in a single system
2639 call: it depends on the abilities of the transport being used.
2658 call: it depends on the abilities of the transport being used.
2640
2659
2641 Each line in the block is de-indented and concatenated. Then, that
2660 Each line in the block is de-indented and concatenated. Then, that
2642 value is evaluated as a Python b'' literal. This allows the use of
2661 value is evaluated as a Python b'' literal. This allows the use of
2643 backslash escaping, etc.
2662 backslash escaping, etc.
2644
2663
2645 raw+
2664 raw+
2646 ----
2665 ----
2647
2666
2648 Behaves like ``raw`` except flushes output afterwards.
2667 Behaves like ``raw`` except flushes output afterwards.
2649
2668
2650 command <X>
2669 command <X>
2651 -----------
2670 -----------
2652
2671
2653 Send a request to run a named command, whose name follows the ``command``
2672 Send a request to run a named command, whose name follows the ``command``
2654 string.
2673 string.
2655
2674
2656 Arguments to the command are defined as lines in this block. The format of
2675 Arguments to the command are defined as lines in this block. The format of
2657 each line is ``<key> <value>``. e.g.::
2676 each line is ``<key> <value>``. e.g.::
2658
2677
2659 command listkeys
2678 command listkeys
2660 namespace bookmarks
2679 namespace bookmarks
2661
2680
2662 Values are interpreted as Python b'' literals. This allows encoding
2681 Values are interpreted as Python b'' literals. This allows encoding
2663 special byte sequences via backslash escaping.
2682 special byte sequences via backslash escaping.
2664
2683
2665 The following arguments have special meaning:
2684 The following arguments have special meaning:
2666
2685
2667 ``PUSHFILE``
2686 ``PUSHFILE``
2668 When defined, the *push* mechanism of the peer will be used instead
2687 When defined, the *push* mechanism of the peer will be used instead
2669 of the static request-response mechanism and the content of the
2688 of the static request-response mechanism and the content of the
2670 file specified in the value of this argument will be sent as the
2689 file specified in the value of this argument will be sent as the
2671 command payload.
2690 command payload.
2672
2691
2673 This can be used to submit a local bundle file to the remote.
2692 This can be used to submit a local bundle file to the remote.
2674
2693
2675 batchbegin
2694 batchbegin
2676 ----------
2695 ----------
2677
2696
2678 Instruct the peer to begin a batched send.
2697 Instruct the peer to begin a batched send.
2679
2698
2680 All ``command`` blocks are queued for execution until the next
2699 All ``command`` blocks are queued for execution until the next
2681 ``batchsubmit`` block.
2700 ``batchsubmit`` block.
2682
2701
2683 batchsubmit
2702 batchsubmit
2684 -----------
2703 -----------
2685
2704
2686 Submit previously queued ``command`` blocks as a batch request.
2705 Submit previously queued ``command`` blocks as a batch request.
2687
2706
2688 This action MUST be paired with a ``batchbegin`` action.
2707 This action MUST be paired with a ``batchbegin`` action.
2689
2708
2690 httprequest <method> <path>
2709 httprequest <method> <path>
2691 ---------------------------
2710 ---------------------------
2692
2711
2693 (HTTP peer only)
2712 (HTTP peer only)
2694
2713
2695 Send an HTTP request to the peer.
2714 Send an HTTP request to the peer.
2696
2715
2697 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2716 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2698
2717
2699 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2718 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2700 headers to add to the request. e.g. ``Accept: foo``.
2719 headers to add to the request. e.g. ``Accept: foo``.
2701
2720
2702 The following arguments are special:
2721 The following arguments are special:
2703
2722
2704 ``BODYFILE``
2723 ``BODYFILE``
2705 The content of the file defined as the value to this argument will be
2724 The content of the file defined as the value to this argument will be
2706 transferred verbatim as the HTTP request body.
2725 transferred verbatim as the HTTP request body.
2707
2726
2708 ``frame <type> <flags> <payload>``
2727 ``frame <type> <flags> <payload>``
2709 Send a unified protocol frame as part of the request body.
2728 Send a unified protocol frame as part of the request body.
2710
2729
2711 All frames will be collected and sent as the body to the HTTP
2730 All frames will be collected and sent as the body to the HTTP
2712 request.
2731 request.
2713
2732
2714 close
2733 close
2715 -----
2734 -----
2716
2735
2717 Close the connection to the server.
2736 Close the connection to the server.
2718
2737
2719 flush
2738 flush
2720 -----
2739 -----
2721
2740
2722 Flush data written to the server.
2741 Flush data written to the server.
2723
2742
2724 readavailable
2743 readavailable
2725 -------------
2744 -------------
2726
2745
2727 Close the write end of the connection and read all available data from
2746 Close the write end of the connection and read all available data from
2728 the server.
2747 the server.
2729
2748
2730 If the connection to the server encompasses multiple pipes, we poll both
2749 If the connection to the server encompasses multiple pipes, we poll both
2731 pipes and read available data.
2750 pipes and read available data.
2732
2751
2733 readline
2752 readline
2734 --------
2753 --------
2735
2754
2736 Read a line of output from the server. If there are multiple output
2755 Read a line of output from the server. If there are multiple output
2737 pipes, reads only the main pipe.
2756 pipes, reads only the main pipe.
2738
2757
2739 ereadline
2758 ereadline
2740 ---------
2759 ---------
2741
2760
2742 Like ``readline``, but read from the stderr pipe, if available.
2761 Like ``readline``, but read from the stderr pipe, if available.
2743
2762
2744 read <X>
2763 read <X>
2745 --------
2764 --------
2746
2765
2747 ``read()`` N bytes from the server's main output pipe.
2766 ``read()`` N bytes from the server's main output pipe.
2748
2767
2749 eread <X>
2768 eread <X>
2750 ---------
2769 ---------
2751
2770
2752 ``read()`` N bytes from the server's stderr pipe, if available.
2771 ``read()`` N bytes from the server's stderr pipe, if available.
2753
2772
2754 Specifying Unified Frame-Based Protocol Frames
2773 Specifying Unified Frame-Based Protocol Frames
2755 ----------------------------------------------
2774 ----------------------------------------------
2756
2775
2757 It is possible to emit a *Unified Frame-Based Protocol* by using special
2776 It is possible to emit a *Unified Frame-Based Protocol* by using special
2758 syntax.
2777 syntax.
2759
2778
2760 A frame is composed as a type, flags, and payload. These can be parsed
2779 A frame is composed as a type, flags, and payload. These can be parsed
2761 from a string of the form ``<requestid> <type> <flags> <payload>``. That is,
2780 from a string of the form ``<requestid> <type> <flags> <payload>``. That is,
2762 4 space-delimited strings.
2781 4 space-delimited strings.
2763
2782
2764 ``payload`` is the simplest: it is evaluated as a Python byte string
2783 ``payload`` is the simplest: it is evaluated as a Python byte string
2765 literal.
2784 literal.
2766
2785
2767 ``requestid`` is an integer defining the request identifier.
2786 ``requestid`` is an integer defining the request identifier.
2768
2787
2769 ``type`` can be an integer value for the frame type or the string name
2788 ``type`` can be an integer value for the frame type or the string name
2770 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
2789 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
2771 ``command-name``.
2790 ``command-name``.
2772
2791
2773 ``flags`` is a ``|`` delimited list of flag components. Each component
2792 ``flags`` is a ``|`` delimited list of flag components. Each component
2774 (and there can be just one) can be an integer or a flag name for the
2793 (and there can be just one) can be an integer or a flag name for the
2775 specified frame type. Values are resolved to integers and then bitwise
2794 specified frame type. Values are resolved to integers and then bitwise
2776 OR'd together.
2795 OR'd together.
2777 """
2796 """
2778 opts = pycompat.byteskwargs(opts)
2797 opts = pycompat.byteskwargs(opts)
2779
2798
2780 if opts['localssh'] and not repo:
2799 if opts['localssh'] and not repo:
2781 raise error.Abort(_('--localssh requires a repository'))
2800 raise error.Abort(_('--localssh requires a repository'))
2782
2801
2783 if opts['peer'] and opts['peer'] not in ('raw', 'ssh1', 'ssh2'):
2802 if opts['peer'] and opts['peer'] not in ('raw', 'ssh1', 'ssh2'):
2784 raise error.Abort(_('invalid value for --peer'),
2803 raise error.Abort(_('invalid value for --peer'),
2785 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2804 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2786
2805
2787 if path and opts['localssh']:
2806 if path and opts['localssh']:
2788 raise error.Abort(_('cannot specify --localssh with an explicit '
2807 raise error.Abort(_('cannot specify --localssh with an explicit '
2789 'path'))
2808 'path'))
2790
2809
2791 if ui.interactive():
2810 if ui.interactive():
2792 ui.write(_('(waiting for commands on stdin)\n'))
2811 ui.write(_('(waiting for commands on stdin)\n'))
2793
2812
2794 blocks = list(_parsewirelangblocks(ui.fin))
2813 blocks = list(_parsewirelangblocks(ui.fin))
2795
2814
2796 proc = None
2815 proc = None
2797 stdin = None
2816 stdin = None
2798 stdout = None
2817 stdout = None
2799 stderr = None
2818 stderr = None
2800 opener = None
2819 opener = None
2801
2820
2802 if opts['localssh']:
2821 if opts['localssh']:
2803 # We start the SSH server in its own process so there is process
2822 # We start the SSH server in its own process so there is process
2804 # separation. This prevents a whole class of potential bugs around
2823 # separation. This prevents a whole class of potential bugs around
2805 # shared state from interfering with server operation.
2824 # shared state from interfering with server operation.
2806 args = procutil.hgcmd() + [
2825 args = procutil.hgcmd() + [
2807 '-R', repo.root,
2826 '-R', repo.root,
2808 'debugserve', '--sshstdio',
2827 'debugserve', '--sshstdio',
2809 ]
2828 ]
2810 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2829 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2811 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2830 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2812 bufsize=0)
2831 bufsize=0)
2813
2832
2814 stdin = proc.stdin
2833 stdin = proc.stdin
2815 stdout = proc.stdout
2834 stdout = proc.stdout
2816 stderr = proc.stderr
2835 stderr = proc.stderr
2817
2836
2818 # We turn the pipes into observers so we can log I/O.
2837 # We turn the pipes into observers so we can log I/O.
2819 if ui.verbose or opts['peer'] == 'raw':
2838 if ui.verbose or opts['peer'] == 'raw':
2820 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2839 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2821 logdata=True)
2840 logdata=True)
2822 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2841 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2823 logdata=True)
2842 logdata=True)
2824 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2843 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2825 logdata=True)
2844 logdata=True)
2826
2845
2827 # --localssh also implies the peer connection settings.
2846 # --localssh also implies the peer connection settings.
2828
2847
2829 url = 'ssh://localserver'
2848 url = 'ssh://localserver'
2830 autoreadstderr = not opts['noreadstderr']
2849 autoreadstderr = not opts['noreadstderr']
2831
2850
2832 if opts['peer'] == 'ssh1':
2851 if opts['peer'] == 'ssh1':
2833 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2852 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2834 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2853 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2835 None, autoreadstderr=autoreadstderr)
2854 None, autoreadstderr=autoreadstderr)
2836 elif opts['peer'] == 'ssh2':
2855 elif opts['peer'] == 'ssh2':
2837 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2856 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2838 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2857 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2839 None, autoreadstderr=autoreadstderr)
2858 None, autoreadstderr=autoreadstderr)
2840 elif opts['peer'] == 'raw':
2859 elif opts['peer'] == 'raw':
2841 ui.write(_('using raw connection to peer\n'))
2860 ui.write(_('using raw connection to peer\n'))
2842 peer = None
2861 peer = None
2843 else:
2862 else:
2844 ui.write(_('creating ssh peer from handshake results\n'))
2863 ui.write(_('creating ssh peer from handshake results\n'))
2845 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
2864 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
2846 autoreadstderr=autoreadstderr)
2865 autoreadstderr=autoreadstderr)
2847
2866
2848 elif path:
2867 elif path:
2849 # We bypass hg.peer() so we can proxy the sockets.
2868 # We bypass hg.peer() so we can proxy the sockets.
2850 # TODO consider not doing this because we skip
2869 # TODO consider not doing this because we skip
2851 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
2870 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
2852 u = util.url(path)
2871 u = util.url(path)
2853 if u.scheme != 'http':
2872 if u.scheme != 'http':
2854 raise error.Abort(_('only http:// paths are currently supported'))
2873 raise error.Abort(_('only http:// paths are currently supported'))
2855
2874
2856 url, authinfo = u.authinfo()
2875 url, authinfo = u.authinfo()
2857 openerargs = {}
2876 openerargs = {}
2858
2877
2859 # Turn pipes/sockets into observers so we can log I/O.
2878 # Turn pipes/sockets into observers so we can log I/O.
2860 if ui.verbose:
2879 if ui.verbose:
2861 openerargs = {
2880 openerargs = {
2862 r'loggingfh': ui,
2881 r'loggingfh': ui,
2863 r'loggingname': b's',
2882 r'loggingname': b's',
2864 r'loggingopts': {
2883 r'loggingopts': {
2865 r'logdata': True,
2884 r'logdata': True,
2866 r'logdataapis': False,
2885 r'logdataapis': False,
2867 },
2886 },
2868 }
2887 }
2869
2888
2870 if ui.debugflag:
2889 if ui.debugflag:
2871 openerargs[r'loggingopts'][r'logdataapis'] = True
2890 openerargs[r'loggingopts'][r'logdataapis'] = True
2872
2891
2873 # Don't send default headers when in raw mode. This allows us to
2892 # Don't send default headers when in raw mode. This allows us to
2874 # bypass most of the behavior of our URL handling code so we can
2893 # bypass most of the behavior of our URL handling code so we can
2875 # have near complete control over what's sent on the wire.
2894 # have near complete control over what's sent on the wire.
2876 if opts['peer'] == 'raw':
2895 if opts['peer'] == 'raw':
2877 openerargs[r'sendaccept'] = False
2896 openerargs[r'sendaccept'] = False
2878
2897
2879 opener = urlmod.opener(ui, authinfo, **openerargs)
2898 opener = urlmod.opener(ui, authinfo, **openerargs)
2880
2899
2881 if opts['peer'] == 'raw':
2900 if opts['peer'] == 'raw':
2882 ui.write(_('using raw connection to peer\n'))
2901 ui.write(_('using raw connection to peer\n'))
2883 peer = None
2902 peer = None
2884 elif opts['peer']:
2903 elif opts['peer']:
2885 raise error.Abort(_('--peer %s not supported with HTTP peers') %
2904 raise error.Abort(_('--peer %s not supported with HTTP peers') %
2886 opts['peer'])
2905 opts['peer'])
2887 else:
2906 else:
2888 peer = httppeer.httppeer(ui, path, url, opener)
2907 peer = httppeer.httppeer(ui, path, url, opener)
2889 peer._fetchcaps()
2908 peer._fetchcaps()
2890
2909
2891 # We /could/ populate stdin/stdout with sock.makefile()...
2910 # We /could/ populate stdin/stdout with sock.makefile()...
2892 else:
2911 else:
2893 raise error.Abort(_('unsupported connection configuration'))
2912 raise error.Abort(_('unsupported connection configuration'))
2894
2913
2895 batchedcommands = None
2914 batchedcommands = None
2896
2915
2897 # Now perform actions based on the parsed wire language instructions.
2916 # Now perform actions based on the parsed wire language instructions.
2898 for action, lines in blocks:
2917 for action, lines in blocks:
2899 if action in ('raw', 'raw+'):
2918 if action in ('raw', 'raw+'):
2900 if not stdin:
2919 if not stdin:
2901 raise error.Abort(_('cannot call raw/raw+ on this peer'))
2920 raise error.Abort(_('cannot call raw/raw+ on this peer'))
2902
2921
2903 # Concatenate the data together.
2922 # Concatenate the data together.
2904 data = ''.join(l.lstrip() for l in lines)
2923 data = ''.join(l.lstrip() for l in lines)
2905 data = stringutil.unescapestr(data)
2924 data = stringutil.unescapestr(data)
2906 stdin.write(data)
2925 stdin.write(data)
2907
2926
2908 if action == 'raw+':
2927 if action == 'raw+':
2909 stdin.flush()
2928 stdin.flush()
2910 elif action == 'flush':
2929 elif action == 'flush':
2911 if not stdin:
2930 if not stdin:
2912 raise error.Abort(_('cannot call flush on this peer'))
2931 raise error.Abort(_('cannot call flush on this peer'))
2913 stdin.flush()
2932 stdin.flush()
2914 elif action.startswith('command'):
2933 elif action.startswith('command'):
2915 if not peer:
2934 if not peer:
2916 raise error.Abort(_('cannot send commands unless peer instance '
2935 raise error.Abort(_('cannot send commands unless peer instance '
2917 'is available'))
2936 'is available'))
2918
2937
2919 command = action.split(' ', 1)[1]
2938 command = action.split(' ', 1)[1]
2920
2939
2921 args = {}
2940 args = {}
2922 for line in lines:
2941 for line in lines:
2923 # We need to allow empty values.
2942 # We need to allow empty values.
2924 fields = line.lstrip().split(' ', 1)
2943 fields = line.lstrip().split(' ', 1)
2925 if len(fields) == 1:
2944 if len(fields) == 1:
2926 key = fields[0]
2945 key = fields[0]
2927 value = ''
2946 value = ''
2928 else:
2947 else:
2929 key, value = fields
2948 key, value = fields
2930
2949
2931 args[key] = stringutil.unescapestr(value)
2950 args[key] = stringutil.unescapestr(value)
2932
2951
2933 if batchedcommands is not None:
2952 if batchedcommands is not None:
2934 batchedcommands.append((command, args))
2953 batchedcommands.append((command, args))
2935 continue
2954 continue
2936
2955
2937 ui.status(_('sending %s command\n') % command)
2956 ui.status(_('sending %s command\n') % command)
2938
2957
2939 if 'PUSHFILE' in args:
2958 if 'PUSHFILE' in args:
2940 with open(args['PUSHFILE'], r'rb') as fh:
2959 with open(args['PUSHFILE'], r'rb') as fh:
2941 del args['PUSHFILE']
2960 del args['PUSHFILE']
2942 res, output = peer._callpush(command, fh,
2961 res, output = peer._callpush(command, fh,
2943 **pycompat.strkwargs(args))
2962 **pycompat.strkwargs(args))
2944 ui.status(_('result: %s\n') % stringutil.escapedata(res))
2963 ui.status(_('result: %s\n') % stringutil.escapedata(res))
2945 ui.status(_('remote output: %s\n') %
2964 ui.status(_('remote output: %s\n') %
2946 stringutil.escapedata(output))
2965 stringutil.escapedata(output))
2947 else:
2966 else:
2948 res = peer._call(command, **pycompat.strkwargs(args))
2967 res = peer._call(command, **pycompat.strkwargs(args))
2949 ui.status(_('response: %s\n') % stringutil.escapedata(res))
2968 ui.status(_('response: %s\n') % stringutil.escapedata(res))
2950
2969
2951 elif action == 'batchbegin':
2970 elif action == 'batchbegin':
2952 if batchedcommands is not None:
2971 if batchedcommands is not None:
2953 raise error.Abort(_('nested batchbegin not allowed'))
2972 raise error.Abort(_('nested batchbegin not allowed'))
2954
2973
2955 batchedcommands = []
2974 batchedcommands = []
2956 elif action == 'batchsubmit':
2975 elif action == 'batchsubmit':
2957 # There is a batching API we could go through. But it would be
2976 # There is a batching API we could go through. But it would be
2958 # difficult to normalize requests into function calls. It is easier
2977 # difficult to normalize requests into function calls. It is easier
2959 # to bypass this layer and normalize to commands + args.
2978 # to bypass this layer and normalize to commands + args.
2960 ui.status(_('sending batch with %d sub-commands\n') %
2979 ui.status(_('sending batch with %d sub-commands\n') %
2961 len(batchedcommands))
2980 len(batchedcommands))
2962 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
2981 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
2963 ui.status(_('response #%d: %s\n') %
2982 ui.status(_('response #%d: %s\n') %
2964 (i, stringutil.escapedata(chunk)))
2983 (i, stringutil.escapedata(chunk)))
2965
2984
2966 batchedcommands = None
2985 batchedcommands = None
2967
2986
2968 elif action.startswith('httprequest '):
2987 elif action.startswith('httprequest '):
2969 if not opener:
2988 if not opener:
2970 raise error.Abort(_('cannot use httprequest without an HTTP '
2989 raise error.Abort(_('cannot use httprequest without an HTTP '
2971 'peer'))
2990 'peer'))
2972
2991
2973 request = action.split(' ', 2)
2992 request = action.split(' ', 2)
2974 if len(request) != 3:
2993 if len(request) != 3:
2975 raise error.Abort(_('invalid httprequest: expected format is '
2994 raise error.Abort(_('invalid httprequest: expected format is '
2976 '"httprequest <method> <path>'))
2995 '"httprequest <method> <path>'))
2977
2996
2978 method, httppath = request[1:]
2997 method, httppath = request[1:]
2979 headers = {}
2998 headers = {}
2980 body = None
2999 body = None
2981 frames = []
3000 frames = []
2982 for line in lines:
3001 for line in lines:
2983 line = line.lstrip()
3002 line = line.lstrip()
2984 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
3003 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
2985 if m:
3004 if m:
2986 headers[m.group(1)] = m.group(2)
3005 headers[m.group(1)] = m.group(2)
2987 continue
3006 continue
2988
3007
2989 if line.startswith(b'BODYFILE '):
3008 if line.startswith(b'BODYFILE '):
2990 with open(line.split(b' ', 1), 'rb') as fh:
3009 with open(line.split(b' ', 1), 'rb') as fh:
2991 body = fh.read()
3010 body = fh.read()
2992 elif line.startswith(b'frame '):
3011 elif line.startswith(b'frame '):
2993 frame = wireprotoframing.makeframefromhumanstring(
3012 frame = wireprotoframing.makeframefromhumanstring(
2994 line[len(b'frame '):])
3013 line[len(b'frame '):])
2995
3014
2996 frames.append(frame)
3015 frames.append(frame)
2997 else:
3016 else:
2998 raise error.Abort(_('unknown argument to httprequest: %s') %
3017 raise error.Abort(_('unknown argument to httprequest: %s') %
2999 line)
3018 line)
3000
3019
3001 url = path + httppath
3020 url = path + httppath
3002
3021
3003 if frames:
3022 if frames:
3004 body = b''.join(bytes(f) for f in frames)
3023 body = b''.join(bytes(f) for f in frames)
3005
3024
3006 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3025 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3007
3026
3008 # urllib.Request insists on using has_data() as a proxy for
3027 # urllib.Request insists on using has_data() as a proxy for
3009 # determining the request method. Override that to use our
3028 # determining the request method. Override that to use our
3010 # explicitly requested method.
3029 # explicitly requested method.
3011 req.get_method = lambda: method
3030 req.get_method = lambda: method
3012
3031
3013 try:
3032 try:
3014 opener.open(req).read()
3033 opener.open(req).read()
3015 except util.urlerr.urlerror as e:
3034 except util.urlerr.urlerror as e:
3016 e.read()
3035 e.read()
3017
3036
3018 elif action == 'close':
3037 elif action == 'close':
3019 peer.close()
3038 peer.close()
3020 elif action == 'readavailable':
3039 elif action == 'readavailable':
3021 if not stdout or not stderr:
3040 if not stdout or not stderr:
3022 raise error.Abort(_('readavailable not available on this peer'))
3041 raise error.Abort(_('readavailable not available on this peer'))
3023
3042
3024 stdin.close()
3043 stdin.close()
3025 stdout.read()
3044 stdout.read()
3026 stderr.read()
3045 stderr.read()
3027
3046
3028 elif action == 'readline':
3047 elif action == 'readline':
3029 if not stdout:
3048 if not stdout:
3030 raise error.Abort(_('readline not available on this peer'))
3049 raise error.Abort(_('readline not available on this peer'))
3031 stdout.readline()
3050 stdout.readline()
3032 elif action == 'ereadline':
3051 elif action == 'ereadline':
3033 if not stderr:
3052 if not stderr:
3034 raise error.Abort(_('ereadline not available on this peer'))
3053 raise error.Abort(_('ereadline not available on this peer'))
3035 stderr.readline()
3054 stderr.readline()
3036 elif action.startswith('read '):
3055 elif action.startswith('read '):
3037 count = int(action.split(' ', 1)[1])
3056 count = int(action.split(' ', 1)[1])
3038 if not stdout:
3057 if not stdout:
3039 raise error.Abort(_('read not available on this peer'))
3058 raise error.Abort(_('read not available on this peer'))
3040 stdout.read(count)
3059 stdout.read(count)
3041 elif action.startswith('eread '):
3060 elif action.startswith('eread '):
3042 count = int(action.split(' ', 1)[1])
3061 count = int(action.split(' ', 1)[1])
3043 if not stderr:
3062 if not stderr:
3044 raise error.Abort(_('eread not available on this peer'))
3063 raise error.Abort(_('eread not available on this peer'))
3045 stderr.read(count)
3064 stderr.read(count)
3046 else:
3065 else:
3047 raise error.Abort(_('unknown action: %s') % action)
3066 raise error.Abort(_('unknown action: %s') % action)
3048
3067
3049 if batchedcommands is not None:
3068 if batchedcommands is not None:
3050 raise error.Abort(_('unclosed "batchbegin" request'))
3069 raise error.Abort(_('unclosed "batchbegin" request'))
3051
3070
3052 if peer:
3071 if peer:
3053 peer.close()
3072 peer.close()
3054
3073
3055 if proc:
3074 if proc:
3056 proc.kill()
3075 proc.kill()
@@ -1,57 +1,57 b''
1 #require execbit
1 #require execbit
2
2
3 b51a8138292a introduced a regression where we would mention in the
3 b51a8138292a introduced a regression where we would mention in the
4 changelog executable files added by the second parent of a merge. Test
4 changelog executable files added by the second parent of a merge. Test
5 that that doesn't happen anymore
5 that that doesn't happen anymore
6
6
7 $ hg init repo
7 $ hg init repo
8 $ cd repo
8 $ cd repo
9 $ echo foo > foo
9 $ echo foo > foo
10 $ hg ci -qAm 'add foo'
10 $ hg ci -qAm 'add foo'
11
11
12 $ echo bar > bar
12 $ echo bar > bar
13 $ chmod +x bar
13 $ chmod +x bar
14 $ hg ci -qAm 'add bar'
14 $ hg ci -qAm 'add bar'
15
15
16 manifest of p2:
16 manifest of p2:
17
17
18 $ hg manifest
18 $ hg manifest
19 bar
19 bar
20 foo
20 foo
21
21
22 $ hg up -qC 0
22 $ hg up -qC 0
23 $ echo >> foo
23 $ echo >> foo
24 $ hg ci -m 'change foo'
24 $ hg ci -m 'change foo'
25 created new head
25 created new head
26
26
27 manifest of p1:
27 manifest of p1:
28
28
29 $ hg manifest
29 $ hg manifest
30 foo
30 foo
31
31
32 $ hg merge
32 $ hg merge
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 (branch merge, don't forget to commit)
34 (branch merge, don't forget to commit)
35 $ chmod +x foo
35 $ chmod +x foo
36 $ hg ci -m 'merge'
36 $ hg ci -m 'merge'
37
37
38 this should not mention bar but should mention foo:
38 this should not mention bar but should mention foo:
39
39
40 $ hg tip -v
40 $ hg tip -v
41 changeset: 3:c53d17ff3380
41 changeset: 3:c53d17ff3380
42 tag: tip
42 tag: tip
43 parent: 2:ed1b79f46b9a
43 parent: 2:ed1b79f46b9a
44 parent: 1:d394a8db219b
44 parent: 1:d394a8db219b
45 user: test
45 user: test
46 date: Thu Jan 01 00:00:00 1970 +0000
46 date: Thu Jan 01 00:00:00 1970 +0000
47 files: foo
47 files: foo
48 description:
48 description:
49 merge
49 merge
50
50
51
51
52
52
53 $ hg debugindex bar
53 $ hg debugindex bar
54 rev offset length linkrev nodeid p1 p2
54 rev linkrev nodeid p1 p2
55 0 0 5 1 b004912a8510 000000000000 000000000000
55 0 1 b004912a8510 000000000000 000000000000
56
56
57 $ cd ..
57 $ cd ..
@@ -1,254 +1,254 b''
1 $ hg init test
1 $ hg init test
2 $ cd test
2 $ cd test
3
3
4 $ echo 0 >> afile
4 $ echo 0 >> afile
5 $ hg add afile
5 $ hg add afile
6 $ hg commit -m "0.0"
6 $ hg commit -m "0.0"
7
7
8 $ echo 1 >> afile
8 $ echo 1 >> afile
9 $ hg commit -m "0.1"
9 $ hg commit -m "0.1"
10
10
11 $ echo 2 >> afile
11 $ echo 2 >> afile
12 $ hg commit -m "0.2"
12 $ hg commit -m "0.2"
13
13
14 $ echo 3 >> afile
14 $ echo 3 >> afile
15 $ hg commit -m "0.3"
15 $ hg commit -m "0.3"
16
16
17 $ hg update -C 0
17 $ hg update -C 0
18 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
18 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
19
19
20 $ echo 1 >> afile
20 $ echo 1 >> afile
21 $ hg commit -m "1.1"
21 $ hg commit -m "1.1"
22 created new head
22 created new head
23
23
24 $ echo 2 >> afile
24 $ echo 2 >> afile
25 $ hg commit -m "1.2"
25 $ hg commit -m "1.2"
26
26
27 $ echo a line > fred
27 $ echo a line > fred
28 $ echo 3 >> afile
28 $ echo 3 >> afile
29 $ hg add fred
29 $ hg add fred
30 $ hg commit -m "1.3"
30 $ hg commit -m "1.3"
31 $ hg mv afile adifferentfile
31 $ hg mv afile adifferentfile
32 $ hg commit -m "1.3m"
32 $ hg commit -m "1.3m"
33
33
34 $ hg update -C 3
34 $ hg update -C 3
35 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
35 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
36
36
37 $ hg mv afile anotherfile
37 $ hg mv afile anotherfile
38 $ hg commit -m "0.3m"
38 $ hg commit -m "0.3m"
39
39
40 $ hg debugindex -f 1 afile
40 $ hg debugindex -f 1 afile
41 rev flag offset length size link p1 p2 nodeid
41 rev flag size link p1 p2 nodeid
42 0 0000 0 3 2 0 -1 -1 362fef284ce2
42 0 0000 2 0 -1 -1 362fef284ce2
43 1 0000 3 5 4 1 0 -1 125144f7e028
43 1 0000 4 1 0 -1 125144f7e028
44 2 0000 8 7 6 2 1 -1 4c982badb186
44 2 0000 6 2 1 -1 4c982badb186
45 3 0000 15 9 8 3 2 -1 19b1fc555737
45 3 0000 8 3 2 -1 19b1fc555737
46
46
47 $ hg debugindex adifferentfile
47 $ hg debugindex adifferentfile
48 rev offset length linkrev nodeid p1 p2
48 rev linkrev nodeid p1 p2
49 0 0 75 7 2565f3199a74 000000000000 000000000000
49 0 7 2565f3199a74 000000000000 000000000000
50
50
51 $ hg debugindex anotherfile
51 $ hg debugindex anotherfile
52 rev offset length linkrev nodeid p1 p2
52 rev linkrev nodeid p1 p2
53 0 0 75 8 2565f3199a74 000000000000 000000000000
53 0 8 2565f3199a74 000000000000 000000000000
54
54
55 $ hg debugindex fred
55 $ hg debugindex fred
56 rev offset length linkrev nodeid p1 p2
56 rev linkrev nodeid p1 p2
57 0 0 8 6 12ab3bcc5ea4 000000000000 000000000000
57 0 6 12ab3bcc5ea4 000000000000 000000000000
58
58
59 $ hg debugindex --manifest
59 $ hg debugindex --manifest
60 rev offset length linkrev nodeid p1 p2
60 rev linkrev nodeid p1 p2
61 0 0 48 0 43eadb1d2d06 000000000000 000000000000
61 0 0 43eadb1d2d06 000000000000 000000000000
62 1 48 48 1 8b89697eba2c 43eadb1d2d06 000000000000
62 1 1 8b89697eba2c 43eadb1d2d06 000000000000
63 2 96 48 2 626a32663c2f 8b89697eba2c 000000000000
63 2 2 626a32663c2f 8b89697eba2c 000000000000
64 3 144 48 3 f54c32f13478 626a32663c2f 000000000000
64 3 3 f54c32f13478 626a32663c2f 000000000000
65 4 192 .. 6 de68e904d169 626a32663c2f 000000000000 (re)
65 4 6 de68e904d169 626a32663c2f 000000000000
66 5 2.. .. 7 09bb521d218d de68e904d169 000000000000 (re)
66 5 7 09bb521d218d de68e904d169 000000000000
67 6 3.. 54 8 1fde233dfb0f f54c32f13478 000000000000 (re)
67 6 8 1fde233dfb0f f54c32f13478 000000000000
68
68
69 $ hg verify
69 $ hg verify
70 checking changesets
70 checking changesets
71 checking manifests
71 checking manifests
72 crosschecking files in changesets and manifests
72 crosschecking files in changesets and manifests
73 checking files
73 checking files
74 4 files, 9 changesets, 7 total revisions
74 4 files, 9 changesets, 7 total revisions
75
75
76 $ cd ..
76 $ cd ..
77
77
78 $ for i in 0 1 2 3 4 5 6 7 8; do
78 $ for i in 0 1 2 3 4 5 6 7 8; do
79 > echo
79 > echo
80 > echo ---- hg clone -r "$i" test test-"$i"
80 > echo ---- hg clone -r "$i" test test-"$i"
81 > hg clone -r "$i" test test-"$i"
81 > hg clone -r "$i" test test-"$i"
82 > cd test-"$i"
82 > cd test-"$i"
83 > hg verify
83 > hg verify
84 > cd ..
84 > cd ..
85 > done
85 > done
86
86
87 ---- hg clone -r 0 test test-0
87 ---- hg clone -r 0 test test-0
88 adding changesets
88 adding changesets
89 adding manifests
89 adding manifests
90 adding file changes
90 adding file changes
91 added 1 changesets with 1 changes to 1 files
91 added 1 changesets with 1 changes to 1 files
92 new changesets f9ee2f85a263
92 new changesets f9ee2f85a263
93 updating to branch default
93 updating to branch default
94 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
94 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
95 checking changesets
95 checking changesets
96 checking manifests
96 checking manifests
97 crosschecking files in changesets and manifests
97 crosschecking files in changesets and manifests
98 checking files
98 checking files
99 1 files, 1 changesets, 1 total revisions
99 1 files, 1 changesets, 1 total revisions
100
100
101 ---- hg clone -r 1 test test-1
101 ---- hg clone -r 1 test test-1
102 adding changesets
102 adding changesets
103 adding manifests
103 adding manifests
104 adding file changes
104 adding file changes
105 added 2 changesets with 2 changes to 1 files
105 added 2 changesets with 2 changes to 1 files
106 new changesets f9ee2f85a263:34c2bf6b0626
106 new changesets f9ee2f85a263:34c2bf6b0626
107 updating to branch default
107 updating to branch default
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 checking changesets
109 checking changesets
110 checking manifests
110 checking manifests
111 crosschecking files in changesets and manifests
111 crosschecking files in changesets and manifests
112 checking files
112 checking files
113 1 files, 2 changesets, 2 total revisions
113 1 files, 2 changesets, 2 total revisions
114
114
115 ---- hg clone -r 2 test test-2
115 ---- hg clone -r 2 test test-2
116 adding changesets
116 adding changesets
117 adding manifests
117 adding manifests
118 adding file changes
118 adding file changes
119 added 3 changesets with 3 changes to 1 files
119 added 3 changesets with 3 changes to 1 files
120 new changesets f9ee2f85a263:e38ba6f5b7e0
120 new changesets f9ee2f85a263:e38ba6f5b7e0
121 updating to branch default
121 updating to branch default
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 checking changesets
123 checking changesets
124 checking manifests
124 checking manifests
125 crosschecking files in changesets and manifests
125 crosschecking files in changesets and manifests
126 checking files
126 checking files
127 1 files, 3 changesets, 3 total revisions
127 1 files, 3 changesets, 3 total revisions
128
128
129 ---- hg clone -r 3 test test-3
129 ---- hg clone -r 3 test test-3
130 adding changesets
130 adding changesets
131 adding manifests
131 adding manifests
132 adding file changes
132 adding file changes
133 added 4 changesets with 4 changes to 1 files
133 added 4 changesets with 4 changes to 1 files
134 new changesets f9ee2f85a263:eebf5a27f8ca
134 new changesets f9ee2f85a263:eebf5a27f8ca
135 updating to branch default
135 updating to branch default
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
137 checking changesets
137 checking changesets
138 checking manifests
138 checking manifests
139 crosschecking files in changesets and manifests
139 crosschecking files in changesets and manifests
140 checking files
140 checking files
141 1 files, 4 changesets, 4 total revisions
141 1 files, 4 changesets, 4 total revisions
142
142
143 ---- hg clone -r 4 test test-4
143 ---- hg clone -r 4 test test-4
144 adding changesets
144 adding changesets
145 adding manifests
145 adding manifests
146 adding file changes
146 adding file changes
147 added 2 changesets with 2 changes to 1 files
147 added 2 changesets with 2 changes to 1 files
148 new changesets f9ee2f85a263:095197eb4973
148 new changesets f9ee2f85a263:095197eb4973
149 updating to branch default
149 updating to branch default
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 checking changesets
151 checking changesets
152 checking manifests
152 checking manifests
153 crosschecking files in changesets and manifests
153 crosschecking files in changesets and manifests
154 checking files
154 checking files
155 1 files, 2 changesets, 2 total revisions
155 1 files, 2 changesets, 2 total revisions
156
156
157 ---- hg clone -r 5 test test-5
157 ---- hg clone -r 5 test test-5
158 adding changesets
158 adding changesets
159 adding manifests
159 adding manifests
160 adding file changes
160 adding file changes
161 added 3 changesets with 3 changes to 1 files
161 added 3 changesets with 3 changes to 1 files
162 new changesets f9ee2f85a263:1bb50a9436a7
162 new changesets f9ee2f85a263:1bb50a9436a7
163 updating to branch default
163 updating to branch default
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 checking changesets
165 checking changesets
166 checking manifests
166 checking manifests
167 crosschecking files in changesets and manifests
167 crosschecking files in changesets and manifests
168 checking files
168 checking files
169 1 files, 3 changesets, 3 total revisions
169 1 files, 3 changesets, 3 total revisions
170
170
171 ---- hg clone -r 6 test test-6
171 ---- hg clone -r 6 test test-6
172 adding changesets
172 adding changesets
173 adding manifests
173 adding manifests
174 adding file changes
174 adding file changes
175 added 4 changesets with 5 changes to 2 files
175 added 4 changesets with 5 changes to 2 files
176 new changesets f9ee2f85a263:7373c1169842
176 new changesets f9ee2f85a263:7373c1169842
177 updating to branch default
177 updating to branch default
178 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 checking changesets
179 checking changesets
180 checking manifests
180 checking manifests
181 crosschecking files in changesets and manifests
181 crosschecking files in changesets and manifests
182 checking files
182 checking files
183 2 files, 4 changesets, 5 total revisions
183 2 files, 4 changesets, 5 total revisions
184
184
185 ---- hg clone -r 7 test test-7
185 ---- hg clone -r 7 test test-7
186 adding changesets
186 adding changesets
187 adding manifests
187 adding manifests
188 adding file changes
188 adding file changes
189 added 5 changesets with 6 changes to 3 files
189 added 5 changesets with 6 changes to 3 files
190 new changesets f9ee2f85a263:a6a34bfa0076
190 new changesets f9ee2f85a263:a6a34bfa0076
191 updating to branch default
191 updating to branch default
192 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 checking changesets
193 checking changesets
194 checking manifests
194 checking manifests
195 crosschecking files in changesets and manifests
195 crosschecking files in changesets and manifests
196 checking files
196 checking files
197 3 files, 5 changesets, 6 total revisions
197 3 files, 5 changesets, 6 total revisions
198
198
199 ---- hg clone -r 8 test test-8
199 ---- hg clone -r 8 test test-8
200 adding changesets
200 adding changesets
201 adding manifests
201 adding manifests
202 adding file changes
202 adding file changes
203 added 5 changesets with 5 changes to 2 files
203 added 5 changesets with 5 changes to 2 files
204 new changesets f9ee2f85a263:aa35859c02ea
204 new changesets f9ee2f85a263:aa35859c02ea
205 updating to branch default
205 updating to branch default
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 checking changesets
207 checking changesets
208 checking manifests
208 checking manifests
209 crosschecking files in changesets and manifests
209 crosschecking files in changesets and manifests
210 checking files
210 checking files
211 2 files, 5 changesets, 5 total revisions
211 2 files, 5 changesets, 5 total revisions
212
212
213 $ cd test-8
213 $ cd test-8
214 $ hg pull ../test-7
214 $ hg pull ../test-7
215 pulling from ../test-7
215 pulling from ../test-7
216 searching for changes
216 searching for changes
217 adding changesets
217 adding changesets
218 adding manifests
218 adding manifests
219 adding file changes
219 adding file changes
220 added 4 changesets with 2 changes to 3 files (+1 heads)
220 added 4 changesets with 2 changes to 3 files (+1 heads)
221 new changesets 095197eb4973:a6a34bfa0076
221 new changesets 095197eb4973:a6a34bfa0076
222 (run 'hg heads' to see heads, 'hg merge' to merge)
222 (run 'hg heads' to see heads, 'hg merge' to merge)
223 $ hg verify
223 $ hg verify
224 checking changesets
224 checking changesets
225 checking manifests
225 checking manifests
226 crosschecking files in changesets and manifests
226 crosschecking files in changesets and manifests
227 checking files
227 checking files
228 4 files, 9 changesets, 7 total revisions
228 4 files, 9 changesets, 7 total revisions
229 $ cd ..
229 $ cd ..
230
230
231 $ hg clone test test-9
231 $ hg clone test test-9
232 updating to branch default
232 updating to branch default
233 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
234 $ cd test-9
234 $ cd test-9
235 $ hg branch foobar
235 $ hg branch foobar
236 marked working directory as branch foobar
236 marked working directory as branch foobar
237 (branches are permanent and global, did you want a bookmark?)
237 (branches are permanent and global, did you want a bookmark?)
238 $ echo file2 >> file2
238 $ echo file2 >> file2
239 $ hg add file2
239 $ hg add file2
240 $ hg commit -m "changeset9"
240 $ hg commit -m "changeset9"
241 $ echo file3 >> file3
241 $ echo file3 >> file3
242 $ hg add file3
242 $ hg add file3
243 $ hg commit -m "changeset10"
243 $ hg commit -m "changeset10"
244 $ cd ..
244 $ cd ..
245 $ hg clone -r 9 -u foobar test-9 test-10
245 $ hg clone -r 9 -u foobar test-9 test-10
246 adding changesets
246 adding changesets
247 adding manifests
247 adding manifests
248 adding file changes
248 adding file changes
249 added 6 changesets with 6 changes to 3 files
249 added 6 changesets with 6 changes to 3 files
250 new changesets f9ee2f85a263:7100abb79635
250 new changesets f9ee2f85a263:7100abb79635
251 updating to branch foobar
251 updating to branch foobar
252 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
253
253
254
254
@@ -1,1288 +1,1288 b''
1 $ cat << EOF >> $HGRCPATH
1 $ cat << EOF >> $HGRCPATH
2 > [format]
2 > [format]
3 > usegeneraldelta=yes
3 > usegeneraldelta=yes
4 > EOF
4 > EOF
5
5
6 $ hg init
6 $ hg init
7
7
8 Setup:
8 Setup:
9
9
10 $ echo a >> a
10 $ echo a >> a
11 $ hg ci -Am 'base'
11 $ hg ci -Am 'base'
12 adding a
12 adding a
13
13
14 Refuse to amend public csets:
14 Refuse to amend public csets:
15
15
16 $ hg phase -r . -p
16 $ hg phase -r . -p
17 $ hg ci --amend
17 $ hg ci --amend
18 abort: cannot amend public changesets
18 abort: cannot amend public changesets
19 (see 'hg help phases' for details)
19 (see 'hg help phases' for details)
20 [255]
20 [255]
21 $ hg phase -r . -f -d
21 $ hg phase -r . -f -d
22
22
23 $ echo a >> a
23 $ echo a >> a
24 $ hg ci -Am 'base1'
24 $ hg ci -Am 'base1'
25
25
26 Nothing to amend:
26 Nothing to amend:
27
27
28 $ hg ci --amend -m 'base1'
28 $ hg ci --amend -m 'base1'
29 nothing changed
29 nothing changed
30 [1]
30 [1]
31
31
32 $ cat >> $HGRCPATH <<EOF
32 $ cat >> $HGRCPATH <<EOF
33 > [hooks]
33 > [hooks]
34 > pretxncommit.foo = sh -c "echo \\"pretxncommit \$HG_NODE\\"; hg id -r \$HG_NODE"
34 > pretxncommit.foo = sh -c "echo \\"pretxncommit \$HG_NODE\\"; hg id -r \$HG_NODE"
35 > EOF
35 > EOF
36
36
37 Amending changeset with changes in working dir:
37 Amending changeset with changes in working dir:
38 (and check that --message does not trigger an editor)
38 (and check that --message does not trigger an editor)
39
39
40 $ echo a >> a
40 $ echo a >> a
41 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -m 'amend base1'
41 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -m 'amend base1'
42 pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149
42 pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149
43 43f1ba15f28a tip
43 43f1ba15f28a tip
44 saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-5ab4f721-amend.hg
44 saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-5ab4f721-amend.hg
45 $ echo 'pretxncommit.foo = ' >> $HGRCPATH
45 $ echo 'pretxncommit.foo = ' >> $HGRCPATH
46 $ hg diff -c .
46 $ hg diff -c .
47 diff -r ad120869acf0 -r 43f1ba15f28a a
47 diff -r ad120869acf0 -r 43f1ba15f28a a
48 --- a/a Thu Jan 01 00:00:00 1970 +0000
48 --- a/a Thu Jan 01 00:00:00 1970 +0000
49 +++ b/a Thu Jan 01 00:00:00 1970 +0000
49 +++ b/a Thu Jan 01 00:00:00 1970 +0000
50 @@ -1,1 +1,3 @@
50 @@ -1,1 +1,3 @@
51 a
51 a
52 +a
52 +a
53 +a
53 +a
54 $ hg log
54 $ hg log
55 changeset: 1:43f1ba15f28a
55 changeset: 1:43f1ba15f28a
56 tag: tip
56 tag: tip
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59 summary: amend base1
59 summary: amend base1
60
60
61 changeset: 0:ad120869acf0
61 changeset: 0:ad120869acf0
62 user: test
62 user: test
63 date: Thu Jan 01 00:00:00 1970 +0000
63 date: Thu Jan 01 00:00:00 1970 +0000
64 summary: base
64 summary: base
65
65
66
66
67 Check proper abort for empty message
67 Check proper abort for empty message
68
68
69 $ cat > editor.sh << '__EOF__'
69 $ cat > editor.sh << '__EOF__'
70 > #!/bin/sh
70 > #!/bin/sh
71 > echo "" > "$1"
71 > echo "" > "$1"
72 > __EOF__
72 > __EOF__
73
73
74 Update the existing file to ensure that the dirstate is not in pending state
74 Update the existing file to ensure that the dirstate is not in pending state
75 (where the status of some files in the working copy is not known yet). This in
75 (where the status of some files in the working copy is not known yet). This in
76 turn ensures that when the transaction is aborted due to an empty message during
76 turn ensures that when the transaction is aborted due to an empty message during
77 the amend, there should be no rollback.
77 the amend, there should be no rollback.
78 $ echo a >> a
78 $ echo a >> a
79
79
80 $ echo b > b
80 $ echo b > b
81 $ hg add b
81 $ hg add b
82 $ hg summary
82 $ hg summary
83 parent: 1:43f1ba15f28a tip
83 parent: 1:43f1ba15f28a tip
84 amend base1
84 amend base1
85 branch: default
85 branch: default
86 commit: 1 modified, 1 added, 1 unknown
86 commit: 1 modified, 1 added, 1 unknown
87 update: (current)
87 update: (current)
88 phases: 2 draft
88 phases: 2 draft
89 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
89 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
90 abort: empty commit message
90 abort: empty commit message
91 [255]
91 [255]
92 $ hg summary
92 $ hg summary
93 parent: 1:43f1ba15f28a tip
93 parent: 1:43f1ba15f28a tip
94 amend base1
94 amend base1
95 branch: default
95 branch: default
96 commit: 1 modified, 1 added, 1 unknown
96 commit: 1 modified, 1 added, 1 unknown
97 update: (current)
97 update: (current)
98 phases: 2 draft
98 phases: 2 draft
99
99
100 Add new file along with modified existing file:
100 Add new file along with modified existing file:
101 $ hg ci --amend -m 'amend base1 new file'
101 $ hg ci --amend -m 'amend base1 new file'
102 saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-007467c2-amend.hg
102 saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-007467c2-amend.hg
103
103
104 Remove file that was added in amended commit:
104 Remove file that was added in amended commit:
105 (and test logfile option)
105 (and test logfile option)
106 (and test that logfile option do not trigger an editor)
106 (and test that logfile option do not trigger an editor)
107
107
108 $ hg rm b
108 $ hg rm b
109 $ echo 'amend base1 remove new file' > ../logfile
109 $ echo 'amend base1 remove new file' > ../logfile
110 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --logfile ../logfile
110 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --logfile ../logfile
111 saved backup bundle to $TESTTMP/.hg/strip-backup/c16295aaf401-1ada9901-amend.hg
111 saved backup bundle to $TESTTMP/.hg/strip-backup/c16295aaf401-1ada9901-amend.hg
112
112
113 $ hg cat b
113 $ hg cat b
114 b: no such file in rev 47343646fa3d
114 b: no such file in rev 47343646fa3d
115 [1]
115 [1]
116
116
117 No changes, just a different message:
117 No changes, just a different message:
118
118
119 $ hg ci -v --amend -m 'no changes, new message'
119 $ hg ci -v --amend -m 'no changes, new message'
120 amending changeset 47343646fa3d
120 amending changeset 47343646fa3d
121 copying changeset 47343646fa3d to ad120869acf0
121 copying changeset 47343646fa3d to ad120869acf0
122 committing files:
122 committing files:
123 a
123 a
124 committing manifest
124 committing manifest
125 committing changelog
125 committing changelog
126 1 changesets found
126 1 changesets found
127 uncompressed size of bundle content:
127 uncompressed size of bundle content:
128 254 (changelog)
128 254 (changelog)
129 163 (manifests)
129 163 (manifests)
130 131 a
130 131 a
131 saved backup bundle to $TESTTMP/.hg/strip-backup/47343646fa3d-c2758885-amend.hg
131 saved backup bundle to $TESTTMP/.hg/strip-backup/47343646fa3d-c2758885-amend.hg
132 1 changesets found
132 1 changesets found
133 uncompressed size of bundle content:
133 uncompressed size of bundle content:
134 250 (changelog)
134 250 (changelog)
135 163 (manifests)
135 163 (manifests)
136 131 a
136 131 a
137 adding branch
137 adding branch
138 adding changesets
138 adding changesets
139 adding manifests
139 adding manifests
140 adding file changes
140 adding file changes
141 added 1 changesets with 1 changes to 1 files
141 added 1 changesets with 1 changes to 1 files
142 committed changeset 1:401431e913a1
142 committed changeset 1:401431e913a1
143 $ hg diff -c .
143 $ hg diff -c .
144 diff -r ad120869acf0 -r 401431e913a1 a
144 diff -r ad120869acf0 -r 401431e913a1 a
145 --- a/a Thu Jan 01 00:00:00 1970 +0000
145 --- a/a Thu Jan 01 00:00:00 1970 +0000
146 +++ b/a Thu Jan 01 00:00:00 1970 +0000
146 +++ b/a Thu Jan 01 00:00:00 1970 +0000
147 @@ -1,1 +1,4 @@
147 @@ -1,1 +1,4 @@
148 a
148 a
149 +a
149 +a
150 +a
150 +a
151 +a
151 +a
152 $ hg log
152 $ hg log
153 changeset: 1:401431e913a1
153 changeset: 1:401431e913a1
154 tag: tip
154 tag: tip
155 user: test
155 user: test
156 date: Thu Jan 01 00:00:00 1970 +0000
156 date: Thu Jan 01 00:00:00 1970 +0000
157 summary: no changes, new message
157 summary: no changes, new message
158
158
159 changeset: 0:ad120869acf0
159 changeset: 0:ad120869acf0
160 user: test
160 user: test
161 date: Thu Jan 01 00:00:00 1970 +0000
161 date: Thu Jan 01 00:00:00 1970 +0000
162 summary: base
162 summary: base
163
163
164
164
165 Disable default date on commit so when -d isn't given, the old date is preserved:
165 Disable default date on commit so when -d isn't given, the old date is preserved:
166
166
167 $ echo '[defaults]' >> $HGRCPATH
167 $ echo '[defaults]' >> $HGRCPATH
168 $ echo 'commit=' >> $HGRCPATH
168 $ echo 'commit=' >> $HGRCPATH
169
169
170 Test -u/-d:
170 Test -u/-d:
171
171
172 $ cat > .hg/checkeditform.sh <<EOF
172 $ cat > .hg/checkeditform.sh <<EOF
173 > env | grep HGEDITFORM
173 > env | grep HGEDITFORM
174 > true
174 > true
175 > EOF
175 > EOF
176 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -u foo -d '1 0'
176 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -u foo -d '1 0'
177 HGEDITFORM=commit.amend.normal
177 HGEDITFORM=commit.amend.normal
178 saved backup bundle to $TESTTMP/.hg/strip-backup/401431e913a1-5e8e532c-amend.hg
178 saved backup bundle to $TESTTMP/.hg/strip-backup/401431e913a1-5e8e532c-amend.hg
179 $ echo a >> a
179 $ echo a >> a
180 $ hg ci --amend -u foo -d '1 0'
180 $ hg ci --amend -u foo -d '1 0'
181 saved backup bundle to $TESTTMP/.hg/strip-backup/d96b1d28ae33-677e0afb-amend.hg
181 saved backup bundle to $TESTTMP/.hg/strip-backup/d96b1d28ae33-677e0afb-amend.hg
182 $ hg log -r .
182 $ hg log -r .
183 changeset: 1:a9a13940fc03
183 changeset: 1:a9a13940fc03
184 tag: tip
184 tag: tip
185 user: foo
185 user: foo
186 date: Thu Jan 01 00:00:01 1970 +0000
186 date: Thu Jan 01 00:00:01 1970 +0000
187 summary: no changes, new message
187 summary: no changes, new message
188
188
189
189
190 Open editor with old commit message if a message isn't given otherwise:
190 Open editor with old commit message if a message isn't given otherwise:
191
191
192 $ cat > editor.sh << '__EOF__'
192 $ cat > editor.sh << '__EOF__'
193 > #!/bin/sh
193 > #!/bin/sh
194 > cat $1
194 > cat $1
195 > echo "another precious commit message" > "$1"
195 > echo "another precious commit message" > "$1"
196 > __EOF__
196 > __EOF__
197
197
198 at first, test saving last-message.txt
198 at first, test saving last-message.txt
199
199
200 $ cat > .hg/hgrc << '__EOF__'
200 $ cat > .hg/hgrc << '__EOF__'
201 > [hooks]
201 > [hooks]
202 > pretxncommit.test-saving-last-message = false
202 > pretxncommit.test-saving-last-message = false
203 > __EOF__
203 > __EOF__
204
204
205 $ rm -f .hg/last-message.txt
205 $ rm -f .hg/last-message.txt
206 $ hg commit --amend -v -m "message given from command line"
206 $ hg commit --amend -v -m "message given from command line"
207 amending changeset a9a13940fc03
207 amending changeset a9a13940fc03
208 copying changeset a9a13940fc03 to ad120869acf0
208 copying changeset a9a13940fc03 to ad120869acf0
209 committing files:
209 committing files:
210 a
210 a
211 committing manifest
211 committing manifest
212 committing changelog
212 committing changelog
213 running hook pretxncommit.test-saving-last-message: false
213 running hook pretxncommit.test-saving-last-message: false
214 transaction abort!
214 transaction abort!
215 rollback completed
215 rollback completed
216 abort: pretxncommit.test-saving-last-message hook exited with status 1
216 abort: pretxncommit.test-saving-last-message hook exited with status 1
217 [255]
217 [255]
218 $ cat .hg/last-message.txt
218 $ cat .hg/last-message.txt
219 message given from command line (no-eol)
219 message given from command line (no-eol)
220
220
221 $ rm -f .hg/last-message.txt
221 $ rm -f .hg/last-message.txt
222 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
222 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
223 amending changeset a9a13940fc03
223 amending changeset a9a13940fc03
224 copying changeset a9a13940fc03 to ad120869acf0
224 copying changeset a9a13940fc03 to ad120869acf0
225 no changes, new message
225 no changes, new message
226
226
227
227
228 HG: Enter commit message. Lines beginning with 'HG:' are removed.
228 HG: Enter commit message. Lines beginning with 'HG:' are removed.
229 HG: Leave message empty to abort commit.
229 HG: Leave message empty to abort commit.
230 HG: --
230 HG: --
231 HG: user: foo
231 HG: user: foo
232 HG: branch 'default'
232 HG: branch 'default'
233 HG: changed a
233 HG: changed a
234 committing files:
234 committing files:
235 a
235 a
236 committing manifest
236 committing manifest
237 committing changelog
237 committing changelog
238 running hook pretxncommit.test-saving-last-message: false
238 running hook pretxncommit.test-saving-last-message: false
239 transaction abort!
239 transaction abort!
240 rollback completed
240 rollback completed
241 abort: pretxncommit.test-saving-last-message hook exited with status 1
241 abort: pretxncommit.test-saving-last-message hook exited with status 1
242 [255]
242 [255]
243
243
244 $ cat .hg/last-message.txt
244 $ cat .hg/last-message.txt
245 another precious commit message
245 another precious commit message
246
246
247 $ cat > .hg/hgrc << '__EOF__'
247 $ cat > .hg/hgrc << '__EOF__'
248 > [hooks]
248 > [hooks]
249 > pretxncommit.test-saving-last-message =
249 > pretxncommit.test-saving-last-message =
250 > __EOF__
250 > __EOF__
251
251
252 then, test editing custom commit message
252 then, test editing custom commit message
253
253
254 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
254 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
255 amending changeset a9a13940fc03
255 amending changeset a9a13940fc03
256 copying changeset a9a13940fc03 to ad120869acf0
256 copying changeset a9a13940fc03 to ad120869acf0
257 no changes, new message
257 no changes, new message
258
258
259
259
260 HG: Enter commit message. Lines beginning with 'HG:' are removed.
260 HG: Enter commit message. Lines beginning with 'HG:' are removed.
261 HG: Leave message empty to abort commit.
261 HG: Leave message empty to abort commit.
262 HG: --
262 HG: --
263 HG: user: foo
263 HG: user: foo
264 HG: branch 'default'
264 HG: branch 'default'
265 HG: changed a
265 HG: changed a
266 committing files:
266 committing files:
267 a
267 a
268 committing manifest
268 committing manifest
269 committing changelog
269 committing changelog
270 1 changesets found
270 1 changesets found
271 uncompressed size of bundle content:
271 uncompressed size of bundle content:
272 249 (changelog)
272 249 (changelog)
273 163 (manifests)
273 163 (manifests)
274 133 a
274 133 a
275 saved backup bundle to $TESTTMP/.hg/strip-backup/a9a13940fc03-7c2e8674-amend.hg
275 saved backup bundle to $TESTTMP/.hg/strip-backup/a9a13940fc03-7c2e8674-amend.hg
276 1 changesets found
276 1 changesets found
277 uncompressed size of bundle content:
277 uncompressed size of bundle content:
278 257 (changelog)
278 257 (changelog)
279 163 (manifests)
279 163 (manifests)
280 133 a
280 133 a
281 adding branch
281 adding branch
282 adding changesets
282 adding changesets
283 adding manifests
283 adding manifests
284 adding file changes
284 adding file changes
285 added 1 changesets with 1 changes to 1 files
285 added 1 changesets with 1 changes to 1 files
286 committed changeset 1:64a124ba1b44
286 committed changeset 1:64a124ba1b44
287
287
288 Same, but with changes in working dir (different code path):
288 Same, but with changes in working dir (different code path):
289
289
290 $ echo a >> a
290 $ echo a >> a
291 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
291 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
292 amending changeset 64a124ba1b44
292 amending changeset 64a124ba1b44
293 another precious commit message
293 another precious commit message
294
294
295
295
296 HG: Enter commit message. Lines beginning with 'HG:' are removed.
296 HG: Enter commit message. Lines beginning with 'HG:' are removed.
297 HG: Leave message empty to abort commit.
297 HG: Leave message empty to abort commit.
298 HG: --
298 HG: --
299 HG: user: foo
299 HG: user: foo
300 HG: branch 'default'
300 HG: branch 'default'
301 HG: changed a
301 HG: changed a
302 committing files:
302 committing files:
303 a
303 a
304 committing manifest
304 committing manifest
305 committing changelog
305 committing changelog
306 1 changesets found
306 1 changesets found
307 uncompressed size of bundle content:
307 uncompressed size of bundle content:
308 257 (changelog)
308 257 (changelog)
309 163 (manifests)
309 163 (manifests)
310 133 a
310 133 a
311 saved backup bundle to $TESTTMP/.hg/strip-backup/64a124ba1b44-10374b8f-amend.hg
311 saved backup bundle to $TESTTMP/.hg/strip-backup/64a124ba1b44-10374b8f-amend.hg
312 1 changesets found
312 1 changesets found
313 uncompressed size of bundle content:
313 uncompressed size of bundle content:
314 257 (changelog)
314 257 (changelog)
315 163 (manifests)
315 163 (manifests)
316 135 a
316 135 a
317 adding branch
317 adding branch
318 adding changesets
318 adding changesets
319 adding manifests
319 adding manifests
320 adding file changes
320 adding file changes
321 added 1 changesets with 1 changes to 1 files
321 added 1 changesets with 1 changes to 1 files
322 committed changeset 1:7892795b8e38
322 committed changeset 1:7892795b8e38
323
323
324 $ rm editor.sh
324 $ rm editor.sh
325 $ hg log -r .
325 $ hg log -r .
326 changeset: 1:7892795b8e38
326 changeset: 1:7892795b8e38
327 tag: tip
327 tag: tip
328 user: foo
328 user: foo
329 date: Thu Jan 01 00:00:01 1970 +0000
329 date: Thu Jan 01 00:00:01 1970 +0000
330 summary: another precious commit message
330 summary: another precious commit message
331
331
332
332
333 Moving bookmarks, preserve active bookmark:
333 Moving bookmarks, preserve active bookmark:
334
334
335 $ hg book book1
335 $ hg book book1
336 $ hg book book2
336 $ hg book book2
337 $ hg ci --amend -m 'move bookmarks'
337 $ hg ci --amend -m 'move bookmarks'
338 saved backup bundle to $TESTTMP/.hg/strip-backup/7892795b8e38-3fb46217-amend.hg
338 saved backup bundle to $TESTTMP/.hg/strip-backup/7892795b8e38-3fb46217-amend.hg
339 $ hg book
339 $ hg book
340 book1 1:8311f17e2616
340 book1 1:8311f17e2616
341 * book2 1:8311f17e2616
341 * book2 1:8311f17e2616
342 $ echo a >> a
342 $ echo a >> a
343 $ hg ci --amend -m 'move bookmarks'
343 $ hg ci --amend -m 'move bookmarks'
344 saved backup bundle to $TESTTMP/.hg/strip-backup/8311f17e2616-f0504fe3-amend.hg
344 saved backup bundle to $TESTTMP/.hg/strip-backup/8311f17e2616-f0504fe3-amend.hg
345 $ hg book
345 $ hg book
346 book1 1:a3b65065808c
346 book1 1:a3b65065808c
347 * book2 1:a3b65065808c
347 * book2 1:a3b65065808c
348
348
349 abort does not loose bookmarks
349 abort does not loose bookmarks
350
350
351 $ cat > editor.sh << '__EOF__'
351 $ cat > editor.sh << '__EOF__'
352 > #!/bin/sh
352 > #!/bin/sh
353 > echo "" > "$1"
353 > echo "" > "$1"
354 > __EOF__
354 > __EOF__
355 $ echo a >> a
355 $ echo a >> a
356 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
356 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
357 abort: empty commit message
357 abort: empty commit message
358 [255]
358 [255]
359 $ hg book
359 $ hg book
360 book1 1:a3b65065808c
360 book1 1:a3b65065808c
361 * book2 1:a3b65065808c
361 * book2 1:a3b65065808c
362 $ hg revert -Caq
362 $ hg revert -Caq
363 $ rm editor.sh
363 $ rm editor.sh
364
364
365 $ echo '[defaults]' >> $HGRCPATH
365 $ echo '[defaults]' >> $HGRCPATH
366 $ echo "commit=-d '0 0'" >> $HGRCPATH
366 $ echo "commit=-d '0 0'" >> $HGRCPATH
367
367
368 Moving branches:
368 Moving branches:
369
369
370 $ hg branch foo
370 $ hg branch foo
371 marked working directory as branch foo
371 marked working directory as branch foo
372 (branches are permanent and global, did you want a bookmark?)
372 (branches are permanent and global, did you want a bookmark?)
373 $ echo a >> a
373 $ echo a >> a
374 $ hg ci -m 'branch foo'
374 $ hg ci -m 'branch foo'
375 $ hg branch default -f
375 $ hg branch default -f
376 marked working directory as branch default
376 marked working directory as branch default
377 $ hg ci --amend -m 'back to default'
377 $ hg ci --amend -m 'back to default'
378 saved backup bundle to $TESTTMP/.hg/strip-backup/f8339a38efe1-c18453c9-amend.hg
378 saved backup bundle to $TESTTMP/.hg/strip-backup/f8339a38efe1-c18453c9-amend.hg
379 $ hg branches
379 $ hg branches
380 default 2:9c07515f2650
380 default 2:9c07515f2650
381
381
382 Close branch:
382 Close branch:
383
383
384 $ hg up -q 0
384 $ hg up -q 0
385 $ echo b >> b
385 $ echo b >> b
386 $ hg branch foo
386 $ hg branch foo
387 marked working directory as branch foo
387 marked working directory as branch foo
388 (branches are permanent and global, did you want a bookmark?)
388 (branches are permanent and global, did you want a bookmark?)
389 $ hg ci -Am 'fork'
389 $ hg ci -Am 'fork'
390 adding b
390 adding b
391 $ echo b >> b
391 $ echo b >> b
392 $ hg ci -mb
392 $ hg ci -mb
393 $ hg ci --amend --close-branch -m 'closing branch foo'
393 $ hg ci --amend --close-branch -m 'closing branch foo'
394 saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-54245dc7-amend.hg
394 saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-54245dc7-amend.hg
395
395
396 Same thing, different code path:
396 Same thing, different code path:
397
397
398 $ echo b >> b
398 $ echo b >> b
399 $ hg ci -m 'reopen branch'
399 $ hg ci -m 'reopen branch'
400 reopening closed branch head 4
400 reopening closed branch head 4
401 $ echo b >> b
401 $ echo b >> b
402 $ hg ci --amend --close-branch
402 $ hg ci --amend --close-branch
403 saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-b900d9fa-amend.hg
403 saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-b900d9fa-amend.hg
404 $ hg branches
404 $ hg branches
405 default 2:9c07515f2650
405 default 2:9c07515f2650
406
406
407 Refuse to amend during a merge:
407 Refuse to amend during a merge:
408
408
409 $ hg up -q default
409 $ hg up -q default
410 $ hg merge foo
410 $ hg merge foo
411 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
411 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
412 (branch merge, don't forget to commit)
412 (branch merge, don't forget to commit)
413 $ hg ci --amend
413 $ hg ci --amend
414 abort: cannot amend while merging
414 abort: cannot amend while merging
415 [255]
415 [255]
416 $ hg ci -m 'merge'
416 $ hg ci -m 'merge'
417
417
418 Refuse to amend if there is a merge conflict (issue5805):
418 Refuse to amend if there is a merge conflict (issue5805):
419
419
420 $ hg up -q foo
420 $ hg up -q foo
421 $ echo c > a
421 $ echo c > a
422 $ hg up default -t :fail
422 $ hg up default -t :fail
423 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
423 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
424 use 'hg resolve' to retry unresolved file merges
424 use 'hg resolve' to retry unresolved file merges
425 [1]
425 [1]
426 $ hg resolve -l
426 $ hg resolve -l
427 U a
427 U a
428
428
429 $ hg ci --amend
429 $ hg ci --amend
430 abort: unresolved merge conflicts (see 'hg help resolve')
430 abort: unresolved merge conflicts (see 'hg help resolve')
431 [255]
431 [255]
432
432
433 $ hg up -qC .
433 $ hg up -qC .
434
434
435 Follow copies/renames:
435 Follow copies/renames:
436
436
437 $ hg mv b c
437 $ hg mv b c
438 $ hg ci -m 'b -> c'
438 $ hg ci -m 'b -> c'
439 $ hg mv c d
439 $ hg mv c d
440 $ hg ci --amend -m 'b -> d'
440 $ hg ci --amend -m 'b -> d'
441 saved backup bundle to $TESTTMP/.hg/strip-backup/42f3f27a067d-f23cc9f7-amend.hg
441 saved backup bundle to $TESTTMP/.hg/strip-backup/42f3f27a067d-f23cc9f7-amend.hg
442 $ hg st --rev '.^' --copies d
442 $ hg st --rev '.^' --copies d
443 A d
443 A d
444 b
444 b
445 $ hg cp d e
445 $ hg cp d e
446 $ hg ci -m 'e = d'
446 $ hg ci -m 'e = d'
447 $ hg cp e f
447 $ hg cp e f
448 $ hg ci --amend -m 'f = d'
448 $ hg ci --amend -m 'f = d'
449 saved backup bundle to $TESTTMP/.hg/strip-backup/9198f73182d5-251d584a-amend.hg
449 saved backup bundle to $TESTTMP/.hg/strip-backup/9198f73182d5-251d584a-amend.hg
450 $ hg st --rev '.^' --copies f
450 $ hg st --rev '.^' --copies f
451 A f
451 A f
452 d
452 d
453
453
454 $ mv f f.orig
454 $ mv f f.orig
455 $ hg rm -A f
455 $ hg rm -A f
456 $ hg ci -m removef
456 $ hg ci -m removef
457 $ hg cp a f
457 $ hg cp a f
458 $ mv f.orig f
458 $ mv f.orig f
459 $ hg ci --amend -m replacef
459 $ hg ci --amend -m replacef
460 saved backup bundle to $TESTTMP/.hg/strip-backup/f0993ab6b482-eda301bf-amend.hg
460 saved backup bundle to $TESTTMP/.hg/strip-backup/f0993ab6b482-eda301bf-amend.hg
461 $ hg st --change . --copies
461 $ hg st --change . --copies
462 $ hg log -r . --template "{file_copies}\n"
462 $ hg log -r . --template "{file_copies}\n"
463
463
464
464
465 Move added file (issue3410):
465 Move added file (issue3410):
466
466
467 $ echo g >> g
467 $ echo g >> g
468 $ hg ci -Am g
468 $ hg ci -Am g
469 adding g
469 adding g
470 $ hg mv g h
470 $ hg mv g h
471 $ hg ci --amend
471 $ hg ci --amend
472 saved backup bundle to $TESTTMP/.hg/strip-backup/58585e3f095c-0f5ebcda-amend.hg
472 saved backup bundle to $TESTTMP/.hg/strip-backup/58585e3f095c-0f5ebcda-amend.hg
473 $ hg st --change . --copies h
473 $ hg st --change . --copies h
474 A h
474 A h
475 $ hg log -r . --template "{file_copies}\n"
475 $ hg log -r . --template "{file_copies}\n"
476
476
477
477
478 Can't rollback an amend:
478 Can't rollback an amend:
479
479
480 $ hg rollback
480 $ hg rollback
481 no rollback information available
481 no rollback information available
482 [1]
482 [1]
483
483
484 Preserve extra dict (issue3430):
484 Preserve extra dict (issue3430):
485
485
486 $ hg branch a
486 $ hg branch a
487 marked working directory as branch a
487 marked working directory as branch a
488 (branches are permanent and global, did you want a bookmark?)
488 (branches are permanent and global, did you want a bookmark?)
489 $ echo a >> a
489 $ echo a >> a
490 $ hg ci -ma
490 $ hg ci -ma
491 $ hg ci --amend -m "a'"
491 $ hg ci --amend -m "a'"
492 saved backup bundle to $TESTTMP/.hg/strip-backup/39a162f1d65e-9dfe13d8-amend.hg
492 saved backup bundle to $TESTTMP/.hg/strip-backup/39a162f1d65e-9dfe13d8-amend.hg
493 $ hg log -r . --template "{branch}\n"
493 $ hg log -r . --template "{branch}\n"
494 a
494 a
495 $ hg ci --amend -m "a''"
495 $ hg ci --amend -m "a''"
496 saved backup bundle to $TESTTMP/.hg/strip-backup/d5ca7b1ac72b-0b4c1a34-amend.hg
496 saved backup bundle to $TESTTMP/.hg/strip-backup/d5ca7b1ac72b-0b4c1a34-amend.hg
497 $ hg log -r . --template "{branch}\n"
497 $ hg log -r . --template "{branch}\n"
498 a
498 a
499
499
500 Also preserve other entries in the dict that are in the old commit,
500 Also preserve other entries in the dict that are in the old commit,
501 first graft something so there's an additional entry:
501 first graft something so there's an additional entry:
502
502
503 $ hg up 0 -q
503 $ hg up 0 -q
504 $ echo z > z
504 $ echo z > z
505 $ hg ci -Am 'fork'
505 $ hg ci -Am 'fork'
506 adding z
506 adding z
507 created new head
507 created new head
508 $ hg up 11
508 $ hg up 11
509 5 files updated, 0 files merged, 1 files removed, 0 files unresolved
509 5 files updated, 0 files merged, 1 files removed, 0 files unresolved
510 $ hg graft 12
510 $ hg graft 12
511 grafting 12:2647734878ef "fork" (tip)
511 grafting 12:2647734878ef "fork" (tip)
512 $ hg ci --amend -m 'graft amend'
512 $ hg ci --amend -m 'graft amend'
513 saved backup bundle to $TESTTMP/.hg/strip-backup/fe8c6f7957ca-25638666-amend.hg
513 saved backup bundle to $TESTTMP/.hg/strip-backup/fe8c6f7957ca-25638666-amend.hg
514 $ hg log -r . --debug | grep extra
514 $ hg log -r . --debug | grep extra
515 extra: amend_source=fe8c6f7957ca1665ed77496ed7a07657d469ac60
515 extra: amend_source=fe8c6f7957ca1665ed77496ed7a07657d469ac60
516 extra: branch=a
516 extra: branch=a
517 extra: source=2647734878ef0236dda712fae9c1651cf694ea8a
517 extra: source=2647734878ef0236dda712fae9c1651cf694ea8a
518
518
519 Preserve phase
519 Preserve phase
520
520
521 $ hg phase '.^::.'
521 $ hg phase '.^::.'
522 11: draft
522 11: draft
523 13: draft
523 13: draft
524 $ hg phase --secret --force .
524 $ hg phase --secret --force .
525 $ hg phase '.^::.'
525 $ hg phase '.^::.'
526 11: draft
526 11: draft
527 13: secret
527 13: secret
528 $ hg commit --amend -m 'amend for phase' -q
528 $ hg commit --amend -m 'amend for phase' -q
529 $ hg phase '.^::.'
529 $ hg phase '.^::.'
530 11: draft
530 11: draft
531 13: secret
531 13: secret
532
532
533 Test amend with obsolete
533 Test amend with obsolete
534 ---------------------------
534 ---------------------------
535
535
536 Enable obsolete
536 Enable obsolete
537
537
538 $ cat >> $HGRCPATH << EOF
538 $ cat >> $HGRCPATH << EOF
539 > [experimental]
539 > [experimental]
540 > evolution.createmarkers=True
540 > evolution.createmarkers=True
541 > evolution.allowunstable=True
541 > evolution.allowunstable=True
542 > EOF
542 > EOF
543
543
544 Amend with no files changes
544 Amend with no files changes
545
545
546 $ hg id -n
546 $ hg id -n
547 13
547 13
548 $ hg ci --amend -m 'babar'
548 $ hg ci --amend -m 'babar'
549 $ hg id -n
549 $ hg id -n
550 14
550 14
551 $ hg log -Gl 3 --style=compact
551 $ hg log -Gl 3 --style=compact
552 @ 14[tip]:11 682950e85999 1970-01-01 00:00 +0000 test
552 @ 14[tip]:11 682950e85999 1970-01-01 00:00 +0000 test
553 | babar
553 | babar
554 |
554 |
555 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
555 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
556 | | fork
556 | | fork
557 | ~
557 | ~
558 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
558 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
559 | a''
559 | a''
560 ~
560 ~
561 $ hg log -Gl 4 --hidden --style=compact
561 $ hg log -Gl 4 --hidden --style=compact
562 @ 14[tip]:11 682950e85999 1970-01-01 00:00 +0000 test
562 @ 14[tip]:11 682950e85999 1970-01-01 00:00 +0000 test
563 | babar
563 | babar
564 |
564 |
565 | x 13:11 5167600b0f7a 1970-01-01 00:00 +0000 test
565 | x 13:11 5167600b0f7a 1970-01-01 00:00 +0000 test
566 |/ amend for phase
566 |/ amend for phase
567 |
567 |
568 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
568 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
569 | | fork
569 | | fork
570 | ~
570 | ~
571 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
571 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
572 | a''
572 | a''
573 ~
573 ~
574
574
575 Amend with files changes
575 Amend with files changes
576
576
577 (note: the extra commit over 15 is a temporary junk I would be happy to get
577 (note: the extra commit over 15 is a temporary junk I would be happy to get
578 ride of)
578 ride of)
579
579
580 $ echo 'babar' >> a
580 $ echo 'babar' >> a
581 $ hg commit --amend
581 $ hg commit --amend
582 $ hg log -Gl 6 --hidden --style=compact
582 $ hg log -Gl 6 --hidden --style=compact
583 @ 15[tip]:11 a5b42b49b0d5 1970-01-01 00:00 +0000 test
583 @ 15[tip]:11 a5b42b49b0d5 1970-01-01 00:00 +0000 test
584 | babar
584 | babar
585 |
585 |
586 | x 14:11 682950e85999 1970-01-01 00:00 +0000 test
586 | x 14:11 682950e85999 1970-01-01 00:00 +0000 test
587 |/ babar
587 |/ babar
588 |
588 |
589 | x 13:11 5167600b0f7a 1970-01-01 00:00 +0000 test
589 | x 13:11 5167600b0f7a 1970-01-01 00:00 +0000 test
590 |/ amend for phase
590 |/ amend for phase
591 |
591 |
592 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
592 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
593 | | fork
593 | | fork
594 | ~
594 | ~
595 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
595 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
596 | a''
596 | a''
597 |
597 |
598 o 10 5fa75032e226 1970-01-01 00:00 +0000 test
598 o 10 5fa75032e226 1970-01-01 00:00 +0000 test
599 | g
599 | g
600 ~
600 ~
601
601
602
602
603 Test that amend does not make it easy to create obsolescence cycle
603 Test that amend does not make it easy to create obsolescence cycle
604 ---------------------------------------------------------------------
604 ---------------------------------------------------------------------
605
605
606 $ hg id -r 14 --hidden
606 $ hg id -r 14 --hidden
607 682950e85999 (a)
607 682950e85999 (a)
608 $ hg revert -ar 14 --hidden
608 $ hg revert -ar 14 --hidden
609 reverting a
609 reverting a
610 $ hg commit --amend
610 $ hg commit --amend
611 $ hg id
611 $ hg id
612 37973c7e0b61 (a) tip
612 37973c7e0b61 (a) tip
613
613
614 Test that rewriting leaving instability behind is allowed
614 Test that rewriting leaving instability behind is allowed
615 ---------------------------------------------------------------------
615 ---------------------------------------------------------------------
616
616
617 $ hg up '.^'
617 $ hg up '.^'
618 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
618 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
619 $ echo 'b' >> a
619 $ echo 'b' >> a
620 $ hg log --style compact -r 'children(.)'
620 $ hg log --style compact -r 'children(.)'
621 16[tip]:11 37973c7e0b61 1970-01-01 00:00 +0000 test
621 16[tip]:11 37973c7e0b61 1970-01-01 00:00 +0000 test
622 babar
622 babar
623
623
624 $ hg commit --amend
624 $ hg commit --amend
625 1 new orphan changesets
625 1 new orphan changesets
626 $ hg log -r 'orphan()'
626 $ hg log -r 'orphan()'
627 changeset: 16:37973c7e0b61
627 changeset: 16:37973c7e0b61
628 branch: a
628 branch: a
629 parent: 11:0ddb275cfad1
629 parent: 11:0ddb275cfad1
630 user: test
630 user: test
631 date: Thu Jan 01 00:00:00 1970 +0000
631 date: Thu Jan 01 00:00:00 1970 +0000
632 instability: orphan
632 instability: orphan
633 summary: babar
633 summary: babar
634
634
635
635
636 Amend a merge changeset (with renames and conflicts from the second parent):
636 Amend a merge changeset (with renames and conflicts from the second parent):
637
637
638 $ hg up -q default
638 $ hg up -q default
639 $ hg branch -q bar
639 $ hg branch -q bar
640 $ hg cp a aa
640 $ hg cp a aa
641 $ hg mv z zz
641 $ hg mv z zz
642 $ echo cc > cc
642 $ echo cc > cc
643 $ hg add cc
643 $ hg add cc
644 $ hg ci -m aazzcc
644 $ hg ci -m aazzcc
645 $ hg up -q default
645 $ hg up -q default
646 $ echo a >> a
646 $ echo a >> a
647 $ echo dd > cc
647 $ echo dd > cc
648 $ hg add cc
648 $ hg add cc
649 $ hg ci -m aa
649 $ hg ci -m aa
650 $ hg merge -q bar
650 $ hg merge -q bar
651 warning: conflicts while merging cc! (edit, then use 'hg resolve --mark')
651 warning: conflicts while merging cc! (edit, then use 'hg resolve --mark')
652 [1]
652 [1]
653 $ hg resolve -m cc
653 $ hg resolve -m cc
654 (no more unresolved files)
654 (no more unresolved files)
655 $ hg ci -m 'merge bar'
655 $ hg ci -m 'merge bar'
656 $ hg log --config diff.git=1 -pr .
656 $ hg log --config diff.git=1 -pr .
657 changeset: 20:163cfd7219f7
657 changeset: 20:163cfd7219f7
658 tag: tip
658 tag: tip
659 parent: 19:30d96aeaf27b
659 parent: 19:30d96aeaf27b
660 parent: 18:1aa437659d19
660 parent: 18:1aa437659d19
661 user: test
661 user: test
662 date: Thu Jan 01 00:00:00 1970 +0000
662 date: Thu Jan 01 00:00:00 1970 +0000
663 summary: merge bar
663 summary: merge bar
664
664
665 diff --git a/a b/aa
665 diff --git a/a b/aa
666 copy from a
666 copy from a
667 copy to aa
667 copy to aa
668 diff --git a/cc b/cc
668 diff --git a/cc b/cc
669 --- a/cc
669 --- a/cc
670 +++ b/cc
670 +++ b/cc
671 @@ -1,1 +1,5 @@
671 @@ -1,1 +1,5 @@
672 +<<<<<<< working copy: 30d96aeaf27b - test: aa
672 +<<<<<<< working copy: 30d96aeaf27b - test: aa
673 dd
673 dd
674 +=======
674 +=======
675 +cc
675 +cc
676 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
676 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
677 diff --git a/z b/zz
677 diff --git a/z b/zz
678 rename from z
678 rename from z
679 rename to zz
679 rename to zz
680
680
681 $ hg debugrename aa
681 $ hg debugrename aa
682 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
682 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
683 $ hg debugrename zz
683 $ hg debugrename zz
684 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
684 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
685 $ hg debugrename cc
685 $ hg debugrename cc
686 cc not renamed
686 cc not renamed
687 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -m 'merge bar (amend message)' --edit
687 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -m 'merge bar (amend message)' --edit
688 HGEDITFORM=commit.amend.merge
688 HGEDITFORM=commit.amend.merge
689 $ hg log --config diff.git=1 -pr .
689 $ hg log --config diff.git=1 -pr .
690 changeset: 21:bca52d4ed186
690 changeset: 21:bca52d4ed186
691 tag: tip
691 tag: tip
692 parent: 19:30d96aeaf27b
692 parent: 19:30d96aeaf27b
693 parent: 18:1aa437659d19
693 parent: 18:1aa437659d19
694 user: test
694 user: test
695 date: Thu Jan 01 00:00:00 1970 +0000
695 date: Thu Jan 01 00:00:00 1970 +0000
696 summary: merge bar (amend message)
696 summary: merge bar (amend message)
697
697
698 diff --git a/a b/aa
698 diff --git a/a b/aa
699 copy from a
699 copy from a
700 copy to aa
700 copy to aa
701 diff --git a/cc b/cc
701 diff --git a/cc b/cc
702 --- a/cc
702 --- a/cc
703 +++ b/cc
703 +++ b/cc
704 @@ -1,1 +1,5 @@
704 @@ -1,1 +1,5 @@
705 +<<<<<<< working copy: 30d96aeaf27b - test: aa
705 +<<<<<<< working copy: 30d96aeaf27b - test: aa
706 dd
706 dd
707 +=======
707 +=======
708 +cc
708 +cc
709 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
709 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
710 diff --git a/z b/zz
710 diff --git a/z b/zz
711 rename from z
711 rename from z
712 rename to zz
712 rename to zz
713
713
714 $ hg debugrename aa
714 $ hg debugrename aa
715 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
715 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
716 $ hg debugrename zz
716 $ hg debugrename zz
717 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
717 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
718 $ hg debugrename cc
718 $ hg debugrename cc
719 cc not renamed
719 cc not renamed
720 $ hg mv zz z
720 $ hg mv zz z
721 $ hg ci --amend -m 'merge bar (undo rename)'
721 $ hg ci --amend -m 'merge bar (undo rename)'
722 $ hg log --config diff.git=1 -pr .
722 $ hg log --config diff.git=1 -pr .
723 changeset: 22:12594a98ca3f
723 changeset: 22:12594a98ca3f
724 tag: tip
724 tag: tip
725 parent: 19:30d96aeaf27b
725 parent: 19:30d96aeaf27b
726 parent: 18:1aa437659d19
726 parent: 18:1aa437659d19
727 user: test
727 user: test
728 date: Thu Jan 01 00:00:00 1970 +0000
728 date: Thu Jan 01 00:00:00 1970 +0000
729 summary: merge bar (undo rename)
729 summary: merge bar (undo rename)
730
730
731 diff --git a/a b/aa
731 diff --git a/a b/aa
732 copy from a
732 copy from a
733 copy to aa
733 copy to aa
734 diff --git a/cc b/cc
734 diff --git a/cc b/cc
735 --- a/cc
735 --- a/cc
736 +++ b/cc
736 +++ b/cc
737 @@ -1,1 +1,5 @@
737 @@ -1,1 +1,5 @@
738 +<<<<<<< working copy: 30d96aeaf27b - test: aa
738 +<<<<<<< working copy: 30d96aeaf27b - test: aa
739 dd
739 dd
740 +=======
740 +=======
741 +cc
741 +cc
742 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
742 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
743
743
744 $ hg debugrename z
744 $ hg debugrename z
745 z not renamed
745 z not renamed
746
746
747 Amend a merge changeset (with renames during the merge):
747 Amend a merge changeset (with renames during the merge):
748
748
749 $ hg up -q bar
749 $ hg up -q bar
750 $ echo x > x
750 $ echo x > x
751 $ hg add x
751 $ hg add x
752 $ hg ci -m x
752 $ hg ci -m x
753 $ hg up -q default
753 $ hg up -q default
754 $ hg merge -q bar
754 $ hg merge -q bar
755 $ hg mv aa aaa
755 $ hg mv aa aaa
756 $ echo aa >> aaa
756 $ echo aa >> aaa
757 $ hg ci -m 'merge bar again'
757 $ hg ci -m 'merge bar again'
758 $ hg log --config diff.git=1 -pr .
758 $ hg log --config diff.git=1 -pr .
759 changeset: 24:dffde028b388
759 changeset: 24:dffde028b388
760 tag: tip
760 tag: tip
761 parent: 22:12594a98ca3f
761 parent: 22:12594a98ca3f
762 parent: 23:4c94d5bc65f5
762 parent: 23:4c94d5bc65f5
763 user: test
763 user: test
764 date: Thu Jan 01 00:00:00 1970 +0000
764 date: Thu Jan 01 00:00:00 1970 +0000
765 summary: merge bar again
765 summary: merge bar again
766
766
767 diff --git a/aa b/aa
767 diff --git a/aa b/aa
768 deleted file mode 100644
768 deleted file mode 100644
769 --- a/aa
769 --- a/aa
770 +++ /dev/null
770 +++ /dev/null
771 @@ -1,2 +0,0 @@
771 @@ -1,2 +0,0 @@
772 -a
772 -a
773 -a
773 -a
774 diff --git a/aaa b/aaa
774 diff --git a/aaa b/aaa
775 new file mode 100644
775 new file mode 100644
776 --- /dev/null
776 --- /dev/null
777 +++ b/aaa
777 +++ b/aaa
778 @@ -0,0 +1,3 @@
778 @@ -0,0 +1,3 @@
779 +a
779 +a
780 +a
780 +a
781 +aa
781 +aa
782 diff --git a/x b/x
782 diff --git a/x b/x
783 new file mode 100644
783 new file mode 100644
784 --- /dev/null
784 --- /dev/null
785 +++ b/x
785 +++ b/x
786 @@ -0,0 +1,1 @@
786 @@ -0,0 +1,1 @@
787 +x
787 +x
788
788
789 $ hg debugrename aaa
789 $ hg debugrename aaa
790 aaa renamed from aa:37d9b5d994eab34eda9c16b195ace52c7b129980
790 aaa renamed from aa:37d9b5d994eab34eda9c16b195ace52c7b129980
791 $ hg mv aaa aa
791 $ hg mv aaa aa
792 $ hg ci --amend -m 'merge bar again (undo rename)'
792 $ hg ci --amend -m 'merge bar again (undo rename)'
793 $ hg log --config diff.git=1 -pr .
793 $ hg log --config diff.git=1 -pr .
794 changeset: 25:18e3ba160489
794 changeset: 25:18e3ba160489
795 tag: tip
795 tag: tip
796 parent: 22:12594a98ca3f
796 parent: 22:12594a98ca3f
797 parent: 23:4c94d5bc65f5
797 parent: 23:4c94d5bc65f5
798 user: test
798 user: test
799 date: Thu Jan 01 00:00:00 1970 +0000
799 date: Thu Jan 01 00:00:00 1970 +0000
800 summary: merge bar again (undo rename)
800 summary: merge bar again (undo rename)
801
801
802 diff --git a/aa b/aa
802 diff --git a/aa b/aa
803 --- a/aa
803 --- a/aa
804 +++ b/aa
804 +++ b/aa
805 @@ -1,2 +1,3 @@
805 @@ -1,2 +1,3 @@
806 a
806 a
807 a
807 a
808 +aa
808 +aa
809 diff --git a/x b/x
809 diff --git a/x b/x
810 new file mode 100644
810 new file mode 100644
811 --- /dev/null
811 --- /dev/null
812 +++ b/x
812 +++ b/x
813 @@ -0,0 +1,1 @@
813 @@ -0,0 +1,1 @@
814 +x
814 +x
815
815
816 $ hg debugrename aa
816 $ hg debugrename aa
817 aa not renamed
817 aa not renamed
818 $ hg debugrename -r '.^' aa
818 $ hg debugrename -r '.^' aa
819 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
819 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
820
820
821 Amend a merge changeset (with manifest-level conflicts):
821 Amend a merge changeset (with manifest-level conflicts):
822
822
823 $ hg up -q bar
823 $ hg up -q bar
824 $ hg rm aa
824 $ hg rm aa
825 $ hg ci -m 'rm aa'
825 $ hg ci -m 'rm aa'
826 $ hg up -q default
826 $ hg up -q default
827 $ echo aa >> aa
827 $ echo aa >> aa
828 $ hg ci -m aa
828 $ hg ci -m aa
829 $ hg merge -q bar --config ui.interactive=True << EOF
829 $ hg merge -q bar --config ui.interactive=True << EOF
830 > c
830 > c
831 > EOF
831 > EOF
832 local [working copy] changed aa which other [merge rev] deleted
832 local [working copy] changed aa which other [merge rev] deleted
833 use (c)hanged version, (d)elete, or leave (u)nresolved? c
833 use (c)hanged version, (d)elete, or leave (u)nresolved? c
834 $ hg ci -m 'merge bar (with conflicts)'
834 $ hg ci -m 'merge bar (with conflicts)'
835 $ hg log --config diff.git=1 -pr .
835 $ hg log --config diff.git=1 -pr .
836 changeset: 28:b4c3035e2544
836 changeset: 28:b4c3035e2544
837 tag: tip
837 tag: tip
838 parent: 27:4b216ca5ba97
838 parent: 27:4b216ca5ba97
839 parent: 26:67db8847a540
839 parent: 26:67db8847a540
840 user: test
840 user: test
841 date: Thu Jan 01 00:00:00 1970 +0000
841 date: Thu Jan 01 00:00:00 1970 +0000
842 summary: merge bar (with conflicts)
842 summary: merge bar (with conflicts)
843
843
844
844
845 $ hg rm aa
845 $ hg rm aa
846 $ hg ci --amend -m 'merge bar (with conflicts, amended)'
846 $ hg ci --amend -m 'merge bar (with conflicts, amended)'
847 $ hg log --config diff.git=1 -pr .
847 $ hg log --config diff.git=1 -pr .
848 changeset: 29:1205ed810051
848 changeset: 29:1205ed810051
849 tag: tip
849 tag: tip
850 parent: 27:4b216ca5ba97
850 parent: 27:4b216ca5ba97
851 parent: 26:67db8847a540
851 parent: 26:67db8847a540
852 user: test
852 user: test
853 date: Thu Jan 01 00:00:00 1970 +0000
853 date: Thu Jan 01 00:00:00 1970 +0000
854 summary: merge bar (with conflicts, amended)
854 summary: merge bar (with conflicts, amended)
855
855
856 diff --git a/aa b/aa
856 diff --git a/aa b/aa
857 deleted file mode 100644
857 deleted file mode 100644
858 --- a/aa
858 --- a/aa
859 +++ /dev/null
859 +++ /dev/null
860 @@ -1,4 +0,0 @@
860 @@ -1,4 +0,0 @@
861 -a
861 -a
862 -a
862 -a
863 -aa
863 -aa
864 -aa
864 -aa
865
865
866 Issue 3445: amending with --close-branch a commit that created a new head should fail
866 Issue 3445: amending with --close-branch a commit that created a new head should fail
867 This shouldn't be possible:
867 This shouldn't be possible:
868
868
869 $ hg up -q default
869 $ hg up -q default
870 $ hg branch closewithamend
870 $ hg branch closewithamend
871 marked working directory as branch closewithamend
871 marked working directory as branch closewithamend
872 $ echo foo > foo
872 $ echo foo > foo
873 $ hg add foo
873 $ hg add foo
874 $ hg ci -m..
874 $ hg ci -m..
875 $ hg ci --amend --close-branch -m 'closing'
875 $ hg ci --amend --close-branch -m 'closing'
876 abort: can only close branch heads
876 abort: can only close branch heads
877 [255]
877 [255]
878
878
879 This silliness fails:
879 This silliness fails:
880
880
881 $ hg branch silliness
881 $ hg branch silliness
882 marked working directory as branch silliness
882 marked working directory as branch silliness
883 $ echo b >> b
883 $ echo b >> b
884 $ hg ci --close-branch -m'open and close'
884 $ hg ci --close-branch -m'open and close'
885 abort: can only close branch heads
885 abort: can only close branch heads
886 [255]
886 [255]
887
887
888 Test that amend with --secret creates new secret changeset forcibly
888 Test that amend with --secret creates new secret changeset forcibly
889 ---------------------------------------------------------------------
889 ---------------------------------------------------------------------
890
890
891 $ hg phase '.^::.'
891 $ hg phase '.^::.'
892 29: draft
892 29: draft
893 30: draft
893 30: draft
894 $ hg commit --amend --secret -m 'amend as secret' -q
894 $ hg commit --amend --secret -m 'amend as secret' -q
895 $ hg phase '.^::.'
895 $ hg phase '.^::.'
896 29: draft
896 29: draft
897 31: secret
897 31: secret
898
898
899 Test that amend with --edit invokes editor forcibly
899 Test that amend with --edit invokes editor forcibly
900 ---------------------------------------------------
900 ---------------------------------------------------
901
901
902 $ hg parents --template "{desc}\n"
902 $ hg parents --template "{desc}\n"
903 amend as secret
903 amend as secret
904 $ HGEDITOR=cat hg commit --amend -m "editor should be suppressed"
904 $ HGEDITOR=cat hg commit --amend -m "editor should be suppressed"
905 $ hg parents --template "{desc}\n"
905 $ hg parents --template "{desc}\n"
906 editor should be suppressed
906 editor should be suppressed
907
907
908 $ hg status --rev '.^1::.'
908 $ hg status --rev '.^1::.'
909 A foo
909 A foo
910 $ HGEDITOR=cat hg commit --amend -m "editor should be invoked" --edit
910 $ HGEDITOR=cat hg commit --amend -m "editor should be invoked" --edit
911 editor should be invoked
911 editor should be invoked
912
912
913
913
914 HG: Enter commit message. Lines beginning with 'HG:' are removed.
914 HG: Enter commit message. Lines beginning with 'HG:' are removed.
915 HG: Leave message empty to abort commit.
915 HG: Leave message empty to abort commit.
916 HG: --
916 HG: --
917 HG: user: test
917 HG: user: test
918 HG: branch 'silliness'
918 HG: branch 'silliness'
919 HG: added foo
919 HG: added foo
920 $ hg parents --template "{desc}\n"
920 $ hg parents --template "{desc}\n"
921 editor should be invoked
921 editor should be invoked
922
922
923 Test that "diff()" in committemplate works correctly for amending
923 Test that "diff()" in committemplate works correctly for amending
924 -----------------------------------------------------------------
924 -----------------------------------------------------------------
925
925
926 $ cat >> .hg/hgrc <<EOF
926 $ cat >> .hg/hgrc <<EOF
927 > [committemplate]
927 > [committemplate]
928 > changeset.commit.amend = {desc}\n
928 > changeset.commit.amend = {desc}\n
929 > HG: M: {file_mods}
929 > HG: M: {file_mods}
930 > HG: A: {file_adds}
930 > HG: A: {file_adds}
931 > HG: R: {file_dels}
931 > HG: R: {file_dels}
932 > {splitlines(diff()) % 'HG: {line}\n'}
932 > {splitlines(diff()) % 'HG: {line}\n'}
933 > EOF
933 > EOF
934
934
935 $ hg parents --template "M: {file_mods}\nA: {file_adds}\nR: {file_dels}\n"
935 $ hg parents --template "M: {file_mods}\nA: {file_adds}\nR: {file_dels}\n"
936 M:
936 M:
937 A: foo
937 A: foo
938 R:
938 R:
939 $ hg status -amr
939 $ hg status -amr
940 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo"
940 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo"
941 expecting diff of foo
941 expecting diff of foo
942
942
943 HG: M:
943 HG: M:
944 HG: A: foo
944 HG: A: foo
945 HG: R:
945 HG: R:
946 HG: diff -r 1205ed810051 foo
946 HG: diff -r 1205ed810051 foo
947 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
947 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
948 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
948 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
949 HG: @@ -0,0 +1,1 @@
949 HG: @@ -0,0 +1,1 @@
950 HG: +foo
950 HG: +foo
951
951
952 $ echo y > y
952 $ echo y > y
953 $ hg add y
953 $ hg add y
954 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo and y"
954 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo and y"
955 expecting diff of foo and y
955 expecting diff of foo and y
956
956
957 HG: M:
957 HG: M:
958 HG: A: foo y
958 HG: A: foo y
959 HG: R:
959 HG: R:
960 HG: diff -r 1205ed810051 foo
960 HG: diff -r 1205ed810051 foo
961 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
961 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
962 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
962 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
963 HG: @@ -0,0 +1,1 @@
963 HG: @@ -0,0 +1,1 @@
964 HG: +foo
964 HG: +foo
965 HG: diff -r 1205ed810051 y
965 HG: diff -r 1205ed810051 y
966 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
966 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
967 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
967 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
968 HG: @@ -0,0 +1,1 @@
968 HG: @@ -0,0 +1,1 @@
969 HG: +y
969 HG: +y
970
970
971 $ hg rm a
971 $ hg rm a
972 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo and y"
972 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo and y"
973 expecting diff of a, foo and y
973 expecting diff of a, foo and y
974
974
975 HG: M:
975 HG: M:
976 HG: A: foo y
976 HG: A: foo y
977 HG: R: a
977 HG: R: a
978 HG: diff -r 1205ed810051 a
978 HG: diff -r 1205ed810051 a
979 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
979 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
980 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
980 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
981 HG: @@ -1,2 +0,0 @@
981 HG: @@ -1,2 +0,0 @@
982 HG: -a
982 HG: -a
983 HG: -a
983 HG: -a
984 HG: diff -r 1205ed810051 foo
984 HG: diff -r 1205ed810051 foo
985 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
985 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
986 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
986 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
987 HG: @@ -0,0 +1,1 @@
987 HG: @@ -0,0 +1,1 @@
988 HG: +foo
988 HG: +foo
989 HG: diff -r 1205ed810051 y
989 HG: diff -r 1205ed810051 y
990 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
990 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
991 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
991 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
992 HG: @@ -0,0 +1,1 @@
992 HG: @@ -0,0 +1,1 @@
993 HG: +y
993 HG: +y
994
994
995 $ hg rm x
995 $ hg rm x
996 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo, x and y"
996 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo, x and y"
997 expecting diff of a, foo, x and y
997 expecting diff of a, foo, x and y
998
998
999 HG: M:
999 HG: M:
1000 HG: A: foo y
1000 HG: A: foo y
1001 HG: R: a x
1001 HG: R: a x
1002 HG: diff -r 1205ed810051 a
1002 HG: diff -r 1205ed810051 a
1003 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1003 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1004 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1004 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1005 HG: @@ -1,2 +0,0 @@
1005 HG: @@ -1,2 +0,0 @@
1006 HG: -a
1006 HG: -a
1007 HG: -a
1007 HG: -a
1008 HG: diff -r 1205ed810051 foo
1008 HG: diff -r 1205ed810051 foo
1009 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1009 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1010 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1010 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1011 HG: @@ -0,0 +1,1 @@
1011 HG: @@ -0,0 +1,1 @@
1012 HG: +foo
1012 HG: +foo
1013 HG: diff -r 1205ed810051 x
1013 HG: diff -r 1205ed810051 x
1014 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1014 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1015 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1015 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1016 HG: @@ -1,1 +0,0 @@
1016 HG: @@ -1,1 +0,0 @@
1017 HG: -x
1017 HG: -x
1018 HG: diff -r 1205ed810051 y
1018 HG: diff -r 1205ed810051 y
1019 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1019 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1020 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1020 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1021 HG: @@ -0,0 +1,1 @@
1021 HG: @@ -0,0 +1,1 @@
1022 HG: +y
1022 HG: +y
1023
1023
1024 $ echo cccc >> cc
1024 $ echo cccc >> cc
1025 $ hg status -amr
1025 $ hg status -amr
1026 M cc
1026 M cc
1027 $ HGEDITOR=cat hg commit --amend -e -m "cc should be excluded" -X cc
1027 $ HGEDITOR=cat hg commit --amend -e -m "cc should be excluded" -X cc
1028 cc should be excluded
1028 cc should be excluded
1029
1029
1030 HG: M:
1030 HG: M:
1031 HG: A: foo y
1031 HG: A: foo y
1032 HG: R: a x
1032 HG: R: a x
1033 HG: diff -r 1205ed810051 a
1033 HG: diff -r 1205ed810051 a
1034 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1034 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1035 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1035 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1036 HG: @@ -1,2 +0,0 @@
1036 HG: @@ -1,2 +0,0 @@
1037 HG: -a
1037 HG: -a
1038 HG: -a
1038 HG: -a
1039 HG: diff -r 1205ed810051 foo
1039 HG: diff -r 1205ed810051 foo
1040 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1040 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1041 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1041 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1042 HG: @@ -0,0 +1,1 @@
1042 HG: @@ -0,0 +1,1 @@
1043 HG: +foo
1043 HG: +foo
1044 HG: diff -r 1205ed810051 x
1044 HG: diff -r 1205ed810051 x
1045 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1045 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1046 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1046 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1047 HG: @@ -1,1 +0,0 @@
1047 HG: @@ -1,1 +0,0 @@
1048 HG: -x
1048 HG: -x
1049 HG: diff -r 1205ed810051 y
1049 HG: diff -r 1205ed810051 y
1050 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1050 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1051 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1051 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1052 HG: @@ -0,0 +1,1 @@
1052 HG: @@ -0,0 +1,1 @@
1053 HG: +y
1053 HG: +y
1054
1054
1055 Check for issue4405
1055 Check for issue4405
1056 -------------------
1056 -------------------
1057
1057
1058 Setup the repo with a file that gets moved in a second commit.
1058 Setup the repo with a file that gets moved in a second commit.
1059 $ hg init repo
1059 $ hg init repo
1060 $ cd repo
1060 $ cd repo
1061 $ touch a0
1061 $ touch a0
1062 $ hg add a0
1062 $ hg add a0
1063 $ hg commit -m a0
1063 $ hg commit -m a0
1064 $ hg mv a0 a1
1064 $ hg mv a0 a1
1065 $ hg commit -m a1
1065 $ hg commit -m a1
1066 $ hg up -q 0
1066 $ hg up -q 0
1067 $ hg log -G --template '{rev} {desc}'
1067 $ hg log -G --template '{rev} {desc}'
1068 o 1 a1
1068 o 1 a1
1069 |
1069 |
1070 @ 0 a0
1070 @ 0 a0
1071
1071
1072
1072
1073 Now we branch the repro, but re-use the file contents, so we have a divergence
1073 Now we branch the repro, but re-use the file contents, so we have a divergence
1074 in the file revlog topology and the changelog topology.
1074 in the file revlog topology and the changelog topology.
1075 $ hg revert --rev 1 --all
1075 $ hg revert --rev 1 --all
1076 removing a0
1076 removing a0
1077 adding a1
1077 adding a1
1078 $ hg ci -qm 'a1-amend'
1078 $ hg ci -qm 'a1-amend'
1079 $ hg log -G --template '{rev} {desc}'
1079 $ hg log -G --template '{rev} {desc}'
1080 @ 2 a1-amend
1080 @ 2 a1-amend
1081 |
1081 |
1082 | o 1 a1
1082 | o 1 a1
1083 |/
1083 |/
1084 o 0 a0
1084 o 0 a0
1085
1085
1086
1086
1087 The way mercurial does amends is by folding the working copy and old commit
1087 The way mercurial does amends is by folding the working copy and old commit
1088 together into another commit (rev 3). During this process, _findlimit is called
1088 together into another commit (rev 3). During this process, _findlimit is called
1089 to check how far back to look for the transitive closure of file copy
1089 to check how far back to look for the transitive closure of file copy
1090 information, but due to the divergence of the filelog and changelog graph
1090 information, but due to the divergence of the filelog and changelog graph
1091 topologies, before _findlimit was fixed, it returned a rev which was not far
1091 topologies, before _findlimit was fixed, it returned a rev which was not far
1092 enough back in this case.
1092 enough back in this case.
1093 $ hg mv a1 a2
1093 $ hg mv a1 a2
1094 $ hg status --copies --rev 0
1094 $ hg status --copies --rev 0
1095 A a2
1095 A a2
1096 a0
1096 a0
1097 R a0
1097 R a0
1098 $ hg ci --amend -q
1098 $ hg ci --amend -q
1099 $ hg log -G --template '{rev} {desc}'
1099 $ hg log -G --template '{rev} {desc}'
1100 @ 3 a1-amend
1100 @ 3 a1-amend
1101 |
1101 |
1102 | o 1 a1
1102 | o 1 a1
1103 |/
1103 |/
1104 o 0 a0
1104 o 0 a0
1105
1105
1106
1106
1107 Before the fix, the copy information was lost.
1107 Before the fix, the copy information was lost.
1108 $ hg status --copies --rev 0
1108 $ hg status --copies --rev 0
1109 A a2
1109 A a2
1110 a0
1110 a0
1111 R a0
1111 R a0
1112 $ cd ..
1112 $ cd ..
1113
1113
1114 Check that amend properly preserve rename from directory rename (issue-4516)
1114 Check that amend properly preserve rename from directory rename (issue-4516)
1115
1115
1116 If a parent of the merge renames a full directory, any files added to the old
1116 If a parent of the merge renames a full directory, any files added to the old
1117 directory in the other parent will be renamed to the new directory. For some
1117 directory in the other parent will be renamed to the new directory. For some
1118 reason, the rename metadata was when amending such merge. This test ensure we
1118 reason, the rename metadata was when amending such merge. This test ensure we
1119 do not regress. We have a dedicated repo because it needs a setup with renamed
1119 do not regress. We have a dedicated repo because it needs a setup with renamed
1120 directory)
1120 directory)
1121
1121
1122 $ hg init issue4516
1122 $ hg init issue4516
1123 $ cd issue4516
1123 $ cd issue4516
1124 $ mkdir olddirname
1124 $ mkdir olddirname
1125 $ echo line1 > olddirname/commonfile.py
1125 $ echo line1 > olddirname/commonfile.py
1126 $ hg add olddirname/commonfile.py
1126 $ hg add olddirname/commonfile.py
1127 $ hg ci -m first
1127 $ hg ci -m first
1128
1128
1129 $ hg branch newdirname
1129 $ hg branch newdirname
1130 marked working directory as branch newdirname
1130 marked working directory as branch newdirname
1131 (branches are permanent and global, did you want a bookmark?)
1131 (branches are permanent and global, did you want a bookmark?)
1132 $ hg mv olddirname newdirname
1132 $ hg mv olddirname newdirname
1133 moving olddirname/commonfile.py to newdirname/commonfile.py
1133 moving olddirname/commonfile.py to newdirname/commonfile.py
1134 $ hg ci -m rename
1134 $ hg ci -m rename
1135
1135
1136 $ hg update default
1136 $ hg update default
1137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1138 $ echo line1 > olddirname/newfile.py
1138 $ echo line1 > olddirname/newfile.py
1139 $ hg add olddirname/newfile.py
1139 $ hg add olddirname/newfile.py
1140 $ hg ci -m log
1140 $ hg ci -m log
1141
1141
1142 $ hg up newdirname
1142 $ hg up newdirname
1143 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1143 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1144 $ # create newdirname/newfile.py
1144 $ # create newdirname/newfile.py
1145 $ hg merge default
1145 $ hg merge default
1146 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1146 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1147 (branch merge, don't forget to commit)
1147 (branch merge, don't forget to commit)
1148 $ hg ci -m add
1148 $ hg ci -m add
1149 $
1149 $
1150 $ hg debugrename newdirname/newfile.py
1150 $ hg debugrename newdirname/newfile.py
1151 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def
1151 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def
1152 $ hg status -C --change .
1152 $ hg status -C --change .
1153 A newdirname/newfile.py
1153 A newdirname/newfile.py
1154 $ hg status -C --rev 1
1154 $ hg status -C --rev 1
1155 A newdirname/newfile.py
1155 A newdirname/newfile.py
1156 $ hg status -C --rev 2
1156 $ hg status -C --rev 2
1157 A newdirname/commonfile.py
1157 A newdirname/commonfile.py
1158 olddirname/commonfile.py
1158 olddirname/commonfile.py
1159 A newdirname/newfile.py
1159 A newdirname/newfile.py
1160 olddirname/newfile.py
1160 olddirname/newfile.py
1161 R olddirname/commonfile.py
1161 R olddirname/commonfile.py
1162 R olddirname/newfile.py
1162 R olddirname/newfile.py
1163 $ hg debugindex newdirname/newfile.py
1163 $ hg debugindex newdirname/newfile.py
1164 rev offset length linkrev nodeid p1 p2
1164 rev linkrev nodeid p1 p2
1165 0 0 89 3 34a4d536c0c0 000000000000 000000000000
1165 0 3 34a4d536c0c0 000000000000 000000000000
1166
1166
1167 $ echo a >> newdirname/commonfile.py
1167 $ echo a >> newdirname/commonfile.py
1168 $ hg ci --amend -m bug
1168 $ hg ci --amend -m bug
1169 $ hg debugrename newdirname/newfile.py
1169 $ hg debugrename newdirname/newfile.py
1170 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def
1170 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def
1171 $ hg debugindex newdirname/newfile.py
1171 $ hg debugindex newdirname/newfile.py
1172 rev offset length linkrev nodeid p1 p2
1172 rev linkrev nodeid p1 p2
1173 0 0 89 3 34a4d536c0c0 000000000000 000000000000
1173 0 3 34a4d536c0c0 000000000000 000000000000
1174
1174
1175 #if execbit
1175 #if execbit
1176
1176
1177 Test if amend preserves executable bit changes
1177 Test if amend preserves executable bit changes
1178 $ chmod +x newdirname/commonfile.py
1178 $ chmod +x newdirname/commonfile.py
1179 $ hg ci -m chmod
1179 $ hg ci -m chmod
1180 $ hg ci --amend -m "chmod amended"
1180 $ hg ci --amend -m "chmod amended"
1181 $ hg ci --amend -m "chmod amended second time"
1181 $ hg ci --amend -m "chmod amended second time"
1182 $ hg log -p --git -r .
1182 $ hg log -p --git -r .
1183 changeset: 7:b1326f52dddf
1183 changeset: 7:b1326f52dddf
1184 branch: newdirname
1184 branch: newdirname
1185 tag: tip
1185 tag: tip
1186 parent: 4:7fd235f7cb2f
1186 parent: 4:7fd235f7cb2f
1187 user: test
1187 user: test
1188 date: Thu Jan 01 00:00:00 1970 +0000
1188 date: Thu Jan 01 00:00:00 1970 +0000
1189 summary: chmod amended second time
1189 summary: chmod amended second time
1190
1190
1191 diff --git a/newdirname/commonfile.py b/newdirname/commonfile.py
1191 diff --git a/newdirname/commonfile.py b/newdirname/commonfile.py
1192 old mode 100644
1192 old mode 100644
1193 new mode 100755
1193 new mode 100755
1194
1194
1195 #endif
1195 #endif
1196
1196
1197 Test amend with file inclusion options
1197 Test amend with file inclusion options
1198 --------------------------------------
1198 --------------------------------------
1199
1199
1200 These tests ensure that we are always amending some files that were part of the
1200 These tests ensure that we are always amending some files that were part of the
1201 pre-amend commit. We want to test that the remaining files in the pre-amend
1201 pre-amend commit. We want to test that the remaining files in the pre-amend
1202 commit were not changed in the amended commit. We do so by performing a diff of
1202 commit were not changed in the amended commit. We do so by performing a diff of
1203 the amended commit against its parent commit.
1203 the amended commit against its parent commit.
1204 $ cd ..
1204 $ cd ..
1205 $ hg init testfileinclusions
1205 $ hg init testfileinclusions
1206 $ cd testfileinclusions
1206 $ cd testfileinclusions
1207 $ echo a > a
1207 $ echo a > a
1208 $ echo b > b
1208 $ echo b > b
1209 $ hg commit -Aqm "Adding a and b"
1209 $ hg commit -Aqm "Adding a and b"
1210
1210
1211 Only add changes to a particular file
1211 Only add changes to a particular file
1212 $ echo a >> a
1212 $ echo a >> a
1213 $ echo b >> b
1213 $ echo b >> b
1214 $ hg commit --amend -I a
1214 $ hg commit --amend -I a
1215 $ hg diff --git -r null -r .
1215 $ hg diff --git -r null -r .
1216 diff --git a/a b/a
1216 diff --git a/a b/a
1217 new file mode 100644
1217 new file mode 100644
1218 --- /dev/null
1218 --- /dev/null
1219 +++ b/a
1219 +++ b/a
1220 @@ -0,0 +1,2 @@
1220 @@ -0,0 +1,2 @@
1221 +a
1221 +a
1222 +a
1222 +a
1223 diff --git a/b b/b
1223 diff --git a/b b/b
1224 new file mode 100644
1224 new file mode 100644
1225 --- /dev/null
1225 --- /dev/null
1226 +++ b/b
1226 +++ b/b
1227 @@ -0,0 +1,1 @@
1227 @@ -0,0 +1,1 @@
1228 +b
1228 +b
1229
1229
1230 $ echo a >> a
1230 $ echo a >> a
1231 $ hg commit --amend b
1231 $ hg commit --amend b
1232 $ hg diff --git -r null -r .
1232 $ hg diff --git -r null -r .
1233 diff --git a/a b/a
1233 diff --git a/a b/a
1234 new file mode 100644
1234 new file mode 100644
1235 --- /dev/null
1235 --- /dev/null
1236 +++ b/a
1236 +++ b/a
1237 @@ -0,0 +1,2 @@
1237 @@ -0,0 +1,2 @@
1238 +a
1238 +a
1239 +a
1239 +a
1240 diff --git a/b b/b
1240 diff --git a/b b/b
1241 new file mode 100644
1241 new file mode 100644
1242 --- /dev/null
1242 --- /dev/null
1243 +++ b/b
1243 +++ b/b
1244 @@ -0,0 +1,2 @@
1244 @@ -0,0 +1,2 @@
1245 +b
1245 +b
1246 +b
1246 +b
1247
1247
1248 Exclude changes to a particular file
1248 Exclude changes to a particular file
1249 $ echo b >> b
1249 $ echo b >> b
1250 $ hg commit --amend -X a
1250 $ hg commit --amend -X a
1251 $ hg diff --git -r null -r .
1251 $ hg diff --git -r null -r .
1252 diff --git a/a b/a
1252 diff --git a/a b/a
1253 new file mode 100644
1253 new file mode 100644
1254 --- /dev/null
1254 --- /dev/null
1255 +++ b/a
1255 +++ b/a
1256 @@ -0,0 +1,2 @@
1256 @@ -0,0 +1,2 @@
1257 +a
1257 +a
1258 +a
1258 +a
1259 diff --git a/b b/b
1259 diff --git a/b b/b
1260 new file mode 100644
1260 new file mode 100644
1261 --- /dev/null
1261 --- /dev/null
1262 +++ b/b
1262 +++ b/b
1263 @@ -0,0 +1,3 @@
1263 @@ -0,0 +1,3 @@
1264 +b
1264 +b
1265 +b
1265 +b
1266 +b
1266 +b
1267
1267
1268 Check the addremove flag
1268 Check the addremove flag
1269 $ echo c > c
1269 $ echo c > c
1270 $ rm a
1270 $ rm a
1271 $ hg commit --amend -A
1271 $ hg commit --amend -A
1272 removing a
1272 removing a
1273 adding c
1273 adding c
1274 $ hg diff --git -r null -r .
1274 $ hg diff --git -r null -r .
1275 diff --git a/b b/b
1275 diff --git a/b b/b
1276 new file mode 100644
1276 new file mode 100644
1277 --- /dev/null
1277 --- /dev/null
1278 +++ b/b
1278 +++ b/b
1279 @@ -0,0 +1,3 @@
1279 @@ -0,0 +1,3 @@
1280 +b
1280 +b
1281 +b
1281 +b
1282 +b
1282 +b
1283 diff --git a/c b/c
1283 diff --git a/c b/c
1284 new file mode 100644
1284 new file mode 100644
1285 --- /dev/null
1285 --- /dev/null
1286 +++ b/c
1286 +++ b/c
1287 @@ -0,0 +1,1 @@
1287 @@ -0,0 +1,1 @@
1288 +c
1288 +c
@@ -1,833 +1,833 b''
1 commit date test
1 commit date test
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ echo foo > foo
5 $ echo foo > foo
6 $ hg add foo
6 $ hg add foo
7 $ cat > $TESTTMP/checkeditform.sh <<EOF
7 $ cat > $TESTTMP/checkeditform.sh <<EOF
8 > env | grep HGEDITFORM
8 > env | grep HGEDITFORM
9 > true
9 > true
10 > EOF
10 > EOF
11 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg commit -m ""
11 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg commit -m ""
12 HGEDITFORM=commit.normal.normal
12 HGEDITFORM=commit.normal.normal
13 abort: empty commit message
13 abort: empty commit message
14 [255]
14 [255]
15 $ hg commit -d '0 0' -m commit-1
15 $ hg commit -d '0 0' -m commit-1
16 $ echo foo >> foo
16 $ echo foo >> foo
17 $ hg commit -d '1 4444444' -m commit-3
17 $ hg commit -d '1 4444444' -m commit-3
18 hg: parse error: impossible time zone offset: 4444444
18 hg: parse error: impossible time zone offset: 4444444
19 [255]
19 [255]
20 $ hg commit -d '1 15.1' -m commit-4
20 $ hg commit -d '1 15.1' -m commit-4
21 hg: parse error: invalid date: '1\t15.1'
21 hg: parse error: invalid date: '1\t15.1'
22 [255]
22 [255]
23 $ hg commit -d 'foo bar' -m commit-5
23 $ hg commit -d 'foo bar' -m commit-5
24 hg: parse error: invalid date: 'foo bar'
24 hg: parse error: invalid date: 'foo bar'
25 [255]
25 [255]
26 $ hg commit -d ' 1 4444' -m commit-6
26 $ hg commit -d ' 1 4444' -m commit-6
27 $ hg commit -d '111111111111 0' -m commit-7
27 $ hg commit -d '111111111111 0' -m commit-7
28 hg: parse error: date exceeds 32 bits: 111111111111
28 hg: parse error: date exceeds 32 bits: 111111111111
29 [255]
29 [255]
30 $ hg commit -d '-111111111111 0' -m commit-7
30 $ hg commit -d '-111111111111 0' -m commit-7
31 hg: parse error: date exceeds 32 bits: -111111111111
31 hg: parse error: date exceeds 32 bits: -111111111111
32 [255]
32 [255]
33 $ echo foo >> foo
33 $ echo foo >> foo
34 $ hg commit -d '1901-12-13 20:45:52 +0000' -m commit-7-2
34 $ hg commit -d '1901-12-13 20:45:52 +0000' -m commit-7-2
35 $ echo foo >> foo
35 $ echo foo >> foo
36 $ hg commit -d '-2147483648 0' -m commit-7-3
36 $ hg commit -d '-2147483648 0' -m commit-7-3
37 $ hg log -T '{rev} {date|isodatesec}\n' -l2
37 $ hg log -T '{rev} {date|isodatesec}\n' -l2
38 3 1901-12-13 20:45:52 +0000
38 3 1901-12-13 20:45:52 +0000
39 2 1901-12-13 20:45:52 +0000
39 2 1901-12-13 20:45:52 +0000
40 $ hg commit -d '1901-12-13 20:45:51 +0000' -m commit-7
40 $ hg commit -d '1901-12-13 20:45:51 +0000' -m commit-7
41 hg: parse error: date exceeds 32 bits: -2147483649
41 hg: parse error: date exceeds 32 bits: -2147483649
42 [255]
42 [255]
43 $ hg commit -d '-2147483649 0' -m commit-7
43 $ hg commit -d '-2147483649 0' -m commit-7
44 hg: parse error: date exceeds 32 bits: -2147483649
44 hg: parse error: date exceeds 32 bits: -2147483649
45 [255]
45 [255]
46
46
47 commit added file that has been deleted
47 commit added file that has been deleted
48
48
49 $ echo bar > bar
49 $ echo bar > bar
50 $ hg add bar
50 $ hg add bar
51 $ rm bar
51 $ rm bar
52 $ hg commit -m commit-8
52 $ hg commit -m commit-8
53 nothing changed (1 missing files, see 'hg status')
53 nothing changed (1 missing files, see 'hg status')
54 [1]
54 [1]
55 $ hg commit -m commit-8-2 bar
55 $ hg commit -m commit-8-2 bar
56 abort: bar: file not found!
56 abort: bar: file not found!
57 [255]
57 [255]
58
58
59 $ hg -q revert -a --no-backup
59 $ hg -q revert -a --no-backup
60
60
61 $ mkdir dir
61 $ mkdir dir
62 $ echo boo > dir/file
62 $ echo boo > dir/file
63 $ hg add
63 $ hg add
64 adding dir/file
64 adding dir/file
65 $ hg -v commit -m commit-9 dir
65 $ hg -v commit -m commit-9 dir
66 committing files:
66 committing files:
67 dir/file
67 dir/file
68 committing manifest
68 committing manifest
69 committing changelog
69 committing changelog
70 committed changeset 4:1957363f1ced
70 committed changeset 4:1957363f1ced
71
71
72 $ echo > dir.file
72 $ echo > dir.file
73 $ hg add
73 $ hg add
74 adding dir.file
74 adding dir.file
75 $ hg commit -m commit-10 dir dir.file
75 $ hg commit -m commit-10 dir dir.file
76 abort: dir: no match under directory!
76 abort: dir: no match under directory!
77 [255]
77 [255]
78
78
79 $ echo >> dir/file
79 $ echo >> dir/file
80 $ mkdir bleh
80 $ mkdir bleh
81 $ mkdir dir2
81 $ mkdir dir2
82 $ cd bleh
82 $ cd bleh
83 $ hg commit -m commit-11 .
83 $ hg commit -m commit-11 .
84 abort: bleh: no match under directory!
84 abort: bleh: no match under directory!
85 [255]
85 [255]
86 $ hg commit -m commit-12 ../dir ../dir2
86 $ hg commit -m commit-12 ../dir ../dir2
87 abort: dir2: no match under directory!
87 abort: dir2: no match under directory!
88 [255]
88 [255]
89 $ hg -v commit -m commit-13 ../dir
89 $ hg -v commit -m commit-13 ../dir
90 committing files:
90 committing files:
91 dir/file
91 dir/file
92 committing manifest
92 committing manifest
93 committing changelog
93 committing changelog
94 committed changeset 5:a31d8f87544a
94 committed changeset 5:a31d8f87544a
95 $ cd ..
95 $ cd ..
96
96
97 $ hg commit -m commit-14 does-not-exist
97 $ hg commit -m commit-14 does-not-exist
98 abort: does-not-exist: * (glob)
98 abort: does-not-exist: * (glob)
99 [255]
99 [255]
100
100
101 #if symlink
101 #if symlink
102 $ ln -s foo baz
102 $ ln -s foo baz
103 $ hg commit -m commit-15 baz
103 $ hg commit -m commit-15 baz
104 abort: baz: file not tracked!
104 abort: baz: file not tracked!
105 [255]
105 [255]
106 $ rm baz
106 $ rm baz
107 #endif
107 #endif
108
108
109 $ touch quux
109 $ touch quux
110 $ hg commit -m commit-16 quux
110 $ hg commit -m commit-16 quux
111 abort: quux: file not tracked!
111 abort: quux: file not tracked!
112 [255]
112 [255]
113 $ echo >> dir/file
113 $ echo >> dir/file
114 $ hg -v commit -m commit-17 dir/file
114 $ hg -v commit -m commit-17 dir/file
115 committing files:
115 committing files:
116 dir/file
116 dir/file
117 committing manifest
117 committing manifest
118 committing changelog
118 committing changelog
119 committed changeset 6:32d054c9d085
119 committed changeset 6:32d054c9d085
120
120
121 An empty date was interpreted as epoch origin
121 An empty date was interpreted as epoch origin
122
122
123 $ echo foo >> foo
123 $ echo foo >> foo
124 $ hg commit -d '' -m commit-no-date --config devel.default-date=
124 $ hg commit -d '' -m commit-no-date --config devel.default-date=
125 $ hg tip --template '{date|isodate}\n' | grep '1970'
125 $ hg tip --template '{date|isodate}\n' | grep '1970'
126 [1]
126 [1]
127
127
128 Using the advanced --extra flag
128 Using the advanced --extra flag
129
129
130 $ echo "[extensions]" >> $HGRCPATH
130 $ echo "[extensions]" >> $HGRCPATH
131 $ echo "commitextras=" >> $HGRCPATH
131 $ echo "commitextras=" >> $HGRCPATH
132 $ hg status
132 $ hg status
133 ? quux
133 ? quux
134 $ hg add quux
134 $ hg add quux
135 $ hg commit -m "adding internal used extras" --extra amend_source=hash
135 $ hg commit -m "adding internal used extras" --extra amend_source=hash
136 abort: key 'amend_source' is used internally, can't be set manually
136 abort: key 'amend_source' is used internally, can't be set manually
137 [255]
137 [255]
138 $ hg commit -m "special chars in extra" --extra id@phab=214
138 $ hg commit -m "special chars in extra" --extra id@phab=214
139 abort: keys can only contain ascii letters, digits, '_' and '-'
139 abort: keys can only contain ascii letters, digits, '_' and '-'
140 [255]
140 [255]
141 $ hg commit -m "empty key" --extra =value
141 $ hg commit -m "empty key" --extra =value
142 abort: unable to parse '=value', keys can't be empty
142 abort: unable to parse '=value', keys can't be empty
143 [255]
143 [255]
144 $ hg commit -m "adding extras" --extra sourcehash=foo --extra oldhash=bar
144 $ hg commit -m "adding extras" --extra sourcehash=foo --extra oldhash=bar
145 $ hg log -r . -T '{extras % "{extra}\n"}'
145 $ hg log -r . -T '{extras % "{extra}\n"}'
146 branch=default
146 branch=default
147 oldhash=bar
147 oldhash=bar
148 sourcehash=foo
148 sourcehash=foo
149
149
150 Failed commit with --addremove should not update dirstate
150 Failed commit with --addremove should not update dirstate
151
151
152 $ echo foo > newfile
152 $ echo foo > newfile
153 $ hg status
153 $ hg status
154 ? newfile
154 ? newfile
155 $ HGEDITOR=false hg ci --addremove
155 $ HGEDITOR=false hg ci --addremove
156 adding newfile
156 adding newfile
157 abort: edit failed: false exited with status 1
157 abort: edit failed: false exited with status 1
158 [255]
158 [255]
159 $ hg status
159 $ hg status
160 ? newfile
160 ? newfile
161
161
162 Make sure we do not obscure unknown requires file entries (issue2649)
162 Make sure we do not obscure unknown requires file entries (issue2649)
163
163
164 $ echo foo >> foo
164 $ echo foo >> foo
165 $ echo fake >> .hg/requires
165 $ echo fake >> .hg/requires
166 $ hg commit -m bla
166 $ hg commit -m bla
167 abort: repository requires features unknown to this Mercurial: fake!
167 abort: repository requires features unknown to this Mercurial: fake!
168 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
168 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
169 [255]
169 [255]
170
170
171 $ cd ..
171 $ cd ..
172
172
173
173
174 partial subdir commit test
174 partial subdir commit test
175
175
176 $ hg init test2
176 $ hg init test2
177 $ cd test2
177 $ cd test2
178 $ mkdir foo
178 $ mkdir foo
179 $ echo foo > foo/foo
179 $ echo foo > foo/foo
180 $ mkdir bar
180 $ mkdir bar
181 $ echo bar > bar/bar
181 $ echo bar > bar/bar
182 $ hg add
182 $ hg add
183 adding bar/bar
183 adding bar/bar
184 adding foo/foo
184 adding foo/foo
185 $ HGEDITOR=cat hg ci -e -m commit-subdir-1 foo
185 $ HGEDITOR=cat hg ci -e -m commit-subdir-1 foo
186 commit-subdir-1
186 commit-subdir-1
187
187
188
188
189 HG: Enter commit message. Lines beginning with 'HG:' are removed.
189 HG: Enter commit message. Lines beginning with 'HG:' are removed.
190 HG: Leave message empty to abort commit.
190 HG: Leave message empty to abort commit.
191 HG: --
191 HG: --
192 HG: user: test
192 HG: user: test
193 HG: branch 'default'
193 HG: branch 'default'
194 HG: added foo/foo
194 HG: added foo/foo
195
195
196
196
197 $ hg ci -m commit-subdir-2 bar
197 $ hg ci -m commit-subdir-2 bar
198
198
199 subdir log 1
199 subdir log 1
200
200
201 $ hg log -v foo
201 $ hg log -v foo
202 changeset: 0:f97e73a25882
202 changeset: 0:f97e73a25882
203 user: test
203 user: test
204 date: Thu Jan 01 00:00:00 1970 +0000
204 date: Thu Jan 01 00:00:00 1970 +0000
205 files: foo/foo
205 files: foo/foo
206 description:
206 description:
207 commit-subdir-1
207 commit-subdir-1
208
208
209
209
210
210
211 subdir log 2
211 subdir log 2
212
212
213 $ hg log -v bar
213 $ hg log -v bar
214 changeset: 1:aa809156d50d
214 changeset: 1:aa809156d50d
215 tag: tip
215 tag: tip
216 user: test
216 user: test
217 date: Thu Jan 01 00:00:00 1970 +0000
217 date: Thu Jan 01 00:00:00 1970 +0000
218 files: bar/bar
218 files: bar/bar
219 description:
219 description:
220 commit-subdir-2
220 commit-subdir-2
221
221
222
222
223
223
224 full log
224 full log
225
225
226 $ hg log -v
226 $ hg log -v
227 changeset: 1:aa809156d50d
227 changeset: 1:aa809156d50d
228 tag: tip
228 tag: tip
229 user: test
229 user: test
230 date: Thu Jan 01 00:00:00 1970 +0000
230 date: Thu Jan 01 00:00:00 1970 +0000
231 files: bar/bar
231 files: bar/bar
232 description:
232 description:
233 commit-subdir-2
233 commit-subdir-2
234
234
235
235
236 changeset: 0:f97e73a25882
236 changeset: 0:f97e73a25882
237 user: test
237 user: test
238 date: Thu Jan 01 00:00:00 1970 +0000
238 date: Thu Jan 01 00:00:00 1970 +0000
239 files: foo/foo
239 files: foo/foo
240 description:
240 description:
241 commit-subdir-1
241 commit-subdir-1
242
242
243
243
244 $ cd ..
244 $ cd ..
245
245
246
246
247 dot and subdir commit test
247 dot and subdir commit test
248
248
249 $ hg init test3
249 $ hg init test3
250 $ echo commit-foo-subdir > commit-log-test
250 $ echo commit-foo-subdir > commit-log-test
251 $ cd test3
251 $ cd test3
252 $ mkdir foo
252 $ mkdir foo
253 $ echo foo content > foo/plain-file
253 $ echo foo content > foo/plain-file
254 $ hg add foo/plain-file
254 $ hg add foo/plain-file
255 $ HGEDITOR=cat hg ci --edit -l ../commit-log-test foo
255 $ HGEDITOR=cat hg ci --edit -l ../commit-log-test foo
256 commit-foo-subdir
256 commit-foo-subdir
257
257
258
258
259 HG: Enter commit message. Lines beginning with 'HG:' are removed.
259 HG: Enter commit message. Lines beginning with 'HG:' are removed.
260 HG: Leave message empty to abort commit.
260 HG: Leave message empty to abort commit.
261 HG: --
261 HG: --
262 HG: user: test
262 HG: user: test
263 HG: branch 'default'
263 HG: branch 'default'
264 HG: added foo/plain-file
264 HG: added foo/plain-file
265
265
266
266
267 $ echo modified foo content > foo/plain-file
267 $ echo modified foo content > foo/plain-file
268 $ hg ci -m commit-foo-dot .
268 $ hg ci -m commit-foo-dot .
269
269
270 full log
270 full log
271
271
272 $ hg log -v
272 $ hg log -v
273 changeset: 1:95b38e3a5b2e
273 changeset: 1:95b38e3a5b2e
274 tag: tip
274 tag: tip
275 user: test
275 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
276 date: Thu Jan 01 00:00:00 1970 +0000
277 files: foo/plain-file
277 files: foo/plain-file
278 description:
278 description:
279 commit-foo-dot
279 commit-foo-dot
280
280
281
281
282 changeset: 0:65d4e9386227
282 changeset: 0:65d4e9386227
283 user: test
283 user: test
284 date: Thu Jan 01 00:00:00 1970 +0000
284 date: Thu Jan 01 00:00:00 1970 +0000
285 files: foo/plain-file
285 files: foo/plain-file
286 description:
286 description:
287 commit-foo-subdir
287 commit-foo-subdir
288
288
289
289
290
290
291 subdir log
291 subdir log
292
292
293 $ cd foo
293 $ cd foo
294 $ hg log .
294 $ hg log .
295 changeset: 1:95b38e3a5b2e
295 changeset: 1:95b38e3a5b2e
296 tag: tip
296 tag: tip
297 user: test
297 user: test
298 date: Thu Jan 01 00:00:00 1970 +0000
298 date: Thu Jan 01 00:00:00 1970 +0000
299 summary: commit-foo-dot
299 summary: commit-foo-dot
300
300
301 changeset: 0:65d4e9386227
301 changeset: 0:65d4e9386227
302 user: test
302 user: test
303 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
304 summary: commit-foo-subdir
304 summary: commit-foo-subdir
305
305
306 $ cd ..
306 $ cd ..
307 $ cd ..
307 $ cd ..
308
308
309 Issue1049: Hg permits partial commit of merge without warning
309 Issue1049: Hg permits partial commit of merge without warning
310
310
311 $ hg init issue1049
311 $ hg init issue1049
312 $ cd issue1049
312 $ cd issue1049
313 $ echo a > a
313 $ echo a > a
314 $ hg ci -Ama
314 $ hg ci -Ama
315 adding a
315 adding a
316 $ echo a >> a
316 $ echo a >> a
317 $ hg ci -mb
317 $ hg ci -mb
318 $ hg up 0
318 $ hg up 0
319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
320 $ echo b >> a
320 $ echo b >> a
321 $ hg ci -mc
321 $ hg ci -mc
322 created new head
322 created new head
323 $ HGMERGE=true hg merge
323 $ HGMERGE=true hg merge
324 merging a
324 merging a
325 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
325 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
326 (branch merge, don't forget to commit)
326 (branch merge, don't forget to commit)
327
327
328 should fail because we are specifying a file name
328 should fail because we are specifying a file name
329
329
330 $ hg ci -mmerge a
330 $ hg ci -mmerge a
331 abort: cannot partially commit a merge (do not specify files or patterns)
331 abort: cannot partially commit a merge (do not specify files or patterns)
332 [255]
332 [255]
333
333
334 should fail because we are specifying a pattern
334 should fail because we are specifying a pattern
335
335
336 $ hg ci -mmerge -I a
336 $ hg ci -mmerge -I a
337 abort: cannot partially commit a merge (do not specify files or patterns)
337 abort: cannot partially commit a merge (do not specify files or patterns)
338 [255]
338 [255]
339
339
340 should succeed
340 should succeed
341
341
342 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg ci -mmerge --edit
342 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg ci -mmerge --edit
343 HGEDITFORM=commit.normal.merge
343 HGEDITFORM=commit.normal.merge
344 $ cd ..
344 $ cd ..
345
345
346
346
347 test commit message content
347 test commit message content
348
348
349 $ hg init commitmsg
349 $ hg init commitmsg
350 $ cd commitmsg
350 $ cd commitmsg
351 $ echo changed > changed
351 $ echo changed > changed
352 $ echo removed > removed
352 $ echo removed > removed
353 $ hg book activebookmark
353 $ hg book activebookmark
354 $ hg ci -qAm init
354 $ hg ci -qAm init
355
355
356 $ hg rm removed
356 $ hg rm removed
357 $ echo changed >> changed
357 $ echo changed >> changed
358 $ echo added > added
358 $ echo added > added
359 $ hg add added
359 $ hg add added
360 $ HGEDITOR=cat hg ci -A
360 $ HGEDITOR=cat hg ci -A
361
361
362
362
363 HG: Enter commit message. Lines beginning with 'HG:' are removed.
363 HG: Enter commit message. Lines beginning with 'HG:' are removed.
364 HG: Leave message empty to abort commit.
364 HG: Leave message empty to abort commit.
365 HG: --
365 HG: --
366 HG: user: test
366 HG: user: test
367 HG: branch 'default'
367 HG: branch 'default'
368 HG: bookmark 'activebookmark'
368 HG: bookmark 'activebookmark'
369 HG: added added
369 HG: added added
370 HG: changed changed
370 HG: changed changed
371 HG: removed removed
371 HG: removed removed
372 abort: empty commit message
372 abort: empty commit message
373 [255]
373 [255]
374
374
375 test saving last-message.txt
375 test saving last-message.txt
376
376
377 $ hg init sub
377 $ hg init sub
378 $ echo a > sub/a
378 $ echo a > sub/a
379 $ hg -R sub add sub/a
379 $ hg -R sub add sub/a
380 $ cat > sub/.hg/hgrc <<EOF
380 $ cat > sub/.hg/hgrc <<EOF
381 > [hooks]
381 > [hooks]
382 > precommit.test-saving-last-message = false
382 > precommit.test-saving-last-message = false
383 > EOF
383 > EOF
384
384
385 $ echo 'sub = sub' > .hgsub
385 $ echo 'sub = sub' > .hgsub
386 $ hg add .hgsub
386 $ hg add .hgsub
387
387
388 $ cat > $TESTTMP/editor.sh <<EOF
388 $ cat > $TESTTMP/editor.sh <<EOF
389 > echo "==== before editing:"
389 > echo "==== before editing:"
390 > cat \$1
390 > cat \$1
391 > echo "===="
391 > echo "===="
392 > echo "test saving last-message.txt" >> \$1
392 > echo "test saving last-message.txt" >> \$1
393 > EOF
393 > EOF
394
394
395 $ rm -f .hg/last-message.txt
395 $ rm -f .hg/last-message.txt
396 $ HGEDITOR="sh $TESTTMP/editor.sh" hg commit -S -q
396 $ HGEDITOR="sh $TESTTMP/editor.sh" hg commit -S -q
397 ==== before editing:
397 ==== before editing:
398
398
399
399
400 HG: Enter commit message. Lines beginning with 'HG:' are removed.
400 HG: Enter commit message. Lines beginning with 'HG:' are removed.
401 HG: Leave message empty to abort commit.
401 HG: Leave message empty to abort commit.
402 HG: --
402 HG: --
403 HG: user: test
403 HG: user: test
404 HG: branch 'default'
404 HG: branch 'default'
405 HG: bookmark 'activebookmark'
405 HG: bookmark 'activebookmark'
406 HG: subrepo sub
406 HG: subrepo sub
407 HG: added .hgsub
407 HG: added .hgsub
408 HG: added added
408 HG: added added
409 HG: changed .hgsubstate
409 HG: changed .hgsubstate
410 HG: changed changed
410 HG: changed changed
411 HG: removed removed
411 HG: removed removed
412 ====
412 ====
413 abort: precommit.test-saving-last-message hook exited with status 1 (in subrepository "sub")
413 abort: precommit.test-saving-last-message hook exited with status 1 (in subrepository "sub")
414 [255]
414 [255]
415 $ cat .hg/last-message.txt
415 $ cat .hg/last-message.txt
416
416
417
417
418 test saving last-message.txt
418 test saving last-message.txt
419
419
420 test that '[committemplate] changeset' definition and commit log
420 test that '[committemplate] changeset' definition and commit log
421 specific template keywords work well
421 specific template keywords work well
422
422
423 $ cat >> .hg/hgrc <<EOF
423 $ cat >> .hg/hgrc <<EOF
424 > [committemplate]
424 > [committemplate]
425 > changeset.commit.normal = 'HG: this is "commit.normal" template
425 > changeset.commit.normal = 'HG: this is "commit.normal" template
426 > HG: {extramsg}
426 > HG: {extramsg}
427 > {if(activebookmark,
427 > {if(activebookmark,
428 > "HG: bookmark '{activebookmark}' is activated\n",
428 > "HG: bookmark '{activebookmark}' is activated\n",
429 > "HG: no bookmark is activated\n")}{subrepos %
429 > "HG: no bookmark is activated\n")}{subrepos %
430 > "HG: subrepo '{subrepo}' is changed\n"}'
430 > "HG: subrepo '{subrepo}' is changed\n"}'
431 >
431 >
432 > changeset.commit = HG: this is "commit" template
432 > changeset.commit = HG: this is "commit" template
433 > HG: {extramsg}
433 > HG: {extramsg}
434 > {if(activebookmark,
434 > {if(activebookmark,
435 > "HG: bookmark '{activebookmark}' is activated\n",
435 > "HG: bookmark '{activebookmark}' is activated\n",
436 > "HG: no bookmark is activated\n")}{subrepos %
436 > "HG: no bookmark is activated\n")}{subrepos %
437 > "HG: subrepo '{subrepo}' is changed\n"}
437 > "HG: subrepo '{subrepo}' is changed\n"}
438 >
438 >
439 > changeset = HG: this is customized commit template
439 > changeset = HG: this is customized commit template
440 > HG: {extramsg}
440 > HG: {extramsg}
441 > {if(activebookmark,
441 > {if(activebookmark,
442 > "HG: bookmark '{activebookmark}' is activated\n",
442 > "HG: bookmark '{activebookmark}' is activated\n",
443 > "HG: no bookmark is activated\n")}{subrepos %
443 > "HG: no bookmark is activated\n")}{subrepos %
444 > "HG: subrepo '{subrepo}' is changed\n"}
444 > "HG: subrepo '{subrepo}' is changed\n"}
445 > EOF
445 > EOF
446
446
447 $ hg init sub2
447 $ hg init sub2
448 $ echo a > sub2/a
448 $ echo a > sub2/a
449 $ hg -R sub2 add sub2/a
449 $ hg -R sub2 add sub2/a
450 $ echo 'sub2 = sub2' >> .hgsub
450 $ echo 'sub2 = sub2' >> .hgsub
451
451
452 $ HGEDITOR=cat hg commit -S -q
452 $ HGEDITOR=cat hg commit -S -q
453 HG: this is "commit.normal" template
453 HG: this is "commit.normal" template
454 HG: Leave message empty to abort commit.
454 HG: Leave message empty to abort commit.
455 HG: bookmark 'activebookmark' is activated
455 HG: bookmark 'activebookmark' is activated
456 HG: subrepo 'sub' is changed
456 HG: subrepo 'sub' is changed
457 HG: subrepo 'sub2' is changed
457 HG: subrepo 'sub2' is changed
458 abort: empty commit message
458 abort: empty commit message
459 [255]
459 [255]
460
460
461 $ cat >> .hg/hgrc <<EOF
461 $ cat >> .hg/hgrc <<EOF
462 > [committemplate]
462 > [committemplate]
463 > changeset.commit.normal =
463 > changeset.commit.normal =
464 > # now, "changeset.commit" should be chosen for "hg commit"
464 > # now, "changeset.commit" should be chosen for "hg commit"
465 > EOF
465 > EOF
466
466
467 $ hg bookmark --inactive activebookmark
467 $ hg bookmark --inactive activebookmark
468 $ hg forget .hgsub
468 $ hg forget .hgsub
469 $ HGEDITOR=cat hg commit -q
469 $ HGEDITOR=cat hg commit -q
470 HG: this is "commit" template
470 HG: this is "commit" template
471 HG: Leave message empty to abort commit.
471 HG: Leave message empty to abort commit.
472 HG: no bookmark is activated
472 HG: no bookmark is activated
473 abort: empty commit message
473 abort: empty commit message
474 [255]
474 [255]
475
475
476 $ cat >> .hg/hgrc <<EOF
476 $ cat >> .hg/hgrc <<EOF
477 > [committemplate]
477 > [committemplate]
478 > changeset.commit =
478 > changeset.commit =
479 > # now, "changeset" should be chosen for "hg commit"
479 > # now, "changeset" should be chosen for "hg commit"
480 > EOF
480 > EOF
481
481
482 $ HGEDITOR=cat hg commit -q
482 $ HGEDITOR=cat hg commit -q
483 HG: this is customized commit template
483 HG: this is customized commit template
484 HG: Leave message empty to abort commit.
484 HG: Leave message empty to abort commit.
485 HG: no bookmark is activated
485 HG: no bookmark is activated
486 abort: empty commit message
486 abort: empty commit message
487 [255]
487 [255]
488
488
489 $ cat >> .hg/hgrc <<EOF
489 $ cat >> .hg/hgrc <<EOF
490 > [committemplate]
490 > [committemplate]
491 > changeset = {desc}
491 > changeset = {desc}
492 > HG: mods={file_mods}
492 > HG: mods={file_mods}
493 > HG: adds={file_adds}
493 > HG: adds={file_adds}
494 > HG: dels={file_dels}
494 > HG: dels={file_dels}
495 > HG: files={files}
495 > HG: files={files}
496 > HG:
496 > HG:
497 > {splitlines(diff()) % 'HG: {line}\n'
497 > {splitlines(diff()) % 'HG: {line}\n'
498 > }HG:
498 > }HG:
499 > HG: mods={file_mods}
499 > HG: mods={file_mods}
500 > HG: adds={file_adds}
500 > HG: adds={file_adds}
501 > HG: dels={file_dels}
501 > HG: dels={file_dels}
502 > HG: files={files}\n
502 > HG: files={files}\n
503 > EOF
503 > EOF
504 $ hg status -amr
504 $ hg status -amr
505 M changed
505 M changed
506 A added
506 A added
507 R removed
507 R removed
508 $ HGEDITOR=cat hg commit -q -e -m "foo bar" changed
508 $ HGEDITOR=cat hg commit -q -e -m "foo bar" changed
509 foo bar
509 foo bar
510 HG: mods=changed
510 HG: mods=changed
511 HG: adds=
511 HG: adds=
512 HG: dels=
512 HG: dels=
513 HG: files=changed
513 HG: files=changed
514 HG:
514 HG:
515 HG: --- a/changed Thu Jan 01 00:00:00 1970 +0000
515 HG: --- a/changed Thu Jan 01 00:00:00 1970 +0000
516 HG: +++ b/changed Thu Jan 01 00:00:00 1970 +0000
516 HG: +++ b/changed Thu Jan 01 00:00:00 1970 +0000
517 HG: @@ -1,1 +1,2 @@
517 HG: @@ -1,1 +1,2 @@
518 HG: changed
518 HG: changed
519 HG: +changed
519 HG: +changed
520 HG:
520 HG:
521 HG: mods=changed
521 HG: mods=changed
522 HG: adds=
522 HG: adds=
523 HG: dels=
523 HG: dels=
524 HG: files=changed
524 HG: files=changed
525 $ hg status -amr
525 $ hg status -amr
526 A added
526 A added
527 R removed
527 R removed
528 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
528 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
529 M changed
529 M changed
530 A
530 A
531 R
531 R
532 $ hg rollback -q
532 $ hg rollback -q
533
533
534 $ cat >> .hg/hgrc <<EOF
534 $ cat >> .hg/hgrc <<EOF
535 > [committemplate]
535 > [committemplate]
536 > changeset = {desc}
536 > changeset = {desc}
537 > HG: mods={file_mods}
537 > HG: mods={file_mods}
538 > HG: adds={file_adds}
538 > HG: adds={file_adds}
539 > HG: dels={file_dels}
539 > HG: dels={file_dels}
540 > HG: files={files}
540 > HG: files={files}
541 > HG:
541 > HG:
542 > {splitlines(diff("changed")) % 'HG: {line}\n'
542 > {splitlines(diff("changed")) % 'HG: {line}\n'
543 > }HG:
543 > }HG:
544 > HG: mods={file_mods}
544 > HG: mods={file_mods}
545 > HG: adds={file_adds}
545 > HG: adds={file_adds}
546 > HG: dels={file_dels}
546 > HG: dels={file_dels}
547 > HG: files={files}
547 > HG: files={files}
548 > HG:
548 > HG:
549 > {splitlines(diff("added")) % 'HG: {line}\n'
549 > {splitlines(diff("added")) % 'HG: {line}\n'
550 > }HG:
550 > }HG:
551 > HG: mods={file_mods}
551 > HG: mods={file_mods}
552 > HG: adds={file_adds}
552 > HG: adds={file_adds}
553 > HG: dels={file_dels}
553 > HG: dels={file_dels}
554 > HG: files={files}
554 > HG: files={files}
555 > HG:
555 > HG:
556 > {splitlines(diff("removed")) % 'HG: {line}\n'
556 > {splitlines(diff("removed")) % 'HG: {line}\n'
557 > }HG:
557 > }HG:
558 > HG: mods={file_mods}
558 > HG: mods={file_mods}
559 > HG: adds={file_adds}
559 > HG: adds={file_adds}
560 > HG: dels={file_dels}
560 > HG: dels={file_dels}
561 > HG: files={files}\n
561 > HG: files={files}\n
562 > EOF
562 > EOF
563 $ HGEDITOR=cat hg commit -q -e -m "foo bar" added removed
563 $ HGEDITOR=cat hg commit -q -e -m "foo bar" added removed
564 foo bar
564 foo bar
565 HG: mods=
565 HG: mods=
566 HG: adds=added
566 HG: adds=added
567 HG: dels=removed
567 HG: dels=removed
568 HG: files=added removed
568 HG: files=added removed
569 HG:
569 HG:
570 HG:
570 HG:
571 HG: mods=
571 HG: mods=
572 HG: adds=added
572 HG: adds=added
573 HG: dels=removed
573 HG: dels=removed
574 HG: files=added removed
574 HG: files=added removed
575 HG:
575 HG:
576 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
576 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
577 HG: +++ b/added Thu Jan 01 00:00:00 1970 +0000
577 HG: +++ b/added Thu Jan 01 00:00:00 1970 +0000
578 HG: @@ -0,0 +1,1 @@
578 HG: @@ -0,0 +1,1 @@
579 HG: +added
579 HG: +added
580 HG:
580 HG:
581 HG: mods=
581 HG: mods=
582 HG: adds=added
582 HG: adds=added
583 HG: dels=removed
583 HG: dels=removed
584 HG: files=added removed
584 HG: files=added removed
585 HG:
585 HG:
586 HG: --- a/removed Thu Jan 01 00:00:00 1970 +0000
586 HG: --- a/removed Thu Jan 01 00:00:00 1970 +0000
587 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
587 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
588 HG: @@ -1,1 +0,0 @@
588 HG: @@ -1,1 +0,0 @@
589 HG: -removed
589 HG: -removed
590 HG:
590 HG:
591 HG: mods=
591 HG: mods=
592 HG: adds=added
592 HG: adds=added
593 HG: dels=removed
593 HG: dels=removed
594 HG: files=added removed
594 HG: files=added removed
595 $ hg status -amr
595 $ hg status -amr
596 M changed
596 M changed
597 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
597 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
598 M
598 M
599 A added
599 A added
600 R removed
600 R removed
601 $ hg rollback -q
601 $ hg rollback -q
602
602
603 $ cat >> .hg/hgrc <<EOF
603 $ cat >> .hg/hgrc <<EOF
604 > # disable customizing for subsequent tests
604 > # disable customizing for subsequent tests
605 > [committemplate]
605 > [committemplate]
606 > changeset =
606 > changeset =
607 > EOF
607 > EOF
608
608
609 $ cd ..
609 $ cd ..
610
610
611
611
612 commit copy
612 commit copy
613
613
614 $ hg init dir2
614 $ hg init dir2
615 $ cd dir2
615 $ cd dir2
616 $ echo bleh > bar
616 $ echo bleh > bar
617 $ hg add bar
617 $ hg add bar
618 $ hg ci -m 'add bar'
618 $ hg ci -m 'add bar'
619
619
620 $ hg cp bar foo
620 $ hg cp bar foo
621 $ echo >> bar
621 $ echo >> bar
622 $ hg ci -m 'cp bar foo; change bar'
622 $ hg ci -m 'cp bar foo; change bar'
623
623
624 $ hg debugrename foo
624 $ hg debugrename foo
625 foo renamed from bar:26d3ca0dfd18e44d796b564e38dd173c9668d3a9
625 foo renamed from bar:26d3ca0dfd18e44d796b564e38dd173c9668d3a9
626 $ hg debugindex bar
626 $ hg debugindex bar
627 rev offset length linkrev nodeid p1 p2
627 rev linkrev nodeid p1 p2
628 0 0 6 0 26d3ca0dfd18 000000000000 000000000000
628 0 0 26d3ca0dfd18 000000000000 000000000000
629 1 6 7 1 d267bddd54f7 26d3ca0dfd18 000000000000
629 1 1 d267bddd54f7 26d3ca0dfd18 000000000000
630
630
631 Test making empty commits
631 Test making empty commits
632 $ hg commit --config ui.allowemptycommit=True -m "empty commit"
632 $ hg commit --config ui.allowemptycommit=True -m "empty commit"
633 $ hg log -r . -v --stat
633 $ hg log -r . -v --stat
634 changeset: 2:d809f3644287
634 changeset: 2:d809f3644287
635 tag: tip
635 tag: tip
636 user: test
636 user: test
637 date: Thu Jan 01 00:00:00 1970 +0000
637 date: Thu Jan 01 00:00:00 1970 +0000
638 description:
638 description:
639 empty commit
639 empty commit
640
640
641
641
642
642
643 verify pathauditor blocks evil filepaths
643 verify pathauditor blocks evil filepaths
644 $ cat > evil-commit.py <<EOF
644 $ cat > evil-commit.py <<EOF
645 > from __future__ import absolute_import
645 > from __future__ import absolute_import
646 > from mercurial import context, hg, node, ui as uimod
646 > from mercurial import context, hg, node, ui as uimod
647 > notrc = u".h\u200cg".encode('utf-8') + b'/hgrc'
647 > notrc = u".h\u200cg".encode('utf-8') + b'/hgrc'
648 > u = uimod.ui.load()
648 > u = uimod.ui.load()
649 > r = hg.repository(u, b'.')
649 > r = hg.repository(u, b'.')
650 > def filectxfn(repo, memctx, path):
650 > def filectxfn(repo, memctx, path):
651 > return context.memfilectx(repo, memctx, path,
651 > return context.memfilectx(repo, memctx, path,
652 > b'[hooks]\nupdate = echo owned')
652 > b'[hooks]\nupdate = echo owned')
653 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
653 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
654 > b'evil', [notrc], filectxfn, 0)
654 > b'evil', [notrc], filectxfn, 0)
655 > r.commitctx(c)
655 > r.commitctx(c)
656 > EOF
656 > EOF
657 $ $PYTHON evil-commit.py
657 $ $PYTHON evil-commit.py
658 #if windows
658 #if windows
659 $ hg co --clean tip
659 $ hg co --clean tip
660 abort: path contains illegal component: .h\xe2\x80\x8cg\\hgrc (esc)
660 abort: path contains illegal component: .h\xe2\x80\x8cg\\hgrc (esc)
661 [255]
661 [255]
662 #else
662 #else
663 $ hg co --clean tip
663 $ hg co --clean tip
664 abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
664 abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
665 [255]
665 [255]
666 #endif
666 #endif
667
667
668 $ hg rollback -f
668 $ hg rollback -f
669 repository tip rolled back to revision 2 (undo commit)
669 repository tip rolled back to revision 2 (undo commit)
670 $ cat > evil-commit.py <<EOF
670 $ cat > evil-commit.py <<EOF
671 > from __future__ import absolute_import
671 > from __future__ import absolute_import
672 > from mercurial import context, hg, node, ui as uimod
672 > from mercurial import context, hg, node, ui as uimod
673 > notrc = b"HG~1/hgrc"
673 > notrc = b"HG~1/hgrc"
674 > u = uimod.ui.load()
674 > u = uimod.ui.load()
675 > r = hg.repository(u, b'.')
675 > r = hg.repository(u, b'.')
676 > def filectxfn(repo, memctx, path):
676 > def filectxfn(repo, memctx, path):
677 > return context.memfilectx(repo, memctx, path,
677 > return context.memfilectx(repo, memctx, path,
678 > b'[hooks]\nupdate = echo owned')
678 > b'[hooks]\nupdate = echo owned')
679 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
679 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
680 > b'evil', [notrc], filectxfn, 0)
680 > b'evil', [notrc], filectxfn, 0)
681 > r.commitctx(c)
681 > r.commitctx(c)
682 > EOF
682 > EOF
683 $ $PYTHON evil-commit.py
683 $ $PYTHON evil-commit.py
684 $ hg co --clean tip
684 $ hg co --clean tip
685 abort: path contains illegal component: HG~1/hgrc
685 abort: path contains illegal component: HG~1/hgrc
686 [255]
686 [255]
687
687
688 $ hg rollback -f
688 $ hg rollback -f
689 repository tip rolled back to revision 2 (undo commit)
689 repository tip rolled back to revision 2 (undo commit)
690 $ cat > evil-commit.py <<EOF
690 $ cat > evil-commit.py <<EOF
691 > from __future__ import absolute_import
691 > from __future__ import absolute_import
692 > from mercurial import context, hg, node, ui as uimod
692 > from mercurial import context, hg, node, ui as uimod
693 > notrc = b"HG8B6C~2/hgrc"
693 > notrc = b"HG8B6C~2/hgrc"
694 > u = uimod.ui.load()
694 > u = uimod.ui.load()
695 > r = hg.repository(u, b'.')
695 > r = hg.repository(u, b'.')
696 > def filectxfn(repo, memctx, path):
696 > def filectxfn(repo, memctx, path):
697 > return context.memfilectx(repo, memctx, path,
697 > return context.memfilectx(repo, memctx, path,
698 > b'[hooks]\nupdate = echo owned')
698 > b'[hooks]\nupdate = echo owned')
699 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
699 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
700 > b'evil', [notrc], filectxfn, 0)
700 > b'evil', [notrc], filectxfn, 0)
701 > r.commitctx(c)
701 > r.commitctx(c)
702 > EOF
702 > EOF
703 $ $PYTHON evil-commit.py
703 $ $PYTHON evil-commit.py
704 $ hg co --clean tip
704 $ hg co --clean tip
705 abort: path contains illegal component: HG8B6C~2/hgrc
705 abort: path contains illegal component: HG8B6C~2/hgrc
706 [255]
706 [255]
707
707
708 # test that an unmodified commit template message aborts
708 # test that an unmodified commit template message aborts
709
709
710 $ hg init unmodified_commit_template
710 $ hg init unmodified_commit_template
711 $ cd unmodified_commit_template
711 $ cd unmodified_commit_template
712 $ echo foo > foo
712 $ echo foo > foo
713 $ hg add foo
713 $ hg add foo
714 $ hg commit -m "foo"
714 $ hg commit -m "foo"
715 $ cat >> .hg/hgrc <<EOF
715 $ cat >> .hg/hgrc <<EOF
716 > [committemplate]
716 > [committemplate]
717 > changeset.commit = HI THIS IS NOT STRIPPED
717 > changeset.commit = HI THIS IS NOT STRIPPED
718 > HG: this is customized commit template
718 > HG: this is customized commit template
719 > HG: {extramsg}
719 > HG: {extramsg}
720 > {if(activebookmark,
720 > {if(activebookmark,
721 > "HG: bookmark '{activebookmark}' is activated\n",
721 > "HG: bookmark '{activebookmark}' is activated\n",
722 > "HG: no bookmark is activated\n")}{subrepos %
722 > "HG: no bookmark is activated\n")}{subrepos %
723 > "HG: subrepo '{subrepo}' is changed\n"}
723 > "HG: subrepo '{subrepo}' is changed\n"}
724 > EOF
724 > EOF
725 $ cat > $TESTTMP/notouching.sh <<EOF
725 $ cat > $TESTTMP/notouching.sh <<EOF
726 > true
726 > true
727 > EOF
727 > EOF
728 $ echo foo2 > foo2
728 $ echo foo2 > foo2
729 $ hg add foo2
729 $ hg add foo2
730 $ HGEDITOR="sh $TESTTMP/notouching.sh" hg commit
730 $ HGEDITOR="sh $TESTTMP/notouching.sh" hg commit
731 abort: commit message unchanged
731 abort: commit message unchanged
732 [255]
732 [255]
733
733
734 test that text below the --- >8 --- special string is ignored
734 test that text below the --- >8 --- special string is ignored
735
735
736 $ cat <<'EOF' > $TESTTMP/lowercaseline.sh
736 $ cat <<'EOF' > $TESTTMP/lowercaseline.sh
737 > cat $1 | sed s/LINE/line/ | tee $1.new
737 > cat $1 | sed s/LINE/line/ | tee $1.new
738 > mv $1.new $1
738 > mv $1.new $1
739 > EOF
739 > EOF
740
740
741 $ hg init ignore_below_special_string
741 $ hg init ignore_below_special_string
742 $ cd ignore_below_special_string
742 $ cd ignore_below_special_string
743 $ echo foo > foo
743 $ echo foo > foo
744 $ hg add foo
744 $ hg add foo
745 $ hg commit -m "foo"
745 $ hg commit -m "foo"
746 $ cat >> .hg/hgrc <<EOF
746 $ cat >> .hg/hgrc <<EOF
747 > [committemplate]
747 > [committemplate]
748 > changeset.commit = first LINE
748 > changeset.commit = first LINE
749 > HG: this is customized commit template
749 > HG: this is customized commit template
750 > HG: {extramsg}
750 > HG: {extramsg}
751 > HG: ------------------------ >8 ------------------------
751 > HG: ------------------------ >8 ------------------------
752 > {diff()}
752 > {diff()}
753 > EOF
753 > EOF
754 $ echo foo2 > foo2
754 $ echo foo2 > foo2
755 $ hg add foo2
755 $ hg add foo2
756 $ HGEDITOR="sh $TESTTMP/notouching.sh" hg ci
756 $ HGEDITOR="sh $TESTTMP/notouching.sh" hg ci
757 abort: commit message unchanged
757 abort: commit message unchanged
758 [255]
758 [255]
759 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
759 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
760 first line
760 first line
761 HG: this is customized commit template
761 HG: this is customized commit template
762 HG: Leave message empty to abort commit.
762 HG: Leave message empty to abort commit.
763 HG: ------------------------ >8 ------------------------
763 HG: ------------------------ >8 ------------------------
764 diff -r e63c23eaa88a foo2
764 diff -r e63c23eaa88a foo2
765 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
765 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
766 +++ b/foo2 Thu Jan 01 00:00:00 1970 +0000
766 +++ b/foo2 Thu Jan 01 00:00:00 1970 +0000
767 @@ -0,0 +1,1 @@
767 @@ -0,0 +1,1 @@
768 +foo2
768 +foo2
769 $ hg log -T '{desc}\n' -r .
769 $ hg log -T '{desc}\n' -r .
770 first line
770 first line
771
771
772 test that the special string --- >8 --- isn't used when not at the beginning of
772 test that the special string --- >8 --- isn't used when not at the beginning of
773 a line
773 a line
774
774
775 $ cat >> .hg/hgrc <<EOF
775 $ cat >> .hg/hgrc <<EOF
776 > [committemplate]
776 > [committemplate]
777 > changeset.commit = first LINE2
777 > changeset.commit = first LINE2
778 > another line HG: ------------------------ >8 ------------------------
778 > another line HG: ------------------------ >8 ------------------------
779 > HG: this is customized commit template
779 > HG: this is customized commit template
780 > HG: {extramsg}
780 > HG: {extramsg}
781 > HG: ------------------------ >8 ------------------------
781 > HG: ------------------------ >8 ------------------------
782 > {diff()}
782 > {diff()}
783 > EOF
783 > EOF
784 $ echo foo >> foo
784 $ echo foo >> foo
785 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
785 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
786 first line2
786 first line2
787 another line HG: ------------------------ >8 ------------------------
787 another line HG: ------------------------ >8 ------------------------
788 HG: this is customized commit template
788 HG: this is customized commit template
789 HG: Leave message empty to abort commit.
789 HG: Leave message empty to abort commit.
790 HG: ------------------------ >8 ------------------------
790 HG: ------------------------ >8 ------------------------
791 diff -r 3661b22b0702 foo
791 diff -r 3661b22b0702 foo
792 --- a/foo Thu Jan 01 00:00:00 1970 +0000
792 --- a/foo Thu Jan 01 00:00:00 1970 +0000
793 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
793 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
794 @@ -1,1 +1,2 @@
794 @@ -1,1 +1,2 @@
795 foo
795 foo
796 +foo
796 +foo
797 $ hg log -T '{desc}\n' -r .
797 $ hg log -T '{desc}\n' -r .
798 first line2
798 first line2
799 another line HG: ------------------------ >8 ------------------------
799 another line HG: ------------------------ >8 ------------------------
800
800
801 also test that this special string isn't accepted when there is some extra text
801 also test that this special string isn't accepted when there is some extra text
802 at the end
802 at the end
803
803
804 $ cat >> .hg/hgrc <<EOF
804 $ cat >> .hg/hgrc <<EOF
805 > [committemplate]
805 > [committemplate]
806 > changeset.commit = first LINE3
806 > changeset.commit = first LINE3
807 > HG: ------------------------ >8 ------------------------foobar
807 > HG: ------------------------ >8 ------------------------foobar
808 > second line
808 > second line
809 > HG: this is customized commit template
809 > HG: this is customized commit template
810 > HG: {extramsg}
810 > HG: {extramsg}
811 > HG: ------------------------ >8 ------------------------
811 > HG: ------------------------ >8 ------------------------
812 > {diff()}
812 > {diff()}
813 > EOF
813 > EOF
814 $ echo foo >> foo
814 $ echo foo >> foo
815 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
815 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
816 first line3
816 first line3
817 HG: ------------------------ >8 ------------------------foobar
817 HG: ------------------------ >8 ------------------------foobar
818 second line
818 second line
819 HG: this is customized commit template
819 HG: this is customized commit template
820 HG: Leave message empty to abort commit.
820 HG: Leave message empty to abort commit.
821 HG: ------------------------ >8 ------------------------
821 HG: ------------------------ >8 ------------------------
822 diff -r ce648f5f066f foo
822 diff -r ce648f5f066f foo
823 --- a/foo Thu Jan 01 00:00:00 1970 +0000
823 --- a/foo Thu Jan 01 00:00:00 1970 +0000
824 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
824 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
825 @@ -1,2 +1,3 @@
825 @@ -1,2 +1,3 @@
826 foo
826 foo
827 foo
827 foo
828 +foo
828 +foo
829 $ hg log -T '{desc}\n' -r .
829 $ hg log -T '{desc}\n' -r .
830 first line3
830 first line3
831 second line
831 second line
832
832
833 $ cd ..
833 $ cd ..
@@ -1,250 +1,250 b''
1 # enable bundle2 in advance
1 # enable bundle2 in advance
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [format]
4 > [format]
5 > usegeneraldelta=yes
5 > usegeneraldelta=yes
6 > EOF
6 > EOF
7
7
8 $ mkdir part1
8 $ mkdir part1
9 $ cd part1
9 $ cd part1
10
10
11 $ hg init
11 $ hg init
12 $ echo a > a
12 $ echo a > a
13 $ hg add a
13 $ hg add a
14 $ hg commit -m "1"
14 $ hg commit -m "1"
15 $ hg status
15 $ hg status
16 $ hg copy a b
16 $ hg copy a b
17 $ hg --config ui.portablefilenames=abort copy a con.xml
17 $ hg --config ui.portablefilenames=abort copy a con.xml
18 abort: filename contains 'con', which is reserved on Windows: con.xml
18 abort: filename contains 'con', which is reserved on Windows: con.xml
19 [255]
19 [255]
20 $ hg status
20 $ hg status
21 A b
21 A b
22 $ hg sum
22 $ hg sum
23 parent: 0:c19d34741b0a tip
23 parent: 0:c19d34741b0a tip
24 1
24 1
25 branch: default
25 branch: default
26 commit: 1 copied
26 commit: 1 copied
27 update: (current)
27 update: (current)
28 phases: 1 draft
28 phases: 1 draft
29 $ hg --debug commit -m "2"
29 $ hg --debug commit -m "2"
30 committing files:
30 committing files:
31 b
31 b
32 b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
32 b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
33 committing manifest
33 committing manifest
34 committing changelog
34 committing changelog
35 updating the branch cache
35 updating the branch cache
36 committed changeset 1:93580a2c28a50a56f63526fb305067e6fbf739c4
36 committed changeset 1:93580a2c28a50a56f63526fb305067e6fbf739c4
37
37
38 we should see two history entries
38 we should see two history entries
39
39
40 $ hg history -v
40 $ hg history -v
41 changeset: 1:93580a2c28a5
41 changeset: 1:93580a2c28a5
42 tag: tip
42 tag: tip
43 user: test
43 user: test
44 date: Thu Jan 01 00:00:00 1970 +0000
44 date: Thu Jan 01 00:00:00 1970 +0000
45 files: b
45 files: b
46 description:
46 description:
47 2
47 2
48
48
49
49
50 changeset: 0:c19d34741b0a
50 changeset: 0:c19d34741b0a
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
53 files: a
53 files: a
54 description:
54 description:
55 1
55 1
56
56
57
57
58
58
59 we should see one log entry for a
59 we should see one log entry for a
60
60
61 $ hg log a
61 $ hg log a
62 changeset: 0:c19d34741b0a
62 changeset: 0:c19d34741b0a
63 user: test
63 user: test
64 date: Thu Jan 01 00:00:00 1970 +0000
64 date: Thu Jan 01 00:00:00 1970 +0000
65 summary: 1
65 summary: 1
66
66
67
67
68 this should show a revision linked to changeset 0
68 this should show a revision linked to changeset 0
69
69
70 $ hg debugindex a
70 $ hg debugindex a
71 rev offset length linkrev nodeid p1 p2
71 rev linkrev nodeid p1 p2
72 0 0 3 0 b789fdd96dc2 000000000000 000000000000
72 0 0 b789fdd96dc2 000000000000 000000000000
73
73
74 we should see one log entry for b
74 we should see one log entry for b
75
75
76 $ hg log b
76 $ hg log b
77 changeset: 1:93580a2c28a5
77 changeset: 1:93580a2c28a5
78 tag: tip
78 tag: tip
79 user: test
79 user: test
80 date: Thu Jan 01 00:00:00 1970 +0000
80 date: Thu Jan 01 00:00:00 1970 +0000
81 summary: 2
81 summary: 2
82
82
83
83
84 this should show a revision linked to changeset 1
84 this should show a revision linked to changeset 1
85
85
86 $ hg debugindex b
86 $ hg debugindex b
87 rev offset length linkrev nodeid p1 p2
87 rev linkrev nodeid p1 p2
88 0 0 65 1 37d9b5d994ea 000000000000 000000000000
88 0 1 37d9b5d994ea 000000000000 000000000000
89
89
90 this should show the rename information in the metadata
90 this should show the rename information in the metadata
91
91
92 $ hg debugdata b 0 | head -3 | tail -2
92 $ hg debugdata b 0 | head -3 | tail -2
93 copy: a
93 copy: a
94 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
94 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
95
95
96 $ md5sum.py .hg/store/data/b.i
96 $ md5sum.py .hg/store/data/b.i
97 44913824c8f5890ae218f9829535922e .hg/store/data/b.i
97 44913824c8f5890ae218f9829535922e .hg/store/data/b.i
98 $ hg cat b > bsum
98 $ hg cat b > bsum
99 $ md5sum.py bsum
99 $ md5sum.py bsum
100 60b725f10c9c85c70d97880dfe8191b3 bsum
100 60b725f10c9c85c70d97880dfe8191b3 bsum
101 $ hg cat a > asum
101 $ hg cat a > asum
102 $ md5sum.py asum
102 $ md5sum.py asum
103 60b725f10c9c85c70d97880dfe8191b3 asum
103 60b725f10c9c85c70d97880dfe8191b3 asum
104 $ hg verify
104 $ hg verify
105 checking changesets
105 checking changesets
106 checking manifests
106 checking manifests
107 crosschecking files in changesets and manifests
107 crosschecking files in changesets and manifests
108 checking files
108 checking files
109 2 files, 2 changesets, 2 total revisions
109 2 files, 2 changesets, 2 total revisions
110
110
111 $ cd ..
111 $ cd ..
112
112
113
113
114 $ mkdir part2
114 $ mkdir part2
115 $ cd part2
115 $ cd part2
116
116
117 $ hg init
117 $ hg init
118 $ echo foo > foo
118 $ echo foo > foo
119 should fail - foo is not managed
119 should fail - foo is not managed
120 $ hg mv foo bar
120 $ hg mv foo bar
121 foo: not copying - file is not managed
121 foo: not copying - file is not managed
122 abort: no files to copy
122 abort: no files to copy
123 [255]
123 [255]
124 $ hg st -A
124 $ hg st -A
125 ? foo
125 ? foo
126 $ hg add foo
126 $ hg add foo
127 dry-run; print a warning that this is not a real copy; foo is added
127 dry-run; print a warning that this is not a real copy; foo is added
128 $ hg mv --dry-run foo bar
128 $ hg mv --dry-run foo bar
129 foo has not been committed yet, so no copy data will be stored for bar.
129 foo has not been committed yet, so no copy data will be stored for bar.
130 $ hg st -A
130 $ hg st -A
131 A foo
131 A foo
132 should print a warning that this is not a real copy; bar is added
132 should print a warning that this is not a real copy; bar is added
133 $ hg mv foo bar
133 $ hg mv foo bar
134 foo has not been committed yet, so no copy data will be stored for bar.
134 foo has not been committed yet, so no copy data will be stored for bar.
135 $ hg st -A
135 $ hg st -A
136 A bar
136 A bar
137 should print a warning that this is not a real copy; foo is added
137 should print a warning that this is not a real copy; foo is added
138 $ hg cp bar foo
138 $ hg cp bar foo
139 bar has not been committed yet, so no copy data will be stored for foo.
139 bar has not been committed yet, so no copy data will be stored for foo.
140 $ hg rm -f bar
140 $ hg rm -f bar
141 $ rm bar
141 $ rm bar
142 $ hg st -A
142 $ hg st -A
143 A foo
143 A foo
144 $ hg commit -m1
144 $ hg commit -m1
145
145
146 moving a missing file
146 moving a missing file
147 $ rm foo
147 $ rm foo
148 $ hg mv foo foo3
148 $ hg mv foo foo3
149 foo: deleted in working directory
149 foo: deleted in working directory
150 foo3 does not exist!
150 foo3 does not exist!
151 $ hg up -qC .
151 $ hg up -qC .
152
152
153 copy --after to a nonexistent target filename
153 copy --after to a nonexistent target filename
154 $ hg cp -A foo dummy
154 $ hg cp -A foo dummy
155 foo: not recording copy - dummy does not exist
155 foo: not recording copy - dummy does not exist
156
156
157 dry-run; should show that foo is clean
157 dry-run; should show that foo is clean
158 $ hg copy --dry-run foo bar
158 $ hg copy --dry-run foo bar
159 $ hg st -A
159 $ hg st -A
160 C foo
160 C foo
161 should show copy
161 should show copy
162 $ hg copy foo bar
162 $ hg copy foo bar
163 $ hg st -C
163 $ hg st -C
164 A bar
164 A bar
165 foo
165 foo
166
166
167 shouldn't show copy
167 shouldn't show copy
168 $ hg commit -m2
168 $ hg commit -m2
169 $ hg st -C
169 $ hg st -C
170
170
171 should match
171 should match
172 $ hg debugindex foo
172 $ hg debugindex foo
173 rev offset length linkrev nodeid p1 p2
173 rev linkrev nodeid p1 p2
174 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
174 0 0 2ed2a3912a0b 000000000000 000000000000
175 $ hg debugrename bar
175 $ hg debugrename bar
176 bar renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
176 bar renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
177
177
178 $ echo bleah > foo
178 $ echo bleah > foo
179 $ echo quux > bar
179 $ echo quux > bar
180 $ hg commit -m3
180 $ hg commit -m3
181
181
182 should not be renamed
182 should not be renamed
183 $ hg debugrename bar
183 $ hg debugrename bar
184 bar not renamed
184 bar not renamed
185
185
186 $ hg copy -f foo bar
186 $ hg copy -f foo bar
187 should show copy
187 should show copy
188 $ hg st -C
188 $ hg st -C
189 M bar
189 M bar
190 foo
190 foo
191
191
192 XXX: filtering lfilesrepo.status() in 3.3-rc causes the copy source to not be
192 XXX: filtering lfilesrepo.status() in 3.3-rc causes the copy source to not be
193 displayed.
193 displayed.
194 $ hg st -C --config extensions.largefiles=
194 $ hg st -C --config extensions.largefiles=
195 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
195 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
196 M bar
196 M bar
197 foo
197 foo
198
198
199 $ hg commit -m3
199 $ hg commit -m3
200
200
201 should show no parents for tip
201 should show no parents for tip
202 $ hg debugindex bar
202 $ hg debugindex bar
203 rev offset length linkrev nodeid p1 p2
203 rev linkrev nodeid p1 p2
204 0 0 69 1 7711d36246cc 000000000000 000000000000
204 0 1 7711d36246cc 000000000000 000000000000
205 1 69 6 2 bdf70a2b8d03 7711d36246cc 000000000000
205 1 2 bdf70a2b8d03 7711d36246cc 000000000000
206 2 75 71 3 b2558327ea8d 000000000000 000000000000
206 2 3 b2558327ea8d 000000000000 000000000000
207 should match
207 should match
208 $ hg debugindex foo
208 $ hg debugindex foo
209 rev offset length linkrev nodeid p1 p2
209 rev linkrev nodeid p1 p2
210 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
210 0 0 2ed2a3912a0b 000000000000 000000000000
211 1 5 7 2 dd12c926cf16 2ed2a3912a0b 000000000000
211 1 2 dd12c926cf16 2ed2a3912a0b 000000000000
212 $ hg debugrename bar
212 $ hg debugrename bar
213 bar renamed from foo:dd12c926cf165e3eb4cf87b084955cb617221c17
213 bar renamed from foo:dd12c926cf165e3eb4cf87b084955cb617221c17
214
214
215 should show no copies
215 should show no copies
216 $ hg st -C
216 $ hg st -C
217
217
218 copy --after on an added file
218 copy --after on an added file
219 $ cp bar baz
219 $ cp bar baz
220 $ hg add baz
220 $ hg add baz
221 $ hg cp -A bar baz
221 $ hg cp -A bar baz
222 $ hg st -C
222 $ hg st -C
223 A baz
223 A baz
224 bar
224 bar
225
225
226 foo was clean:
226 foo was clean:
227 $ hg st -AC foo
227 $ hg st -AC foo
228 C foo
228 C foo
229 Trying to copy on top of an existing file fails,
229 Trying to copy on top of an existing file fails,
230 $ hg copy -A bar foo
230 $ hg copy -A bar foo
231 foo: not overwriting - file already committed
231 foo: not overwriting - file already committed
232 (hg copy --after --force to replace the file by recording a copy)
232 (hg copy --after --force to replace the file by recording a copy)
233 same error without the --after, so the user doesn't have to go through
233 same error without the --after, so the user doesn't have to go through
234 two hints:
234 two hints:
235 $ hg copy bar foo
235 $ hg copy bar foo
236 foo: not overwriting - file already committed
236 foo: not overwriting - file already committed
237 (hg copy --force to replace the file by recording a copy)
237 (hg copy --force to replace the file by recording a copy)
238 but it's considered modified after a copy --after --force
238 but it's considered modified after a copy --after --force
239 $ hg copy -Af bar foo
239 $ hg copy -Af bar foo
240 $ hg st -AC foo
240 $ hg st -AC foo
241 M foo
241 M foo
242 bar
242 bar
243 The hint for a file that exists but is not in file history doesn't
243 The hint for a file that exists but is not in file history doesn't
244 mention --force:
244 mention --force:
245 $ touch xyzzy
245 $ touch xyzzy
246 $ hg cp bar xyzzy
246 $ hg cp bar xyzzy
247 xyzzy: not overwriting - file exists
247 xyzzy: not overwriting - file exists
248 (hg copy --after to record the copy)
248 (hg copy --after to record the copy)
249
249
250 $ cd ..
250 $ cd ..
@@ -1,406 +1,417 b''
1 $ cat << EOF >> $HGRCPATH
1 $ cat << EOF >> $HGRCPATH
2 > [ui]
2 > [ui]
3 > interactive=yes
3 > interactive=yes
4 > [format]
4 > [format]
5 > usegeneraldelta=yes
5 > usegeneraldelta=yes
6 > EOF
6 > EOF
7
7
8 $ hg init debugrevlog
8 $ hg init debugrevlog
9 $ cd debugrevlog
9 $ cd debugrevlog
10 $ echo a > a
10 $ echo a > a
11 $ hg ci -Am adda
11 $ hg ci -Am adda
12 adding a
12 adding a
13 $ hg debugrevlog -m
13 $ hg debugrevlog -m
14 format : 1
14 format : 1
15 flags : inline, generaldelta
15 flags : inline, generaldelta
16
16
17 revisions : 1
17 revisions : 1
18 merges : 0 ( 0.00%)
18 merges : 0 ( 0.00%)
19 normal : 1 (100.00%)
19 normal : 1 (100.00%)
20 revisions : 1
20 revisions : 1
21 full : 1 (100.00%)
21 full : 1 (100.00%)
22 deltas : 0 ( 0.00%)
22 deltas : 0 ( 0.00%)
23 revision size : 44
23 revision size : 44
24 full : 44 (100.00%)
24 full : 44 (100.00%)
25 deltas : 0 ( 0.00%)
25 deltas : 0 ( 0.00%)
26
26
27 chunks : 1
27 chunks : 1
28 0x75 (u) : 1 (100.00%)
28 0x75 (u) : 1 (100.00%)
29 chunks size : 44
29 chunks size : 44
30 0x75 (u) : 44 (100.00%)
30 0x75 (u) : 44 (100.00%)
31
31
32 avg chain length : 0
32 avg chain length : 0
33 max chain length : 0
33 max chain length : 0
34 max chain reach : 44
34 max chain reach : 44
35 compression ratio : 0
35 compression ratio : 0
36
36
37 uncompressed data size (min/max/avg) : 43 / 43 / 43
37 uncompressed data size (min/max/avg) : 43 / 43 / 43
38 full revision size (min/max/avg) : 44 / 44 / 44
38 full revision size (min/max/avg) : 44 / 44 / 44
39 delta size (min/max/avg) : 0 / 0 / 0
39 delta size (min/max/avg) : 0 / 0 / 0
40
40
41 Test debugindex, with and without the --debug flag
41 Test debugindex, with and without the --verbose/--debug flag
42 $ hg debugindex a
42 $ hg debugindex a
43 rev linkrev nodeid p1 p2
44 0 0 b789fdd96dc2 000000000000 000000000000
45
46 $ hg --verbose debugindex a
43 rev offset length linkrev nodeid p1 p2
47 rev offset length linkrev nodeid p1 p2
44 0 0 3 0 b789fdd96dc2 000000000000 000000000000
48 0 0 3 0 b789fdd96dc2 000000000000 000000000000
49
45 $ hg --debug debugindex a
50 $ hg --debug debugindex a
46 rev offset length linkrev nodeid p1 p2
51 rev offset length linkrev nodeid p1 p2
47 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
52 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
53
48 $ hg debugindex -f 1 a
54 $ hg debugindex -f 1 a
55 rev flag size link p1 p2 nodeid
56 0 0000 2 0 -1 -1 b789fdd96dc2
57
58 $ hg --verbose debugindex -f 1 a
49 rev flag offset length size link p1 p2 nodeid
59 rev flag offset length size link p1 p2 nodeid
50 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
60 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
61
51 $ hg --debug debugindex -f 1 a
62 $ hg --debug debugindex -f 1 a
52 rev flag offset length size link p1 p2 nodeid
63 rev flag offset length size link p1 p2 nodeid
53 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
64 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
54
65
55 debugdelta chain basic output
66 debugdelta chain basic output
56
67
57 $ hg debugdeltachain -m
68 $ hg debugdeltachain -m
58 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
69 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
59 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000
70 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000
60
71
61 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
72 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
62 0 1 1
73 0 1 1
63
74
64 $ hg debugdeltachain -m -Tjson
75 $ hg debugdeltachain -m -Tjson
65 [
76 [
66 {
77 {
67 "chainid": 1,
78 "chainid": 1,
68 "chainlen": 1,
79 "chainlen": 1,
69 "chainratio": 1.02325581395,
80 "chainratio": 1.02325581395,
70 "chainsize": 44,
81 "chainsize": 44,
71 "compsize": 44,
82 "compsize": 44,
72 "deltatype": "base",
83 "deltatype": "base",
73 "extradist": 0,
84 "extradist": 0,
74 "extraratio": 0.0,
85 "extraratio": 0.0,
75 "lindist": 44,
86 "lindist": 44,
76 "prevrev": -1,
87 "prevrev": -1,
77 "rev": 0,
88 "rev": 0,
78 "uncompsize": 43
89 "uncompsize": 43
79 }
90 }
80 ]
91 ]
81
92
82 debugdelta chain with sparse read enabled
93 debugdelta chain with sparse read enabled
83
94
84 $ cat >> $HGRCPATH <<EOF
95 $ cat >> $HGRCPATH <<EOF
85 > [experimental]
96 > [experimental]
86 > sparse-read = True
97 > sparse-read = True
87 > EOF
98 > EOF
88 $ hg debugdeltachain -m
99 $ hg debugdeltachain -m
89 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
100 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
90 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
101 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
91
102
92 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
103 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
93 0 1 1 44 44 1.0
104 0 1 1 44 44 1.0
94
105
95 $ hg debugdeltachain -m -Tjson
106 $ hg debugdeltachain -m -Tjson
96 [
107 [
97 {
108 {
98 "chainid": 1,
109 "chainid": 1,
99 "chainlen": 1,
110 "chainlen": 1,
100 "chainratio": 1.02325581395,
111 "chainratio": 1.02325581395,
101 "chainsize": 44,
112 "chainsize": 44,
102 "compsize": 44,
113 "compsize": 44,
103 "deltatype": "base",
114 "deltatype": "base",
104 "extradist": 0,
115 "extradist": 0,
105 "extraratio": 0.0,
116 "extraratio": 0.0,
106 "largestblock": 44,
117 "largestblock": 44,
107 "lindist": 44,
118 "lindist": 44,
108 "prevrev": -1,
119 "prevrev": -1,
109 "readdensity": 1.0,
120 "readdensity": 1.0,
110 "readsize": 44,
121 "readsize": 44,
111 "rev": 0,
122 "rev": 0,
112 "srchunks": 1,
123 "srchunks": 1,
113 "uncompsize": 43
124 "uncompsize": 43
114 }
125 }
115 ]
126 ]
116
127
117 $ printf "This test checks things.\n" >> a
128 $ printf "This test checks things.\n" >> a
118 $ hg ci -m a
129 $ hg ci -m a
119 $ hg branch other
130 $ hg branch other
120 marked working directory as branch other
131 marked working directory as branch other
121 (branches are permanent and global, did you want a bookmark?)
132 (branches are permanent and global, did you want a bookmark?)
122 $ for i in `$TESTDIR/seq.py 5`; do
133 $ for i in `$TESTDIR/seq.py 5`; do
123 > printf "shorter ${i}" >> a
134 > printf "shorter ${i}" >> a
124 > hg ci -m "a other:$i"
135 > hg ci -m "a other:$i"
125 > hg up -q default
136 > hg up -q default
126 > printf "for the branch default we want longer chains: ${i}" >> a
137 > printf "for the branch default we want longer chains: ${i}" >> a
127 > hg ci -m "a default:$i"
138 > hg ci -m "a default:$i"
128 > hg up -q other
139 > hg up -q other
129 > done
140 > done
130 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
141 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
131 > --config experimental.sparse-read.density-threshold=0.50 \
142 > --config experimental.sparse-read.density-threshold=0.50 \
132 > --config experimental.sparse-read.min-gap-size=0
143 > --config experimental.sparse-read.min-gap-size=0
133 0 1
144 0 1
134 1 1
145 1 1
135 2 1
146 2 1
136 3 1
147 3 1
137 4 1
148 4 1
138 5 1
149 5 1
139 6 1
150 6 1
140 7 1
151 7 1
141 8 1
152 8 1
142 9 1
153 9 1
143 10 2
154 10 2
144 11 1
155 11 1
145 $ hg --config extensions.strip= strip --no-backup -r 1
156 $ hg --config extensions.strip= strip --no-backup -r 1
146 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
157 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
147
158
148 Test max chain len
159 Test max chain len
149 $ cat >> $HGRCPATH << EOF
160 $ cat >> $HGRCPATH << EOF
150 > [format]
161 > [format]
151 > maxchainlen=4
162 > maxchainlen=4
152 > EOF
163 > EOF
153
164
154 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
165 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
155 $ hg ci -m a
166 $ hg ci -m a
156 $ printf "b\n" >> a
167 $ printf "b\n" >> a
157 $ hg ci -m a
168 $ hg ci -m a
158 $ printf "c\n" >> a
169 $ printf "c\n" >> a
159 $ hg ci -m a
170 $ hg ci -m a
160 $ printf "d\n" >> a
171 $ printf "d\n" >> a
161 $ hg ci -m a
172 $ hg ci -m a
162 $ printf "e\n" >> a
173 $ printf "e\n" >> a
163 $ hg ci -m a
174 $ hg ci -m a
164 $ printf "f\n" >> a
175 $ printf "f\n" >> a
165 $ hg ci -m a
176 $ hg ci -m a
166 $ printf 'g\n' >> a
177 $ printf 'g\n' >> a
167 $ hg ci -m a
178 $ hg ci -m a
168 $ printf 'h\n' >> a
179 $ printf 'h\n' >> a
169 $ hg ci -m a
180 $ hg ci -m a
170 $ hg debugrevlog -d a
181 $ hg debugrevlog -d a
171 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
182 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
172 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
183 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
173 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
184 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
174 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
185 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
175 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
186 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
176 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
187 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
177 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
188 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
178 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
189 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
179 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
190 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
180 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
191 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
181
192
182 Test debuglocks command:
193 Test debuglocks command:
183
194
184 $ hg debuglocks
195 $ hg debuglocks
185 lock: free
196 lock: free
186 wlock: free
197 wlock: free
187
198
188 * Test setting the lock
199 * Test setting the lock
189
200
190 waitlock <file> will wait for file to be created. If it isn't in a reasonable
201 waitlock <file> will wait for file to be created. If it isn't in a reasonable
191 amount of time, displays error message and returns 1
202 amount of time, displays error message and returns 1
192 $ waitlock() {
203 $ waitlock() {
193 > start=`date +%s`
204 > start=`date +%s`
194 > timeout=5
205 > timeout=5
195 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
206 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
196 > now=`date +%s`
207 > now=`date +%s`
197 > if [ "`expr $now - $start`" -gt $timeout ]; then
208 > if [ "`expr $now - $start`" -gt $timeout ]; then
198 > echo "timeout: $1 was not created in $timeout seconds"
209 > echo "timeout: $1 was not created in $timeout seconds"
199 > return 1
210 > return 1
200 > fi
211 > fi
201 > sleep 0.1
212 > sleep 0.1
202 > done
213 > done
203 > }
214 > }
204 $ dolock() {
215 $ dolock() {
205 > {
216 > {
206 > waitlock .hg/unlock
217 > waitlock .hg/unlock
207 > rm -f .hg/unlock
218 > rm -f .hg/unlock
208 > echo y
219 > echo y
209 > } | hg debuglocks "$@" > /dev/null
220 > } | hg debuglocks "$@" > /dev/null
210 > }
221 > }
211 $ dolock -s &
222 $ dolock -s &
212 $ waitlock .hg/store/lock
223 $ waitlock .hg/store/lock
213
224
214 $ hg debuglocks
225 $ hg debuglocks
215 lock: user *, process * (*s) (glob)
226 lock: user *, process * (*s) (glob)
216 wlock: free
227 wlock: free
217 [1]
228 [1]
218 $ touch .hg/unlock
229 $ touch .hg/unlock
219 $ wait
230 $ wait
220 $ [ -f .hg/store/lock ] || echo "There is no lock"
231 $ [ -f .hg/store/lock ] || echo "There is no lock"
221 There is no lock
232 There is no lock
222
233
223 * Test setting the wlock
234 * Test setting the wlock
224
235
225 $ dolock -S &
236 $ dolock -S &
226 $ waitlock .hg/wlock
237 $ waitlock .hg/wlock
227
238
228 $ hg debuglocks
239 $ hg debuglocks
229 lock: free
240 lock: free
230 wlock: user *, process * (*s) (glob)
241 wlock: user *, process * (*s) (glob)
231 [1]
242 [1]
232 $ touch .hg/unlock
243 $ touch .hg/unlock
233 $ wait
244 $ wait
234 $ [ -f .hg/wlock ] || echo "There is no wlock"
245 $ [ -f .hg/wlock ] || echo "There is no wlock"
235 There is no wlock
246 There is no wlock
236
247
237 * Test setting both locks
248 * Test setting both locks
238
249
239 $ dolock -Ss &
250 $ dolock -Ss &
240 $ waitlock .hg/wlock && waitlock .hg/store/lock
251 $ waitlock .hg/wlock && waitlock .hg/store/lock
241
252
242 $ hg debuglocks
253 $ hg debuglocks
243 lock: user *, process * (*s) (glob)
254 lock: user *, process * (*s) (glob)
244 wlock: user *, process * (*s) (glob)
255 wlock: user *, process * (*s) (glob)
245 [2]
256 [2]
246
257
247 * Test failing to set a lock
258 * Test failing to set a lock
248
259
249 $ hg debuglocks -s
260 $ hg debuglocks -s
250 abort: lock is already held
261 abort: lock is already held
251 [255]
262 [255]
252
263
253 $ hg debuglocks -S
264 $ hg debuglocks -S
254 abort: wlock is already held
265 abort: wlock is already held
255 [255]
266 [255]
256
267
257 $ touch .hg/unlock
268 $ touch .hg/unlock
258 $ wait
269 $ wait
259
270
260 $ hg debuglocks
271 $ hg debuglocks
261 lock: free
272 lock: free
262 wlock: free
273 wlock: free
263
274
264 * Test forcing the lock
275 * Test forcing the lock
265
276
266 $ dolock -s &
277 $ dolock -s &
267 $ waitlock .hg/store/lock
278 $ waitlock .hg/store/lock
268
279
269 $ hg debuglocks
280 $ hg debuglocks
270 lock: user *, process * (*s) (glob)
281 lock: user *, process * (*s) (glob)
271 wlock: free
282 wlock: free
272 [1]
283 [1]
273
284
274 $ hg debuglocks -L
285 $ hg debuglocks -L
275
286
276 $ hg debuglocks
287 $ hg debuglocks
277 lock: free
288 lock: free
278 wlock: free
289 wlock: free
279
290
280 $ touch .hg/unlock
291 $ touch .hg/unlock
281 $ wait
292 $ wait
282
293
283 * Test forcing the wlock
294 * Test forcing the wlock
284
295
285 $ dolock -S &
296 $ dolock -S &
286 $ waitlock .hg/wlock
297 $ waitlock .hg/wlock
287
298
288 $ hg debuglocks
299 $ hg debuglocks
289 lock: free
300 lock: free
290 wlock: user *, process * (*s) (glob)
301 wlock: user *, process * (*s) (glob)
291 [1]
302 [1]
292
303
293 $ hg debuglocks -W
304 $ hg debuglocks -W
294
305
295 $ hg debuglocks
306 $ hg debuglocks
296 lock: free
307 lock: free
297 wlock: free
308 wlock: free
298
309
299 $ touch .hg/unlock
310 $ touch .hg/unlock
300 $ wait
311 $ wait
301
312
302 Test WdirUnsupported exception
313 Test WdirUnsupported exception
303
314
304 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
315 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
305 abort: working directory revision cannot be specified
316 abort: working directory revision cannot be specified
306 [255]
317 [255]
307
318
308 Test cache warming command
319 Test cache warming command
309
320
310 $ rm -rf .hg/cache/
321 $ rm -rf .hg/cache/
311 $ hg debugupdatecaches --debug
322 $ hg debugupdatecaches --debug
312 updating the branch cache
323 updating the branch cache
313 $ ls -r .hg/cache/*
324 $ ls -r .hg/cache/*
314 .hg/cache/rbc-revs-v1
325 .hg/cache/rbc-revs-v1
315 .hg/cache/rbc-names-v1
326 .hg/cache/rbc-names-v1
316 .hg/cache/branch2-served
327 .hg/cache/branch2-served
317
328
318 $ cd ..
329 $ cd ..
319
330
320 Test internal debugstacktrace command
331 Test internal debugstacktrace command
321
332
322 $ cat > debugstacktrace.py << EOF
333 $ cat > debugstacktrace.py << EOF
323 > from __future__ import absolute_import
334 > from __future__ import absolute_import
324 > import sys
335 > import sys
325 > from mercurial import util
336 > from mercurial import util
326 > def f():
337 > def f():
327 > util.debugstacktrace(f=sys.stdout)
338 > util.debugstacktrace(f=sys.stdout)
328 > g()
339 > g()
329 > def g():
340 > def g():
330 > util.dst('hello from g\\n', skip=1)
341 > util.dst('hello from g\\n', skip=1)
331 > h()
342 > h()
332 > def h():
343 > def h():
333 > util.dst('hi ...\\nfrom h hidden in g', 1, depth=2)
344 > util.dst('hi ...\\nfrom h hidden in g', 1, depth=2)
334 > f()
345 > f()
335 > EOF
346 > EOF
336 $ $PYTHON debugstacktrace.py
347 $ $PYTHON debugstacktrace.py
337 stacktrace at:
348 stacktrace at:
338 debugstacktrace.py:12 in * (glob)
349 debugstacktrace.py:12 in * (glob)
339 debugstacktrace.py:5 in f
350 debugstacktrace.py:5 in f
340 hello from g at:
351 hello from g at:
341 debugstacktrace.py:12 in * (glob)
352 debugstacktrace.py:12 in * (glob)
342 debugstacktrace.py:6 in f
353 debugstacktrace.py:6 in f
343 hi ...
354 hi ...
344 from h hidden in g at:
355 from h hidden in g at:
345 debugstacktrace.py:6 in f
356 debugstacktrace.py:6 in f
346 debugstacktrace.py:9 in g
357 debugstacktrace.py:9 in g
347
358
348 Test debugcapabilities command:
359 Test debugcapabilities command:
349
360
350 $ hg debugcapabilities ./debugrevlog/
361 $ hg debugcapabilities ./debugrevlog/
351 Main capabilities:
362 Main capabilities:
352 branchmap
363 branchmap
353 $USUAL_BUNDLE2_CAPS$
364 $USUAL_BUNDLE2_CAPS$
354 getbundle
365 getbundle
355 known
366 known
356 lookup
367 lookup
357 pushkey
368 pushkey
358 unbundle
369 unbundle
359 Bundle2 capabilities:
370 Bundle2 capabilities:
360 HG20
371 HG20
361 bookmarks
372 bookmarks
362 changegroup
373 changegroup
363 01
374 01
364 02
375 02
365 digests
376 digests
366 md5
377 md5
367 sha1
378 sha1
368 sha512
379 sha512
369 error
380 error
370 abort
381 abort
371 unsupportedcontent
382 unsupportedcontent
372 pushraced
383 pushraced
373 pushkey
384 pushkey
374 hgtagsfnodes
385 hgtagsfnodes
375 listkeys
386 listkeys
376 phases
387 phases
377 heads
388 heads
378 pushkey
389 pushkey
379 remote-changegroup
390 remote-changegroup
380 http
391 http
381 https
392 https
382 rev-branch-cache
393 rev-branch-cache
383 stream
394 stream
384 v2
395 v2
385
396
386 Test debugpeer
397 Test debugpeer
387
398
388 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
399 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
389 url: ssh://user@dummy/debugrevlog
400 url: ssh://user@dummy/debugrevlog
390 local: no
401 local: no
391 pushable: yes
402 pushable: yes
392
403
393 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
404 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
394 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
405 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
395 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
406 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
396 devel-peer-request: hello
407 devel-peer-request: hello
397 sending hello command
408 sending hello command
398 devel-peer-request: between
409 devel-peer-request: between
399 devel-peer-request: pairs: 81 bytes
410 devel-peer-request: pairs: 81 bytes
400 sending between command
411 sending between command
401 remote: 403
412 remote: 403
402 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
413 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
403 remote: 1
414 remote: 1
404 url: ssh://user@dummy/debugrevlog
415 url: ssh://user@dummy/debugrevlog
405 local: no
416 local: no
406 pushable: yes
417 pushable: yes
@@ -1,101 +1,101 b''
1 $ hg init
1 $ hg init
2
2
3 $ echo foo > a
3 $ echo foo > a
4 $ echo foo > b
4 $ echo foo > b
5 $ hg add a b
5 $ hg add a b
6
6
7 $ hg ci -m "test"
7 $ hg ci -m "test"
8
8
9 $ echo blah > a
9 $ echo blah > a
10
10
11 $ hg ci -m "branch a"
11 $ hg ci -m "branch a"
12
12
13 $ hg co 0
13 $ hg co 0
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15
15
16 $ echo blah > b
16 $ echo blah > b
17
17
18 $ hg ci -m "branch b"
18 $ hg ci -m "branch b"
19 created new head
19 created new head
20 $ HGMERGE=true hg merge 1
20 $ HGMERGE=true hg merge 1
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 (branch merge, don't forget to commit)
22 (branch merge, don't forget to commit)
23
23
24 $ hg ci -m "merge b/a -> blah"
24 $ hg ci -m "merge b/a -> blah"
25
25
26 $ hg co 1
26 $ hg co 1
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 $ HGMERGE=true hg merge 2
28 $ HGMERGE=true hg merge 2
29 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 (branch merge, don't forget to commit)
30 (branch merge, don't forget to commit)
31 $ hg ci -m "merge a/b -> blah"
31 $ hg ci -m "merge a/b -> blah"
32 created new head
32 created new head
33
33
34 $ hg log
34 $ hg log
35 changeset: 4:2ee31f665a86
35 changeset: 4:2ee31f665a86
36 tag: tip
36 tag: tip
37 parent: 1:96155394af80
37 parent: 1:96155394af80
38 parent: 2:92cc4c306b19
38 parent: 2:92cc4c306b19
39 user: test
39 user: test
40 date: Thu Jan 01 00:00:00 1970 +0000
40 date: Thu Jan 01 00:00:00 1970 +0000
41 summary: merge a/b -> blah
41 summary: merge a/b -> blah
42
42
43 changeset: 3:e16a66a37edd
43 changeset: 3:e16a66a37edd
44 parent: 2:92cc4c306b19
44 parent: 2:92cc4c306b19
45 parent: 1:96155394af80
45 parent: 1:96155394af80
46 user: test
46 user: test
47 date: Thu Jan 01 00:00:00 1970 +0000
47 date: Thu Jan 01 00:00:00 1970 +0000
48 summary: merge b/a -> blah
48 summary: merge b/a -> blah
49
49
50 changeset: 2:92cc4c306b19
50 changeset: 2:92cc4c306b19
51 parent: 0:5e0375449e74
51 parent: 0:5e0375449e74
52 user: test
52 user: test
53 date: Thu Jan 01 00:00:00 1970 +0000
53 date: Thu Jan 01 00:00:00 1970 +0000
54 summary: branch b
54 summary: branch b
55
55
56 changeset: 1:96155394af80
56 changeset: 1:96155394af80
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59 summary: branch a
59 summary: branch a
60
60
61 changeset: 0:5e0375449e74
61 changeset: 0:5e0375449e74
62 user: test
62 user: test
63 date: Thu Jan 01 00:00:00 1970 +0000
63 date: Thu Jan 01 00:00:00 1970 +0000
64 summary: test
64 summary: test
65
65
66 $ hg debugindex --changelog
66 $ hg debugindex --changelog
67 rev offset length linkrev nodeid p1 p2
67 rev linkrev nodeid p1 p2
68 0 0 60 0 5e0375449e74 000000000000 000000000000
68 0 0 5e0375449e74 000000000000 000000000000
69 1 60 62 1 96155394af80 5e0375449e74 000000000000
69 1 1 96155394af80 5e0375449e74 000000000000
70 2 122 62 2 92cc4c306b19 5e0375449e74 000000000000
70 2 2 92cc4c306b19 5e0375449e74 000000000000
71 3 184 69 3 e16a66a37edd 92cc4c306b19 96155394af80
71 3 3 e16a66a37edd 92cc4c306b19 96155394af80
72 4 253 69 4 2ee31f665a86 96155394af80 92cc4c306b19
72 4 4 2ee31f665a86 96155394af80 92cc4c306b19
73
73
74 revision 1
74 revision 1
75 $ hg manifest --debug 1
75 $ hg manifest --debug 1
76 79d7492df40aa0fa093ec4209be78043c181f094 644 a
76 79d7492df40aa0fa093ec4209be78043c181f094 644 a
77 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 b
77 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 b
78 revision 2
78 revision 2
79 $ hg manifest --debug 2
79 $ hg manifest --debug 2
80 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 a
80 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 a
81 79d7492df40aa0fa093ec4209be78043c181f094 644 b
81 79d7492df40aa0fa093ec4209be78043c181f094 644 b
82 revision 3
82 revision 3
83 $ hg manifest --debug 3
83 $ hg manifest --debug 3
84 79d7492df40aa0fa093ec4209be78043c181f094 644 a
84 79d7492df40aa0fa093ec4209be78043c181f094 644 a
85 79d7492df40aa0fa093ec4209be78043c181f094 644 b
85 79d7492df40aa0fa093ec4209be78043c181f094 644 b
86 revision 4
86 revision 4
87 $ hg manifest --debug 4
87 $ hg manifest --debug 4
88 79d7492df40aa0fa093ec4209be78043c181f094 644 a
88 79d7492df40aa0fa093ec4209be78043c181f094 644 a
89 79d7492df40aa0fa093ec4209be78043c181f094 644 b
89 79d7492df40aa0fa093ec4209be78043c181f094 644 b
90
90
91 $ hg debugindex a
91 $ hg debugindex a
92 rev offset length linkrev nodeid p1 p2
92 rev linkrev nodeid p1 p2
93 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
93 0 0 2ed2a3912a0b 000000000000 000000000000
94 1 5 6 1 79d7492df40a 2ed2a3912a0b 000000000000
94 1 1 79d7492df40a 2ed2a3912a0b 000000000000
95
95
96 $ hg verify
96 $ hg verify
97 checking changesets
97 checking changesets
98 checking manifests
98 checking manifests
99 crosschecking files in changesets and manifests
99 crosschecking files in changesets and manifests
100 checking files
100 checking files
101 2 files, 5 changesets, 4 total revisions
101 2 files, 5 changesets, 4 total revisions
@@ -1,21 +1,21 b''
1 Issue351: mq: qrefresh can create extra revlog entry
1 Issue351: mq: qrefresh can create extra revlog entry
2
2
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "mq=" >> $HGRCPATH
4 $ echo "mq=" >> $HGRCPATH
5
5
6 $ hg init
6 $ hg init
7 $ hg qinit
7 $ hg qinit
8
8
9 $ echo b > b
9 $ echo b > b
10 $ hg ci -A -m foo
10 $ hg ci -A -m foo
11 adding b
11 adding b
12
12
13 $ echo cc > b
13 $ echo cc > b
14 $ hg qnew -f foo.diff
14 $ hg qnew -f foo.diff
15 $ echo b > b
15 $ echo b > b
16 $ hg qrefresh
16 $ hg qrefresh
17
17
18 $ hg debugindex b
18 $ hg debugindex b
19 rev offset length linkrev nodeid p1 p2
19 rev linkrev nodeid p1 p2
20 0 0 3 0 1e88685f5dde 000000000000 000000000000
20 0 0 1e88685f5dde 000000000000 000000000000
21
21
@@ -1,146 +1,146 b''
1 This test makes sure that we don't mark a file as merged with its ancestor
1 This test makes sure that we don't mark a file as merged with its ancestor
2 when we do a merge.
2 when we do a merge.
3
3
4 $ cat <<EOF > merge
4 $ cat <<EOF > merge
5 > from __future__ import print_function
5 > from __future__ import print_function
6 > import sys, os
6 > import sys, os
7 > print("merging for", os.path.basename(sys.argv[1]))
7 > print("merging for", os.path.basename(sys.argv[1]))
8 > EOF
8 > EOF
9 $ HGMERGE="$PYTHON ../merge"; export HGMERGE
9 $ HGMERGE="$PYTHON ../merge"; export HGMERGE
10
10
11 Creating base:
11 Creating base:
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ echo 1 > foo
15 $ echo 1 > foo
16 $ echo 1 > bar
16 $ echo 1 > bar
17 $ echo 1 > baz
17 $ echo 1 > baz
18 $ echo 1 > quux
18 $ echo 1 > quux
19 $ hg add foo bar baz quux
19 $ hg add foo bar baz quux
20 $ hg commit -m "base"
20 $ hg commit -m "base"
21
21
22 $ cd ..
22 $ cd ..
23 $ hg clone a b
23 $ hg clone a b
24 updating to branch default
24 updating to branch default
25 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
26
26
27 Creating branch a:
27 Creating branch a:
28
28
29 $ cd a
29 $ cd a
30 $ echo 2a > foo
30 $ echo 2a > foo
31 $ echo 2a > bar
31 $ echo 2a > bar
32 $ hg commit -m "branch a"
32 $ hg commit -m "branch a"
33
33
34 Creating branch b:
34 Creating branch b:
35
35
36 $ cd ..
36 $ cd ..
37 $ cd b
37 $ cd b
38 $ echo 2b > foo
38 $ echo 2b > foo
39 $ echo 2b > baz
39 $ echo 2b > baz
40 $ hg commit -m "branch b"
40 $ hg commit -m "branch b"
41
41
42 We shouldn't have anything but n state here:
42 We shouldn't have anything but n state here:
43
43
44 $ hg debugstate --nodates | grep -v "^n"
44 $ hg debugstate --nodates | grep -v "^n"
45 [1]
45 [1]
46
46
47 Merging:
47 Merging:
48
48
49 $ hg pull ../a
49 $ hg pull ../a
50 pulling from ../a
50 pulling from ../a
51 searching for changes
51 searching for changes
52 adding changesets
52 adding changesets
53 adding manifests
53 adding manifests
54 adding file changes
54 adding file changes
55 added 1 changesets with 2 changes to 2 files (+1 heads)
55 added 1 changesets with 2 changes to 2 files (+1 heads)
56 new changesets bdd988058d16
56 new changesets bdd988058d16
57 (run 'hg heads' to see heads, 'hg merge' to merge)
57 (run 'hg heads' to see heads, 'hg merge' to merge)
58
58
59 $ hg merge -v
59 $ hg merge -v
60 resolving manifests
60 resolving manifests
61 getting bar
61 getting bar
62 merging foo
62 merging foo
63 merging for foo
63 merging for foo
64 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
64 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
65 (branch merge, don't forget to commit)
65 (branch merge, don't forget to commit)
66
66
67 $ echo 2m > foo
67 $ echo 2m > foo
68 $ echo 2b > baz
68 $ echo 2b > baz
69 $ echo new > quux
69 $ echo new > quux
70
70
71 $ hg ci -m "merge"
71 $ hg ci -m "merge"
72
72
73 main: we should have a merge here:
73 main: we should have a merge here:
74
74
75 $ hg debugindex --changelog
75 $ hg debugindex --changelog
76 rev offset length linkrev nodeid p1 p2
76 rev linkrev nodeid p1 p2
77 0 0 73 0 cdca01651b96 000000000000 000000000000
77 0 0 cdca01651b96 000000000000 000000000000
78 1 73 68 1 f6718a9cb7f3 cdca01651b96 000000000000
78 1 1 f6718a9cb7f3 cdca01651b96 000000000000
79 2 141 68 2 bdd988058d16 cdca01651b96 000000000000
79 2 2 bdd988058d16 cdca01651b96 000000000000
80 3 209 66 3 d8a521142a3c f6718a9cb7f3 bdd988058d16
80 3 3 d8a521142a3c f6718a9cb7f3 bdd988058d16
81
81
82 log should show foo and quux changed:
82 log should show foo and quux changed:
83
83
84 $ hg log -v -r tip
84 $ hg log -v -r tip
85 changeset: 3:d8a521142a3c
85 changeset: 3:d8a521142a3c
86 tag: tip
86 tag: tip
87 parent: 1:f6718a9cb7f3
87 parent: 1:f6718a9cb7f3
88 parent: 2:bdd988058d16
88 parent: 2:bdd988058d16
89 user: test
89 user: test
90 date: Thu Jan 01 00:00:00 1970 +0000
90 date: Thu Jan 01 00:00:00 1970 +0000
91 files: foo quux
91 files: foo quux
92 description:
92 description:
93 merge
93 merge
94
94
95
95
96
96
97 foo: we should have a merge here:
97 foo: we should have a merge here:
98
98
99 $ hg debugindex foo
99 $ hg debugindex foo
100 rev offset length linkrev nodeid p1 p2
100 rev linkrev nodeid p1 p2
101 0 0 3 0 b8e02f643373 000000000000 000000000000
101 0 0 b8e02f643373 000000000000 000000000000
102 1 3 4 1 2ffeddde1b65 b8e02f643373 000000000000
102 1 1 2ffeddde1b65 b8e02f643373 000000000000
103 2 7 4 2 33d1fb69067a b8e02f643373 000000000000
103 2 2 33d1fb69067a b8e02f643373 000000000000
104 3 11 4 3 aa27919ee430 2ffeddde1b65 33d1fb69067a
104 3 3 aa27919ee430 2ffeddde1b65 33d1fb69067a
105
105
106 bar: we should not have a merge here:
106 bar: we should not have a merge here:
107
107
108 $ hg debugindex bar
108 $ hg debugindex bar
109 rev offset length linkrev nodeid p1 p2
109 rev linkrev nodeid p1 p2
110 0 0 3 0 b8e02f643373 000000000000 000000000000
110 0 0 b8e02f643373 000000000000 000000000000
111 1 3 4 2 33d1fb69067a b8e02f643373 000000000000
111 1 2 33d1fb69067a b8e02f643373 000000000000
112
112
113 baz: we should not have a merge here:
113 baz: we should not have a merge here:
114
114
115 $ hg debugindex baz
115 $ hg debugindex baz
116 rev offset length linkrev nodeid p1 p2
116 rev linkrev nodeid p1 p2
117 0 0 3 0 b8e02f643373 000000000000 000000000000
117 0 0 b8e02f643373 000000000000 000000000000
118 1 3 4 1 2ffeddde1b65 b8e02f643373 000000000000
118 1 1 2ffeddde1b65 b8e02f643373 000000000000
119
119
120 quux: we should not have a merge here:
120 quux: we should not have a merge here:
121
121
122 $ hg debugindex quux
122 $ hg debugindex quux
123 rev offset length linkrev nodeid p1 p2
123 rev linkrev nodeid p1 p2
124 0 0 3 0 b8e02f643373 000000000000 000000000000
124 0 0 b8e02f643373 000000000000 000000000000
125 1 3 5 3 6128c0f33108 b8e02f643373 000000000000
125 1 3 6128c0f33108 b8e02f643373 000000000000
126
126
127 Manifest entries should match tips of all files:
127 Manifest entries should match tips of all files:
128
128
129 $ hg manifest --debug
129 $ hg manifest --debug
130 33d1fb69067a0139622a3fa3b7ba1cdb1367972e 644 bar
130 33d1fb69067a0139622a3fa3b7ba1cdb1367972e 644 bar
131 2ffeddde1b65b4827f6746174a145474129fa2ce 644 baz
131 2ffeddde1b65b4827f6746174a145474129fa2ce 644 baz
132 aa27919ee4303cfd575e1fb932dd64d75aa08be4 644 foo
132 aa27919ee4303cfd575e1fb932dd64d75aa08be4 644 foo
133 6128c0f33108e8cfbb4e0824d13ae48b466d7280 644 quux
133 6128c0f33108e8cfbb4e0824d13ae48b466d7280 644 quux
134
134
135 Everything should be clean now:
135 Everything should be clean now:
136
136
137 $ hg status
137 $ hg status
138
138
139 $ hg verify
139 $ hg verify
140 checking changesets
140 checking changesets
141 checking manifests
141 checking manifests
142 crosschecking files in changesets and manifests
142 crosschecking files in changesets and manifests
143 checking files
143 checking files
144 4 files, 4 changesets, 10 total revisions
144 4 files, 4 changesets, 10 total revisions
145
145
146 $ cd ..
146 $ cd ..
@@ -1,157 +1,157 b''
1 #require execbit
1 #require execbit
2
2
3 $ umask 027
3 $ umask 027
4
4
5 $ hg init test1
5 $ hg init test1
6 $ cd test1
6 $ cd test1
7 $ touch a b
7 $ touch a b
8 $ hg add a b
8 $ hg add a b
9 $ hg ci -m "added a b"
9 $ hg ci -m "added a b"
10
10
11 $ cd ..
11 $ cd ..
12 $ hg clone test1 test3
12 $ hg clone test1 test3
13 updating to branch default
13 updating to branch default
14 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
15
15
16 $ hg init test2
16 $ hg init test2
17 $ cd test2
17 $ cd test2
18 $ hg pull ../test1
18 $ hg pull ../test1
19 pulling from ../test1
19 pulling from ../test1
20 requesting all changes
20 requesting all changes
21 adding changesets
21 adding changesets
22 adding manifests
22 adding manifests
23 adding file changes
23 adding file changes
24 added 1 changesets with 2 changes to 2 files
24 added 1 changesets with 2 changes to 2 files
25 new changesets 22a449e20da5
25 new changesets 22a449e20da5
26 (run 'hg update' to get a working copy)
26 (run 'hg update' to get a working copy)
27 $ hg co
27 $ hg co
28 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 $ chmod +x a
29 $ chmod +x a
30 $ hg ci -m "chmod +x a"
30 $ hg ci -m "chmod +x a"
31
31
32 the changelog should mention file a:
32 the changelog should mention file a:
33
33
34 $ hg tip --template '{files}\n'
34 $ hg tip --template '{files}\n'
35 a
35 a
36
36
37 $ cd ../test1
37 $ cd ../test1
38 $ echo 123 >>a
38 $ echo 123 >>a
39 $ hg ci -m "a updated"
39 $ hg ci -m "a updated"
40
40
41 $ hg pull ../test2
41 $ hg pull ../test2
42 pulling from ../test2
42 pulling from ../test2
43 searching for changes
43 searching for changes
44 adding changesets
44 adding changesets
45 adding manifests
45 adding manifests
46 adding file changes
46 adding file changes
47 added 1 changesets with 0 changes to 0 files (+1 heads)
47 added 1 changesets with 0 changes to 0 files (+1 heads)
48 new changesets 7f4313b42a34
48 new changesets 7f4313b42a34
49 (run 'hg heads' to see heads, 'hg merge' to merge)
49 (run 'hg heads' to see heads, 'hg merge' to merge)
50 $ hg heads
50 $ hg heads
51 changeset: 2:7f4313b42a34
51 changeset: 2:7f4313b42a34
52 tag: tip
52 tag: tip
53 parent: 0:22a449e20da5
53 parent: 0:22a449e20da5
54 user: test
54 user: test
55 date: Thu Jan 01 00:00:00 1970 +0000
55 date: Thu Jan 01 00:00:00 1970 +0000
56 summary: chmod +x a
56 summary: chmod +x a
57
57
58 changeset: 1:c6ecefc45368
58 changeset: 1:c6ecefc45368
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: a updated
61 summary: a updated
62
62
63 $ hg history
63 $ hg history
64 changeset: 2:7f4313b42a34
64 changeset: 2:7f4313b42a34
65 tag: tip
65 tag: tip
66 parent: 0:22a449e20da5
66 parent: 0:22a449e20da5
67 user: test
67 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
68 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: chmod +x a
69 summary: chmod +x a
70
70
71 changeset: 1:c6ecefc45368
71 changeset: 1:c6ecefc45368
72 user: test
72 user: test
73 date: Thu Jan 01 00:00:00 1970 +0000
73 date: Thu Jan 01 00:00:00 1970 +0000
74 summary: a updated
74 summary: a updated
75
75
76 changeset: 0:22a449e20da5
76 changeset: 0:22a449e20da5
77 user: test
77 user: test
78 date: Thu Jan 01 00:00:00 1970 +0000
78 date: Thu Jan 01 00:00:00 1970 +0000
79 summary: added a b
79 summary: added a b
80
80
81
81
82 $ hg -v merge
82 $ hg -v merge
83 resolving manifests
83 resolving manifests
84 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 (branch merge, don't forget to commit)
85 (branch merge, don't forget to commit)
86 $ cat a
86 $ cat a
87 123
87 123
88 $ [ -x a ]
88 $ [ -x a ]
89
89
90 $ cd ../test3
90 $ cd ../test3
91 $ echo 123 >>b
91 $ echo 123 >>b
92 $ hg ci -m "b updated"
92 $ hg ci -m "b updated"
93
93
94 $ hg pull ../test2
94 $ hg pull ../test2
95 pulling from ../test2
95 pulling from ../test2
96 searching for changes
96 searching for changes
97 adding changesets
97 adding changesets
98 adding manifests
98 adding manifests
99 adding file changes
99 adding file changes
100 added 1 changesets with 0 changes to 0 files (+1 heads)
100 added 1 changesets with 0 changes to 0 files (+1 heads)
101 new changesets 7f4313b42a34
101 new changesets 7f4313b42a34
102 (run 'hg heads' to see heads, 'hg merge' to merge)
102 (run 'hg heads' to see heads, 'hg merge' to merge)
103 $ hg heads
103 $ hg heads
104 changeset: 2:7f4313b42a34
104 changeset: 2:7f4313b42a34
105 tag: tip
105 tag: tip
106 parent: 0:22a449e20da5
106 parent: 0:22a449e20da5
107 user: test
107 user: test
108 date: Thu Jan 01 00:00:00 1970 +0000
108 date: Thu Jan 01 00:00:00 1970 +0000
109 summary: chmod +x a
109 summary: chmod +x a
110
110
111 changeset: 1:dc57ead75f79
111 changeset: 1:dc57ead75f79
112 user: test
112 user: test
113 date: Thu Jan 01 00:00:00 1970 +0000
113 date: Thu Jan 01 00:00:00 1970 +0000
114 summary: b updated
114 summary: b updated
115
115
116 $ hg history
116 $ hg history
117 changeset: 2:7f4313b42a34
117 changeset: 2:7f4313b42a34
118 tag: tip
118 tag: tip
119 parent: 0:22a449e20da5
119 parent: 0:22a449e20da5
120 user: test
120 user: test
121 date: Thu Jan 01 00:00:00 1970 +0000
121 date: Thu Jan 01 00:00:00 1970 +0000
122 summary: chmod +x a
122 summary: chmod +x a
123
123
124 changeset: 1:dc57ead75f79
124 changeset: 1:dc57ead75f79
125 user: test
125 user: test
126 date: Thu Jan 01 00:00:00 1970 +0000
126 date: Thu Jan 01 00:00:00 1970 +0000
127 summary: b updated
127 summary: b updated
128
128
129 changeset: 0:22a449e20da5
129 changeset: 0:22a449e20da5
130 user: test
130 user: test
131 date: Thu Jan 01 00:00:00 1970 +0000
131 date: Thu Jan 01 00:00:00 1970 +0000
132 summary: added a b
132 summary: added a b
133
133
134
134
135 $ hg -v merge
135 $ hg -v merge
136 resolving manifests
136 resolving manifests
137 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
137 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
138 (branch merge, don't forget to commit)
138 (branch merge, don't forget to commit)
139
139
140 $ ls -l ../test[123]/a > foo
140 $ ls -l ../test[123]/a > foo
141 $ cut -b 1-10 < foo
141 $ cut -b 1-10 < foo
142 -rwxr-x---
142 -rwxr-x---
143 -rwxr-x---
143 -rwxr-x---
144 -rwxr-x---
144 -rwxr-x---
145
145
146 $ hg debugindex a
146 $ hg debugindex a
147 rev offset length linkrev nodeid p1 p2
147 rev linkrev nodeid p1 p2
148 0 0 0 0 b80de5d13875 000000000000 000000000000
148 0 0 b80de5d13875 000000000000 000000000000
149 $ hg debugindex -R ../test2 a
149 $ hg debugindex -R ../test2 a
150 rev offset length linkrev nodeid p1 p2
150 rev linkrev nodeid p1 p2
151 0 0 0 0 b80de5d13875 000000000000 000000000000
151 0 0 b80de5d13875 000000000000 000000000000
152 $ hg debugindex -R ../test1 a
152 $ hg debugindex -R ../test1 a
153 rev offset length linkrev nodeid p1 p2
153 rev linkrev nodeid p1 p2
154 0 0 0 0 b80de5d13875 000000000000 000000000000
154 0 0 b80de5d13875 000000000000 000000000000
155 1 0 5 1 7fe919cc0336 b80de5d13875 000000000000
155 1 1 7fe919cc0336 b80de5d13875 000000000000
156
156
157 $ cd ..
157 $ cd ..
@@ -1,55 +1,55 b''
1 https://bz.mercurial-scm.org/522
1 https://bz.mercurial-scm.org/522
2
2
3 In the merge below, the file "foo" has the same contents in both
3 In the merge below, the file "foo" has the same contents in both
4 parents, but if we look at the file-level history, we'll notice that
4 parents, but if we look at the file-level history, we'll notice that
5 the version in p1 is an ancestor of the version in p2. This test makes
5 the version in p1 is an ancestor of the version in p2. This test makes
6 sure that we'll use the version from p2 in the manifest of the merge
6 sure that we'll use the version from p2 in the manifest of the merge
7 revision.
7 revision.
8
8
9 $ hg init
9 $ hg init
10
10
11 $ echo foo > foo
11 $ echo foo > foo
12 $ hg ci -qAm 'add foo'
12 $ hg ci -qAm 'add foo'
13
13
14 $ echo bar >> foo
14 $ echo bar >> foo
15 $ hg ci -m 'change foo'
15 $ hg ci -m 'change foo'
16
16
17 $ hg backout -r tip -m 'backout changed foo'
17 $ hg backout -r tip -m 'backout changed foo'
18 reverting foo
18 reverting foo
19 changeset 2:4d9e78aaceee backs out changeset 1:b515023e500e
19 changeset 2:4d9e78aaceee backs out changeset 1:b515023e500e
20
20
21 $ hg up -C 0
21 $ hg up -C 0
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23
23
24 $ touch bar
24 $ touch bar
25 $ hg ci -qAm 'add bar'
25 $ hg ci -qAm 'add bar'
26
26
27 $ hg merge --debug
27 $ hg merge --debug
28 searching for copies back to rev 1
28 searching for copies back to rev 1
29 unmatched files in local:
29 unmatched files in local:
30 bar
30 bar
31 resolving manifests
31 resolving manifests
32 branchmerge: True, force: False, partial: False
32 branchmerge: True, force: False, partial: False
33 ancestor: bbd179dfa0a7, local: 71766447bdbb+, remote: 4d9e78aaceee
33 ancestor: bbd179dfa0a7, local: 71766447bdbb+, remote: 4d9e78aaceee
34 foo: remote is newer -> g
34 foo: remote is newer -> g
35 getting foo
35 getting foo
36 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 (branch merge, don't forget to commit)
37 (branch merge, don't forget to commit)
38
38
39 $ hg debugstate | grep foo
39 $ hg debugstate | grep foo
40 m 0 -2 unset foo
40 m 0 -2 unset foo
41
41
42 $ hg st -A foo
42 $ hg st -A foo
43 M foo
43 M foo
44
44
45 $ hg ci -m 'merge'
45 $ hg ci -m 'merge'
46
46
47 $ hg manifest --debug | grep foo
47 $ hg manifest --debug | grep foo
48 c6fc755d7e68f49f880599da29f15add41f42f5a 644 foo
48 c6fc755d7e68f49f880599da29f15add41f42f5a 644 foo
49
49
50 $ hg debugindex foo
50 $ hg debugindex foo
51 rev offset length linkrev nodeid p1 p2
51 rev linkrev nodeid p1 p2
52 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
52 0 0 2ed2a3912a0b 000000000000 000000000000
53 1 5 9 1 6f4310b00b9a 2ed2a3912a0b 000000000000
53 1 1 6f4310b00b9a 2ed2a3912a0b 000000000000
54 2 14 5 2 c6fc755d7e68 6f4310b00b9a 000000000000
54 2 2 c6fc755d7e68 6f4310b00b9a 000000000000
55
55
@@ -1,185 +1,185 b''
1 Check that renames are correctly saved by a commit after a merge
1 Check that renames are correctly saved by a commit after a merge
2
2
3 Test with the merge on 3 having the rename on the local parent
3 Test with the merge on 3 having the rename on the local parent
4
4
5 $ hg init a
5 $ hg init a
6 $ cd a
6 $ cd a
7
7
8 $ echo line1 > foo
8 $ echo line1 > foo
9 $ hg add foo
9 $ hg add foo
10 $ hg ci -m '0: add foo'
10 $ hg ci -m '0: add foo'
11
11
12 $ echo line2 >> foo
12 $ echo line2 >> foo
13 $ hg ci -m '1: change foo'
13 $ hg ci -m '1: change foo'
14
14
15 $ hg up -C 0
15 $ hg up -C 0
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17
17
18 $ hg mv foo bar
18 $ hg mv foo bar
19 $ rm bar
19 $ rm bar
20 $ echo line0 > bar
20 $ echo line0 > bar
21 $ echo line1 >> bar
21 $ echo line1 >> bar
22 $ hg ci -m '2: mv foo bar; change bar'
22 $ hg ci -m '2: mv foo bar; change bar'
23 created new head
23 created new head
24
24
25 $ hg merge 1
25 $ hg merge 1
26 merging bar and foo to bar
26 merging bar and foo to bar
27 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
27 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
28 (branch merge, don't forget to commit)
28 (branch merge, don't forget to commit)
29
29
30 $ cat bar
30 $ cat bar
31 line0
31 line0
32 line1
32 line1
33 line2
33 line2
34
34
35 $ hg ci -m '3: merge with local rename'
35 $ hg ci -m '3: merge with local rename'
36
36
37 $ hg debugindex bar
37 $ hg debugindex bar
38 rev offset length linkrev nodeid p1 p2
38 rev linkrev nodeid p1 p2
39 0 0 77 2 d35118874825 000000000000 000000000000
39 0 2 d35118874825 000000000000 000000000000
40 1 77 76 3 5345f5ab8abd 000000000000 d35118874825
40 1 3 5345f5ab8abd 000000000000 d35118874825
41
41
42 $ hg debugrename bar
42 $ hg debugrename bar
43 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
43 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
44
44
45 $ hg debugindex foo
45 $ hg debugindex foo
46 rev offset length linkrev nodeid p1 p2
46 rev linkrev nodeid p1 p2
47 0 0 7 0 690b295714ae 000000000000 000000000000
47 0 0 690b295714ae 000000000000 000000000000
48 1 7 13 1 9e25c27b8757 690b295714ae 000000000000
48 1 1 9e25c27b8757 690b295714ae 000000000000
49
49
50
50
51 Revert the content change from rev 2:
51 Revert the content change from rev 2:
52
52
53 $ hg up -C 2
53 $ hg up -C 2
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ rm bar
55 $ rm bar
56 $ echo line1 > bar
56 $ echo line1 > bar
57 $ hg ci -m '4: revert content change from rev 2'
57 $ hg ci -m '4: revert content change from rev 2'
58 created new head
58 created new head
59
59
60 $ hg log --template '{rev}:{node|short} {parents}\n'
60 $ hg log --template '{rev}:{node|short} {parents}\n'
61 4:2263c1be0967 2:0f2ff26688b9
61 4:2263c1be0967 2:0f2ff26688b9
62 3:0555950ead28 2:0f2ff26688b9 1:5cd961e4045d
62 3:0555950ead28 2:0f2ff26688b9 1:5cd961e4045d
63 2:0f2ff26688b9 0:2665aaee66e9
63 2:0f2ff26688b9 0:2665aaee66e9
64 1:5cd961e4045d
64 1:5cd961e4045d
65 0:2665aaee66e9
65 0:2665aaee66e9
66
66
67 This should use bar@rev2 as the ancestor:
67 This should use bar@rev2 as the ancestor:
68
68
69 $ hg --debug merge 3
69 $ hg --debug merge 3
70 searching for copies back to rev 1
70 searching for copies back to rev 1
71 resolving manifests
71 resolving manifests
72 branchmerge: True, force: False, partial: False
72 branchmerge: True, force: False, partial: False
73 ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 0555950ead28
73 ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 0555950ead28
74 preserving bar for resolve of bar
74 preserving bar for resolve of bar
75 starting 4 threads for background file closing (?)
75 starting 4 threads for background file closing (?)
76 bar: versions differ -> m (premerge)
76 bar: versions differ -> m (premerge)
77 picked tool ':merge' for bar (binary False symlink False changedelete False)
77 picked tool ':merge' for bar (binary False symlink False changedelete False)
78 merging bar
78 merging bar
79 my bar@2263c1be0967+ other bar@0555950ead28 ancestor bar@0f2ff26688b9
79 my bar@2263c1be0967+ other bar@0555950ead28 ancestor bar@0f2ff26688b9
80 premerge successful
80 premerge successful
81 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
81 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
82 (branch merge, don't forget to commit)
82 (branch merge, don't forget to commit)
83
83
84 $ cat bar
84 $ cat bar
85 line1
85 line1
86 line2
86 line2
87
87
88 $ hg ci -m '5: merge'
88 $ hg ci -m '5: merge'
89
89
90 $ hg debugindex bar
90 $ hg debugindex bar
91 rev offset length linkrev nodeid p1 p2
91 rev linkrev nodeid p1 p2
92 0 0 77 2 d35118874825 000000000000 000000000000
92 0 2 d35118874825 000000000000 000000000000
93 1 77 76 3 5345f5ab8abd 000000000000 d35118874825
93 1 3 5345f5ab8abd 000000000000 d35118874825
94 2 153 7 4 ff4b45017382 d35118874825 000000000000
94 2 4 ff4b45017382 d35118874825 000000000000
95 3 160 13 5 3701b4893544 ff4b45017382 5345f5ab8abd
95 3 5 3701b4893544 ff4b45017382 5345f5ab8abd
96
96
97
97
98 Same thing, but with the merge on 3 having the rename
98 Same thing, but with the merge on 3 having the rename
99 on the remote parent:
99 on the remote parent:
100
100
101 $ cd ..
101 $ cd ..
102 $ hg clone -U -r 1 -r 2 a b
102 $ hg clone -U -r 1 -r 2 a b
103 adding changesets
103 adding changesets
104 adding manifests
104 adding manifests
105 adding file changes
105 adding file changes
106 added 3 changesets with 3 changes to 2 files (+1 heads)
106 added 3 changesets with 3 changes to 2 files (+1 heads)
107 new changesets 2665aaee66e9:0f2ff26688b9
107 new changesets 2665aaee66e9:0f2ff26688b9
108 $ cd b
108 $ cd b
109
109
110 $ hg up -C 1
110 $ hg up -C 1
111 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
112
112
113 $ hg merge 2
113 $ hg merge 2
114 merging foo and bar to bar
114 merging foo and bar to bar
115 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
115 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
116 (branch merge, don't forget to commit)
116 (branch merge, don't forget to commit)
117
117
118 $ cat bar
118 $ cat bar
119 line0
119 line0
120 line1
120 line1
121 line2
121 line2
122
122
123 $ hg ci -m '3: merge with remote rename'
123 $ hg ci -m '3: merge with remote rename'
124
124
125 $ hg debugindex bar
125 $ hg debugindex bar
126 rev offset length linkrev nodeid p1 p2
126 rev linkrev nodeid p1 p2
127 0 0 77 2 d35118874825 000000000000 000000000000
127 0 2 d35118874825 000000000000 000000000000
128 1 77 76 3 5345f5ab8abd 000000000000 d35118874825
128 1 3 5345f5ab8abd 000000000000 d35118874825
129
129
130 $ hg debugrename bar
130 $ hg debugrename bar
131 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
131 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
132
132
133 $ hg debugindex foo
133 $ hg debugindex foo
134 rev offset length linkrev nodeid p1 p2
134 rev linkrev nodeid p1 p2
135 0 0 7 0 690b295714ae 000000000000 000000000000
135 0 0 690b295714ae 000000000000 000000000000
136 1 7 13 1 9e25c27b8757 690b295714ae 000000000000
136 1 1 9e25c27b8757 690b295714ae 000000000000
137
137
138
138
139 Revert the content change from rev 2:
139 Revert the content change from rev 2:
140
140
141 $ hg up -C 2
141 $ hg up -C 2
142 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
143 $ rm bar
143 $ rm bar
144 $ echo line1 > bar
144 $ echo line1 > bar
145 $ hg ci -m '4: revert content change from rev 2'
145 $ hg ci -m '4: revert content change from rev 2'
146 created new head
146 created new head
147
147
148 $ hg log --template '{rev}:{node|short} {parents}\n'
148 $ hg log --template '{rev}:{node|short} {parents}\n'
149 4:2263c1be0967 2:0f2ff26688b9
149 4:2263c1be0967 2:0f2ff26688b9
150 3:3ffa6b9e35f0 1:5cd961e4045d 2:0f2ff26688b9
150 3:3ffa6b9e35f0 1:5cd961e4045d 2:0f2ff26688b9
151 2:0f2ff26688b9 0:2665aaee66e9
151 2:0f2ff26688b9 0:2665aaee66e9
152 1:5cd961e4045d
152 1:5cd961e4045d
153 0:2665aaee66e9
153 0:2665aaee66e9
154
154
155 This should use bar@rev2 as the ancestor:
155 This should use bar@rev2 as the ancestor:
156
156
157 $ hg --debug merge 3
157 $ hg --debug merge 3
158 searching for copies back to rev 1
158 searching for copies back to rev 1
159 resolving manifests
159 resolving manifests
160 branchmerge: True, force: False, partial: False
160 branchmerge: True, force: False, partial: False
161 ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 3ffa6b9e35f0
161 ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 3ffa6b9e35f0
162 preserving bar for resolve of bar
162 preserving bar for resolve of bar
163 starting 4 threads for background file closing (?)
163 starting 4 threads for background file closing (?)
164 bar: versions differ -> m (premerge)
164 bar: versions differ -> m (premerge)
165 picked tool ':merge' for bar (binary False symlink False changedelete False)
165 picked tool ':merge' for bar (binary False symlink False changedelete False)
166 merging bar
166 merging bar
167 my bar@2263c1be0967+ other bar@3ffa6b9e35f0 ancestor bar@0f2ff26688b9
167 my bar@2263c1be0967+ other bar@3ffa6b9e35f0 ancestor bar@0f2ff26688b9
168 premerge successful
168 premerge successful
169 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
169 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
170 (branch merge, don't forget to commit)
170 (branch merge, don't forget to commit)
171
171
172 $ cat bar
172 $ cat bar
173 line1
173 line1
174 line2
174 line2
175
175
176 $ hg ci -m '5: merge'
176 $ hg ci -m '5: merge'
177
177
178 $ hg debugindex bar
178 $ hg debugindex bar
179 rev offset length linkrev nodeid p1 p2
179 rev linkrev nodeid p1 p2
180 0 0 77 2 d35118874825 000000000000 000000000000
180 0 2 d35118874825 000000000000 000000000000
181 1 77 76 3 5345f5ab8abd 000000000000 d35118874825
181 1 3 5345f5ab8abd 000000000000 d35118874825
182 2 153 7 4 ff4b45017382 d35118874825 000000000000
182 2 4 ff4b45017382 d35118874825 000000000000
183 3 160 13 5 3701b4893544 ff4b45017382 5345f5ab8abd
183 3 5 3701b4893544 ff4b45017382 5345f5ab8abd
184
184
185 $ cd ..
185 $ cd ..
@@ -1,151 +1,151 b''
1 initial
1 initial
2 $ hg init test-a
2 $ hg init test-a
3 $ cd test-a
3 $ cd test-a
4 $ cat >test.txt <<"EOF"
4 $ cat >test.txt <<"EOF"
5 > 1
5 > 1
6 > 2
6 > 2
7 > 3
7 > 3
8 > EOF
8 > EOF
9 $ hg add test.txt
9 $ hg add test.txt
10 $ hg commit -m "Initial"
10 $ hg commit -m "Initial"
11
11
12 clone
12 clone
13 $ cd ..
13 $ cd ..
14 $ hg clone test-a test-b
14 $ hg clone test-a test-b
15 updating to branch default
15 updating to branch default
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17
17
18 change test-a
18 change test-a
19 $ cd test-a
19 $ cd test-a
20 $ cat >test.txt <<"EOF"
20 $ cat >test.txt <<"EOF"
21 > one
21 > one
22 > two
22 > two
23 > three
23 > three
24 > EOF
24 > EOF
25 $ hg commit -m "Numbers as words"
25 $ hg commit -m "Numbers as words"
26
26
27 change test-b
27 change test-b
28 $ cd ../test-b
28 $ cd ../test-b
29 $ cat >test.txt <<"EOF"
29 $ cat >test.txt <<"EOF"
30 > 1
30 > 1
31 > 2.5
31 > 2.5
32 > 3
32 > 3
33 > EOF
33 > EOF
34 $ hg commit -m "2 -> 2.5"
34 $ hg commit -m "2 -> 2.5"
35
35
36 now pull and merge from test-a
36 now pull and merge from test-a
37 $ hg pull ../test-a
37 $ hg pull ../test-a
38 pulling from ../test-a
38 pulling from ../test-a
39 searching for changes
39 searching for changes
40 adding changesets
40 adding changesets
41 adding manifests
41 adding manifests
42 adding file changes
42 adding file changes
43 added 1 changesets with 1 changes to 1 files (+1 heads)
43 added 1 changesets with 1 changes to 1 files (+1 heads)
44 new changesets 96b70246a118
44 new changesets 96b70246a118
45 (run 'hg heads' to see heads, 'hg merge' to merge)
45 (run 'hg heads' to see heads, 'hg merge' to merge)
46 $ hg merge
46 $ hg merge
47 merging test.txt
47 merging test.txt
48 warning: conflicts while merging test.txt! (edit, then use 'hg resolve --mark')
48 warning: conflicts while merging test.txt! (edit, then use 'hg resolve --mark')
49 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
49 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
50 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
50 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
51 [1]
51 [1]
52 resolve conflict
52 resolve conflict
53 $ cat >test.txt <<"EOF"
53 $ cat >test.txt <<"EOF"
54 > one
54 > one
55 > two-point-five
55 > two-point-five
56 > three
56 > three
57 > EOF
57 > EOF
58 $ rm -f *.orig
58 $ rm -f *.orig
59 $ hg resolve -m test.txt
59 $ hg resolve -m test.txt
60 (no more unresolved files)
60 (no more unresolved files)
61 $ hg commit -m "Merge 1"
61 $ hg commit -m "Merge 1"
62
62
63 change test-a again
63 change test-a again
64 $ cd ../test-a
64 $ cd ../test-a
65 $ cat >test.txt <<"EOF"
65 $ cat >test.txt <<"EOF"
66 > one
66 > one
67 > two-point-one
67 > two-point-one
68 > three
68 > three
69 > EOF
69 > EOF
70 $ hg commit -m "two -> two-point-one"
70 $ hg commit -m "two -> two-point-one"
71
71
72 pull and merge from test-a again
72 pull and merge from test-a again
73 $ cd ../test-b
73 $ cd ../test-b
74 $ hg pull ../test-a
74 $ hg pull ../test-a
75 pulling from ../test-a
75 pulling from ../test-a
76 searching for changes
76 searching for changes
77 adding changesets
77 adding changesets
78 adding manifests
78 adding manifests
79 adding file changes
79 adding file changes
80 added 1 changesets with 1 changes to 1 files (+1 heads)
80 added 1 changesets with 1 changes to 1 files (+1 heads)
81 new changesets 40d11a4173a8
81 new changesets 40d11a4173a8
82 (run 'hg heads' to see heads, 'hg merge' to merge)
82 (run 'hg heads' to see heads, 'hg merge' to merge)
83 $ hg merge --debug
83 $ hg merge --debug
84 searching for copies back to rev 1
84 searching for copies back to rev 1
85 resolving manifests
85 resolving manifests
86 branchmerge: True, force: False, partial: False
86 branchmerge: True, force: False, partial: False
87 ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
87 ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
88 preserving test.txt for resolve of test.txt
88 preserving test.txt for resolve of test.txt
89 starting 4 threads for background file closing (?)
89 starting 4 threads for background file closing (?)
90 test.txt: versions differ -> m (premerge)
90 test.txt: versions differ -> m (premerge)
91 picked tool ':merge' for test.txt (binary False symlink False changedelete False)
91 picked tool ':merge' for test.txt (binary False symlink False changedelete False)
92 merging test.txt
92 merging test.txt
93 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
93 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
94 test.txt: versions differ -> m (merge)
94 test.txt: versions differ -> m (merge)
95 picked tool ':merge' for test.txt (binary False symlink False changedelete False)
95 picked tool ':merge' for test.txt (binary False symlink False changedelete False)
96 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
96 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
97 warning: conflicts while merging test.txt! (edit, then use 'hg resolve --mark')
97 warning: conflicts while merging test.txt! (edit, then use 'hg resolve --mark')
98 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
98 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
99 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
99 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
100 [1]
100 [1]
101
101
102 $ cat test.txt
102 $ cat test.txt
103 one
103 one
104 <<<<<<< working copy: 50c3a7e29886 - test: Merge 1
104 <<<<<<< working copy: 50c3a7e29886 - test: Merge 1
105 two-point-five
105 two-point-five
106 =======
106 =======
107 two-point-one
107 two-point-one
108 >>>>>>> merge rev: 40d11a4173a8 - test: two -> two-point-one
108 >>>>>>> merge rev: 40d11a4173a8 - test: two -> two-point-one
109 three
109 three
110
110
111 $ hg debugindex test.txt
111 $ hg debugindex test.txt
112 rev offset length linkrev nodeid p1 p2
112 rev linkrev nodeid p1 p2
113 0 0 7 0 01365c4cca56 000000000000 000000000000
113 0 0 01365c4cca56 000000000000 000000000000
114 1 7 9 1 7b013192566a 01365c4cca56 000000000000
114 1 1 7b013192566a 01365c4cca56 000000000000
115 2 16 15 2 8fe46a3eb557 01365c4cca56 000000000000
115 2 2 8fe46a3eb557 01365c4cca56 000000000000
116 3 31 2. 3 fc3148072371 7b013192566a 8fe46a3eb557 (re)
116 3 3 fc3148072371 7b013192566a 8fe46a3eb557
117 4 5. 25 4 d40249267ae3 8fe46a3eb557 000000000000 (re)
117 4 4 d40249267ae3 8fe46a3eb557 000000000000
118
118
119 $ hg log
119 $ hg log
120 changeset: 4:40d11a4173a8
120 changeset: 4:40d11a4173a8
121 tag: tip
121 tag: tip
122 parent: 2:96b70246a118
122 parent: 2:96b70246a118
123 user: test
123 user: test
124 date: Thu Jan 01 00:00:00 1970 +0000
124 date: Thu Jan 01 00:00:00 1970 +0000
125 summary: two -> two-point-one
125 summary: two -> two-point-one
126
126
127 changeset: 3:50c3a7e29886
127 changeset: 3:50c3a7e29886
128 parent: 1:d1e159716d41
128 parent: 1:d1e159716d41
129 parent: 2:96b70246a118
129 parent: 2:96b70246a118
130 user: test
130 user: test
131 date: Thu Jan 01 00:00:00 1970 +0000
131 date: Thu Jan 01 00:00:00 1970 +0000
132 summary: Merge 1
132 summary: Merge 1
133
133
134 changeset: 2:96b70246a118
134 changeset: 2:96b70246a118
135 parent: 0:b1832b9d912a
135 parent: 0:b1832b9d912a
136 user: test
136 user: test
137 date: Thu Jan 01 00:00:00 1970 +0000
137 date: Thu Jan 01 00:00:00 1970 +0000
138 summary: Numbers as words
138 summary: Numbers as words
139
139
140 changeset: 1:d1e159716d41
140 changeset: 1:d1e159716d41
141 user: test
141 user: test
142 date: Thu Jan 01 00:00:00 1970 +0000
142 date: Thu Jan 01 00:00:00 1970 +0000
143 summary: 2 -> 2.5
143 summary: 2 -> 2.5
144
144
145 changeset: 0:b1832b9d912a
145 changeset: 0:b1832b9d912a
146 user: test
146 user: test
147 date: Thu Jan 01 00:00:00 1970 +0000
147 date: Thu Jan 01 00:00:00 1970 +0000
148 summary: Initial
148 summary: Initial
149
149
150
150
151 $ cd ..
151 $ cd ..
@@ -1,43 +1,43 b''
1 $ . "$TESTDIR/narrow-library.sh"
1 $ . "$TESTDIR/narrow-library.sh"
2 $ hg init repo
2 $ hg init repo
3 $ cd repo
3 $ cd repo
4 $ cat << EOF > .hg/narrowspec
4 $ cat << EOF > .hg/narrowspec
5 > [includes]
5 > [includes]
6 > path:foo
6 > path:foo
7 > [excludes]
7 > [excludes]
8 > EOF
8 > EOF
9 $ echo treemanifest >> .hg/requires
9 $ echo treemanifest >> .hg/requires
10 $ echo narrowhg-experimental >> .hg/requires
10 $ echo narrowhg-experimental >> .hg/requires
11 $ mkdir -p foo/bar
11 $ mkdir -p foo/bar
12 $ echo b > foo/f
12 $ echo b > foo/f
13 $ echo c > foo/bar/f
13 $ echo c > foo/bar/f
14 $ hg commit -Am hi
14 $ hg commit -Am hi
15 adding foo/bar/f
15 adding foo/bar/f
16 adding foo/f
16 adding foo/f
17 $ hg debugindex -m
17 $ hg debugindex -m
18 rev offset length linkrev nodeid p1 p2
18 rev linkrev nodeid p1 p2
19 0 0 47 0 14a5d056d75a 000000000000 000000000000
19 0 0 14a5d056d75a 000000000000 000000000000
20 $ hg debugindex --dir foo
20 $ hg debugindex --dir foo
21 rev offset length linkrev nodeid p1 p2
21 rev linkrev nodeid p1 p2
22 0 0 77 0 e635c7857aef 000000000000 000000000000
22 0 0 e635c7857aef 000000000000 000000000000
23 $ hg debugindex --dir foo/
23 $ hg debugindex --dir foo/
24 rev offset length linkrev nodeid p1 p2
24 rev linkrev nodeid p1 p2
25 0 0 77 0 e635c7857aef 000000000000 000000000000
25 0 0 e635c7857aef 000000000000 000000000000
26 $ hg debugindex --dir foo/bar
26 $ hg debugindex --dir foo/bar
27 rev offset length linkrev nodeid p1 p2
27 rev linkrev nodeid p1 p2
28 0 0 44 0 e091d4224761 000000000000 000000000000
28 0 0 e091d4224761 000000000000 000000000000
29 $ hg debugindex --dir foo/bar/
29 $ hg debugindex --dir foo/bar/
30 rev offset length linkrev nodeid p1 p2
30 rev linkrev nodeid p1 p2
31 0 0 44 0 e091d4224761 000000000000 000000000000
31 0 0 e091d4224761 000000000000 000000000000
32 $ hg debugdata -m 0
32 $ hg debugdata -m 0
33 foo\x00e635c7857aef92ac761ce5741a99da159abbbb24t (esc)
33 foo\x00e635c7857aef92ac761ce5741a99da159abbbb24t (esc)
34 $ hg debugdata --dir foo 0
34 $ hg debugdata --dir foo 0
35 bar\x00e091d42247613adff5d41b67f15fe7189ee97b39t (esc)
35 bar\x00e091d42247613adff5d41b67f15fe7189ee97b39t (esc)
36 f\x001e88685f5ddec574a34c70af492f95b6debc8741 (esc)
36 f\x001e88685f5ddec574a34c70af492f95b6debc8741 (esc)
37 $ hg debugdata --dir foo/ 0
37 $ hg debugdata --dir foo/ 0
38 bar\x00e091d42247613adff5d41b67f15fe7189ee97b39t (esc)
38 bar\x00e091d42247613adff5d41b67f15fe7189ee97b39t (esc)
39 f\x001e88685f5ddec574a34c70af492f95b6debc8741 (esc)
39 f\x001e88685f5ddec574a34c70af492f95b6debc8741 (esc)
40 $ hg debugdata --dir foo/bar 0
40 $ hg debugdata --dir foo/bar 0
41 f\x00149da44f2a4e14f488b7bd4157945a9837408c00 (esc)
41 f\x00149da44f2a4e14f488b7bd4157945a9837408c00 (esc)
42 $ hg debugdata --dir foo/bar/ 0
42 $ hg debugdata --dir foo/bar/ 0
43 f\x00149da44f2a4e14f488b7bd4157945a9837408c00 (esc)
43 f\x00149da44f2a4e14f488b7bd4157945a9837408c00 (esc)
@@ -1,76 +1,76 b''
1
1
2 $ . "$TESTDIR/narrow-library.sh"
2 $ . "$TESTDIR/narrow-library.sh"
3
3
4 create full repo
4 create full repo
5
5
6 $ hg init master
6 $ hg init master
7 $ cd master
7 $ cd master
8 $ echo init > init
8 $ echo init > init
9 $ hg ci -Aqm 'initial'
9 $ hg ci -Aqm 'initial'
10
10
11 $ mkdir inside
11 $ mkdir inside
12 $ echo inside > inside/f1
12 $ echo inside > inside/f1
13 $ mkdir outside
13 $ mkdir outside
14 $ echo outside > outside/f1
14 $ echo outside > outside/f1
15 $ hg ci -Aqm 'add inside and outside'
15 $ hg ci -Aqm 'add inside and outside'
16
16
17 $ echo modified > inside/f1
17 $ echo modified > inside/f1
18 $ hg ci -qm 'modify inside'
18 $ hg ci -qm 'modify inside'
19
19
20 $ echo modified > outside/f1
20 $ echo modified > outside/f1
21 $ hg ci -qm 'modify outside'
21 $ hg ci -qm 'modify outside'
22
22
23 $ cd ..
23 $ cd ..
24
24
25 $ hg clone --narrow ssh://user@dummy/master narrow --include inside
25 $ hg clone --narrow ssh://user@dummy/master narrow --include inside
26 requesting all changes
26 requesting all changes
27 adding changesets
27 adding changesets
28 adding manifests
28 adding manifests
29 adding file changes
29 adding file changes
30 added 4 changesets with 2 changes to 1 files
30 added 4 changesets with 2 changes to 1 files
31 new changesets *:* (glob)
31 new changesets *:* (glob)
32 updating to branch default
32 updating to branch default
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 $ cd narrow
34 $ cd narrow
35 $ hg debugindex -c
35 $ hg debugindex -c
36 rev offset length linkrev nodeid p1 p2
36 rev linkrev nodeid p1 p2
37 0 0 64 0 9958b1af2add 000000000000 000000000000
37 0 0 9958b1af2add 000000000000 000000000000
38 1 64 81 1 2db4ce2a3bfe 9958b1af2add 000000000000
38 1 1 2db4ce2a3bfe 9958b1af2add 000000000000
39 2 145 75 2 0980ee31a742 2db4ce2a3bfe 000000000000
39 2 2 0980ee31a742 2db4ce2a3bfe 000000000000
40 3 220 (76|77) 3 4410145019b7 0980ee31a742 000000000000 (re)
40 3 3 4410145019b7 0980ee31a742 000000000000
41
41
42 $ hg update -q 0
42 $ hg update -q 0
43
43
44 Can update to revision with changes inside
44 Can update to revision with changes inside
45
45
46 $ hg update -q 'desc("add inside and outside")'
46 $ hg update -q 'desc("add inside and outside")'
47 $ hg update -q 'desc("modify inside")'
47 $ hg update -q 'desc("modify inside")'
48 $ find *
48 $ find *
49 inside
49 inside
50 inside/f1
50 inside/f1
51 $ cat inside/f1
51 $ cat inside/f1
52 modified
52 modified
53
53
54 Can update to revision with changes outside
54 Can update to revision with changes outside
55
55
56 $ hg update -q 'desc("modify outside")'
56 $ hg update -q 'desc("modify outside")'
57 $ find *
57 $ find *
58 inside
58 inside
59 inside/f1
59 inside/f1
60 $ cat inside/f1
60 $ cat inside/f1
61 modified
61 modified
62
62
63 Can update with a deleted file inside
63 Can update with a deleted file inside
64
64
65 $ hg rm inside/f1
65 $ hg rm inside/f1
66 $ hg update -q 'desc("modify inside")'
66 $ hg update -q 'desc("modify inside")'
67 $ hg update -q 'desc("modify outside")'
67 $ hg update -q 'desc("modify outside")'
68 $ hg update -q 'desc("initial")'
68 $ hg update -q 'desc("initial")'
69 $ hg update -q 'desc("modify inside")'
69 $ hg update -q 'desc("modify inside")'
70
70
71 Can update with a moved file inside
71 Can update with a moved file inside
72
72
73 $ hg mv inside/f1 inside/f2
73 $ hg mv inside/f1 inside/f2
74 $ hg update -q 'desc("modify outside")'
74 $ hg update -q 'desc("modify outside")'
75 $ hg update -q 'desc("initial")'
75 $ hg update -q 'desc("initial")'
76 $ hg update -q 'desc("modify inside")'
76 $ hg update -q 'desc("modify inside")'
@@ -1,203 +1,203 b''
1 revlog.parseindex must be able to parse the index file even if
1 revlog.parseindex must be able to parse the index file even if
2 an index entry is split between two 64k blocks. The ideal test
2 an index entry is split between two 64k blocks. The ideal test
3 would be to create an index file with inline data where
3 would be to create an index file with inline data where
4 64k < size < 64k + 64 (64k is the size of the read buffer, 64 is
4 64k < size < 64k + 64 (64k is the size of the read buffer, 64 is
5 the size of an index entry) and with an index entry starting right
5 the size of an index entry) and with an index entry starting right
6 before the 64k block boundary, and try to read it.
6 before the 64k block boundary, and try to read it.
7 We approximate that by reducing the read buffer to 1 byte.
7 We approximate that by reducing the read buffer to 1 byte.
8
8
9 $ hg init a
9 $ hg init a
10 $ cd a
10 $ cd a
11 $ echo abc > foo
11 $ echo abc > foo
12 $ hg add foo
12 $ hg add foo
13 $ hg commit -m 'add foo'
13 $ hg commit -m 'add foo'
14 $ echo >> foo
14 $ echo >> foo
15 $ hg commit -m 'change foo'
15 $ hg commit -m 'change foo'
16 $ hg log -r 0:
16 $ hg log -r 0:
17 changeset: 0:7c31755bf9b5
17 changeset: 0:7c31755bf9b5
18 user: test
18 user: test
19 date: Thu Jan 01 00:00:00 1970 +0000
19 date: Thu Jan 01 00:00:00 1970 +0000
20 summary: add foo
20 summary: add foo
21
21
22 changeset: 1:26333235a41c
22 changeset: 1:26333235a41c
23 tag: tip
23 tag: tip
24 user: test
24 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
25 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: change foo
26 summary: change foo
27
27
28 $ cat >> test.py << EOF
28 $ cat >> test.py << EOF
29 > from mercurial import changelog, vfs
29 > from mercurial import changelog, vfs
30 > from mercurial.node import *
30 > from mercurial.node import *
31 >
31 >
32 > class singlebyteread(object):
32 > class singlebyteread(object):
33 > def __init__(self, real):
33 > def __init__(self, real):
34 > self.real = real
34 > self.real = real
35 >
35 >
36 > def read(self, size=-1):
36 > def read(self, size=-1):
37 > if size == 65536:
37 > if size == 65536:
38 > size = 1
38 > size = 1
39 > return self.real.read(size)
39 > return self.real.read(size)
40 >
40 >
41 > def __getattr__(self, key):
41 > def __getattr__(self, key):
42 > return getattr(self.real, key)
42 > return getattr(self.real, key)
43 >
43 >
44 > def __enter__(self):
44 > def __enter__(self):
45 > self.real.__enter__()
45 > self.real.__enter__()
46 > return self
46 > return self
47 >
47 >
48 > def __exit__(self, *args, **kwargs):
48 > def __exit__(self, *args, **kwargs):
49 > return self.real.__exit__(*args, **kwargs)
49 > return self.real.__exit__(*args, **kwargs)
50 >
50 >
51 > def opener(*args):
51 > def opener(*args):
52 > o = vfs.vfs(*args)
52 > o = vfs.vfs(*args)
53 > def wrapper(*a, **kwargs):
53 > def wrapper(*a, **kwargs):
54 > f = o(*a, **kwargs)
54 > f = o(*a, **kwargs)
55 > return singlebyteread(f)
55 > return singlebyteread(f)
56 > return wrapper
56 > return wrapper
57 >
57 >
58 > cl = changelog.changelog(opener('.hg/store'))
58 > cl = changelog.changelog(opener('.hg/store'))
59 > print len(cl), 'revisions:'
59 > print len(cl), 'revisions:'
60 > for r in cl:
60 > for r in cl:
61 > print short(cl.node(r))
61 > print short(cl.node(r))
62 > EOF
62 > EOF
63 $ $PYTHON test.py
63 $ $PYTHON test.py
64 2 revisions:
64 2 revisions:
65 7c31755bf9b5
65 7c31755bf9b5
66 26333235a41c
66 26333235a41c
67
67
68 $ cd ..
68 $ cd ..
69
69
70 #if no-pure
70 #if no-pure
71
71
72 Test SEGV caused by bad revision passed to reachableroots() (issue4775):
72 Test SEGV caused by bad revision passed to reachableroots() (issue4775):
73
73
74 $ cd a
74 $ cd a
75
75
76 $ $PYTHON <<EOF
76 $ $PYTHON <<EOF
77 > from mercurial import changelog, vfs
77 > from mercurial import changelog, vfs
78 > cl = changelog.changelog(vfs.vfs('.hg/store'))
78 > cl = changelog.changelog(vfs.vfs('.hg/store'))
79 > print 'good heads:'
79 > print 'good heads:'
80 > for head in [0, len(cl) - 1, -1]:
80 > for head in [0, len(cl) - 1, -1]:
81 > print'%s: %r' % (head, cl.reachableroots(0, [head], [0]))
81 > print'%s: %r' % (head, cl.reachableroots(0, [head], [0]))
82 > print 'bad heads:'
82 > print 'bad heads:'
83 > for head in [len(cl), 10000, -2, -10000, None]:
83 > for head in [len(cl), 10000, -2, -10000, None]:
84 > print '%s:' % head,
84 > print '%s:' % head,
85 > try:
85 > try:
86 > cl.reachableroots(0, [head], [0])
86 > cl.reachableroots(0, [head], [0])
87 > print 'uncaught buffer overflow?'
87 > print 'uncaught buffer overflow?'
88 > except (IndexError, TypeError) as inst:
88 > except (IndexError, TypeError) as inst:
89 > print inst
89 > print inst
90 > print 'good roots:'
90 > print 'good roots:'
91 > for root in [0, len(cl) - 1, -1]:
91 > for root in [0, len(cl) - 1, -1]:
92 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
92 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
93 > print 'out-of-range roots are ignored:'
93 > print 'out-of-range roots are ignored:'
94 > for root in [len(cl), 10000, -2, -10000]:
94 > for root in [len(cl), 10000, -2, -10000]:
95 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
95 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
96 > print 'bad roots:'
96 > print 'bad roots:'
97 > for root in [None]:
97 > for root in [None]:
98 > print '%s:' % root,
98 > print '%s:' % root,
99 > try:
99 > try:
100 > cl.reachableroots(root, [len(cl) - 1], [root])
100 > cl.reachableroots(root, [len(cl) - 1], [root])
101 > print 'uncaught error?'
101 > print 'uncaught error?'
102 > except TypeError as inst:
102 > except TypeError as inst:
103 > print inst
103 > print inst
104 > EOF
104 > EOF
105 good heads:
105 good heads:
106 0: [0]
106 0: [0]
107 1: [0]
107 1: [0]
108 -1: []
108 -1: []
109 bad heads:
109 bad heads:
110 2: head out of range
110 2: head out of range
111 10000: head out of range
111 10000: head out of range
112 -2: head out of range
112 -2: head out of range
113 -10000: head out of range
113 -10000: head out of range
114 None: an integer is required
114 None: an integer is required
115 good roots:
115 good roots:
116 0: [0]
116 0: [0]
117 1: [1]
117 1: [1]
118 -1: [-1]
118 -1: [-1]
119 out-of-range roots are ignored:
119 out-of-range roots are ignored:
120 2: []
120 2: []
121 10000: []
121 10000: []
122 -2: []
122 -2: []
123 -10000: []
123 -10000: []
124 bad roots:
124 bad roots:
125 None: an integer is required
125 None: an integer is required
126
126
127 $ cd ..
127 $ cd ..
128
128
129 Test corrupted p1/p2 fields that could cause SEGV at parsers.c:
129 Test corrupted p1/p2 fields that could cause SEGV at parsers.c:
130
130
131 $ mkdir invalidparent
131 $ mkdir invalidparent
132 $ cd invalidparent
132 $ cd invalidparent
133
133
134 $ hg clone --pull -q --config phases.publish=False ../a limit
134 $ hg clone --pull -q --config phases.publish=False ../a limit
135 $ hg clone --pull -q --config phases.publish=False ../a segv
135 $ hg clone --pull -q --config phases.publish=False ../a segv
136 $ rm -R limit/.hg/cache segv/.hg/cache
136 $ rm -R limit/.hg/cache segv/.hg/cache
137
137
138 $ $PYTHON <<EOF
138 $ $PYTHON <<EOF
139 > data = open("limit/.hg/store/00changelog.i", "rb").read()
139 > data = open("limit/.hg/store/00changelog.i", "rb").read()
140 > for n, p in [('limit', '\0\0\0\x02'), ('segv', '\0\x01\0\0')]:
140 > for n, p in [('limit', '\0\0\0\x02'), ('segv', '\0\x01\0\0')]:
141 > # corrupt p1 at rev0 and p2 at rev1
141 > # corrupt p1 at rev0 and p2 at rev1
142 > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:]
142 > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:]
143 > open(n + "/.hg/store/00changelog.i", "wb").write(d)
143 > open(n + "/.hg/store/00changelog.i", "wb").write(d)
144 > EOF
144 > EOF
145
145
146 $ hg -R limit debugindex -f1 -c
146 $ hg -R limit debugindex -f1 -c
147 rev flag offset length size link p1 p2 nodeid
147 rev flag size link p1 p2 nodeid
148 0 0000 0 63 62 0 2 -1 7c31755bf9b5
148 0 0000 62 0 2 -1 7c31755bf9b5
149 1 0000 63 66 65 1 0 2 26333235a41c
149 1 0000 65 1 0 2 26333235a41c
150
150
151 $ hg -R limit debugdeltachain -c
151 $ hg -R limit debugdeltachain -c
152 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
152 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
153 0 1 1 -1 base 63 62 63 1.01613 63 0 0.00000
153 0 1 1 -1 base 63 62 63 1.01613 63 0 0.00000
154 1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000
154 1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000
155
155
156 $ hg -R segv debugindex -f1 -c
156 $ hg -R segv debugindex -f1 -c
157 rev flag offset length size link p1 p2 nodeid
157 rev flag size link p1 p2 nodeid
158 0 0000 0 63 62 0 65536 -1 7c31755bf9b5
158 0 0000 62 0 65536 -1 7c31755bf9b5
159 1 0000 63 66 65 1 0 65536 26333235a41c
159 1 0000 65 1 0 65536 26333235a41c
160
160
161 $ hg -R segv debugdeltachain -c
161 $ hg -R segv debugdeltachain -c
162 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
162 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
163 0 1 1 -1 base 63 62 63 1.01613 63 0 0.00000
163 0 1 1 -1 base 63 62 63 1.01613 63 0 0.00000
164 1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000
164 1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000
165
165
166 $ cat <<EOF > test.py
166 $ cat <<EOF > test.py
167 > import sys
167 > import sys
168 > from mercurial import changelog, vfs
168 > from mercurial import changelog, vfs
169 > cl = changelog.changelog(vfs.vfs(sys.argv[1]))
169 > cl = changelog.changelog(vfs.vfs(sys.argv[1]))
170 > n0, n1 = cl.node(0), cl.node(1)
170 > n0, n1 = cl.node(0), cl.node(1)
171 > ops = [
171 > ops = [
172 > ('reachableroots',
172 > ('reachableroots',
173 > lambda: cl.index.reachableroots2(0, [1], [0], False)),
173 > lambda: cl.index.reachableroots2(0, [1], [0], False)),
174 > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
174 > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
175 > ('index_headrevs', lambda: cl.headrevs()),
175 > ('index_headrevs', lambda: cl.headrevs()),
176 > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
176 > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
177 > ('find_deepest', lambda: cl.ancestor(n0, n1)),
177 > ('find_deepest', lambda: cl.ancestor(n0, n1)),
178 > ]
178 > ]
179 > for l, f in ops:
179 > for l, f in ops:
180 > print l + ':',
180 > print l + ':',
181 > try:
181 > try:
182 > f()
182 > f()
183 > print 'uncaught buffer overflow?'
183 > print 'uncaught buffer overflow?'
184 > except ValueError, inst:
184 > except ValueError, inst:
185 > print inst
185 > print inst
186 > EOF
186 > EOF
187
187
188 $ $PYTHON test.py limit/.hg/store
188 $ $PYTHON test.py limit/.hg/store
189 reachableroots: parent out of range
189 reachableroots: parent out of range
190 compute_phases_map_sets: parent out of range
190 compute_phases_map_sets: parent out of range
191 index_headrevs: parent out of range
191 index_headrevs: parent out of range
192 find_gca_candidates: parent out of range
192 find_gca_candidates: parent out of range
193 find_deepest: parent out of range
193 find_deepest: parent out of range
194 $ $PYTHON test.py segv/.hg/store
194 $ $PYTHON test.py segv/.hg/store
195 reachableroots: parent out of range
195 reachableroots: parent out of range
196 compute_phases_map_sets: parent out of range
196 compute_phases_map_sets: parent out of range
197 index_headrevs: parent out of range
197 index_headrevs: parent out of range
198 find_gca_candidates: parent out of range
198 find_gca_candidates: parent out of range
199 find_deepest: parent out of range
199 find_deepest: parent out of range
200
200
201 $ cd ..
201 $ cd ..
202
202
203 #endif
203 #endif
@@ -1,188 +1,188 b''
1 $ hg init
1 $ hg init
2
2
3 $ echo "[merge]" >> .hg/hgrc
3 $ echo "[merge]" >> .hg/hgrc
4 $ echo "followcopies = 1" >> .hg/hgrc
4 $ echo "followcopies = 1" >> .hg/hgrc
5
5
6 $ echo foo > a
6 $ echo foo > a
7 $ echo foo > a2
7 $ echo foo > a2
8 $ hg add a a2
8 $ hg add a a2
9 $ hg ci -m "start"
9 $ hg ci -m "start"
10
10
11 $ hg mv a b
11 $ hg mv a b
12 $ hg mv a2 b2
12 $ hg mv a2 b2
13 $ hg ci -m "rename"
13 $ hg ci -m "rename"
14
14
15 $ hg co 0
15 $ hg co 0
16 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
17
17
18 $ echo blahblah > a
18 $ echo blahblah > a
19 $ echo blahblah > a2
19 $ echo blahblah > a2
20 $ hg mv a2 c2
20 $ hg mv a2 c2
21 $ hg ci -m "modify"
21 $ hg ci -m "modify"
22 created new head
22 created new head
23
23
24 $ hg merge -y --debug
24 $ hg merge -y --debug
25 searching for copies back to rev 1
25 searching for copies back to rev 1
26 unmatched files in local:
26 unmatched files in local:
27 c2
27 c2
28 unmatched files in other:
28 unmatched files in other:
29 b
29 b
30 b2
30 b2
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 src: 'a' -> dst: 'b' *
32 src: 'a' -> dst: 'b' *
33 src: 'a2' -> dst: 'b2' !
33 src: 'a2' -> dst: 'b2' !
34 src: 'a2' -> dst: 'c2' !
34 src: 'a2' -> dst: 'c2' !
35 checking for directory renames
35 checking for directory renames
36 resolving manifests
36 resolving manifests
37 branchmerge: True, force: False, partial: False
37 branchmerge: True, force: False, partial: False
38 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
38 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
39 note: possible conflict - a2 was renamed multiple times to:
39 note: possible conflict - a2 was renamed multiple times to:
40 c2
40 c2
41 b2
41 b2
42 preserving a for resolve of b
42 preserving a for resolve of b
43 removing a
43 removing a
44 b2: remote created -> g
44 b2: remote created -> g
45 getting b2
45 getting b2
46 b: remote moved from a -> m (premerge)
46 b: remote moved from a -> m (premerge)
47 picked tool ':merge' for b (binary False symlink False changedelete False)
47 picked tool ':merge' for b (binary False symlink False changedelete False)
48 merging a and b to b
48 merging a and b to b
49 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
49 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
50 premerge successful
50 premerge successful
51 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
51 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
52 (branch merge, don't forget to commit)
52 (branch merge, don't forget to commit)
53
53
54 $ hg status -AC
54 $ hg status -AC
55 M b
55 M b
56 a
56 a
57 M b2
57 M b2
58 R a
58 R a
59 C c2
59 C c2
60
60
61 $ cat b
61 $ cat b
62 blahblah
62 blahblah
63
63
64 $ hg ci -m "merge"
64 $ hg ci -m "merge"
65
65
66 $ hg debugindex b
66 $ hg debugindex b
67 rev offset length linkrev nodeid p1 p2
67 rev linkrev nodeid p1 p2
68 0 0 67 1 57eacc201a7f 000000000000 000000000000
68 0 1 57eacc201a7f 000000000000 000000000000
69 1 67 72 3 4727ba907962 000000000000 57eacc201a7f
69 1 3 4727ba907962 000000000000 57eacc201a7f
70
70
71 $ hg debugrename b
71 $ hg debugrename b
72 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
72 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
73
73
74 This used to trigger a "divergent renames" warning, despite no renames
74 This used to trigger a "divergent renames" warning, despite no renames
75
75
76 $ hg cp b b3
76 $ hg cp b b3
77 $ hg cp b b4
77 $ hg cp b b4
78 $ hg ci -A -m 'copy b twice'
78 $ hg ci -A -m 'copy b twice'
79 $ hg up eb92d88a9712
79 $ hg up eb92d88a9712
80 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
80 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
81 $ hg up
81 $ hg up
82 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 $ hg rm b3 b4
83 $ hg rm b3 b4
84 $ hg ci -m 'clean up a bit of our mess'
84 $ hg ci -m 'clean up a bit of our mess'
85
85
86 We'd rather not warn on divergent renames done in the same changeset (issue2113)
86 We'd rather not warn on divergent renames done in the same changeset (issue2113)
87
87
88 $ hg cp b b3
88 $ hg cp b b3
89 $ hg mv b b4
89 $ hg mv b b4
90 $ hg ci -A -m 'divergent renames in same changeset'
90 $ hg ci -A -m 'divergent renames in same changeset'
91 $ hg up c761c6948de0
91 $ hg up c761c6948de0
92 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
92 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
93 $ hg up
93 $ hg up
94 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
94 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
95
95
96 Check for issue2642
96 Check for issue2642
97
97
98 $ hg init t
98 $ hg init t
99 $ cd t
99 $ cd t
100
100
101 $ echo c0 > f1
101 $ echo c0 > f1
102 $ hg ci -Aqm0
102 $ hg ci -Aqm0
103
103
104 $ hg up null -q
104 $ hg up null -q
105 $ echo c1 > f1 # backport
105 $ echo c1 > f1 # backport
106 $ hg ci -Aqm1
106 $ hg ci -Aqm1
107 $ hg mv f1 f2
107 $ hg mv f1 f2
108 $ hg ci -qm2
108 $ hg ci -qm2
109
109
110 $ hg up 0 -q
110 $ hg up 0 -q
111 $ hg merge 1 -q --tool internal:local
111 $ hg merge 1 -q --tool internal:local
112 $ hg ci -qm3
112 $ hg ci -qm3
113
113
114 $ hg merge 2
114 $ hg merge 2
115 merging f1 and f2 to f2
115 merging f1 and f2 to f2
116 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
116 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
117 (branch merge, don't forget to commit)
117 (branch merge, don't forget to commit)
118
118
119 $ cat f2
119 $ cat f2
120 c0
120 c0
121
121
122 $ cd ..
122 $ cd ..
123
123
124 Check for issue2089
124 Check for issue2089
125
125
126 $ hg init repo2089
126 $ hg init repo2089
127 $ cd repo2089
127 $ cd repo2089
128
128
129 $ echo c0 > f1
129 $ echo c0 > f1
130 $ hg ci -Aqm0
130 $ hg ci -Aqm0
131
131
132 $ hg up null -q
132 $ hg up null -q
133 $ echo c1 > f1
133 $ echo c1 > f1
134 $ hg ci -Aqm1
134 $ hg ci -Aqm1
135
135
136 $ hg up 0 -q
136 $ hg up 0 -q
137 $ hg merge 1 -q --tool internal:local
137 $ hg merge 1 -q --tool internal:local
138 $ echo c2 > f1
138 $ echo c2 > f1
139 $ hg ci -qm2
139 $ hg ci -qm2
140
140
141 $ hg up 1 -q
141 $ hg up 1 -q
142 $ hg mv f1 f2
142 $ hg mv f1 f2
143 $ hg ci -Aqm3
143 $ hg ci -Aqm3
144
144
145 $ hg up 2 -q
145 $ hg up 2 -q
146 $ hg merge 3
146 $ hg merge 3
147 merging f1 and f2 to f2
147 merging f1 and f2 to f2
148 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
148 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
149 (branch merge, don't forget to commit)
149 (branch merge, don't forget to commit)
150
150
151 $ cat f2
151 $ cat f2
152 c2
152 c2
153
153
154 $ cd ..
154 $ cd ..
155
155
156 Check for issue3074
156 Check for issue3074
157
157
158 $ hg init repo3074
158 $ hg init repo3074
159 $ cd repo3074
159 $ cd repo3074
160 $ echo foo > file
160 $ echo foo > file
161 $ hg add file
161 $ hg add file
162 $ hg commit -m "added file"
162 $ hg commit -m "added file"
163 $ hg mv file newfile
163 $ hg mv file newfile
164 $ hg commit -m "renamed file"
164 $ hg commit -m "renamed file"
165 $ hg update 0
165 $ hg update 0
166 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
166 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
167 $ hg rm file
167 $ hg rm file
168 $ hg commit -m "deleted file"
168 $ hg commit -m "deleted file"
169 created new head
169 created new head
170 $ hg merge --debug
170 $ hg merge --debug
171 searching for copies back to rev 1
171 searching for copies back to rev 1
172 unmatched files in other:
172 unmatched files in other:
173 newfile
173 newfile
174 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
174 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
175 src: 'file' -> dst: 'newfile' %
175 src: 'file' -> dst: 'newfile' %
176 checking for directory renames
176 checking for directory renames
177 resolving manifests
177 resolving manifests
178 branchmerge: True, force: False, partial: False
178 branchmerge: True, force: False, partial: False
179 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
179 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
180 note: possible conflict - file was deleted and renamed to:
180 note: possible conflict - file was deleted and renamed to:
181 newfile
181 newfile
182 newfile: remote created -> g
182 newfile: remote created -> g
183 getting newfile
183 getting newfile
184 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
184 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
185 (branch merge, don't forget to commit)
185 (branch merge, don't forget to commit)
186 $ hg status
186 $ hg status
187 M newfile
187 M newfile
188 $ cd ..
188 $ cd ..
@@ -1,23 +1,23 b''
1 $ hg init repo
1 $ hg init repo
2 $ cd repo
2 $ cd repo
3
3
4 $ touch foo
4 $ touch foo
5 $ hg ci -Am 'add foo'
5 $ hg ci -Am 'add foo'
6 adding foo
6 adding foo
7
7
8 $ hg up -C null
8 $ hg up -C null
9 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
9 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
10
10
11 this should be stored as a delta against rev 0
11 this should be stored as a delta against rev 0
12
12
13 $ echo foo bar baz > foo
13 $ echo foo bar baz > foo
14 $ hg ci -Am 'add foo again'
14 $ hg ci -Am 'add foo again'
15 adding foo
15 adding foo
16 created new head
16 created new head
17
17
18 $ hg debugindex foo
18 $ hg debugindex foo
19 rev offset length linkrev nodeid p1 p2
19 rev linkrev nodeid p1 p2
20 0 0 0 0 b80de5d13875 000000000000 000000000000
20 0 0 b80de5d13875 000000000000 000000000000
21 1 0 13 1 0376abec49b8 000000000000 000000000000
21 1 1 0376abec49b8 000000000000 000000000000
22
22
23 $ cd ..
23 $ cd ..
@@ -1,47 +1,47 b''
1 $ hg init empty-repo
1 $ hg init empty-repo
2 $ cd empty-repo
2 $ cd empty-repo
3
3
4 Flags on revlog version 0 are rejected
4 Flags on revlog version 0 are rejected
5
5
6 >>> with open('.hg/store/00changelog.i', 'wb') as fh:
6 >>> with open('.hg/store/00changelog.i', 'wb') as fh:
7 ... fh.write(b'\x00\x01\x00\x00')
7 ... fh.write(b'\x00\x01\x00\x00')
8
8
9 $ hg log
9 $ hg log
10 abort: unknown flags (0x01) in version 0 revlog 00changelog.i!
10 abort: unknown flags (0x01) in version 0 revlog 00changelog.i!
11 [255]
11 [255]
12
12
13 Unknown flags on revlog version 1 are rejected
13 Unknown flags on revlog version 1 are rejected
14
14
15 >>> with open('.hg/store/00changelog.i', 'wb') as fh:
15 >>> with open('.hg/store/00changelog.i', 'wb') as fh:
16 ... fh.write(b'\x00\x04\x00\x01')
16 ... fh.write(b'\x00\x04\x00\x01')
17
17
18 $ hg log
18 $ hg log
19 abort: unknown flags (0x04) in version 1 revlog 00changelog.i!
19 abort: unknown flags (0x04) in version 1 revlog 00changelog.i!
20 [255]
20 [255]
21
21
22 Unknown version is rejected
22 Unknown version is rejected
23
23
24 >>> with open('.hg/store/00changelog.i', 'wb') as fh:
24 >>> with open('.hg/store/00changelog.i', 'wb') as fh:
25 ... fh.write(b'\x00\x00\x00\x02')
25 ... fh.write(b'\x00\x00\x00\x02')
26
26
27 $ hg log
27 $ hg log
28 abort: unknown version (2) in revlog 00changelog.i!
28 abort: unknown version (2) in revlog 00changelog.i!
29 [255]
29 [255]
30
30
31 $ cd ..
31 $ cd ..
32
32
33 Test for CVE-2016-3630
33 Test for CVE-2016-3630
34
34
35 $ hg init
35 $ hg init
36
36
37 >>> open("a.i", "wb").write(
37 >>> open("a.i", "wb").write(
38 ... b"""eJxjYGZgZIAAYQYGxhgom+k/FMx8YKx9ZUaKSOyqo4cnuKb8mbqHV5cBCVTMWb1Cwqkhe4Gsg9AD
38 ... b"""eJxjYGZgZIAAYQYGxhgom+k/FMx8YKx9ZUaKSOyqo4cnuKb8mbqHV5cBCVTMWb1Cwqkhe4Gsg9AD
39 ... Joa3dYtcYYYBAQ8Qr4OqZAYRICPTSr5WKd/42rV36d+8/VmrNpv7NP1jQAXrQE4BqQUARngwVA=="""
39 ... Joa3dYtcYYYBAQ8Qr4OqZAYRICPTSr5WKd/42rV36d+8/VmrNpv7NP1jQAXrQE4BqQUARngwVA=="""
40 ... .decode("base64").decode("zlib"))
40 ... .decode("base64").decode("zlib"))
41
41
42 $ hg debugindex a.i
42 $ hg debugindex a.i
43 rev offset length linkrev nodeid p1 p2
43 rev linkrev nodeid p1 p2
44 0 0 19 2 99e0332bd498 000000000000 000000000000
44 0 2 99e0332bd498 000000000000 000000000000
45 1 19 12 3 6674f57a23d8 99e0332bd498 000000000000
45 1 3 6674f57a23d8 99e0332bd498 000000000000
46 $ hg debugdata a.i 1 2>&1 | egrep 'Error:.*decoded'
46 $ hg debugdata a.i 1 2>&1 | egrep 'Error:.*decoded'
47 (mercurial\.\w+\.mpatch\.)?mpatchError: patch cannot be decoded (re)
47 (mercurial\.\w+\.mpatch\.)?mpatchError: patch cannot be decoded (re)
@@ -1,143 +1,143 b''
1 test stripping of filelogs where the linkrev doesn't always increase
1 test stripping of filelogs where the linkrev doesn't always increase
2
2
3 $ echo '[extensions]' >> $HGRCPATH
3 $ echo '[extensions]' >> $HGRCPATH
4 $ echo 'strip =' >> $HGRCPATH
4 $ echo 'strip =' >> $HGRCPATH
5 $ hg init orig
5 $ hg init orig
6 $ cd orig
6 $ cd orig
7 $ commit()
7 $ commit()
8 > {
8 > {
9 > hg up -qC null
9 > hg up -qC null
10 > count=1
10 > count=1
11 > for i in "$@"; do
11 > for i in "$@"; do
12 > for f in $i; do
12 > for f in $i; do
13 > echo $count > $f
13 > echo $count > $f
14 > done
14 > done
15 > count=`expr $count + 1`
15 > count=`expr $count + 1`
16 > done
16 > done
17 > hg commit -qAm "$*"
17 > hg commit -qAm "$*"
18 > }
18 > }
19
19
20 2 1 0 2 0 1 2
20 2 1 0 2 0 1 2
21
21
22 $ commit '201 210'
22 $ commit '201 210'
23 $ commit '102 120' '210'
23 $ commit '102 120' '210'
24 $ commit '021'
24 $ commit '021'
25 $ commit '201' '021 120'
25 $ commit '201' '021 120'
26 $ commit '012 021' '102 201' '120 210'
26 $ commit '012 021' '102 201' '120 210'
27 $ commit 'manifest-file'
27 $ commit 'manifest-file'
28 $ commit '102 120' '012 210' '021 201'
28 $ commit '102 120' '012 210' '021 201'
29 $ commit '201 210' '021 120' '012 102'
29 $ commit '201 210' '021 120' '012 102'
30 $ HGUSER=another-user; export HGUSER
30 $ HGUSER=another-user; export HGUSER
31 $ commit 'manifest-file'
31 $ commit 'manifest-file'
32 $ commit '012' 'manifest-file'
32 $ commit '012' 'manifest-file'
33 $ cd ..
33 $ cd ..
34 $ hg clone -q -U -r -1 -r -2 -r -3 -r -4 -r -6 orig crossed
34 $ hg clone -q -U -r -1 -r -2 -r -3 -r -4 -r -6 orig crossed
35 $ cd crossed
35 $ cd crossed
36 $ hg debugindex --manifest
36 $ hg debugindex --manifest
37 rev offset length linkrev nodeid p1 p2
37 rev linkrev nodeid p1 p2
38 0 0 112 0 6f105cbb914d 000000000000 000000000000
38 0 0 6f105cbb914d 000000000000 000000000000
39 1 112 56 3 1b55917b3699 000000000000 000000000000
39 1 3 1b55917b3699 000000000000 000000000000
40 2 168 123 1 8f3d04e263e5 000000000000 000000000000
40 2 1 8f3d04e263e5 000000000000 000000000000
41 3 291 122 2 f0ef8726ac4f 000000000000 000000000000
41 3 2 f0ef8726ac4f 000000000000 000000000000
42 4 413 87 4 0b76e38b4070 000000000000 000000000000
42 4 4 0b76e38b4070 000000000000 000000000000
43
43
44 $ for i in 012 021 102 120 201 210 manifest-file; do
44 $ for i in 012 021 102 120 201 210 manifest-file; do
45 > echo $i
45 > echo $i
46 > hg debugindex $i
46 > hg debugindex $i
47 > echo
47 > echo
48 > done
48 > done
49 012
49 012
50 rev offset length linkrev nodeid p1 p2
50 rev linkrev nodeid p1 p2
51 0 0 3 0 b8e02f643373 000000000000 000000000000
51 0 0 b8e02f643373 000000000000 000000000000
52 1 3 3 1 5d9299349fc0 000000000000 000000000000
52 1 1 5d9299349fc0 000000000000 000000000000
53 2 6 3 2 2661d26c6496 000000000000 000000000000
53 2 2 2661d26c6496 000000000000 000000000000
54
54
55 021
55 021
56 rev offset length linkrev nodeid p1 p2
56 rev linkrev nodeid p1 p2
57 0 0 3 0 b8e02f643373 000000000000 000000000000
57 0 0 b8e02f643373 000000000000 000000000000
58 1 3 3 2 5d9299349fc0 000000000000 000000000000
58 1 2 5d9299349fc0 000000000000 000000000000
59 2 6 3 1 2661d26c6496 000000000000 000000000000
59 2 1 2661d26c6496 000000000000 000000000000
60
60
61 102
61 102
62 rev offset length linkrev nodeid p1 p2
62 rev linkrev nodeid p1 p2
63 0 0 3 1 b8e02f643373 000000000000 000000000000
63 0 1 b8e02f643373 000000000000 000000000000
64 1 3 3 0 5d9299349fc0 000000000000 000000000000
64 1 0 5d9299349fc0 000000000000 000000000000
65 2 6 3 2 2661d26c6496 000000000000 000000000000
65 2 2 2661d26c6496 000000000000 000000000000
66
66
67 120
67 120
68 rev offset length linkrev nodeid p1 p2
68 rev linkrev nodeid p1 p2
69 0 0 3 1 b8e02f643373 000000000000 000000000000
69 0 1 b8e02f643373 000000000000 000000000000
70 1 3 3 2 5d9299349fc0 000000000000 000000000000
70 1 2 5d9299349fc0 000000000000 000000000000
71 2 6 3 0 2661d26c6496 000000000000 000000000000
71 2 0 2661d26c6496 000000000000 000000000000
72
72
73 201
73 201
74 rev offset length linkrev nodeid p1 p2
74 rev linkrev nodeid p1 p2
75 0 0 3 2 b8e02f643373 000000000000 000000000000
75 0 2 b8e02f643373 000000000000 000000000000
76 1 3 3 0 5d9299349fc0 000000000000 000000000000
76 1 0 5d9299349fc0 000000000000 000000000000
77 2 6 3 1 2661d26c6496 000000000000 000000000000
77 2 1 2661d26c6496 000000000000 000000000000
78
78
79 210
79 210
80 rev offset length linkrev nodeid p1 p2
80 rev linkrev nodeid p1 p2
81 0 0 3 2 b8e02f643373 000000000000 000000000000
81 0 2 b8e02f643373 000000000000 000000000000
82 1 3 3 1 5d9299349fc0 000000000000 000000000000
82 1 1 5d9299349fc0 000000000000 000000000000
83 2 6 3 0 2661d26c6496 000000000000 000000000000
83 2 0 2661d26c6496 000000000000 000000000000
84
84
85 manifest-file
85 manifest-file
86 rev offset length linkrev nodeid p1 p2
86 rev linkrev nodeid p1 p2
87 0 0 3 3 b8e02f643373 000000000000 000000000000
87 0 3 b8e02f643373 000000000000 000000000000
88 1 3 3 4 5d9299349fc0 000000000000 000000000000
88 1 4 5d9299349fc0 000000000000 000000000000
89
89
90 $ cd ..
90 $ cd ..
91 $ for i in 0 1 2 3 4; do
91 $ for i in 0 1 2 3 4; do
92 > hg clone -q -U --pull crossed $i
92 > hg clone -q -U --pull crossed $i
93 > echo "% Trying to strip revision $i"
93 > echo "% Trying to strip revision $i"
94 > hg --cwd $i strip $i
94 > hg --cwd $i strip $i
95 > echo "% Verifying"
95 > echo "% Verifying"
96 > hg --cwd $i verify
96 > hg --cwd $i verify
97 > echo
97 > echo
98 > done
98 > done
99 % Trying to strip revision 0
99 % Trying to strip revision 0
100 saved backup bundle to $TESTTMP/0/.hg/strip-backup/*-backup.hg (glob)
100 saved backup bundle to $TESTTMP/0/.hg/strip-backup/*-backup.hg (glob)
101 % Verifying
101 % Verifying
102 checking changesets
102 checking changesets
103 checking manifests
103 checking manifests
104 crosschecking files in changesets and manifests
104 crosschecking files in changesets and manifests
105 checking files
105 checking files
106 7 files, 4 changesets, 15 total revisions
106 7 files, 4 changesets, 15 total revisions
107
107
108 % Trying to strip revision 1
108 % Trying to strip revision 1
109 saved backup bundle to $TESTTMP/1/.hg/strip-backup/*-backup.hg (glob)
109 saved backup bundle to $TESTTMP/1/.hg/strip-backup/*-backup.hg (glob)
110 % Verifying
110 % Verifying
111 checking changesets
111 checking changesets
112 checking manifests
112 checking manifests
113 crosschecking files in changesets and manifests
113 crosschecking files in changesets and manifests
114 checking files
114 checking files
115 7 files, 4 changesets, 14 total revisions
115 7 files, 4 changesets, 14 total revisions
116
116
117 % Trying to strip revision 2
117 % Trying to strip revision 2
118 saved backup bundle to $TESTTMP/2/.hg/strip-backup/*-backup.hg (glob)
118 saved backup bundle to $TESTTMP/2/.hg/strip-backup/*-backup.hg (glob)
119 % Verifying
119 % Verifying
120 checking changesets
120 checking changesets
121 checking manifests
121 checking manifests
122 crosschecking files in changesets and manifests
122 crosschecking files in changesets and manifests
123 checking files
123 checking files
124 7 files, 4 changesets, 14 total revisions
124 7 files, 4 changesets, 14 total revisions
125
125
126 % Trying to strip revision 3
126 % Trying to strip revision 3
127 saved backup bundle to $TESTTMP/3/.hg/strip-backup/*-backup.hg (glob)
127 saved backup bundle to $TESTTMP/3/.hg/strip-backup/*-backup.hg (glob)
128 % Verifying
128 % Verifying
129 checking changesets
129 checking changesets
130 checking manifests
130 checking manifests
131 crosschecking files in changesets and manifests
131 crosschecking files in changesets and manifests
132 checking files
132 checking files
133 7 files, 4 changesets, 19 total revisions
133 7 files, 4 changesets, 19 total revisions
134
134
135 % Trying to strip revision 4
135 % Trying to strip revision 4
136 saved backup bundle to $TESTTMP/4/.hg/strip-backup/*-backup.hg (glob)
136 saved backup bundle to $TESTTMP/4/.hg/strip-backup/*-backup.hg (glob)
137 % Verifying
137 % Verifying
138 checking changesets
138 checking changesets
139 checking manifests
139 checking manifests
140 crosschecking files in changesets and manifests
140 crosschecking files in changesets and manifests
141 checking files
141 checking files
142 7 files, 4 changesets, 19 total revisions
142 7 files, 4 changesets, 19 total revisions
143
143
@@ -1,876 +1,876 b''
1 #require killdaemons
1 #require killdaemons
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [format]
4 > [format]
5 > usegeneraldelta=yes
5 > usegeneraldelta=yes
6 > [ui]
6 > [ui]
7 > ssh=$PYTHON "$TESTDIR/dummyssh"
7 > ssh=$PYTHON "$TESTDIR/dummyssh"
8 > EOF
8 > EOF
9
9
10 Set up repo
10 Set up repo
11
11
12 $ hg --config experimental.treemanifest=True init repo
12 $ hg --config experimental.treemanifest=True init repo
13 $ cd repo
13 $ cd repo
14
14
15 Requirements get set on init
15 Requirements get set on init
16
16
17 $ grep treemanifest .hg/requires
17 $ grep treemanifest .hg/requires
18 treemanifest
18 treemanifest
19
19
20 Without directories, looks like any other repo
20 Without directories, looks like any other repo
21
21
22 $ echo 0 > a
22 $ echo 0 > a
23 $ echo 0 > b
23 $ echo 0 > b
24 $ hg ci -Aqm initial
24 $ hg ci -Aqm initial
25 $ hg debugdata -m 0
25 $ hg debugdata -m 0
26 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
26 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
27 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
27 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
28
28
29 Submanifest is stored in separate revlog
29 Submanifest is stored in separate revlog
30
30
31 $ mkdir dir1
31 $ mkdir dir1
32 $ echo 1 > dir1/a
32 $ echo 1 > dir1/a
33 $ echo 1 > dir1/b
33 $ echo 1 > dir1/b
34 $ echo 1 > e
34 $ echo 1 > e
35 $ hg ci -Aqm 'add dir1'
35 $ hg ci -Aqm 'add dir1'
36 $ hg debugdata -m 1
36 $ hg debugdata -m 1
37 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
37 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
38 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
38 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
39 dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44et (esc)
39 dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44et (esc)
40 e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
40 e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
41 $ hg debugdata --dir dir1 0
41 $ hg debugdata --dir dir1 0
42 a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
42 a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
43 b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
43 b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
44
44
45 Can add nested directories
45 Can add nested directories
46
46
47 $ mkdir dir1/dir1
47 $ mkdir dir1/dir1
48 $ echo 2 > dir1/dir1/a
48 $ echo 2 > dir1/dir1/a
49 $ echo 2 > dir1/dir1/b
49 $ echo 2 > dir1/dir1/b
50 $ mkdir dir1/dir2
50 $ mkdir dir1/dir2
51 $ echo 2 > dir1/dir2/a
51 $ echo 2 > dir1/dir2/a
52 $ echo 2 > dir1/dir2/b
52 $ echo 2 > dir1/dir2/b
53 $ hg ci -Aqm 'add dir1/dir1'
53 $ hg ci -Aqm 'add dir1/dir1'
54 $ hg files -r .
54 $ hg files -r .
55 a
55 a
56 b
56 b
57 dir1/a
57 dir1/a
58 dir1/b
58 dir1/b
59 dir1/dir1/a
59 dir1/dir1/a
60 dir1/dir1/b
60 dir1/dir1/b
61 dir1/dir2/a
61 dir1/dir2/a
62 dir1/dir2/b
62 dir1/dir2/b
63 e
63 e
64
64
65 The manifest command works
65 The manifest command works
66
66
67 $ hg manifest
67 $ hg manifest
68 a
68 a
69 b
69 b
70 dir1/a
70 dir1/a
71 dir1/b
71 dir1/b
72 dir1/dir1/a
72 dir1/dir1/a
73 dir1/dir1/b
73 dir1/dir1/b
74 dir1/dir2/a
74 dir1/dir2/a
75 dir1/dir2/b
75 dir1/dir2/b
76 e
76 e
77
77
78 Revision is not created for unchanged directory
78 Revision is not created for unchanged directory
79
79
80 $ mkdir dir2
80 $ mkdir dir2
81 $ echo 3 > dir2/a
81 $ echo 3 > dir2/a
82 $ hg add dir2
82 $ hg add dir2
83 adding dir2/a
83 adding dir2/a
84 $ hg debugindex --dir dir1 > before
84 $ hg debugindex --dir dir1 > before
85 $ hg ci -qm 'add dir2'
85 $ hg ci -qm 'add dir2'
86 $ hg debugindex --dir dir1 > after
86 $ hg debugindex --dir dir1 > after
87 $ diff before after
87 $ diff before after
88 $ rm before after
88 $ rm before after
89
89
90 Removing directory does not create an revlog entry
90 Removing directory does not create an revlog entry
91
91
92 $ hg rm dir1/dir1
92 $ hg rm dir1/dir1
93 removing dir1/dir1/a
93 removing dir1/dir1/a
94 removing dir1/dir1/b
94 removing dir1/dir1/b
95 $ hg debugindex --dir dir1/dir1 > before
95 $ hg debugindex --dir dir1/dir1 > before
96 $ hg ci -qm 'remove dir1/dir1'
96 $ hg ci -qm 'remove dir1/dir1'
97 $ hg debugindex --dir dir1/dir1 > after
97 $ hg debugindex --dir dir1/dir1 > after
98 $ diff before after
98 $ diff before after
99 $ rm before after
99 $ rm before after
100
100
101 Check that hg files (calls treemanifest.walk()) works
101 Check that hg files (calls treemanifest.walk()) works
102 without loading all directory revlogs
102 without loading all directory revlogs
103
103
104 $ hg co 'desc("add dir2")'
104 $ hg co 'desc("add dir2")'
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 $ mv .hg/store/meta/dir2 .hg/store/meta/dir2-backup
106 $ mv .hg/store/meta/dir2 .hg/store/meta/dir2-backup
107 $ hg files -r . dir1
107 $ hg files -r . dir1
108 dir1/a
108 dir1/a
109 dir1/b
109 dir1/b
110 dir1/dir1/a
110 dir1/dir1/a
111 dir1/dir1/b
111 dir1/dir1/b
112 dir1/dir2/a
112 dir1/dir2/a
113 dir1/dir2/b
113 dir1/dir2/b
114
114
115 Check that status between revisions works (calls treemanifest.matches())
115 Check that status between revisions works (calls treemanifest.matches())
116 without loading all directory revlogs
116 without loading all directory revlogs
117
117
118 $ hg status --rev 'desc("add dir1")' --rev . dir1
118 $ hg status --rev 'desc("add dir1")' --rev . dir1
119 A dir1/dir1/a
119 A dir1/dir1/a
120 A dir1/dir1/b
120 A dir1/dir1/b
121 A dir1/dir2/a
121 A dir1/dir2/a
122 A dir1/dir2/b
122 A dir1/dir2/b
123 $ mv .hg/store/meta/dir2-backup .hg/store/meta/dir2
123 $ mv .hg/store/meta/dir2-backup .hg/store/meta/dir2
124
124
125 Merge creates 2-parent revision of directory revlog
125 Merge creates 2-parent revision of directory revlog
126
126
127 $ echo 5 > dir1/a
127 $ echo 5 > dir1/a
128 $ hg ci -Aqm 'modify dir1/a'
128 $ hg ci -Aqm 'modify dir1/a'
129 $ hg co '.^'
129 $ hg co '.^'
130 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
130 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 $ echo 6 > dir1/b
131 $ echo 6 > dir1/b
132 $ hg ci -Aqm 'modify dir1/b'
132 $ hg ci -Aqm 'modify dir1/b'
133 $ hg merge 'desc("modify dir1/a")'
133 $ hg merge 'desc("modify dir1/a")'
134 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
134 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
135 (branch merge, don't forget to commit)
135 (branch merge, don't forget to commit)
136 $ hg ci -m 'conflict-free merge involving dir1/'
136 $ hg ci -m 'conflict-free merge involving dir1/'
137 $ cat dir1/a
137 $ cat dir1/a
138 5
138 5
139 $ cat dir1/b
139 $ cat dir1/b
140 6
140 6
141 $ hg debugindex --dir dir1
141 $ hg debugindex --dir dir1
142 rev offset length linkrev nodeid p1 p2
142 rev linkrev nodeid p1 p2
143 0 0 54 1 8b3ffd73f901 000000000000 000000000000
143 0 1 8b3ffd73f901 000000000000 000000000000
144 1 54 68 2 68e9d057c5a8 8b3ffd73f901 000000000000
144 1 2 68e9d057c5a8 8b3ffd73f901 000000000000
145 2 122 12 4 4698198d2624 68e9d057c5a8 000000000000
145 2 4 4698198d2624 68e9d057c5a8 000000000000
146 3 134 55 5 44844058ccce 68e9d057c5a8 000000000000
146 3 5 44844058ccce 68e9d057c5a8 000000000000
147 4 189 55 6 bf3d9b744927 68e9d057c5a8 000000000000
147 4 6 bf3d9b744927 68e9d057c5a8 000000000000
148 5 244 55 7 dde7c0af2a03 bf3d9b744927 44844058ccce
148 5 7 dde7c0af2a03 bf3d9b744927 44844058ccce
149
149
150 Merge keeping directory from parent 1 does not create revlog entry. (Note that
150 Merge keeping directory from parent 1 does not create revlog entry. (Note that
151 dir1's manifest does change, but only because dir1/a's filelog changes.)
151 dir1's manifest does change, but only because dir1/a's filelog changes.)
152
152
153 $ hg co 'desc("add dir2")'
153 $ hg co 'desc("add dir2")'
154 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 $ echo 8 > dir2/a
155 $ echo 8 > dir2/a
156 $ hg ci -m 'modify dir2/a'
156 $ hg ci -m 'modify dir2/a'
157 created new head
157 created new head
158
158
159 $ hg debugindex --dir dir2 > before
159 $ hg debugindex --dir dir2 > before
160 $ hg merge 'desc("modify dir1/a")'
160 $ hg merge 'desc("modify dir1/a")'
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 (branch merge, don't forget to commit)
162 (branch merge, don't forget to commit)
163 $ hg revert -r 'desc("modify dir2/a")' .
163 $ hg revert -r 'desc("modify dir2/a")' .
164 reverting dir1/a
164 reverting dir1/a
165 $ hg ci -m 'merge, keeping parent 1'
165 $ hg ci -m 'merge, keeping parent 1'
166 $ hg debugindex --dir dir2 > after
166 $ hg debugindex --dir dir2 > after
167 $ diff before after
167 $ diff before after
168 $ rm before after
168 $ rm before after
169
169
170 Merge keeping directory from parent 2 does not create revlog entry. (Note that
170 Merge keeping directory from parent 2 does not create revlog entry. (Note that
171 dir2's manifest does change, but only because dir2/a's filelog changes.)
171 dir2's manifest does change, but only because dir2/a's filelog changes.)
172
172
173 $ hg co 'desc("modify dir2/a")'
173 $ hg co 'desc("modify dir2/a")'
174 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 $ hg debugindex --dir dir1 > before
175 $ hg debugindex --dir dir1 > before
176 $ hg merge 'desc("modify dir1/a")'
176 $ hg merge 'desc("modify dir1/a")'
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 (branch merge, don't forget to commit)
178 (branch merge, don't forget to commit)
179 $ hg revert -r 'desc("modify dir1/a")' .
179 $ hg revert -r 'desc("modify dir1/a")' .
180 reverting dir2/a
180 reverting dir2/a
181 $ hg ci -m 'merge, keeping parent 2'
181 $ hg ci -m 'merge, keeping parent 2'
182 created new head
182 created new head
183 $ hg debugindex --dir dir1 > after
183 $ hg debugindex --dir dir1 > after
184 $ diff before after
184 $ diff before after
185 $ rm before after
185 $ rm before after
186
186
187 Create flat source repo for tests with mixed flat/tree manifests
187 Create flat source repo for tests with mixed flat/tree manifests
188
188
189 $ cd ..
189 $ cd ..
190 $ hg init repo-flat
190 $ hg init repo-flat
191 $ cd repo-flat
191 $ cd repo-flat
192
192
193 Create a few commits with flat manifest
193 Create a few commits with flat manifest
194
194
195 $ echo 0 > a
195 $ echo 0 > a
196 $ echo 0 > b
196 $ echo 0 > b
197 $ echo 0 > e
197 $ echo 0 > e
198 $ for d in dir1 dir1/dir1 dir1/dir2 dir2
198 $ for d in dir1 dir1/dir1 dir1/dir2 dir2
199 > do
199 > do
200 > mkdir $d
200 > mkdir $d
201 > echo 0 > $d/a
201 > echo 0 > $d/a
202 > echo 0 > $d/b
202 > echo 0 > $d/b
203 > done
203 > done
204 $ hg ci -Aqm initial
204 $ hg ci -Aqm initial
205
205
206 $ echo 1 > a
206 $ echo 1 > a
207 $ echo 1 > dir1/a
207 $ echo 1 > dir1/a
208 $ echo 1 > dir1/dir1/a
208 $ echo 1 > dir1/dir1/a
209 $ hg ci -Aqm 'modify on branch 1'
209 $ hg ci -Aqm 'modify on branch 1'
210
210
211 $ hg co 0
211 $ hg co 0
212 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
213 $ echo 2 > b
213 $ echo 2 > b
214 $ echo 2 > dir1/b
214 $ echo 2 > dir1/b
215 $ echo 2 > dir1/dir1/b
215 $ echo 2 > dir1/dir1/b
216 $ hg ci -Aqm 'modify on branch 2'
216 $ hg ci -Aqm 'modify on branch 2'
217
217
218 $ hg merge 1
218 $ hg merge 1
219 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 (branch merge, don't forget to commit)
220 (branch merge, don't forget to commit)
221 $ hg ci -m 'merge of flat manifests to new flat manifest'
221 $ hg ci -m 'merge of flat manifests to new flat manifest'
222
222
223 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
223 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
224 $ cat hg.pid >> $DAEMON_PIDS
224 $ cat hg.pid >> $DAEMON_PIDS
225
225
226 Create clone with tree manifests enabled
226 Create clone with tree manifests enabled
227
227
228 $ cd ..
228 $ cd ..
229 $ hg clone --config experimental.treemanifest=1 \
229 $ hg clone --config experimental.treemanifest=1 \
230 > http://localhost:$HGPORT repo-mixed -r 1
230 > http://localhost:$HGPORT repo-mixed -r 1
231 adding changesets
231 adding changesets
232 adding manifests
232 adding manifests
233 adding file changes
233 adding file changes
234 added 2 changesets with 14 changes to 11 files
234 added 2 changesets with 14 changes to 11 files
235 new changesets 5b02a3e8db7e:581ef6037d8b
235 new changesets 5b02a3e8db7e:581ef6037d8b
236 updating to branch default
236 updating to branch default
237 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
237 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
238 $ cd repo-mixed
238 $ cd repo-mixed
239 $ test -d .hg/store/meta
239 $ test -d .hg/store/meta
240 [1]
240 [1]
241 $ grep treemanifest .hg/requires
241 $ grep treemanifest .hg/requires
242 treemanifest
242 treemanifest
243
243
244 Should be possible to push updates from flat to tree manifest repo
244 Should be possible to push updates from flat to tree manifest repo
245
245
246 $ hg -R ../repo-flat push ssh://user@dummy/repo-mixed
246 $ hg -R ../repo-flat push ssh://user@dummy/repo-mixed
247 pushing to ssh://user@dummy/repo-mixed
247 pushing to ssh://user@dummy/repo-mixed
248 searching for changes
248 searching for changes
249 remote: adding changesets
249 remote: adding changesets
250 remote: adding manifests
250 remote: adding manifests
251 remote: adding file changes
251 remote: adding file changes
252 remote: added 2 changesets with 3 changes to 3 files
252 remote: added 2 changesets with 3 changes to 3 files
253
253
254 Commit should store revlog per directory
254 Commit should store revlog per directory
255
255
256 $ hg co 1
256 $ hg co 1
257 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 $ echo 3 > a
258 $ echo 3 > a
259 $ echo 3 > dir1/a
259 $ echo 3 > dir1/a
260 $ echo 3 > dir1/dir1/a
260 $ echo 3 > dir1/dir1/a
261 $ hg ci -m 'first tree'
261 $ hg ci -m 'first tree'
262 created new head
262 created new head
263 $ find .hg/store/meta | sort
263 $ find .hg/store/meta | sort
264 .hg/store/meta
264 .hg/store/meta
265 .hg/store/meta/dir1
265 .hg/store/meta/dir1
266 .hg/store/meta/dir1/00manifest.i
266 .hg/store/meta/dir1/00manifest.i
267 .hg/store/meta/dir1/dir1
267 .hg/store/meta/dir1/dir1
268 .hg/store/meta/dir1/dir1/00manifest.i
268 .hg/store/meta/dir1/dir1/00manifest.i
269 .hg/store/meta/dir1/dir2
269 .hg/store/meta/dir1/dir2
270 .hg/store/meta/dir1/dir2/00manifest.i
270 .hg/store/meta/dir1/dir2/00manifest.i
271 .hg/store/meta/dir2
271 .hg/store/meta/dir2
272 .hg/store/meta/dir2/00manifest.i
272 .hg/store/meta/dir2/00manifest.i
273
273
274 Merge of two trees
274 Merge of two trees
275
275
276 $ hg co 2
276 $ hg co 2
277 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 $ hg merge 1
278 $ hg merge 1
279 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 (branch merge, don't forget to commit)
280 (branch merge, don't forget to commit)
281 $ hg ci -m 'merge of flat manifests to new tree manifest'
281 $ hg ci -m 'merge of flat manifests to new tree manifest'
282 created new head
282 created new head
283 $ hg diff -r 3
283 $ hg diff -r 3
284
284
285 Parent of tree root manifest should be flat manifest, and two for merge
285 Parent of tree root manifest should be flat manifest, and two for merge
286
286
287 $ hg debugindex -m
287 $ hg debugindex -m
288 rev offset length linkrev nodeid p1 p2
288 rev linkrev nodeid p1 p2
289 0 0 80 0 40536115ed9e 000000000000 000000000000
289 0 0 40536115ed9e 000000000000 000000000000
290 1 80 83 1 f3376063c255 40536115ed9e 000000000000
290 1 1 f3376063c255 40536115ed9e 000000000000
291 2 163 89 2 5d9b9da231a2 40536115ed9e 000000000000
291 2 2 5d9b9da231a2 40536115ed9e 000000000000
292 3 252 83 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
292 3 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
293 4 335 124 4 51e32a8c60ee f3376063c255 000000000000
293 4 4 51e32a8c60ee f3376063c255 000000000000
294 5 459 126 5 cc5baa78b230 5d9b9da231a2 f3376063c255
294 5 5 cc5baa78b230 5d9b9da231a2 f3376063c255
295
295
296
296
297 Status across flat/tree boundary should work
297 Status across flat/tree boundary should work
298
298
299 $ hg status --rev '.^' --rev .
299 $ hg status --rev '.^' --rev .
300 M a
300 M a
301 M dir1/a
301 M dir1/a
302 M dir1/dir1/a
302 M dir1/dir1/a
303
303
304
304
305 Turning off treemanifest config has no effect
305 Turning off treemanifest config has no effect
306
306
307 $ hg debugindex --dir dir1
307 $ hg debugindex --dir dir1
308 rev offset length linkrev nodeid p1 p2
308 rev linkrev nodeid p1 p2
309 0 0 127 4 064927a0648a 000000000000 000000000000
309 0 4 064927a0648a 000000000000 000000000000
310 1 127 111 5 25ecb8cb8618 000000000000 000000000000
310 1 5 25ecb8cb8618 000000000000 000000000000
311 $ echo 2 > dir1/a
311 $ echo 2 > dir1/a
312 $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
312 $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
313 $ hg debugindex --dir dir1
313 $ hg debugindex --dir dir1
314 rev offset length linkrev nodeid p1 p2
314 rev linkrev nodeid p1 p2
315 0 0 127 4 064927a0648a 000000000000 000000000000
315 0 4 064927a0648a 000000000000 000000000000
316 1 127 111 5 25ecb8cb8618 000000000000 000000000000
316 1 5 25ecb8cb8618 000000000000 000000000000
317 2 238 55 6 5b16163a30c6 25ecb8cb8618 000000000000
317 2 6 5b16163a30c6 25ecb8cb8618 000000000000
318
318
319 Stripping and recovering changes should work
319 Stripping and recovering changes should work
320
320
321 $ hg st --change tip
321 $ hg st --change tip
322 M dir1/a
322 M dir1/a
323 $ hg --config extensions.strip= strip tip
323 $ hg --config extensions.strip= strip tip
324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
325 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg
325 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg
326 $ hg debugindex --dir dir1
326 $ hg debugindex --dir dir1
327 rev offset length linkrev nodeid p1 p2
327 rev linkrev nodeid p1 p2
328 0 0 127 4 064927a0648a 000000000000 000000000000
328 0 4 064927a0648a 000000000000 000000000000
329 1 127 111 5 25ecb8cb8618 000000000000 000000000000
329 1 5 25ecb8cb8618 000000000000 000000000000
330 $ hg incoming .hg/strip-backup/*
330 $ hg incoming .hg/strip-backup/*
331 comparing with .hg/strip-backup/*-backup.hg (glob)
331 comparing with .hg/strip-backup/*-backup.hg (glob)
332 searching for changes
332 searching for changes
333 changeset: 6:51cfd7b1e13b
333 changeset: 6:51cfd7b1e13b
334 tag: tip
334 tag: tip
335 user: test
335 user: test
336 date: Thu Jan 01 00:00:00 1970 +0000
336 date: Thu Jan 01 00:00:00 1970 +0000
337 summary: modify dir1/a
337 summary: modify dir1/a
338
338
339 $ hg pull .hg/strip-backup/*
339 $ hg pull .hg/strip-backup/*
340 pulling from .hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg
340 pulling from .hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg
341 searching for changes
341 searching for changes
342 adding changesets
342 adding changesets
343 adding manifests
343 adding manifests
344 adding file changes
344 adding file changes
345 added 1 changesets with 1 changes to 1 files
345 added 1 changesets with 1 changes to 1 files
346 new changesets 51cfd7b1e13b
346 new changesets 51cfd7b1e13b
347 (run 'hg update' to get a working copy)
347 (run 'hg update' to get a working copy)
348 $ hg --config extensions.strip= strip tip
348 $ hg --config extensions.strip= strip tip
349 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/*-backup.hg (glob)
349 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/*-backup.hg (glob)
350 $ hg unbundle -q .hg/strip-backup/*
350 $ hg unbundle -q .hg/strip-backup/*
351 $ hg debugindex --dir dir1
351 $ hg debugindex --dir dir1
352 rev offset length linkrev nodeid p1 p2
352 rev linkrev nodeid p1 p2
353 0 0 127 4 064927a0648a 000000000000 000000000000
353 0 4 064927a0648a 000000000000 000000000000
354 1 127 111 5 25ecb8cb8618 000000000000 000000000000
354 1 5 25ecb8cb8618 000000000000 000000000000
355 2 238 55 6 5b16163a30c6 25ecb8cb8618 000000000000
355 2 6 5b16163a30c6 25ecb8cb8618 000000000000
356 $ hg st --change tip
356 $ hg st --change tip
357 M dir1/a
357 M dir1/a
358
358
359 Shelving and unshelving should work
359 Shelving and unshelving should work
360
360
361 $ echo foo >> dir1/a
361 $ echo foo >> dir1/a
362 $ hg --config extensions.shelve= shelve
362 $ hg --config extensions.shelve= shelve
363 shelved as default
363 shelved as default
364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 $ hg --config extensions.shelve= unshelve
365 $ hg --config extensions.shelve= unshelve
366 unshelving change 'default'
366 unshelving change 'default'
367 $ hg diff --nodates
367 $ hg diff --nodates
368 diff -r 708a273da119 dir1/a
368 diff -r 708a273da119 dir1/a
369 --- a/dir1/a
369 --- a/dir1/a
370 +++ b/dir1/a
370 +++ b/dir1/a
371 @@ -1,1 +1,2 @@
371 @@ -1,1 +1,2 @@
372 1
372 1
373 +foo
373 +foo
374
374
375 Pushing from treemanifest repo to an empty repo makes that a treemanifest repo
375 Pushing from treemanifest repo to an empty repo makes that a treemanifest repo
376
376
377 $ cd ..
377 $ cd ..
378 $ hg init empty-repo
378 $ hg init empty-repo
379 $ cat << EOF >> empty-repo/.hg/hgrc
379 $ cat << EOF >> empty-repo/.hg/hgrc
380 > [experimental]
380 > [experimental]
381 > changegroup3=yes
381 > changegroup3=yes
382 > EOF
382 > EOF
383 $ grep treemanifest empty-repo/.hg/requires
383 $ grep treemanifest empty-repo/.hg/requires
384 [1]
384 [1]
385 $ hg push -R repo -r 0 empty-repo
385 $ hg push -R repo -r 0 empty-repo
386 pushing to empty-repo
386 pushing to empty-repo
387 searching for changes
387 searching for changes
388 adding changesets
388 adding changesets
389 adding manifests
389 adding manifests
390 adding file changes
390 adding file changes
391 added 1 changesets with 2 changes to 2 files
391 added 1 changesets with 2 changes to 2 files
392 $ grep treemanifest empty-repo/.hg/requires
392 $ grep treemanifest empty-repo/.hg/requires
393 treemanifest
393 treemanifest
394
394
395 Pushing to an empty repo works
395 Pushing to an empty repo works
396
396
397 $ hg --config experimental.treemanifest=1 init clone
397 $ hg --config experimental.treemanifest=1 init clone
398 $ grep treemanifest clone/.hg/requires
398 $ grep treemanifest clone/.hg/requires
399 treemanifest
399 treemanifest
400 $ hg push -R repo clone
400 $ hg push -R repo clone
401 pushing to clone
401 pushing to clone
402 searching for changes
402 searching for changes
403 adding changesets
403 adding changesets
404 adding manifests
404 adding manifests
405 adding file changes
405 adding file changes
406 added 11 changesets with 15 changes to 10 files (+3 heads)
406 added 11 changesets with 15 changes to 10 files (+3 heads)
407 $ grep treemanifest clone/.hg/requires
407 $ grep treemanifest clone/.hg/requires
408 treemanifest
408 treemanifest
409 $ hg -R clone verify
409 $ hg -R clone verify
410 checking changesets
410 checking changesets
411 checking manifests
411 checking manifests
412 checking directory manifests
412 checking directory manifests
413 crosschecking files in changesets and manifests
413 crosschecking files in changesets and manifests
414 checking files
414 checking files
415 10 files, 11 changesets, 15 total revisions
415 10 files, 11 changesets, 15 total revisions
416
416
417 Create deeper repo with tree manifests.
417 Create deeper repo with tree manifests.
418
418
419 $ hg --config experimental.treemanifest=True init deeprepo
419 $ hg --config experimental.treemanifest=True init deeprepo
420 $ cd deeprepo
420 $ cd deeprepo
421
421
422 $ mkdir .A
422 $ mkdir .A
423 $ mkdir b
423 $ mkdir b
424 $ mkdir b/bar
424 $ mkdir b/bar
425 $ mkdir b/bar/orange
425 $ mkdir b/bar/orange
426 $ mkdir b/bar/orange/fly
426 $ mkdir b/bar/orange/fly
427 $ mkdir b/foo
427 $ mkdir b/foo
428 $ mkdir b/foo/apple
428 $ mkdir b/foo/apple
429 $ mkdir b/foo/apple/bees
429 $ mkdir b/foo/apple/bees
430
430
431 $ touch .A/one.txt
431 $ touch .A/one.txt
432 $ touch .A/two.txt
432 $ touch .A/two.txt
433 $ touch b/bar/fruits.txt
433 $ touch b/bar/fruits.txt
434 $ touch b/bar/orange/fly/gnat.py
434 $ touch b/bar/orange/fly/gnat.py
435 $ touch b/bar/orange/fly/housefly.txt
435 $ touch b/bar/orange/fly/housefly.txt
436 $ touch b/foo/apple/bees/flower.py
436 $ touch b/foo/apple/bees/flower.py
437 $ touch c.txt
437 $ touch c.txt
438 $ touch d.py
438 $ touch d.py
439
439
440 $ hg ci -Aqm 'initial'
440 $ hg ci -Aqm 'initial'
441
441
442 $ echo >> .A/one.txt
442 $ echo >> .A/one.txt
443 $ echo >> .A/two.txt
443 $ echo >> .A/two.txt
444 $ echo >> b/bar/fruits.txt
444 $ echo >> b/bar/fruits.txt
445 $ echo >> b/bar/orange/fly/gnat.py
445 $ echo >> b/bar/orange/fly/gnat.py
446 $ echo >> b/bar/orange/fly/housefly.txt
446 $ echo >> b/bar/orange/fly/housefly.txt
447 $ echo >> b/foo/apple/bees/flower.py
447 $ echo >> b/foo/apple/bees/flower.py
448 $ echo >> c.txt
448 $ echo >> c.txt
449 $ echo >> d.py
449 $ echo >> d.py
450 $ hg ci -Aqm 'second'
450 $ hg ci -Aqm 'second'
451
451
452 We'll see that visitdir works by removing some treemanifest revlogs and running
452 We'll see that visitdir works by removing some treemanifest revlogs and running
453 the files command with various parameters.
453 the files command with various parameters.
454
454
455 Test files from the root.
455 Test files from the root.
456
456
457 $ hg files -r .
457 $ hg files -r .
458 .A/one.txt
458 .A/one.txt
459 .A/two.txt
459 .A/two.txt
460 b/bar/fruits.txt
460 b/bar/fruits.txt
461 b/bar/orange/fly/gnat.py
461 b/bar/orange/fly/gnat.py
462 b/bar/orange/fly/housefly.txt
462 b/bar/orange/fly/housefly.txt
463 b/foo/apple/bees/flower.py
463 b/foo/apple/bees/flower.py
464 c.txt
464 c.txt
465 d.py
465 d.py
466
466
467 Excludes with a glob should not exclude everything from the glob's root
467 Excludes with a glob should not exclude everything from the glob's root
468
468
469 $ hg files -r . -X 'b/fo?' b
469 $ hg files -r . -X 'b/fo?' b
470 b/bar/fruits.txt
470 b/bar/fruits.txt
471 b/bar/orange/fly/gnat.py
471 b/bar/orange/fly/gnat.py
472 b/bar/orange/fly/housefly.txt
472 b/bar/orange/fly/housefly.txt
473 $ cp -R .hg/store .hg/store-copy
473 $ cp -R .hg/store .hg/store-copy
474
474
475 Test files for a subdirectory.
475 Test files for a subdirectory.
476
476
477 $ rm -r .hg/store/meta/~2e_a
477 $ rm -r .hg/store/meta/~2e_a
478 $ hg files -r . b
478 $ hg files -r . b
479 b/bar/fruits.txt
479 b/bar/fruits.txt
480 b/bar/orange/fly/gnat.py
480 b/bar/orange/fly/gnat.py
481 b/bar/orange/fly/housefly.txt
481 b/bar/orange/fly/housefly.txt
482 b/foo/apple/bees/flower.py
482 b/foo/apple/bees/flower.py
483 $ hg diff -r '.^' -r . --stat b
483 $ hg diff -r '.^' -r . --stat b
484 b/bar/fruits.txt | 1 +
484 b/bar/fruits.txt | 1 +
485 b/bar/orange/fly/gnat.py | 1 +
485 b/bar/orange/fly/gnat.py | 1 +
486 b/bar/orange/fly/housefly.txt | 1 +
486 b/bar/orange/fly/housefly.txt | 1 +
487 b/foo/apple/bees/flower.py | 1 +
487 b/foo/apple/bees/flower.py | 1 +
488 4 files changed, 4 insertions(+), 0 deletions(-)
488 4 files changed, 4 insertions(+), 0 deletions(-)
489 $ cp -R .hg/store-copy/. .hg/store
489 $ cp -R .hg/store-copy/. .hg/store
490
490
491 Test files with just includes and excludes.
491 Test files with just includes and excludes.
492
492
493 $ rm -r .hg/store/meta/~2e_a
493 $ rm -r .hg/store/meta/~2e_a
494 $ rm -r .hg/store/meta/b/bar/orange/fly
494 $ rm -r .hg/store/meta/b/bar/orange/fly
495 $ rm -r .hg/store/meta/b/foo/apple/bees
495 $ rm -r .hg/store/meta/b/foo/apple/bees
496 $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
496 $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
497 b/bar/fruits.txt
497 b/bar/fruits.txt
498 $ hg diff -r '.^' -r . --stat -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
498 $ hg diff -r '.^' -r . --stat -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
499 b/bar/fruits.txt | 1 +
499 b/bar/fruits.txt | 1 +
500 1 files changed, 1 insertions(+), 0 deletions(-)
500 1 files changed, 1 insertions(+), 0 deletions(-)
501 $ cp -R .hg/store-copy/. .hg/store
501 $ cp -R .hg/store-copy/. .hg/store
502
502
503 Test files for a subdirectory, excluding a directory within it.
503 Test files for a subdirectory, excluding a directory within it.
504
504
505 $ rm -r .hg/store/meta/~2e_a
505 $ rm -r .hg/store/meta/~2e_a
506 $ rm -r .hg/store/meta/b/foo
506 $ rm -r .hg/store/meta/b/foo
507 $ hg files -r . -X path:b/foo b
507 $ hg files -r . -X path:b/foo b
508 b/bar/fruits.txt
508 b/bar/fruits.txt
509 b/bar/orange/fly/gnat.py
509 b/bar/orange/fly/gnat.py
510 b/bar/orange/fly/housefly.txt
510 b/bar/orange/fly/housefly.txt
511 $ hg diff -r '.^' -r . --stat -X path:b/foo b
511 $ hg diff -r '.^' -r . --stat -X path:b/foo b
512 b/bar/fruits.txt | 1 +
512 b/bar/fruits.txt | 1 +
513 b/bar/orange/fly/gnat.py | 1 +
513 b/bar/orange/fly/gnat.py | 1 +
514 b/bar/orange/fly/housefly.txt | 1 +
514 b/bar/orange/fly/housefly.txt | 1 +
515 3 files changed, 3 insertions(+), 0 deletions(-)
515 3 files changed, 3 insertions(+), 0 deletions(-)
516 $ cp -R .hg/store-copy/. .hg/store
516 $ cp -R .hg/store-copy/. .hg/store
517
517
518 Test files for a sub directory, including only a directory within it, and
518 Test files for a sub directory, including only a directory within it, and
519 including an unrelated directory.
519 including an unrelated directory.
520
520
521 $ rm -r .hg/store/meta/~2e_a
521 $ rm -r .hg/store/meta/~2e_a
522 $ rm -r .hg/store/meta/b/foo
522 $ rm -r .hg/store/meta/b/foo
523 $ hg files -r . -I path:b/bar/orange -I path:a b
523 $ hg files -r . -I path:b/bar/orange -I path:a b
524 b/bar/orange/fly/gnat.py
524 b/bar/orange/fly/gnat.py
525 b/bar/orange/fly/housefly.txt
525 b/bar/orange/fly/housefly.txt
526 $ hg diff -r '.^' -r . --stat -I path:b/bar/orange -I path:a b
526 $ hg diff -r '.^' -r . --stat -I path:b/bar/orange -I path:a b
527 b/bar/orange/fly/gnat.py | 1 +
527 b/bar/orange/fly/gnat.py | 1 +
528 b/bar/orange/fly/housefly.txt | 1 +
528 b/bar/orange/fly/housefly.txt | 1 +
529 2 files changed, 2 insertions(+), 0 deletions(-)
529 2 files changed, 2 insertions(+), 0 deletions(-)
530 $ cp -R .hg/store-copy/. .hg/store
530 $ cp -R .hg/store-copy/. .hg/store
531
531
532 Test files for a pattern, including a directory, and excluding a directory
532 Test files for a pattern, including a directory, and excluding a directory
533 within that.
533 within that.
534
534
535 $ rm -r .hg/store/meta/~2e_a
535 $ rm -r .hg/store/meta/~2e_a
536 $ rm -r .hg/store/meta/b/foo
536 $ rm -r .hg/store/meta/b/foo
537 $ rm -r .hg/store/meta/b/bar/orange
537 $ rm -r .hg/store/meta/b/bar/orange
538 $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
538 $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
539 b/bar/fruits.txt
539 b/bar/fruits.txt
540 $ hg diff -r '.^' -r . --stat glob:**.txt -I path:b/bar -X path:b/bar/orange
540 $ hg diff -r '.^' -r . --stat glob:**.txt -I path:b/bar -X path:b/bar/orange
541 b/bar/fruits.txt | 1 +
541 b/bar/fruits.txt | 1 +
542 1 files changed, 1 insertions(+), 0 deletions(-)
542 1 files changed, 1 insertions(+), 0 deletions(-)
543 $ cp -R .hg/store-copy/. .hg/store
543 $ cp -R .hg/store-copy/. .hg/store
544
544
545 Add some more changes to the deep repo
545 Add some more changes to the deep repo
546 $ echo narf >> b/bar/fruits.txt
546 $ echo narf >> b/bar/fruits.txt
547 $ hg ci -m narf
547 $ hg ci -m narf
548 $ echo troz >> b/bar/orange/fly/gnat.py
548 $ echo troz >> b/bar/orange/fly/gnat.py
549 $ hg ci -m troz
549 $ hg ci -m troz
550
550
551 Verify works
551 Verify works
552 $ hg verify
552 $ hg verify
553 checking changesets
553 checking changesets
554 checking manifests
554 checking manifests
555 checking directory manifests
555 checking directory manifests
556 crosschecking files in changesets and manifests
556 crosschecking files in changesets and manifests
557 checking files
557 checking files
558 8 files, 4 changesets, 18 total revisions
558 8 files, 4 changesets, 18 total revisions
559
559
560 Dirlogs are included in fncache
560 Dirlogs are included in fncache
561 $ grep meta/.A/00manifest.i .hg/store/fncache
561 $ grep meta/.A/00manifest.i .hg/store/fncache
562 meta/.A/00manifest.i
562 meta/.A/00manifest.i
563
563
564 Rebuilt fncache includes dirlogs
564 Rebuilt fncache includes dirlogs
565 $ rm .hg/store/fncache
565 $ rm .hg/store/fncache
566 $ hg debugrebuildfncache
566 $ hg debugrebuildfncache
567 adding data/.A/one.txt.i
567 adding data/.A/one.txt.i
568 adding data/.A/two.txt.i
568 adding data/.A/two.txt.i
569 adding data/b/bar/fruits.txt.i
569 adding data/b/bar/fruits.txt.i
570 adding data/b/bar/orange/fly/gnat.py.i
570 adding data/b/bar/orange/fly/gnat.py.i
571 adding data/b/bar/orange/fly/housefly.txt.i
571 adding data/b/bar/orange/fly/housefly.txt.i
572 adding data/b/foo/apple/bees/flower.py.i
572 adding data/b/foo/apple/bees/flower.py.i
573 adding data/c.txt.i
573 adding data/c.txt.i
574 adding data/d.py.i
574 adding data/d.py.i
575 adding meta/.A/00manifest.i
575 adding meta/.A/00manifest.i
576 adding meta/b/00manifest.i
576 adding meta/b/00manifest.i
577 adding meta/b/bar/00manifest.i
577 adding meta/b/bar/00manifest.i
578 adding meta/b/bar/orange/00manifest.i
578 adding meta/b/bar/orange/00manifest.i
579 adding meta/b/bar/orange/fly/00manifest.i
579 adding meta/b/bar/orange/fly/00manifest.i
580 adding meta/b/foo/00manifest.i
580 adding meta/b/foo/00manifest.i
581 adding meta/b/foo/apple/00manifest.i
581 adding meta/b/foo/apple/00manifest.i
582 adding meta/b/foo/apple/bees/00manifest.i
582 adding meta/b/foo/apple/bees/00manifest.i
583 16 items added, 0 removed from fncache
583 16 items added, 0 removed from fncache
584
584
585 Finish first server
585 Finish first server
586 $ killdaemons.py
586 $ killdaemons.py
587
587
588 Back up the recently added revlogs
588 Back up the recently added revlogs
589 $ cp -R .hg/store .hg/store-newcopy
589 $ cp -R .hg/store .hg/store-newcopy
590
590
591 Verify reports missing dirlog
591 Verify reports missing dirlog
592 $ rm .hg/store/meta/b/00manifest.*
592 $ rm .hg/store/meta/b/00manifest.*
593 $ hg verify
593 $ hg verify
594 checking changesets
594 checking changesets
595 checking manifests
595 checking manifests
596 checking directory manifests
596 checking directory manifests
597 0: empty or missing b/
597 0: empty or missing b/
598 b/@0: parent-directory manifest refers to unknown revision 67688a370455
598 b/@0: parent-directory manifest refers to unknown revision 67688a370455
599 b/@1: parent-directory manifest refers to unknown revision f065da70369e
599 b/@1: parent-directory manifest refers to unknown revision f065da70369e
600 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
600 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
601 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
601 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
602 warning: orphan revlog 'meta/b/bar/00manifest.i'
602 warning: orphan revlog 'meta/b/bar/00manifest.i'
603 warning: orphan revlog 'meta/b/bar/orange/00manifest.i'
603 warning: orphan revlog 'meta/b/bar/orange/00manifest.i'
604 warning: orphan revlog 'meta/b/bar/orange/fly/00manifest.i'
604 warning: orphan revlog 'meta/b/bar/orange/fly/00manifest.i'
605 warning: orphan revlog 'meta/b/foo/00manifest.i'
605 warning: orphan revlog 'meta/b/foo/00manifest.i'
606 warning: orphan revlog 'meta/b/foo/apple/00manifest.i'
606 warning: orphan revlog 'meta/b/foo/apple/00manifest.i'
607 warning: orphan revlog 'meta/b/foo/apple/bees/00manifest.i'
607 warning: orphan revlog 'meta/b/foo/apple/bees/00manifest.i'
608 crosschecking files in changesets and manifests
608 crosschecking files in changesets and manifests
609 b/bar/fruits.txt@0: in changeset but not in manifest
609 b/bar/fruits.txt@0: in changeset but not in manifest
610 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
610 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
611 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
611 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
612 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
612 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
613 checking files
613 checking files
614 8 files, 4 changesets, 18 total revisions
614 8 files, 4 changesets, 18 total revisions
615 6 warnings encountered!
615 6 warnings encountered!
616 9 integrity errors encountered!
616 9 integrity errors encountered!
617 (first damaged changeset appears to be 0)
617 (first damaged changeset appears to be 0)
618 [1]
618 [1]
619 $ cp -R .hg/store-newcopy/. .hg/store
619 $ cp -R .hg/store-newcopy/. .hg/store
620
620
621 Verify reports missing dirlog entry
621 Verify reports missing dirlog entry
622 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
622 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
623 $ hg verify
623 $ hg verify
624 checking changesets
624 checking changesets
625 checking manifests
625 checking manifests
626 checking directory manifests
626 checking directory manifests
627 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
627 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
628 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
628 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
629 b/bar/@?: rev 2 points to unexpected changeset 2
629 b/bar/@?: rev 2 points to unexpected changeset 2
630 b/bar/@?: 44d7e1146e0d not in parent-directory manifest
630 b/bar/@?: 44d7e1146e0d not in parent-directory manifest
631 b/bar/@?: rev 3 points to unexpected changeset 3
631 b/bar/@?: rev 3 points to unexpected changeset 3
632 b/bar/@?: 70b10c6b17b7 not in parent-directory manifest
632 b/bar/@?: 70b10c6b17b7 not in parent-directory manifest
633 b/bar/orange/@?: rev 2 points to unexpected changeset 3
633 b/bar/orange/@?: rev 2 points to unexpected changeset 3
634 (expected None)
634 (expected None)
635 b/bar/orange/fly/@?: rev 2 points to unexpected changeset 3
635 b/bar/orange/fly/@?: rev 2 points to unexpected changeset 3
636 (expected None)
636 (expected None)
637 crosschecking files in changesets and manifests
637 crosschecking files in changesets and manifests
638 checking files
638 checking files
639 8 files, 4 changesets, 18 total revisions
639 8 files, 4 changesets, 18 total revisions
640 2 warnings encountered!
640 2 warnings encountered!
641 8 integrity errors encountered!
641 8 integrity errors encountered!
642 (first damaged changeset appears to be 2)
642 (first damaged changeset appears to be 2)
643 [1]
643 [1]
644 $ cp -R .hg/store-newcopy/. .hg/store
644 $ cp -R .hg/store-newcopy/. .hg/store
645
645
646 Test cloning a treemanifest repo over http.
646 Test cloning a treemanifest repo over http.
647 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
647 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
648 $ cat hg.pid >> $DAEMON_PIDS
648 $ cat hg.pid >> $DAEMON_PIDS
649 $ cd ..
649 $ cd ..
650 We can clone even with the knob turned off and we'll get a treemanifest repo.
650 We can clone even with the knob turned off and we'll get a treemanifest repo.
651 $ hg clone --config experimental.treemanifest=False \
651 $ hg clone --config experimental.treemanifest=False \
652 > --config experimental.changegroup3=True \
652 > --config experimental.changegroup3=True \
653 > http://localhost:$HGPORT deepclone
653 > http://localhost:$HGPORT deepclone
654 requesting all changes
654 requesting all changes
655 adding changesets
655 adding changesets
656 adding manifests
656 adding manifests
657 adding file changes
657 adding file changes
658 added 4 changesets with 18 changes to 8 files
658 added 4 changesets with 18 changes to 8 files
659 new changesets 775704be6f52:523e5c631710
659 new changesets 775704be6f52:523e5c631710
660 updating to branch default
660 updating to branch default
661 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
661 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
662 No server errors.
662 No server errors.
663 $ cat deeprepo/errors.log
663 $ cat deeprepo/errors.log
664 requires got updated to include treemanifest
664 requires got updated to include treemanifest
665 $ cat deepclone/.hg/requires | grep treemanifest
665 $ cat deepclone/.hg/requires | grep treemanifest
666 treemanifest
666 treemanifest
667 Tree manifest revlogs exist.
667 Tree manifest revlogs exist.
668 $ find deepclone/.hg/store/meta | sort
668 $ find deepclone/.hg/store/meta | sort
669 deepclone/.hg/store/meta
669 deepclone/.hg/store/meta
670 deepclone/.hg/store/meta/b
670 deepclone/.hg/store/meta/b
671 deepclone/.hg/store/meta/b/00manifest.i
671 deepclone/.hg/store/meta/b/00manifest.i
672 deepclone/.hg/store/meta/b/bar
672 deepclone/.hg/store/meta/b/bar
673 deepclone/.hg/store/meta/b/bar/00manifest.i
673 deepclone/.hg/store/meta/b/bar/00manifest.i
674 deepclone/.hg/store/meta/b/bar/orange
674 deepclone/.hg/store/meta/b/bar/orange
675 deepclone/.hg/store/meta/b/bar/orange/00manifest.i
675 deepclone/.hg/store/meta/b/bar/orange/00manifest.i
676 deepclone/.hg/store/meta/b/bar/orange/fly
676 deepclone/.hg/store/meta/b/bar/orange/fly
677 deepclone/.hg/store/meta/b/bar/orange/fly/00manifest.i
677 deepclone/.hg/store/meta/b/bar/orange/fly/00manifest.i
678 deepclone/.hg/store/meta/b/foo
678 deepclone/.hg/store/meta/b/foo
679 deepclone/.hg/store/meta/b/foo/00manifest.i
679 deepclone/.hg/store/meta/b/foo/00manifest.i
680 deepclone/.hg/store/meta/b/foo/apple
680 deepclone/.hg/store/meta/b/foo/apple
681 deepclone/.hg/store/meta/b/foo/apple/00manifest.i
681 deepclone/.hg/store/meta/b/foo/apple/00manifest.i
682 deepclone/.hg/store/meta/b/foo/apple/bees
682 deepclone/.hg/store/meta/b/foo/apple/bees
683 deepclone/.hg/store/meta/b/foo/apple/bees/00manifest.i
683 deepclone/.hg/store/meta/b/foo/apple/bees/00manifest.i
684 deepclone/.hg/store/meta/~2e_a
684 deepclone/.hg/store/meta/~2e_a
685 deepclone/.hg/store/meta/~2e_a/00manifest.i
685 deepclone/.hg/store/meta/~2e_a/00manifest.i
686 Verify passes.
686 Verify passes.
687 $ cd deepclone
687 $ cd deepclone
688 $ hg verify
688 $ hg verify
689 checking changesets
689 checking changesets
690 checking manifests
690 checking manifests
691 checking directory manifests
691 checking directory manifests
692 crosschecking files in changesets and manifests
692 crosschecking files in changesets and manifests
693 checking files
693 checking files
694 8 files, 4 changesets, 18 total revisions
694 8 files, 4 changesets, 18 total revisions
695 $ cd ..
695 $ cd ..
696
696
697 Create clones using old repo formats to use in later tests
697 Create clones using old repo formats to use in later tests
698 $ hg clone --config format.usestore=False \
698 $ hg clone --config format.usestore=False \
699 > --config experimental.changegroup3=True \
699 > --config experimental.changegroup3=True \
700 > http://localhost:$HGPORT deeprepo-basicstore
700 > http://localhost:$HGPORT deeprepo-basicstore
701 requesting all changes
701 requesting all changes
702 adding changesets
702 adding changesets
703 adding manifests
703 adding manifests
704 adding file changes
704 adding file changes
705 added 4 changesets with 18 changes to 8 files
705 added 4 changesets with 18 changes to 8 files
706 new changesets 775704be6f52:523e5c631710
706 new changesets 775704be6f52:523e5c631710
707 updating to branch default
707 updating to branch default
708 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
708 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
709 $ cd deeprepo-basicstore
709 $ cd deeprepo-basicstore
710 $ grep store .hg/requires
710 $ grep store .hg/requires
711 [1]
711 [1]
712 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --errorlog=errors.log
712 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --errorlog=errors.log
713 $ cat hg.pid >> $DAEMON_PIDS
713 $ cat hg.pid >> $DAEMON_PIDS
714 $ cd ..
714 $ cd ..
715 $ hg clone --config format.usefncache=False \
715 $ hg clone --config format.usefncache=False \
716 > --config experimental.changegroup3=True \
716 > --config experimental.changegroup3=True \
717 > http://localhost:$HGPORT deeprepo-encodedstore
717 > http://localhost:$HGPORT deeprepo-encodedstore
718 requesting all changes
718 requesting all changes
719 adding changesets
719 adding changesets
720 adding manifests
720 adding manifests
721 adding file changes
721 adding file changes
722 added 4 changesets with 18 changes to 8 files
722 added 4 changesets with 18 changes to 8 files
723 new changesets 775704be6f52:523e5c631710
723 new changesets 775704be6f52:523e5c631710
724 updating to branch default
724 updating to branch default
725 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
725 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 $ cd deeprepo-encodedstore
726 $ cd deeprepo-encodedstore
727 $ grep fncache .hg/requires
727 $ grep fncache .hg/requires
728 [1]
728 [1]
729 $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log
729 $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log
730 $ cat hg.pid >> $DAEMON_PIDS
730 $ cat hg.pid >> $DAEMON_PIDS
731 $ cd ..
731 $ cd ..
732
732
733 Local clone with basicstore
733 Local clone with basicstore
734 $ hg clone -U deeprepo-basicstore local-clone-basicstore
734 $ hg clone -U deeprepo-basicstore local-clone-basicstore
735 $ hg -R local-clone-basicstore verify
735 $ hg -R local-clone-basicstore verify
736 checking changesets
736 checking changesets
737 checking manifests
737 checking manifests
738 checking directory manifests
738 checking directory manifests
739 crosschecking files in changesets and manifests
739 crosschecking files in changesets and manifests
740 checking files
740 checking files
741 8 files, 4 changesets, 18 total revisions
741 8 files, 4 changesets, 18 total revisions
742
742
743 Local clone with encodedstore
743 Local clone with encodedstore
744 $ hg clone -U deeprepo-encodedstore local-clone-encodedstore
744 $ hg clone -U deeprepo-encodedstore local-clone-encodedstore
745 $ hg -R local-clone-encodedstore verify
745 $ hg -R local-clone-encodedstore verify
746 checking changesets
746 checking changesets
747 checking manifests
747 checking manifests
748 checking directory manifests
748 checking directory manifests
749 crosschecking files in changesets and manifests
749 crosschecking files in changesets and manifests
750 checking files
750 checking files
751 8 files, 4 changesets, 18 total revisions
751 8 files, 4 changesets, 18 total revisions
752
752
753 Local clone with fncachestore
753 Local clone with fncachestore
754 $ hg clone -U deeprepo local-clone-fncachestore
754 $ hg clone -U deeprepo local-clone-fncachestore
755 $ hg -R local-clone-fncachestore verify
755 $ hg -R local-clone-fncachestore verify
756 checking changesets
756 checking changesets
757 checking manifests
757 checking manifests
758 checking directory manifests
758 checking directory manifests
759 crosschecking files in changesets and manifests
759 crosschecking files in changesets and manifests
760 checking files
760 checking files
761 8 files, 4 changesets, 18 total revisions
761 8 files, 4 changesets, 18 total revisions
762
762
763 Stream clone with basicstore
763 Stream clone with basicstore
764 $ hg clone --config experimental.changegroup3=True --stream -U \
764 $ hg clone --config experimental.changegroup3=True --stream -U \
765 > http://localhost:$HGPORT1 stream-clone-basicstore
765 > http://localhost:$HGPORT1 stream-clone-basicstore
766 streaming all changes
766 streaming all changes
767 18 files to transfer, * of data (glob)
767 18 files to transfer, * of data (glob)
768 transferred * in * seconds (*) (glob)
768 transferred * in * seconds (*) (glob)
769 searching for changes
769 searching for changes
770 no changes found
770 no changes found
771 $ hg -R stream-clone-basicstore verify
771 $ hg -R stream-clone-basicstore verify
772 checking changesets
772 checking changesets
773 checking manifests
773 checking manifests
774 checking directory manifests
774 checking directory manifests
775 crosschecking files in changesets and manifests
775 crosschecking files in changesets and manifests
776 checking files
776 checking files
777 8 files, 4 changesets, 18 total revisions
777 8 files, 4 changesets, 18 total revisions
778
778
779 Stream clone with encodedstore
779 Stream clone with encodedstore
780 $ hg clone --config experimental.changegroup3=True --stream -U \
780 $ hg clone --config experimental.changegroup3=True --stream -U \
781 > http://localhost:$HGPORT2 stream-clone-encodedstore
781 > http://localhost:$HGPORT2 stream-clone-encodedstore
782 streaming all changes
782 streaming all changes
783 18 files to transfer, * of data (glob)
783 18 files to transfer, * of data (glob)
784 transferred * in * seconds (*) (glob)
784 transferred * in * seconds (*) (glob)
785 searching for changes
785 searching for changes
786 no changes found
786 no changes found
787 $ hg -R stream-clone-encodedstore verify
787 $ hg -R stream-clone-encodedstore verify
788 checking changesets
788 checking changesets
789 checking manifests
789 checking manifests
790 checking directory manifests
790 checking directory manifests
791 crosschecking files in changesets and manifests
791 crosschecking files in changesets and manifests
792 checking files
792 checking files
793 8 files, 4 changesets, 18 total revisions
793 8 files, 4 changesets, 18 total revisions
794
794
795 Stream clone with fncachestore
795 Stream clone with fncachestore
796 $ hg clone --config experimental.changegroup3=True --stream -U \
796 $ hg clone --config experimental.changegroup3=True --stream -U \
797 > http://localhost:$HGPORT stream-clone-fncachestore
797 > http://localhost:$HGPORT stream-clone-fncachestore
798 streaming all changes
798 streaming all changes
799 18 files to transfer, * of data (glob)
799 18 files to transfer, * of data (glob)
800 transferred * in * seconds (*) (glob)
800 transferred * in * seconds (*) (glob)
801 searching for changes
801 searching for changes
802 no changes found
802 no changes found
803 $ hg -R stream-clone-fncachestore verify
803 $ hg -R stream-clone-fncachestore verify
804 checking changesets
804 checking changesets
805 checking manifests
805 checking manifests
806 checking directory manifests
806 checking directory manifests
807 crosschecking files in changesets and manifests
807 crosschecking files in changesets and manifests
808 checking files
808 checking files
809 8 files, 4 changesets, 18 total revisions
809 8 files, 4 changesets, 18 total revisions
810
810
811 Packed bundle
811 Packed bundle
812 $ hg -R deeprepo debugcreatestreamclonebundle repo-packed.hg
812 $ hg -R deeprepo debugcreatestreamclonebundle repo-packed.hg
813 writing 5330 bytes for 18 files
813 writing 5330 bytes for 18 files
814 bundle requirements: generaldelta, revlogv1, treemanifest
814 bundle requirements: generaldelta, revlogv1, treemanifest
815 $ hg debugbundle --spec repo-packed.hg
815 $ hg debugbundle --spec repo-packed.hg
816 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1%2Ctreemanifest
816 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1%2Ctreemanifest
817
817
818 Bundle with changegroup2 is not supported
818 Bundle with changegroup2 is not supported
819
819
820 $ hg -R deeprepo bundle --all -t v2 deeprepo.bundle
820 $ hg -R deeprepo bundle --all -t v2 deeprepo.bundle
821 abort: repository does not support bundle version 02
821 abort: repository does not support bundle version 02
822 [255]
822 [255]
823
823
824 Pull does not include changegroup for manifest the client already has from
824 Pull does not include changegroup for manifest the client already has from
825 other branch
825 other branch
826
826
827 $ mkdir grafted-dir-repo
827 $ mkdir grafted-dir-repo
828 $ cd grafted-dir-repo
828 $ cd grafted-dir-repo
829 $ hg --config experimental.treemanifest=1 init
829 $ hg --config experimental.treemanifest=1 init
830 $ mkdir dir
830 $ mkdir dir
831 $ echo a > dir/file
831 $ echo a > dir/file
832 $ echo a > file
832 $ echo a > file
833 $ hg ci -Am initial
833 $ hg ci -Am initial
834 adding dir/file
834 adding dir/file
835 adding file
835 adding file
836 $ echo b > dir/file
836 $ echo b > dir/file
837 $ hg ci -m updated
837 $ hg ci -m updated
838 $ hg co '.^'
838 $ hg co '.^'
839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 $ hg revert -r tip dir/
840 $ hg revert -r tip dir/
841 reverting dir/file
841 reverting dir/file
842 $ echo b > file # to make sure root manifest is sent
842 $ echo b > file # to make sure root manifest is sent
843 $ hg ci -m grafted
843 $ hg ci -m grafted
844 created new head
844 created new head
845 $ cd ..
845 $ cd ..
846
846
847 $ hg --config experimental.treemanifest=1 clone --pull -r 1 \
847 $ hg --config experimental.treemanifest=1 clone --pull -r 1 \
848 > grafted-dir-repo grafted-dir-repo-clone
848 > grafted-dir-repo grafted-dir-repo-clone
849 adding changesets
849 adding changesets
850 adding manifests
850 adding manifests
851 adding file changes
851 adding file changes
852 added 2 changesets with 3 changes to 2 files
852 added 2 changesets with 3 changes to 2 files
853 new changesets d84f4c419457:09ab742f3b0f
853 new changesets d84f4c419457:09ab742f3b0f
854 updating to branch default
854 updating to branch default
855 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
855 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
856 $ cd grafted-dir-repo-clone
856 $ cd grafted-dir-repo-clone
857 $ hg pull -r 2
857 $ hg pull -r 2
858 pulling from $TESTTMP/grafted-dir-repo
858 pulling from $TESTTMP/grafted-dir-repo
859 searching for changes
859 searching for changes
860 adding changesets
860 adding changesets
861 adding manifests
861 adding manifests
862 adding file changes
862 adding file changes
863 added 1 changesets with 1 changes to 1 files (+1 heads)
863 added 1 changesets with 1 changes to 1 files (+1 heads)
864 new changesets 73699489fb7c
864 new changesets 73699489fb7c
865 (run 'hg heads' to see heads, 'hg merge' to merge)
865 (run 'hg heads' to see heads, 'hg merge' to merge)
866
866
867 Committing a empty commit does not duplicate root treemanifest
867 Committing a empty commit does not duplicate root treemanifest
868 $ echo z >> z
868 $ echo z >> z
869 $ hg commit -Aqm 'pre-empty commit'
869 $ hg commit -Aqm 'pre-empty commit'
870 $ hg rm z
870 $ hg rm z
871 $ hg commit --amend -m 'empty commit'
871 $ hg commit --amend -m 'empty commit'
872 saved backup bundle to $TESTTMP/grafted-dir-repo-clone/.hg/strip-backup/cb99d5717cea-9e3b6b02-amend.hg
872 saved backup bundle to $TESTTMP/grafted-dir-repo-clone/.hg/strip-backup/cb99d5717cea-9e3b6b02-amend.hg
873 $ hg log -r 'tip + tip^' -T '{manifest}\n'
873 $ hg log -r 'tip + tip^' -T '{manifest}\n'
874 1:678d3574b88c
874 1:678d3574b88c
875 1:678d3574b88c
875 1:678d3574b88c
876 $ hg --config extensions.strip= strip -r . -q
876 $ hg --config extensions.strip= strip -r . -q
General Comments 0
You need to be logged in to leave comments. Login now