##// END OF EJS Templates
debugcommands: drop base revision from debugindex...
Gregory Szorc -
r37300:009d0283 default
parent child Browse files
Show More
@@ -1,3067 +1,3056 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 generaldelta = r.version & revlog.FLAG_GENERALDELTA
1063 if generaldelta:
1064 basehdr = ' delta'
1065 else:
1066 basehdr = ' base'
1067
1068 if ui.debugflag:
1062 if ui.debugflag:
1069 shortfn = hex
1063 shortfn = hex
1070 else:
1064 else:
1071 shortfn = short
1065 shortfn = short
1072
1066
1073 # 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
1074 idlen = 12
1068 idlen = 12
1075 for i in r:
1069 for i in r:
1076 idlen = len(shortfn(r.node(i)))
1070 idlen = len(shortfn(r.node(i)))
1077 break
1071 break
1078
1072
1079 if format == 0:
1073 if format == 0:
1080 ui.write((" rev offset length " + basehdr + " linkrev"
1074 ui.write((" rev offset length linkrev"
1081 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
1075 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
1082 elif format == 1:
1076 elif format == 1:
1083 ui.write((" rev flag offset length"
1077 ui.write((" rev flag offset length size link p1 p2"
1084 " size " + basehdr + " link p1 p2"
1085 " %s\n") % "nodeid".rjust(idlen))
1078 " %s\n") % "nodeid".rjust(idlen))
1086
1079
1087 for i in r:
1080 for i in r:
1088 node = r.node(i)
1081 node = r.node(i)
1089 if generaldelta:
1090 base = r.deltaparent(i)
1091 else:
1092 base = r.chainbase(i)
1093 if format == 0:
1082 if format == 0:
1094 try:
1083 try:
1095 pp = r.parents(node)
1084 pp = r.parents(node)
1096 except Exception:
1085 except Exception:
1097 pp = [nullid, nullid]
1086 pp = [nullid, nullid]
1098 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1087 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
1099 i, r.start(i), r.length(i), base, r.linkrev(i),
1088 i, r.start(i), r.length(i), r.linkrev(i),
1100 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1089 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1101 elif format == 1:
1090 elif format == 1:
1102 pr = r.parentrevs(i)
1091 pr = r.parentrevs(i)
1103 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1092 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
1104 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1093 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1105 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
1094 r.linkrev(i), pr[0], pr[1], shortfn(node)))
1106
1095
1107 @command('debugindexdot', cmdutil.debugrevlogopts,
1096 @command('debugindexdot', cmdutil.debugrevlogopts,
1108 _('-c|-m|FILE'), optionalrepo=True)
1097 _('-c|-m|FILE'), optionalrepo=True)
1109 def debugindexdot(ui, repo, file_=None, **opts):
1098 def debugindexdot(ui, repo, file_=None, **opts):
1110 """dump an index DAG as a graphviz dot file"""
1099 """dump an index DAG as a graphviz dot file"""
1111 opts = pycompat.byteskwargs(opts)
1100 opts = pycompat.byteskwargs(opts)
1112 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1101 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1113 ui.write(("digraph G {\n"))
1102 ui.write(("digraph G {\n"))
1114 for i in r:
1103 for i in r:
1115 node = r.node(i)
1104 node = r.node(i)
1116 pp = r.parents(node)
1105 pp = r.parents(node)
1117 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1106 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1118 if pp[1] != nullid:
1107 if pp[1] != nullid:
1119 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1108 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1120 ui.write("}\n")
1109 ui.write("}\n")
1121
1110
1122 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1111 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1123 def debuginstall(ui, **opts):
1112 def debuginstall(ui, **opts):
1124 '''test Mercurial installation
1113 '''test Mercurial installation
1125
1114
1126 Returns 0 on success.
1115 Returns 0 on success.
1127 '''
1116 '''
1128 opts = pycompat.byteskwargs(opts)
1117 opts = pycompat.byteskwargs(opts)
1129
1118
1130 def writetemp(contents):
1119 def writetemp(contents):
1131 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1120 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1132 f = os.fdopen(fd, r"wb")
1121 f = os.fdopen(fd, r"wb")
1133 f.write(contents)
1122 f.write(contents)
1134 f.close()
1123 f.close()
1135 return name
1124 return name
1136
1125
1137 problems = 0
1126 problems = 0
1138
1127
1139 fm = ui.formatter('debuginstall', opts)
1128 fm = ui.formatter('debuginstall', opts)
1140 fm.startitem()
1129 fm.startitem()
1141
1130
1142 # encoding
1131 # encoding
1143 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1132 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1144 err = None
1133 err = None
1145 try:
1134 try:
1146 codecs.lookup(pycompat.sysstr(encoding.encoding))
1135 codecs.lookup(pycompat.sysstr(encoding.encoding))
1147 except LookupError as inst:
1136 except LookupError as inst:
1148 err = stringutil.forcebytestr(inst)
1137 err = stringutil.forcebytestr(inst)
1149 problems += 1
1138 problems += 1
1150 fm.condwrite(err, 'encodingerror', _(" %s\n"
1139 fm.condwrite(err, 'encodingerror', _(" %s\n"
1151 " (check that your locale is properly set)\n"), err)
1140 " (check that your locale is properly set)\n"), err)
1152
1141
1153 # Python
1142 # Python
1154 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1143 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1155 pycompat.sysexecutable)
1144 pycompat.sysexecutable)
1156 fm.write('pythonver', _("checking Python version (%s)\n"),
1145 fm.write('pythonver', _("checking Python version (%s)\n"),
1157 ("%d.%d.%d" % sys.version_info[:3]))
1146 ("%d.%d.%d" % sys.version_info[:3]))
1158 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1147 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1159 os.path.dirname(pycompat.fsencode(os.__file__)))
1148 os.path.dirname(pycompat.fsencode(os.__file__)))
1160
1149
1161 security = set(sslutil.supportedprotocols)
1150 security = set(sslutil.supportedprotocols)
1162 if sslutil.hassni:
1151 if sslutil.hassni:
1163 security.add('sni')
1152 security.add('sni')
1164
1153
1165 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1154 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1166 fm.formatlist(sorted(security), name='protocol',
1155 fm.formatlist(sorted(security), name='protocol',
1167 fmt='%s', sep=','))
1156 fmt='%s', sep=','))
1168
1157
1169 # These are warnings, not errors. So don't increment problem count. This
1158 # These are warnings, not errors. So don't increment problem count. This
1170 # may change in the future.
1159 # may change in the future.
1171 if 'tls1.2' not in security:
1160 if 'tls1.2' not in security:
1172 fm.plain(_(' TLS 1.2 not supported by Python install; '
1161 fm.plain(_(' TLS 1.2 not supported by Python install; '
1173 'network connections lack modern security\n'))
1162 'network connections lack modern security\n'))
1174 if 'sni' not in security:
1163 if 'sni' not in security:
1175 fm.plain(_(' SNI not supported by Python install; may have '
1164 fm.plain(_(' SNI not supported by Python install; may have '
1176 'connectivity issues with some servers\n'))
1165 'connectivity issues with some servers\n'))
1177
1166
1178 # TODO print CA cert info
1167 # TODO print CA cert info
1179
1168
1180 # hg version
1169 # hg version
1181 hgver = util.version()
1170 hgver = util.version()
1182 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1171 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1183 hgver.split('+')[0])
1172 hgver.split('+')[0])
1184 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1173 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1185 '+'.join(hgver.split('+')[1:]))
1174 '+'.join(hgver.split('+')[1:]))
1186
1175
1187 # compiled modules
1176 # compiled modules
1188 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1177 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1189 policy.policy)
1178 policy.policy)
1190 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1179 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1191 os.path.dirname(pycompat.fsencode(__file__)))
1180 os.path.dirname(pycompat.fsencode(__file__)))
1192
1181
1193 if policy.policy in ('c', 'allow'):
1182 if policy.policy in ('c', 'allow'):
1194 err = None
1183 err = None
1195 try:
1184 try:
1196 from .cext import (
1185 from .cext import (
1197 base85,
1186 base85,
1198 bdiff,
1187 bdiff,
1199 mpatch,
1188 mpatch,
1200 osutil,
1189 osutil,
1201 )
1190 )
1202 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1191 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1203 except Exception as inst:
1192 except Exception as inst:
1204 err = stringutil.forcebytestr(inst)
1193 err = stringutil.forcebytestr(inst)
1205 problems += 1
1194 problems += 1
1206 fm.condwrite(err, 'extensionserror', " %s\n", err)
1195 fm.condwrite(err, 'extensionserror', " %s\n", err)
1207
1196
1208 compengines = util.compengines._engines.values()
1197 compengines = util.compengines._engines.values()
1209 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1198 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1210 fm.formatlist(sorted(e.name() for e in compengines),
1199 fm.formatlist(sorted(e.name() for e in compengines),
1211 name='compengine', fmt='%s', sep=', '))
1200 name='compengine', fmt='%s', sep=', '))
1212 fm.write('compenginesavail', _('checking available compression engines '
1201 fm.write('compenginesavail', _('checking available compression engines '
1213 '(%s)\n'),
1202 '(%s)\n'),
1214 fm.formatlist(sorted(e.name() for e in compengines
1203 fm.formatlist(sorted(e.name() for e in compengines
1215 if e.available()),
1204 if e.available()),
1216 name='compengine', fmt='%s', sep=', '))
1205 name='compengine', fmt='%s', sep=', '))
1217 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1206 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1218 fm.write('compenginesserver', _('checking available compression engines '
1207 fm.write('compenginesserver', _('checking available compression engines '
1219 'for wire protocol (%s)\n'),
1208 'for wire protocol (%s)\n'),
1220 fm.formatlist([e.name() for e in wirecompengines
1209 fm.formatlist([e.name() for e in wirecompengines
1221 if e.wireprotosupport()],
1210 if e.wireprotosupport()],
1222 name='compengine', fmt='%s', sep=', '))
1211 name='compengine', fmt='%s', sep=', '))
1223 re2 = 'missing'
1212 re2 = 'missing'
1224 if util._re2:
1213 if util._re2:
1225 re2 = 'available'
1214 re2 = 'available'
1226 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1215 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1227 fm.data(re2=bool(util._re2))
1216 fm.data(re2=bool(util._re2))
1228
1217
1229 # templates
1218 # templates
1230 p = templater.templatepaths()
1219 p = templater.templatepaths()
1231 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1220 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1232 fm.condwrite(not p, '', _(" no template directories found\n"))
1221 fm.condwrite(not p, '', _(" no template directories found\n"))
1233 if p:
1222 if p:
1234 m = templater.templatepath("map-cmdline.default")
1223 m = templater.templatepath("map-cmdline.default")
1235 if m:
1224 if m:
1236 # template found, check if it is working
1225 # template found, check if it is working
1237 err = None
1226 err = None
1238 try:
1227 try:
1239 templater.templater.frommapfile(m)
1228 templater.templater.frommapfile(m)
1240 except Exception as inst:
1229 except Exception as inst:
1241 err = stringutil.forcebytestr(inst)
1230 err = stringutil.forcebytestr(inst)
1242 p = None
1231 p = None
1243 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1232 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1244 else:
1233 else:
1245 p = None
1234 p = None
1246 fm.condwrite(p, 'defaulttemplate',
1235 fm.condwrite(p, 'defaulttemplate',
1247 _("checking default template (%s)\n"), m)
1236 _("checking default template (%s)\n"), m)
1248 fm.condwrite(not m, 'defaulttemplatenotfound',
1237 fm.condwrite(not m, 'defaulttemplatenotfound',
1249 _(" template '%s' not found\n"), "default")
1238 _(" template '%s' not found\n"), "default")
1250 if not p:
1239 if not p:
1251 problems += 1
1240 problems += 1
1252 fm.condwrite(not p, '',
1241 fm.condwrite(not p, '',
1253 _(" (templates seem to have been installed incorrectly)\n"))
1242 _(" (templates seem to have been installed incorrectly)\n"))
1254
1243
1255 # editor
1244 # editor
1256 editor = ui.geteditor()
1245 editor = ui.geteditor()
1257 editor = util.expandpath(editor)
1246 editor = util.expandpath(editor)
1258 editorbin = procutil.shellsplit(editor)[0]
1247 editorbin = procutil.shellsplit(editor)[0]
1259 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1248 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1260 cmdpath = procutil.findexe(editorbin)
1249 cmdpath = procutil.findexe(editorbin)
1261 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1250 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1262 _(" No commit editor set and can't find %s in PATH\n"
1251 _(" No commit editor set and can't find %s in PATH\n"
1263 " (specify a commit editor in your configuration"
1252 " (specify a commit editor in your configuration"
1264 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1253 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1265 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1254 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1266 _(" Can't find editor '%s' in PATH\n"
1255 _(" Can't find editor '%s' in PATH\n"
1267 " (specify a commit editor in your configuration"
1256 " (specify a commit editor in your configuration"
1268 " file)\n"), not cmdpath and editorbin)
1257 " file)\n"), not cmdpath and editorbin)
1269 if not cmdpath and editor != 'vi':
1258 if not cmdpath and editor != 'vi':
1270 problems += 1
1259 problems += 1
1271
1260
1272 # check username
1261 # check username
1273 username = None
1262 username = None
1274 err = None
1263 err = None
1275 try:
1264 try:
1276 username = ui.username()
1265 username = ui.username()
1277 except error.Abort as e:
1266 except error.Abort as e:
1278 err = stringutil.forcebytestr(e)
1267 err = stringutil.forcebytestr(e)
1279 problems += 1
1268 problems += 1
1280
1269
1281 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1270 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1282 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1271 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1283 " (specify a username in your configuration file)\n"), err)
1272 " (specify a username in your configuration file)\n"), err)
1284
1273
1285 fm.condwrite(not problems, '',
1274 fm.condwrite(not problems, '',
1286 _("no problems detected\n"))
1275 _("no problems detected\n"))
1287 if not problems:
1276 if not problems:
1288 fm.data(problems=problems)
1277 fm.data(problems=problems)
1289 fm.condwrite(problems, 'problems',
1278 fm.condwrite(problems, 'problems',
1290 _("%d problems detected,"
1279 _("%d problems detected,"
1291 " please check your install!\n"), problems)
1280 " please check your install!\n"), problems)
1292 fm.end()
1281 fm.end()
1293
1282
1294 return problems
1283 return problems
1295
1284
1296 @command('debugknown', [], _('REPO ID...'), norepo=True)
1285 @command('debugknown', [], _('REPO ID...'), norepo=True)
1297 def debugknown(ui, repopath, *ids, **opts):
1286 def debugknown(ui, repopath, *ids, **opts):
1298 """test whether node ids are known to a repo
1287 """test whether node ids are known to a repo
1299
1288
1300 Every ID must be a full-length hex node id string. Returns a list of 0s
1289 Every ID must be a full-length hex node id string. Returns a list of 0s
1301 and 1s indicating unknown/known.
1290 and 1s indicating unknown/known.
1302 """
1291 """
1303 opts = pycompat.byteskwargs(opts)
1292 opts = pycompat.byteskwargs(opts)
1304 repo = hg.peer(ui, opts, repopath)
1293 repo = hg.peer(ui, opts, repopath)
1305 if not repo.capable('known'):
1294 if not repo.capable('known'):
1306 raise error.Abort("known() not supported by target repository")
1295 raise error.Abort("known() not supported by target repository")
1307 flags = repo.known([bin(s) for s in ids])
1296 flags = repo.known([bin(s) for s in ids])
1308 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1297 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1309
1298
1310 @command('debuglabelcomplete', [], _('LABEL...'))
1299 @command('debuglabelcomplete', [], _('LABEL...'))
1311 def debuglabelcomplete(ui, repo, *args):
1300 def debuglabelcomplete(ui, repo, *args):
1312 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1301 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1313 debugnamecomplete(ui, repo, *args)
1302 debugnamecomplete(ui, repo, *args)
1314
1303
1315 @command('debuglocks',
1304 @command('debuglocks',
1316 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1305 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1317 ('W', 'force-wlock', None,
1306 ('W', 'force-wlock', None,
1318 _('free the working state lock (DANGEROUS)')),
1307 _('free the working state lock (DANGEROUS)')),
1319 ('s', 'set-lock', None, _('set the store lock until stopped')),
1308 ('s', 'set-lock', None, _('set the store lock until stopped')),
1320 ('S', 'set-wlock', None,
1309 ('S', 'set-wlock', None,
1321 _('set the working state lock until stopped'))],
1310 _('set the working state lock until stopped'))],
1322 _('[OPTION]...'))
1311 _('[OPTION]...'))
1323 def debuglocks(ui, repo, **opts):
1312 def debuglocks(ui, repo, **opts):
1324 """show or modify state of locks
1313 """show or modify state of locks
1325
1314
1326 By default, this command will show which locks are held. This
1315 By default, this command will show which locks are held. This
1327 includes the user and process holding the lock, the amount of time
1316 includes the user and process holding the lock, the amount of time
1328 the lock has been held, and the machine name where the process is
1317 the lock has been held, and the machine name where the process is
1329 running if it's not local.
1318 running if it's not local.
1330
1319
1331 Locks protect the integrity of Mercurial's data, so should be
1320 Locks protect the integrity of Mercurial's data, so should be
1332 treated with care. System crashes or other interruptions may cause
1321 treated with care. System crashes or other interruptions may cause
1333 locks to not be properly released, though Mercurial will usually
1322 locks to not be properly released, though Mercurial will usually
1334 detect and remove such stale locks automatically.
1323 detect and remove such stale locks automatically.
1335
1324
1336 However, detecting stale locks may not always be possible (for
1325 However, detecting stale locks may not always be possible (for
1337 instance, on a shared filesystem). Removing locks may also be
1326 instance, on a shared filesystem). Removing locks may also be
1338 blocked by filesystem permissions.
1327 blocked by filesystem permissions.
1339
1328
1340 Setting a lock will prevent other commands from changing the data.
1329 Setting a lock will prevent other commands from changing the data.
1341 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1330 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1342 The set locks are removed when the command exits.
1331 The set locks are removed when the command exits.
1343
1332
1344 Returns 0 if no locks are held.
1333 Returns 0 if no locks are held.
1345
1334
1346 """
1335 """
1347
1336
1348 if opts.get(r'force_lock'):
1337 if opts.get(r'force_lock'):
1349 repo.svfs.unlink('lock')
1338 repo.svfs.unlink('lock')
1350 if opts.get(r'force_wlock'):
1339 if opts.get(r'force_wlock'):
1351 repo.vfs.unlink('wlock')
1340 repo.vfs.unlink('wlock')
1352 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1341 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1353 return 0
1342 return 0
1354
1343
1355 locks = []
1344 locks = []
1356 try:
1345 try:
1357 if opts.get(r'set_wlock'):
1346 if opts.get(r'set_wlock'):
1358 try:
1347 try:
1359 locks.append(repo.wlock(False))
1348 locks.append(repo.wlock(False))
1360 except error.LockHeld:
1349 except error.LockHeld:
1361 raise error.Abort(_('wlock is already held'))
1350 raise error.Abort(_('wlock is already held'))
1362 if opts.get(r'set_lock'):
1351 if opts.get(r'set_lock'):
1363 try:
1352 try:
1364 locks.append(repo.lock(False))
1353 locks.append(repo.lock(False))
1365 except error.LockHeld:
1354 except error.LockHeld:
1366 raise error.Abort(_('lock is already held'))
1355 raise error.Abort(_('lock is already held'))
1367 if len(locks):
1356 if len(locks):
1368 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1357 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1369 return 0
1358 return 0
1370 finally:
1359 finally:
1371 release(*locks)
1360 release(*locks)
1372
1361
1373 now = time.time()
1362 now = time.time()
1374 held = 0
1363 held = 0
1375
1364
1376 def report(vfs, name, method):
1365 def report(vfs, name, method):
1377 # this causes stale locks to get reaped for more accurate reporting
1366 # this causes stale locks to get reaped for more accurate reporting
1378 try:
1367 try:
1379 l = method(False)
1368 l = method(False)
1380 except error.LockHeld:
1369 except error.LockHeld:
1381 l = None
1370 l = None
1382
1371
1383 if l:
1372 if l:
1384 l.release()
1373 l.release()
1385 else:
1374 else:
1386 try:
1375 try:
1387 st = vfs.lstat(name)
1376 st = vfs.lstat(name)
1388 age = now - st[stat.ST_MTIME]
1377 age = now - st[stat.ST_MTIME]
1389 user = util.username(st.st_uid)
1378 user = util.username(st.st_uid)
1390 locker = vfs.readlock(name)
1379 locker = vfs.readlock(name)
1391 if ":" in locker:
1380 if ":" in locker:
1392 host, pid = locker.split(':')
1381 host, pid = locker.split(':')
1393 if host == socket.gethostname():
1382 if host == socket.gethostname():
1394 locker = 'user %s, process %s' % (user, pid)
1383 locker = 'user %s, process %s' % (user, pid)
1395 else:
1384 else:
1396 locker = 'user %s, process %s, host %s' \
1385 locker = 'user %s, process %s, host %s' \
1397 % (user, pid, host)
1386 % (user, pid, host)
1398 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1387 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1399 return 1
1388 return 1
1400 except OSError as e:
1389 except OSError as e:
1401 if e.errno != errno.ENOENT:
1390 if e.errno != errno.ENOENT:
1402 raise
1391 raise
1403
1392
1404 ui.write(("%-6s free\n") % (name + ":"))
1393 ui.write(("%-6s free\n") % (name + ":"))
1405 return 0
1394 return 0
1406
1395
1407 held += report(repo.svfs, "lock", repo.lock)
1396 held += report(repo.svfs, "lock", repo.lock)
1408 held += report(repo.vfs, "wlock", repo.wlock)
1397 held += report(repo.vfs, "wlock", repo.wlock)
1409
1398
1410 return held
1399 return held
1411
1400
1412 @command('debugmergestate', [], '')
1401 @command('debugmergestate', [], '')
1413 def debugmergestate(ui, repo, *args):
1402 def debugmergestate(ui, repo, *args):
1414 """print merge state
1403 """print merge state
1415
1404
1416 Use --verbose to print out information about whether v1 or v2 merge state
1405 Use --verbose to print out information about whether v1 or v2 merge state
1417 was chosen."""
1406 was chosen."""
1418 def _hashornull(h):
1407 def _hashornull(h):
1419 if h == nullhex:
1408 if h == nullhex:
1420 return 'null'
1409 return 'null'
1421 else:
1410 else:
1422 return h
1411 return h
1423
1412
1424 def printrecords(version):
1413 def printrecords(version):
1425 ui.write(('* version %d records\n') % version)
1414 ui.write(('* version %d records\n') % version)
1426 if version == 1:
1415 if version == 1:
1427 records = v1records
1416 records = v1records
1428 else:
1417 else:
1429 records = v2records
1418 records = v2records
1430
1419
1431 for rtype, record in records:
1420 for rtype, record in records:
1432 # pretty print some record types
1421 # pretty print some record types
1433 if rtype == 'L':
1422 if rtype == 'L':
1434 ui.write(('local: %s\n') % record)
1423 ui.write(('local: %s\n') % record)
1435 elif rtype == 'O':
1424 elif rtype == 'O':
1436 ui.write(('other: %s\n') % record)
1425 ui.write(('other: %s\n') % record)
1437 elif rtype == 'm':
1426 elif rtype == 'm':
1438 driver, mdstate = record.split('\0', 1)
1427 driver, mdstate = record.split('\0', 1)
1439 ui.write(('merge driver: %s (state "%s")\n')
1428 ui.write(('merge driver: %s (state "%s")\n')
1440 % (driver, mdstate))
1429 % (driver, mdstate))
1441 elif rtype in 'FDC':
1430 elif rtype in 'FDC':
1442 r = record.split('\0')
1431 r = record.split('\0')
1443 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1432 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1444 if version == 1:
1433 if version == 1:
1445 onode = 'not stored in v1 format'
1434 onode = 'not stored in v1 format'
1446 flags = r[7]
1435 flags = r[7]
1447 else:
1436 else:
1448 onode, flags = r[7:9]
1437 onode, flags = r[7:9]
1449 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1438 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1450 % (f, rtype, state, _hashornull(hash)))
1439 % (f, rtype, state, _hashornull(hash)))
1451 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1440 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1452 ui.write((' ancestor path: %s (node %s)\n')
1441 ui.write((' ancestor path: %s (node %s)\n')
1453 % (afile, _hashornull(anode)))
1442 % (afile, _hashornull(anode)))
1454 ui.write((' other path: %s (node %s)\n')
1443 ui.write((' other path: %s (node %s)\n')
1455 % (ofile, _hashornull(onode)))
1444 % (ofile, _hashornull(onode)))
1456 elif rtype == 'f':
1445 elif rtype == 'f':
1457 filename, rawextras = record.split('\0', 1)
1446 filename, rawextras = record.split('\0', 1)
1458 extras = rawextras.split('\0')
1447 extras = rawextras.split('\0')
1459 i = 0
1448 i = 0
1460 extrastrings = []
1449 extrastrings = []
1461 while i < len(extras):
1450 while i < len(extras):
1462 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1451 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1463 i += 2
1452 i += 2
1464
1453
1465 ui.write(('file extras: %s (%s)\n')
1454 ui.write(('file extras: %s (%s)\n')
1466 % (filename, ', '.join(extrastrings)))
1455 % (filename, ', '.join(extrastrings)))
1467 elif rtype == 'l':
1456 elif rtype == 'l':
1468 labels = record.split('\0', 2)
1457 labels = record.split('\0', 2)
1469 labels = [l for l in labels if len(l) > 0]
1458 labels = [l for l in labels if len(l) > 0]
1470 ui.write(('labels:\n'))
1459 ui.write(('labels:\n'))
1471 ui.write((' local: %s\n' % labels[0]))
1460 ui.write((' local: %s\n' % labels[0]))
1472 ui.write((' other: %s\n' % labels[1]))
1461 ui.write((' other: %s\n' % labels[1]))
1473 if len(labels) > 2:
1462 if len(labels) > 2:
1474 ui.write((' base: %s\n' % labels[2]))
1463 ui.write((' base: %s\n' % labels[2]))
1475 else:
1464 else:
1476 ui.write(('unrecognized entry: %s\t%s\n')
1465 ui.write(('unrecognized entry: %s\t%s\n')
1477 % (rtype, record.replace('\0', '\t')))
1466 % (rtype, record.replace('\0', '\t')))
1478
1467
1479 # Avoid mergestate.read() since it may raise an exception for unsupported
1468 # Avoid mergestate.read() since it may raise an exception for unsupported
1480 # merge state records. We shouldn't be doing this, but this is OK since this
1469 # merge state records. We shouldn't be doing this, but this is OK since this
1481 # command is pretty low-level.
1470 # command is pretty low-level.
1482 ms = mergemod.mergestate(repo)
1471 ms = mergemod.mergestate(repo)
1483
1472
1484 # sort so that reasonable information is on top
1473 # sort so that reasonable information is on top
1485 v1records = ms._readrecordsv1()
1474 v1records = ms._readrecordsv1()
1486 v2records = ms._readrecordsv2()
1475 v2records = ms._readrecordsv2()
1487 order = 'LOml'
1476 order = 'LOml'
1488 def key(r):
1477 def key(r):
1489 idx = order.find(r[0])
1478 idx = order.find(r[0])
1490 if idx == -1:
1479 if idx == -1:
1491 return (1, r[1])
1480 return (1, r[1])
1492 else:
1481 else:
1493 return (0, idx)
1482 return (0, idx)
1494 v1records.sort(key=key)
1483 v1records.sort(key=key)
1495 v2records.sort(key=key)
1484 v2records.sort(key=key)
1496
1485
1497 if not v1records and not v2records:
1486 if not v1records and not v2records:
1498 ui.write(('no merge state found\n'))
1487 ui.write(('no merge state found\n'))
1499 elif not v2records:
1488 elif not v2records:
1500 ui.note(('no version 2 merge state\n'))
1489 ui.note(('no version 2 merge state\n'))
1501 printrecords(1)
1490 printrecords(1)
1502 elif ms._v1v2match(v1records, v2records):
1491 elif ms._v1v2match(v1records, v2records):
1503 ui.note(('v1 and v2 states match: using v2\n'))
1492 ui.note(('v1 and v2 states match: using v2\n'))
1504 printrecords(2)
1493 printrecords(2)
1505 else:
1494 else:
1506 ui.note(('v1 and v2 states mismatch: using v1\n'))
1495 ui.note(('v1 and v2 states mismatch: using v1\n'))
1507 printrecords(1)
1496 printrecords(1)
1508 if ui.verbose:
1497 if ui.verbose:
1509 printrecords(2)
1498 printrecords(2)
1510
1499
1511 @command('debugnamecomplete', [], _('NAME...'))
1500 @command('debugnamecomplete', [], _('NAME...'))
1512 def debugnamecomplete(ui, repo, *args):
1501 def debugnamecomplete(ui, repo, *args):
1513 '''complete "names" - tags, open branch names, bookmark names'''
1502 '''complete "names" - tags, open branch names, bookmark names'''
1514
1503
1515 names = set()
1504 names = set()
1516 # since we previously only listed open branches, we will handle that
1505 # since we previously only listed open branches, we will handle that
1517 # specially (after this for loop)
1506 # specially (after this for loop)
1518 for name, ns in repo.names.iteritems():
1507 for name, ns in repo.names.iteritems():
1519 if name != 'branches':
1508 if name != 'branches':
1520 names.update(ns.listnames(repo))
1509 names.update(ns.listnames(repo))
1521 names.update(tag for (tag, heads, tip, closed)
1510 names.update(tag for (tag, heads, tip, closed)
1522 in repo.branchmap().iterbranches() if not closed)
1511 in repo.branchmap().iterbranches() if not closed)
1523 completions = set()
1512 completions = set()
1524 if not args:
1513 if not args:
1525 args = ['']
1514 args = ['']
1526 for a in args:
1515 for a in args:
1527 completions.update(n for n in names if n.startswith(a))
1516 completions.update(n for n in names if n.startswith(a))
1528 ui.write('\n'.join(sorted(completions)))
1517 ui.write('\n'.join(sorted(completions)))
1529 ui.write('\n')
1518 ui.write('\n')
1530
1519
1531 @command('debugobsolete',
1520 @command('debugobsolete',
1532 [('', 'flags', 0, _('markers flag')),
1521 [('', 'flags', 0, _('markers flag')),
1533 ('', 'record-parents', False,
1522 ('', 'record-parents', False,
1534 _('record parent information for the precursor')),
1523 _('record parent information for the precursor')),
1535 ('r', 'rev', [], _('display markers relevant to REV')),
1524 ('r', 'rev', [], _('display markers relevant to REV')),
1536 ('', 'exclusive', False, _('restrict display to markers only '
1525 ('', 'exclusive', False, _('restrict display to markers only '
1537 'relevant to REV')),
1526 'relevant to REV')),
1538 ('', 'index', False, _('display index of the marker')),
1527 ('', 'index', False, _('display index of the marker')),
1539 ('', 'delete', [], _('delete markers specified by indices')),
1528 ('', 'delete', [], _('delete markers specified by indices')),
1540 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1529 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1541 _('[OBSOLETED [REPLACEMENT ...]]'))
1530 _('[OBSOLETED [REPLACEMENT ...]]'))
1542 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1531 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1543 """create arbitrary obsolete marker
1532 """create arbitrary obsolete marker
1544
1533
1545 With no arguments, displays the list of obsolescence markers."""
1534 With no arguments, displays the list of obsolescence markers."""
1546
1535
1547 opts = pycompat.byteskwargs(opts)
1536 opts = pycompat.byteskwargs(opts)
1548
1537
1549 def parsenodeid(s):
1538 def parsenodeid(s):
1550 try:
1539 try:
1551 # We do not use revsingle/revrange functions here to accept
1540 # We do not use revsingle/revrange functions here to accept
1552 # arbitrary node identifiers, possibly not present in the
1541 # arbitrary node identifiers, possibly not present in the
1553 # local repository.
1542 # local repository.
1554 n = bin(s)
1543 n = bin(s)
1555 if len(n) != len(nullid):
1544 if len(n) != len(nullid):
1556 raise TypeError()
1545 raise TypeError()
1557 return n
1546 return n
1558 except TypeError:
1547 except TypeError:
1559 raise error.Abort('changeset references must be full hexadecimal '
1548 raise error.Abort('changeset references must be full hexadecimal '
1560 'node identifiers')
1549 'node identifiers')
1561
1550
1562 if opts.get('delete'):
1551 if opts.get('delete'):
1563 indices = []
1552 indices = []
1564 for v in opts.get('delete'):
1553 for v in opts.get('delete'):
1565 try:
1554 try:
1566 indices.append(int(v))
1555 indices.append(int(v))
1567 except ValueError:
1556 except ValueError:
1568 raise error.Abort(_('invalid index value: %r') % v,
1557 raise error.Abort(_('invalid index value: %r') % v,
1569 hint=_('use integers for indices'))
1558 hint=_('use integers for indices'))
1570
1559
1571 if repo.currenttransaction():
1560 if repo.currenttransaction():
1572 raise error.Abort(_('cannot delete obsmarkers in the middle '
1561 raise error.Abort(_('cannot delete obsmarkers in the middle '
1573 'of transaction.'))
1562 'of transaction.'))
1574
1563
1575 with repo.lock():
1564 with repo.lock():
1576 n = repair.deleteobsmarkers(repo.obsstore, indices)
1565 n = repair.deleteobsmarkers(repo.obsstore, indices)
1577 ui.write(_('deleted %i obsolescence markers\n') % n)
1566 ui.write(_('deleted %i obsolescence markers\n') % n)
1578
1567
1579 return
1568 return
1580
1569
1581 if precursor is not None:
1570 if precursor is not None:
1582 if opts['rev']:
1571 if opts['rev']:
1583 raise error.Abort('cannot select revision when creating marker')
1572 raise error.Abort('cannot select revision when creating marker')
1584 metadata = {}
1573 metadata = {}
1585 metadata['user'] = opts['user'] or ui.username()
1574 metadata['user'] = opts['user'] or ui.username()
1586 succs = tuple(parsenodeid(succ) for succ in successors)
1575 succs = tuple(parsenodeid(succ) for succ in successors)
1587 l = repo.lock()
1576 l = repo.lock()
1588 try:
1577 try:
1589 tr = repo.transaction('debugobsolete')
1578 tr = repo.transaction('debugobsolete')
1590 try:
1579 try:
1591 date = opts.get('date')
1580 date = opts.get('date')
1592 if date:
1581 if date:
1593 date = dateutil.parsedate(date)
1582 date = dateutil.parsedate(date)
1594 else:
1583 else:
1595 date = None
1584 date = None
1596 prec = parsenodeid(precursor)
1585 prec = parsenodeid(precursor)
1597 parents = None
1586 parents = None
1598 if opts['record_parents']:
1587 if opts['record_parents']:
1599 if prec not in repo.unfiltered():
1588 if prec not in repo.unfiltered():
1600 raise error.Abort('cannot used --record-parents on '
1589 raise error.Abort('cannot used --record-parents on '
1601 'unknown changesets')
1590 'unknown changesets')
1602 parents = repo.unfiltered()[prec].parents()
1591 parents = repo.unfiltered()[prec].parents()
1603 parents = tuple(p.node() for p in parents)
1592 parents = tuple(p.node() for p in parents)
1604 repo.obsstore.create(tr, prec, succs, opts['flags'],
1593 repo.obsstore.create(tr, prec, succs, opts['flags'],
1605 parents=parents, date=date,
1594 parents=parents, date=date,
1606 metadata=metadata, ui=ui)
1595 metadata=metadata, ui=ui)
1607 tr.close()
1596 tr.close()
1608 except ValueError as exc:
1597 except ValueError as exc:
1609 raise error.Abort(_('bad obsmarker input: %s') %
1598 raise error.Abort(_('bad obsmarker input: %s') %
1610 pycompat.bytestr(exc))
1599 pycompat.bytestr(exc))
1611 finally:
1600 finally:
1612 tr.release()
1601 tr.release()
1613 finally:
1602 finally:
1614 l.release()
1603 l.release()
1615 else:
1604 else:
1616 if opts['rev']:
1605 if opts['rev']:
1617 revs = scmutil.revrange(repo, opts['rev'])
1606 revs = scmutil.revrange(repo, opts['rev'])
1618 nodes = [repo[r].node() for r in revs]
1607 nodes = [repo[r].node() for r in revs]
1619 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1608 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1620 exclusive=opts['exclusive']))
1609 exclusive=opts['exclusive']))
1621 markers.sort(key=lambda x: x._data)
1610 markers.sort(key=lambda x: x._data)
1622 else:
1611 else:
1623 markers = obsutil.getmarkers(repo)
1612 markers = obsutil.getmarkers(repo)
1624
1613
1625 markerstoiter = markers
1614 markerstoiter = markers
1626 isrelevant = lambda m: True
1615 isrelevant = lambda m: True
1627 if opts.get('rev') and opts.get('index'):
1616 if opts.get('rev') and opts.get('index'):
1628 markerstoiter = obsutil.getmarkers(repo)
1617 markerstoiter = obsutil.getmarkers(repo)
1629 markerset = set(markers)
1618 markerset = set(markers)
1630 isrelevant = lambda m: m in markerset
1619 isrelevant = lambda m: m in markerset
1631
1620
1632 fm = ui.formatter('debugobsolete', opts)
1621 fm = ui.formatter('debugobsolete', opts)
1633 for i, m in enumerate(markerstoiter):
1622 for i, m in enumerate(markerstoiter):
1634 if not isrelevant(m):
1623 if not isrelevant(m):
1635 # marker can be irrelevant when we're iterating over a set
1624 # marker can be irrelevant when we're iterating over a set
1636 # of markers (markerstoiter) which is bigger than the set
1625 # of markers (markerstoiter) which is bigger than the set
1637 # of markers we want to display (markers)
1626 # of markers we want to display (markers)
1638 # this can happen if both --index and --rev options are
1627 # this can happen if both --index and --rev options are
1639 # provided and thus we need to iterate over all of the markers
1628 # provided and thus we need to iterate over all of the markers
1640 # to get the correct indices, but only display the ones that
1629 # to get the correct indices, but only display the ones that
1641 # are relevant to --rev value
1630 # are relevant to --rev value
1642 continue
1631 continue
1643 fm.startitem()
1632 fm.startitem()
1644 ind = i if opts.get('index') else None
1633 ind = i if opts.get('index') else None
1645 cmdutil.showmarker(fm, m, index=ind)
1634 cmdutil.showmarker(fm, m, index=ind)
1646 fm.end()
1635 fm.end()
1647
1636
1648 @command('debugpathcomplete',
1637 @command('debugpathcomplete',
1649 [('f', 'full', None, _('complete an entire path')),
1638 [('f', 'full', None, _('complete an entire path')),
1650 ('n', 'normal', None, _('show only normal files')),
1639 ('n', 'normal', None, _('show only normal files')),
1651 ('a', 'added', None, _('show only added files')),
1640 ('a', 'added', None, _('show only added files')),
1652 ('r', 'removed', None, _('show only removed files'))],
1641 ('r', 'removed', None, _('show only removed files'))],
1653 _('FILESPEC...'))
1642 _('FILESPEC...'))
1654 def debugpathcomplete(ui, repo, *specs, **opts):
1643 def debugpathcomplete(ui, repo, *specs, **opts):
1655 '''complete part or all of a tracked path
1644 '''complete part or all of a tracked path
1656
1645
1657 This command supports shells that offer path name completion. It
1646 This command supports shells that offer path name completion. It
1658 currently completes only files already known to the dirstate.
1647 currently completes only files already known to the dirstate.
1659
1648
1660 Completion extends only to the next path segment unless
1649 Completion extends only to the next path segment unless
1661 --full is specified, in which case entire paths are used.'''
1650 --full is specified, in which case entire paths are used.'''
1662
1651
1663 def complete(path, acceptable):
1652 def complete(path, acceptable):
1664 dirstate = repo.dirstate
1653 dirstate = repo.dirstate
1665 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1654 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1666 rootdir = repo.root + pycompat.ossep
1655 rootdir = repo.root + pycompat.ossep
1667 if spec != repo.root and not spec.startswith(rootdir):
1656 if spec != repo.root and not spec.startswith(rootdir):
1668 return [], []
1657 return [], []
1669 if os.path.isdir(spec):
1658 if os.path.isdir(spec):
1670 spec += '/'
1659 spec += '/'
1671 spec = spec[len(rootdir):]
1660 spec = spec[len(rootdir):]
1672 fixpaths = pycompat.ossep != '/'
1661 fixpaths = pycompat.ossep != '/'
1673 if fixpaths:
1662 if fixpaths:
1674 spec = spec.replace(pycompat.ossep, '/')
1663 spec = spec.replace(pycompat.ossep, '/')
1675 speclen = len(spec)
1664 speclen = len(spec)
1676 fullpaths = opts[r'full']
1665 fullpaths = opts[r'full']
1677 files, dirs = set(), set()
1666 files, dirs = set(), set()
1678 adddir, addfile = dirs.add, files.add
1667 adddir, addfile = dirs.add, files.add
1679 for f, st in dirstate.iteritems():
1668 for f, st in dirstate.iteritems():
1680 if f.startswith(spec) and st[0] in acceptable:
1669 if f.startswith(spec) and st[0] in acceptable:
1681 if fixpaths:
1670 if fixpaths:
1682 f = f.replace('/', pycompat.ossep)
1671 f = f.replace('/', pycompat.ossep)
1683 if fullpaths:
1672 if fullpaths:
1684 addfile(f)
1673 addfile(f)
1685 continue
1674 continue
1686 s = f.find(pycompat.ossep, speclen)
1675 s = f.find(pycompat.ossep, speclen)
1687 if s >= 0:
1676 if s >= 0:
1688 adddir(f[:s])
1677 adddir(f[:s])
1689 else:
1678 else:
1690 addfile(f)
1679 addfile(f)
1691 return files, dirs
1680 return files, dirs
1692
1681
1693 acceptable = ''
1682 acceptable = ''
1694 if opts[r'normal']:
1683 if opts[r'normal']:
1695 acceptable += 'nm'
1684 acceptable += 'nm'
1696 if opts[r'added']:
1685 if opts[r'added']:
1697 acceptable += 'a'
1686 acceptable += 'a'
1698 if opts[r'removed']:
1687 if opts[r'removed']:
1699 acceptable += 'r'
1688 acceptable += 'r'
1700 cwd = repo.getcwd()
1689 cwd = repo.getcwd()
1701 if not specs:
1690 if not specs:
1702 specs = ['.']
1691 specs = ['.']
1703
1692
1704 files, dirs = set(), set()
1693 files, dirs = set(), set()
1705 for spec in specs:
1694 for spec in specs:
1706 f, d = complete(spec, acceptable or 'nmar')
1695 f, d = complete(spec, acceptable or 'nmar')
1707 files.update(f)
1696 files.update(f)
1708 dirs.update(d)
1697 dirs.update(d)
1709 files.update(dirs)
1698 files.update(dirs)
1710 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1699 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1711 ui.write('\n')
1700 ui.write('\n')
1712
1701
1713 @command('debugpeer', [], _('PATH'), norepo=True)
1702 @command('debugpeer', [], _('PATH'), norepo=True)
1714 def debugpeer(ui, path):
1703 def debugpeer(ui, path):
1715 """establish a connection to a peer repository"""
1704 """establish a connection to a peer repository"""
1716 # Always enable peer request logging. Requires --debug to display
1705 # Always enable peer request logging. Requires --debug to display
1717 # though.
1706 # though.
1718 overrides = {
1707 overrides = {
1719 ('devel', 'debug.peer-request'): True,
1708 ('devel', 'debug.peer-request'): True,
1720 }
1709 }
1721
1710
1722 with ui.configoverride(overrides):
1711 with ui.configoverride(overrides):
1723 peer = hg.peer(ui, {}, path)
1712 peer = hg.peer(ui, {}, path)
1724
1713
1725 local = peer.local() is not None
1714 local = peer.local() is not None
1726 canpush = peer.canpush()
1715 canpush = peer.canpush()
1727
1716
1728 ui.write(_('url: %s\n') % peer.url())
1717 ui.write(_('url: %s\n') % peer.url())
1729 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1718 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1730 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1719 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1731
1720
1732 @command('debugpickmergetool',
1721 @command('debugpickmergetool',
1733 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1722 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1734 ('', 'changedelete', None, _('emulate merging change and delete')),
1723 ('', 'changedelete', None, _('emulate merging change and delete')),
1735 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1724 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1736 _('[PATTERN]...'),
1725 _('[PATTERN]...'),
1737 inferrepo=True)
1726 inferrepo=True)
1738 def debugpickmergetool(ui, repo, *pats, **opts):
1727 def debugpickmergetool(ui, repo, *pats, **opts):
1739 """examine which merge tool is chosen for specified file
1728 """examine which merge tool is chosen for specified file
1740
1729
1741 As described in :hg:`help merge-tools`, Mercurial examines
1730 As described in :hg:`help merge-tools`, Mercurial examines
1742 configurations below in this order to decide which merge tool is
1731 configurations below in this order to decide which merge tool is
1743 chosen for specified file.
1732 chosen for specified file.
1744
1733
1745 1. ``--tool`` option
1734 1. ``--tool`` option
1746 2. ``HGMERGE`` environment variable
1735 2. ``HGMERGE`` environment variable
1747 3. configurations in ``merge-patterns`` section
1736 3. configurations in ``merge-patterns`` section
1748 4. configuration of ``ui.merge``
1737 4. configuration of ``ui.merge``
1749 5. configurations in ``merge-tools`` section
1738 5. configurations in ``merge-tools`` section
1750 6. ``hgmerge`` tool (for historical reason only)
1739 6. ``hgmerge`` tool (for historical reason only)
1751 7. default tool for fallback (``:merge`` or ``:prompt``)
1740 7. default tool for fallback (``:merge`` or ``:prompt``)
1752
1741
1753 This command writes out examination result in the style below::
1742 This command writes out examination result in the style below::
1754
1743
1755 FILE = MERGETOOL
1744 FILE = MERGETOOL
1756
1745
1757 By default, all files known in the first parent context of the
1746 By default, all files known in the first parent context of the
1758 working directory are examined. Use file patterns and/or -I/-X
1747 working directory are examined. Use file patterns and/or -I/-X
1759 options to limit target files. -r/--rev is also useful to examine
1748 options to limit target files. -r/--rev is also useful to examine
1760 files in another context without actual updating to it.
1749 files in another context without actual updating to it.
1761
1750
1762 With --debug, this command shows warning messages while matching
1751 With --debug, this command shows warning messages while matching
1763 against ``merge-patterns`` and so on, too. It is recommended to
1752 against ``merge-patterns`` and so on, too. It is recommended to
1764 use this option with explicit file patterns and/or -I/-X options,
1753 use this option with explicit file patterns and/or -I/-X options,
1765 because this option increases amount of output per file according
1754 because this option increases amount of output per file according
1766 to configurations in hgrc.
1755 to configurations in hgrc.
1767
1756
1768 With -v/--verbose, this command shows configurations below at
1757 With -v/--verbose, this command shows configurations below at
1769 first (only if specified).
1758 first (only if specified).
1770
1759
1771 - ``--tool`` option
1760 - ``--tool`` option
1772 - ``HGMERGE`` environment variable
1761 - ``HGMERGE`` environment variable
1773 - configuration of ``ui.merge``
1762 - configuration of ``ui.merge``
1774
1763
1775 If merge tool is chosen before matching against
1764 If merge tool is chosen before matching against
1776 ``merge-patterns``, this command can't show any helpful
1765 ``merge-patterns``, this command can't show any helpful
1777 information, even with --debug. In such case, information above is
1766 information, even with --debug. In such case, information above is
1778 useful to know why a merge tool is chosen.
1767 useful to know why a merge tool is chosen.
1779 """
1768 """
1780 opts = pycompat.byteskwargs(opts)
1769 opts = pycompat.byteskwargs(opts)
1781 overrides = {}
1770 overrides = {}
1782 if opts['tool']:
1771 if opts['tool']:
1783 overrides[('ui', 'forcemerge')] = opts['tool']
1772 overrides[('ui', 'forcemerge')] = opts['tool']
1784 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1773 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1785
1774
1786 with ui.configoverride(overrides, 'debugmergepatterns'):
1775 with ui.configoverride(overrides, 'debugmergepatterns'):
1787 hgmerge = encoding.environ.get("HGMERGE")
1776 hgmerge = encoding.environ.get("HGMERGE")
1788 if hgmerge is not None:
1777 if hgmerge is not None:
1789 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1778 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1790 uimerge = ui.config("ui", "merge")
1779 uimerge = ui.config("ui", "merge")
1791 if uimerge:
1780 if uimerge:
1792 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1781 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1793
1782
1794 ctx = scmutil.revsingle(repo, opts.get('rev'))
1783 ctx = scmutil.revsingle(repo, opts.get('rev'))
1795 m = scmutil.match(ctx, pats, opts)
1784 m = scmutil.match(ctx, pats, opts)
1796 changedelete = opts['changedelete']
1785 changedelete = opts['changedelete']
1797 for path in ctx.walk(m):
1786 for path in ctx.walk(m):
1798 fctx = ctx[path]
1787 fctx = ctx[path]
1799 try:
1788 try:
1800 if not ui.debugflag:
1789 if not ui.debugflag:
1801 ui.pushbuffer(error=True)
1790 ui.pushbuffer(error=True)
1802 tool, toolpath = filemerge._picktool(repo, ui, path,
1791 tool, toolpath = filemerge._picktool(repo, ui, path,
1803 fctx.isbinary(),
1792 fctx.isbinary(),
1804 'l' in fctx.flags(),
1793 'l' in fctx.flags(),
1805 changedelete)
1794 changedelete)
1806 finally:
1795 finally:
1807 if not ui.debugflag:
1796 if not ui.debugflag:
1808 ui.popbuffer()
1797 ui.popbuffer()
1809 ui.write(('%s = %s\n') % (path, tool))
1798 ui.write(('%s = %s\n') % (path, tool))
1810
1799
1811 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1800 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1812 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1801 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1813 '''access the pushkey key/value protocol
1802 '''access the pushkey key/value protocol
1814
1803
1815 With two args, list the keys in the given namespace.
1804 With two args, list the keys in the given namespace.
1816
1805
1817 With five args, set a key to new if it currently is set to old.
1806 With five args, set a key to new if it currently is set to old.
1818 Reports success or failure.
1807 Reports success or failure.
1819 '''
1808 '''
1820
1809
1821 target = hg.peer(ui, {}, repopath)
1810 target = hg.peer(ui, {}, repopath)
1822 if keyinfo:
1811 if keyinfo:
1823 key, old, new = keyinfo
1812 key, old, new = keyinfo
1824 r = target.pushkey(namespace, key, old, new)
1813 r = target.pushkey(namespace, key, old, new)
1825 ui.status(pycompat.bytestr(r) + '\n')
1814 ui.status(pycompat.bytestr(r) + '\n')
1826 return not r
1815 return not r
1827 else:
1816 else:
1828 for k, v in sorted(target.listkeys(namespace).iteritems()):
1817 for k, v in sorted(target.listkeys(namespace).iteritems()):
1829 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1818 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1830 stringutil.escapestr(v)))
1819 stringutil.escapestr(v)))
1831
1820
1832 @command('debugpvec', [], _('A B'))
1821 @command('debugpvec', [], _('A B'))
1833 def debugpvec(ui, repo, a, b=None):
1822 def debugpvec(ui, repo, a, b=None):
1834 ca = scmutil.revsingle(repo, a)
1823 ca = scmutil.revsingle(repo, a)
1835 cb = scmutil.revsingle(repo, b)
1824 cb = scmutil.revsingle(repo, b)
1836 pa = pvec.ctxpvec(ca)
1825 pa = pvec.ctxpvec(ca)
1837 pb = pvec.ctxpvec(cb)
1826 pb = pvec.ctxpvec(cb)
1838 if pa == pb:
1827 if pa == pb:
1839 rel = "="
1828 rel = "="
1840 elif pa > pb:
1829 elif pa > pb:
1841 rel = ">"
1830 rel = ">"
1842 elif pa < pb:
1831 elif pa < pb:
1843 rel = "<"
1832 rel = "<"
1844 elif pa | pb:
1833 elif pa | pb:
1845 rel = "|"
1834 rel = "|"
1846 ui.write(_("a: %s\n") % pa)
1835 ui.write(_("a: %s\n") % pa)
1847 ui.write(_("b: %s\n") % pb)
1836 ui.write(_("b: %s\n") % pb)
1848 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1837 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1849 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1838 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1850 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1839 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1851 pa.distance(pb), rel))
1840 pa.distance(pb), rel))
1852
1841
1853 @command('debugrebuilddirstate|debugrebuildstate',
1842 @command('debugrebuilddirstate|debugrebuildstate',
1854 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1843 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1855 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1844 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1856 'the working copy parent')),
1845 'the working copy parent')),
1857 ],
1846 ],
1858 _('[-r REV]'))
1847 _('[-r REV]'))
1859 def debugrebuilddirstate(ui, repo, rev, **opts):
1848 def debugrebuilddirstate(ui, repo, rev, **opts):
1860 """rebuild the dirstate as it would look like for the given revision
1849 """rebuild the dirstate as it would look like for the given revision
1861
1850
1862 If no revision is specified the first current parent will be used.
1851 If no revision is specified the first current parent will be used.
1863
1852
1864 The dirstate will be set to the files of the given revision.
1853 The dirstate will be set to the files of the given revision.
1865 The actual working directory content or existing dirstate
1854 The actual working directory content or existing dirstate
1866 information such as adds or removes is not considered.
1855 information such as adds or removes is not considered.
1867
1856
1868 ``minimal`` will only rebuild the dirstate status for files that claim to be
1857 ``minimal`` will only rebuild the dirstate status for files that claim to be
1869 tracked but are not in the parent manifest, or that exist in the parent
1858 tracked but are not in the parent manifest, or that exist in the parent
1870 manifest but are not in the dirstate. It will not change adds, removes, or
1859 manifest but are not in the dirstate. It will not change adds, removes, or
1871 modified files that are in the working copy parent.
1860 modified files that are in the working copy parent.
1872
1861
1873 One use of this command is to make the next :hg:`status` invocation
1862 One use of this command is to make the next :hg:`status` invocation
1874 check the actual file content.
1863 check the actual file content.
1875 """
1864 """
1876 ctx = scmutil.revsingle(repo, rev)
1865 ctx = scmutil.revsingle(repo, rev)
1877 with repo.wlock():
1866 with repo.wlock():
1878 dirstate = repo.dirstate
1867 dirstate = repo.dirstate
1879 changedfiles = None
1868 changedfiles = None
1880 # See command doc for what minimal does.
1869 # See command doc for what minimal does.
1881 if opts.get(r'minimal'):
1870 if opts.get(r'minimal'):
1882 manifestfiles = set(ctx.manifest().keys())
1871 manifestfiles = set(ctx.manifest().keys())
1883 dirstatefiles = set(dirstate)
1872 dirstatefiles = set(dirstate)
1884 manifestonly = manifestfiles - dirstatefiles
1873 manifestonly = manifestfiles - dirstatefiles
1885 dsonly = dirstatefiles - manifestfiles
1874 dsonly = dirstatefiles - manifestfiles
1886 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1875 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1887 changedfiles = manifestonly | dsnotadded
1876 changedfiles = manifestonly | dsnotadded
1888
1877
1889 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1878 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1890
1879
1891 @command('debugrebuildfncache', [], '')
1880 @command('debugrebuildfncache', [], '')
1892 def debugrebuildfncache(ui, repo):
1881 def debugrebuildfncache(ui, repo):
1893 """rebuild the fncache file"""
1882 """rebuild the fncache file"""
1894 repair.rebuildfncache(ui, repo)
1883 repair.rebuildfncache(ui, repo)
1895
1884
1896 @command('debugrename',
1885 @command('debugrename',
1897 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1886 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1898 _('[-r REV] FILE'))
1887 _('[-r REV] FILE'))
1899 def debugrename(ui, repo, file1, *pats, **opts):
1888 def debugrename(ui, repo, file1, *pats, **opts):
1900 """dump rename information"""
1889 """dump rename information"""
1901
1890
1902 opts = pycompat.byteskwargs(opts)
1891 opts = pycompat.byteskwargs(opts)
1903 ctx = scmutil.revsingle(repo, opts.get('rev'))
1892 ctx = scmutil.revsingle(repo, opts.get('rev'))
1904 m = scmutil.match(ctx, (file1,) + pats, opts)
1893 m = scmutil.match(ctx, (file1,) + pats, opts)
1905 for abs in ctx.walk(m):
1894 for abs in ctx.walk(m):
1906 fctx = ctx[abs]
1895 fctx = ctx[abs]
1907 o = fctx.filelog().renamed(fctx.filenode())
1896 o = fctx.filelog().renamed(fctx.filenode())
1908 rel = m.rel(abs)
1897 rel = m.rel(abs)
1909 if o:
1898 if o:
1910 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1899 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1911 else:
1900 else:
1912 ui.write(_("%s not renamed\n") % rel)
1901 ui.write(_("%s not renamed\n") % rel)
1913
1902
1914 @command('debugrevlog', cmdutil.debugrevlogopts +
1903 @command('debugrevlog', cmdutil.debugrevlogopts +
1915 [('d', 'dump', False, _('dump index data'))],
1904 [('d', 'dump', False, _('dump index data'))],
1916 _('-c|-m|FILE'),
1905 _('-c|-m|FILE'),
1917 optionalrepo=True)
1906 optionalrepo=True)
1918 def debugrevlog(ui, repo, file_=None, **opts):
1907 def debugrevlog(ui, repo, file_=None, **opts):
1919 """show data and statistics about a revlog"""
1908 """show data and statistics about a revlog"""
1920 opts = pycompat.byteskwargs(opts)
1909 opts = pycompat.byteskwargs(opts)
1921 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1910 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1922
1911
1923 if opts.get("dump"):
1912 if opts.get("dump"):
1924 numrevs = len(r)
1913 numrevs = len(r)
1925 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1914 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1926 " rawsize totalsize compression heads chainlen\n"))
1915 " rawsize totalsize compression heads chainlen\n"))
1927 ts = 0
1916 ts = 0
1928 heads = set()
1917 heads = set()
1929
1918
1930 for rev in xrange(numrevs):
1919 for rev in xrange(numrevs):
1931 dbase = r.deltaparent(rev)
1920 dbase = r.deltaparent(rev)
1932 if dbase == -1:
1921 if dbase == -1:
1933 dbase = rev
1922 dbase = rev
1934 cbase = r.chainbase(rev)
1923 cbase = r.chainbase(rev)
1935 clen = r.chainlen(rev)
1924 clen = r.chainlen(rev)
1936 p1, p2 = r.parentrevs(rev)
1925 p1, p2 = r.parentrevs(rev)
1937 rs = r.rawsize(rev)
1926 rs = r.rawsize(rev)
1938 ts = ts + rs
1927 ts = ts + rs
1939 heads -= set(r.parentrevs(rev))
1928 heads -= set(r.parentrevs(rev))
1940 heads.add(rev)
1929 heads.add(rev)
1941 try:
1930 try:
1942 compression = ts / r.end(rev)
1931 compression = ts / r.end(rev)
1943 except ZeroDivisionError:
1932 except ZeroDivisionError:
1944 compression = 0
1933 compression = 0
1945 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1934 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1946 "%11d %5d %8d\n" %
1935 "%11d %5d %8d\n" %
1947 (rev, p1, p2, r.start(rev), r.end(rev),
1936 (rev, p1, p2, r.start(rev), r.end(rev),
1948 r.start(dbase), r.start(cbase),
1937 r.start(dbase), r.start(cbase),
1949 r.start(p1), r.start(p2),
1938 r.start(p1), r.start(p2),
1950 rs, ts, compression, len(heads), clen))
1939 rs, ts, compression, len(heads), clen))
1951 return 0
1940 return 0
1952
1941
1953 v = r.version
1942 v = r.version
1954 format = v & 0xFFFF
1943 format = v & 0xFFFF
1955 flags = []
1944 flags = []
1956 gdelta = False
1945 gdelta = False
1957 if v & revlog.FLAG_INLINE_DATA:
1946 if v & revlog.FLAG_INLINE_DATA:
1958 flags.append('inline')
1947 flags.append('inline')
1959 if v & revlog.FLAG_GENERALDELTA:
1948 if v & revlog.FLAG_GENERALDELTA:
1960 gdelta = True
1949 gdelta = True
1961 flags.append('generaldelta')
1950 flags.append('generaldelta')
1962 if not flags:
1951 if not flags:
1963 flags = ['(none)']
1952 flags = ['(none)']
1964
1953
1965 nummerges = 0
1954 nummerges = 0
1966 numfull = 0
1955 numfull = 0
1967 numprev = 0
1956 numprev = 0
1968 nump1 = 0
1957 nump1 = 0
1969 nump2 = 0
1958 nump2 = 0
1970 numother = 0
1959 numother = 0
1971 nump1prev = 0
1960 nump1prev = 0
1972 nump2prev = 0
1961 nump2prev = 0
1973 chainlengths = []
1962 chainlengths = []
1974 chainbases = []
1963 chainbases = []
1975 chainspans = []
1964 chainspans = []
1976
1965
1977 datasize = [None, 0, 0]
1966 datasize = [None, 0, 0]
1978 fullsize = [None, 0, 0]
1967 fullsize = [None, 0, 0]
1979 deltasize = [None, 0, 0]
1968 deltasize = [None, 0, 0]
1980 chunktypecounts = {}
1969 chunktypecounts = {}
1981 chunktypesizes = {}
1970 chunktypesizes = {}
1982
1971
1983 def addsize(size, l):
1972 def addsize(size, l):
1984 if l[0] is None or size < l[0]:
1973 if l[0] is None or size < l[0]:
1985 l[0] = size
1974 l[0] = size
1986 if size > l[1]:
1975 if size > l[1]:
1987 l[1] = size
1976 l[1] = size
1988 l[2] += size
1977 l[2] += size
1989
1978
1990 numrevs = len(r)
1979 numrevs = len(r)
1991 for rev in xrange(numrevs):
1980 for rev in xrange(numrevs):
1992 p1, p2 = r.parentrevs(rev)
1981 p1, p2 = r.parentrevs(rev)
1993 delta = r.deltaparent(rev)
1982 delta = r.deltaparent(rev)
1994 if format > 0:
1983 if format > 0:
1995 addsize(r.rawsize(rev), datasize)
1984 addsize(r.rawsize(rev), datasize)
1996 if p2 != nullrev:
1985 if p2 != nullrev:
1997 nummerges += 1
1986 nummerges += 1
1998 size = r.length(rev)
1987 size = r.length(rev)
1999 if delta == nullrev:
1988 if delta == nullrev:
2000 chainlengths.append(0)
1989 chainlengths.append(0)
2001 chainbases.append(r.start(rev))
1990 chainbases.append(r.start(rev))
2002 chainspans.append(size)
1991 chainspans.append(size)
2003 numfull += 1
1992 numfull += 1
2004 addsize(size, fullsize)
1993 addsize(size, fullsize)
2005 else:
1994 else:
2006 chainlengths.append(chainlengths[delta] + 1)
1995 chainlengths.append(chainlengths[delta] + 1)
2007 baseaddr = chainbases[delta]
1996 baseaddr = chainbases[delta]
2008 revaddr = r.start(rev)
1997 revaddr = r.start(rev)
2009 chainbases.append(baseaddr)
1998 chainbases.append(baseaddr)
2010 chainspans.append((revaddr - baseaddr) + size)
1999 chainspans.append((revaddr - baseaddr) + size)
2011 addsize(size, deltasize)
2000 addsize(size, deltasize)
2012 if delta == rev - 1:
2001 if delta == rev - 1:
2013 numprev += 1
2002 numprev += 1
2014 if delta == p1:
2003 if delta == p1:
2015 nump1prev += 1
2004 nump1prev += 1
2016 elif delta == p2:
2005 elif delta == p2:
2017 nump2prev += 1
2006 nump2prev += 1
2018 elif delta == p1:
2007 elif delta == p1:
2019 nump1 += 1
2008 nump1 += 1
2020 elif delta == p2:
2009 elif delta == p2:
2021 nump2 += 1
2010 nump2 += 1
2022 elif delta != nullrev:
2011 elif delta != nullrev:
2023 numother += 1
2012 numother += 1
2024
2013
2025 # Obtain data on the raw chunks in the revlog.
2014 # Obtain data on the raw chunks in the revlog.
2026 segment = r._getsegmentforrevs(rev, rev)[1]
2015 segment = r._getsegmentforrevs(rev, rev)[1]
2027 if segment:
2016 if segment:
2028 chunktype = bytes(segment[0:1])
2017 chunktype = bytes(segment[0:1])
2029 else:
2018 else:
2030 chunktype = 'empty'
2019 chunktype = 'empty'
2031
2020
2032 if chunktype not in chunktypecounts:
2021 if chunktype not in chunktypecounts:
2033 chunktypecounts[chunktype] = 0
2022 chunktypecounts[chunktype] = 0
2034 chunktypesizes[chunktype] = 0
2023 chunktypesizes[chunktype] = 0
2035
2024
2036 chunktypecounts[chunktype] += 1
2025 chunktypecounts[chunktype] += 1
2037 chunktypesizes[chunktype] += size
2026 chunktypesizes[chunktype] += size
2038
2027
2039 # Adjust size min value for empty cases
2028 # Adjust size min value for empty cases
2040 for size in (datasize, fullsize, deltasize):
2029 for size in (datasize, fullsize, deltasize):
2041 if size[0] is None:
2030 if size[0] is None:
2042 size[0] = 0
2031 size[0] = 0
2043
2032
2044 numdeltas = numrevs - numfull
2033 numdeltas = numrevs - numfull
2045 numoprev = numprev - nump1prev - nump2prev
2034 numoprev = numprev - nump1prev - nump2prev
2046 totalrawsize = datasize[2]
2035 totalrawsize = datasize[2]
2047 datasize[2] /= numrevs
2036 datasize[2] /= numrevs
2048 fulltotal = fullsize[2]
2037 fulltotal = fullsize[2]
2049 fullsize[2] /= numfull
2038 fullsize[2] /= numfull
2050 deltatotal = deltasize[2]
2039 deltatotal = deltasize[2]
2051 if numrevs - numfull > 0:
2040 if numrevs - numfull > 0:
2052 deltasize[2] /= numrevs - numfull
2041 deltasize[2] /= numrevs - numfull
2053 totalsize = fulltotal + deltatotal
2042 totalsize = fulltotal + deltatotal
2054 avgchainlen = sum(chainlengths) / numrevs
2043 avgchainlen = sum(chainlengths) / numrevs
2055 maxchainlen = max(chainlengths)
2044 maxchainlen = max(chainlengths)
2056 maxchainspan = max(chainspans)
2045 maxchainspan = max(chainspans)
2057 compratio = 1
2046 compratio = 1
2058 if totalsize:
2047 if totalsize:
2059 compratio = totalrawsize / totalsize
2048 compratio = totalrawsize / totalsize
2060
2049
2061 basedfmtstr = '%%%dd\n'
2050 basedfmtstr = '%%%dd\n'
2062 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2051 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2063
2052
2064 def dfmtstr(max):
2053 def dfmtstr(max):
2065 return basedfmtstr % len(str(max))
2054 return basedfmtstr % len(str(max))
2066 def pcfmtstr(max, padding=0):
2055 def pcfmtstr(max, padding=0):
2067 return basepcfmtstr % (len(str(max)), ' ' * padding)
2056 return basepcfmtstr % (len(str(max)), ' ' * padding)
2068
2057
2069 def pcfmt(value, total):
2058 def pcfmt(value, total):
2070 if total:
2059 if total:
2071 return (value, 100 * float(value) / total)
2060 return (value, 100 * float(value) / total)
2072 else:
2061 else:
2073 return value, 100.0
2062 return value, 100.0
2074
2063
2075 ui.write(('format : %d\n') % format)
2064 ui.write(('format : %d\n') % format)
2076 ui.write(('flags : %s\n') % ', '.join(flags))
2065 ui.write(('flags : %s\n') % ', '.join(flags))
2077
2066
2078 ui.write('\n')
2067 ui.write('\n')
2079 fmt = pcfmtstr(totalsize)
2068 fmt = pcfmtstr(totalsize)
2080 fmt2 = dfmtstr(totalsize)
2069 fmt2 = dfmtstr(totalsize)
2081 ui.write(('revisions : ') + fmt2 % numrevs)
2070 ui.write(('revisions : ') + fmt2 % numrevs)
2082 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2071 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2083 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2072 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2084 ui.write(('revisions : ') + fmt2 % numrevs)
2073 ui.write(('revisions : ') + fmt2 % numrevs)
2085 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2074 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2086 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2075 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2087 ui.write(('revision size : ') + fmt2 % totalsize)
2076 ui.write(('revision size : ') + fmt2 % totalsize)
2088 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2077 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2089 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2078 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2090
2079
2091 def fmtchunktype(chunktype):
2080 def fmtchunktype(chunktype):
2092 if chunktype == 'empty':
2081 if chunktype == 'empty':
2093 return ' %s : ' % chunktype
2082 return ' %s : ' % chunktype
2094 elif chunktype in pycompat.bytestr(string.ascii_letters):
2083 elif chunktype in pycompat.bytestr(string.ascii_letters):
2095 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2084 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2096 else:
2085 else:
2097 return ' 0x%s : ' % hex(chunktype)
2086 return ' 0x%s : ' % hex(chunktype)
2098
2087
2099 ui.write('\n')
2088 ui.write('\n')
2100 ui.write(('chunks : ') + fmt2 % numrevs)
2089 ui.write(('chunks : ') + fmt2 % numrevs)
2101 for chunktype in sorted(chunktypecounts):
2090 for chunktype in sorted(chunktypecounts):
2102 ui.write(fmtchunktype(chunktype))
2091 ui.write(fmtchunktype(chunktype))
2103 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2092 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2104 ui.write(('chunks size : ') + fmt2 % totalsize)
2093 ui.write(('chunks size : ') + fmt2 % totalsize)
2105 for chunktype in sorted(chunktypecounts):
2094 for chunktype in sorted(chunktypecounts):
2106 ui.write(fmtchunktype(chunktype))
2095 ui.write(fmtchunktype(chunktype))
2107 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2096 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2108
2097
2109 ui.write('\n')
2098 ui.write('\n')
2110 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2099 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2111 ui.write(('avg chain length : ') + fmt % avgchainlen)
2100 ui.write(('avg chain length : ') + fmt % avgchainlen)
2112 ui.write(('max chain length : ') + fmt % maxchainlen)
2101 ui.write(('max chain length : ') + fmt % maxchainlen)
2113 ui.write(('max chain reach : ') + fmt % maxchainspan)
2102 ui.write(('max chain reach : ') + fmt % maxchainspan)
2114 ui.write(('compression ratio : ') + fmt % compratio)
2103 ui.write(('compression ratio : ') + fmt % compratio)
2115
2104
2116 if format > 0:
2105 if format > 0:
2117 ui.write('\n')
2106 ui.write('\n')
2118 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2107 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2119 % tuple(datasize))
2108 % tuple(datasize))
2120 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2109 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2121 % tuple(fullsize))
2110 % tuple(fullsize))
2122 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2111 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2123 % tuple(deltasize))
2112 % tuple(deltasize))
2124
2113
2125 if numdeltas > 0:
2114 if numdeltas > 0:
2126 ui.write('\n')
2115 ui.write('\n')
2127 fmt = pcfmtstr(numdeltas)
2116 fmt = pcfmtstr(numdeltas)
2128 fmt2 = pcfmtstr(numdeltas, 4)
2117 fmt2 = pcfmtstr(numdeltas, 4)
2129 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2118 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2130 if numprev > 0:
2119 if numprev > 0:
2131 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2120 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2132 numprev))
2121 numprev))
2133 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2122 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2134 numprev))
2123 numprev))
2135 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2124 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2136 numprev))
2125 numprev))
2137 if gdelta:
2126 if gdelta:
2138 ui.write(('deltas against p1 : ')
2127 ui.write(('deltas against p1 : ')
2139 + fmt % pcfmt(nump1, numdeltas))
2128 + fmt % pcfmt(nump1, numdeltas))
2140 ui.write(('deltas against p2 : ')
2129 ui.write(('deltas against p2 : ')
2141 + fmt % pcfmt(nump2, numdeltas))
2130 + fmt % pcfmt(nump2, numdeltas))
2142 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2131 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2143 numdeltas))
2132 numdeltas))
2144
2133
2145 @command('debugrevspec',
2134 @command('debugrevspec',
2146 [('', 'optimize', None,
2135 [('', 'optimize', None,
2147 _('print parsed tree after optimizing (DEPRECATED)')),
2136 _('print parsed tree after optimizing (DEPRECATED)')),
2148 ('', 'show-revs', True, _('print list of result revisions (default)')),
2137 ('', 'show-revs', True, _('print list of result revisions (default)')),
2149 ('s', 'show-set', None, _('print internal representation of result set')),
2138 ('s', 'show-set', None, _('print internal representation of result set')),
2150 ('p', 'show-stage', [],
2139 ('p', 'show-stage', [],
2151 _('print parsed tree at the given stage'), _('NAME')),
2140 _('print parsed tree at the given stage'), _('NAME')),
2152 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2141 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2153 ('', 'verify-optimized', False, _('verify optimized result')),
2142 ('', 'verify-optimized', False, _('verify optimized result')),
2154 ],
2143 ],
2155 ('REVSPEC'))
2144 ('REVSPEC'))
2156 def debugrevspec(ui, repo, expr, **opts):
2145 def debugrevspec(ui, repo, expr, **opts):
2157 """parse and apply a revision specification
2146 """parse and apply a revision specification
2158
2147
2159 Use -p/--show-stage option to print the parsed tree at the given stages.
2148 Use -p/--show-stage option to print the parsed tree at the given stages.
2160 Use -p all to print tree at every stage.
2149 Use -p all to print tree at every stage.
2161
2150
2162 Use --no-show-revs option with -s or -p to print only the set
2151 Use --no-show-revs option with -s or -p to print only the set
2163 representation or the parsed tree respectively.
2152 representation or the parsed tree respectively.
2164
2153
2165 Use --verify-optimized to compare the optimized result with the unoptimized
2154 Use --verify-optimized to compare the optimized result with the unoptimized
2166 one. Returns 1 if the optimized result differs.
2155 one. Returns 1 if the optimized result differs.
2167 """
2156 """
2168 opts = pycompat.byteskwargs(opts)
2157 opts = pycompat.byteskwargs(opts)
2169 aliases = ui.configitems('revsetalias')
2158 aliases = ui.configitems('revsetalias')
2170 stages = [
2159 stages = [
2171 ('parsed', lambda tree: tree),
2160 ('parsed', lambda tree: tree),
2172 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2161 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2173 ui.warn)),
2162 ui.warn)),
2174 ('concatenated', revsetlang.foldconcat),
2163 ('concatenated', revsetlang.foldconcat),
2175 ('analyzed', revsetlang.analyze),
2164 ('analyzed', revsetlang.analyze),
2176 ('optimized', revsetlang.optimize),
2165 ('optimized', revsetlang.optimize),
2177 ]
2166 ]
2178 if opts['no_optimized']:
2167 if opts['no_optimized']:
2179 stages = stages[:-1]
2168 stages = stages[:-1]
2180 if opts['verify_optimized'] and opts['no_optimized']:
2169 if opts['verify_optimized'] and opts['no_optimized']:
2181 raise error.Abort(_('cannot use --verify-optimized with '
2170 raise error.Abort(_('cannot use --verify-optimized with '
2182 '--no-optimized'))
2171 '--no-optimized'))
2183 stagenames = set(n for n, f in stages)
2172 stagenames = set(n for n, f in stages)
2184
2173
2185 showalways = set()
2174 showalways = set()
2186 showchanged = set()
2175 showchanged = set()
2187 if ui.verbose and not opts['show_stage']:
2176 if ui.verbose and not opts['show_stage']:
2188 # show parsed tree by --verbose (deprecated)
2177 # show parsed tree by --verbose (deprecated)
2189 showalways.add('parsed')
2178 showalways.add('parsed')
2190 showchanged.update(['expanded', 'concatenated'])
2179 showchanged.update(['expanded', 'concatenated'])
2191 if opts['optimize']:
2180 if opts['optimize']:
2192 showalways.add('optimized')
2181 showalways.add('optimized')
2193 if opts['show_stage'] and opts['optimize']:
2182 if opts['show_stage'] and opts['optimize']:
2194 raise error.Abort(_('cannot use --optimize with --show-stage'))
2183 raise error.Abort(_('cannot use --optimize with --show-stage'))
2195 if opts['show_stage'] == ['all']:
2184 if opts['show_stage'] == ['all']:
2196 showalways.update(stagenames)
2185 showalways.update(stagenames)
2197 else:
2186 else:
2198 for n in opts['show_stage']:
2187 for n in opts['show_stage']:
2199 if n not in stagenames:
2188 if n not in stagenames:
2200 raise error.Abort(_('invalid stage name: %s') % n)
2189 raise error.Abort(_('invalid stage name: %s') % n)
2201 showalways.update(opts['show_stage'])
2190 showalways.update(opts['show_stage'])
2202
2191
2203 treebystage = {}
2192 treebystage = {}
2204 printedtree = None
2193 printedtree = None
2205 tree = revsetlang.parse(expr, lookup=repo.__contains__)
2194 tree = revsetlang.parse(expr, lookup=repo.__contains__)
2206 for n, f in stages:
2195 for n, f in stages:
2207 treebystage[n] = tree = f(tree)
2196 treebystage[n] = tree = f(tree)
2208 if n in showalways or (n in showchanged and tree != printedtree):
2197 if n in showalways or (n in showchanged and tree != printedtree):
2209 if opts['show_stage'] or n != 'parsed':
2198 if opts['show_stage'] or n != 'parsed':
2210 ui.write(("* %s:\n") % n)
2199 ui.write(("* %s:\n") % n)
2211 ui.write(revsetlang.prettyformat(tree), "\n")
2200 ui.write(revsetlang.prettyformat(tree), "\n")
2212 printedtree = tree
2201 printedtree = tree
2213
2202
2214 if opts['verify_optimized']:
2203 if opts['verify_optimized']:
2215 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2204 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2216 brevs = revset.makematcher(treebystage['optimized'])(repo)
2205 brevs = revset.makematcher(treebystage['optimized'])(repo)
2217 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2206 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2218 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2207 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2219 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2208 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2220 arevs = list(arevs)
2209 arevs = list(arevs)
2221 brevs = list(brevs)
2210 brevs = list(brevs)
2222 if arevs == brevs:
2211 if arevs == brevs:
2223 return 0
2212 return 0
2224 ui.write(('--- analyzed\n'), label='diff.file_a')
2213 ui.write(('--- analyzed\n'), label='diff.file_a')
2225 ui.write(('+++ optimized\n'), label='diff.file_b')
2214 ui.write(('+++ optimized\n'), label='diff.file_b')
2226 sm = difflib.SequenceMatcher(None, arevs, brevs)
2215 sm = difflib.SequenceMatcher(None, arevs, brevs)
2227 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2216 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2228 if tag in ('delete', 'replace'):
2217 if tag in ('delete', 'replace'):
2229 for c in arevs[alo:ahi]:
2218 for c in arevs[alo:ahi]:
2230 ui.write('-%s\n' % c, label='diff.deleted')
2219 ui.write('-%s\n' % c, label='diff.deleted')
2231 if tag in ('insert', 'replace'):
2220 if tag in ('insert', 'replace'):
2232 for c in brevs[blo:bhi]:
2221 for c in brevs[blo:bhi]:
2233 ui.write('+%s\n' % c, label='diff.inserted')
2222 ui.write('+%s\n' % c, label='diff.inserted')
2234 if tag == 'equal':
2223 if tag == 'equal':
2235 for c in arevs[alo:ahi]:
2224 for c in arevs[alo:ahi]:
2236 ui.write(' %s\n' % c)
2225 ui.write(' %s\n' % c)
2237 return 1
2226 return 1
2238
2227
2239 func = revset.makematcher(tree)
2228 func = revset.makematcher(tree)
2240 revs = func(repo)
2229 revs = func(repo)
2241 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2230 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2242 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2231 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2243 if not opts['show_revs']:
2232 if not opts['show_revs']:
2244 return
2233 return
2245 for c in revs:
2234 for c in revs:
2246 ui.write("%d\n" % c)
2235 ui.write("%d\n" % c)
2247
2236
2248 @command('debugserve', [
2237 @command('debugserve', [
2249 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2238 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2250 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2239 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2251 ('', 'logiofile', '', _('file to log server I/O to')),
2240 ('', 'logiofile', '', _('file to log server I/O to')),
2252 ], '')
2241 ], '')
2253 def debugserve(ui, repo, **opts):
2242 def debugserve(ui, repo, **opts):
2254 """run a server with advanced settings
2243 """run a server with advanced settings
2255
2244
2256 This command is similar to :hg:`serve`. It exists partially as a
2245 This command is similar to :hg:`serve`. It exists partially as a
2257 workaround to the fact that ``hg serve --stdio`` must have specific
2246 workaround to the fact that ``hg serve --stdio`` must have specific
2258 arguments for security reasons.
2247 arguments for security reasons.
2259 """
2248 """
2260 opts = pycompat.byteskwargs(opts)
2249 opts = pycompat.byteskwargs(opts)
2261
2250
2262 if not opts['sshstdio']:
2251 if not opts['sshstdio']:
2263 raise error.Abort(_('only --sshstdio is currently supported'))
2252 raise error.Abort(_('only --sshstdio is currently supported'))
2264
2253
2265 logfh = None
2254 logfh = None
2266
2255
2267 if opts['logiofd'] and opts['logiofile']:
2256 if opts['logiofd'] and opts['logiofile']:
2268 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2257 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2269
2258
2270 if opts['logiofd']:
2259 if opts['logiofd']:
2271 # Line buffered because output is line based.
2260 # Line buffered because output is line based.
2272 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2261 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2273 elif opts['logiofile']:
2262 elif opts['logiofile']:
2274 logfh = open(opts['logiofile'], 'ab', 1)
2263 logfh = open(opts['logiofile'], 'ab', 1)
2275
2264
2276 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2265 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2277 s.serve_forever()
2266 s.serve_forever()
2278
2267
2279 @command('debugsetparents', [], _('REV1 [REV2]'))
2268 @command('debugsetparents', [], _('REV1 [REV2]'))
2280 def debugsetparents(ui, repo, rev1, rev2=None):
2269 def debugsetparents(ui, repo, rev1, rev2=None):
2281 """manually set the parents of the current working directory
2270 """manually set the parents of the current working directory
2282
2271
2283 This is useful for writing repository conversion tools, but should
2272 This is useful for writing repository conversion tools, but should
2284 be used with care. For example, neither the working directory nor the
2273 be used with care. For example, neither the working directory nor the
2285 dirstate is updated, so file status may be incorrect after running this
2274 dirstate is updated, so file status may be incorrect after running this
2286 command.
2275 command.
2287
2276
2288 Returns 0 on success.
2277 Returns 0 on success.
2289 """
2278 """
2290
2279
2291 node1 = scmutil.revsingle(repo, rev1).node()
2280 node1 = scmutil.revsingle(repo, rev1).node()
2292 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2281 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2293
2282
2294 with repo.wlock():
2283 with repo.wlock():
2295 repo.setparents(node1, node2)
2284 repo.setparents(node1, node2)
2296
2285
2297 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2286 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2298 def debugssl(ui, repo, source=None, **opts):
2287 def debugssl(ui, repo, source=None, **opts):
2299 '''test a secure connection to a server
2288 '''test a secure connection to a server
2300
2289
2301 This builds the certificate chain for the server on Windows, installing the
2290 This builds the certificate chain for the server on Windows, installing the
2302 missing intermediates and trusted root via Windows Update if necessary. It
2291 missing intermediates and trusted root via Windows Update if necessary. It
2303 does nothing on other platforms.
2292 does nothing on other platforms.
2304
2293
2305 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2294 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2306 that server is used. See :hg:`help urls` for more information.
2295 that server is used. See :hg:`help urls` for more information.
2307
2296
2308 If the update succeeds, retry the original operation. Otherwise, the cause
2297 If the update succeeds, retry the original operation. Otherwise, the cause
2309 of the SSL error is likely another issue.
2298 of the SSL error is likely another issue.
2310 '''
2299 '''
2311 if not pycompat.iswindows:
2300 if not pycompat.iswindows:
2312 raise error.Abort(_('certificate chain building is only possible on '
2301 raise error.Abort(_('certificate chain building is only possible on '
2313 'Windows'))
2302 'Windows'))
2314
2303
2315 if not source:
2304 if not source:
2316 if not repo:
2305 if not repo:
2317 raise error.Abort(_("there is no Mercurial repository here, and no "
2306 raise error.Abort(_("there is no Mercurial repository here, and no "
2318 "server specified"))
2307 "server specified"))
2319 source = "default"
2308 source = "default"
2320
2309
2321 source, branches = hg.parseurl(ui.expandpath(source))
2310 source, branches = hg.parseurl(ui.expandpath(source))
2322 url = util.url(source)
2311 url = util.url(source)
2323 addr = None
2312 addr = None
2324
2313
2325 defaultport = {'https': 443, 'ssh': 22}
2314 defaultport = {'https': 443, 'ssh': 22}
2326 if url.scheme in defaultport:
2315 if url.scheme in defaultport:
2327 try:
2316 try:
2328 addr = (url.host, int(url.port or defaultport[url.scheme]))
2317 addr = (url.host, int(url.port or defaultport[url.scheme]))
2329 except ValueError:
2318 except ValueError:
2330 raise error.Abort(_("malformed port number in URL"))
2319 raise error.Abort(_("malformed port number in URL"))
2331 else:
2320 else:
2332 raise error.Abort(_("only https and ssh connections are supported"))
2321 raise error.Abort(_("only https and ssh connections are supported"))
2333
2322
2334 from . import win32
2323 from . import win32
2335
2324
2336 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2325 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2337 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2326 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2338
2327
2339 try:
2328 try:
2340 s.connect(addr)
2329 s.connect(addr)
2341 cert = s.getpeercert(True)
2330 cert = s.getpeercert(True)
2342
2331
2343 ui.status(_('checking the certificate chain for %s\n') % url.host)
2332 ui.status(_('checking the certificate chain for %s\n') % url.host)
2344
2333
2345 complete = win32.checkcertificatechain(cert, build=False)
2334 complete = win32.checkcertificatechain(cert, build=False)
2346
2335
2347 if not complete:
2336 if not complete:
2348 ui.status(_('certificate chain is incomplete, updating... '))
2337 ui.status(_('certificate chain is incomplete, updating... '))
2349
2338
2350 if not win32.checkcertificatechain(cert):
2339 if not win32.checkcertificatechain(cert):
2351 ui.status(_('failed.\n'))
2340 ui.status(_('failed.\n'))
2352 else:
2341 else:
2353 ui.status(_('done.\n'))
2342 ui.status(_('done.\n'))
2354 else:
2343 else:
2355 ui.status(_('full certificate chain is available\n'))
2344 ui.status(_('full certificate chain is available\n'))
2356 finally:
2345 finally:
2357 s.close()
2346 s.close()
2358
2347
2359 @command('debugsub',
2348 @command('debugsub',
2360 [('r', 'rev', '',
2349 [('r', 'rev', '',
2361 _('revision to check'), _('REV'))],
2350 _('revision to check'), _('REV'))],
2362 _('[-r REV] [REV]'))
2351 _('[-r REV] [REV]'))
2363 def debugsub(ui, repo, rev=None):
2352 def debugsub(ui, repo, rev=None):
2364 ctx = scmutil.revsingle(repo, rev, None)
2353 ctx = scmutil.revsingle(repo, rev, None)
2365 for k, v in sorted(ctx.substate.items()):
2354 for k, v in sorted(ctx.substate.items()):
2366 ui.write(('path %s\n') % k)
2355 ui.write(('path %s\n') % k)
2367 ui.write((' source %s\n') % v[0])
2356 ui.write((' source %s\n') % v[0])
2368 ui.write((' revision %s\n') % v[1])
2357 ui.write((' revision %s\n') % v[1])
2369
2358
2370 @command('debugsuccessorssets',
2359 @command('debugsuccessorssets',
2371 [('', 'closest', False, _('return closest successors sets only'))],
2360 [('', 'closest', False, _('return closest successors sets only'))],
2372 _('[REV]'))
2361 _('[REV]'))
2373 def debugsuccessorssets(ui, repo, *revs, **opts):
2362 def debugsuccessorssets(ui, repo, *revs, **opts):
2374 """show set of successors for revision
2363 """show set of successors for revision
2375
2364
2376 A successors set of changeset A is a consistent group of revisions that
2365 A successors set of changeset A is a consistent group of revisions that
2377 succeed A. It contains non-obsolete changesets only unless closests
2366 succeed A. It contains non-obsolete changesets only unless closests
2378 successors set is set.
2367 successors set is set.
2379
2368
2380 In most cases a changeset A has a single successors set containing a single
2369 In most cases a changeset A has a single successors set containing a single
2381 successor (changeset A replaced by A').
2370 successor (changeset A replaced by A').
2382
2371
2383 A changeset that is made obsolete with no successors are called "pruned".
2372 A changeset that is made obsolete with no successors are called "pruned".
2384 Such changesets have no successors sets at all.
2373 Such changesets have no successors sets at all.
2385
2374
2386 A changeset that has been "split" will have a successors set containing
2375 A changeset that has been "split" will have a successors set containing
2387 more than one successor.
2376 more than one successor.
2388
2377
2389 A changeset that has been rewritten in multiple different ways is called
2378 A changeset that has been rewritten in multiple different ways is called
2390 "divergent". Such changesets have multiple successor sets (each of which
2379 "divergent". Such changesets have multiple successor sets (each of which
2391 may also be split, i.e. have multiple successors).
2380 may also be split, i.e. have multiple successors).
2392
2381
2393 Results are displayed as follows::
2382 Results are displayed as follows::
2394
2383
2395 <rev1>
2384 <rev1>
2396 <successors-1A>
2385 <successors-1A>
2397 <rev2>
2386 <rev2>
2398 <successors-2A>
2387 <successors-2A>
2399 <successors-2B1> <successors-2B2> <successors-2B3>
2388 <successors-2B1> <successors-2B2> <successors-2B3>
2400
2389
2401 Here rev2 has two possible (i.e. divergent) successors sets. The first
2390 Here rev2 has two possible (i.e. divergent) successors sets. The first
2402 holds one element, whereas the second holds three (i.e. the changeset has
2391 holds one element, whereas the second holds three (i.e. the changeset has
2403 been split).
2392 been split).
2404 """
2393 """
2405 # passed to successorssets caching computation from one call to another
2394 # passed to successorssets caching computation from one call to another
2406 cache = {}
2395 cache = {}
2407 ctx2str = bytes
2396 ctx2str = bytes
2408 node2str = short
2397 node2str = short
2409 for rev in scmutil.revrange(repo, revs):
2398 for rev in scmutil.revrange(repo, revs):
2410 ctx = repo[rev]
2399 ctx = repo[rev]
2411 ui.write('%s\n'% ctx2str(ctx))
2400 ui.write('%s\n'% ctx2str(ctx))
2412 for succsset in obsutil.successorssets(repo, ctx.node(),
2401 for succsset in obsutil.successorssets(repo, ctx.node(),
2413 closest=opts[r'closest'],
2402 closest=opts[r'closest'],
2414 cache=cache):
2403 cache=cache):
2415 if succsset:
2404 if succsset:
2416 ui.write(' ')
2405 ui.write(' ')
2417 ui.write(node2str(succsset[0]))
2406 ui.write(node2str(succsset[0]))
2418 for node in succsset[1:]:
2407 for node in succsset[1:]:
2419 ui.write(' ')
2408 ui.write(' ')
2420 ui.write(node2str(node))
2409 ui.write(node2str(node))
2421 ui.write('\n')
2410 ui.write('\n')
2422
2411
2423 @command('debugtemplate',
2412 @command('debugtemplate',
2424 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2413 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2425 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2414 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2426 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2415 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2427 optionalrepo=True)
2416 optionalrepo=True)
2428 def debugtemplate(ui, repo, tmpl, **opts):
2417 def debugtemplate(ui, repo, tmpl, **opts):
2429 """parse and apply a template
2418 """parse and apply a template
2430
2419
2431 If -r/--rev is given, the template is processed as a log template and
2420 If -r/--rev is given, the template is processed as a log template and
2432 applied to the given changesets. Otherwise, it is processed as a generic
2421 applied to the given changesets. Otherwise, it is processed as a generic
2433 template.
2422 template.
2434
2423
2435 Use --verbose to print the parsed tree.
2424 Use --verbose to print the parsed tree.
2436 """
2425 """
2437 revs = None
2426 revs = None
2438 if opts[r'rev']:
2427 if opts[r'rev']:
2439 if repo is None:
2428 if repo is None:
2440 raise error.RepoError(_('there is no Mercurial repository here '
2429 raise error.RepoError(_('there is no Mercurial repository here '
2441 '(.hg not found)'))
2430 '(.hg not found)'))
2442 revs = scmutil.revrange(repo, opts[r'rev'])
2431 revs = scmutil.revrange(repo, opts[r'rev'])
2443
2432
2444 props = {}
2433 props = {}
2445 for d in opts[r'define']:
2434 for d in opts[r'define']:
2446 try:
2435 try:
2447 k, v = (e.strip() for e in d.split('=', 1))
2436 k, v = (e.strip() for e in d.split('=', 1))
2448 if not k or k == 'ui':
2437 if not k or k == 'ui':
2449 raise ValueError
2438 raise ValueError
2450 props[k] = v
2439 props[k] = v
2451 except ValueError:
2440 except ValueError:
2452 raise error.Abort(_('malformed keyword definition: %s') % d)
2441 raise error.Abort(_('malformed keyword definition: %s') % d)
2453
2442
2454 if ui.verbose:
2443 if ui.verbose:
2455 aliases = ui.configitems('templatealias')
2444 aliases = ui.configitems('templatealias')
2456 tree = templater.parse(tmpl)
2445 tree = templater.parse(tmpl)
2457 ui.note(templater.prettyformat(tree), '\n')
2446 ui.note(templater.prettyformat(tree), '\n')
2458 newtree = templater.expandaliases(tree, aliases)
2447 newtree = templater.expandaliases(tree, aliases)
2459 if newtree != tree:
2448 if newtree != tree:
2460 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2449 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2461
2450
2462 if revs is None:
2451 if revs is None:
2463 tres = formatter.templateresources(ui, repo)
2452 tres = formatter.templateresources(ui, repo)
2464 t = formatter.maketemplater(ui, tmpl, resources=tres)
2453 t = formatter.maketemplater(ui, tmpl, resources=tres)
2465 ui.write(t.renderdefault(props))
2454 ui.write(t.renderdefault(props))
2466 else:
2455 else:
2467 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2456 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2468 for r in revs:
2457 for r in revs:
2469 displayer.show(repo[r], **pycompat.strkwargs(props))
2458 displayer.show(repo[r], **pycompat.strkwargs(props))
2470 displayer.close()
2459 displayer.close()
2471
2460
2472 @command('debuguigetpass', [
2461 @command('debuguigetpass', [
2473 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2462 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2474 ], _('[-p TEXT]'), norepo=True)
2463 ], _('[-p TEXT]'), norepo=True)
2475 def debuguigetpass(ui, prompt=''):
2464 def debuguigetpass(ui, prompt=''):
2476 """show prompt to type password"""
2465 """show prompt to type password"""
2477 r = ui.getpass(prompt)
2466 r = ui.getpass(prompt)
2478 ui.write(('respose: %s\n') % r)
2467 ui.write(('respose: %s\n') % r)
2479
2468
2480 @command('debuguiprompt', [
2469 @command('debuguiprompt', [
2481 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2470 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2482 ], _('[-p TEXT]'), norepo=True)
2471 ], _('[-p TEXT]'), norepo=True)
2483 def debuguiprompt(ui, prompt=''):
2472 def debuguiprompt(ui, prompt=''):
2484 """show plain prompt"""
2473 """show plain prompt"""
2485 r = ui.prompt(prompt)
2474 r = ui.prompt(prompt)
2486 ui.write(('response: %s\n') % r)
2475 ui.write(('response: %s\n') % r)
2487
2476
2488 @command('debugupdatecaches', [])
2477 @command('debugupdatecaches', [])
2489 def debugupdatecaches(ui, repo, *pats, **opts):
2478 def debugupdatecaches(ui, repo, *pats, **opts):
2490 """warm all known caches in the repository"""
2479 """warm all known caches in the repository"""
2491 with repo.wlock(), repo.lock():
2480 with repo.wlock(), repo.lock():
2492 repo.updatecaches(full=True)
2481 repo.updatecaches(full=True)
2493
2482
2494 @command('debugupgraderepo', [
2483 @command('debugupgraderepo', [
2495 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2484 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2496 ('', 'run', False, _('performs an upgrade')),
2485 ('', 'run', False, _('performs an upgrade')),
2497 ])
2486 ])
2498 def debugupgraderepo(ui, repo, run=False, optimize=None):
2487 def debugupgraderepo(ui, repo, run=False, optimize=None):
2499 """upgrade a repository to use different features
2488 """upgrade a repository to use different features
2500
2489
2501 If no arguments are specified, the repository is evaluated for upgrade
2490 If no arguments are specified, the repository is evaluated for upgrade
2502 and a list of problems and potential optimizations is printed.
2491 and a list of problems and potential optimizations is printed.
2503
2492
2504 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2493 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2505 can be influenced via additional arguments. More details will be provided
2494 can be influenced via additional arguments. More details will be provided
2506 by the command output when run without ``--run``.
2495 by the command output when run without ``--run``.
2507
2496
2508 During the upgrade, the repository will be locked and no writes will be
2497 During the upgrade, the repository will be locked and no writes will be
2509 allowed.
2498 allowed.
2510
2499
2511 At the end of the upgrade, the repository may not be readable while new
2500 At the end of the upgrade, the repository may not be readable while new
2512 repository data is swapped in. This window will be as long as it takes to
2501 repository data is swapped in. This window will be as long as it takes to
2513 rename some directories inside the ``.hg`` directory. On most machines, this
2502 rename some directories inside the ``.hg`` directory. On most machines, this
2514 should complete almost instantaneously and the chances of a consumer being
2503 should complete almost instantaneously and the chances of a consumer being
2515 unable to access the repository should be low.
2504 unable to access the repository should be low.
2516 """
2505 """
2517 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2506 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2518
2507
2519 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2508 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2520 inferrepo=True)
2509 inferrepo=True)
2521 def debugwalk(ui, repo, *pats, **opts):
2510 def debugwalk(ui, repo, *pats, **opts):
2522 """show how files match on given patterns"""
2511 """show how files match on given patterns"""
2523 opts = pycompat.byteskwargs(opts)
2512 opts = pycompat.byteskwargs(opts)
2524 m = scmutil.match(repo[None], pats, opts)
2513 m = scmutil.match(repo[None], pats, opts)
2525 ui.write(('matcher: %r\n' % m))
2514 ui.write(('matcher: %r\n' % m))
2526 items = list(repo[None].walk(m))
2515 items = list(repo[None].walk(m))
2527 if not items:
2516 if not items:
2528 return
2517 return
2529 f = lambda fn: fn
2518 f = lambda fn: fn
2530 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2519 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2531 f = lambda fn: util.normpath(fn)
2520 f = lambda fn: util.normpath(fn)
2532 fmt = 'f %%-%ds %%-%ds %%s' % (
2521 fmt = 'f %%-%ds %%-%ds %%s' % (
2533 max([len(abs) for abs in items]),
2522 max([len(abs) for abs in items]),
2534 max([len(m.rel(abs)) for abs in items]))
2523 max([len(m.rel(abs)) for abs in items]))
2535 for abs in items:
2524 for abs in items:
2536 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2525 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2537 ui.write("%s\n" % line.rstrip())
2526 ui.write("%s\n" % line.rstrip())
2538
2527
2539 @command('debugwhyunstable', [], _('REV'))
2528 @command('debugwhyunstable', [], _('REV'))
2540 def debugwhyunstable(ui, repo, rev):
2529 def debugwhyunstable(ui, repo, rev):
2541 """explain instabilities of a changeset"""
2530 """explain instabilities of a changeset"""
2542 for entry in obsutil.whyunstable(repo, repo[rev]):
2531 for entry in obsutil.whyunstable(repo, repo[rev]):
2543 dnodes = ''
2532 dnodes = ''
2544 if entry.get('divergentnodes'):
2533 if entry.get('divergentnodes'):
2545 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2534 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2546 for ctx in entry['divergentnodes']) + ' '
2535 for ctx in entry['divergentnodes']) + ' '
2547 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2536 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2548 entry['reason'], entry['node']))
2537 entry['reason'], entry['node']))
2549
2538
2550 @command('debugwireargs',
2539 @command('debugwireargs',
2551 [('', 'three', '', 'three'),
2540 [('', 'three', '', 'three'),
2552 ('', 'four', '', 'four'),
2541 ('', 'four', '', 'four'),
2553 ('', 'five', '', 'five'),
2542 ('', 'five', '', 'five'),
2554 ] + cmdutil.remoteopts,
2543 ] + cmdutil.remoteopts,
2555 _('REPO [OPTIONS]... [ONE [TWO]]'),
2544 _('REPO [OPTIONS]... [ONE [TWO]]'),
2556 norepo=True)
2545 norepo=True)
2557 def debugwireargs(ui, repopath, *vals, **opts):
2546 def debugwireargs(ui, repopath, *vals, **opts):
2558 opts = pycompat.byteskwargs(opts)
2547 opts = pycompat.byteskwargs(opts)
2559 repo = hg.peer(ui, opts, repopath)
2548 repo = hg.peer(ui, opts, repopath)
2560 for opt in cmdutil.remoteopts:
2549 for opt in cmdutil.remoteopts:
2561 del opts[opt[1]]
2550 del opts[opt[1]]
2562 args = {}
2551 args = {}
2563 for k, v in opts.iteritems():
2552 for k, v in opts.iteritems():
2564 if v:
2553 if v:
2565 args[k] = v
2554 args[k] = v
2566 args = pycompat.strkwargs(args)
2555 args = pycompat.strkwargs(args)
2567 # run twice to check that we don't mess up the stream for the next command
2556 # run twice to check that we don't mess up the stream for the next command
2568 res1 = repo.debugwireargs(*vals, **args)
2557 res1 = repo.debugwireargs(*vals, **args)
2569 res2 = repo.debugwireargs(*vals, **args)
2558 res2 = repo.debugwireargs(*vals, **args)
2570 ui.write("%s\n" % res1)
2559 ui.write("%s\n" % res1)
2571 if res1 != res2:
2560 if res1 != res2:
2572 ui.warn("%s\n" % res2)
2561 ui.warn("%s\n" % res2)
2573
2562
2574 def _parsewirelangblocks(fh):
2563 def _parsewirelangblocks(fh):
2575 activeaction = None
2564 activeaction = None
2576 blocklines = []
2565 blocklines = []
2577
2566
2578 for line in fh:
2567 for line in fh:
2579 line = line.rstrip()
2568 line = line.rstrip()
2580 if not line:
2569 if not line:
2581 continue
2570 continue
2582
2571
2583 if line.startswith(b'#'):
2572 if line.startswith(b'#'):
2584 continue
2573 continue
2585
2574
2586 if not line.startswith(' '):
2575 if not line.startswith(' '):
2587 # New block. Flush previous one.
2576 # New block. Flush previous one.
2588 if activeaction:
2577 if activeaction:
2589 yield activeaction, blocklines
2578 yield activeaction, blocklines
2590
2579
2591 activeaction = line
2580 activeaction = line
2592 blocklines = []
2581 blocklines = []
2593 continue
2582 continue
2594
2583
2595 # Else we start with an indent.
2584 # Else we start with an indent.
2596
2585
2597 if not activeaction:
2586 if not activeaction:
2598 raise error.Abort(_('indented line outside of block'))
2587 raise error.Abort(_('indented line outside of block'))
2599
2588
2600 blocklines.append(line)
2589 blocklines.append(line)
2601
2590
2602 # Flush last block.
2591 # Flush last block.
2603 if activeaction:
2592 if activeaction:
2604 yield activeaction, blocklines
2593 yield activeaction, blocklines
2605
2594
2606 @command('debugwireproto',
2595 @command('debugwireproto',
2607 [
2596 [
2608 ('', 'localssh', False, _('start an SSH server for this repo')),
2597 ('', 'localssh', False, _('start an SSH server for this repo')),
2609 ('', 'peer', '', _('construct a specific version of the peer')),
2598 ('', 'peer', '', _('construct a specific version of the peer')),
2610 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2599 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2611 ] + cmdutil.remoteopts,
2600 ] + cmdutil.remoteopts,
2612 _('[PATH]'),
2601 _('[PATH]'),
2613 optionalrepo=True)
2602 optionalrepo=True)
2614 def debugwireproto(ui, repo, path=None, **opts):
2603 def debugwireproto(ui, repo, path=None, **opts):
2615 """send wire protocol commands to a server
2604 """send wire protocol commands to a server
2616
2605
2617 This command can be used to issue wire protocol commands to remote
2606 This command can be used to issue wire protocol commands to remote
2618 peers and to debug the raw data being exchanged.
2607 peers and to debug the raw data being exchanged.
2619
2608
2620 ``--localssh`` will start an SSH server against the current repository
2609 ``--localssh`` will start an SSH server against the current repository
2621 and connect to that. By default, the connection will perform a handshake
2610 and connect to that. By default, the connection will perform a handshake
2622 and establish an appropriate peer instance.
2611 and establish an appropriate peer instance.
2623
2612
2624 ``--peer`` can be used to bypass the handshake protocol and construct a
2613 ``--peer`` can be used to bypass the handshake protocol and construct a
2625 peer instance using the specified class type. Valid values are ``raw``,
2614 peer instance using the specified class type. Valid values are ``raw``,
2626 ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending raw data
2615 ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending raw data
2627 payloads and don't support higher-level command actions.
2616 payloads and don't support higher-level command actions.
2628
2617
2629 ``--noreadstderr`` can be used to disable automatic reading from stderr
2618 ``--noreadstderr`` can be used to disable automatic reading from stderr
2630 of the peer (for SSH connections only). Disabling automatic reading of
2619 of the peer (for SSH connections only). Disabling automatic reading of
2631 stderr is useful for making output more deterministic.
2620 stderr is useful for making output more deterministic.
2632
2621
2633 Commands are issued via a mini language which is specified via stdin.
2622 Commands are issued via a mini language which is specified via stdin.
2634 The language consists of individual actions to perform. An action is
2623 The language consists of individual actions to perform. An action is
2635 defined by a block. A block is defined as a line with no leading
2624 defined by a block. A block is defined as a line with no leading
2636 space followed by 0 or more lines with leading space. Blocks are
2625 space followed by 0 or more lines with leading space. Blocks are
2637 effectively a high-level command with additional metadata.
2626 effectively a high-level command with additional metadata.
2638
2627
2639 Lines beginning with ``#`` are ignored.
2628 Lines beginning with ``#`` are ignored.
2640
2629
2641 The following sections denote available actions.
2630 The following sections denote available actions.
2642
2631
2643 raw
2632 raw
2644 ---
2633 ---
2645
2634
2646 Send raw data to the server.
2635 Send raw data to the server.
2647
2636
2648 The block payload contains the raw data to send as one atomic send
2637 The block payload contains the raw data to send as one atomic send
2649 operation. The data may not actually be delivered in a single system
2638 operation. The data may not actually be delivered in a single system
2650 call: it depends on the abilities of the transport being used.
2639 call: it depends on the abilities of the transport being used.
2651
2640
2652 Each line in the block is de-indented and concatenated. Then, that
2641 Each line in the block is de-indented and concatenated. Then, that
2653 value is evaluated as a Python b'' literal. This allows the use of
2642 value is evaluated as a Python b'' literal. This allows the use of
2654 backslash escaping, etc.
2643 backslash escaping, etc.
2655
2644
2656 raw+
2645 raw+
2657 ----
2646 ----
2658
2647
2659 Behaves like ``raw`` except flushes output afterwards.
2648 Behaves like ``raw`` except flushes output afterwards.
2660
2649
2661 command <X>
2650 command <X>
2662 -----------
2651 -----------
2663
2652
2664 Send a request to run a named command, whose name follows the ``command``
2653 Send a request to run a named command, whose name follows the ``command``
2665 string.
2654 string.
2666
2655
2667 Arguments to the command are defined as lines in this block. The format of
2656 Arguments to the command are defined as lines in this block. The format of
2668 each line is ``<key> <value>``. e.g.::
2657 each line is ``<key> <value>``. e.g.::
2669
2658
2670 command listkeys
2659 command listkeys
2671 namespace bookmarks
2660 namespace bookmarks
2672
2661
2673 Values are interpreted as Python b'' literals. This allows encoding
2662 Values are interpreted as Python b'' literals. This allows encoding
2674 special byte sequences via backslash escaping.
2663 special byte sequences via backslash escaping.
2675
2664
2676 The following arguments have special meaning:
2665 The following arguments have special meaning:
2677
2666
2678 ``PUSHFILE``
2667 ``PUSHFILE``
2679 When defined, the *push* mechanism of the peer will be used instead
2668 When defined, the *push* mechanism of the peer will be used instead
2680 of the static request-response mechanism and the content of the
2669 of the static request-response mechanism and the content of the
2681 file specified in the value of this argument will be sent as the
2670 file specified in the value of this argument will be sent as the
2682 command payload.
2671 command payload.
2683
2672
2684 This can be used to submit a local bundle file to the remote.
2673 This can be used to submit a local bundle file to the remote.
2685
2674
2686 batchbegin
2675 batchbegin
2687 ----------
2676 ----------
2688
2677
2689 Instruct the peer to begin a batched send.
2678 Instruct the peer to begin a batched send.
2690
2679
2691 All ``command`` blocks are queued for execution until the next
2680 All ``command`` blocks are queued for execution until the next
2692 ``batchsubmit`` block.
2681 ``batchsubmit`` block.
2693
2682
2694 batchsubmit
2683 batchsubmit
2695 -----------
2684 -----------
2696
2685
2697 Submit previously queued ``command`` blocks as a batch request.
2686 Submit previously queued ``command`` blocks as a batch request.
2698
2687
2699 This action MUST be paired with a ``batchbegin`` action.
2688 This action MUST be paired with a ``batchbegin`` action.
2700
2689
2701 httprequest <method> <path>
2690 httprequest <method> <path>
2702 ---------------------------
2691 ---------------------------
2703
2692
2704 (HTTP peer only)
2693 (HTTP peer only)
2705
2694
2706 Send an HTTP request to the peer.
2695 Send an HTTP request to the peer.
2707
2696
2708 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2697 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2709
2698
2710 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2699 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2711 headers to add to the request. e.g. ``Accept: foo``.
2700 headers to add to the request. e.g. ``Accept: foo``.
2712
2701
2713 The following arguments are special:
2702 The following arguments are special:
2714
2703
2715 ``BODYFILE``
2704 ``BODYFILE``
2716 The content of the file defined as the value to this argument will be
2705 The content of the file defined as the value to this argument will be
2717 transferred verbatim as the HTTP request body.
2706 transferred verbatim as the HTTP request body.
2718
2707
2719 ``frame <type> <flags> <payload>``
2708 ``frame <type> <flags> <payload>``
2720 Send a unified protocol frame as part of the request body.
2709 Send a unified protocol frame as part of the request body.
2721
2710
2722 All frames will be collected and sent as the body to the HTTP
2711 All frames will be collected and sent as the body to the HTTP
2723 request.
2712 request.
2724
2713
2725 close
2714 close
2726 -----
2715 -----
2727
2716
2728 Close the connection to the server.
2717 Close the connection to the server.
2729
2718
2730 flush
2719 flush
2731 -----
2720 -----
2732
2721
2733 Flush data written to the server.
2722 Flush data written to the server.
2734
2723
2735 readavailable
2724 readavailable
2736 -------------
2725 -------------
2737
2726
2738 Close the write end of the connection and read all available data from
2727 Close the write end of the connection and read all available data from
2739 the server.
2728 the server.
2740
2729
2741 If the connection to the server encompasses multiple pipes, we poll both
2730 If the connection to the server encompasses multiple pipes, we poll both
2742 pipes and read available data.
2731 pipes and read available data.
2743
2732
2744 readline
2733 readline
2745 --------
2734 --------
2746
2735
2747 Read a line of output from the server. If there are multiple output
2736 Read a line of output from the server. If there are multiple output
2748 pipes, reads only the main pipe.
2737 pipes, reads only the main pipe.
2749
2738
2750 ereadline
2739 ereadline
2751 ---------
2740 ---------
2752
2741
2753 Like ``readline``, but read from the stderr pipe, if available.
2742 Like ``readline``, but read from the stderr pipe, if available.
2754
2743
2755 read <X>
2744 read <X>
2756 --------
2745 --------
2757
2746
2758 ``read()`` N bytes from the server's main output pipe.
2747 ``read()`` N bytes from the server's main output pipe.
2759
2748
2760 eread <X>
2749 eread <X>
2761 ---------
2750 ---------
2762
2751
2763 ``read()`` N bytes from the server's stderr pipe, if available.
2752 ``read()`` N bytes from the server's stderr pipe, if available.
2764
2753
2765 Specifying Unified Frame-Based Protocol Frames
2754 Specifying Unified Frame-Based Protocol Frames
2766 ----------------------------------------------
2755 ----------------------------------------------
2767
2756
2768 It is possible to emit a *Unified Frame-Based Protocol* by using special
2757 It is possible to emit a *Unified Frame-Based Protocol* by using special
2769 syntax.
2758 syntax.
2770
2759
2771 A frame is composed as a type, flags, and payload. These can be parsed
2760 A frame is composed as a type, flags, and payload. These can be parsed
2772 from a string of the form ``<requestid> <type> <flags> <payload>``. That is,
2761 from a string of the form ``<requestid> <type> <flags> <payload>``. That is,
2773 4 space-delimited strings.
2762 4 space-delimited strings.
2774
2763
2775 ``payload`` is the simplest: it is evaluated as a Python byte string
2764 ``payload`` is the simplest: it is evaluated as a Python byte string
2776 literal.
2765 literal.
2777
2766
2778 ``requestid`` is an integer defining the request identifier.
2767 ``requestid`` is an integer defining the request identifier.
2779
2768
2780 ``type`` can be an integer value for the frame type or the string name
2769 ``type`` can be an integer value for the frame type or the string name
2781 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
2770 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
2782 ``command-name``.
2771 ``command-name``.
2783
2772
2784 ``flags`` is a ``|`` delimited list of flag components. Each component
2773 ``flags`` is a ``|`` delimited list of flag components. Each component
2785 (and there can be just one) can be an integer or a flag name for the
2774 (and there can be just one) can be an integer or a flag name for the
2786 specified frame type. Values are resolved to integers and then bitwise
2775 specified frame type. Values are resolved to integers and then bitwise
2787 OR'd together.
2776 OR'd together.
2788 """
2777 """
2789 opts = pycompat.byteskwargs(opts)
2778 opts = pycompat.byteskwargs(opts)
2790
2779
2791 if opts['localssh'] and not repo:
2780 if opts['localssh'] and not repo:
2792 raise error.Abort(_('--localssh requires a repository'))
2781 raise error.Abort(_('--localssh requires a repository'))
2793
2782
2794 if opts['peer'] and opts['peer'] not in ('raw', 'ssh1', 'ssh2'):
2783 if opts['peer'] and opts['peer'] not in ('raw', 'ssh1', 'ssh2'):
2795 raise error.Abort(_('invalid value for --peer'),
2784 raise error.Abort(_('invalid value for --peer'),
2796 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2785 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2797
2786
2798 if path and opts['localssh']:
2787 if path and opts['localssh']:
2799 raise error.Abort(_('cannot specify --localssh with an explicit '
2788 raise error.Abort(_('cannot specify --localssh with an explicit '
2800 'path'))
2789 'path'))
2801
2790
2802 if ui.interactive():
2791 if ui.interactive():
2803 ui.write(_('(waiting for commands on stdin)\n'))
2792 ui.write(_('(waiting for commands on stdin)\n'))
2804
2793
2805 blocks = list(_parsewirelangblocks(ui.fin))
2794 blocks = list(_parsewirelangblocks(ui.fin))
2806
2795
2807 proc = None
2796 proc = None
2808 stdin = None
2797 stdin = None
2809 stdout = None
2798 stdout = None
2810 stderr = None
2799 stderr = None
2811 opener = None
2800 opener = None
2812
2801
2813 if opts['localssh']:
2802 if opts['localssh']:
2814 # We start the SSH server in its own process so there is process
2803 # We start the SSH server in its own process so there is process
2815 # separation. This prevents a whole class of potential bugs around
2804 # separation. This prevents a whole class of potential bugs around
2816 # shared state from interfering with server operation.
2805 # shared state from interfering with server operation.
2817 args = procutil.hgcmd() + [
2806 args = procutil.hgcmd() + [
2818 '-R', repo.root,
2807 '-R', repo.root,
2819 'debugserve', '--sshstdio',
2808 'debugserve', '--sshstdio',
2820 ]
2809 ]
2821 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2810 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2822 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2811 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2823 bufsize=0)
2812 bufsize=0)
2824
2813
2825 stdin = proc.stdin
2814 stdin = proc.stdin
2826 stdout = proc.stdout
2815 stdout = proc.stdout
2827 stderr = proc.stderr
2816 stderr = proc.stderr
2828
2817
2829 # We turn the pipes into observers so we can log I/O.
2818 # We turn the pipes into observers so we can log I/O.
2830 if ui.verbose or opts['peer'] == 'raw':
2819 if ui.verbose or opts['peer'] == 'raw':
2831 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2820 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2832 logdata=True)
2821 logdata=True)
2833 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2822 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2834 logdata=True)
2823 logdata=True)
2835 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2824 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2836 logdata=True)
2825 logdata=True)
2837
2826
2838 # --localssh also implies the peer connection settings.
2827 # --localssh also implies the peer connection settings.
2839
2828
2840 url = 'ssh://localserver'
2829 url = 'ssh://localserver'
2841 autoreadstderr = not opts['noreadstderr']
2830 autoreadstderr = not opts['noreadstderr']
2842
2831
2843 if opts['peer'] == 'ssh1':
2832 if opts['peer'] == 'ssh1':
2844 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2833 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2845 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2834 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2846 None, autoreadstderr=autoreadstderr)
2835 None, autoreadstderr=autoreadstderr)
2847 elif opts['peer'] == 'ssh2':
2836 elif opts['peer'] == 'ssh2':
2848 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2837 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2849 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2838 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2850 None, autoreadstderr=autoreadstderr)
2839 None, autoreadstderr=autoreadstderr)
2851 elif opts['peer'] == 'raw':
2840 elif opts['peer'] == 'raw':
2852 ui.write(_('using raw connection to peer\n'))
2841 ui.write(_('using raw connection to peer\n'))
2853 peer = None
2842 peer = None
2854 else:
2843 else:
2855 ui.write(_('creating ssh peer from handshake results\n'))
2844 ui.write(_('creating ssh peer from handshake results\n'))
2856 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
2845 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
2857 autoreadstderr=autoreadstderr)
2846 autoreadstderr=autoreadstderr)
2858
2847
2859 elif path:
2848 elif path:
2860 # We bypass hg.peer() so we can proxy the sockets.
2849 # We bypass hg.peer() so we can proxy the sockets.
2861 # TODO consider not doing this because we skip
2850 # TODO consider not doing this because we skip
2862 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
2851 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
2863 u = util.url(path)
2852 u = util.url(path)
2864 if u.scheme != 'http':
2853 if u.scheme != 'http':
2865 raise error.Abort(_('only http:// paths are currently supported'))
2854 raise error.Abort(_('only http:// paths are currently supported'))
2866
2855
2867 url, authinfo = u.authinfo()
2856 url, authinfo = u.authinfo()
2868 openerargs = {}
2857 openerargs = {}
2869
2858
2870 # Turn pipes/sockets into observers so we can log I/O.
2859 # Turn pipes/sockets into observers so we can log I/O.
2871 if ui.verbose:
2860 if ui.verbose:
2872 openerargs = {
2861 openerargs = {
2873 r'loggingfh': ui,
2862 r'loggingfh': ui,
2874 r'loggingname': b's',
2863 r'loggingname': b's',
2875 r'loggingopts': {
2864 r'loggingopts': {
2876 r'logdata': True,
2865 r'logdata': True,
2877 r'logdataapis': False,
2866 r'logdataapis': False,
2878 },
2867 },
2879 }
2868 }
2880
2869
2881 if ui.debugflag:
2870 if ui.debugflag:
2882 openerargs[r'loggingopts'][r'logdataapis'] = True
2871 openerargs[r'loggingopts'][r'logdataapis'] = True
2883
2872
2884 # Don't send default headers when in raw mode. This allows us to
2873 # Don't send default headers when in raw mode. This allows us to
2885 # bypass most of the behavior of our URL handling code so we can
2874 # bypass most of the behavior of our URL handling code so we can
2886 # have near complete control over what's sent on the wire.
2875 # have near complete control over what's sent on the wire.
2887 if opts['peer'] == 'raw':
2876 if opts['peer'] == 'raw':
2888 openerargs[r'sendaccept'] = False
2877 openerargs[r'sendaccept'] = False
2889
2878
2890 opener = urlmod.opener(ui, authinfo, **openerargs)
2879 opener = urlmod.opener(ui, authinfo, **openerargs)
2891
2880
2892 if opts['peer'] == 'raw':
2881 if opts['peer'] == 'raw':
2893 ui.write(_('using raw connection to peer\n'))
2882 ui.write(_('using raw connection to peer\n'))
2894 peer = None
2883 peer = None
2895 elif opts['peer']:
2884 elif opts['peer']:
2896 raise error.Abort(_('--peer %s not supported with HTTP peers') %
2885 raise error.Abort(_('--peer %s not supported with HTTP peers') %
2897 opts['peer'])
2886 opts['peer'])
2898 else:
2887 else:
2899 peer = httppeer.httppeer(ui, path, url, opener)
2888 peer = httppeer.httppeer(ui, path, url, opener)
2900 peer._fetchcaps()
2889 peer._fetchcaps()
2901
2890
2902 # We /could/ populate stdin/stdout with sock.makefile()...
2891 # We /could/ populate stdin/stdout with sock.makefile()...
2903 else:
2892 else:
2904 raise error.Abort(_('unsupported connection configuration'))
2893 raise error.Abort(_('unsupported connection configuration'))
2905
2894
2906 batchedcommands = None
2895 batchedcommands = None
2907
2896
2908 # Now perform actions based on the parsed wire language instructions.
2897 # Now perform actions based on the parsed wire language instructions.
2909 for action, lines in blocks:
2898 for action, lines in blocks:
2910 if action in ('raw', 'raw+'):
2899 if action in ('raw', 'raw+'):
2911 if not stdin:
2900 if not stdin:
2912 raise error.Abort(_('cannot call raw/raw+ on this peer'))
2901 raise error.Abort(_('cannot call raw/raw+ on this peer'))
2913
2902
2914 # Concatenate the data together.
2903 # Concatenate the data together.
2915 data = ''.join(l.lstrip() for l in lines)
2904 data = ''.join(l.lstrip() for l in lines)
2916 data = stringutil.unescapestr(data)
2905 data = stringutil.unescapestr(data)
2917 stdin.write(data)
2906 stdin.write(data)
2918
2907
2919 if action == 'raw+':
2908 if action == 'raw+':
2920 stdin.flush()
2909 stdin.flush()
2921 elif action == 'flush':
2910 elif action == 'flush':
2922 if not stdin:
2911 if not stdin:
2923 raise error.Abort(_('cannot call flush on this peer'))
2912 raise error.Abort(_('cannot call flush on this peer'))
2924 stdin.flush()
2913 stdin.flush()
2925 elif action.startswith('command'):
2914 elif action.startswith('command'):
2926 if not peer:
2915 if not peer:
2927 raise error.Abort(_('cannot send commands unless peer instance '
2916 raise error.Abort(_('cannot send commands unless peer instance '
2928 'is available'))
2917 'is available'))
2929
2918
2930 command = action.split(' ', 1)[1]
2919 command = action.split(' ', 1)[1]
2931
2920
2932 args = {}
2921 args = {}
2933 for line in lines:
2922 for line in lines:
2934 # We need to allow empty values.
2923 # We need to allow empty values.
2935 fields = line.lstrip().split(' ', 1)
2924 fields = line.lstrip().split(' ', 1)
2936 if len(fields) == 1:
2925 if len(fields) == 1:
2937 key = fields[0]
2926 key = fields[0]
2938 value = ''
2927 value = ''
2939 else:
2928 else:
2940 key, value = fields
2929 key, value = fields
2941
2930
2942 args[key] = stringutil.unescapestr(value)
2931 args[key] = stringutil.unescapestr(value)
2943
2932
2944 if batchedcommands is not None:
2933 if batchedcommands is not None:
2945 batchedcommands.append((command, args))
2934 batchedcommands.append((command, args))
2946 continue
2935 continue
2947
2936
2948 ui.status(_('sending %s command\n') % command)
2937 ui.status(_('sending %s command\n') % command)
2949
2938
2950 if 'PUSHFILE' in args:
2939 if 'PUSHFILE' in args:
2951 with open(args['PUSHFILE'], r'rb') as fh:
2940 with open(args['PUSHFILE'], r'rb') as fh:
2952 del args['PUSHFILE']
2941 del args['PUSHFILE']
2953 res, output = peer._callpush(command, fh,
2942 res, output = peer._callpush(command, fh,
2954 **pycompat.strkwargs(args))
2943 **pycompat.strkwargs(args))
2955 ui.status(_('result: %s\n') % stringutil.escapedata(res))
2944 ui.status(_('result: %s\n') % stringutil.escapedata(res))
2956 ui.status(_('remote output: %s\n') %
2945 ui.status(_('remote output: %s\n') %
2957 stringutil.escapedata(output))
2946 stringutil.escapedata(output))
2958 else:
2947 else:
2959 res = peer._call(command, **pycompat.strkwargs(args))
2948 res = peer._call(command, **pycompat.strkwargs(args))
2960 ui.status(_('response: %s\n') % stringutil.escapedata(res))
2949 ui.status(_('response: %s\n') % stringutil.escapedata(res))
2961
2950
2962 elif action == 'batchbegin':
2951 elif action == 'batchbegin':
2963 if batchedcommands is not None:
2952 if batchedcommands is not None:
2964 raise error.Abort(_('nested batchbegin not allowed'))
2953 raise error.Abort(_('nested batchbegin not allowed'))
2965
2954
2966 batchedcommands = []
2955 batchedcommands = []
2967 elif action == 'batchsubmit':
2956 elif action == 'batchsubmit':
2968 # There is a batching API we could go through. But it would be
2957 # There is a batching API we could go through. But it would be
2969 # difficult to normalize requests into function calls. It is easier
2958 # difficult to normalize requests into function calls. It is easier
2970 # to bypass this layer and normalize to commands + args.
2959 # to bypass this layer and normalize to commands + args.
2971 ui.status(_('sending batch with %d sub-commands\n') %
2960 ui.status(_('sending batch with %d sub-commands\n') %
2972 len(batchedcommands))
2961 len(batchedcommands))
2973 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
2962 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
2974 ui.status(_('response #%d: %s\n') %
2963 ui.status(_('response #%d: %s\n') %
2975 (i, stringutil.escapedata(chunk)))
2964 (i, stringutil.escapedata(chunk)))
2976
2965
2977 batchedcommands = None
2966 batchedcommands = None
2978
2967
2979 elif action.startswith('httprequest '):
2968 elif action.startswith('httprequest '):
2980 if not opener:
2969 if not opener:
2981 raise error.Abort(_('cannot use httprequest without an HTTP '
2970 raise error.Abort(_('cannot use httprequest without an HTTP '
2982 'peer'))
2971 'peer'))
2983
2972
2984 request = action.split(' ', 2)
2973 request = action.split(' ', 2)
2985 if len(request) != 3:
2974 if len(request) != 3:
2986 raise error.Abort(_('invalid httprequest: expected format is '
2975 raise error.Abort(_('invalid httprequest: expected format is '
2987 '"httprequest <method> <path>'))
2976 '"httprequest <method> <path>'))
2988
2977
2989 method, httppath = request[1:]
2978 method, httppath = request[1:]
2990 headers = {}
2979 headers = {}
2991 body = None
2980 body = None
2992 frames = []
2981 frames = []
2993 for line in lines:
2982 for line in lines:
2994 line = line.lstrip()
2983 line = line.lstrip()
2995 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
2984 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
2996 if m:
2985 if m:
2997 headers[m.group(1)] = m.group(2)
2986 headers[m.group(1)] = m.group(2)
2998 continue
2987 continue
2999
2988
3000 if line.startswith(b'BODYFILE '):
2989 if line.startswith(b'BODYFILE '):
3001 with open(line.split(b' ', 1), 'rb') as fh:
2990 with open(line.split(b' ', 1), 'rb') as fh:
3002 body = fh.read()
2991 body = fh.read()
3003 elif line.startswith(b'frame '):
2992 elif line.startswith(b'frame '):
3004 frame = wireprotoframing.makeframefromhumanstring(
2993 frame = wireprotoframing.makeframefromhumanstring(
3005 line[len(b'frame '):])
2994 line[len(b'frame '):])
3006
2995
3007 frames.append(frame)
2996 frames.append(frame)
3008 else:
2997 else:
3009 raise error.Abort(_('unknown argument to httprequest: %s') %
2998 raise error.Abort(_('unknown argument to httprequest: %s') %
3010 line)
2999 line)
3011
3000
3012 url = path + httppath
3001 url = path + httppath
3013
3002
3014 if frames:
3003 if frames:
3015 body = b''.join(bytes(f) for f in frames)
3004 body = b''.join(bytes(f) for f in frames)
3016
3005
3017 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3006 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3018
3007
3019 # urllib.Request insists on using has_data() as a proxy for
3008 # urllib.Request insists on using has_data() as a proxy for
3020 # determining the request method. Override that to use our
3009 # determining the request method. Override that to use our
3021 # explicitly requested method.
3010 # explicitly requested method.
3022 req.get_method = lambda: method
3011 req.get_method = lambda: method
3023
3012
3024 try:
3013 try:
3025 opener.open(req).read()
3014 opener.open(req).read()
3026 except util.urlerr.urlerror as e:
3015 except util.urlerr.urlerror as e:
3027 e.read()
3016 e.read()
3028
3017
3029 elif action == 'close':
3018 elif action == 'close':
3030 peer.close()
3019 peer.close()
3031 elif action == 'readavailable':
3020 elif action == 'readavailable':
3032 if not stdout or not stderr:
3021 if not stdout or not stderr:
3033 raise error.Abort(_('readavailable not available on this peer'))
3022 raise error.Abort(_('readavailable not available on this peer'))
3034
3023
3035 stdin.close()
3024 stdin.close()
3036 stdout.read()
3025 stdout.read()
3037 stderr.read()
3026 stderr.read()
3038
3027
3039 elif action == 'readline':
3028 elif action == 'readline':
3040 if not stdout:
3029 if not stdout:
3041 raise error.Abort(_('readline not available on this peer'))
3030 raise error.Abort(_('readline not available on this peer'))
3042 stdout.readline()
3031 stdout.readline()
3043 elif action == 'ereadline':
3032 elif action == 'ereadline':
3044 if not stderr:
3033 if not stderr:
3045 raise error.Abort(_('ereadline not available on this peer'))
3034 raise error.Abort(_('ereadline not available on this peer'))
3046 stderr.readline()
3035 stderr.readline()
3047 elif action.startswith('read '):
3036 elif action.startswith('read '):
3048 count = int(action.split(' ', 1)[1])
3037 count = int(action.split(' ', 1)[1])
3049 if not stdout:
3038 if not stdout:
3050 raise error.Abort(_('read not available on this peer'))
3039 raise error.Abort(_('read not available on this peer'))
3051 stdout.read(count)
3040 stdout.read(count)
3052 elif action.startswith('eread '):
3041 elif action.startswith('eread '):
3053 count = int(action.split(' ', 1)[1])
3042 count = int(action.split(' ', 1)[1])
3054 if not stderr:
3043 if not stderr:
3055 raise error.Abort(_('eread not available on this peer'))
3044 raise error.Abort(_('eread not available on this peer'))
3056 stderr.read(count)
3045 stderr.read(count)
3057 else:
3046 else:
3058 raise error.Abort(_('unknown action: %s') % action)
3047 raise error.Abort(_('unknown action: %s') % action)
3059
3048
3060 if batchedcommands is not None:
3049 if batchedcommands is not None:
3061 raise error.Abort(_('unclosed "batchbegin" request'))
3050 raise error.Abort(_('unclosed "batchbegin" request'))
3062
3051
3063 if peer:
3052 if peer:
3064 peer.close()
3053 peer.close()
3065
3054
3066 if proc:
3055 if proc:
3067 proc.kill()
3056 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 (re)
54 rev offset length linkrev nodeid p1 p2
55 0 0 5 ..... 1 b004912a8510 000000000000 000000000000 (re)
55 0 0 5 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 (re)
41 rev flag offset length size link p1 p2 nodeid
42 0 0000 0 3 2 ..... 0 -1 -1 362fef284ce2 (re)
42 0 0000 0 3 2 0 -1 -1 362fef284ce2
43 1 0000 3 5 4 ..... 1 0 -1 125144f7e028 (re)
43 1 0000 3 5 4 1 0 -1 125144f7e028
44 2 0000 8 7 6 ..... 2 1 -1 4c982badb186 (re)
44 2 0000 8 7 6 2 1 -1 4c982badb186
45 3 0000 15 9 8 ..... 3 2 -1 19b1fc555737 (re)
45 3 0000 15 9 8 3 2 -1 19b1fc555737
46
46
47 $ hg debugindex adifferentfile
47 $ hg debugindex adifferentfile
48 rev offset length ..... linkrev nodeid p1 p2 (re)
48 rev offset length linkrev nodeid p1 p2
49 0 0 75 ..... 7 2565f3199a74 000000000000 000000000000 (re)
49 0 0 75 7 2565f3199a74 000000000000 000000000000
50
50
51 $ hg debugindex anotherfile
51 $ hg debugindex anotherfile
52 rev offset length ..... linkrev nodeid p1 p2 (re)
52 rev offset length linkrev nodeid p1 p2
53 0 0 75 ..... 8 2565f3199a74 000000000000 000000000000 (re)
53 0 0 75 8 2565f3199a74 000000000000 000000000000
54
54
55 $ hg debugindex fred
55 $ hg debugindex fred
56 rev offset length ..... linkrev nodeid p1 p2 (re)
56 rev offset length linkrev nodeid p1 p2
57 0 0 8 ..... 6 12ab3bcc5ea4 000000000000 000000000000 (re)
57 0 0 8 6 12ab3bcc5ea4 000000000000 000000000000
58
58
59 $ hg debugindex --manifest
59 $ hg debugindex --manifest
60 rev offset length ..... linkrev nodeid p1 p2 (re)
60 rev offset length linkrev nodeid p1 p2
61 0 0 48 ..... 0 43eadb1d2d06 000000000000 000000000000 (re)
61 0 0 48 0 43eadb1d2d06 000000000000 000000000000
62 1 48 48 ..... 1 8b89697eba2c 43eadb1d2d06 000000000000 (re)
62 1 48 48 1 8b89697eba2c 43eadb1d2d06 000000000000
63 2 96 48 ..... 2 626a32663c2f 8b89697eba2c 000000000000 (re)
63 2 96 48 2 626a32663c2f 8b89697eba2c 000000000000
64 3 144 48 ..... 3 f54c32f13478 626a32663c2f 000000000000 (re)
64 3 144 48 3 f54c32f13478 626a32663c2f 000000000000
65 4 192 .. ..... 6 de68e904d169 626a32663c2f 000000000000 (re)
65 4 192 .. 6 de68e904d169 626a32663c2f 000000000000 (re)
66 5 2.. .. ..... 7 09bb521d218d de68e904d169 000000000000 (re)
66 5 2.. .. 7 09bb521d218d de68e904d169 000000000000 (re)
67 6 3.. 54 ..... 8 1fde233dfb0f f54c32f13478 000000000000 (re)
67 6 3.. 54 8 1fde233dfb0f f54c32f13478 000000000000 (re)
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 delta linkrev nodeid p1 p2
1164 rev offset length linkrev nodeid p1 p2
1165 0 0 89 -1 3 34a4d536c0c0 000000000000 000000000000
1165 0 0 89 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 delta linkrev nodeid p1 p2
1172 rev offset length linkrev nodeid p1 p2
1173 0 0 89 -1 3 34a4d536c0c0 000000000000 000000000000
1173 0 0 89 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 (re)
627 rev offset length linkrev nodeid p1 p2
628 0 0 6 ..... 0 26d3ca0dfd18 000000000000 000000000000 (re)
628 0 0 6 0 26d3ca0dfd18 000000000000 000000000000
629 1 6 7 ..... 1 d267bddd54f7 26d3ca0dfd18 000000000000 (re)
629 1 6 7 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 (re)
71 rev offset length linkrev nodeid p1 p2
72 0 0 3 ..... 0 b789fdd96dc2 000000000000 000000000000 (re)
72 0 0 3 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 (re)
87 rev offset length linkrev nodeid p1 p2
88 0 0 65 ..... 1 37d9b5d994ea 000000000000 000000000000 (re)
88 0 0 65 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 (re)
173 rev offset length linkrev nodeid p1 p2
174 0 0 5 ..... 0 2ed2a3912a0b 000000000000 000000000000 (re)
174 0 0 5 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 (re)
203 rev offset length linkrev nodeid p1 p2
204 0 0 69 ..... 1 7711d36246cc 000000000000 000000000000 (re)
204 0 0 69 1 7711d36246cc 000000000000 000000000000
205 1 69 6 ..... 2 bdf70a2b8d03 7711d36246cc 000000000000 (re)
205 1 69 6 2 bdf70a2b8d03 7711d36246cc 000000000000
206 2 75 71 ..... 3 b2558327ea8d 000000000000 000000000000 (re)
206 2 75 71 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 (re)
209 rev offset length linkrev nodeid p1 p2
210 0 0 5 ..... 0 2ed2a3912a0b 000000000000 000000000000 (re)
210 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
211 1 5 7 ..... 2 dd12c926cf16 2ed2a3912a0b 000000000000 (re)
211 1 5 7 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,406 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 --debug flag
42 $ hg debugindex a
42 $ hg debugindex a
43 rev offset length ..... linkrev nodeid p1 p2 (re)
43 rev offset length linkrev nodeid p1 p2
44 0 0 3 .... 0 b789fdd96dc2 000000000000 000000000000 (re)
44 0 0 3 0 b789fdd96dc2 000000000000 000000000000
45 $ hg --debug debugindex a
45 $ hg --debug debugindex a
46 rev offset length ..... linkrev nodeid p1 p2 (re)
46 rev offset length linkrev nodeid p1 p2
47 0 0 3 .... 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 (re)
47 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
48 $ hg debugindex -f 1 a
48 $ hg debugindex -f 1 a
49 rev flag offset length size ..... link p1 p2 nodeid (re)
49 rev flag offset length size link p1 p2 nodeid
50 0 0000 0 3 2 .... 0 -1 -1 b789fdd96dc2 (re)
50 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
51 $ hg --debug debugindex -f 1 a
51 $ hg --debug debugindex -f 1 a
52 rev flag offset length size ..... link p1 p2 nodeid (re)
52 rev flag offset length size link p1 p2 nodeid
53 0 0000 0 3 2 .... 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 (re)
53 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
54
54
55 debugdelta chain basic output
55 debugdelta chain basic output
56
56
57 $ hg debugdeltachain -m
57 $ hg debugdeltachain -m
58 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
58 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
59 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000
60
60
61 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
61 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
62 0 1 1
62 0 1 1
63
63
64 $ hg debugdeltachain -m -Tjson
64 $ hg debugdeltachain -m -Tjson
65 [
65 [
66 {
66 {
67 "chainid": 1,
67 "chainid": 1,
68 "chainlen": 1,
68 "chainlen": 1,
69 "chainratio": 1.02325581395,
69 "chainratio": 1.02325581395,
70 "chainsize": 44,
70 "chainsize": 44,
71 "compsize": 44,
71 "compsize": 44,
72 "deltatype": "base",
72 "deltatype": "base",
73 "extradist": 0,
73 "extradist": 0,
74 "extraratio": 0.0,
74 "extraratio": 0.0,
75 "lindist": 44,
75 "lindist": 44,
76 "prevrev": -1,
76 "prevrev": -1,
77 "rev": 0,
77 "rev": 0,
78 "uncompsize": 43
78 "uncompsize": 43
79 }
79 }
80 ]
80 ]
81
81
82 debugdelta chain with sparse read enabled
82 debugdelta chain with sparse read enabled
83
83
84 $ cat >> $HGRCPATH <<EOF
84 $ cat >> $HGRCPATH <<EOF
85 > [experimental]
85 > [experimental]
86 > sparse-read = True
86 > sparse-read = True
87 > EOF
87 > EOF
88 $ hg debugdeltachain -m
88 $ hg debugdeltachain -m
89 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
89 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
90 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
91
91
92 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
92 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
93 0 1 1 44 44 1.0
93 0 1 1 44 44 1.0
94
94
95 $ hg debugdeltachain -m -Tjson
95 $ hg debugdeltachain -m -Tjson
96 [
96 [
97 {
97 {
98 "chainid": 1,
98 "chainid": 1,
99 "chainlen": 1,
99 "chainlen": 1,
100 "chainratio": 1.02325581395,
100 "chainratio": 1.02325581395,
101 "chainsize": 44,
101 "chainsize": 44,
102 "compsize": 44,
102 "compsize": 44,
103 "deltatype": "base",
103 "deltatype": "base",
104 "extradist": 0,
104 "extradist": 0,
105 "extraratio": 0.0,
105 "extraratio": 0.0,
106 "largestblock": 44,
106 "largestblock": 44,
107 "lindist": 44,
107 "lindist": 44,
108 "prevrev": -1,
108 "prevrev": -1,
109 "readdensity": 1.0,
109 "readdensity": 1.0,
110 "readsize": 44,
110 "readsize": 44,
111 "rev": 0,
111 "rev": 0,
112 "srchunks": 1,
112 "srchunks": 1,
113 "uncompsize": 43
113 "uncompsize": 43
114 }
114 }
115 ]
115 ]
116
116
117 $ printf "This test checks things.\n" >> a
117 $ printf "This test checks things.\n" >> a
118 $ hg ci -m a
118 $ hg ci -m a
119 $ hg branch other
119 $ hg branch other
120 marked working directory as branch other
120 marked working directory as branch other
121 (branches are permanent and global, did you want a bookmark?)
121 (branches are permanent and global, did you want a bookmark?)
122 $ for i in `$TESTDIR/seq.py 5`; do
122 $ for i in `$TESTDIR/seq.py 5`; do
123 > printf "shorter ${i}" >> a
123 > printf "shorter ${i}" >> a
124 > hg ci -m "a other:$i"
124 > hg ci -m "a other:$i"
125 > hg up -q default
125 > hg up -q default
126 > printf "for the branch default we want longer chains: ${i}" >> a
126 > printf "for the branch default we want longer chains: ${i}" >> a
127 > hg ci -m "a default:$i"
127 > hg ci -m "a default:$i"
128 > hg up -q other
128 > hg up -q other
129 > done
129 > done
130 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
130 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
131 > --config experimental.sparse-read.density-threshold=0.50 \
131 > --config experimental.sparse-read.density-threshold=0.50 \
132 > --config experimental.sparse-read.min-gap-size=0
132 > --config experimental.sparse-read.min-gap-size=0
133 0 1
133 0 1
134 1 1
134 1 1
135 2 1
135 2 1
136 3 1
136 3 1
137 4 1
137 4 1
138 5 1
138 5 1
139 6 1
139 6 1
140 7 1
140 7 1
141 8 1
141 8 1
142 9 1
142 9 1
143 10 2
143 10 2
144 11 1
144 11 1
145 $ hg --config extensions.strip= strip --no-backup -r 1
145 $ hg --config extensions.strip= strip --no-backup -r 1
146 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
147
147
148 Test max chain len
148 Test max chain len
149 $ cat >> $HGRCPATH << EOF
149 $ cat >> $HGRCPATH << EOF
150 > [format]
150 > [format]
151 > maxchainlen=4
151 > maxchainlen=4
152 > EOF
152 > EOF
153
153
154 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
154 $ 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
155 $ hg ci -m a
156 $ printf "b\n" >> a
156 $ printf "b\n" >> a
157 $ hg ci -m a
157 $ hg ci -m a
158 $ printf "c\n" >> a
158 $ printf "c\n" >> a
159 $ hg ci -m a
159 $ hg ci -m a
160 $ printf "d\n" >> a
160 $ printf "d\n" >> a
161 $ hg ci -m a
161 $ hg ci -m a
162 $ printf "e\n" >> a
162 $ printf "e\n" >> a
163 $ hg ci -m a
163 $ hg ci -m a
164 $ printf "f\n" >> a
164 $ printf "f\n" >> a
165 $ hg ci -m a
165 $ hg ci -m a
166 $ printf 'g\n' >> a
166 $ printf 'g\n' >> a
167 $ hg ci -m a
167 $ hg ci -m a
168 $ printf 'h\n' >> a
168 $ printf 'h\n' >> a
169 $ hg ci -m a
169 $ hg ci -m a
170 $ hg debugrevlog -d a
170 $ hg debugrevlog -d a
171 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
171 # 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)
172 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
173 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
173 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
174 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
174 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
175 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
175 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
176 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
176 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
177 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
177 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
178 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
178 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
179 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
179 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
180 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
180 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
181
181
182 Test debuglocks command:
182 Test debuglocks command:
183
183
184 $ hg debuglocks
184 $ hg debuglocks
185 lock: free
185 lock: free
186 wlock: free
186 wlock: free
187
187
188 * Test setting the lock
188 * Test setting the lock
189
189
190 waitlock <file> will wait for file to be created. If it isn't in a reasonable
190 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
191 amount of time, displays error message and returns 1
192 $ waitlock() {
192 $ waitlock() {
193 > start=`date +%s`
193 > start=`date +%s`
194 > timeout=5
194 > timeout=5
195 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
195 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
196 > now=`date +%s`
196 > now=`date +%s`
197 > if [ "`expr $now - $start`" -gt $timeout ]; then
197 > if [ "`expr $now - $start`" -gt $timeout ]; then
198 > echo "timeout: $1 was not created in $timeout seconds"
198 > echo "timeout: $1 was not created in $timeout seconds"
199 > return 1
199 > return 1
200 > fi
200 > fi
201 > sleep 0.1
201 > sleep 0.1
202 > done
202 > done
203 > }
203 > }
204 $ dolock() {
204 $ dolock() {
205 > {
205 > {
206 > waitlock .hg/unlock
206 > waitlock .hg/unlock
207 > rm -f .hg/unlock
207 > rm -f .hg/unlock
208 > echo y
208 > echo y
209 > } | hg debuglocks "$@" > /dev/null
209 > } | hg debuglocks "$@" > /dev/null
210 > }
210 > }
211 $ dolock -s &
211 $ dolock -s &
212 $ waitlock .hg/store/lock
212 $ waitlock .hg/store/lock
213
213
214 $ hg debuglocks
214 $ hg debuglocks
215 lock: user *, process * (*s) (glob)
215 lock: user *, process * (*s) (glob)
216 wlock: free
216 wlock: free
217 [1]
217 [1]
218 $ touch .hg/unlock
218 $ touch .hg/unlock
219 $ wait
219 $ wait
220 $ [ -f .hg/store/lock ] || echo "There is no lock"
220 $ [ -f .hg/store/lock ] || echo "There is no lock"
221 There is no lock
221 There is no lock
222
222
223 * Test setting the wlock
223 * Test setting the wlock
224
224
225 $ dolock -S &
225 $ dolock -S &
226 $ waitlock .hg/wlock
226 $ waitlock .hg/wlock
227
227
228 $ hg debuglocks
228 $ hg debuglocks
229 lock: free
229 lock: free
230 wlock: user *, process * (*s) (glob)
230 wlock: user *, process * (*s) (glob)
231 [1]
231 [1]
232 $ touch .hg/unlock
232 $ touch .hg/unlock
233 $ wait
233 $ wait
234 $ [ -f .hg/wlock ] || echo "There is no wlock"
234 $ [ -f .hg/wlock ] || echo "There is no wlock"
235 There is no wlock
235 There is no wlock
236
236
237 * Test setting both locks
237 * Test setting both locks
238
238
239 $ dolock -Ss &
239 $ dolock -Ss &
240 $ waitlock .hg/wlock && waitlock .hg/store/lock
240 $ waitlock .hg/wlock && waitlock .hg/store/lock
241
241
242 $ hg debuglocks
242 $ hg debuglocks
243 lock: user *, process * (*s) (glob)
243 lock: user *, process * (*s) (glob)
244 wlock: user *, process * (*s) (glob)
244 wlock: user *, process * (*s) (glob)
245 [2]
245 [2]
246
246
247 * Test failing to set a lock
247 * Test failing to set a lock
248
248
249 $ hg debuglocks -s
249 $ hg debuglocks -s
250 abort: lock is already held
250 abort: lock is already held
251 [255]
251 [255]
252
252
253 $ hg debuglocks -S
253 $ hg debuglocks -S
254 abort: wlock is already held
254 abort: wlock is already held
255 [255]
255 [255]
256
256
257 $ touch .hg/unlock
257 $ touch .hg/unlock
258 $ wait
258 $ wait
259
259
260 $ hg debuglocks
260 $ hg debuglocks
261 lock: free
261 lock: free
262 wlock: free
262 wlock: free
263
263
264 * Test forcing the lock
264 * Test forcing the lock
265
265
266 $ dolock -s &
266 $ dolock -s &
267 $ waitlock .hg/store/lock
267 $ waitlock .hg/store/lock
268
268
269 $ hg debuglocks
269 $ hg debuglocks
270 lock: user *, process * (*s) (glob)
270 lock: user *, process * (*s) (glob)
271 wlock: free
271 wlock: free
272 [1]
272 [1]
273
273
274 $ hg debuglocks -L
274 $ hg debuglocks -L
275
275
276 $ hg debuglocks
276 $ hg debuglocks
277 lock: free
277 lock: free
278 wlock: free
278 wlock: free
279
279
280 $ touch .hg/unlock
280 $ touch .hg/unlock
281 $ wait
281 $ wait
282
282
283 * Test forcing the wlock
283 * Test forcing the wlock
284
284
285 $ dolock -S &
285 $ dolock -S &
286 $ waitlock .hg/wlock
286 $ waitlock .hg/wlock
287
287
288 $ hg debuglocks
288 $ hg debuglocks
289 lock: free
289 lock: free
290 wlock: user *, process * (*s) (glob)
290 wlock: user *, process * (*s) (glob)
291 [1]
291 [1]
292
292
293 $ hg debuglocks -W
293 $ hg debuglocks -W
294
294
295 $ hg debuglocks
295 $ hg debuglocks
296 lock: free
296 lock: free
297 wlock: free
297 wlock: free
298
298
299 $ touch .hg/unlock
299 $ touch .hg/unlock
300 $ wait
300 $ wait
301
301
302 Test WdirUnsupported exception
302 Test WdirUnsupported exception
303
303
304 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
304 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
305 abort: working directory revision cannot be specified
305 abort: working directory revision cannot be specified
306 [255]
306 [255]
307
307
308 Test cache warming command
308 Test cache warming command
309
309
310 $ rm -rf .hg/cache/
310 $ rm -rf .hg/cache/
311 $ hg debugupdatecaches --debug
311 $ hg debugupdatecaches --debug
312 updating the branch cache
312 updating the branch cache
313 $ ls -r .hg/cache/*
313 $ ls -r .hg/cache/*
314 .hg/cache/rbc-revs-v1
314 .hg/cache/rbc-revs-v1
315 .hg/cache/rbc-names-v1
315 .hg/cache/rbc-names-v1
316 .hg/cache/branch2-served
316 .hg/cache/branch2-served
317
317
318 $ cd ..
318 $ cd ..
319
319
320 Test internal debugstacktrace command
320 Test internal debugstacktrace command
321
321
322 $ cat > debugstacktrace.py << EOF
322 $ cat > debugstacktrace.py << EOF
323 > from __future__ import absolute_import
323 > from __future__ import absolute_import
324 > import sys
324 > import sys
325 > from mercurial import util
325 > from mercurial import util
326 > def f():
326 > def f():
327 > util.debugstacktrace(f=sys.stdout)
327 > util.debugstacktrace(f=sys.stdout)
328 > g()
328 > g()
329 > def g():
329 > def g():
330 > util.dst('hello from g\\n', skip=1)
330 > util.dst('hello from g\\n', skip=1)
331 > h()
331 > h()
332 > def h():
332 > def h():
333 > util.dst('hi ...\\nfrom h hidden in g', 1, depth=2)
333 > util.dst('hi ...\\nfrom h hidden in g', 1, depth=2)
334 > f()
334 > f()
335 > EOF
335 > EOF
336 $ $PYTHON debugstacktrace.py
336 $ $PYTHON debugstacktrace.py
337 stacktrace at:
337 stacktrace at:
338 debugstacktrace.py:12 in * (glob)
338 debugstacktrace.py:12 in * (glob)
339 debugstacktrace.py:5 in f
339 debugstacktrace.py:5 in f
340 hello from g at:
340 hello from g at:
341 debugstacktrace.py:12 in * (glob)
341 debugstacktrace.py:12 in * (glob)
342 debugstacktrace.py:6 in f
342 debugstacktrace.py:6 in f
343 hi ...
343 hi ...
344 from h hidden in g at:
344 from h hidden in g at:
345 debugstacktrace.py:6 in f
345 debugstacktrace.py:6 in f
346 debugstacktrace.py:9 in g
346 debugstacktrace.py:9 in g
347
347
348 Test debugcapabilities command:
348 Test debugcapabilities command:
349
349
350 $ hg debugcapabilities ./debugrevlog/
350 $ hg debugcapabilities ./debugrevlog/
351 Main capabilities:
351 Main capabilities:
352 branchmap
352 branchmap
353 $USUAL_BUNDLE2_CAPS$
353 $USUAL_BUNDLE2_CAPS$
354 getbundle
354 getbundle
355 known
355 known
356 lookup
356 lookup
357 pushkey
357 pushkey
358 unbundle
358 unbundle
359 Bundle2 capabilities:
359 Bundle2 capabilities:
360 HG20
360 HG20
361 bookmarks
361 bookmarks
362 changegroup
362 changegroup
363 01
363 01
364 02
364 02
365 digests
365 digests
366 md5
366 md5
367 sha1
367 sha1
368 sha512
368 sha512
369 error
369 error
370 abort
370 abort
371 unsupportedcontent
371 unsupportedcontent
372 pushraced
372 pushraced
373 pushkey
373 pushkey
374 hgtagsfnodes
374 hgtagsfnodes
375 listkeys
375 listkeys
376 phases
376 phases
377 heads
377 heads
378 pushkey
378 pushkey
379 remote-changegroup
379 remote-changegroup
380 http
380 http
381 https
381 https
382 rev-branch-cache
382 rev-branch-cache
383 stream
383 stream
384 v2
384 v2
385
385
386 Test debugpeer
386 Test debugpeer
387
387
388 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
388 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
389 url: ssh://user@dummy/debugrevlog
389 url: ssh://user@dummy/debugrevlog
390 local: no
390 local: no
391 pushable: yes
391 pushable: yes
392
392
393 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
393 $ 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 !)
394 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 !)
395 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
396 devel-peer-request: hello
396 devel-peer-request: hello
397 sending hello command
397 sending hello command
398 devel-peer-request: between
398 devel-peer-request: between
399 devel-peer-request: pairs: 81 bytes
399 devel-peer-request: pairs: 81 bytes
400 sending between command
400 sending between command
401 remote: 403
401 remote: 403
402 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
402 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
403 remote: 1
403 remote: 1
404 url: ssh://user@dummy/debugrevlog
404 url: ssh://user@dummy/debugrevlog
405 local: no
405 local: no
406 pushable: yes
406 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 (re)
67 rev offset length linkrev nodeid p1 p2
68 0 0 60 ..... 0 5e0375449e74 000000000000 000000000000 (re)
68 0 0 60 0 5e0375449e74 000000000000 000000000000
69 1 60 62 ..... 1 96155394af80 5e0375449e74 000000000000 (re)
69 1 60 62 1 96155394af80 5e0375449e74 000000000000
70 2 122 62 ..... 2 92cc4c306b19 5e0375449e74 000000000000 (re)
70 2 122 62 2 92cc4c306b19 5e0375449e74 000000000000
71 3 184 69 ..... 3 e16a66a37edd 92cc4c306b19 96155394af80 (re)
71 3 184 69 3 e16a66a37edd 92cc4c306b19 96155394af80
72 4 253 69 ..... 4 2ee31f665a86 96155394af80 92cc4c306b19 (re)
72 4 253 69 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 (re)
92 rev offset length linkrev nodeid p1 p2
93 0 0 5 ..... 0 2ed2a3912a0b 000000000000 000000000000 (re)
93 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
94 1 5 6 ..... 1 79d7492df40a 2ed2a3912a0b 000000000000 (re)
94 1 5 6 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 (re)
19 rev offset length linkrev nodeid p1 p2
20 0 0 3 ..... 0 1e88685f5dde 000000000000 000000000000 (re)
20 0 0 3 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 (re)
76 rev offset length linkrev nodeid p1 p2
77 0 0 73 ..... 0 cdca01651b96 000000000000 000000000000 (re)
77 0 0 73 0 cdca01651b96 000000000000 000000000000
78 1 73 68 ..... 1 f6718a9cb7f3 cdca01651b96 000000000000 (re)
78 1 73 68 1 f6718a9cb7f3 cdca01651b96 000000000000
79 2 141 68 ..... 2 bdd988058d16 cdca01651b96 000000000000 (re)
79 2 141 68 2 bdd988058d16 cdca01651b96 000000000000
80 3 209 66 ..... 3 d8a521142a3c f6718a9cb7f3 bdd988058d16 (re)
80 3 209 66 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 (re)
100 rev offset length linkrev nodeid p1 p2
101 0 0 3 ..... 0 b8e02f643373 000000000000 000000000000 (re)
101 0 0 3 0 b8e02f643373 000000000000 000000000000
102 1 3 4 ..... 1 2ffeddde1b65 b8e02f643373 000000000000 (re)
102 1 3 4 1 2ffeddde1b65 b8e02f643373 000000000000
103 2 7 4 ..... 2 33d1fb69067a b8e02f643373 000000000000 (re)
103 2 7 4 2 33d1fb69067a b8e02f643373 000000000000
104 3 11 4 ..... 3 aa27919ee430 2ffeddde1b65 33d1fb69067a (re)
104 3 11 4 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 (re)
109 rev offset length linkrev nodeid p1 p2
110 0 0 3 ..... 0 b8e02f643373 000000000000 000000000000 (re)
110 0 0 3 0 b8e02f643373 000000000000 000000000000
111 1 3 4 ..... 2 33d1fb69067a b8e02f643373 000000000000 (re)
111 1 3 4 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 (re)
116 rev offset length linkrev nodeid p1 p2
117 0 0 3 ..... 0 b8e02f643373 000000000000 000000000000 (re)
117 0 0 3 0 b8e02f643373 000000000000 000000000000
118 1 3 4 ..... 1 2ffeddde1b65 b8e02f643373 000000000000 (re)
118 1 3 4 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 (re)
123 rev offset length linkrev nodeid p1 p2
124 0 0 3 ..... 0 b8e02f643373 000000000000 000000000000 (re)
124 0 0 3 0 b8e02f643373 000000000000 000000000000
125 1 3 5 ..... 3 6128c0f33108 b8e02f643373 000000000000 (re)
125 1 3 5 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 (re)
147 rev offset length linkrev nodeid p1 p2
148 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
148 0 0 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 (re)
150 rev offset length linkrev nodeid p1 p2
151 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
151 0 0 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 (re)
153 rev offset length linkrev nodeid p1 p2
154 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
154 0 0 0 0 b80de5d13875 000000000000 000000000000
155 1 0 5 ..... 1 7fe919cc0336 b80de5d13875 000000000000 (re)
155 1 0 5 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 (re)
51 rev offset length linkrev nodeid p1 p2
52 0 0 5 ..... 0 2ed2a3912a0b 000000000000 000000000000 (re)
52 0 0 5 0 2ed2a3912a0b 000000000000 000000000000
53 1 5 9 ..... 1 6f4310b00b9a 2ed2a3912a0b 000000000000 (re)
53 1 5 9 1 6f4310b00b9a 2ed2a3912a0b 000000000000
54 2 14 5 ..... 2 c6fc755d7e68 6f4310b00b9a 000000000000 (re)
54 2 14 5 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 (re)
38 rev offset length linkrev nodeid p1 p2
39 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
39 0 0 77 2 d35118874825 000000000000 000000000000
40 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
40 1 77 76 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 (re)
46 rev offset length linkrev nodeid p1 p2
47 0 0 7 ..... 0 690b295714ae 000000000000 000000000000 (re)
47 0 0 7 0 690b295714ae 000000000000 000000000000
48 1 7 13 ..... 1 9e25c27b8757 690b295714ae 000000000000 (re)
48 1 7 13 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 (re)
91 rev offset length linkrev nodeid p1 p2
92 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
92 0 0 77 2 d35118874825 000000000000 000000000000
93 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
93 1 77 76 3 5345f5ab8abd 000000000000 d35118874825
94 2 153 7 ..... 4 ff4b45017382 d35118874825 000000000000 (re)
94 2 153 7 4 ff4b45017382 d35118874825 000000000000
95 3 160 13 ..... 5 3701b4893544 ff4b45017382 5345f5ab8abd (re)
95 3 160 13 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 (re)
126 rev offset length linkrev nodeid p1 p2
127 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
127 0 0 77 2 d35118874825 000000000000 000000000000
128 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
128 1 77 76 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 (re)
134 rev offset length linkrev nodeid p1 p2
135 0 0 7 ..... 0 690b295714ae 000000000000 000000000000 (re)
135 0 0 7 0 690b295714ae 000000000000 000000000000
136 1 7 13 ..... 1 9e25c27b8757 690b295714ae 000000000000 (re)
136 1 7 13 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 (re)
179 rev offset length linkrev nodeid p1 p2
180 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
180 0 0 77 2 d35118874825 000000000000 000000000000
181 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
181 1 77 76 3 5345f5ab8abd 000000000000 d35118874825
182 2 153 7 ..... 4 ff4b45017382 d35118874825 000000000000 (re)
182 2 153 7 4 ff4b45017382 d35118874825 000000000000
183 3 160 13 ..... 5 3701b4893544 ff4b45017382 5345f5ab8abd (re)
183 3 160 13 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 (re)
112 rev offset length linkrev nodeid p1 p2
113 0 0 7 ..... 0 01365c4cca56 000000000000 000000000000 (re)
113 0 0 7 0 01365c4cca56 000000000000 000000000000
114 1 7 9 ..... 1 7b013192566a 01365c4cca56 000000000000 (re)
114 1 7 9 1 7b013192566a 01365c4cca56 000000000000
115 2 16 15 ..... 2 8fe46a3eb557 01365c4cca56 000000000000 (re)
115 2 16 15 2 8fe46a3eb557 01365c4cca56 000000000000
116 3 31 2. ..... 3 fc3148072371 7b013192566a 8fe46a3eb557 (re)
116 3 31 2. 3 fc3148072371 7b013192566a 8fe46a3eb557 (re)
117 4 5. 25 ..... 4 d40249267ae3 8fe46a3eb557 000000000000 (re)
117 4 5. 25 4 d40249267ae3 8fe46a3eb557 000000000000 (re)
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 delta linkrev nodeid p1 p2
18 rev offset length linkrev nodeid p1 p2
19 0 0 47 -1 0 14a5d056d75a 000000000000 000000000000
19 0 0 47 0 14a5d056d75a 000000000000 000000000000
20 $ hg debugindex --dir foo
20 $ hg debugindex --dir foo
21 rev offset length delta linkrev nodeid p1 p2
21 rev offset length linkrev nodeid p1 p2
22 0 0 77 -1 0 e635c7857aef 000000000000 000000000000
22 0 0 77 0 e635c7857aef 000000000000 000000000000
23 $ hg debugindex --dir foo/
23 $ hg debugindex --dir foo/
24 rev offset length delta linkrev nodeid p1 p2
24 rev offset length linkrev nodeid p1 p2
25 0 0 77 -1 0 e635c7857aef 000000000000 000000000000
25 0 0 77 0 e635c7857aef 000000000000 000000000000
26 $ hg debugindex --dir foo/bar
26 $ hg debugindex --dir foo/bar
27 rev offset length delta linkrev nodeid p1 p2
27 rev offset length linkrev nodeid p1 p2
28 0 0 44 -1 0 e091d4224761 000000000000 000000000000
28 0 0 44 0 e091d4224761 000000000000 000000000000
29 $ hg debugindex --dir foo/bar/
29 $ hg debugindex --dir foo/bar/
30 rev offset length delta linkrev nodeid p1 p2
30 rev offset length linkrev nodeid p1 p2
31 0 0 44 -1 0 e091d4224761 000000000000 000000000000
31 0 0 44 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 base linkrev nodeid p1 p2
36 rev offset length linkrev nodeid p1 p2
37 0 0 64 0 0 9958b1af2add 000000000000 000000000000
37 0 0 64 0 9958b1af2add 000000000000 000000000000
38 1 64 81 1 1 2db4ce2a3bfe 9958b1af2add 000000000000
38 1 64 81 1 2db4ce2a3bfe 9958b1af2add 000000000000
39 2 145 75 2 2 0980ee31a742 2db4ce2a3bfe 000000000000
39 2 145 75 2 0980ee31a742 2db4ce2a3bfe 000000000000
40 3 220 (76|77) 3 3 4410145019b7 0980ee31a742 000000000000 (re)
40 3 220 (76|77) 3 4410145019b7 0980ee31a742 000000000000 (re)
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 base link p1 p2 nodeid
147 rev flag offset length size link p1 p2 nodeid
148 0 0000 0 63 62 0 0 2 -1 7c31755bf9b5
148 0 0000 0 63 62 0 2 -1 7c31755bf9b5
149 1 0000 63 66 65 1 1 0 2 26333235a41c
149 1 0000 63 66 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 base link p1 p2 nodeid
157 rev flag offset length size link p1 p2 nodeid
158 0 0000 0 63 62 0 0 65536 -1 7c31755bf9b5
158 0 0000 0 63 62 0 65536 -1 7c31755bf9b5
159 1 0000 63 66 65 1 1 0 65536 26333235a41c
159 1 0000 63 66 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 (re)
67 rev offset length linkrev nodeid p1 p2
68 0 0 67 ..... 1 57eacc201a7f 000000000000 000000000000 (re)
68 0 0 67 1 57eacc201a7f 000000000000 000000000000
69 1 67 72 ..... 3 4727ba907962 000000000000 57eacc201a7f (re)
69 1 67 72 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 (re)
19 rev offset length linkrev nodeid p1 p2
20 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
20 0 0 0 0 b80de5d13875 000000000000 000000000000
21 1 0 13 ..... 1 0376abec49b8 000000000000 000000000000 (re)
21 1 0 13 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 delta linkrev nodeid p1 p2
43 rev offset length linkrev nodeid p1 p2
44 0 0 19 -1 2 99e0332bd498 000000000000 000000000000
44 0 0 19 2 99e0332bd498 000000000000 000000000000
45 1 19 12 0 3 6674f57a23d8 99e0332bd498 000000000000
45 1 19 12 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 (re)
37 rev offset length linkrev nodeid p1 p2
38 0 0 112 ..... 0 6f105cbb914d 000000000000 000000000000 (re)
38 0 0 112 0 6f105cbb914d 000000000000 000000000000
39 1 112 56 ..... 3 1b55917b3699 000000000000 000000000000 (re)
39 1 112 56 3 1b55917b3699 000000000000 000000000000
40 2 168 123 ..... 1 8f3d04e263e5 000000000000 000000000000 (re)
40 2 168 123 1 8f3d04e263e5 000000000000 000000000000
41 3 291 122 ..... 2 f0ef8726ac4f 000000000000 000000000000 (re)
41 3 291 122 2 f0ef8726ac4f 000000000000 000000000000
42 4 413 87 ..... 4 0b76e38b4070 000000000000 000000000000 (re)
42 4 413 87 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 (re)
50 rev offset length linkrev nodeid p1 p2
51 0 0 3 ..... 0 b8e02f643373 000000000000 000000000000 (re)
51 0 0 3 0 b8e02f643373 000000000000 000000000000
52 1 3 3 ..... 1 5d9299349fc0 000000000000 000000000000 (re)
52 1 3 3 1 5d9299349fc0 000000000000 000000000000
53 2 6 3 ..... 2 2661d26c6496 000000000000 000000000000 (re)
53 2 6 3 2 2661d26c6496 000000000000 000000000000
54
54
55 021
55 021
56 rev offset length ..... linkrev nodeid p1 p2 (re)
56 rev offset length linkrev nodeid p1 p2
57 0 0 3 ..... 0 b8e02f643373 000000000000 000000000000 (re)
57 0 0 3 0 b8e02f643373 000000000000 000000000000
58 1 3 3 ..... 2 5d9299349fc0 000000000000 000000000000 (re)
58 1 3 3 2 5d9299349fc0 000000000000 000000000000
59 2 6 3 ..... 1 2661d26c6496 000000000000 000000000000 (re)
59 2 6 3 1 2661d26c6496 000000000000 000000000000
60
60
61 102
61 102
62 rev offset length ..... linkrev nodeid p1 p2 (re)
62 rev offset length linkrev nodeid p1 p2
63 0 0 3 ..... 1 b8e02f643373 000000000000 000000000000 (re)
63 0 0 3 1 b8e02f643373 000000000000 000000000000
64 1 3 3 ..... 0 5d9299349fc0 000000000000 000000000000 (re)
64 1 3 3 0 5d9299349fc0 000000000000 000000000000
65 2 6 3 ..... 2 2661d26c6496 000000000000 000000000000 (re)
65 2 6 3 2 2661d26c6496 000000000000 000000000000
66
66
67 120
67 120
68 rev offset length ..... linkrev nodeid p1 p2 (re)
68 rev offset length linkrev nodeid p1 p2
69 0 0 3 ..... 1 b8e02f643373 000000000000 000000000000 (re)
69 0 0 3 1 b8e02f643373 000000000000 000000000000
70 1 3 3 ..... 2 5d9299349fc0 000000000000 000000000000 (re)
70 1 3 3 2 5d9299349fc0 000000000000 000000000000
71 2 6 3 ..... 0 2661d26c6496 000000000000 000000000000 (re)
71 2 6 3 0 2661d26c6496 000000000000 000000000000
72
72
73 201
73 201
74 rev offset length ..... linkrev nodeid p1 p2 (re)
74 rev offset length linkrev nodeid p1 p2
75 0 0 3 ..... 2 b8e02f643373 000000000000 000000000000 (re)
75 0 0 3 2 b8e02f643373 000000000000 000000000000
76 1 3 3 ..... 0 5d9299349fc0 000000000000 000000000000 (re)
76 1 3 3 0 5d9299349fc0 000000000000 000000000000
77 2 6 3 ..... 1 2661d26c6496 000000000000 000000000000 (re)
77 2 6 3 1 2661d26c6496 000000000000 000000000000
78
78
79 210
79 210
80 rev offset length ..... linkrev nodeid p1 p2 (re)
80 rev offset length linkrev nodeid p1 p2
81 0 0 3 ..... 2 b8e02f643373 000000000000 000000000000 (re)
81 0 0 3 2 b8e02f643373 000000000000 000000000000
82 1 3 3 ..... 1 5d9299349fc0 000000000000 000000000000 (re)
82 1 3 3 1 5d9299349fc0 000000000000 000000000000
83 2 6 3 ..... 0 2661d26c6496 000000000000 000000000000 (re)
83 2 6 3 0 2661d26c6496 000000000000 000000000000
84
84
85 manifest-file
85 manifest-file
86 rev offset length ..... linkrev nodeid p1 p2 (re)
86 rev offset length linkrev nodeid p1 p2
87 0 0 3 ..... 3 b8e02f643373 000000000000 000000000000 (re)
87 0 0 3 3 b8e02f643373 000000000000 000000000000
88 1 3 3 ..... 4 5d9299349fc0 000000000000 000000000000 (re)
88 1 3 3 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 delta linkrev nodeid p1 p2
142 rev offset length linkrev nodeid p1 p2
143 0 0 54 -1 1 8b3ffd73f901 000000000000 000000000000
143 0 0 54 1 8b3ffd73f901 000000000000 000000000000
144 1 54 68 0 2 68e9d057c5a8 8b3ffd73f901 000000000000
144 1 54 68 2 68e9d057c5a8 8b3ffd73f901 000000000000
145 2 122 12 1 4 4698198d2624 68e9d057c5a8 000000000000
145 2 122 12 4 4698198d2624 68e9d057c5a8 000000000000
146 3 134 55 1 5 44844058ccce 68e9d057c5a8 000000000000
146 3 134 55 5 44844058ccce 68e9d057c5a8 000000000000
147 4 189 55 1 6 bf3d9b744927 68e9d057c5a8 000000000000
147 4 189 55 6 bf3d9b744927 68e9d057c5a8 000000000000
148 5 244 55 4 7 dde7c0af2a03 bf3d9b744927 44844058ccce
148 5 244 55 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 delta linkrev nodeid p1 p2
288 rev offset length linkrev nodeid p1 p2
289 0 0 80 -1 0 40536115ed9e 000000000000 000000000000
289 0 0 80 0 40536115ed9e 000000000000 000000000000
290 1 80 83 0 1 f3376063c255 40536115ed9e 000000000000
290 1 80 83 1 f3376063c255 40536115ed9e 000000000000
291 2 163 89 0 2 5d9b9da231a2 40536115ed9e 000000000000
291 2 163 89 2 5d9b9da231a2 40536115ed9e 000000000000
292 3 252 83 2 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
292 3 252 83 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
293 4 335 124 1 4 51e32a8c60ee f3376063c255 000000000000
293 4 335 124 4 51e32a8c60ee f3376063c255 000000000000
294 5 459 126 2 5 cc5baa78b230 5d9b9da231a2 f3376063c255
294 5 459 126 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 delta linkrev nodeid p1 p2
308 rev offset length linkrev nodeid p1 p2
309 0 0 127 -1 4 064927a0648a 000000000000 000000000000
309 0 0 127 4 064927a0648a 000000000000 000000000000
310 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
310 1 127 111 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 delta linkrev nodeid p1 p2
314 rev offset length linkrev nodeid p1 p2
315 0 0 127 -1 4 064927a0648a 000000000000 000000000000
315 0 0 127 4 064927a0648a 000000000000 000000000000
316 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
316 1 127 111 5 25ecb8cb8618 000000000000 000000000000
317 2 238 55 1 6 5b16163a30c6 25ecb8cb8618 000000000000
317 2 238 55 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 delta linkrev nodeid p1 p2
327 rev offset length linkrev nodeid p1 p2
328 0 0 127 -1 4 064927a0648a 000000000000 000000000000
328 0 0 127 4 064927a0648a 000000000000 000000000000
329 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
329 1 127 111 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 delta linkrev nodeid p1 p2
352 rev offset length linkrev nodeid p1 p2
353 0 0 127 -1 4 064927a0648a 000000000000 000000000000
353 0 0 127 4 064927a0648a 000000000000 000000000000
354 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
354 1 127 111 5 25ecb8cb8618 000000000000 000000000000
355 2 238 55 1 6 5b16163a30c6 25ecb8cb8618 000000000000
355 2 238 55 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