##// END OF EJS Templates
debugdirstate: deprecate --nodates in favor of --no-dates...
Martin von Zweigbergk -
r39796:7e99b027 default
parent child Browse files
Show More
@@ -1,3364 +1,3367 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 time
24 import time
25
25
26 from .i18n import _
26 from .i18n import _
27 from .node import (
27 from .node import (
28 bin,
28 bin,
29 hex,
29 hex,
30 nullhex,
30 nullhex,
31 nullid,
31 nullid,
32 nullrev,
32 nullrev,
33 short,
33 short,
34 )
34 )
35 from . import (
35 from . import (
36 bundle2,
36 bundle2,
37 changegroup,
37 changegroup,
38 cmdutil,
38 cmdutil,
39 color,
39 color,
40 context,
40 context,
41 dagparser,
41 dagparser,
42 encoding,
42 encoding,
43 error,
43 error,
44 exchange,
44 exchange,
45 extensions,
45 extensions,
46 filemerge,
46 filemerge,
47 filesetlang,
47 filesetlang,
48 formatter,
48 formatter,
49 hg,
49 hg,
50 httppeer,
50 httppeer,
51 localrepo,
51 localrepo,
52 lock as lockmod,
52 lock as lockmod,
53 logcmdutil,
53 logcmdutil,
54 merge as mergemod,
54 merge as mergemod,
55 obsolete,
55 obsolete,
56 obsutil,
56 obsutil,
57 phases,
57 phases,
58 policy,
58 policy,
59 pvec,
59 pvec,
60 pycompat,
60 pycompat,
61 registrar,
61 registrar,
62 repair,
62 repair,
63 revlog,
63 revlog,
64 revset,
64 revset,
65 revsetlang,
65 revsetlang,
66 scmutil,
66 scmutil,
67 setdiscovery,
67 setdiscovery,
68 simplemerge,
68 simplemerge,
69 sshpeer,
69 sshpeer,
70 sslutil,
70 sslutil,
71 streamclone,
71 streamclone,
72 templater,
72 templater,
73 treediscovery,
73 treediscovery,
74 upgrade,
74 upgrade,
75 url as urlmod,
75 url as urlmod,
76 util,
76 util,
77 vfs as vfsmod,
77 vfs as vfsmod,
78 wireprotoframing,
78 wireprotoframing,
79 wireprotoserver,
79 wireprotoserver,
80 wireprotov2peer,
80 wireprotov2peer,
81 )
81 )
82 from .utils import (
82 from .utils import (
83 cborutil,
83 cborutil,
84 dateutil,
84 dateutil,
85 procutil,
85 procutil,
86 stringutil,
86 stringutil,
87 )
87 )
88
88
89 from .revlogutils import (
89 from .revlogutils import (
90 deltas as deltautil
90 deltas as deltautil
91 )
91 )
92
92
93 release = lockmod.release
93 release = lockmod.release
94
94
95 command = registrar.command()
95 command = registrar.command()
96
96
97 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
97 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
98 def debugancestor(ui, repo, *args):
98 def debugancestor(ui, repo, *args):
99 """find the ancestor revision of two revisions in a given index"""
99 """find the ancestor revision of two revisions in a given index"""
100 if len(args) == 3:
100 if len(args) == 3:
101 index, rev1, rev2 = args
101 index, rev1, rev2 = args
102 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
102 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
103 lookup = r.lookup
103 lookup = r.lookup
104 elif len(args) == 2:
104 elif len(args) == 2:
105 if not repo:
105 if not repo:
106 raise error.Abort(_('there is no Mercurial repository here '
106 raise error.Abort(_('there is no Mercurial repository here '
107 '(.hg not found)'))
107 '(.hg not found)'))
108 rev1, rev2 = args
108 rev1, rev2 = args
109 r = repo.changelog
109 r = repo.changelog
110 lookup = repo.lookup
110 lookup = repo.lookup
111 else:
111 else:
112 raise error.Abort(_('either two or three arguments required'))
112 raise error.Abort(_('either two or three arguments required'))
113 a = r.ancestor(lookup(rev1), lookup(rev2))
113 a = r.ancestor(lookup(rev1), lookup(rev2))
114 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
114 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
115
115
116 @command('debugapplystreamclonebundle', [], 'FILE')
116 @command('debugapplystreamclonebundle', [], 'FILE')
117 def debugapplystreamclonebundle(ui, repo, fname):
117 def debugapplystreamclonebundle(ui, repo, fname):
118 """apply a stream clone bundle file"""
118 """apply a stream clone bundle file"""
119 f = hg.openpath(ui, fname)
119 f = hg.openpath(ui, fname)
120 gen = exchange.readbundle(ui, f, fname)
120 gen = exchange.readbundle(ui, f, fname)
121 gen.apply(repo)
121 gen.apply(repo)
122
122
123 @command('debugbuilddag',
123 @command('debugbuilddag',
124 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
124 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
125 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
125 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
126 ('n', 'new-file', None, _('add new file at each rev'))],
126 ('n', 'new-file', None, _('add new file at each rev'))],
127 _('[OPTION]... [TEXT]'))
127 _('[OPTION]... [TEXT]'))
128 def debugbuilddag(ui, repo, text=None,
128 def debugbuilddag(ui, repo, text=None,
129 mergeable_file=False,
129 mergeable_file=False,
130 overwritten_file=False,
130 overwritten_file=False,
131 new_file=False):
131 new_file=False):
132 """builds a repo with a given DAG from scratch in the current empty repo
132 """builds a repo with a given DAG from scratch in the current empty repo
133
133
134 The description of the DAG is read from stdin if not given on the
134 The description of the DAG is read from stdin if not given on the
135 command line.
135 command line.
136
136
137 Elements:
137 Elements:
138
138
139 - "+n" is a linear run of n nodes based on the current default parent
139 - "+n" is a linear run of n nodes based on the current default parent
140 - "." is a single node based on the current default parent
140 - "." is a single node based on the current default parent
141 - "$" resets the default parent to null (implied at the start);
141 - "$" resets the default parent to null (implied at the start);
142 otherwise the default parent is always the last node created
142 otherwise the default parent is always the last node created
143 - "<p" sets the default parent to the backref p
143 - "<p" sets the default parent to the backref p
144 - "*p" is a fork at parent p, which is a backref
144 - "*p" is a fork at parent p, which is a backref
145 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
145 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
146 - "/p2" is a merge of the preceding node and p2
146 - "/p2" is a merge of the preceding node and p2
147 - ":tag" defines a local tag for the preceding node
147 - ":tag" defines a local tag for the preceding node
148 - "@branch" sets the named branch for subsequent nodes
148 - "@branch" sets the named branch for subsequent nodes
149 - "#...\\n" is a comment up to the end of the line
149 - "#...\\n" is a comment up to the end of the line
150
150
151 Whitespace between the above elements is ignored.
151 Whitespace between the above elements is ignored.
152
152
153 A backref is either
153 A backref is either
154
154
155 - a number n, which references the node curr-n, where curr is the current
155 - a number n, which references the node curr-n, where curr is the current
156 node, or
156 node, or
157 - the name of a local tag you placed earlier using ":tag", or
157 - the name of a local tag you placed earlier using ":tag", or
158 - empty to denote the default parent.
158 - empty to denote the default parent.
159
159
160 All string valued-elements are either strictly alphanumeric, or must
160 All string valued-elements are either strictly alphanumeric, or must
161 be enclosed in double quotes ("..."), with "\\" as escape character.
161 be enclosed in double quotes ("..."), with "\\" as escape character.
162 """
162 """
163
163
164 if text is None:
164 if text is None:
165 ui.status(_("reading DAG from stdin\n"))
165 ui.status(_("reading DAG from stdin\n"))
166 text = ui.fin.read()
166 text = ui.fin.read()
167
167
168 cl = repo.changelog
168 cl = repo.changelog
169 if len(cl) > 0:
169 if len(cl) > 0:
170 raise error.Abort(_('repository is not empty'))
170 raise error.Abort(_('repository is not empty'))
171
171
172 # determine number of revs in DAG
172 # determine number of revs in DAG
173 total = 0
173 total = 0
174 for type, data in dagparser.parsedag(text):
174 for type, data in dagparser.parsedag(text):
175 if type == 'n':
175 if type == 'n':
176 total += 1
176 total += 1
177
177
178 if mergeable_file:
178 if mergeable_file:
179 linesperrev = 2
179 linesperrev = 2
180 # make a file with k lines per rev
180 # make a file with k lines per rev
181 initialmergedlines = ['%d' % i
181 initialmergedlines = ['%d' % i
182 for i in pycompat.xrange(0, total * linesperrev)]
182 for i in pycompat.xrange(0, total * linesperrev)]
183 initialmergedlines.append("")
183 initialmergedlines.append("")
184
184
185 tags = []
185 tags = []
186 progress = ui.makeprogress(_('building'), unit=_('revisions'),
186 progress = ui.makeprogress(_('building'), unit=_('revisions'),
187 total=total)
187 total=total)
188 with progress, repo.wlock(), repo.lock(), repo.transaction("builddag"):
188 with progress, repo.wlock(), repo.lock(), repo.transaction("builddag"):
189 at = -1
189 at = -1
190 atbranch = 'default'
190 atbranch = 'default'
191 nodeids = []
191 nodeids = []
192 id = 0
192 id = 0
193 progress.update(id)
193 progress.update(id)
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 progress.update(id)
266 progress.update(id)
267
267
268 if tags:
268 if tags:
269 repo.vfs.write("localtags", "".join(tags))
269 repo.vfs.write("localtags", "".join(tags))
270
270
271 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
271 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
272 indent_string = ' ' * indent
272 indent_string = ' ' * indent
273 if all:
273 if all:
274 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
274 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
275 % indent_string)
275 % indent_string)
276
276
277 def showchunks(named):
277 def showchunks(named):
278 ui.write("\n%s%s\n" % (indent_string, named))
278 ui.write("\n%s%s\n" % (indent_string, named))
279 for deltadata in gen.deltaiter():
279 for deltadata in gen.deltaiter():
280 node, p1, p2, cs, deltabase, delta, flags = deltadata
280 node, p1, p2, cs, deltabase, delta, flags = deltadata
281 ui.write("%s%s %s %s %s %s %d\n" %
281 ui.write("%s%s %s %s %s %s %d\n" %
282 (indent_string, hex(node), hex(p1), hex(p2),
282 (indent_string, hex(node), hex(p1), hex(p2),
283 hex(cs), hex(deltabase), len(delta)))
283 hex(cs), hex(deltabase), len(delta)))
284
284
285 chunkdata = gen.changelogheader()
285 chunkdata = gen.changelogheader()
286 showchunks("changelog")
286 showchunks("changelog")
287 chunkdata = gen.manifestheader()
287 chunkdata = gen.manifestheader()
288 showchunks("manifest")
288 showchunks("manifest")
289 for chunkdata in iter(gen.filelogheader, {}):
289 for chunkdata in iter(gen.filelogheader, {}):
290 fname = chunkdata['filename']
290 fname = chunkdata['filename']
291 showchunks(fname)
291 showchunks(fname)
292 else:
292 else:
293 if isinstance(gen, bundle2.unbundle20):
293 if isinstance(gen, bundle2.unbundle20):
294 raise error.Abort(_('use debugbundle2 for this file'))
294 raise error.Abort(_('use debugbundle2 for this file'))
295 chunkdata = gen.changelogheader()
295 chunkdata = gen.changelogheader()
296 for deltadata in gen.deltaiter():
296 for deltadata in gen.deltaiter():
297 node, p1, p2, cs, deltabase, delta, flags = deltadata
297 node, p1, p2, cs, deltabase, delta, flags = deltadata
298 ui.write("%s%s\n" % (indent_string, hex(node)))
298 ui.write("%s%s\n" % (indent_string, hex(node)))
299
299
300 def _debugobsmarkers(ui, part, indent=0, **opts):
300 def _debugobsmarkers(ui, part, indent=0, **opts):
301 """display version and markers contained in 'data'"""
301 """display version and markers contained in 'data'"""
302 opts = pycompat.byteskwargs(opts)
302 opts = pycompat.byteskwargs(opts)
303 data = part.read()
303 data = part.read()
304 indent_string = ' ' * indent
304 indent_string = ' ' * indent
305 try:
305 try:
306 version, markers = obsolete._readmarkers(data)
306 version, markers = obsolete._readmarkers(data)
307 except error.UnknownVersion as exc:
307 except error.UnknownVersion as exc:
308 msg = "%sunsupported version: %s (%d bytes)\n"
308 msg = "%sunsupported version: %s (%d bytes)\n"
309 msg %= indent_string, exc.version, len(data)
309 msg %= indent_string, exc.version, len(data)
310 ui.write(msg)
310 ui.write(msg)
311 else:
311 else:
312 msg = "%sversion: %d (%d bytes)\n"
312 msg = "%sversion: %d (%d bytes)\n"
313 msg %= indent_string, version, len(data)
313 msg %= indent_string, version, len(data)
314 ui.write(msg)
314 ui.write(msg)
315 fm = ui.formatter('debugobsolete', opts)
315 fm = ui.formatter('debugobsolete', opts)
316 for rawmarker in sorted(markers):
316 for rawmarker in sorted(markers):
317 m = obsutil.marker(None, rawmarker)
317 m = obsutil.marker(None, rawmarker)
318 fm.startitem()
318 fm.startitem()
319 fm.plain(indent_string)
319 fm.plain(indent_string)
320 cmdutil.showmarker(fm, m)
320 cmdutil.showmarker(fm, m)
321 fm.end()
321 fm.end()
322
322
323 def _debugphaseheads(ui, data, indent=0):
323 def _debugphaseheads(ui, data, indent=0):
324 """display version and markers contained in 'data'"""
324 """display version and markers contained in 'data'"""
325 indent_string = ' ' * indent
325 indent_string = ' ' * indent
326 headsbyphase = phases.binarydecode(data)
326 headsbyphase = phases.binarydecode(data)
327 for phase in phases.allphases:
327 for phase in phases.allphases:
328 for head in headsbyphase[phase]:
328 for head in headsbyphase[phase]:
329 ui.write(indent_string)
329 ui.write(indent_string)
330 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
330 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
331
331
332 def _quasirepr(thing):
332 def _quasirepr(thing):
333 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
333 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
334 return '{%s}' % (
334 return '{%s}' % (
335 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
335 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
336 return pycompat.bytestr(repr(thing))
336 return pycompat.bytestr(repr(thing))
337
337
338 def _debugbundle2(ui, gen, all=None, **opts):
338 def _debugbundle2(ui, gen, all=None, **opts):
339 """lists the contents of a bundle2"""
339 """lists the contents of a bundle2"""
340 if not isinstance(gen, bundle2.unbundle20):
340 if not isinstance(gen, bundle2.unbundle20):
341 raise error.Abort(_('not a bundle2 file'))
341 raise error.Abort(_('not a bundle2 file'))
342 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
342 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
343 parttypes = opts.get(r'part_type', [])
343 parttypes = opts.get(r'part_type', [])
344 for part in gen.iterparts():
344 for part in gen.iterparts():
345 if parttypes and part.type not in parttypes:
345 if parttypes and part.type not in parttypes:
346 continue
346 continue
347 msg = '%s -- %s (mandatory: %r)\n'
347 msg = '%s -- %s (mandatory: %r)\n'
348 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
348 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
349 if part.type == 'changegroup':
349 if part.type == 'changegroup':
350 version = part.params.get('version', '01')
350 version = part.params.get('version', '01')
351 cg = changegroup.getunbundler(version, part, 'UN')
351 cg = changegroup.getunbundler(version, part, 'UN')
352 if not ui.quiet:
352 if not ui.quiet:
353 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
353 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
354 if part.type == 'obsmarkers':
354 if part.type == 'obsmarkers':
355 if not ui.quiet:
355 if not ui.quiet:
356 _debugobsmarkers(ui, part, indent=4, **opts)
356 _debugobsmarkers(ui, part, indent=4, **opts)
357 if part.type == 'phase-heads':
357 if part.type == 'phase-heads':
358 if not ui.quiet:
358 if not ui.quiet:
359 _debugphaseheads(ui, part, indent=4)
359 _debugphaseheads(ui, part, indent=4)
360
360
361 @command('debugbundle',
361 @command('debugbundle',
362 [('a', 'all', None, _('show all details')),
362 [('a', 'all', None, _('show all details')),
363 ('', 'part-type', [], _('show only the named part type')),
363 ('', 'part-type', [], _('show only the named part type')),
364 ('', 'spec', None, _('print the bundlespec of the bundle'))],
364 ('', 'spec', None, _('print the bundlespec of the bundle'))],
365 _('FILE'),
365 _('FILE'),
366 norepo=True)
366 norepo=True)
367 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
367 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
368 """lists the contents of a bundle"""
368 """lists the contents of a bundle"""
369 with hg.openpath(ui, bundlepath) as f:
369 with hg.openpath(ui, bundlepath) as f:
370 if spec:
370 if spec:
371 spec = exchange.getbundlespec(ui, f)
371 spec = exchange.getbundlespec(ui, f)
372 ui.write('%s\n' % spec)
372 ui.write('%s\n' % spec)
373 return
373 return
374
374
375 gen = exchange.readbundle(ui, f, bundlepath)
375 gen = exchange.readbundle(ui, f, bundlepath)
376 if isinstance(gen, bundle2.unbundle20):
376 if isinstance(gen, bundle2.unbundle20):
377 return _debugbundle2(ui, gen, all=all, **opts)
377 return _debugbundle2(ui, gen, all=all, **opts)
378 _debugchangegroup(ui, gen, all=all, **opts)
378 _debugchangegroup(ui, gen, all=all, **opts)
379
379
380 @command('debugcapabilities',
380 @command('debugcapabilities',
381 [], _('PATH'),
381 [], _('PATH'),
382 norepo=True)
382 norepo=True)
383 def debugcapabilities(ui, path, **opts):
383 def debugcapabilities(ui, path, **opts):
384 """lists the capabilities of a remote peer"""
384 """lists the capabilities of a remote peer"""
385 opts = pycompat.byteskwargs(opts)
385 opts = pycompat.byteskwargs(opts)
386 peer = hg.peer(ui, opts, path)
386 peer = hg.peer(ui, opts, path)
387 caps = peer.capabilities()
387 caps = peer.capabilities()
388 ui.write(('Main capabilities:\n'))
388 ui.write(('Main capabilities:\n'))
389 for c in sorted(caps):
389 for c in sorted(caps):
390 ui.write((' %s\n') % c)
390 ui.write((' %s\n') % c)
391 b2caps = bundle2.bundle2caps(peer)
391 b2caps = bundle2.bundle2caps(peer)
392 if b2caps:
392 if b2caps:
393 ui.write(('Bundle2 capabilities:\n'))
393 ui.write(('Bundle2 capabilities:\n'))
394 for key, values in sorted(b2caps.iteritems()):
394 for key, values in sorted(b2caps.iteritems()):
395 ui.write((' %s\n') % key)
395 ui.write((' %s\n') % key)
396 for v in values:
396 for v in values:
397 ui.write((' %s\n') % v)
397 ui.write((' %s\n') % v)
398
398
399 @command('debugcheckstate', [], '')
399 @command('debugcheckstate', [], '')
400 def debugcheckstate(ui, repo):
400 def debugcheckstate(ui, repo):
401 """validate the correctness of the current dirstate"""
401 """validate the correctness of the current dirstate"""
402 parent1, parent2 = repo.dirstate.parents()
402 parent1, parent2 = repo.dirstate.parents()
403 m1 = repo[parent1].manifest()
403 m1 = repo[parent1].manifest()
404 m2 = repo[parent2].manifest()
404 m2 = repo[parent2].manifest()
405 errors = 0
405 errors = 0
406 for f in repo.dirstate:
406 for f in repo.dirstate:
407 state = repo.dirstate[f]
407 state = repo.dirstate[f]
408 if state in "nr" and f not in m1:
408 if state in "nr" and f not in m1:
409 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
409 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
410 errors += 1
410 errors += 1
411 if state in "a" and f in m1:
411 if state in "a" and f in m1:
412 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
412 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
413 errors += 1
413 errors += 1
414 if state in "m" and f not in m1 and f not in m2:
414 if state in "m" and f not in m1 and f not in m2:
415 ui.warn(_("%s in state %s, but not in either manifest\n") %
415 ui.warn(_("%s in state %s, but not in either manifest\n") %
416 (f, state))
416 (f, state))
417 errors += 1
417 errors += 1
418 for f in m1:
418 for f in m1:
419 state = repo.dirstate[f]
419 state = repo.dirstate[f]
420 if state not in "nrm":
420 if state not in "nrm":
421 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
421 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
422 errors += 1
422 errors += 1
423 if errors:
423 if errors:
424 error = _(".hg/dirstate inconsistent with current parent's manifest")
424 error = _(".hg/dirstate inconsistent with current parent's manifest")
425 raise error.Abort(error)
425 raise error.Abort(error)
426
426
427 @command('debugcolor',
427 @command('debugcolor',
428 [('', 'style', None, _('show all configured styles'))],
428 [('', 'style', None, _('show all configured styles'))],
429 'hg debugcolor')
429 'hg debugcolor')
430 def debugcolor(ui, repo, **opts):
430 def debugcolor(ui, repo, **opts):
431 """show available color, effects or style"""
431 """show available color, effects or style"""
432 ui.write(('color mode: %s\n') % stringutil.pprint(ui._colormode))
432 ui.write(('color mode: %s\n') % stringutil.pprint(ui._colormode))
433 if opts.get(r'style'):
433 if opts.get(r'style'):
434 return _debugdisplaystyle(ui)
434 return _debugdisplaystyle(ui)
435 else:
435 else:
436 return _debugdisplaycolor(ui)
436 return _debugdisplaycolor(ui)
437
437
438 def _debugdisplaycolor(ui):
438 def _debugdisplaycolor(ui):
439 ui = ui.copy()
439 ui = ui.copy()
440 ui._styles.clear()
440 ui._styles.clear()
441 for effect in color._activeeffects(ui).keys():
441 for effect in color._activeeffects(ui).keys():
442 ui._styles[effect] = effect
442 ui._styles[effect] = effect
443 if ui._terminfoparams:
443 if ui._terminfoparams:
444 for k, v in ui.configitems('color'):
444 for k, v in ui.configitems('color'):
445 if k.startswith('color.'):
445 if k.startswith('color.'):
446 ui._styles[k] = k[6:]
446 ui._styles[k] = k[6:]
447 elif k.startswith('terminfo.'):
447 elif k.startswith('terminfo.'):
448 ui._styles[k] = k[9:]
448 ui._styles[k] = k[9:]
449 ui.write(_('available colors:\n'))
449 ui.write(_('available colors:\n'))
450 # sort label with a '_' after the other to group '_background' entry.
450 # sort label with a '_' after the other to group '_background' entry.
451 items = sorted(ui._styles.items(),
451 items = sorted(ui._styles.items(),
452 key=lambda i: ('_' in i[0], i[0], i[1]))
452 key=lambda i: ('_' in i[0], i[0], i[1]))
453 for colorname, label in items:
453 for colorname, label in items:
454 ui.write(('%s\n') % colorname, label=label)
454 ui.write(('%s\n') % colorname, label=label)
455
455
456 def _debugdisplaystyle(ui):
456 def _debugdisplaystyle(ui):
457 ui.write(_('available style:\n'))
457 ui.write(_('available style:\n'))
458 if not ui._styles:
458 if not ui._styles:
459 return
459 return
460 width = max(len(s) for s in ui._styles)
460 width = max(len(s) for s in ui._styles)
461 for label, effects in sorted(ui._styles.items()):
461 for label, effects in sorted(ui._styles.items()):
462 ui.write('%s' % label, label=label)
462 ui.write('%s' % label, label=label)
463 if effects:
463 if effects:
464 # 50
464 # 50
465 ui.write(': ')
465 ui.write(': ')
466 ui.write(' ' * (max(0, width - len(label))))
466 ui.write(' ' * (max(0, width - len(label))))
467 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
467 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
468 ui.write('\n')
468 ui.write('\n')
469
469
470 @command('debugcreatestreamclonebundle', [], 'FILE')
470 @command('debugcreatestreamclonebundle', [], 'FILE')
471 def debugcreatestreamclonebundle(ui, repo, fname):
471 def debugcreatestreamclonebundle(ui, repo, fname):
472 """create a stream clone bundle file
472 """create a stream clone bundle file
473
473
474 Stream bundles are special bundles that are essentially archives of
474 Stream bundles are special bundles that are essentially archives of
475 revlog files. They are commonly used for cloning very quickly.
475 revlog files. They are commonly used for cloning very quickly.
476 """
476 """
477 # TODO we may want to turn this into an abort when this functionality
477 # TODO we may want to turn this into an abort when this functionality
478 # is moved into `hg bundle`.
478 # is moved into `hg bundle`.
479 if phases.hassecret(repo):
479 if phases.hassecret(repo):
480 ui.warn(_('(warning: stream clone bundle will contain secret '
480 ui.warn(_('(warning: stream clone bundle will contain secret '
481 'revisions)\n'))
481 'revisions)\n'))
482
482
483 requirements, gen = streamclone.generatebundlev1(repo)
483 requirements, gen = streamclone.generatebundlev1(repo)
484 changegroup.writechunks(ui, gen, fname)
484 changegroup.writechunks(ui, gen, fname)
485
485
486 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
486 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
487
487
488 @command('debugdag',
488 @command('debugdag',
489 [('t', 'tags', None, _('use tags as labels')),
489 [('t', 'tags', None, _('use tags as labels')),
490 ('b', 'branches', None, _('annotate with branch names')),
490 ('b', 'branches', None, _('annotate with branch names')),
491 ('', 'dots', None, _('use dots for runs')),
491 ('', 'dots', None, _('use dots for runs')),
492 ('s', 'spaces', None, _('separate elements by spaces'))],
492 ('s', 'spaces', None, _('separate elements by spaces'))],
493 _('[OPTION]... [FILE [REV]...]'),
493 _('[OPTION]... [FILE [REV]...]'),
494 optionalrepo=True)
494 optionalrepo=True)
495 def debugdag(ui, repo, file_=None, *revs, **opts):
495 def debugdag(ui, repo, file_=None, *revs, **opts):
496 """format the changelog or an index DAG as a concise textual description
496 """format the changelog or an index DAG as a concise textual description
497
497
498 If you pass a revlog index, the revlog's DAG is emitted. If you list
498 If you pass a revlog index, the revlog's DAG is emitted. If you list
499 revision numbers, they get labeled in the output as rN.
499 revision numbers, they get labeled in the output as rN.
500
500
501 Otherwise, the changelog DAG of the current repo is emitted.
501 Otherwise, the changelog DAG of the current repo is emitted.
502 """
502 """
503 spaces = opts.get(r'spaces')
503 spaces = opts.get(r'spaces')
504 dots = opts.get(r'dots')
504 dots = opts.get(r'dots')
505 if file_:
505 if file_:
506 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
506 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
507 file_)
507 file_)
508 revs = set((int(r) for r in revs))
508 revs = set((int(r) for r in revs))
509 def events():
509 def events():
510 for r in rlog:
510 for r in rlog:
511 yield 'n', (r, list(p for p in rlog.parentrevs(r)
511 yield 'n', (r, list(p for p in rlog.parentrevs(r)
512 if p != -1))
512 if p != -1))
513 if r in revs:
513 if r in revs:
514 yield 'l', (r, "r%i" % r)
514 yield 'l', (r, "r%i" % r)
515 elif repo:
515 elif repo:
516 cl = repo.changelog
516 cl = repo.changelog
517 tags = opts.get(r'tags')
517 tags = opts.get(r'tags')
518 branches = opts.get(r'branches')
518 branches = opts.get(r'branches')
519 if tags:
519 if tags:
520 labels = {}
520 labels = {}
521 for l, n in repo.tags().items():
521 for l, n in repo.tags().items():
522 labels.setdefault(cl.rev(n), []).append(l)
522 labels.setdefault(cl.rev(n), []).append(l)
523 def events():
523 def events():
524 b = "default"
524 b = "default"
525 for r in cl:
525 for r in cl:
526 if branches:
526 if branches:
527 newb = cl.read(cl.node(r))[5]['branch']
527 newb = cl.read(cl.node(r))[5]['branch']
528 if newb != b:
528 if newb != b:
529 yield 'a', newb
529 yield 'a', newb
530 b = newb
530 b = newb
531 yield 'n', (r, list(p for p in cl.parentrevs(r)
531 yield 'n', (r, list(p for p in cl.parentrevs(r)
532 if p != -1))
532 if p != -1))
533 if tags:
533 if tags:
534 ls = labels.get(r)
534 ls = labels.get(r)
535 if ls:
535 if ls:
536 for l in ls:
536 for l in ls:
537 yield 'l', (r, l)
537 yield 'l', (r, l)
538 else:
538 else:
539 raise error.Abort(_('need repo for changelog dag'))
539 raise error.Abort(_('need repo for changelog dag'))
540
540
541 for line in dagparser.dagtextlines(events(),
541 for line in dagparser.dagtextlines(events(),
542 addspaces=spaces,
542 addspaces=spaces,
543 wraplabels=True,
543 wraplabels=True,
544 wrapannotations=True,
544 wrapannotations=True,
545 wrapnonlinear=dots,
545 wrapnonlinear=dots,
546 usedots=dots,
546 usedots=dots,
547 maxlinewidth=70):
547 maxlinewidth=70):
548 ui.write(line)
548 ui.write(line)
549 ui.write("\n")
549 ui.write("\n")
550
550
551 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
551 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
552 def debugdata(ui, repo, file_, rev=None, **opts):
552 def debugdata(ui, repo, file_, rev=None, **opts):
553 """dump the contents of a data file revision"""
553 """dump the contents of a data file revision"""
554 opts = pycompat.byteskwargs(opts)
554 opts = pycompat.byteskwargs(opts)
555 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
555 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
556 if rev is not None:
556 if rev is not None:
557 raise error.CommandError('debugdata', _('invalid arguments'))
557 raise error.CommandError('debugdata', _('invalid arguments'))
558 file_, rev = None, file_
558 file_, rev = None, file_
559 elif rev is None:
559 elif rev is None:
560 raise error.CommandError('debugdata', _('invalid arguments'))
560 raise error.CommandError('debugdata', _('invalid arguments'))
561 r = cmdutil.openstorage(repo, 'debugdata', file_, opts)
561 r = cmdutil.openstorage(repo, 'debugdata', file_, opts)
562 try:
562 try:
563 ui.write(r.revision(r.lookup(rev), raw=True))
563 ui.write(r.revision(r.lookup(rev), raw=True))
564 except KeyError:
564 except KeyError:
565 raise error.Abort(_('invalid revision identifier %s') % rev)
565 raise error.Abort(_('invalid revision identifier %s') % rev)
566
566
567 @command('debugdate',
567 @command('debugdate',
568 [('e', 'extended', None, _('try extended date formats'))],
568 [('e', 'extended', None, _('try extended date formats'))],
569 _('[-e] DATE [RANGE]'),
569 _('[-e] DATE [RANGE]'),
570 norepo=True, optionalrepo=True)
570 norepo=True, optionalrepo=True)
571 def debugdate(ui, date, range=None, **opts):
571 def debugdate(ui, date, range=None, **opts):
572 """parse and display a date"""
572 """parse and display a date"""
573 if opts[r"extended"]:
573 if opts[r"extended"]:
574 d = dateutil.parsedate(date, util.extendeddateformats)
574 d = dateutil.parsedate(date, util.extendeddateformats)
575 else:
575 else:
576 d = dateutil.parsedate(date)
576 d = dateutil.parsedate(date)
577 ui.write(("internal: %d %d\n") % d)
577 ui.write(("internal: %d %d\n") % d)
578 ui.write(("standard: %s\n") % dateutil.datestr(d))
578 ui.write(("standard: %s\n") % dateutil.datestr(d))
579 if range:
579 if range:
580 m = dateutil.matchdate(range)
580 m = dateutil.matchdate(range)
581 ui.write(("match: %s\n") % m(d[0]))
581 ui.write(("match: %s\n") % m(d[0]))
582
582
583 @command('debugdeltachain',
583 @command('debugdeltachain',
584 cmdutil.debugrevlogopts + cmdutil.formatteropts,
584 cmdutil.debugrevlogopts + cmdutil.formatteropts,
585 _('-c|-m|FILE'),
585 _('-c|-m|FILE'),
586 optionalrepo=True)
586 optionalrepo=True)
587 def debugdeltachain(ui, repo, file_=None, **opts):
587 def debugdeltachain(ui, repo, file_=None, **opts):
588 """dump information about delta chains in a revlog
588 """dump information about delta chains in a revlog
589
589
590 Output can be templatized. Available template keywords are:
590 Output can be templatized. Available template keywords are:
591
591
592 :``rev``: revision number
592 :``rev``: revision number
593 :``chainid``: delta chain identifier (numbered by unique base)
593 :``chainid``: delta chain identifier (numbered by unique base)
594 :``chainlen``: delta chain length to this revision
594 :``chainlen``: delta chain length to this revision
595 :``prevrev``: previous revision in delta chain
595 :``prevrev``: previous revision in delta chain
596 :``deltatype``: role of delta / how it was computed
596 :``deltatype``: role of delta / how it was computed
597 :``compsize``: compressed size of revision
597 :``compsize``: compressed size of revision
598 :``uncompsize``: uncompressed size of revision
598 :``uncompsize``: uncompressed size of revision
599 :``chainsize``: total size of compressed revisions in chain
599 :``chainsize``: total size of compressed revisions in chain
600 :``chainratio``: total chain size divided by uncompressed revision size
600 :``chainratio``: total chain size divided by uncompressed revision size
601 (new delta chains typically start at ratio 2.00)
601 (new delta chains typically start at ratio 2.00)
602 :``lindist``: linear distance from base revision in delta chain to end
602 :``lindist``: linear distance from base revision in delta chain to end
603 of this revision
603 of this revision
604 :``extradist``: total size of revisions not part of this delta chain from
604 :``extradist``: total size of revisions not part of this delta chain from
605 base of delta chain to end of this revision; a measurement
605 base of delta chain to end of this revision; a measurement
606 of how much extra data we need to read/seek across to read
606 of how much extra data we need to read/seek across to read
607 the delta chain for this revision
607 the delta chain for this revision
608 :``extraratio``: extradist divided by chainsize; another representation of
608 :``extraratio``: extradist divided by chainsize; another representation of
609 how much unrelated data is needed to load this delta chain
609 how much unrelated data is needed to load this delta chain
610
610
611 If the repository is configured to use the sparse read, additional keywords
611 If the repository is configured to use the sparse read, additional keywords
612 are available:
612 are available:
613
613
614 :``readsize``: total size of data read from the disk for a revision
614 :``readsize``: total size of data read from the disk for a revision
615 (sum of the sizes of all the blocks)
615 (sum of the sizes of all the blocks)
616 :``largestblock``: size of the largest block of data read from the disk
616 :``largestblock``: size of the largest block of data read from the disk
617 :``readdensity``: density of useful bytes in the data read from the disk
617 :``readdensity``: density of useful bytes in the data read from the disk
618 :``srchunks``: in how many data hunks the whole revision would be read
618 :``srchunks``: in how many data hunks the whole revision would be read
619
619
620 The sparse read can be enabled with experimental.sparse-read = True
620 The sparse read can be enabled with experimental.sparse-read = True
621 """
621 """
622 opts = pycompat.byteskwargs(opts)
622 opts = pycompat.byteskwargs(opts)
623 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
623 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
624 index = r.index
624 index = r.index
625 start = r.start
625 start = r.start
626 length = r.length
626 length = r.length
627 generaldelta = r.version & revlog.FLAG_GENERALDELTA
627 generaldelta = r.version & revlog.FLAG_GENERALDELTA
628 withsparseread = getattr(r, '_withsparseread', False)
628 withsparseread = getattr(r, '_withsparseread', False)
629
629
630 def revinfo(rev):
630 def revinfo(rev):
631 e = index[rev]
631 e = index[rev]
632 compsize = e[1]
632 compsize = e[1]
633 uncompsize = e[2]
633 uncompsize = e[2]
634 chainsize = 0
634 chainsize = 0
635
635
636 if generaldelta:
636 if generaldelta:
637 if e[3] == e[5]:
637 if e[3] == e[5]:
638 deltatype = 'p1'
638 deltatype = 'p1'
639 elif e[3] == e[6]:
639 elif e[3] == e[6]:
640 deltatype = 'p2'
640 deltatype = 'p2'
641 elif e[3] == rev - 1:
641 elif e[3] == rev - 1:
642 deltatype = 'prev'
642 deltatype = 'prev'
643 elif e[3] == rev:
643 elif e[3] == rev:
644 deltatype = 'base'
644 deltatype = 'base'
645 else:
645 else:
646 deltatype = 'other'
646 deltatype = 'other'
647 else:
647 else:
648 if e[3] == rev:
648 if e[3] == rev:
649 deltatype = 'base'
649 deltatype = 'base'
650 else:
650 else:
651 deltatype = 'prev'
651 deltatype = 'prev'
652
652
653 chain = r._deltachain(rev)[0]
653 chain = r._deltachain(rev)[0]
654 for iterrev in chain:
654 for iterrev in chain:
655 e = index[iterrev]
655 e = index[iterrev]
656 chainsize += e[1]
656 chainsize += e[1]
657
657
658 return compsize, uncompsize, deltatype, chain, chainsize
658 return compsize, uncompsize, deltatype, chain, chainsize
659
659
660 fm = ui.formatter('debugdeltachain', opts)
660 fm = ui.formatter('debugdeltachain', opts)
661
661
662 fm.plain(' rev chain# chainlen prev delta '
662 fm.plain(' rev chain# chainlen prev delta '
663 'size rawsize chainsize ratio lindist extradist '
663 'size rawsize chainsize ratio lindist extradist '
664 'extraratio')
664 'extraratio')
665 if withsparseread:
665 if withsparseread:
666 fm.plain(' readsize largestblk rddensity srchunks')
666 fm.plain(' readsize largestblk rddensity srchunks')
667 fm.plain('\n')
667 fm.plain('\n')
668
668
669 chainbases = {}
669 chainbases = {}
670 for rev in r:
670 for rev in r:
671 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
671 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
672 chainbase = chain[0]
672 chainbase = chain[0]
673 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
673 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
674 basestart = start(chainbase)
674 basestart = start(chainbase)
675 revstart = start(rev)
675 revstart = start(rev)
676 lineardist = revstart + comp - basestart
676 lineardist = revstart + comp - basestart
677 extradist = lineardist - chainsize
677 extradist = lineardist - chainsize
678 try:
678 try:
679 prevrev = chain[-2]
679 prevrev = chain[-2]
680 except IndexError:
680 except IndexError:
681 prevrev = -1
681 prevrev = -1
682
682
683 if uncomp != 0:
683 if uncomp != 0:
684 chainratio = float(chainsize) / float(uncomp)
684 chainratio = float(chainsize) / float(uncomp)
685 else:
685 else:
686 chainratio = chainsize
686 chainratio = chainsize
687
687
688 if chainsize != 0:
688 if chainsize != 0:
689 extraratio = float(extradist) / float(chainsize)
689 extraratio = float(extradist) / float(chainsize)
690 else:
690 else:
691 extraratio = extradist
691 extraratio = extradist
692
692
693 fm.startitem()
693 fm.startitem()
694 fm.write('rev chainid chainlen prevrev deltatype compsize '
694 fm.write('rev chainid chainlen prevrev deltatype compsize '
695 'uncompsize chainsize chainratio lindist extradist '
695 'uncompsize chainsize chainratio lindist extradist '
696 'extraratio',
696 'extraratio',
697 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
697 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
698 rev, chainid, len(chain), prevrev, deltatype, comp,
698 rev, chainid, len(chain), prevrev, deltatype, comp,
699 uncomp, chainsize, chainratio, lineardist, extradist,
699 uncomp, chainsize, chainratio, lineardist, extradist,
700 extraratio,
700 extraratio,
701 rev=rev, chainid=chainid, chainlen=len(chain),
701 rev=rev, chainid=chainid, chainlen=len(chain),
702 prevrev=prevrev, deltatype=deltatype, compsize=comp,
702 prevrev=prevrev, deltatype=deltatype, compsize=comp,
703 uncompsize=uncomp, chainsize=chainsize,
703 uncompsize=uncomp, chainsize=chainsize,
704 chainratio=chainratio, lindist=lineardist,
704 chainratio=chainratio, lindist=lineardist,
705 extradist=extradist, extraratio=extraratio)
705 extradist=extradist, extraratio=extraratio)
706 if withsparseread:
706 if withsparseread:
707 readsize = 0
707 readsize = 0
708 largestblock = 0
708 largestblock = 0
709 srchunks = 0
709 srchunks = 0
710
710
711 for revschunk in deltautil.slicechunk(r, chain):
711 for revschunk in deltautil.slicechunk(r, chain):
712 srchunks += 1
712 srchunks += 1
713 blkend = start(revschunk[-1]) + length(revschunk[-1])
713 blkend = start(revschunk[-1]) + length(revschunk[-1])
714 blksize = blkend - start(revschunk[0])
714 blksize = blkend - start(revschunk[0])
715
715
716 readsize += blksize
716 readsize += blksize
717 if largestblock < blksize:
717 if largestblock < blksize:
718 largestblock = blksize
718 largestblock = blksize
719
719
720 if readsize:
720 if readsize:
721 readdensity = float(chainsize) / float(readsize)
721 readdensity = float(chainsize) / float(readsize)
722 else:
722 else:
723 readdensity = 1
723 readdensity = 1
724
724
725 fm.write('readsize largestblock readdensity srchunks',
725 fm.write('readsize largestblock readdensity srchunks',
726 ' %10d %10d %9.5f %8d',
726 ' %10d %10d %9.5f %8d',
727 readsize, largestblock, readdensity, srchunks,
727 readsize, largestblock, readdensity, srchunks,
728 readsize=readsize, largestblock=largestblock,
728 readsize=readsize, largestblock=largestblock,
729 readdensity=readdensity, srchunks=srchunks)
729 readdensity=readdensity, srchunks=srchunks)
730
730
731 fm.plain('\n')
731 fm.plain('\n')
732
732
733 fm.end()
733 fm.end()
734
734
735 @command('debugdirstate|debugstate',
735 @command('debugdirstate|debugstate',
736 [('', 'nodates', None, _('do not display the saved mtime')),
736 [('', 'nodates', None, _('do not display the saved mtime (DEPRECATED)')),
737 ('', 'datesort', None, _('sort by saved mtime'))],
737 ('', 'dates', True, _('display the saved mtime')),
738 ('', 'datesort', None, _('sort by saved mtime'))],
738 _('[OPTION]...'))
739 _('[OPTION]...'))
739 def debugstate(ui, repo, **opts):
740 def debugstate(ui, repo, **opts):
740 """show the contents of the current dirstate"""
741 """show the contents of the current dirstate"""
741
742
742 nodates = opts.get(r'nodates')
743 nodates = not opts[r'dates']
744 if opts.get(r'nodates') is not None:
745 nodates = True
743 datesort = opts.get(r'datesort')
746 datesort = opts.get(r'datesort')
744
747
745 timestr = ""
748 timestr = ""
746 if datesort:
749 if datesort:
747 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
750 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
748 else:
751 else:
749 keyfunc = None # sort by filename
752 keyfunc = None # sort by filename
750 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
753 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
751 if ent[3] == -1:
754 if ent[3] == -1:
752 timestr = 'unset '
755 timestr = 'unset '
753 elif nodates:
756 elif nodates:
754 timestr = 'set '
757 timestr = 'set '
755 else:
758 else:
756 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
759 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
757 time.localtime(ent[3]))
760 time.localtime(ent[3]))
758 timestr = encoding.strtolocal(timestr)
761 timestr = encoding.strtolocal(timestr)
759 if ent[1] & 0o20000:
762 if ent[1] & 0o20000:
760 mode = 'lnk'
763 mode = 'lnk'
761 else:
764 else:
762 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
765 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
763 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
766 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
764 for f in repo.dirstate.copies():
767 for f in repo.dirstate.copies():
765 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
768 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
766
769
767 @command('debugdiscovery',
770 @command('debugdiscovery',
768 [('', 'old', None, _('use old-style discovery')),
771 [('', 'old', None, _('use old-style discovery')),
769 ('', 'nonheads', None,
772 ('', 'nonheads', None,
770 _('use old-style discovery with non-heads included')),
773 _('use old-style discovery with non-heads included')),
771 ('', 'rev', [], 'restrict discovery to this set of revs'),
774 ('', 'rev', [], 'restrict discovery to this set of revs'),
772 ] + cmdutil.remoteopts,
775 ] + cmdutil.remoteopts,
773 _('[--rev REV] [OTHER]'))
776 _('[--rev REV] [OTHER]'))
774 def debugdiscovery(ui, repo, remoteurl="default", **opts):
777 def debugdiscovery(ui, repo, remoteurl="default", **opts):
775 """runs the changeset discovery protocol in isolation"""
778 """runs the changeset discovery protocol in isolation"""
776 opts = pycompat.byteskwargs(opts)
779 opts = pycompat.byteskwargs(opts)
777 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
780 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
778 remote = hg.peer(repo, opts, remoteurl)
781 remote = hg.peer(repo, opts, remoteurl)
779 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
782 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
780
783
781 # make sure tests are repeatable
784 # make sure tests are repeatable
782 random.seed(12323)
785 random.seed(12323)
783
786
784 def doit(pushedrevs, remoteheads, remote=remote):
787 def doit(pushedrevs, remoteheads, remote=remote):
785 if opts.get('old'):
788 if opts.get('old'):
786 if not util.safehasattr(remote, 'branches'):
789 if not util.safehasattr(remote, 'branches'):
787 # enable in-client legacy support
790 # enable in-client legacy support
788 remote = localrepo.locallegacypeer(remote.local())
791 remote = localrepo.locallegacypeer(remote.local())
789 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
792 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
790 force=True)
793 force=True)
791 common = set(common)
794 common = set(common)
792 if not opts.get('nonheads'):
795 if not opts.get('nonheads'):
793 ui.write(("unpruned common: %s\n") %
796 ui.write(("unpruned common: %s\n") %
794 " ".join(sorted(short(n) for n in common)))
797 " ".join(sorted(short(n) for n in common)))
795
798
796 clnode = repo.changelog.node
799 clnode = repo.changelog.node
797 common = repo.revs('heads(::%ln)', common)
800 common = repo.revs('heads(::%ln)', common)
798 common = {clnode(r) for r in common}
801 common = {clnode(r) for r in common}
799 else:
802 else:
800 nodes = None
803 nodes = None
801 if pushedrevs:
804 if pushedrevs:
802 revs = scmutil.revrange(repo, pushedrevs)
805 revs = scmutil.revrange(repo, pushedrevs)
803 nodes = [repo[r].node() for r in revs]
806 nodes = [repo[r].node() for r in revs]
804 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
807 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
805 ancestorsof=nodes)
808 ancestorsof=nodes)
806 common = set(common)
809 common = set(common)
807 rheads = set(hds)
810 rheads = set(hds)
808 lheads = set(repo.heads())
811 lheads = set(repo.heads())
809 ui.write(("common heads: %s\n") %
812 ui.write(("common heads: %s\n") %
810 " ".join(sorted(short(n) for n in common)))
813 " ".join(sorted(short(n) for n in common)))
811 if lheads <= common:
814 if lheads <= common:
812 ui.write(("local is subset\n"))
815 ui.write(("local is subset\n"))
813 elif rheads <= common:
816 elif rheads <= common:
814 ui.write(("remote is subset\n"))
817 ui.write(("remote is subset\n"))
815
818
816 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
819 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
817 localrevs = opts['rev']
820 localrevs = opts['rev']
818 doit(localrevs, remoterevs)
821 doit(localrevs, remoterevs)
819
822
820 _chunksize = 4 << 10
823 _chunksize = 4 << 10
821
824
822 @command('debugdownload',
825 @command('debugdownload',
823 [
826 [
824 ('o', 'output', '', _('path')),
827 ('o', 'output', '', _('path')),
825 ],
828 ],
826 optionalrepo=True)
829 optionalrepo=True)
827 def debugdownload(ui, repo, url, output=None, **opts):
830 def debugdownload(ui, repo, url, output=None, **opts):
828 """download a resource using Mercurial logic and config
831 """download a resource using Mercurial logic and config
829 """
832 """
830 fh = urlmod.open(ui, url, output)
833 fh = urlmod.open(ui, url, output)
831
834
832 dest = ui
835 dest = ui
833 if output:
836 if output:
834 dest = open(output, "wb", _chunksize)
837 dest = open(output, "wb", _chunksize)
835 try:
838 try:
836 data = fh.read(_chunksize)
839 data = fh.read(_chunksize)
837 while data:
840 while data:
838 dest.write(data)
841 dest.write(data)
839 data = fh.read(_chunksize)
842 data = fh.read(_chunksize)
840 finally:
843 finally:
841 if output:
844 if output:
842 dest.close()
845 dest.close()
843
846
844 @command('debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
847 @command('debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
845 def debugextensions(ui, repo, **opts):
848 def debugextensions(ui, repo, **opts):
846 '''show information about active extensions'''
849 '''show information about active extensions'''
847 opts = pycompat.byteskwargs(opts)
850 opts = pycompat.byteskwargs(opts)
848 exts = extensions.extensions(ui)
851 exts = extensions.extensions(ui)
849 hgver = util.version()
852 hgver = util.version()
850 fm = ui.formatter('debugextensions', opts)
853 fm = ui.formatter('debugextensions', opts)
851 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
854 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
852 isinternal = extensions.ismoduleinternal(extmod)
855 isinternal = extensions.ismoduleinternal(extmod)
853 extsource = pycompat.fsencode(extmod.__file__)
856 extsource = pycompat.fsencode(extmod.__file__)
854 if isinternal:
857 if isinternal:
855 exttestedwith = [] # never expose magic string to users
858 exttestedwith = [] # never expose magic string to users
856 else:
859 else:
857 exttestedwith = getattr(extmod, 'testedwith', '').split()
860 exttestedwith = getattr(extmod, 'testedwith', '').split()
858 extbuglink = getattr(extmod, 'buglink', None)
861 extbuglink = getattr(extmod, 'buglink', None)
859
862
860 fm.startitem()
863 fm.startitem()
861
864
862 if ui.quiet or ui.verbose:
865 if ui.quiet or ui.verbose:
863 fm.write('name', '%s\n', extname)
866 fm.write('name', '%s\n', extname)
864 else:
867 else:
865 fm.write('name', '%s', extname)
868 fm.write('name', '%s', extname)
866 if isinternal or hgver in exttestedwith:
869 if isinternal or hgver in exttestedwith:
867 fm.plain('\n')
870 fm.plain('\n')
868 elif not exttestedwith:
871 elif not exttestedwith:
869 fm.plain(_(' (untested!)\n'))
872 fm.plain(_(' (untested!)\n'))
870 else:
873 else:
871 lasttestedversion = exttestedwith[-1]
874 lasttestedversion = exttestedwith[-1]
872 fm.plain(' (%s!)\n' % lasttestedversion)
875 fm.plain(' (%s!)\n' % lasttestedversion)
873
876
874 fm.condwrite(ui.verbose and extsource, 'source',
877 fm.condwrite(ui.verbose and extsource, 'source',
875 _(' location: %s\n'), extsource or "")
878 _(' location: %s\n'), extsource or "")
876
879
877 if ui.verbose:
880 if ui.verbose:
878 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
881 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
879 fm.data(bundled=isinternal)
882 fm.data(bundled=isinternal)
880
883
881 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
884 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
882 _(' tested with: %s\n'),
885 _(' tested with: %s\n'),
883 fm.formatlist(exttestedwith, name='ver'))
886 fm.formatlist(exttestedwith, name='ver'))
884
887
885 fm.condwrite(ui.verbose and extbuglink, 'buglink',
888 fm.condwrite(ui.verbose and extbuglink, 'buglink',
886 _(' bug reporting: %s\n'), extbuglink or "")
889 _(' bug reporting: %s\n'), extbuglink or "")
887
890
888 fm.end()
891 fm.end()
889
892
890 @command('debugfileset',
893 @command('debugfileset',
891 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV')),
894 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV')),
892 ('', 'all-files', False,
895 ('', 'all-files', False,
893 _('test files from all revisions and working directory')),
896 _('test files from all revisions and working directory')),
894 ('s', 'show-matcher', None,
897 ('s', 'show-matcher', None,
895 _('print internal representation of matcher')),
898 _('print internal representation of matcher')),
896 ('p', 'show-stage', [],
899 ('p', 'show-stage', [],
897 _('print parsed tree at the given stage'), _('NAME'))],
900 _('print parsed tree at the given stage'), _('NAME'))],
898 _('[-r REV] [--all-files] [OPTION]... FILESPEC'))
901 _('[-r REV] [--all-files] [OPTION]... FILESPEC'))
899 def debugfileset(ui, repo, expr, **opts):
902 def debugfileset(ui, repo, expr, **opts):
900 '''parse and apply a fileset specification'''
903 '''parse and apply a fileset specification'''
901 from . import fileset
904 from . import fileset
902 fileset.symbols # force import of fileset so we have predicates to optimize
905 fileset.symbols # force import of fileset so we have predicates to optimize
903 opts = pycompat.byteskwargs(opts)
906 opts = pycompat.byteskwargs(opts)
904 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
907 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
905
908
906 stages = [
909 stages = [
907 ('parsed', pycompat.identity),
910 ('parsed', pycompat.identity),
908 ('analyzed', filesetlang.analyze),
911 ('analyzed', filesetlang.analyze),
909 ('optimized', filesetlang.optimize),
912 ('optimized', filesetlang.optimize),
910 ]
913 ]
911 stagenames = set(n for n, f in stages)
914 stagenames = set(n for n, f in stages)
912
915
913 showalways = set()
916 showalways = set()
914 if ui.verbose and not opts['show_stage']:
917 if ui.verbose and not opts['show_stage']:
915 # show parsed tree by --verbose (deprecated)
918 # show parsed tree by --verbose (deprecated)
916 showalways.add('parsed')
919 showalways.add('parsed')
917 if opts['show_stage'] == ['all']:
920 if opts['show_stage'] == ['all']:
918 showalways.update(stagenames)
921 showalways.update(stagenames)
919 else:
922 else:
920 for n in opts['show_stage']:
923 for n in opts['show_stage']:
921 if n not in stagenames:
924 if n not in stagenames:
922 raise error.Abort(_('invalid stage name: %s') % n)
925 raise error.Abort(_('invalid stage name: %s') % n)
923 showalways.update(opts['show_stage'])
926 showalways.update(opts['show_stage'])
924
927
925 tree = filesetlang.parse(expr)
928 tree = filesetlang.parse(expr)
926 for n, f in stages:
929 for n, f in stages:
927 tree = f(tree)
930 tree = f(tree)
928 if n in showalways:
931 if n in showalways:
929 if opts['show_stage'] or n != 'parsed':
932 if opts['show_stage'] or n != 'parsed':
930 ui.write(("* %s:\n") % n)
933 ui.write(("* %s:\n") % n)
931 ui.write(filesetlang.prettyformat(tree), "\n")
934 ui.write(filesetlang.prettyformat(tree), "\n")
932
935
933 files = set()
936 files = set()
934 if opts['all_files']:
937 if opts['all_files']:
935 for r in repo:
938 for r in repo:
936 c = repo[r]
939 c = repo[r]
937 files.update(c.files())
940 files.update(c.files())
938 files.update(c.substate)
941 files.update(c.substate)
939 if opts['all_files'] or ctx.rev() is None:
942 if opts['all_files'] or ctx.rev() is None:
940 wctx = repo[None]
943 wctx = repo[None]
941 files.update(repo.dirstate.walk(scmutil.matchall(repo),
944 files.update(repo.dirstate.walk(scmutil.matchall(repo),
942 subrepos=list(wctx.substate),
945 subrepos=list(wctx.substate),
943 unknown=True, ignored=True))
946 unknown=True, ignored=True))
944 files.update(wctx.substate)
947 files.update(wctx.substate)
945 else:
948 else:
946 files.update(ctx.files())
949 files.update(ctx.files())
947 files.update(ctx.substate)
950 files.update(ctx.substate)
948
951
949 m = ctx.matchfileset(expr)
952 m = ctx.matchfileset(expr)
950 if opts['show_matcher'] or (opts['show_matcher'] is None and ui.verbose):
953 if opts['show_matcher'] or (opts['show_matcher'] is None and ui.verbose):
951 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n')
954 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n')
952 for f in sorted(files):
955 for f in sorted(files):
953 if not m(f):
956 if not m(f):
954 continue
957 continue
955 ui.write("%s\n" % f)
958 ui.write("%s\n" % f)
956
959
957 @command('debugformat',
960 @command('debugformat',
958 [] + cmdutil.formatteropts)
961 [] + cmdutil.formatteropts)
959 def debugformat(ui, repo, **opts):
962 def debugformat(ui, repo, **opts):
960 """display format information about the current repository
963 """display format information about the current repository
961
964
962 Use --verbose to get extra information about current config value and
965 Use --verbose to get extra information about current config value and
963 Mercurial default."""
966 Mercurial default."""
964 opts = pycompat.byteskwargs(opts)
967 opts = pycompat.byteskwargs(opts)
965 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
968 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
966 maxvariantlength = max(len('format-variant'), maxvariantlength)
969 maxvariantlength = max(len('format-variant'), maxvariantlength)
967
970
968 def makeformatname(name):
971 def makeformatname(name):
969 return '%s:' + (' ' * (maxvariantlength - len(name)))
972 return '%s:' + (' ' * (maxvariantlength - len(name)))
970
973
971 fm = ui.formatter('debugformat', opts)
974 fm = ui.formatter('debugformat', opts)
972 if fm.isplain():
975 if fm.isplain():
973 def formatvalue(value):
976 def formatvalue(value):
974 if util.safehasattr(value, 'startswith'):
977 if util.safehasattr(value, 'startswith'):
975 return value
978 return value
976 if value:
979 if value:
977 return 'yes'
980 return 'yes'
978 else:
981 else:
979 return 'no'
982 return 'no'
980 else:
983 else:
981 formatvalue = pycompat.identity
984 formatvalue = pycompat.identity
982
985
983 fm.plain('format-variant')
986 fm.plain('format-variant')
984 fm.plain(' ' * (maxvariantlength - len('format-variant')))
987 fm.plain(' ' * (maxvariantlength - len('format-variant')))
985 fm.plain(' repo')
988 fm.plain(' repo')
986 if ui.verbose:
989 if ui.verbose:
987 fm.plain(' config default')
990 fm.plain(' config default')
988 fm.plain('\n')
991 fm.plain('\n')
989 for fv in upgrade.allformatvariant:
992 for fv in upgrade.allformatvariant:
990 fm.startitem()
993 fm.startitem()
991 repovalue = fv.fromrepo(repo)
994 repovalue = fv.fromrepo(repo)
992 configvalue = fv.fromconfig(repo)
995 configvalue = fv.fromconfig(repo)
993
996
994 if repovalue != configvalue:
997 if repovalue != configvalue:
995 namelabel = 'formatvariant.name.mismatchconfig'
998 namelabel = 'formatvariant.name.mismatchconfig'
996 repolabel = 'formatvariant.repo.mismatchconfig'
999 repolabel = 'formatvariant.repo.mismatchconfig'
997 elif repovalue != fv.default:
1000 elif repovalue != fv.default:
998 namelabel = 'formatvariant.name.mismatchdefault'
1001 namelabel = 'formatvariant.name.mismatchdefault'
999 repolabel = 'formatvariant.repo.mismatchdefault'
1002 repolabel = 'formatvariant.repo.mismatchdefault'
1000 else:
1003 else:
1001 namelabel = 'formatvariant.name.uptodate'
1004 namelabel = 'formatvariant.name.uptodate'
1002 repolabel = 'formatvariant.repo.uptodate'
1005 repolabel = 'formatvariant.repo.uptodate'
1003
1006
1004 fm.write('name', makeformatname(fv.name), fv.name,
1007 fm.write('name', makeformatname(fv.name), fv.name,
1005 label=namelabel)
1008 label=namelabel)
1006 fm.write('repo', ' %3s', formatvalue(repovalue),
1009 fm.write('repo', ' %3s', formatvalue(repovalue),
1007 label=repolabel)
1010 label=repolabel)
1008 if fv.default != configvalue:
1011 if fv.default != configvalue:
1009 configlabel = 'formatvariant.config.special'
1012 configlabel = 'formatvariant.config.special'
1010 else:
1013 else:
1011 configlabel = 'formatvariant.config.default'
1014 configlabel = 'formatvariant.config.default'
1012 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
1015 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
1013 label=configlabel)
1016 label=configlabel)
1014 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
1017 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
1015 label='formatvariant.default')
1018 label='formatvariant.default')
1016 fm.plain('\n')
1019 fm.plain('\n')
1017 fm.end()
1020 fm.end()
1018
1021
1019 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
1022 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
1020 def debugfsinfo(ui, path="."):
1023 def debugfsinfo(ui, path="."):
1021 """show information detected about current filesystem"""
1024 """show information detected about current filesystem"""
1022 ui.write(('path: %s\n') % path)
1025 ui.write(('path: %s\n') % path)
1023 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
1026 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
1024 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
1027 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
1025 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
1028 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
1026 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
1029 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
1027 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
1030 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
1028 casesensitive = '(unknown)'
1031 casesensitive = '(unknown)'
1029 try:
1032 try:
1030 with pycompat.namedtempfile(prefix='.debugfsinfo', dir=path) as f:
1033 with pycompat.namedtempfile(prefix='.debugfsinfo', dir=path) as f:
1031 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
1034 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
1032 except OSError:
1035 except OSError:
1033 pass
1036 pass
1034 ui.write(('case-sensitive: %s\n') % casesensitive)
1037 ui.write(('case-sensitive: %s\n') % casesensitive)
1035
1038
1036 @command('debuggetbundle',
1039 @command('debuggetbundle',
1037 [('H', 'head', [], _('id of head node'), _('ID')),
1040 [('H', 'head', [], _('id of head node'), _('ID')),
1038 ('C', 'common', [], _('id of common node'), _('ID')),
1041 ('C', 'common', [], _('id of common node'), _('ID')),
1039 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1042 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1040 _('REPO FILE [-H|-C ID]...'),
1043 _('REPO FILE [-H|-C ID]...'),
1041 norepo=True)
1044 norepo=True)
1042 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1045 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1043 """retrieves a bundle from a repo
1046 """retrieves a bundle from a repo
1044
1047
1045 Every ID must be a full-length hex node id string. Saves the bundle to the
1048 Every ID must be a full-length hex node id string. Saves the bundle to the
1046 given file.
1049 given file.
1047 """
1050 """
1048 opts = pycompat.byteskwargs(opts)
1051 opts = pycompat.byteskwargs(opts)
1049 repo = hg.peer(ui, opts, repopath)
1052 repo = hg.peer(ui, opts, repopath)
1050 if not repo.capable('getbundle'):
1053 if not repo.capable('getbundle'):
1051 raise error.Abort("getbundle() not supported by target repository")
1054 raise error.Abort("getbundle() not supported by target repository")
1052 args = {}
1055 args = {}
1053 if common:
1056 if common:
1054 args[r'common'] = [bin(s) for s in common]
1057 args[r'common'] = [bin(s) for s in common]
1055 if head:
1058 if head:
1056 args[r'heads'] = [bin(s) for s in head]
1059 args[r'heads'] = [bin(s) for s in head]
1057 # TODO: get desired bundlecaps from command line.
1060 # TODO: get desired bundlecaps from command line.
1058 args[r'bundlecaps'] = None
1061 args[r'bundlecaps'] = None
1059 bundle = repo.getbundle('debug', **args)
1062 bundle = repo.getbundle('debug', **args)
1060
1063
1061 bundletype = opts.get('type', 'bzip2').lower()
1064 bundletype = opts.get('type', 'bzip2').lower()
1062 btypes = {'none': 'HG10UN',
1065 btypes = {'none': 'HG10UN',
1063 'bzip2': 'HG10BZ',
1066 'bzip2': 'HG10BZ',
1064 'gzip': 'HG10GZ',
1067 'gzip': 'HG10GZ',
1065 'bundle2': 'HG20'}
1068 'bundle2': 'HG20'}
1066 bundletype = btypes.get(bundletype)
1069 bundletype = btypes.get(bundletype)
1067 if bundletype not in bundle2.bundletypes:
1070 if bundletype not in bundle2.bundletypes:
1068 raise error.Abort(_('unknown bundle type specified with --type'))
1071 raise error.Abort(_('unknown bundle type specified with --type'))
1069 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1072 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1070
1073
1071 @command('debugignore', [], '[FILE]')
1074 @command('debugignore', [], '[FILE]')
1072 def debugignore(ui, repo, *files, **opts):
1075 def debugignore(ui, repo, *files, **opts):
1073 """display the combined ignore pattern and information about ignored files
1076 """display the combined ignore pattern and information about ignored files
1074
1077
1075 With no argument display the combined ignore pattern.
1078 With no argument display the combined ignore pattern.
1076
1079
1077 Given space separated file names, shows if the given file is ignored and
1080 Given space separated file names, shows if the given file is ignored and
1078 if so, show the ignore rule (file and line number) that matched it.
1081 if so, show the ignore rule (file and line number) that matched it.
1079 """
1082 """
1080 ignore = repo.dirstate._ignore
1083 ignore = repo.dirstate._ignore
1081 if not files:
1084 if not files:
1082 # Show all the patterns
1085 # Show all the patterns
1083 ui.write("%s\n" % pycompat.byterepr(ignore))
1086 ui.write("%s\n" % pycompat.byterepr(ignore))
1084 else:
1087 else:
1085 m = scmutil.match(repo[None], pats=files)
1088 m = scmutil.match(repo[None], pats=files)
1086 for f in m.files():
1089 for f in m.files():
1087 nf = util.normpath(f)
1090 nf = util.normpath(f)
1088 ignored = None
1091 ignored = None
1089 ignoredata = None
1092 ignoredata = None
1090 if nf != '.':
1093 if nf != '.':
1091 if ignore(nf):
1094 if ignore(nf):
1092 ignored = nf
1095 ignored = nf
1093 ignoredata = repo.dirstate._ignorefileandline(nf)
1096 ignoredata = repo.dirstate._ignorefileandline(nf)
1094 else:
1097 else:
1095 for p in util.finddirs(nf):
1098 for p in util.finddirs(nf):
1096 if ignore(p):
1099 if ignore(p):
1097 ignored = p
1100 ignored = p
1098 ignoredata = repo.dirstate._ignorefileandline(p)
1101 ignoredata = repo.dirstate._ignorefileandline(p)
1099 break
1102 break
1100 if ignored:
1103 if ignored:
1101 if ignored == nf:
1104 if ignored == nf:
1102 ui.write(_("%s is ignored\n") % m.uipath(f))
1105 ui.write(_("%s is ignored\n") % m.uipath(f))
1103 else:
1106 else:
1104 ui.write(_("%s is ignored because of "
1107 ui.write(_("%s is ignored because of "
1105 "containing folder %s\n")
1108 "containing folder %s\n")
1106 % (m.uipath(f), ignored))
1109 % (m.uipath(f), ignored))
1107 ignorefile, lineno, line = ignoredata
1110 ignorefile, lineno, line = ignoredata
1108 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1111 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1109 % (ignorefile, lineno, line))
1112 % (ignorefile, lineno, line))
1110 else:
1113 else:
1111 ui.write(_("%s is not ignored\n") % m.uipath(f))
1114 ui.write(_("%s is not ignored\n") % m.uipath(f))
1112
1115
1113 @command('debugindex', cmdutil.debugrevlogopts + cmdutil.formatteropts,
1116 @command('debugindex', cmdutil.debugrevlogopts + cmdutil.formatteropts,
1114 _('-c|-m|FILE'))
1117 _('-c|-m|FILE'))
1115 def debugindex(ui, repo, file_=None, **opts):
1118 def debugindex(ui, repo, file_=None, **opts):
1116 """dump index data for a storage primitive"""
1119 """dump index data for a storage primitive"""
1117 opts = pycompat.byteskwargs(opts)
1120 opts = pycompat.byteskwargs(opts)
1118 store = cmdutil.openstorage(repo, 'debugindex', file_, opts)
1121 store = cmdutil.openstorage(repo, 'debugindex', file_, opts)
1119
1122
1120 if ui.debugflag:
1123 if ui.debugflag:
1121 shortfn = hex
1124 shortfn = hex
1122 else:
1125 else:
1123 shortfn = short
1126 shortfn = short
1124
1127
1125 idlen = 12
1128 idlen = 12
1126 for i in store:
1129 for i in store:
1127 idlen = len(shortfn(store.node(i)))
1130 idlen = len(shortfn(store.node(i)))
1128 break
1131 break
1129
1132
1130 fm = ui.formatter('debugindex', opts)
1133 fm = ui.formatter('debugindex', opts)
1131 fm.plain(b' rev linkrev %s %s p2\n' % (
1134 fm.plain(b' rev linkrev %s %s p2\n' % (
1132 b'nodeid'.ljust(idlen),
1135 b'nodeid'.ljust(idlen),
1133 b'p1'.ljust(idlen)))
1136 b'p1'.ljust(idlen)))
1134
1137
1135 for rev in store:
1138 for rev in store:
1136 node = store.node(rev)
1139 node = store.node(rev)
1137 parents = store.parents(node)
1140 parents = store.parents(node)
1138
1141
1139 fm.startitem()
1142 fm.startitem()
1140 fm.write(b'rev', b'%6d ', rev)
1143 fm.write(b'rev', b'%6d ', rev)
1141 fm.write(b'linkrev', '%7d ', store.linkrev(rev))
1144 fm.write(b'linkrev', '%7d ', store.linkrev(rev))
1142 fm.write(b'node', '%s ', shortfn(node))
1145 fm.write(b'node', '%s ', shortfn(node))
1143 fm.write(b'p1', '%s ', shortfn(parents[0]))
1146 fm.write(b'p1', '%s ', shortfn(parents[0]))
1144 fm.write(b'p2', '%s', shortfn(parents[1]))
1147 fm.write(b'p2', '%s', shortfn(parents[1]))
1145 fm.plain(b'\n')
1148 fm.plain(b'\n')
1146
1149
1147 fm.end()
1150 fm.end()
1148
1151
1149 @command('debugindexdot', cmdutil.debugrevlogopts,
1152 @command('debugindexdot', cmdutil.debugrevlogopts,
1150 _('-c|-m|FILE'), optionalrepo=True)
1153 _('-c|-m|FILE'), optionalrepo=True)
1151 def debugindexdot(ui, repo, file_=None, **opts):
1154 def debugindexdot(ui, repo, file_=None, **opts):
1152 """dump an index DAG as a graphviz dot file"""
1155 """dump an index DAG as a graphviz dot file"""
1153 opts = pycompat.byteskwargs(opts)
1156 opts = pycompat.byteskwargs(opts)
1154 r = cmdutil.openstorage(repo, 'debugindexdot', file_, opts)
1157 r = cmdutil.openstorage(repo, 'debugindexdot', file_, opts)
1155 ui.write(("digraph G {\n"))
1158 ui.write(("digraph G {\n"))
1156 for i in r:
1159 for i in r:
1157 node = r.node(i)
1160 node = r.node(i)
1158 pp = r.parents(node)
1161 pp = r.parents(node)
1159 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1162 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1160 if pp[1] != nullid:
1163 if pp[1] != nullid:
1161 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1164 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1162 ui.write("}\n")
1165 ui.write("}\n")
1163
1166
1164 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1167 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1165 def debuginstall(ui, **opts):
1168 def debuginstall(ui, **opts):
1166 '''test Mercurial installation
1169 '''test Mercurial installation
1167
1170
1168 Returns 0 on success.
1171 Returns 0 on success.
1169 '''
1172 '''
1170 opts = pycompat.byteskwargs(opts)
1173 opts = pycompat.byteskwargs(opts)
1171
1174
1172 def writetemp(contents):
1175 def writetemp(contents):
1173 (fd, name) = pycompat.mkstemp(prefix="hg-debuginstall-")
1176 (fd, name) = pycompat.mkstemp(prefix="hg-debuginstall-")
1174 f = os.fdopen(fd, r"wb")
1177 f = os.fdopen(fd, r"wb")
1175 f.write(contents)
1178 f.write(contents)
1176 f.close()
1179 f.close()
1177 return name
1180 return name
1178
1181
1179 problems = 0
1182 problems = 0
1180
1183
1181 fm = ui.formatter('debuginstall', opts)
1184 fm = ui.formatter('debuginstall', opts)
1182 fm.startitem()
1185 fm.startitem()
1183
1186
1184 # encoding
1187 # encoding
1185 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1188 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1186 err = None
1189 err = None
1187 try:
1190 try:
1188 codecs.lookup(pycompat.sysstr(encoding.encoding))
1191 codecs.lookup(pycompat.sysstr(encoding.encoding))
1189 except LookupError as inst:
1192 except LookupError as inst:
1190 err = stringutil.forcebytestr(inst)
1193 err = stringutil.forcebytestr(inst)
1191 problems += 1
1194 problems += 1
1192 fm.condwrite(err, 'encodingerror', _(" %s\n"
1195 fm.condwrite(err, 'encodingerror', _(" %s\n"
1193 " (check that your locale is properly set)\n"), err)
1196 " (check that your locale is properly set)\n"), err)
1194
1197
1195 # Python
1198 # Python
1196 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1199 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1197 pycompat.sysexecutable)
1200 pycompat.sysexecutable)
1198 fm.write('pythonver', _("checking Python version (%s)\n"),
1201 fm.write('pythonver', _("checking Python version (%s)\n"),
1199 ("%d.%d.%d" % sys.version_info[:3]))
1202 ("%d.%d.%d" % sys.version_info[:3]))
1200 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1203 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1201 os.path.dirname(pycompat.fsencode(os.__file__)))
1204 os.path.dirname(pycompat.fsencode(os.__file__)))
1202
1205
1203 security = set(sslutil.supportedprotocols)
1206 security = set(sslutil.supportedprotocols)
1204 if sslutil.hassni:
1207 if sslutil.hassni:
1205 security.add('sni')
1208 security.add('sni')
1206
1209
1207 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1210 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1208 fm.formatlist(sorted(security), name='protocol',
1211 fm.formatlist(sorted(security), name='protocol',
1209 fmt='%s', sep=','))
1212 fmt='%s', sep=','))
1210
1213
1211 # These are warnings, not errors. So don't increment problem count. This
1214 # These are warnings, not errors. So don't increment problem count. This
1212 # may change in the future.
1215 # may change in the future.
1213 if 'tls1.2' not in security:
1216 if 'tls1.2' not in security:
1214 fm.plain(_(' TLS 1.2 not supported by Python install; '
1217 fm.plain(_(' TLS 1.2 not supported by Python install; '
1215 'network connections lack modern security\n'))
1218 'network connections lack modern security\n'))
1216 if 'sni' not in security:
1219 if 'sni' not in security:
1217 fm.plain(_(' SNI not supported by Python install; may have '
1220 fm.plain(_(' SNI not supported by Python install; may have '
1218 'connectivity issues with some servers\n'))
1221 'connectivity issues with some servers\n'))
1219
1222
1220 # TODO print CA cert info
1223 # TODO print CA cert info
1221
1224
1222 # hg version
1225 # hg version
1223 hgver = util.version()
1226 hgver = util.version()
1224 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1227 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1225 hgver.split('+')[0])
1228 hgver.split('+')[0])
1226 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1229 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1227 '+'.join(hgver.split('+')[1:]))
1230 '+'.join(hgver.split('+')[1:]))
1228
1231
1229 # compiled modules
1232 # compiled modules
1230 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1233 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1231 policy.policy)
1234 policy.policy)
1232 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1235 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1233 os.path.dirname(pycompat.fsencode(__file__)))
1236 os.path.dirname(pycompat.fsencode(__file__)))
1234
1237
1235 if policy.policy in ('c', 'allow'):
1238 if policy.policy in ('c', 'allow'):
1236 err = None
1239 err = None
1237 try:
1240 try:
1238 from .cext import (
1241 from .cext import (
1239 base85,
1242 base85,
1240 bdiff,
1243 bdiff,
1241 mpatch,
1244 mpatch,
1242 osutil,
1245 osutil,
1243 )
1246 )
1244 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1247 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1245 except Exception as inst:
1248 except Exception as inst:
1246 err = stringutil.forcebytestr(inst)
1249 err = stringutil.forcebytestr(inst)
1247 problems += 1
1250 problems += 1
1248 fm.condwrite(err, 'extensionserror', " %s\n", err)
1251 fm.condwrite(err, 'extensionserror', " %s\n", err)
1249
1252
1250 compengines = util.compengines._engines.values()
1253 compengines = util.compengines._engines.values()
1251 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1254 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1252 fm.formatlist(sorted(e.name() for e in compengines),
1255 fm.formatlist(sorted(e.name() for e in compengines),
1253 name='compengine', fmt='%s', sep=', '))
1256 name='compengine', fmt='%s', sep=', '))
1254 fm.write('compenginesavail', _('checking available compression engines '
1257 fm.write('compenginesavail', _('checking available compression engines '
1255 '(%s)\n'),
1258 '(%s)\n'),
1256 fm.formatlist(sorted(e.name() for e in compengines
1259 fm.formatlist(sorted(e.name() for e in compengines
1257 if e.available()),
1260 if e.available()),
1258 name='compengine', fmt='%s', sep=', '))
1261 name='compengine', fmt='%s', sep=', '))
1259 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1262 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1260 fm.write('compenginesserver', _('checking available compression engines '
1263 fm.write('compenginesserver', _('checking available compression engines '
1261 'for wire protocol (%s)\n'),
1264 'for wire protocol (%s)\n'),
1262 fm.formatlist([e.name() for e in wirecompengines
1265 fm.formatlist([e.name() for e in wirecompengines
1263 if e.wireprotosupport()],
1266 if e.wireprotosupport()],
1264 name='compengine', fmt='%s', sep=', '))
1267 name='compengine', fmt='%s', sep=', '))
1265 re2 = 'missing'
1268 re2 = 'missing'
1266 if util._re2:
1269 if util._re2:
1267 re2 = 'available'
1270 re2 = 'available'
1268 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1271 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1269 fm.data(re2=bool(util._re2))
1272 fm.data(re2=bool(util._re2))
1270
1273
1271 # templates
1274 # templates
1272 p = templater.templatepaths()
1275 p = templater.templatepaths()
1273 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1276 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1274 fm.condwrite(not p, '', _(" no template directories found\n"))
1277 fm.condwrite(not p, '', _(" no template directories found\n"))
1275 if p:
1278 if p:
1276 m = templater.templatepath("map-cmdline.default")
1279 m = templater.templatepath("map-cmdline.default")
1277 if m:
1280 if m:
1278 # template found, check if it is working
1281 # template found, check if it is working
1279 err = None
1282 err = None
1280 try:
1283 try:
1281 templater.templater.frommapfile(m)
1284 templater.templater.frommapfile(m)
1282 except Exception as inst:
1285 except Exception as inst:
1283 err = stringutil.forcebytestr(inst)
1286 err = stringutil.forcebytestr(inst)
1284 p = None
1287 p = None
1285 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1288 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1286 else:
1289 else:
1287 p = None
1290 p = None
1288 fm.condwrite(p, 'defaulttemplate',
1291 fm.condwrite(p, 'defaulttemplate',
1289 _("checking default template (%s)\n"), m)
1292 _("checking default template (%s)\n"), m)
1290 fm.condwrite(not m, 'defaulttemplatenotfound',
1293 fm.condwrite(not m, 'defaulttemplatenotfound',
1291 _(" template '%s' not found\n"), "default")
1294 _(" template '%s' not found\n"), "default")
1292 if not p:
1295 if not p:
1293 problems += 1
1296 problems += 1
1294 fm.condwrite(not p, '',
1297 fm.condwrite(not p, '',
1295 _(" (templates seem to have been installed incorrectly)\n"))
1298 _(" (templates seem to have been installed incorrectly)\n"))
1296
1299
1297 # editor
1300 # editor
1298 editor = ui.geteditor()
1301 editor = ui.geteditor()
1299 editor = util.expandpath(editor)
1302 editor = util.expandpath(editor)
1300 editorbin = procutil.shellsplit(editor)[0]
1303 editorbin = procutil.shellsplit(editor)[0]
1301 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1304 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1302 cmdpath = procutil.findexe(editorbin)
1305 cmdpath = procutil.findexe(editorbin)
1303 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1306 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1304 _(" No commit editor set and can't find %s in PATH\n"
1307 _(" No commit editor set and can't find %s in PATH\n"
1305 " (specify a commit editor in your configuration"
1308 " (specify a commit editor in your configuration"
1306 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1309 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1307 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1310 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1308 _(" Can't find editor '%s' in PATH\n"
1311 _(" Can't find editor '%s' in PATH\n"
1309 " (specify a commit editor in your configuration"
1312 " (specify a commit editor in your configuration"
1310 " file)\n"), not cmdpath and editorbin)
1313 " file)\n"), not cmdpath and editorbin)
1311 if not cmdpath and editor != 'vi':
1314 if not cmdpath and editor != 'vi':
1312 problems += 1
1315 problems += 1
1313
1316
1314 # check username
1317 # check username
1315 username = None
1318 username = None
1316 err = None
1319 err = None
1317 try:
1320 try:
1318 username = ui.username()
1321 username = ui.username()
1319 except error.Abort as e:
1322 except error.Abort as e:
1320 err = stringutil.forcebytestr(e)
1323 err = stringutil.forcebytestr(e)
1321 problems += 1
1324 problems += 1
1322
1325
1323 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1326 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1324 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1327 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1325 " (specify a username in your configuration file)\n"), err)
1328 " (specify a username in your configuration file)\n"), err)
1326
1329
1327 fm.condwrite(not problems, '',
1330 fm.condwrite(not problems, '',
1328 _("no problems detected\n"))
1331 _("no problems detected\n"))
1329 if not problems:
1332 if not problems:
1330 fm.data(problems=problems)
1333 fm.data(problems=problems)
1331 fm.condwrite(problems, 'problems',
1334 fm.condwrite(problems, 'problems',
1332 _("%d problems detected,"
1335 _("%d problems detected,"
1333 " please check your install!\n"), problems)
1336 " please check your install!\n"), problems)
1334 fm.end()
1337 fm.end()
1335
1338
1336 return problems
1339 return problems
1337
1340
1338 @command('debugknown', [], _('REPO ID...'), norepo=True)
1341 @command('debugknown', [], _('REPO ID...'), norepo=True)
1339 def debugknown(ui, repopath, *ids, **opts):
1342 def debugknown(ui, repopath, *ids, **opts):
1340 """test whether node ids are known to a repo
1343 """test whether node ids are known to a repo
1341
1344
1342 Every ID must be a full-length hex node id string. Returns a list of 0s
1345 Every ID must be a full-length hex node id string. Returns a list of 0s
1343 and 1s indicating unknown/known.
1346 and 1s indicating unknown/known.
1344 """
1347 """
1345 opts = pycompat.byteskwargs(opts)
1348 opts = pycompat.byteskwargs(opts)
1346 repo = hg.peer(ui, opts, repopath)
1349 repo = hg.peer(ui, opts, repopath)
1347 if not repo.capable('known'):
1350 if not repo.capable('known'):
1348 raise error.Abort("known() not supported by target repository")
1351 raise error.Abort("known() not supported by target repository")
1349 flags = repo.known([bin(s) for s in ids])
1352 flags = repo.known([bin(s) for s in ids])
1350 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1353 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1351
1354
1352 @command('debuglabelcomplete', [], _('LABEL...'))
1355 @command('debuglabelcomplete', [], _('LABEL...'))
1353 def debuglabelcomplete(ui, repo, *args):
1356 def debuglabelcomplete(ui, repo, *args):
1354 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1357 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1355 debugnamecomplete(ui, repo, *args)
1358 debugnamecomplete(ui, repo, *args)
1356
1359
1357 @command('debuglocks',
1360 @command('debuglocks',
1358 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1361 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1359 ('W', 'force-wlock', None,
1362 ('W', 'force-wlock', None,
1360 _('free the working state lock (DANGEROUS)')),
1363 _('free the working state lock (DANGEROUS)')),
1361 ('s', 'set-lock', None, _('set the store lock until stopped')),
1364 ('s', 'set-lock', None, _('set the store lock until stopped')),
1362 ('S', 'set-wlock', None,
1365 ('S', 'set-wlock', None,
1363 _('set the working state lock until stopped'))],
1366 _('set the working state lock until stopped'))],
1364 _('[OPTION]...'))
1367 _('[OPTION]...'))
1365 def debuglocks(ui, repo, **opts):
1368 def debuglocks(ui, repo, **opts):
1366 """show or modify state of locks
1369 """show or modify state of locks
1367
1370
1368 By default, this command will show which locks are held. This
1371 By default, this command will show which locks are held. This
1369 includes the user and process holding the lock, the amount of time
1372 includes the user and process holding the lock, the amount of time
1370 the lock has been held, and the machine name where the process is
1373 the lock has been held, and the machine name where the process is
1371 running if it's not local.
1374 running if it's not local.
1372
1375
1373 Locks protect the integrity of Mercurial's data, so should be
1376 Locks protect the integrity of Mercurial's data, so should be
1374 treated with care. System crashes or other interruptions may cause
1377 treated with care. System crashes or other interruptions may cause
1375 locks to not be properly released, though Mercurial will usually
1378 locks to not be properly released, though Mercurial will usually
1376 detect and remove such stale locks automatically.
1379 detect and remove such stale locks automatically.
1377
1380
1378 However, detecting stale locks may not always be possible (for
1381 However, detecting stale locks may not always be possible (for
1379 instance, on a shared filesystem). Removing locks may also be
1382 instance, on a shared filesystem). Removing locks may also be
1380 blocked by filesystem permissions.
1383 blocked by filesystem permissions.
1381
1384
1382 Setting a lock will prevent other commands from changing the data.
1385 Setting a lock will prevent other commands from changing the data.
1383 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1386 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1384 The set locks are removed when the command exits.
1387 The set locks are removed when the command exits.
1385
1388
1386 Returns 0 if no locks are held.
1389 Returns 0 if no locks are held.
1387
1390
1388 """
1391 """
1389
1392
1390 if opts.get(r'force_lock'):
1393 if opts.get(r'force_lock'):
1391 repo.svfs.unlink('lock')
1394 repo.svfs.unlink('lock')
1392 if opts.get(r'force_wlock'):
1395 if opts.get(r'force_wlock'):
1393 repo.vfs.unlink('wlock')
1396 repo.vfs.unlink('wlock')
1394 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1397 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1395 return 0
1398 return 0
1396
1399
1397 locks = []
1400 locks = []
1398 try:
1401 try:
1399 if opts.get(r'set_wlock'):
1402 if opts.get(r'set_wlock'):
1400 try:
1403 try:
1401 locks.append(repo.wlock(False))
1404 locks.append(repo.wlock(False))
1402 except error.LockHeld:
1405 except error.LockHeld:
1403 raise error.Abort(_('wlock is already held'))
1406 raise error.Abort(_('wlock is already held'))
1404 if opts.get(r'set_lock'):
1407 if opts.get(r'set_lock'):
1405 try:
1408 try:
1406 locks.append(repo.lock(False))
1409 locks.append(repo.lock(False))
1407 except error.LockHeld:
1410 except error.LockHeld:
1408 raise error.Abort(_('lock is already held'))
1411 raise error.Abort(_('lock is already held'))
1409 if len(locks):
1412 if len(locks):
1410 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1413 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1411 return 0
1414 return 0
1412 finally:
1415 finally:
1413 release(*locks)
1416 release(*locks)
1414
1417
1415 now = time.time()
1418 now = time.time()
1416 held = 0
1419 held = 0
1417
1420
1418 def report(vfs, name, method):
1421 def report(vfs, name, method):
1419 # this causes stale locks to get reaped for more accurate reporting
1422 # this causes stale locks to get reaped for more accurate reporting
1420 try:
1423 try:
1421 l = method(False)
1424 l = method(False)
1422 except error.LockHeld:
1425 except error.LockHeld:
1423 l = None
1426 l = None
1424
1427
1425 if l:
1428 if l:
1426 l.release()
1429 l.release()
1427 else:
1430 else:
1428 try:
1431 try:
1429 st = vfs.lstat(name)
1432 st = vfs.lstat(name)
1430 age = now - st[stat.ST_MTIME]
1433 age = now - st[stat.ST_MTIME]
1431 user = util.username(st.st_uid)
1434 user = util.username(st.st_uid)
1432 locker = vfs.readlock(name)
1435 locker = vfs.readlock(name)
1433 if ":" in locker:
1436 if ":" in locker:
1434 host, pid = locker.split(':')
1437 host, pid = locker.split(':')
1435 if host == socket.gethostname():
1438 if host == socket.gethostname():
1436 locker = 'user %s, process %s' % (user, pid)
1439 locker = 'user %s, process %s' % (user, pid)
1437 else:
1440 else:
1438 locker = 'user %s, process %s, host %s' \
1441 locker = 'user %s, process %s, host %s' \
1439 % (user, pid, host)
1442 % (user, pid, host)
1440 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1443 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1441 return 1
1444 return 1
1442 except OSError as e:
1445 except OSError as e:
1443 if e.errno != errno.ENOENT:
1446 if e.errno != errno.ENOENT:
1444 raise
1447 raise
1445
1448
1446 ui.write(("%-6s free\n") % (name + ":"))
1449 ui.write(("%-6s free\n") % (name + ":"))
1447 return 0
1450 return 0
1448
1451
1449 held += report(repo.svfs, "lock", repo.lock)
1452 held += report(repo.svfs, "lock", repo.lock)
1450 held += report(repo.vfs, "wlock", repo.wlock)
1453 held += report(repo.vfs, "wlock", repo.wlock)
1451
1454
1452 return held
1455 return held
1453
1456
1454 @command('debugmanifestfulltextcache', [
1457 @command('debugmanifestfulltextcache', [
1455 ('', 'clear', False, _('clear the cache')),
1458 ('', 'clear', False, _('clear the cache')),
1456 ('a', 'add', '', _('add the given manifest node to the cache'),
1459 ('a', 'add', '', _('add the given manifest node to the cache'),
1457 _('NODE'))
1460 _('NODE'))
1458 ], '')
1461 ], '')
1459 def debugmanifestfulltextcache(ui, repo, add=None, **opts):
1462 def debugmanifestfulltextcache(ui, repo, add=None, **opts):
1460 """show, clear or amend the contents of the manifest fulltext cache"""
1463 """show, clear or amend the contents of the manifest fulltext cache"""
1461 with repo.lock():
1464 with repo.lock():
1462 r = repo.manifestlog.getstorage(b'')
1465 r = repo.manifestlog.getstorage(b'')
1463 try:
1466 try:
1464 cache = r._fulltextcache
1467 cache = r._fulltextcache
1465 except AttributeError:
1468 except AttributeError:
1466 ui.warn(_(
1469 ui.warn(_(
1467 "Current revlog implementation doesn't appear to have a "
1470 "Current revlog implementation doesn't appear to have a "
1468 'manifest fulltext cache\n'))
1471 'manifest fulltext cache\n'))
1469 return
1472 return
1470
1473
1471 if opts.get(r'clear'):
1474 if opts.get(r'clear'):
1472 cache.clear()
1475 cache.clear()
1473
1476
1474 if add:
1477 if add:
1475 try:
1478 try:
1476 manifest = repo.manifestlog[r.lookup(add)]
1479 manifest = repo.manifestlog[r.lookup(add)]
1477 except error.LookupError as e:
1480 except error.LookupError as e:
1478 raise error.Abort(e, hint="Check your manifest node id")
1481 raise error.Abort(e, hint="Check your manifest node id")
1479 manifest.read() # stores revisision in cache too
1482 manifest.read() # stores revisision in cache too
1480
1483
1481 if not len(cache):
1484 if not len(cache):
1482 ui.write(_('Cache empty'))
1485 ui.write(_('Cache empty'))
1483 else:
1486 else:
1484 ui.write(
1487 ui.write(
1485 _('Cache contains %d manifest entries, in order of most to '
1488 _('Cache contains %d manifest entries, in order of most to '
1486 'least recent:\n') % (len(cache),))
1489 'least recent:\n') % (len(cache),))
1487 totalsize = 0
1490 totalsize = 0
1488 for nodeid in cache:
1491 for nodeid in cache:
1489 # Use cache.get to not update the LRU order
1492 # Use cache.get to not update the LRU order
1490 data = cache.get(nodeid)
1493 data = cache.get(nodeid)
1491 size = len(data)
1494 size = len(data)
1492 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1495 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1493 ui.write(_('id: %s, size %s\n') % (
1496 ui.write(_('id: %s, size %s\n') % (
1494 hex(nodeid), util.bytecount(size)))
1497 hex(nodeid), util.bytecount(size)))
1495 ondisk = cache._opener.stat('manifestfulltextcache').st_size
1498 ondisk = cache._opener.stat('manifestfulltextcache').st_size
1496 ui.write(
1499 ui.write(
1497 _('Total cache data size %s, on-disk %s\n') % (
1500 _('Total cache data size %s, on-disk %s\n') % (
1498 util.bytecount(totalsize), util.bytecount(ondisk))
1501 util.bytecount(totalsize), util.bytecount(ondisk))
1499 )
1502 )
1500
1503
1501 @command('debugmergestate', [], '')
1504 @command('debugmergestate', [], '')
1502 def debugmergestate(ui, repo, *args):
1505 def debugmergestate(ui, repo, *args):
1503 """print merge state
1506 """print merge state
1504
1507
1505 Use --verbose to print out information about whether v1 or v2 merge state
1508 Use --verbose to print out information about whether v1 or v2 merge state
1506 was chosen."""
1509 was chosen."""
1507 def _hashornull(h):
1510 def _hashornull(h):
1508 if h == nullhex:
1511 if h == nullhex:
1509 return 'null'
1512 return 'null'
1510 else:
1513 else:
1511 return h
1514 return h
1512
1515
1513 def printrecords(version):
1516 def printrecords(version):
1514 ui.write(('* version %d records\n') % version)
1517 ui.write(('* version %d records\n') % version)
1515 if version == 1:
1518 if version == 1:
1516 records = v1records
1519 records = v1records
1517 else:
1520 else:
1518 records = v2records
1521 records = v2records
1519
1522
1520 for rtype, record in records:
1523 for rtype, record in records:
1521 # pretty print some record types
1524 # pretty print some record types
1522 if rtype == 'L':
1525 if rtype == 'L':
1523 ui.write(('local: %s\n') % record)
1526 ui.write(('local: %s\n') % record)
1524 elif rtype == 'O':
1527 elif rtype == 'O':
1525 ui.write(('other: %s\n') % record)
1528 ui.write(('other: %s\n') % record)
1526 elif rtype == 'm':
1529 elif rtype == 'm':
1527 driver, mdstate = record.split('\0', 1)
1530 driver, mdstate = record.split('\0', 1)
1528 ui.write(('merge driver: %s (state "%s")\n')
1531 ui.write(('merge driver: %s (state "%s")\n')
1529 % (driver, mdstate))
1532 % (driver, mdstate))
1530 elif rtype in 'FDC':
1533 elif rtype in 'FDC':
1531 r = record.split('\0')
1534 r = record.split('\0')
1532 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1535 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1533 if version == 1:
1536 if version == 1:
1534 onode = 'not stored in v1 format'
1537 onode = 'not stored in v1 format'
1535 flags = r[7]
1538 flags = r[7]
1536 else:
1539 else:
1537 onode, flags = r[7:9]
1540 onode, flags = r[7:9]
1538 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1541 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1539 % (f, rtype, state, _hashornull(hash)))
1542 % (f, rtype, state, _hashornull(hash)))
1540 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1543 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1541 ui.write((' ancestor path: %s (node %s)\n')
1544 ui.write((' ancestor path: %s (node %s)\n')
1542 % (afile, _hashornull(anode)))
1545 % (afile, _hashornull(anode)))
1543 ui.write((' other path: %s (node %s)\n')
1546 ui.write((' other path: %s (node %s)\n')
1544 % (ofile, _hashornull(onode)))
1547 % (ofile, _hashornull(onode)))
1545 elif rtype == 'f':
1548 elif rtype == 'f':
1546 filename, rawextras = record.split('\0', 1)
1549 filename, rawextras = record.split('\0', 1)
1547 extras = rawextras.split('\0')
1550 extras = rawextras.split('\0')
1548 i = 0
1551 i = 0
1549 extrastrings = []
1552 extrastrings = []
1550 while i < len(extras):
1553 while i < len(extras):
1551 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1554 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1552 i += 2
1555 i += 2
1553
1556
1554 ui.write(('file extras: %s (%s)\n')
1557 ui.write(('file extras: %s (%s)\n')
1555 % (filename, ', '.join(extrastrings)))
1558 % (filename, ', '.join(extrastrings)))
1556 elif rtype == 'l':
1559 elif rtype == 'l':
1557 labels = record.split('\0', 2)
1560 labels = record.split('\0', 2)
1558 labels = [l for l in labels if len(l) > 0]
1561 labels = [l for l in labels if len(l) > 0]
1559 ui.write(('labels:\n'))
1562 ui.write(('labels:\n'))
1560 ui.write((' local: %s\n' % labels[0]))
1563 ui.write((' local: %s\n' % labels[0]))
1561 ui.write((' other: %s\n' % labels[1]))
1564 ui.write((' other: %s\n' % labels[1]))
1562 if len(labels) > 2:
1565 if len(labels) > 2:
1563 ui.write((' base: %s\n' % labels[2]))
1566 ui.write((' base: %s\n' % labels[2]))
1564 else:
1567 else:
1565 ui.write(('unrecognized entry: %s\t%s\n')
1568 ui.write(('unrecognized entry: %s\t%s\n')
1566 % (rtype, record.replace('\0', '\t')))
1569 % (rtype, record.replace('\0', '\t')))
1567
1570
1568 # Avoid mergestate.read() since it may raise an exception for unsupported
1571 # Avoid mergestate.read() since it may raise an exception for unsupported
1569 # merge state records. We shouldn't be doing this, but this is OK since this
1572 # merge state records. We shouldn't be doing this, but this is OK since this
1570 # command is pretty low-level.
1573 # command is pretty low-level.
1571 ms = mergemod.mergestate(repo)
1574 ms = mergemod.mergestate(repo)
1572
1575
1573 # sort so that reasonable information is on top
1576 # sort so that reasonable information is on top
1574 v1records = ms._readrecordsv1()
1577 v1records = ms._readrecordsv1()
1575 v2records = ms._readrecordsv2()
1578 v2records = ms._readrecordsv2()
1576 order = 'LOml'
1579 order = 'LOml'
1577 def key(r):
1580 def key(r):
1578 idx = order.find(r[0])
1581 idx = order.find(r[0])
1579 if idx == -1:
1582 if idx == -1:
1580 return (1, r[1])
1583 return (1, r[1])
1581 else:
1584 else:
1582 return (0, idx)
1585 return (0, idx)
1583 v1records.sort(key=key)
1586 v1records.sort(key=key)
1584 v2records.sort(key=key)
1587 v2records.sort(key=key)
1585
1588
1586 if not v1records and not v2records:
1589 if not v1records and not v2records:
1587 ui.write(('no merge state found\n'))
1590 ui.write(('no merge state found\n'))
1588 elif not v2records:
1591 elif not v2records:
1589 ui.note(('no version 2 merge state\n'))
1592 ui.note(('no version 2 merge state\n'))
1590 printrecords(1)
1593 printrecords(1)
1591 elif ms._v1v2match(v1records, v2records):
1594 elif ms._v1v2match(v1records, v2records):
1592 ui.note(('v1 and v2 states match: using v2\n'))
1595 ui.note(('v1 and v2 states match: using v2\n'))
1593 printrecords(2)
1596 printrecords(2)
1594 else:
1597 else:
1595 ui.note(('v1 and v2 states mismatch: using v1\n'))
1598 ui.note(('v1 and v2 states mismatch: using v1\n'))
1596 printrecords(1)
1599 printrecords(1)
1597 if ui.verbose:
1600 if ui.verbose:
1598 printrecords(2)
1601 printrecords(2)
1599
1602
1600 @command('debugnamecomplete', [], _('NAME...'))
1603 @command('debugnamecomplete', [], _('NAME...'))
1601 def debugnamecomplete(ui, repo, *args):
1604 def debugnamecomplete(ui, repo, *args):
1602 '''complete "names" - tags, open branch names, bookmark names'''
1605 '''complete "names" - tags, open branch names, bookmark names'''
1603
1606
1604 names = set()
1607 names = set()
1605 # since we previously only listed open branches, we will handle that
1608 # since we previously only listed open branches, we will handle that
1606 # specially (after this for loop)
1609 # specially (after this for loop)
1607 for name, ns in repo.names.iteritems():
1610 for name, ns in repo.names.iteritems():
1608 if name != 'branches':
1611 if name != 'branches':
1609 names.update(ns.listnames(repo))
1612 names.update(ns.listnames(repo))
1610 names.update(tag for (tag, heads, tip, closed)
1613 names.update(tag for (tag, heads, tip, closed)
1611 in repo.branchmap().iterbranches() if not closed)
1614 in repo.branchmap().iterbranches() if not closed)
1612 completions = set()
1615 completions = set()
1613 if not args:
1616 if not args:
1614 args = ['']
1617 args = ['']
1615 for a in args:
1618 for a in args:
1616 completions.update(n for n in names if n.startswith(a))
1619 completions.update(n for n in names if n.startswith(a))
1617 ui.write('\n'.join(sorted(completions)))
1620 ui.write('\n'.join(sorted(completions)))
1618 ui.write('\n')
1621 ui.write('\n')
1619
1622
1620 @command('debugobsolete',
1623 @command('debugobsolete',
1621 [('', 'flags', 0, _('markers flag')),
1624 [('', 'flags', 0, _('markers flag')),
1622 ('', 'record-parents', False,
1625 ('', 'record-parents', False,
1623 _('record parent information for the precursor')),
1626 _('record parent information for the precursor')),
1624 ('r', 'rev', [], _('display markers relevant to REV')),
1627 ('r', 'rev', [], _('display markers relevant to REV')),
1625 ('', 'exclusive', False, _('restrict display to markers only '
1628 ('', 'exclusive', False, _('restrict display to markers only '
1626 'relevant to REV')),
1629 'relevant to REV')),
1627 ('', 'index', False, _('display index of the marker')),
1630 ('', 'index', False, _('display index of the marker')),
1628 ('', 'delete', [], _('delete markers specified by indices')),
1631 ('', 'delete', [], _('delete markers specified by indices')),
1629 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1632 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1630 _('[OBSOLETED [REPLACEMENT ...]]'))
1633 _('[OBSOLETED [REPLACEMENT ...]]'))
1631 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1634 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1632 """create arbitrary obsolete marker
1635 """create arbitrary obsolete marker
1633
1636
1634 With no arguments, displays the list of obsolescence markers."""
1637 With no arguments, displays the list of obsolescence markers."""
1635
1638
1636 opts = pycompat.byteskwargs(opts)
1639 opts = pycompat.byteskwargs(opts)
1637
1640
1638 def parsenodeid(s):
1641 def parsenodeid(s):
1639 try:
1642 try:
1640 # We do not use revsingle/revrange functions here to accept
1643 # We do not use revsingle/revrange functions here to accept
1641 # arbitrary node identifiers, possibly not present in the
1644 # arbitrary node identifiers, possibly not present in the
1642 # local repository.
1645 # local repository.
1643 n = bin(s)
1646 n = bin(s)
1644 if len(n) != len(nullid):
1647 if len(n) != len(nullid):
1645 raise TypeError()
1648 raise TypeError()
1646 return n
1649 return n
1647 except TypeError:
1650 except TypeError:
1648 raise error.Abort('changeset references must be full hexadecimal '
1651 raise error.Abort('changeset references must be full hexadecimal '
1649 'node identifiers')
1652 'node identifiers')
1650
1653
1651 if opts.get('delete'):
1654 if opts.get('delete'):
1652 indices = []
1655 indices = []
1653 for v in opts.get('delete'):
1656 for v in opts.get('delete'):
1654 try:
1657 try:
1655 indices.append(int(v))
1658 indices.append(int(v))
1656 except ValueError:
1659 except ValueError:
1657 raise error.Abort(_('invalid index value: %r') % v,
1660 raise error.Abort(_('invalid index value: %r') % v,
1658 hint=_('use integers for indices'))
1661 hint=_('use integers for indices'))
1659
1662
1660 if repo.currenttransaction():
1663 if repo.currenttransaction():
1661 raise error.Abort(_('cannot delete obsmarkers in the middle '
1664 raise error.Abort(_('cannot delete obsmarkers in the middle '
1662 'of transaction.'))
1665 'of transaction.'))
1663
1666
1664 with repo.lock():
1667 with repo.lock():
1665 n = repair.deleteobsmarkers(repo.obsstore, indices)
1668 n = repair.deleteobsmarkers(repo.obsstore, indices)
1666 ui.write(_('deleted %i obsolescence markers\n') % n)
1669 ui.write(_('deleted %i obsolescence markers\n') % n)
1667
1670
1668 return
1671 return
1669
1672
1670 if precursor is not None:
1673 if precursor is not None:
1671 if opts['rev']:
1674 if opts['rev']:
1672 raise error.Abort('cannot select revision when creating marker')
1675 raise error.Abort('cannot select revision when creating marker')
1673 metadata = {}
1676 metadata = {}
1674 metadata['user'] = encoding.fromlocal(opts['user'] or ui.username())
1677 metadata['user'] = encoding.fromlocal(opts['user'] or ui.username())
1675 succs = tuple(parsenodeid(succ) for succ in successors)
1678 succs = tuple(parsenodeid(succ) for succ in successors)
1676 l = repo.lock()
1679 l = repo.lock()
1677 try:
1680 try:
1678 tr = repo.transaction('debugobsolete')
1681 tr = repo.transaction('debugobsolete')
1679 try:
1682 try:
1680 date = opts.get('date')
1683 date = opts.get('date')
1681 if date:
1684 if date:
1682 date = dateutil.parsedate(date)
1685 date = dateutil.parsedate(date)
1683 else:
1686 else:
1684 date = None
1687 date = None
1685 prec = parsenodeid(precursor)
1688 prec = parsenodeid(precursor)
1686 parents = None
1689 parents = None
1687 if opts['record_parents']:
1690 if opts['record_parents']:
1688 if prec not in repo.unfiltered():
1691 if prec not in repo.unfiltered():
1689 raise error.Abort('cannot used --record-parents on '
1692 raise error.Abort('cannot used --record-parents on '
1690 'unknown changesets')
1693 'unknown changesets')
1691 parents = repo.unfiltered()[prec].parents()
1694 parents = repo.unfiltered()[prec].parents()
1692 parents = tuple(p.node() for p in parents)
1695 parents = tuple(p.node() for p in parents)
1693 repo.obsstore.create(tr, prec, succs, opts['flags'],
1696 repo.obsstore.create(tr, prec, succs, opts['flags'],
1694 parents=parents, date=date,
1697 parents=parents, date=date,
1695 metadata=metadata, ui=ui)
1698 metadata=metadata, ui=ui)
1696 tr.close()
1699 tr.close()
1697 except ValueError as exc:
1700 except ValueError as exc:
1698 raise error.Abort(_('bad obsmarker input: %s') %
1701 raise error.Abort(_('bad obsmarker input: %s') %
1699 pycompat.bytestr(exc))
1702 pycompat.bytestr(exc))
1700 finally:
1703 finally:
1701 tr.release()
1704 tr.release()
1702 finally:
1705 finally:
1703 l.release()
1706 l.release()
1704 else:
1707 else:
1705 if opts['rev']:
1708 if opts['rev']:
1706 revs = scmutil.revrange(repo, opts['rev'])
1709 revs = scmutil.revrange(repo, opts['rev'])
1707 nodes = [repo[r].node() for r in revs]
1710 nodes = [repo[r].node() for r in revs]
1708 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1711 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1709 exclusive=opts['exclusive']))
1712 exclusive=opts['exclusive']))
1710 markers.sort(key=lambda x: x._data)
1713 markers.sort(key=lambda x: x._data)
1711 else:
1714 else:
1712 markers = obsutil.getmarkers(repo)
1715 markers = obsutil.getmarkers(repo)
1713
1716
1714 markerstoiter = markers
1717 markerstoiter = markers
1715 isrelevant = lambda m: True
1718 isrelevant = lambda m: True
1716 if opts.get('rev') and opts.get('index'):
1719 if opts.get('rev') and opts.get('index'):
1717 markerstoiter = obsutil.getmarkers(repo)
1720 markerstoiter = obsutil.getmarkers(repo)
1718 markerset = set(markers)
1721 markerset = set(markers)
1719 isrelevant = lambda m: m in markerset
1722 isrelevant = lambda m: m in markerset
1720
1723
1721 fm = ui.formatter('debugobsolete', opts)
1724 fm = ui.formatter('debugobsolete', opts)
1722 for i, m in enumerate(markerstoiter):
1725 for i, m in enumerate(markerstoiter):
1723 if not isrelevant(m):
1726 if not isrelevant(m):
1724 # marker can be irrelevant when we're iterating over a set
1727 # marker can be irrelevant when we're iterating over a set
1725 # of markers (markerstoiter) which is bigger than the set
1728 # of markers (markerstoiter) which is bigger than the set
1726 # of markers we want to display (markers)
1729 # of markers we want to display (markers)
1727 # this can happen if both --index and --rev options are
1730 # this can happen if both --index and --rev options are
1728 # provided and thus we need to iterate over all of the markers
1731 # provided and thus we need to iterate over all of the markers
1729 # to get the correct indices, but only display the ones that
1732 # to get the correct indices, but only display the ones that
1730 # are relevant to --rev value
1733 # are relevant to --rev value
1731 continue
1734 continue
1732 fm.startitem()
1735 fm.startitem()
1733 ind = i if opts.get('index') else None
1736 ind = i if opts.get('index') else None
1734 cmdutil.showmarker(fm, m, index=ind)
1737 cmdutil.showmarker(fm, m, index=ind)
1735 fm.end()
1738 fm.end()
1736
1739
1737 @command('debugpathcomplete',
1740 @command('debugpathcomplete',
1738 [('f', 'full', None, _('complete an entire path')),
1741 [('f', 'full', None, _('complete an entire path')),
1739 ('n', 'normal', None, _('show only normal files')),
1742 ('n', 'normal', None, _('show only normal files')),
1740 ('a', 'added', None, _('show only added files')),
1743 ('a', 'added', None, _('show only added files')),
1741 ('r', 'removed', None, _('show only removed files'))],
1744 ('r', 'removed', None, _('show only removed files'))],
1742 _('FILESPEC...'))
1745 _('FILESPEC...'))
1743 def debugpathcomplete(ui, repo, *specs, **opts):
1746 def debugpathcomplete(ui, repo, *specs, **opts):
1744 '''complete part or all of a tracked path
1747 '''complete part or all of a tracked path
1745
1748
1746 This command supports shells that offer path name completion. It
1749 This command supports shells that offer path name completion. It
1747 currently completes only files already known to the dirstate.
1750 currently completes only files already known to the dirstate.
1748
1751
1749 Completion extends only to the next path segment unless
1752 Completion extends only to the next path segment unless
1750 --full is specified, in which case entire paths are used.'''
1753 --full is specified, in which case entire paths are used.'''
1751
1754
1752 def complete(path, acceptable):
1755 def complete(path, acceptable):
1753 dirstate = repo.dirstate
1756 dirstate = repo.dirstate
1754 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1757 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1755 rootdir = repo.root + pycompat.ossep
1758 rootdir = repo.root + pycompat.ossep
1756 if spec != repo.root and not spec.startswith(rootdir):
1759 if spec != repo.root and not spec.startswith(rootdir):
1757 return [], []
1760 return [], []
1758 if os.path.isdir(spec):
1761 if os.path.isdir(spec):
1759 spec += '/'
1762 spec += '/'
1760 spec = spec[len(rootdir):]
1763 spec = spec[len(rootdir):]
1761 fixpaths = pycompat.ossep != '/'
1764 fixpaths = pycompat.ossep != '/'
1762 if fixpaths:
1765 if fixpaths:
1763 spec = spec.replace(pycompat.ossep, '/')
1766 spec = spec.replace(pycompat.ossep, '/')
1764 speclen = len(spec)
1767 speclen = len(spec)
1765 fullpaths = opts[r'full']
1768 fullpaths = opts[r'full']
1766 files, dirs = set(), set()
1769 files, dirs = set(), set()
1767 adddir, addfile = dirs.add, files.add
1770 adddir, addfile = dirs.add, files.add
1768 for f, st in dirstate.iteritems():
1771 for f, st in dirstate.iteritems():
1769 if f.startswith(spec) and st[0] in acceptable:
1772 if f.startswith(spec) and st[0] in acceptable:
1770 if fixpaths:
1773 if fixpaths:
1771 f = f.replace('/', pycompat.ossep)
1774 f = f.replace('/', pycompat.ossep)
1772 if fullpaths:
1775 if fullpaths:
1773 addfile(f)
1776 addfile(f)
1774 continue
1777 continue
1775 s = f.find(pycompat.ossep, speclen)
1778 s = f.find(pycompat.ossep, speclen)
1776 if s >= 0:
1779 if s >= 0:
1777 adddir(f[:s])
1780 adddir(f[:s])
1778 else:
1781 else:
1779 addfile(f)
1782 addfile(f)
1780 return files, dirs
1783 return files, dirs
1781
1784
1782 acceptable = ''
1785 acceptable = ''
1783 if opts[r'normal']:
1786 if opts[r'normal']:
1784 acceptable += 'nm'
1787 acceptable += 'nm'
1785 if opts[r'added']:
1788 if opts[r'added']:
1786 acceptable += 'a'
1789 acceptable += 'a'
1787 if opts[r'removed']:
1790 if opts[r'removed']:
1788 acceptable += 'r'
1791 acceptable += 'r'
1789 cwd = repo.getcwd()
1792 cwd = repo.getcwd()
1790 if not specs:
1793 if not specs:
1791 specs = ['.']
1794 specs = ['.']
1792
1795
1793 files, dirs = set(), set()
1796 files, dirs = set(), set()
1794 for spec in specs:
1797 for spec in specs:
1795 f, d = complete(spec, acceptable or 'nmar')
1798 f, d = complete(spec, acceptable or 'nmar')
1796 files.update(f)
1799 files.update(f)
1797 dirs.update(d)
1800 dirs.update(d)
1798 files.update(dirs)
1801 files.update(dirs)
1799 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1802 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1800 ui.write('\n')
1803 ui.write('\n')
1801
1804
1802 @command('debugpeer', [], _('PATH'), norepo=True)
1805 @command('debugpeer', [], _('PATH'), norepo=True)
1803 def debugpeer(ui, path):
1806 def debugpeer(ui, path):
1804 """establish a connection to a peer repository"""
1807 """establish a connection to a peer repository"""
1805 # Always enable peer request logging. Requires --debug to display
1808 # Always enable peer request logging. Requires --debug to display
1806 # though.
1809 # though.
1807 overrides = {
1810 overrides = {
1808 ('devel', 'debug.peer-request'): True,
1811 ('devel', 'debug.peer-request'): True,
1809 }
1812 }
1810
1813
1811 with ui.configoverride(overrides):
1814 with ui.configoverride(overrides):
1812 peer = hg.peer(ui, {}, path)
1815 peer = hg.peer(ui, {}, path)
1813
1816
1814 local = peer.local() is not None
1817 local = peer.local() is not None
1815 canpush = peer.canpush()
1818 canpush = peer.canpush()
1816
1819
1817 ui.write(_('url: %s\n') % peer.url())
1820 ui.write(_('url: %s\n') % peer.url())
1818 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1821 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1819 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1822 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1820
1823
1821 @command('debugpickmergetool',
1824 @command('debugpickmergetool',
1822 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1825 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1823 ('', 'changedelete', None, _('emulate merging change and delete')),
1826 ('', 'changedelete', None, _('emulate merging change and delete')),
1824 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1827 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1825 _('[PATTERN]...'),
1828 _('[PATTERN]...'),
1826 inferrepo=True)
1829 inferrepo=True)
1827 def debugpickmergetool(ui, repo, *pats, **opts):
1830 def debugpickmergetool(ui, repo, *pats, **opts):
1828 """examine which merge tool is chosen for specified file
1831 """examine which merge tool is chosen for specified file
1829
1832
1830 As described in :hg:`help merge-tools`, Mercurial examines
1833 As described in :hg:`help merge-tools`, Mercurial examines
1831 configurations below in this order to decide which merge tool is
1834 configurations below in this order to decide which merge tool is
1832 chosen for specified file.
1835 chosen for specified file.
1833
1836
1834 1. ``--tool`` option
1837 1. ``--tool`` option
1835 2. ``HGMERGE`` environment variable
1838 2. ``HGMERGE`` environment variable
1836 3. configurations in ``merge-patterns`` section
1839 3. configurations in ``merge-patterns`` section
1837 4. configuration of ``ui.merge``
1840 4. configuration of ``ui.merge``
1838 5. configurations in ``merge-tools`` section
1841 5. configurations in ``merge-tools`` section
1839 6. ``hgmerge`` tool (for historical reason only)
1842 6. ``hgmerge`` tool (for historical reason only)
1840 7. default tool for fallback (``:merge`` or ``:prompt``)
1843 7. default tool for fallback (``:merge`` or ``:prompt``)
1841
1844
1842 This command writes out examination result in the style below::
1845 This command writes out examination result in the style below::
1843
1846
1844 FILE = MERGETOOL
1847 FILE = MERGETOOL
1845
1848
1846 By default, all files known in the first parent context of the
1849 By default, all files known in the first parent context of the
1847 working directory are examined. Use file patterns and/or -I/-X
1850 working directory are examined. Use file patterns and/or -I/-X
1848 options to limit target files. -r/--rev is also useful to examine
1851 options to limit target files. -r/--rev is also useful to examine
1849 files in another context without actual updating to it.
1852 files in another context without actual updating to it.
1850
1853
1851 With --debug, this command shows warning messages while matching
1854 With --debug, this command shows warning messages while matching
1852 against ``merge-patterns`` and so on, too. It is recommended to
1855 against ``merge-patterns`` and so on, too. It is recommended to
1853 use this option with explicit file patterns and/or -I/-X options,
1856 use this option with explicit file patterns and/or -I/-X options,
1854 because this option increases amount of output per file according
1857 because this option increases amount of output per file according
1855 to configurations in hgrc.
1858 to configurations in hgrc.
1856
1859
1857 With -v/--verbose, this command shows configurations below at
1860 With -v/--verbose, this command shows configurations below at
1858 first (only if specified).
1861 first (only if specified).
1859
1862
1860 - ``--tool`` option
1863 - ``--tool`` option
1861 - ``HGMERGE`` environment variable
1864 - ``HGMERGE`` environment variable
1862 - configuration of ``ui.merge``
1865 - configuration of ``ui.merge``
1863
1866
1864 If merge tool is chosen before matching against
1867 If merge tool is chosen before matching against
1865 ``merge-patterns``, this command can't show any helpful
1868 ``merge-patterns``, this command can't show any helpful
1866 information, even with --debug. In such case, information above is
1869 information, even with --debug. In such case, information above is
1867 useful to know why a merge tool is chosen.
1870 useful to know why a merge tool is chosen.
1868 """
1871 """
1869 opts = pycompat.byteskwargs(opts)
1872 opts = pycompat.byteskwargs(opts)
1870 overrides = {}
1873 overrides = {}
1871 if opts['tool']:
1874 if opts['tool']:
1872 overrides[('ui', 'forcemerge')] = opts['tool']
1875 overrides[('ui', 'forcemerge')] = opts['tool']
1873 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1876 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1874
1877
1875 with ui.configoverride(overrides, 'debugmergepatterns'):
1878 with ui.configoverride(overrides, 'debugmergepatterns'):
1876 hgmerge = encoding.environ.get("HGMERGE")
1879 hgmerge = encoding.environ.get("HGMERGE")
1877 if hgmerge is not None:
1880 if hgmerge is not None:
1878 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1881 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1879 uimerge = ui.config("ui", "merge")
1882 uimerge = ui.config("ui", "merge")
1880 if uimerge:
1883 if uimerge:
1881 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1884 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1882
1885
1883 ctx = scmutil.revsingle(repo, opts.get('rev'))
1886 ctx = scmutil.revsingle(repo, opts.get('rev'))
1884 m = scmutil.match(ctx, pats, opts)
1887 m = scmutil.match(ctx, pats, opts)
1885 changedelete = opts['changedelete']
1888 changedelete = opts['changedelete']
1886 for path in ctx.walk(m):
1889 for path in ctx.walk(m):
1887 fctx = ctx[path]
1890 fctx = ctx[path]
1888 try:
1891 try:
1889 if not ui.debugflag:
1892 if not ui.debugflag:
1890 ui.pushbuffer(error=True)
1893 ui.pushbuffer(error=True)
1891 tool, toolpath = filemerge._picktool(repo, ui, path,
1894 tool, toolpath = filemerge._picktool(repo, ui, path,
1892 fctx.isbinary(),
1895 fctx.isbinary(),
1893 'l' in fctx.flags(),
1896 'l' in fctx.flags(),
1894 changedelete)
1897 changedelete)
1895 finally:
1898 finally:
1896 if not ui.debugflag:
1899 if not ui.debugflag:
1897 ui.popbuffer()
1900 ui.popbuffer()
1898 ui.write(('%s = %s\n') % (path, tool))
1901 ui.write(('%s = %s\n') % (path, tool))
1899
1902
1900 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1903 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1901 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1904 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1902 '''access the pushkey key/value protocol
1905 '''access the pushkey key/value protocol
1903
1906
1904 With two args, list the keys in the given namespace.
1907 With two args, list the keys in the given namespace.
1905
1908
1906 With five args, set a key to new if it currently is set to old.
1909 With five args, set a key to new if it currently is set to old.
1907 Reports success or failure.
1910 Reports success or failure.
1908 '''
1911 '''
1909
1912
1910 target = hg.peer(ui, {}, repopath)
1913 target = hg.peer(ui, {}, repopath)
1911 if keyinfo:
1914 if keyinfo:
1912 key, old, new = keyinfo
1915 key, old, new = keyinfo
1913 with target.commandexecutor() as e:
1916 with target.commandexecutor() as e:
1914 r = e.callcommand('pushkey', {
1917 r = e.callcommand('pushkey', {
1915 'namespace': namespace,
1918 'namespace': namespace,
1916 'key': key,
1919 'key': key,
1917 'old': old,
1920 'old': old,
1918 'new': new,
1921 'new': new,
1919 }).result()
1922 }).result()
1920
1923
1921 ui.status(pycompat.bytestr(r) + '\n')
1924 ui.status(pycompat.bytestr(r) + '\n')
1922 return not r
1925 return not r
1923 else:
1926 else:
1924 for k, v in sorted(target.listkeys(namespace).iteritems()):
1927 for k, v in sorted(target.listkeys(namespace).iteritems()):
1925 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1928 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1926 stringutil.escapestr(v)))
1929 stringutil.escapestr(v)))
1927
1930
1928 @command('debugpvec', [], _('A B'))
1931 @command('debugpvec', [], _('A B'))
1929 def debugpvec(ui, repo, a, b=None):
1932 def debugpvec(ui, repo, a, b=None):
1930 ca = scmutil.revsingle(repo, a)
1933 ca = scmutil.revsingle(repo, a)
1931 cb = scmutil.revsingle(repo, b)
1934 cb = scmutil.revsingle(repo, b)
1932 pa = pvec.ctxpvec(ca)
1935 pa = pvec.ctxpvec(ca)
1933 pb = pvec.ctxpvec(cb)
1936 pb = pvec.ctxpvec(cb)
1934 if pa == pb:
1937 if pa == pb:
1935 rel = "="
1938 rel = "="
1936 elif pa > pb:
1939 elif pa > pb:
1937 rel = ">"
1940 rel = ">"
1938 elif pa < pb:
1941 elif pa < pb:
1939 rel = "<"
1942 rel = "<"
1940 elif pa | pb:
1943 elif pa | pb:
1941 rel = "|"
1944 rel = "|"
1942 ui.write(_("a: %s\n") % pa)
1945 ui.write(_("a: %s\n") % pa)
1943 ui.write(_("b: %s\n") % pb)
1946 ui.write(_("b: %s\n") % pb)
1944 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1947 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1945 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1948 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1946 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1949 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1947 pa.distance(pb), rel))
1950 pa.distance(pb), rel))
1948
1951
1949 @command('debugrebuilddirstate|debugrebuildstate',
1952 @command('debugrebuilddirstate|debugrebuildstate',
1950 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1953 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1951 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1954 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1952 'the working copy parent')),
1955 'the working copy parent')),
1953 ],
1956 ],
1954 _('[-r REV]'))
1957 _('[-r REV]'))
1955 def debugrebuilddirstate(ui, repo, rev, **opts):
1958 def debugrebuilddirstate(ui, repo, rev, **opts):
1956 """rebuild the dirstate as it would look like for the given revision
1959 """rebuild the dirstate as it would look like for the given revision
1957
1960
1958 If no revision is specified the first current parent will be used.
1961 If no revision is specified the first current parent will be used.
1959
1962
1960 The dirstate will be set to the files of the given revision.
1963 The dirstate will be set to the files of the given revision.
1961 The actual working directory content or existing dirstate
1964 The actual working directory content or existing dirstate
1962 information such as adds or removes is not considered.
1965 information such as adds or removes is not considered.
1963
1966
1964 ``minimal`` will only rebuild the dirstate status for files that claim to be
1967 ``minimal`` will only rebuild the dirstate status for files that claim to be
1965 tracked but are not in the parent manifest, or that exist in the parent
1968 tracked but are not in the parent manifest, or that exist in the parent
1966 manifest but are not in the dirstate. It will not change adds, removes, or
1969 manifest but are not in the dirstate. It will not change adds, removes, or
1967 modified files that are in the working copy parent.
1970 modified files that are in the working copy parent.
1968
1971
1969 One use of this command is to make the next :hg:`status` invocation
1972 One use of this command is to make the next :hg:`status` invocation
1970 check the actual file content.
1973 check the actual file content.
1971 """
1974 """
1972 ctx = scmutil.revsingle(repo, rev)
1975 ctx = scmutil.revsingle(repo, rev)
1973 with repo.wlock():
1976 with repo.wlock():
1974 dirstate = repo.dirstate
1977 dirstate = repo.dirstate
1975 changedfiles = None
1978 changedfiles = None
1976 # See command doc for what minimal does.
1979 # See command doc for what minimal does.
1977 if opts.get(r'minimal'):
1980 if opts.get(r'minimal'):
1978 manifestfiles = set(ctx.manifest().keys())
1981 manifestfiles = set(ctx.manifest().keys())
1979 dirstatefiles = set(dirstate)
1982 dirstatefiles = set(dirstate)
1980 manifestonly = manifestfiles - dirstatefiles
1983 manifestonly = manifestfiles - dirstatefiles
1981 dsonly = dirstatefiles - manifestfiles
1984 dsonly = dirstatefiles - manifestfiles
1982 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1985 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1983 changedfiles = manifestonly | dsnotadded
1986 changedfiles = manifestonly | dsnotadded
1984
1987
1985 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1988 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1986
1989
1987 @command('debugrebuildfncache', [], '')
1990 @command('debugrebuildfncache', [], '')
1988 def debugrebuildfncache(ui, repo):
1991 def debugrebuildfncache(ui, repo):
1989 """rebuild the fncache file"""
1992 """rebuild the fncache file"""
1990 repair.rebuildfncache(ui, repo)
1993 repair.rebuildfncache(ui, repo)
1991
1994
1992 @command('debugrename',
1995 @command('debugrename',
1993 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1996 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1994 _('[-r REV] FILE'))
1997 _('[-r REV] FILE'))
1995 def debugrename(ui, repo, file1, *pats, **opts):
1998 def debugrename(ui, repo, file1, *pats, **opts):
1996 """dump rename information"""
1999 """dump rename information"""
1997
2000
1998 opts = pycompat.byteskwargs(opts)
2001 opts = pycompat.byteskwargs(opts)
1999 ctx = scmutil.revsingle(repo, opts.get('rev'))
2002 ctx = scmutil.revsingle(repo, opts.get('rev'))
2000 m = scmutil.match(ctx, (file1,) + pats, opts)
2003 m = scmutil.match(ctx, (file1,) + pats, opts)
2001 for abs in ctx.walk(m):
2004 for abs in ctx.walk(m):
2002 fctx = ctx[abs]
2005 fctx = ctx[abs]
2003 o = fctx.filelog().renamed(fctx.filenode())
2006 o = fctx.filelog().renamed(fctx.filenode())
2004 rel = m.rel(abs)
2007 rel = m.rel(abs)
2005 if o:
2008 if o:
2006 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2009 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2007 else:
2010 else:
2008 ui.write(_("%s not renamed\n") % rel)
2011 ui.write(_("%s not renamed\n") % rel)
2009
2012
2010 @command('debugrevlog', cmdutil.debugrevlogopts +
2013 @command('debugrevlog', cmdutil.debugrevlogopts +
2011 [('d', 'dump', False, _('dump index data'))],
2014 [('d', 'dump', False, _('dump index data'))],
2012 _('-c|-m|FILE'),
2015 _('-c|-m|FILE'),
2013 optionalrepo=True)
2016 optionalrepo=True)
2014 def debugrevlog(ui, repo, file_=None, **opts):
2017 def debugrevlog(ui, repo, file_=None, **opts):
2015 """show data and statistics about a revlog"""
2018 """show data and statistics about a revlog"""
2016 opts = pycompat.byteskwargs(opts)
2019 opts = pycompat.byteskwargs(opts)
2017 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2020 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2018
2021
2019 if opts.get("dump"):
2022 if opts.get("dump"):
2020 numrevs = len(r)
2023 numrevs = len(r)
2021 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
2024 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
2022 " rawsize totalsize compression heads chainlen\n"))
2025 " rawsize totalsize compression heads chainlen\n"))
2023 ts = 0
2026 ts = 0
2024 heads = set()
2027 heads = set()
2025
2028
2026 for rev in pycompat.xrange(numrevs):
2029 for rev in pycompat.xrange(numrevs):
2027 dbase = r.deltaparent(rev)
2030 dbase = r.deltaparent(rev)
2028 if dbase == -1:
2031 if dbase == -1:
2029 dbase = rev
2032 dbase = rev
2030 cbase = r.chainbase(rev)
2033 cbase = r.chainbase(rev)
2031 clen = r.chainlen(rev)
2034 clen = r.chainlen(rev)
2032 p1, p2 = r.parentrevs(rev)
2035 p1, p2 = r.parentrevs(rev)
2033 rs = r.rawsize(rev)
2036 rs = r.rawsize(rev)
2034 ts = ts + rs
2037 ts = ts + rs
2035 heads -= set(r.parentrevs(rev))
2038 heads -= set(r.parentrevs(rev))
2036 heads.add(rev)
2039 heads.add(rev)
2037 try:
2040 try:
2038 compression = ts / r.end(rev)
2041 compression = ts / r.end(rev)
2039 except ZeroDivisionError:
2042 except ZeroDivisionError:
2040 compression = 0
2043 compression = 0
2041 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2044 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2042 "%11d %5d %8d\n" %
2045 "%11d %5d %8d\n" %
2043 (rev, p1, p2, r.start(rev), r.end(rev),
2046 (rev, p1, p2, r.start(rev), r.end(rev),
2044 r.start(dbase), r.start(cbase),
2047 r.start(dbase), r.start(cbase),
2045 r.start(p1), r.start(p2),
2048 r.start(p1), r.start(p2),
2046 rs, ts, compression, len(heads), clen))
2049 rs, ts, compression, len(heads), clen))
2047 return 0
2050 return 0
2048
2051
2049 v = r.version
2052 v = r.version
2050 format = v & 0xFFFF
2053 format = v & 0xFFFF
2051 flags = []
2054 flags = []
2052 gdelta = False
2055 gdelta = False
2053 if v & revlog.FLAG_INLINE_DATA:
2056 if v & revlog.FLAG_INLINE_DATA:
2054 flags.append('inline')
2057 flags.append('inline')
2055 if v & revlog.FLAG_GENERALDELTA:
2058 if v & revlog.FLAG_GENERALDELTA:
2056 gdelta = True
2059 gdelta = True
2057 flags.append('generaldelta')
2060 flags.append('generaldelta')
2058 if not flags:
2061 if not flags:
2059 flags = ['(none)']
2062 flags = ['(none)']
2060
2063
2061 ### tracks merge vs single parent
2064 ### tracks merge vs single parent
2062 nummerges = 0
2065 nummerges = 0
2063
2066
2064 ### tracks ways the "delta" are build
2067 ### tracks ways the "delta" are build
2065 # nodelta
2068 # nodelta
2066 numempty = 0
2069 numempty = 0
2067 numemptytext = 0
2070 numemptytext = 0
2068 numemptydelta = 0
2071 numemptydelta = 0
2069 # full file content
2072 # full file content
2070 numfull = 0
2073 numfull = 0
2071 # intermediate snapshot against a prior snapshot
2074 # intermediate snapshot against a prior snapshot
2072 numsemi = 0
2075 numsemi = 0
2073 # snapshot count per depth
2076 # snapshot count per depth
2074 numsnapdepth = collections.defaultdict(lambda: 0)
2077 numsnapdepth = collections.defaultdict(lambda: 0)
2075 # delta against previous revision
2078 # delta against previous revision
2076 numprev = 0
2079 numprev = 0
2077 # delta against first or second parent (not prev)
2080 # delta against first or second parent (not prev)
2078 nump1 = 0
2081 nump1 = 0
2079 nump2 = 0
2082 nump2 = 0
2080 # delta against neither prev nor parents
2083 # delta against neither prev nor parents
2081 numother = 0
2084 numother = 0
2082 # delta against prev that are also first or second parent
2085 # delta against prev that are also first or second parent
2083 # (details of `numprev`)
2086 # (details of `numprev`)
2084 nump1prev = 0
2087 nump1prev = 0
2085 nump2prev = 0
2088 nump2prev = 0
2086
2089
2087 # data about delta chain of each revs
2090 # data about delta chain of each revs
2088 chainlengths = []
2091 chainlengths = []
2089 chainbases = []
2092 chainbases = []
2090 chainspans = []
2093 chainspans = []
2091
2094
2092 # data about each revision
2095 # data about each revision
2093 datasize = [None, 0, 0]
2096 datasize = [None, 0, 0]
2094 fullsize = [None, 0, 0]
2097 fullsize = [None, 0, 0]
2095 semisize = [None, 0, 0]
2098 semisize = [None, 0, 0]
2096 # snapshot count per depth
2099 # snapshot count per depth
2097 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2100 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2098 deltasize = [None, 0, 0]
2101 deltasize = [None, 0, 0]
2099 chunktypecounts = {}
2102 chunktypecounts = {}
2100 chunktypesizes = {}
2103 chunktypesizes = {}
2101
2104
2102 def addsize(size, l):
2105 def addsize(size, l):
2103 if l[0] is None or size < l[0]:
2106 if l[0] is None or size < l[0]:
2104 l[0] = size
2107 l[0] = size
2105 if size > l[1]:
2108 if size > l[1]:
2106 l[1] = size
2109 l[1] = size
2107 l[2] += size
2110 l[2] += size
2108
2111
2109 numrevs = len(r)
2112 numrevs = len(r)
2110 for rev in pycompat.xrange(numrevs):
2113 for rev in pycompat.xrange(numrevs):
2111 p1, p2 = r.parentrevs(rev)
2114 p1, p2 = r.parentrevs(rev)
2112 delta = r.deltaparent(rev)
2115 delta = r.deltaparent(rev)
2113 if format > 0:
2116 if format > 0:
2114 addsize(r.rawsize(rev), datasize)
2117 addsize(r.rawsize(rev), datasize)
2115 if p2 != nullrev:
2118 if p2 != nullrev:
2116 nummerges += 1
2119 nummerges += 1
2117 size = r.length(rev)
2120 size = r.length(rev)
2118 if delta == nullrev:
2121 if delta == nullrev:
2119 chainlengths.append(0)
2122 chainlengths.append(0)
2120 chainbases.append(r.start(rev))
2123 chainbases.append(r.start(rev))
2121 chainspans.append(size)
2124 chainspans.append(size)
2122 if size == 0:
2125 if size == 0:
2123 numempty += 1
2126 numempty += 1
2124 numemptytext += 1
2127 numemptytext += 1
2125 else:
2128 else:
2126 numfull += 1
2129 numfull += 1
2127 numsnapdepth[0] += 1
2130 numsnapdepth[0] += 1
2128 addsize(size, fullsize)
2131 addsize(size, fullsize)
2129 addsize(size, snapsizedepth[0])
2132 addsize(size, snapsizedepth[0])
2130 else:
2133 else:
2131 chainlengths.append(chainlengths[delta] + 1)
2134 chainlengths.append(chainlengths[delta] + 1)
2132 baseaddr = chainbases[delta]
2135 baseaddr = chainbases[delta]
2133 revaddr = r.start(rev)
2136 revaddr = r.start(rev)
2134 chainbases.append(baseaddr)
2137 chainbases.append(baseaddr)
2135 chainspans.append((revaddr - baseaddr) + size)
2138 chainspans.append((revaddr - baseaddr) + size)
2136 if size == 0:
2139 if size == 0:
2137 numempty += 1
2140 numempty += 1
2138 numemptydelta += 1
2141 numemptydelta += 1
2139 elif r.issnapshot(rev):
2142 elif r.issnapshot(rev):
2140 addsize(size, semisize)
2143 addsize(size, semisize)
2141 numsemi += 1
2144 numsemi += 1
2142 depth = r.snapshotdepth(rev)
2145 depth = r.snapshotdepth(rev)
2143 numsnapdepth[depth] += 1
2146 numsnapdepth[depth] += 1
2144 addsize(size, snapsizedepth[depth])
2147 addsize(size, snapsizedepth[depth])
2145 else:
2148 else:
2146 addsize(size, deltasize)
2149 addsize(size, deltasize)
2147 if delta == rev - 1:
2150 if delta == rev - 1:
2148 numprev += 1
2151 numprev += 1
2149 if delta == p1:
2152 if delta == p1:
2150 nump1prev += 1
2153 nump1prev += 1
2151 elif delta == p2:
2154 elif delta == p2:
2152 nump2prev += 1
2155 nump2prev += 1
2153 elif delta == p1:
2156 elif delta == p1:
2154 nump1 += 1
2157 nump1 += 1
2155 elif delta == p2:
2158 elif delta == p2:
2156 nump2 += 1
2159 nump2 += 1
2157 elif delta != nullrev:
2160 elif delta != nullrev:
2158 numother += 1
2161 numother += 1
2159
2162
2160 # Obtain data on the raw chunks in the revlog.
2163 # Obtain data on the raw chunks in the revlog.
2161 if util.safehasattr(r, '_getsegmentforrevs'):
2164 if util.safehasattr(r, '_getsegmentforrevs'):
2162 segment = r._getsegmentforrevs(rev, rev)[1]
2165 segment = r._getsegmentforrevs(rev, rev)[1]
2163 else:
2166 else:
2164 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2167 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2165 if segment:
2168 if segment:
2166 chunktype = bytes(segment[0:1])
2169 chunktype = bytes(segment[0:1])
2167 else:
2170 else:
2168 chunktype = 'empty'
2171 chunktype = 'empty'
2169
2172
2170 if chunktype not in chunktypecounts:
2173 if chunktype not in chunktypecounts:
2171 chunktypecounts[chunktype] = 0
2174 chunktypecounts[chunktype] = 0
2172 chunktypesizes[chunktype] = 0
2175 chunktypesizes[chunktype] = 0
2173
2176
2174 chunktypecounts[chunktype] += 1
2177 chunktypecounts[chunktype] += 1
2175 chunktypesizes[chunktype] += size
2178 chunktypesizes[chunktype] += size
2176
2179
2177 # Adjust size min value for empty cases
2180 # Adjust size min value for empty cases
2178 for size in (datasize, fullsize, semisize, deltasize):
2181 for size in (datasize, fullsize, semisize, deltasize):
2179 if size[0] is None:
2182 if size[0] is None:
2180 size[0] = 0
2183 size[0] = 0
2181
2184
2182 numdeltas = numrevs - numfull - numempty - numsemi
2185 numdeltas = numrevs - numfull - numempty - numsemi
2183 numoprev = numprev - nump1prev - nump2prev
2186 numoprev = numprev - nump1prev - nump2prev
2184 totalrawsize = datasize[2]
2187 totalrawsize = datasize[2]
2185 datasize[2] /= numrevs
2188 datasize[2] /= numrevs
2186 fulltotal = fullsize[2]
2189 fulltotal = fullsize[2]
2187 fullsize[2] /= numfull
2190 fullsize[2] /= numfull
2188 semitotal = semisize[2]
2191 semitotal = semisize[2]
2189 snaptotal = {}
2192 snaptotal = {}
2190 if 0 < numsemi:
2193 if 0 < numsemi:
2191 semisize[2] /= numsemi
2194 semisize[2] /= numsemi
2192 for depth in snapsizedepth:
2195 for depth in snapsizedepth:
2193 snaptotal[depth] = snapsizedepth[depth][2]
2196 snaptotal[depth] = snapsizedepth[depth][2]
2194 snapsizedepth[depth][2] /= numsnapdepth[depth]
2197 snapsizedepth[depth][2] /= numsnapdepth[depth]
2195
2198
2196 deltatotal = deltasize[2]
2199 deltatotal = deltasize[2]
2197 if numdeltas > 0:
2200 if numdeltas > 0:
2198 deltasize[2] /= numdeltas
2201 deltasize[2] /= numdeltas
2199 totalsize = fulltotal + semitotal + deltatotal
2202 totalsize = fulltotal + semitotal + deltatotal
2200 avgchainlen = sum(chainlengths) / numrevs
2203 avgchainlen = sum(chainlengths) / numrevs
2201 maxchainlen = max(chainlengths)
2204 maxchainlen = max(chainlengths)
2202 maxchainspan = max(chainspans)
2205 maxchainspan = max(chainspans)
2203 compratio = 1
2206 compratio = 1
2204 if totalsize:
2207 if totalsize:
2205 compratio = totalrawsize / totalsize
2208 compratio = totalrawsize / totalsize
2206
2209
2207 basedfmtstr = '%%%dd\n'
2210 basedfmtstr = '%%%dd\n'
2208 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2211 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2209
2212
2210 def dfmtstr(max):
2213 def dfmtstr(max):
2211 return basedfmtstr % len(str(max))
2214 return basedfmtstr % len(str(max))
2212 def pcfmtstr(max, padding=0):
2215 def pcfmtstr(max, padding=0):
2213 return basepcfmtstr % (len(str(max)), ' ' * padding)
2216 return basepcfmtstr % (len(str(max)), ' ' * padding)
2214
2217
2215 def pcfmt(value, total):
2218 def pcfmt(value, total):
2216 if total:
2219 if total:
2217 return (value, 100 * float(value) / total)
2220 return (value, 100 * float(value) / total)
2218 else:
2221 else:
2219 return value, 100.0
2222 return value, 100.0
2220
2223
2221 ui.write(('format : %d\n') % format)
2224 ui.write(('format : %d\n') % format)
2222 ui.write(('flags : %s\n') % ', '.join(flags))
2225 ui.write(('flags : %s\n') % ', '.join(flags))
2223
2226
2224 ui.write('\n')
2227 ui.write('\n')
2225 fmt = pcfmtstr(totalsize)
2228 fmt = pcfmtstr(totalsize)
2226 fmt2 = dfmtstr(totalsize)
2229 fmt2 = dfmtstr(totalsize)
2227 ui.write(('revisions : ') + fmt2 % numrevs)
2230 ui.write(('revisions : ') + fmt2 % numrevs)
2228 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2231 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2229 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2232 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2230 ui.write(('revisions : ') + fmt2 % numrevs)
2233 ui.write(('revisions : ') + fmt2 % numrevs)
2231 ui.write((' empty : ') + fmt % pcfmt(numempty, numrevs))
2234 ui.write((' empty : ') + fmt % pcfmt(numempty, numrevs))
2232 ui.write((' text : ')
2235 ui.write((' text : ')
2233 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta))
2236 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta))
2234 ui.write((' delta : ')
2237 ui.write((' delta : ')
2235 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta))
2238 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta))
2236 ui.write((' snapshot : ') + fmt % pcfmt(numfull + numsemi, numrevs))
2239 ui.write((' snapshot : ') + fmt % pcfmt(numfull + numsemi, numrevs))
2237 for depth in sorted(numsnapdepth):
2240 for depth in sorted(numsnapdepth):
2238 ui.write((' lvl-%-3d : ' % depth)
2241 ui.write((' lvl-%-3d : ' % depth)
2239 + fmt % pcfmt(numsnapdepth[depth], numrevs))
2242 + fmt % pcfmt(numsnapdepth[depth], numrevs))
2240 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2243 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2241 ui.write(('revision size : ') + fmt2 % totalsize)
2244 ui.write(('revision size : ') + fmt2 % totalsize)
2242 ui.write((' snapshot : ')
2245 ui.write((' snapshot : ')
2243 + fmt % pcfmt(fulltotal + semitotal, totalsize))
2246 + fmt % pcfmt(fulltotal + semitotal, totalsize))
2244 for depth in sorted(numsnapdepth):
2247 for depth in sorted(numsnapdepth):
2245 ui.write((' lvl-%-3d : ' % depth)
2248 ui.write((' lvl-%-3d : ' % depth)
2246 + fmt % pcfmt(snaptotal[depth], totalsize))
2249 + fmt % pcfmt(snaptotal[depth], totalsize))
2247 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2250 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2248
2251
2249 def fmtchunktype(chunktype):
2252 def fmtchunktype(chunktype):
2250 if chunktype == 'empty':
2253 if chunktype == 'empty':
2251 return ' %s : ' % chunktype
2254 return ' %s : ' % chunktype
2252 elif chunktype in pycompat.bytestr(string.ascii_letters):
2255 elif chunktype in pycompat.bytestr(string.ascii_letters):
2253 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2256 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2254 else:
2257 else:
2255 return ' 0x%s : ' % hex(chunktype)
2258 return ' 0x%s : ' % hex(chunktype)
2256
2259
2257 ui.write('\n')
2260 ui.write('\n')
2258 ui.write(('chunks : ') + fmt2 % numrevs)
2261 ui.write(('chunks : ') + fmt2 % numrevs)
2259 for chunktype in sorted(chunktypecounts):
2262 for chunktype in sorted(chunktypecounts):
2260 ui.write(fmtchunktype(chunktype))
2263 ui.write(fmtchunktype(chunktype))
2261 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2264 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2262 ui.write(('chunks size : ') + fmt2 % totalsize)
2265 ui.write(('chunks size : ') + fmt2 % totalsize)
2263 for chunktype in sorted(chunktypecounts):
2266 for chunktype in sorted(chunktypecounts):
2264 ui.write(fmtchunktype(chunktype))
2267 ui.write(fmtchunktype(chunktype))
2265 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2268 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2266
2269
2267 ui.write('\n')
2270 ui.write('\n')
2268 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2271 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2269 ui.write(('avg chain length : ') + fmt % avgchainlen)
2272 ui.write(('avg chain length : ') + fmt % avgchainlen)
2270 ui.write(('max chain length : ') + fmt % maxchainlen)
2273 ui.write(('max chain length : ') + fmt % maxchainlen)
2271 ui.write(('max chain reach : ') + fmt % maxchainspan)
2274 ui.write(('max chain reach : ') + fmt % maxchainspan)
2272 ui.write(('compression ratio : ') + fmt % compratio)
2275 ui.write(('compression ratio : ') + fmt % compratio)
2273
2276
2274 if format > 0:
2277 if format > 0:
2275 ui.write('\n')
2278 ui.write('\n')
2276 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2279 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2277 % tuple(datasize))
2280 % tuple(datasize))
2278 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2281 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2279 % tuple(fullsize))
2282 % tuple(fullsize))
2280 ui.write(('inter-snapshot size (min/max/avg) : %d / %d / %d\n')
2283 ui.write(('inter-snapshot size (min/max/avg) : %d / %d / %d\n')
2281 % tuple(semisize))
2284 % tuple(semisize))
2282 for depth in sorted(snapsizedepth):
2285 for depth in sorted(snapsizedepth):
2283 if depth == 0:
2286 if depth == 0:
2284 continue
2287 continue
2285 ui.write((' level-%-3d (min/max/avg) : %d / %d / %d\n')
2288 ui.write((' level-%-3d (min/max/avg) : %d / %d / %d\n')
2286 % ((depth,) + tuple(snapsizedepth[depth])))
2289 % ((depth,) + tuple(snapsizedepth[depth])))
2287 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2290 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2288 % tuple(deltasize))
2291 % tuple(deltasize))
2289
2292
2290 if numdeltas > 0:
2293 if numdeltas > 0:
2291 ui.write('\n')
2294 ui.write('\n')
2292 fmt = pcfmtstr(numdeltas)
2295 fmt = pcfmtstr(numdeltas)
2293 fmt2 = pcfmtstr(numdeltas, 4)
2296 fmt2 = pcfmtstr(numdeltas, 4)
2294 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2297 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2295 if numprev > 0:
2298 if numprev > 0:
2296 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2299 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2297 numprev))
2300 numprev))
2298 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2301 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2299 numprev))
2302 numprev))
2300 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2303 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2301 numprev))
2304 numprev))
2302 if gdelta:
2305 if gdelta:
2303 ui.write(('deltas against p1 : ')
2306 ui.write(('deltas against p1 : ')
2304 + fmt % pcfmt(nump1, numdeltas))
2307 + fmt % pcfmt(nump1, numdeltas))
2305 ui.write(('deltas against p2 : ')
2308 ui.write(('deltas against p2 : ')
2306 + fmt % pcfmt(nump2, numdeltas))
2309 + fmt % pcfmt(nump2, numdeltas))
2307 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2310 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2308 numdeltas))
2311 numdeltas))
2309
2312
2310 @command('debugrevlogindex', cmdutil.debugrevlogopts +
2313 @command('debugrevlogindex', cmdutil.debugrevlogopts +
2311 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2314 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2312 _('[-f FORMAT] -c|-m|FILE'),
2315 _('[-f FORMAT] -c|-m|FILE'),
2313 optionalrepo=True)
2316 optionalrepo=True)
2314 def debugrevlogindex(ui, repo, file_=None, **opts):
2317 def debugrevlogindex(ui, repo, file_=None, **opts):
2315 """dump the contents of a revlog index"""
2318 """dump the contents of a revlog index"""
2316 opts = pycompat.byteskwargs(opts)
2319 opts = pycompat.byteskwargs(opts)
2317 r = cmdutil.openrevlog(repo, 'debugrevlogindex', file_, opts)
2320 r = cmdutil.openrevlog(repo, 'debugrevlogindex', file_, opts)
2318 format = opts.get('format', 0)
2321 format = opts.get('format', 0)
2319 if format not in (0, 1):
2322 if format not in (0, 1):
2320 raise error.Abort(_("unknown format %d") % format)
2323 raise error.Abort(_("unknown format %d") % format)
2321
2324
2322 if ui.debugflag:
2325 if ui.debugflag:
2323 shortfn = hex
2326 shortfn = hex
2324 else:
2327 else:
2325 shortfn = short
2328 shortfn = short
2326
2329
2327 # There might not be anything in r, so have a sane default
2330 # There might not be anything in r, so have a sane default
2328 idlen = 12
2331 idlen = 12
2329 for i in r:
2332 for i in r:
2330 idlen = len(shortfn(r.node(i)))
2333 idlen = len(shortfn(r.node(i)))
2331 break
2334 break
2332
2335
2333 if format == 0:
2336 if format == 0:
2334 if ui.verbose:
2337 if ui.verbose:
2335 ui.write((" rev offset length linkrev"
2338 ui.write((" rev offset length linkrev"
2336 " %s %s p2\n") % ("nodeid".ljust(idlen),
2339 " %s %s p2\n") % ("nodeid".ljust(idlen),
2337 "p1".ljust(idlen)))
2340 "p1".ljust(idlen)))
2338 else:
2341 else:
2339 ui.write((" rev linkrev %s %s p2\n") % (
2342 ui.write((" rev linkrev %s %s p2\n") % (
2340 "nodeid".ljust(idlen), "p1".ljust(idlen)))
2343 "nodeid".ljust(idlen), "p1".ljust(idlen)))
2341 elif format == 1:
2344 elif format == 1:
2342 if ui.verbose:
2345 if ui.verbose:
2343 ui.write((" rev flag offset length size link p1"
2346 ui.write((" rev flag offset length size link p1"
2344 " p2 %s\n") % "nodeid".rjust(idlen))
2347 " p2 %s\n") % "nodeid".rjust(idlen))
2345 else:
2348 else:
2346 ui.write((" rev flag size link p1 p2 %s\n") %
2349 ui.write((" rev flag size link p1 p2 %s\n") %
2347 "nodeid".rjust(idlen))
2350 "nodeid".rjust(idlen))
2348
2351
2349 for i in r:
2352 for i in r:
2350 node = r.node(i)
2353 node = r.node(i)
2351 if format == 0:
2354 if format == 0:
2352 try:
2355 try:
2353 pp = r.parents(node)
2356 pp = r.parents(node)
2354 except Exception:
2357 except Exception:
2355 pp = [nullid, nullid]
2358 pp = [nullid, nullid]
2356 if ui.verbose:
2359 if ui.verbose:
2357 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
2360 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
2358 i, r.start(i), r.length(i), r.linkrev(i),
2361 i, r.start(i), r.length(i), r.linkrev(i),
2359 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2362 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2360 else:
2363 else:
2361 ui.write("% 6d % 7d %s %s %s\n" % (
2364 ui.write("% 6d % 7d %s %s %s\n" % (
2362 i, r.linkrev(i), shortfn(node), shortfn(pp[0]),
2365 i, r.linkrev(i), shortfn(node), shortfn(pp[0]),
2363 shortfn(pp[1])))
2366 shortfn(pp[1])))
2364 elif format == 1:
2367 elif format == 1:
2365 pr = r.parentrevs(i)
2368 pr = r.parentrevs(i)
2366 if ui.verbose:
2369 if ui.verbose:
2367 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
2370 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
2368 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2371 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2369 r.linkrev(i), pr[0], pr[1], shortfn(node)))
2372 r.linkrev(i), pr[0], pr[1], shortfn(node)))
2370 else:
2373 else:
2371 ui.write("% 6d %04x % 8d % 6d % 6d % 6d %s\n" % (
2374 ui.write("% 6d %04x % 8d % 6d % 6d % 6d %s\n" % (
2372 i, r.flags(i), r.rawsize(i), r.linkrev(i), pr[0], pr[1],
2375 i, r.flags(i), r.rawsize(i), r.linkrev(i), pr[0], pr[1],
2373 shortfn(node)))
2376 shortfn(node)))
2374
2377
2375 @command('debugrevspec',
2378 @command('debugrevspec',
2376 [('', 'optimize', None,
2379 [('', 'optimize', None,
2377 _('print parsed tree after optimizing (DEPRECATED)')),
2380 _('print parsed tree after optimizing (DEPRECATED)')),
2378 ('', 'show-revs', True, _('print list of result revisions (default)')),
2381 ('', 'show-revs', True, _('print list of result revisions (default)')),
2379 ('s', 'show-set', None, _('print internal representation of result set')),
2382 ('s', 'show-set', None, _('print internal representation of result set')),
2380 ('p', 'show-stage', [],
2383 ('p', 'show-stage', [],
2381 _('print parsed tree at the given stage'), _('NAME')),
2384 _('print parsed tree at the given stage'), _('NAME')),
2382 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2385 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2383 ('', 'verify-optimized', False, _('verify optimized result')),
2386 ('', 'verify-optimized', False, _('verify optimized result')),
2384 ],
2387 ],
2385 ('REVSPEC'))
2388 ('REVSPEC'))
2386 def debugrevspec(ui, repo, expr, **opts):
2389 def debugrevspec(ui, repo, expr, **opts):
2387 """parse and apply a revision specification
2390 """parse and apply a revision specification
2388
2391
2389 Use -p/--show-stage option to print the parsed tree at the given stages.
2392 Use -p/--show-stage option to print the parsed tree at the given stages.
2390 Use -p all to print tree at every stage.
2393 Use -p all to print tree at every stage.
2391
2394
2392 Use --no-show-revs option with -s or -p to print only the set
2395 Use --no-show-revs option with -s or -p to print only the set
2393 representation or the parsed tree respectively.
2396 representation or the parsed tree respectively.
2394
2397
2395 Use --verify-optimized to compare the optimized result with the unoptimized
2398 Use --verify-optimized to compare the optimized result with the unoptimized
2396 one. Returns 1 if the optimized result differs.
2399 one. Returns 1 if the optimized result differs.
2397 """
2400 """
2398 opts = pycompat.byteskwargs(opts)
2401 opts = pycompat.byteskwargs(opts)
2399 aliases = ui.configitems('revsetalias')
2402 aliases = ui.configitems('revsetalias')
2400 stages = [
2403 stages = [
2401 ('parsed', lambda tree: tree),
2404 ('parsed', lambda tree: tree),
2402 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2405 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2403 ui.warn)),
2406 ui.warn)),
2404 ('concatenated', revsetlang.foldconcat),
2407 ('concatenated', revsetlang.foldconcat),
2405 ('analyzed', revsetlang.analyze),
2408 ('analyzed', revsetlang.analyze),
2406 ('optimized', revsetlang.optimize),
2409 ('optimized', revsetlang.optimize),
2407 ]
2410 ]
2408 if opts['no_optimized']:
2411 if opts['no_optimized']:
2409 stages = stages[:-1]
2412 stages = stages[:-1]
2410 if opts['verify_optimized'] and opts['no_optimized']:
2413 if opts['verify_optimized'] and opts['no_optimized']:
2411 raise error.Abort(_('cannot use --verify-optimized with '
2414 raise error.Abort(_('cannot use --verify-optimized with '
2412 '--no-optimized'))
2415 '--no-optimized'))
2413 stagenames = set(n for n, f in stages)
2416 stagenames = set(n for n, f in stages)
2414
2417
2415 showalways = set()
2418 showalways = set()
2416 showchanged = set()
2419 showchanged = set()
2417 if ui.verbose and not opts['show_stage']:
2420 if ui.verbose and not opts['show_stage']:
2418 # show parsed tree by --verbose (deprecated)
2421 # show parsed tree by --verbose (deprecated)
2419 showalways.add('parsed')
2422 showalways.add('parsed')
2420 showchanged.update(['expanded', 'concatenated'])
2423 showchanged.update(['expanded', 'concatenated'])
2421 if opts['optimize']:
2424 if opts['optimize']:
2422 showalways.add('optimized')
2425 showalways.add('optimized')
2423 if opts['show_stage'] and opts['optimize']:
2426 if opts['show_stage'] and opts['optimize']:
2424 raise error.Abort(_('cannot use --optimize with --show-stage'))
2427 raise error.Abort(_('cannot use --optimize with --show-stage'))
2425 if opts['show_stage'] == ['all']:
2428 if opts['show_stage'] == ['all']:
2426 showalways.update(stagenames)
2429 showalways.update(stagenames)
2427 else:
2430 else:
2428 for n in opts['show_stage']:
2431 for n in opts['show_stage']:
2429 if n not in stagenames:
2432 if n not in stagenames:
2430 raise error.Abort(_('invalid stage name: %s') % n)
2433 raise error.Abort(_('invalid stage name: %s') % n)
2431 showalways.update(opts['show_stage'])
2434 showalways.update(opts['show_stage'])
2432
2435
2433 treebystage = {}
2436 treebystage = {}
2434 printedtree = None
2437 printedtree = None
2435 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
2438 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
2436 for n, f in stages:
2439 for n, f in stages:
2437 treebystage[n] = tree = f(tree)
2440 treebystage[n] = tree = f(tree)
2438 if n in showalways or (n in showchanged and tree != printedtree):
2441 if n in showalways or (n in showchanged and tree != printedtree):
2439 if opts['show_stage'] or n != 'parsed':
2442 if opts['show_stage'] or n != 'parsed':
2440 ui.write(("* %s:\n") % n)
2443 ui.write(("* %s:\n") % n)
2441 ui.write(revsetlang.prettyformat(tree), "\n")
2444 ui.write(revsetlang.prettyformat(tree), "\n")
2442 printedtree = tree
2445 printedtree = tree
2443
2446
2444 if opts['verify_optimized']:
2447 if opts['verify_optimized']:
2445 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2448 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2446 brevs = revset.makematcher(treebystage['optimized'])(repo)
2449 brevs = revset.makematcher(treebystage['optimized'])(repo)
2447 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2450 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2448 ui.write(("* analyzed set:\n"), stringutil.prettyrepr(arevs), "\n")
2451 ui.write(("* analyzed set:\n"), stringutil.prettyrepr(arevs), "\n")
2449 ui.write(("* optimized set:\n"), stringutil.prettyrepr(brevs), "\n")
2452 ui.write(("* optimized set:\n"), stringutil.prettyrepr(brevs), "\n")
2450 arevs = list(arevs)
2453 arevs = list(arevs)
2451 brevs = list(brevs)
2454 brevs = list(brevs)
2452 if arevs == brevs:
2455 if arevs == brevs:
2453 return 0
2456 return 0
2454 ui.write(('--- analyzed\n'), label='diff.file_a')
2457 ui.write(('--- analyzed\n'), label='diff.file_a')
2455 ui.write(('+++ optimized\n'), label='diff.file_b')
2458 ui.write(('+++ optimized\n'), label='diff.file_b')
2456 sm = difflib.SequenceMatcher(None, arevs, brevs)
2459 sm = difflib.SequenceMatcher(None, arevs, brevs)
2457 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2460 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2458 if tag in ('delete', 'replace'):
2461 if tag in ('delete', 'replace'):
2459 for c in arevs[alo:ahi]:
2462 for c in arevs[alo:ahi]:
2460 ui.write('-%s\n' % c, label='diff.deleted')
2463 ui.write('-%s\n' % c, label='diff.deleted')
2461 if tag in ('insert', 'replace'):
2464 if tag in ('insert', 'replace'):
2462 for c in brevs[blo:bhi]:
2465 for c in brevs[blo:bhi]:
2463 ui.write('+%s\n' % c, label='diff.inserted')
2466 ui.write('+%s\n' % c, label='diff.inserted')
2464 if tag == 'equal':
2467 if tag == 'equal':
2465 for c in arevs[alo:ahi]:
2468 for c in arevs[alo:ahi]:
2466 ui.write(' %s\n' % c)
2469 ui.write(' %s\n' % c)
2467 return 1
2470 return 1
2468
2471
2469 func = revset.makematcher(tree)
2472 func = revset.makematcher(tree)
2470 revs = func(repo)
2473 revs = func(repo)
2471 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2474 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2472 ui.write(("* set:\n"), stringutil.prettyrepr(revs), "\n")
2475 ui.write(("* set:\n"), stringutil.prettyrepr(revs), "\n")
2473 if not opts['show_revs']:
2476 if not opts['show_revs']:
2474 return
2477 return
2475 for c in revs:
2478 for c in revs:
2476 ui.write("%d\n" % c)
2479 ui.write("%d\n" % c)
2477
2480
2478 @command('debugserve', [
2481 @command('debugserve', [
2479 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2482 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2480 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2483 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2481 ('', 'logiofile', '', _('file to log server I/O to')),
2484 ('', 'logiofile', '', _('file to log server I/O to')),
2482 ], '')
2485 ], '')
2483 def debugserve(ui, repo, **opts):
2486 def debugserve(ui, repo, **opts):
2484 """run a server with advanced settings
2487 """run a server with advanced settings
2485
2488
2486 This command is similar to :hg:`serve`. It exists partially as a
2489 This command is similar to :hg:`serve`. It exists partially as a
2487 workaround to the fact that ``hg serve --stdio`` must have specific
2490 workaround to the fact that ``hg serve --stdio`` must have specific
2488 arguments for security reasons.
2491 arguments for security reasons.
2489 """
2492 """
2490 opts = pycompat.byteskwargs(opts)
2493 opts = pycompat.byteskwargs(opts)
2491
2494
2492 if not opts['sshstdio']:
2495 if not opts['sshstdio']:
2493 raise error.Abort(_('only --sshstdio is currently supported'))
2496 raise error.Abort(_('only --sshstdio is currently supported'))
2494
2497
2495 logfh = None
2498 logfh = None
2496
2499
2497 if opts['logiofd'] and opts['logiofile']:
2500 if opts['logiofd'] and opts['logiofile']:
2498 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2501 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2499
2502
2500 if opts['logiofd']:
2503 if opts['logiofd']:
2501 # Line buffered because output is line based.
2504 # Line buffered because output is line based.
2502 try:
2505 try:
2503 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2506 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2504 except OSError as e:
2507 except OSError as e:
2505 if e.errno != errno.ESPIPE:
2508 if e.errno != errno.ESPIPE:
2506 raise
2509 raise
2507 # can't seek a pipe, so `ab` mode fails on py3
2510 # can't seek a pipe, so `ab` mode fails on py3
2508 logfh = os.fdopen(int(opts['logiofd']), r'wb', 1)
2511 logfh = os.fdopen(int(opts['logiofd']), r'wb', 1)
2509 elif opts['logiofile']:
2512 elif opts['logiofile']:
2510 logfh = open(opts['logiofile'], 'ab', 1)
2513 logfh = open(opts['logiofile'], 'ab', 1)
2511
2514
2512 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2515 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2513 s.serve_forever()
2516 s.serve_forever()
2514
2517
2515 @command('debugsetparents', [], _('REV1 [REV2]'))
2518 @command('debugsetparents', [], _('REV1 [REV2]'))
2516 def debugsetparents(ui, repo, rev1, rev2=None):
2519 def debugsetparents(ui, repo, rev1, rev2=None):
2517 """manually set the parents of the current working directory
2520 """manually set the parents of the current working directory
2518
2521
2519 This is useful for writing repository conversion tools, but should
2522 This is useful for writing repository conversion tools, but should
2520 be used with care. For example, neither the working directory nor the
2523 be used with care. For example, neither the working directory nor the
2521 dirstate is updated, so file status may be incorrect after running this
2524 dirstate is updated, so file status may be incorrect after running this
2522 command.
2525 command.
2523
2526
2524 Returns 0 on success.
2527 Returns 0 on success.
2525 """
2528 """
2526
2529
2527 node1 = scmutil.revsingle(repo, rev1).node()
2530 node1 = scmutil.revsingle(repo, rev1).node()
2528 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2531 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2529
2532
2530 with repo.wlock():
2533 with repo.wlock():
2531 repo.setparents(node1, node2)
2534 repo.setparents(node1, node2)
2532
2535
2533 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2536 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2534 def debugssl(ui, repo, source=None, **opts):
2537 def debugssl(ui, repo, source=None, **opts):
2535 '''test a secure connection to a server
2538 '''test a secure connection to a server
2536
2539
2537 This builds the certificate chain for the server on Windows, installing the
2540 This builds the certificate chain for the server on Windows, installing the
2538 missing intermediates and trusted root via Windows Update if necessary. It
2541 missing intermediates and trusted root via Windows Update if necessary. It
2539 does nothing on other platforms.
2542 does nothing on other platforms.
2540
2543
2541 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2544 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2542 that server is used. See :hg:`help urls` for more information.
2545 that server is used. See :hg:`help urls` for more information.
2543
2546
2544 If the update succeeds, retry the original operation. Otherwise, the cause
2547 If the update succeeds, retry the original operation. Otherwise, the cause
2545 of the SSL error is likely another issue.
2548 of the SSL error is likely another issue.
2546 '''
2549 '''
2547 if not pycompat.iswindows:
2550 if not pycompat.iswindows:
2548 raise error.Abort(_('certificate chain building is only possible on '
2551 raise error.Abort(_('certificate chain building is only possible on '
2549 'Windows'))
2552 'Windows'))
2550
2553
2551 if not source:
2554 if not source:
2552 if not repo:
2555 if not repo:
2553 raise error.Abort(_("there is no Mercurial repository here, and no "
2556 raise error.Abort(_("there is no Mercurial repository here, and no "
2554 "server specified"))
2557 "server specified"))
2555 source = "default"
2558 source = "default"
2556
2559
2557 source, branches = hg.parseurl(ui.expandpath(source))
2560 source, branches = hg.parseurl(ui.expandpath(source))
2558 url = util.url(source)
2561 url = util.url(source)
2559 addr = None
2562 addr = None
2560
2563
2561 defaultport = {'https': 443, 'ssh': 22}
2564 defaultport = {'https': 443, 'ssh': 22}
2562 if url.scheme in defaultport:
2565 if url.scheme in defaultport:
2563 try:
2566 try:
2564 addr = (url.host, int(url.port or defaultport[url.scheme]))
2567 addr = (url.host, int(url.port or defaultport[url.scheme]))
2565 except ValueError:
2568 except ValueError:
2566 raise error.Abort(_("malformed port number in URL"))
2569 raise error.Abort(_("malformed port number in URL"))
2567 else:
2570 else:
2568 raise error.Abort(_("only https and ssh connections are supported"))
2571 raise error.Abort(_("only https and ssh connections are supported"))
2569
2572
2570 from . import win32
2573 from . import win32
2571
2574
2572 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2575 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2573 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2576 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2574
2577
2575 try:
2578 try:
2576 s.connect(addr)
2579 s.connect(addr)
2577 cert = s.getpeercert(True)
2580 cert = s.getpeercert(True)
2578
2581
2579 ui.status(_('checking the certificate chain for %s\n') % url.host)
2582 ui.status(_('checking the certificate chain for %s\n') % url.host)
2580
2583
2581 complete = win32.checkcertificatechain(cert, build=False)
2584 complete = win32.checkcertificatechain(cert, build=False)
2582
2585
2583 if not complete:
2586 if not complete:
2584 ui.status(_('certificate chain is incomplete, updating... '))
2587 ui.status(_('certificate chain is incomplete, updating... '))
2585
2588
2586 if not win32.checkcertificatechain(cert):
2589 if not win32.checkcertificatechain(cert):
2587 ui.status(_('failed.\n'))
2590 ui.status(_('failed.\n'))
2588 else:
2591 else:
2589 ui.status(_('done.\n'))
2592 ui.status(_('done.\n'))
2590 else:
2593 else:
2591 ui.status(_('full certificate chain is available\n'))
2594 ui.status(_('full certificate chain is available\n'))
2592 finally:
2595 finally:
2593 s.close()
2596 s.close()
2594
2597
2595 @command('debugsub',
2598 @command('debugsub',
2596 [('r', 'rev', '',
2599 [('r', 'rev', '',
2597 _('revision to check'), _('REV'))],
2600 _('revision to check'), _('REV'))],
2598 _('[-r REV] [REV]'))
2601 _('[-r REV] [REV]'))
2599 def debugsub(ui, repo, rev=None):
2602 def debugsub(ui, repo, rev=None):
2600 ctx = scmutil.revsingle(repo, rev, None)
2603 ctx = scmutil.revsingle(repo, rev, None)
2601 for k, v in sorted(ctx.substate.items()):
2604 for k, v in sorted(ctx.substate.items()):
2602 ui.write(('path %s\n') % k)
2605 ui.write(('path %s\n') % k)
2603 ui.write((' source %s\n') % v[0])
2606 ui.write((' source %s\n') % v[0])
2604 ui.write((' revision %s\n') % v[1])
2607 ui.write((' revision %s\n') % v[1])
2605
2608
2606 @command('debugsuccessorssets',
2609 @command('debugsuccessorssets',
2607 [('', 'closest', False, _('return closest successors sets only'))],
2610 [('', 'closest', False, _('return closest successors sets only'))],
2608 _('[REV]'))
2611 _('[REV]'))
2609 def debugsuccessorssets(ui, repo, *revs, **opts):
2612 def debugsuccessorssets(ui, repo, *revs, **opts):
2610 """show set of successors for revision
2613 """show set of successors for revision
2611
2614
2612 A successors set of changeset A is a consistent group of revisions that
2615 A successors set of changeset A is a consistent group of revisions that
2613 succeed A. It contains non-obsolete changesets only unless closests
2616 succeed A. It contains non-obsolete changesets only unless closests
2614 successors set is set.
2617 successors set is set.
2615
2618
2616 In most cases a changeset A has a single successors set containing a single
2619 In most cases a changeset A has a single successors set containing a single
2617 successor (changeset A replaced by A').
2620 successor (changeset A replaced by A').
2618
2621
2619 A changeset that is made obsolete with no successors are called "pruned".
2622 A changeset that is made obsolete with no successors are called "pruned".
2620 Such changesets have no successors sets at all.
2623 Such changesets have no successors sets at all.
2621
2624
2622 A changeset that has been "split" will have a successors set containing
2625 A changeset that has been "split" will have a successors set containing
2623 more than one successor.
2626 more than one successor.
2624
2627
2625 A changeset that has been rewritten in multiple different ways is called
2628 A changeset that has been rewritten in multiple different ways is called
2626 "divergent". Such changesets have multiple successor sets (each of which
2629 "divergent". Such changesets have multiple successor sets (each of which
2627 may also be split, i.e. have multiple successors).
2630 may also be split, i.e. have multiple successors).
2628
2631
2629 Results are displayed as follows::
2632 Results are displayed as follows::
2630
2633
2631 <rev1>
2634 <rev1>
2632 <successors-1A>
2635 <successors-1A>
2633 <rev2>
2636 <rev2>
2634 <successors-2A>
2637 <successors-2A>
2635 <successors-2B1> <successors-2B2> <successors-2B3>
2638 <successors-2B1> <successors-2B2> <successors-2B3>
2636
2639
2637 Here rev2 has two possible (i.e. divergent) successors sets. The first
2640 Here rev2 has two possible (i.e. divergent) successors sets. The first
2638 holds one element, whereas the second holds three (i.e. the changeset has
2641 holds one element, whereas the second holds three (i.e. the changeset has
2639 been split).
2642 been split).
2640 """
2643 """
2641 # passed to successorssets caching computation from one call to another
2644 # passed to successorssets caching computation from one call to another
2642 cache = {}
2645 cache = {}
2643 ctx2str = bytes
2646 ctx2str = bytes
2644 node2str = short
2647 node2str = short
2645 for rev in scmutil.revrange(repo, revs):
2648 for rev in scmutil.revrange(repo, revs):
2646 ctx = repo[rev]
2649 ctx = repo[rev]
2647 ui.write('%s\n'% ctx2str(ctx))
2650 ui.write('%s\n'% ctx2str(ctx))
2648 for succsset in obsutil.successorssets(repo, ctx.node(),
2651 for succsset in obsutil.successorssets(repo, ctx.node(),
2649 closest=opts[r'closest'],
2652 closest=opts[r'closest'],
2650 cache=cache):
2653 cache=cache):
2651 if succsset:
2654 if succsset:
2652 ui.write(' ')
2655 ui.write(' ')
2653 ui.write(node2str(succsset[0]))
2656 ui.write(node2str(succsset[0]))
2654 for node in succsset[1:]:
2657 for node in succsset[1:]:
2655 ui.write(' ')
2658 ui.write(' ')
2656 ui.write(node2str(node))
2659 ui.write(node2str(node))
2657 ui.write('\n')
2660 ui.write('\n')
2658
2661
2659 @command('debugtemplate',
2662 @command('debugtemplate',
2660 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2663 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2661 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2664 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2662 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2665 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2663 optionalrepo=True)
2666 optionalrepo=True)
2664 def debugtemplate(ui, repo, tmpl, **opts):
2667 def debugtemplate(ui, repo, tmpl, **opts):
2665 """parse and apply a template
2668 """parse and apply a template
2666
2669
2667 If -r/--rev is given, the template is processed as a log template and
2670 If -r/--rev is given, the template is processed as a log template and
2668 applied to the given changesets. Otherwise, it is processed as a generic
2671 applied to the given changesets. Otherwise, it is processed as a generic
2669 template.
2672 template.
2670
2673
2671 Use --verbose to print the parsed tree.
2674 Use --verbose to print the parsed tree.
2672 """
2675 """
2673 revs = None
2676 revs = None
2674 if opts[r'rev']:
2677 if opts[r'rev']:
2675 if repo is None:
2678 if repo is None:
2676 raise error.RepoError(_('there is no Mercurial repository here '
2679 raise error.RepoError(_('there is no Mercurial repository here '
2677 '(.hg not found)'))
2680 '(.hg not found)'))
2678 revs = scmutil.revrange(repo, opts[r'rev'])
2681 revs = scmutil.revrange(repo, opts[r'rev'])
2679
2682
2680 props = {}
2683 props = {}
2681 for d in opts[r'define']:
2684 for d in opts[r'define']:
2682 try:
2685 try:
2683 k, v = (e.strip() for e in d.split('=', 1))
2686 k, v = (e.strip() for e in d.split('=', 1))
2684 if not k or k == 'ui':
2687 if not k or k == 'ui':
2685 raise ValueError
2688 raise ValueError
2686 props[k] = v
2689 props[k] = v
2687 except ValueError:
2690 except ValueError:
2688 raise error.Abort(_('malformed keyword definition: %s') % d)
2691 raise error.Abort(_('malformed keyword definition: %s') % d)
2689
2692
2690 if ui.verbose:
2693 if ui.verbose:
2691 aliases = ui.configitems('templatealias')
2694 aliases = ui.configitems('templatealias')
2692 tree = templater.parse(tmpl)
2695 tree = templater.parse(tmpl)
2693 ui.note(templater.prettyformat(tree), '\n')
2696 ui.note(templater.prettyformat(tree), '\n')
2694 newtree = templater.expandaliases(tree, aliases)
2697 newtree = templater.expandaliases(tree, aliases)
2695 if newtree != tree:
2698 if newtree != tree:
2696 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2699 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2697
2700
2698 if revs is None:
2701 if revs is None:
2699 tres = formatter.templateresources(ui, repo)
2702 tres = formatter.templateresources(ui, repo)
2700 t = formatter.maketemplater(ui, tmpl, resources=tres)
2703 t = formatter.maketemplater(ui, tmpl, resources=tres)
2701 if ui.verbose:
2704 if ui.verbose:
2702 kwds, funcs = t.symbolsuseddefault()
2705 kwds, funcs = t.symbolsuseddefault()
2703 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds)))
2706 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds)))
2704 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs)))
2707 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs)))
2705 ui.write(t.renderdefault(props))
2708 ui.write(t.renderdefault(props))
2706 else:
2709 else:
2707 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2710 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2708 if ui.verbose:
2711 if ui.verbose:
2709 kwds, funcs = displayer.t.symbolsuseddefault()
2712 kwds, funcs = displayer.t.symbolsuseddefault()
2710 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds)))
2713 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds)))
2711 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs)))
2714 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs)))
2712 for r in revs:
2715 for r in revs:
2713 displayer.show(repo[r], **pycompat.strkwargs(props))
2716 displayer.show(repo[r], **pycompat.strkwargs(props))
2714 displayer.close()
2717 displayer.close()
2715
2718
2716 @command('debuguigetpass', [
2719 @command('debuguigetpass', [
2717 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2720 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2718 ], _('[-p TEXT]'), norepo=True)
2721 ], _('[-p TEXT]'), norepo=True)
2719 def debuguigetpass(ui, prompt=''):
2722 def debuguigetpass(ui, prompt=''):
2720 """show prompt to type password"""
2723 """show prompt to type password"""
2721 r = ui.getpass(prompt)
2724 r = ui.getpass(prompt)
2722 ui.write(('respose: %s\n') % r)
2725 ui.write(('respose: %s\n') % r)
2723
2726
2724 @command('debuguiprompt', [
2727 @command('debuguiprompt', [
2725 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2728 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2726 ], _('[-p TEXT]'), norepo=True)
2729 ], _('[-p TEXT]'), norepo=True)
2727 def debuguiprompt(ui, prompt=''):
2730 def debuguiprompt(ui, prompt=''):
2728 """show plain prompt"""
2731 """show plain prompt"""
2729 r = ui.prompt(prompt)
2732 r = ui.prompt(prompt)
2730 ui.write(('response: %s\n') % r)
2733 ui.write(('response: %s\n') % r)
2731
2734
2732 @command('debugupdatecaches', [])
2735 @command('debugupdatecaches', [])
2733 def debugupdatecaches(ui, repo, *pats, **opts):
2736 def debugupdatecaches(ui, repo, *pats, **opts):
2734 """warm all known caches in the repository"""
2737 """warm all known caches in the repository"""
2735 with repo.wlock(), repo.lock():
2738 with repo.wlock(), repo.lock():
2736 repo.updatecaches(full=True)
2739 repo.updatecaches(full=True)
2737
2740
2738 @command('debugupgraderepo', [
2741 @command('debugupgraderepo', [
2739 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2742 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2740 ('', 'run', False, _('performs an upgrade')),
2743 ('', 'run', False, _('performs an upgrade')),
2741 ])
2744 ])
2742 def debugupgraderepo(ui, repo, run=False, optimize=None):
2745 def debugupgraderepo(ui, repo, run=False, optimize=None):
2743 """upgrade a repository to use different features
2746 """upgrade a repository to use different features
2744
2747
2745 If no arguments are specified, the repository is evaluated for upgrade
2748 If no arguments are specified, the repository is evaluated for upgrade
2746 and a list of problems and potential optimizations is printed.
2749 and a list of problems and potential optimizations is printed.
2747
2750
2748 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2751 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2749 can be influenced via additional arguments. More details will be provided
2752 can be influenced via additional arguments. More details will be provided
2750 by the command output when run without ``--run``.
2753 by the command output when run without ``--run``.
2751
2754
2752 During the upgrade, the repository will be locked and no writes will be
2755 During the upgrade, the repository will be locked and no writes will be
2753 allowed.
2756 allowed.
2754
2757
2755 At the end of the upgrade, the repository may not be readable while new
2758 At the end of the upgrade, the repository may not be readable while new
2756 repository data is swapped in. This window will be as long as it takes to
2759 repository data is swapped in. This window will be as long as it takes to
2757 rename some directories inside the ``.hg`` directory. On most machines, this
2760 rename some directories inside the ``.hg`` directory. On most machines, this
2758 should complete almost instantaneously and the chances of a consumer being
2761 should complete almost instantaneously and the chances of a consumer being
2759 unable to access the repository should be low.
2762 unable to access the repository should be low.
2760 """
2763 """
2761 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2764 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2762
2765
2763 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2766 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2764 inferrepo=True)
2767 inferrepo=True)
2765 def debugwalk(ui, repo, *pats, **opts):
2768 def debugwalk(ui, repo, *pats, **opts):
2766 """show how files match on given patterns"""
2769 """show how files match on given patterns"""
2767 opts = pycompat.byteskwargs(opts)
2770 opts = pycompat.byteskwargs(opts)
2768 m = scmutil.match(repo[None], pats, opts)
2771 m = scmutil.match(repo[None], pats, opts)
2769 if ui.verbose:
2772 if ui.verbose:
2770 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n')
2773 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n')
2771 items = list(repo[None].walk(m))
2774 items = list(repo[None].walk(m))
2772 if not items:
2775 if not items:
2773 return
2776 return
2774 f = lambda fn: fn
2777 f = lambda fn: fn
2775 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2778 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2776 f = lambda fn: util.normpath(fn)
2779 f = lambda fn: util.normpath(fn)
2777 fmt = 'f %%-%ds %%-%ds %%s' % (
2780 fmt = 'f %%-%ds %%-%ds %%s' % (
2778 max([len(abs) for abs in items]),
2781 max([len(abs) for abs in items]),
2779 max([len(m.rel(abs)) for abs in items]))
2782 max([len(m.rel(abs)) for abs in items]))
2780 for abs in items:
2783 for abs in items:
2781 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2784 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2782 ui.write("%s\n" % line.rstrip())
2785 ui.write("%s\n" % line.rstrip())
2783
2786
2784 @command('debugwhyunstable', [], _('REV'))
2787 @command('debugwhyunstable', [], _('REV'))
2785 def debugwhyunstable(ui, repo, rev):
2788 def debugwhyunstable(ui, repo, rev):
2786 """explain instabilities of a changeset"""
2789 """explain instabilities of a changeset"""
2787 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
2790 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
2788 dnodes = ''
2791 dnodes = ''
2789 if entry.get('divergentnodes'):
2792 if entry.get('divergentnodes'):
2790 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2793 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2791 for ctx in entry['divergentnodes']) + ' '
2794 for ctx in entry['divergentnodes']) + ' '
2792 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2795 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2793 entry['reason'], entry['node']))
2796 entry['reason'], entry['node']))
2794
2797
2795 @command('debugwireargs',
2798 @command('debugwireargs',
2796 [('', 'three', '', 'three'),
2799 [('', 'three', '', 'three'),
2797 ('', 'four', '', 'four'),
2800 ('', 'four', '', 'four'),
2798 ('', 'five', '', 'five'),
2801 ('', 'five', '', 'five'),
2799 ] + cmdutil.remoteopts,
2802 ] + cmdutil.remoteopts,
2800 _('REPO [OPTIONS]... [ONE [TWO]]'),
2803 _('REPO [OPTIONS]... [ONE [TWO]]'),
2801 norepo=True)
2804 norepo=True)
2802 def debugwireargs(ui, repopath, *vals, **opts):
2805 def debugwireargs(ui, repopath, *vals, **opts):
2803 opts = pycompat.byteskwargs(opts)
2806 opts = pycompat.byteskwargs(opts)
2804 repo = hg.peer(ui, opts, repopath)
2807 repo = hg.peer(ui, opts, repopath)
2805 for opt in cmdutil.remoteopts:
2808 for opt in cmdutil.remoteopts:
2806 del opts[opt[1]]
2809 del opts[opt[1]]
2807 args = {}
2810 args = {}
2808 for k, v in opts.iteritems():
2811 for k, v in opts.iteritems():
2809 if v:
2812 if v:
2810 args[k] = v
2813 args[k] = v
2811 args = pycompat.strkwargs(args)
2814 args = pycompat.strkwargs(args)
2812 # run twice to check that we don't mess up the stream for the next command
2815 # run twice to check that we don't mess up the stream for the next command
2813 res1 = repo.debugwireargs(*vals, **args)
2816 res1 = repo.debugwireargs(*vals, **args)
2814 res2 = repo.debugwireargs(*vals, **args)
2817 res2 = repo.debugwireargs(*vals, **args)
2815 ui.write("%s\n" % res1)
2818 ui.write("%s\n" % res1)
2816 if res1 != res2:
2819 if res1 != res2:
2817 ui.warn("%s\n" % res2)
2820 ui.warn("%s\n" % res2)
2818
2821
2819 def _parsewirelangblocks(fh):
2822 def _parsewirelangblocks(fh):
2820 activeaction = None
2823 activeaction = None
2821 blocklines = []
2824 blocklines = []
2822
2825
2823 for line in fh:
2826 for line in fh:
2824 line = line.rstrip()
2827 line = line.rstrip()
2825 if not line:
2828 if not line:
2826 continue
2829 continue
2827
2830
2828 if line.startswith(b'#'):
2831 if line.startswith(b'#'):
2829 continue
2832 continue
2830
2833
2831 if not line.startswith(b' '):
2834 if not line.startswith(b' '):
2832 # New block. Flush previous one.
2835 # New block. Flush previous one.
2833 if activeaction:
2836 if activeaction:
2834 yield activeaction, blocklines
2837 yield activeaction, blocklines
2835
2838
2836 activeaction = line
2839 activeaction = line
2837 blocklines = []
2840 blocklines = []
2838 continue
2841 continue
2839
2842
2840 # Else we start with an indent.
2843 # Else we start with an indent.
2841
2844
2842 if not activeaction:
2845 if not activeaction:
2843 raise error.Abort(_('indented line outside of block'))
2846 raise error.Abort(_('indented line outside of block'))
2844
2847
2845 blocklines.append(line)
2848 blocklines.append(line)
2846
2849
2847 # Flush last block.
2850 # Flush last block.
2848 if activeaction:
2851 if activeaction:
2849 yield activeaction, blocklines
2852 yield activeaction, blocklines
2850
2853
2851 @command('debugwireproto',
2854 @command('debugwireproto',
2852 [
2855 [
2853 ('', 'localssh', False, _('start an SSH server for this repo')),
2856 ('', 'localssh', False, _('start an SSH server for this repo')),
2854 ('', 'peer', '', _('construct a specific version of the peer')),
2857 ('', 'peer', '', _('construct a specific version of the peer')),
2855 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2858 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2856 ('', 'nologhandshake', False,
2859 ('', 'nologhandshake', False,
2857 _('do not log I/O related to the peer handshake')),
2860 _('do not log I/O related to the peer handshake')),
2858 ] + cmdutil.remoteopts,
2861 ] + cmdutil.remoteopts,
2859 _('[PATH]'),
2862 _('[PATH]'),
2860 optionalrepo=True)
2863 optionalrepo=True)
2861 def debugwireproto(ui, repo, path=None, **opts):
2864 def debugwireproto(ui, repo, path=None, **opts):
2862 """send wire protocol commands to a server
2865 """send wire protocol commands to a server
2863
2866
2864 This command can be used to issue wire protocol commands to remote
2867 This command can be used to issue wire protocol commands to remote
2865 peers and to debug the raw data being exchanged.
2868 peers and to debug the raw data being exchanged.
2866
2869
2867 ``--localssh`` will start an SSH server against the current repository
2870 ``--localssh`` will start an SSH server against the current repository
2868 and connect to that. By default, the connection will perform a handshake
2871 and connect to that. By default, the connection will perform a handshake
2869 and establish an appropriate peer instance.
2872 and establish an appropriate peer instance.
2870
2873
2871 ``--peer`` can be used to bypass the handshake protocol and construct a
2874 ``--peer`` can be used to bypass the handshake protocol and construct a
2872 peer instance using the specified class type. Valid values are ``raw``,
2875 peer instance using the specified class type. Valid values are ``raw``,
2873 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
2876 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
2874 raw data payloads and don't support higher-level command actions.
2877 raw data payloads and don't support higher-level command actions.
2875
2878
2876 ``--noreadstderr`` can be used to disable automatic reading from stderr
2879 ``--noreadstderr`` can be used to disable automatic reading from stderr
2877 of the peer (for SSH connections only). Disabling automatic reading of
2880 of the peer (for SSH connections only). Disabling automatic reading of
2878 stderr is useful for making output more deterministic.
2881 stderr is useful for making output more deterministic.
2879
2882
2880 Commands are issued via a mini language which is specified via stdin.
2883 Commands are issued via a mini language which is specified via stdin.
2881 The language consists of individual actions to perform. An action is
2884 The language consists of individual actions to perform. An action is
2882 defined by a block. A block is defined as a line with no leading
2885 defined by a block. A block is defined as a line with no leading
2883 space followed by 0 or more lines with leading space. Blocks are
2886 space followed by 0 or more lines with leading space. Blocks are
2884 effectively a high-level command with additional metadata.
2887 effectively a high-level command with additional metadata.
2885
2888
2886 Lines beginning with ``#`` are ignored.
2889 Lines beginning with ``#`` are ignored.
2887
2890
2888 The following sections denote available actions.
2891 The following sections denote available actions.
2889
2892
2890 raw
2893 raw
2891 ---
2894 ---
2892
2895
2893 Send raw data to the server.
2896 Send raw data to the server.
2894
2897
2895 The block payload contains the raw data to send as one atomic send
2898 The block payload contains the raw data to send as one atomic send
2896 operation. The data may not actually be delivered in a single system
2899 operation. The data may not actually be delivered in a single system
2897 call: it depends on the abilities of the transport being used.
2900 call: it depends on the abilities of the transport being used.
2898
2901
2899 Each line in the block is de-indented and concatenated. Then, that
2902 Each line in the block is de-indented and concatenated. Then, that
2900 value is evaluated as a Python b'' literal. This allows the use of
2903 value is evaluated as a Python b'' literal. This allows the use of
2901 backslash escaping, etc.
2904 backslash escaping, etc.
2902
2905
2903 raw+
2906 raw+
2904 ----
2907 ----
2905
2908
2906 Behaves like ``raw`` except flushes output afterwards.
2909 Behaves like ``raw`` except flushes output afterwards.
2907
2910
2908 command <X>
2911 command <X>
2909 -----------
2912 -----------
2910
2913
2911 Send a request to run a named command, whose name follows the ``command``
2914 Send a request to run a named command, whose name follows the ``command``
2912 string.
2915 string.
2913
2916
2914 Arguments to the command are defined as lines in this block. The format of
2917 Arguments to the command are defined as lines in this block. The format of
2915 each line is ``<key> <value>``. e.g.::
2918 each line is ``<key> <value>``. e.g.::
2916
2919
2917 command listkeys
2920 command listkeys
2918 namespace bookmarks
2921 namespace bookmarks
2919
2922
2920 If the value begins with ``eval:``, it will be interpreted as a Python
2923 If the value begins with ``eval:``, it will be interpreted as a Python
2921 literal expression. Otherwise values are interpreted as Python b'' literals.
2924 literal expression. Otherwise values are interpreted as Python b'' literals.
2922 This allows sending complex types and encoding special byte sequences via
2925 This allows sending complex types and encoding special byte sequences via
2923 backslash escaping.
2926 backslash escaping.
2924
2927
2925 The following arguments have special meaning:
2928 The following arguments have special meaning:
2926
2929
2927 ``PUSHFILE``
2930 ``PUSHFILE``
2928 When defined, the *push* mechanism of the peer will be used instead
2931 When defined, the *push* mechanism of the peer will be used instead
2929 of the static request-response mechanism and the content of the
2932 of the static request-response mechanism and the content of the
2930 file specified in the value of this argument will be sent as the
2933 file specified in the value of this argument will be sent as the
2931 command payload.
2934 command payload.
2932
2935
2933 This can be used to submit a local bundle file to the remote.
2936 This can be used to submit a local bundle file to the remote.
2934
2937
2935 batchbegin
2938 batchbegin
2936 ----------
2939 ----------
2937
2940
2938 Instruct the peer to begin a batched send.
2941 Instruct the peer to begin a batched send.
2939
2942
2940 All ``command`` blocks are queued for execution until the next
2943 All ``command`` blocks are queued for execution until the next
2941 ``batchsubmit`` block.
2944 ``batchsubmit`` block.
2942
2945
2943 batchsubmit
2946 batchsubmit
2944 -----------
2947 -----------
2945
2948
2946 Submit previously queued ``command`` blocks as a batch request.
2949 Submit previously queued ``command`` blocks as a batch request.
2947
2950
2948 This action MUST be paired with a ``batchbegin`` action.
2951 This action MUST be paired with a ``batchbegin`` action.
2949
2952
2950 httprequest <method> <path>
2953 httprequest <method> <path>
2951 ---------------------------
2954 ---------------------------
2952
2955
2953 (HTTP peer only)
2956 (HTTP peer only)
2954
2957
2955 Send an HTTP request to the peer.
2958 Send an HTTP request to the peer.
2956
2959
2957 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2960 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2958
2961
2959 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2962 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2960 headers to add to the request. e.g. ``Accept: foo``.
2963 headers to add to the request. e.g. ``Accept: foo``.
2961
2964
2962 The following arguments are special:
2965 The following arguments are special:
2963
2966
2964 ``BODYFILE``
2967 ``BODYFILE``
2965 The content of the file defined as the value to this argument will be
2968 The content of the file defined as the value to this argument will be
2966 transferred verbatim as the HTTP request body.
2969 transferred verbatim as the HTTP request body.
2967
2970
2968 ``frame <type> <flags> <payload>``
2971 ``frame <type> <flags> <payload>``
2969 Send a unified protocol frame as part of the request body.
2972 Send a unified protocol frame as part of the request body.
2970
2973
2971 All frames will be collected and sent as the body to the HTTP
2974 All frames will be collected and sent as the body to the HTTP
2972 request.
2975 request.
2973
2976
2974 close
2977 close
2975 -----
2978 -----
2976
2979
2977 Close the connection to the server.
2980 Close the connection to the server.
2978
2981
2979 flush
2982 flush
2980 -----
2983 -----
2981
2984
2982 Flush data written to the server.
2985 Flush data written to the server.
2983
2986
2984 readavailable
2987 readavailable
2985 -------------
2988 -------------
2986
2989
2987 Close the write end of the connection and read all available data from
2990 Close the write end of the connection and read all available data from
2988 the server.
2991 the server.
2989
2992
2990 If the connection to the server encompasses multiple pipes, we poll both
2993 If the connection to the server encompasses multiple pipes, we poll both
2991 pipes and read available data.
2994 pipes and read available data.
2992
2995
2993 readline
2996 readline
2994 --------
2997 --------
2995
2998
2996 Read a line of output from the server. If there are multiple output
2999 Read a line of output from the server. If there are multiple output
2997 pipes, reads only the main pipe.
3000 pipes, reads only the main pipe.
2998
3001
2999 ereadline
3002 ereadline
3000 ---------
3003 ---------
3001
3004
3002 Like ``readline``, but read from the stderr pipe, if available.
3005 Like ``readline``, but read from the stderr pipe, if available.
3003
3006
3004 read <X>
3007 read <X>
3005 --------
3008 --------
3006
3009
3007 ``read()`` N bytes from the server's main output pipe.
3010 ``read()`` N bytes from the server's main output pipe.
3008
3011
3009 eread <X>
3012 eread <X>
3010 ---------
3013 ---------
3011
3014
3012 ``read()`` N bytes from the server's stderr pipe, if available.
3015 ``read()`` N bytes from the server's stderr pipe, if available.
3013
3016
3014 Specifying Unified Frame-Based Protocol Frames
3017 Specifying Unified Frame-Based Protocol Frames
3015 ----------------------------------------------
3018 ----------------------------------------------
3016
3019
3017 It is possible to emit a *Unified Frame-Based Protocol* by using special
3020 It is possible to emit a *Unified Frame-Based Protocol* by using special
3018 syntax.
3021 syntax.
3019
3022
3020 A frame is composed as a type, flags, and payload. These can be parsed
3023 A frame is composed as a type, flags, and payload. These can be parsed
3021 from a string of the form:
3024 from a string of the form:
3022
3025
3023 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3026 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3024
3027
3025 ``request-id`` and ``stream-id`` are integers defining the request and
3028 ``request-id`` and ``stream-id`` are integers defining the request and
3026 stream identifiers.
3029 stream identifiers.
3027
3030
3028 ``type`` can be an integer value for the frame type or the string name
3031 ``type`` can be an integer value for the frame type or the string name
3029 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3032 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3030 ``command-name``.
3033 ``command-name``.
3031
3034
3032 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3035 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3033 components. Each component (and there can be just one) can be an integer
3036 components. Each component (and there can be just one) can be an integer
3034 or a flag name for stream flags or frame flags, respectively. Values are
3037 or a flag name for stream flags or frame flags, respectively. Values are
3035 resolved to integers and then bitwise OR'd together.
3038 resolved to integers and then bitwise OR'd together.
3036
3039
3037 ``payload`` represents the raw frame payload. If it begins with
3040 ``payload`` represents the raw frame payload. If it begins with
3038 ``cbor:``, the following string is evaluated as Python code and the
3041 ``cbor:``, the following string is evaluated as Python code and the
3039 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3042 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3040 as a Python byte string literal.
3043 as a Python byte string literal.
3041 """
3044 """
3042 opts = pycompat.byteskwargs(opts)
3045 opts = pycompat.byteskwargs(opts)
3043
3046
3044 if opts['localssh'] and not repo:
3047 if opts['localssh'] and not repo:
3045 raise error.Abort(_('--localssh requires a repository'))
3048 raise error.Abort(_('--localssh requires a repository'))
3046
3049
3047 if opts['peer'] and opts['peer'] not in ('raw', 'http2', 'ssh1', 'ssh2'):
3050 if opts['peer'] and opts['peer'] not in ('raw', 'http2', 'ssh1', 'ssh2'):
3048 raise error.Abort(_('invalid value for --peer'),
3051 raise error.Abort(_('invalid value for --peer'),
3049 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
3052 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
3050
3053
3051 if path and opts['localssh']:
3054 if path and opts['localssh']:
3052 raise error.Abort(_('cannot specify --localssh with an explicit '
3055 raise error.Abort(_('cannot specify --localssh with an explicit '
3053 'path'))
3056 'path'))
3054
3057
3055 if ui.interactive():
3058 if ui.interactive():
3056 ui.write(_('(waiting for commands on stdin)\n'))
3059 ui.write(_('(waiting for commands on stdin)\n'))
3057
3060
3058 blocks = list(_parsewirelangblocks(ui.fin))
3061 blocks = list(_parsewirelangblocks(ui.fin))
3059
3062
3060 proc = None
3063 proc = None
3061 stdin = None
3064 stdin = None
3062 stdout = None
3065 stdout = None
3063 stderr = None
3066 stderr = None
3064 opener = None
3067 opener = None
3065
3068
3066 if opts['localssh']:
3069 if opts['localssh']:
3067 # We start the SSH server in its own process so there is process
3070 # We start the SSH server in its own process so there is process
3068 # separation. This prevents a whole class of potential bugs around
3071 # separation. This prevents a whole class of potential bugs around
3069 # shared state from interfering with server operation.
3072 # shared state from interfering with server operation.
3070 args = procutil.hgcmd() + [
3073 args = procutil.hgcmd() + [
3071 '-R', repo.root,
3074 '-R', repo.root,
3072 'debugserve', '--sshstdio',
3075 'debugserve', '--sshstdio',
3073 ]
3076 ]
3074 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
3077 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
3075 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
3078 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
3076 bufsize=0)
3079 bufsize=0)
3077
3080
3078 stdin = proc.stdin
3081 stdin = proc.stdin
3079 stdout = proc.stdout
3082 stdout = proc.stdout
3080 stderr = proc.stderr
3083 stderr = proc.stderr
3081
3084
3082 # We turn the pipes into observers so we can log I/O.
3085 # We turn the pipes into observers so we can log I/O.
3083 if ui.verbose or opts['peer'] == 'raw':
3086 if ui.verbose or opts['peer'] == 'raw':
3084 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
3087 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
3085 logdata=True)
3088 logdata=True)
3086 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
3089 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
3087 logdata=True)
3090 logdata=True)
3088 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
3091 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
3089 logdata=True)
3092 logdata=True)
3090
3093
3091 # --localssh also implies the peer connection settings.
3094 # --localssh also implies the peer connection settings.
3092
3095
3093 url = 'ssh://localserver'
3096 url = 'ssh://localserver'
3094 autoreadstderr = not opts['noreadstderr']
3097 autoreadstderr = not opts['noreadstderr']
3095
3098
3096 if opts['peer'] == 'ssh1':
3099 if opts['peer'] == 'ssh1':
3097 ui.write(_('creating ssh peer for wire protocol version 1\n'))
3100 ui.write(_('creating ssh peer for wire protocol version 1\n'))
3098 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
3101 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
3099 None, autoreadstderr=autoreadstderr)
3102 None, autoreadstderr=autoreadstderr)
3100 elif opts['peer'] == 'ssh2':
3103 elif opts['peer'] == 'ssh2':
3101 ui.write(_('creating ssh peer for wire protocol version 2\n'))
3104 ui.write(_('creating ssh peer for wire protocol version 2\n'))
3102 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
3105 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
3103 None, autoreadstderr=autoreadstderr)
3106 None, autoreadstderr=autoreadstderr)
3104 elif opts['peer'] == 'raw':
3107 elif opts['peer'] == 'raw':
3105 ui.write(_('using raw connection to peer\n'))
3108 ui.write(_('using raw connection to peer\n'))
3106 peer = None
3109 peer = None
3107 else:
3110 else:
3108 ui.write(_('creating ssh peer from handshake results\n'))
3111 ui.write(_('creating ssh peer from handshake results\n'))
3109 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
3112 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
3110 autoreadstderr=autoreadstderr)
3113 autoreadstderr=autoreadstderr)
3111
3114
3112 elif path:
3115 elif path:
3113 # We bypass hg.peer() so we can proxy the sockets.
3116 # We bypass hg.peer() so we can proxy the sockets.
3114 # TODO consider not doing this because we skip
3117 # TODO consider not doing this because we skip
3115 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
3118 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
3116 u = util.url(path)
3119 u = util.url(path)
3117 if u.scheme != 'http':
3120 if u.scheme != 'http':
3118 raise error.Abort(_('only http:// paths are currently supported'))
3121 raise error.Abort(_('only http:// paths are currently supported'))
3119
3122
3120 url, authinfo = u.authinfo()
3123 url, authinfo = u.authinfo()
3121 openerargs = {
3124 openerargs = {
3122 r'useragent': b'Mercurial debugwireproto',
3125 r'useragent': b'Mercurial debugwireproto',
3123 }
3126 }
3124
3127
3125 # Turn pipes/sockets into observers so we can log I/O.
3128 # Turn pipes/sockets into observers so we can log I/O.
3126 if ui.verbose:
3129 if ui.verbose:
3127 openerargs.update({
3130 openerargs.update({
3128 r'loggingfh': ui,
3131 r'loggingfh': ui,
3129 r'loggingname': b's',
3132 r'loggingname': b's',
3130 r'loggingopts': {
3133 r'loggingopts': {
3131 r'logdata': True,
3134 r'logdata': True,
3132 r'logdataapis': False,
3135 r'logdataapis': False,
3133 },
3136 },
3134 })
3137 })
3135
3138
3136 if ui.debugflag:
3139 if ui.debugflag:
3137 openerargs[r'loggingopts'][r'logdataapis'] = True
3140 openerargs[r'loggingopts'][r'logdataapis'] = True
3138
3141
3139 # Don't send default headers when in raw mode. This allows us to
3142 # Don't send default headers when in raw mode. This allows us to
3140 # bypass most of the behavior of our URL handling code so we can
3143 # bypass most of the behavior of our URL handling code so we can
3141 # have near complete control over what's sent on the wire.
3144 # have near complete control over what's sent on the wire.
3142 if opts['peer'] == 'raw':
3145 if opts['peer'] == 'raw':
3143 openerargs[r'sendaccept'] = False
3146 openerargs[r'sendaccept'] = False
3144
3147
3145 opener = urlmod.opener(ui, authinfo, **openerargs)
3148 opener = urlmod.opener(ui, authinfo, **openerargs)
3146
3149
3147 if opts['peer'] == 'http2':
3150 if opts['peer'] == 'http2':
3148 ui.write(_('creating http peer for wire protocol version 2\n'))
3151 ui.write(_('creating http peer for wire protocol version 2\n'))
3149 # We go through makepeer() because we need an API descriptor for
3152 # We go through makepeer() because we need an API descriptor for
3150 # the peer instance to be useful.
3153 # the peer instance to be useful.
3151 with ui.configoverride({
3154 with ui.configoverride({
3152 ('experimental', 'httppeer.advertise-v2'): True}):
3155 ('experimental', 'httppeer.advertise-v2'): True}):
3153 if opts['nologhandshake']:
3156 if opts['nologhandshake']:
3154 ui.pushbuffer()
3157 ui.pushbuffer()
3155
3158
3156 peer = httppeer.makepeer(ui, path, opener=opener)
3159 peer = httppeer.makepeer(ui, path, opener=opener)
3157
3160
3158 if opts['nologhandshake']:
3161 if opts['nologhandshake']:
3159 ui.popbuffer()
3162 ui.popbuffer()
3160
3163
3161 if not isinstance(peer, httppeer.httpv2peer):
3164 if not isinstance(peer, httppeer.httpv2peer):
3162 raise error.Abort(_('could not instantiate HTTP peer for '
3165 raise error.Abort(_('could not instantiate HTTP peer for '
3163 'wire protocol version 2'),
3166 'wire protocol version 2'),
3164 hint=_('the server may not have the feature '
3167 hint=_('the server may not have the feature '
3165 'enabled or is not allowing this '
3168 'enabled or is not allowing this '
3166 'client version'))
3169 'client version'))
3167
3170
3168 elif opts['peer'] == 'raw':
3171 elif opts['peer'] == 'raw':
3169 ui.write(_('using raw connection to peer\n'))
3172 ui.write(_('using raw connection to peer\n'))
3170 peer = None
3173 peer = None
3171 elif opts['peer']:
3174 elif opts['peer']:
3172 raise error.Abort(_('--peer %s not supported with HTTP peers') %
3175 raise error.Abort(_('--peer %s not supported with HTTP peers') %
3173 opts['peer'])
3176 opts['peer'])
3174 else:
3177 else:
3175 peer = httppeer.makepeer(ui, path, opener=opener)
3178 peer = httppeer.makepeer(ui, path, opener=opener)
3176
3179
3177 # We /could/ populate stdin/stdout with sock.makefile()...
3180 # We /could/ populate stdin/stdout with sock.makefile()...
3178 else:
3181 else:
3179 raise error.Abort(_('unsupported connection configuration'))
3182 raise error.Abort(_('unsupported connection configuration'))
3180
3183
3181 batchedcommands = None
3184 batchedcommands = None
3182
3185
3183 # Now perform actions based on the parsed wire language instructions.
3186 # Now perform actions based on the parsed wire language instructions.
3184 for action, lines in blocks:
3187 for action, lines in blocks:
3185 if action in ('raw', 'raw+'):
3188 if action in ('raw', 'raw+'):
3186 if not stdin:
3189 if not stdin:
3187 raise error.Abort(_('cannot call raw/raw+ on this peer'))
3190 raise error.Abort(_('cannot call raw/raw+ on this peer'))
3188
3191
3189 # Concatenate the data together.
3192 # Concatenate the data together.
3190 data = ''.join(l.lstrip() for l in lines)
3193 data = ''.join(l.lstrip() for l in lines)
3191 data = stringutil.unescapestr(data)
3194 data = stringutil.unescapestr(data)
3192 stdin.write(data)
3195 stdin.write(data)
3193
3196
3194 if action == 'raw+':
3197 if action == 'raw+':
3195 stdin.flush()
3198 stdin.flush()
3196 elif action == 'flush':
3199 elif action == 'flush':
3197 if not stdin:
3200 if not stdin:
3198 raise error.Abort(_('cannot call flush on this peer'))
3201 raise error.Abort(_('cannot call flush on this peer'))
3199 stdin.flush()
3202 stdin.flush()
3200 elif action.startswith('command'):
3203 elif action.startswith('command'):
3201 if not peer:
3204 if not peer:
3202 raise error.Abort(_('cannot send commands unless peer instance '
3205 raise error.Abort(_('cannot send commands unless peer instance '
3203 'is available'))
3206 'is available'))
3204
3207
3205 command = action.split(' ', 1)[1]
3208 command = action.split(' ', 1)[1]
3206
3209
3207 args = {}
3210 args = {}
3208 for line in lines:
3211 for line in lines:
3209 # We need to allow empty values.
3212 # We need to allow empty values.
3210 fields = line.lstrip().split(' ', 1)
3213 fields = line.lstrip().split(' ', 1)
3211 if len(fields) == 1:
3214 if len(fields) == 1:
3212 key = fields[0]
3215 key = fields[0]
3213 value = ''
3216 value = ''
3214 else:
3217 else:
3215 key, value = fields
3218 key, value = fields
3216
3219
3217 if value.startswith('eval:'):
3220 if value.startswith('eval:'):
3218 value = stringutil.evalpythonliteral(value[5:])
3221 value = stringutil.evalpythonliteral(value[5:])
3219 else:
3222 else:
3220 value = stringutil.unescapestr(value)
3223 value = stringutil.unescapestr(value)
3221
3224
3222 args[key] = value
3225 args[key] = value
3223
3226
3224 if batchedcommands is not None:
3227 if batchedcommands is not None:
3225 batchedcommands.append((command, args))
3228 batchedcommands.append((command, args))
3226 continue
3229 continue
3227
3230
3228 ui.status(_('sending %s command\n') % command)
3231 ui.status(_('sending %s command\n') % command)
3229
3232
3230 if 'PUSHFILE' in args:
3233 if 'PUSHFILE' in args:
3231 with open(args['PUSHFILE'], r'rb') as fh:
3234 with open(args['PUSHFILE'], r'rb') as fh:
3232 del args['PUSHFILE']
3235 del args['PUSHFILE']
3233 res, output = peer._callpush(command, fh,
3236 res, output = peer._callpush(command, fh,
3234 **pycompat.strkwargs(args))
3237 **pycompat.strkwargs(args))
3235 ui.status(_('result: %s\n') % stringutil.escapestr(res))
3238 ui.status(_('result: %s\n') % stringutil.escapestr(res))
3236 ui.status(_('remote output: %s\n') %
3239 ui.status(_('remote output: %s\n') %
3237 stringutil.escapestr(output))
3240 stringutil.escapestr(output))
3238 else:
3241 else:
3239 with peer.commandexecutor() as e:
3242 with peer.commandexecutor() as e:
3240 res = e.callcommand(command, args).result()
3243 res = e.callcommand(command, args).result()
3241
3244
3242 if isinstance(res, wireprotov2peer.commandresponse):
3245 if isinstance(res, wireprotov2peer.commandresponse):
3243 val = res.objects()
3246 val = res.objects()
3244 ui.status(_('response: %s\n') %
3247 ui.status(_('response: %s\n') %
3245 stringutil.pprint(val, bprefix=True, indent=2))
3248 stringutil.pprint(val, bprefix=True, indent=2))
3246 else:
3249 else:
3247 ui.status(_('response: %s\n') %
3250 ui.status(_('response: %s\n') %
3248 stringutil.pprint(res, bprefix=True, indent=2))
3251 stringutil.pprint(res, bprefix=True, indent=2))
3249
3252
3250 elif action == 'batchbegin':
3253 elif action == 'batchbegin':
3251 if batchedcommands is not None:
3254 if batchedcommands is not None:
3252 raise error.Abort(_('nested batchbegin not allowed'))
3255 raise error.Abort(_('nested batchbegin not allowed'))
3253
3256
3254 batchedcommands = []
3257 batchedcommands = []
3255 elif action == 'batchsubmit':
3258 elif action == 'batchsubmit':
3256 # There is a batching API we could go through. But it would be
3259 # There is a batching API we could go through. But it would be
3257 # difficult to normalize requests into function calls. It is easier
3260 # difficult to normalize requests into function calls. It is easier
3258 # to bypass this layer and normalize to commands + args.
3261 # to bypass this layer and normalize to commands + args.
3259 ui.status(_('sending batch with %d sub-commands\n') %
3262 ui.status(_('sending batch with %d sub-commands\n') %
3260 len(batchedcommands))
3263 len(batchedcommands))
3261 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
3264 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
3262 ui.status(_('response #%d: %s\n') %
3265 ui.status(_('response #%d: %s\n') %
3263 (i, stringutil.escapestr(chunk)))
3266 (i, stringutil.escapestr(chunk)))
3264
3267
3265 batchedcommands = None
3268 batchedcommands = None
3266
3269
3267 elif action.startswith('httprequest '):
3270 elif action.startswith('httprequest '):
3268 if not opener:
3271 if not opener:
3269 raise error.Abort(_('cannot use httprequest without an HTTP '
3272 raise error.Abort(_('cannot use httprequest without an HTTP '
3270 'peer'))
3273 'peer'))
3271
3274
3272 request = action.split(' ', 2)
3275 request = action.split(' ', 2)
3273 if len(request) != 3:
3276 if len(request) != 3:
3274 raise error.Abort(_('invalid httprequest: expected format is '
3277 raise error.Abort(_('invalid httprequest: expected format is '
3275 '"httprequest <method> <path>'))
3278 '"httprequest <method> <path>'))
3276
3279
3277 method, httppath = request[1:]
3280 method, httppath = request[1:]
3278 headers = {}
3281 headers = {}
3279 body = None
3282 body = None
3280 frames = []
3283 frames = []
3281 for line in lines:
3284 for line in lines:
3282 line = line.lstrip()
3285 line = line.lstrip()
3283 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
3286 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
3284 if m:
3287 if m:
3285 headers[m.group(1)] = m.group(2)
3288 headers[m.group(1)] = m.group(2)
3286 continue
3289 continue
3287
3290
3288 if line.startswith(b'BODYFILE '):
3291 if line.startswith(b'BODYFILE '):
3289 with open(line.split(b' ', 1), 'rb') as fh:
3292 with open(line.split(b' ', 1), 'rb') as fh:
3290 body = fh.read()
3293 body = fh.read()
3291 elif line.startswith(b'frame '):
3294 elif line.startswith(b'frame '):
3292 frame = wireprotoframing.makeframefromhumanstring(
3295 frame = wireprotoframing.makeframefromhumanstring(
3293 line[len(b'frame '):])
3296 line[len(b'frame '):])
3294
3297
3295 frames.append(frame)
3298 frames.append(frame)
3296 else:
3299 else:
3297 raise error.Abort(_('unknown argument to httprequest: %s') %
3300 raise error.Abort(_('unknown argument to httprequest: %s') %
3298 line)
3301 line)
3299
3302
3300 url = path + httppath
3303 url = path + httppath
3301
3304
3302 if frames:
3305 if frames:
3303 body = b''.join(bytes(f) for f in frames)
3306 body = b''.join(bytes(f) for f in frames)
3304
3307
3305 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3308 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3306
3309
3307 # urllib.Request insists on using has_data() as a proxy for
3310 # urllib.Request insists on using has_data() as a proxy for
3308 # determining the request method. Override that to use our
3311 # determining the request method. Override that to use our
3309 # explicitly requested method.
3312 # explicitly requested method.
3310 req.get_method = lambda: pycompat.sysstr(method)
3313 req.get_method = lambda: pycompat.sysstr(method)
3311
3314
3312 try:
3315 try:
3313 res = opener.open(req)
3316 res = opener.open(req)
3314 body = res.read()
3317 body = res.read()
3315 except util.urlerr.urlerror as e:
3318 except util.urlerr.urlerror as e:
3316 # read() method must be called, but only exists in Python 2
3319 # read() method must be called, but only exists in Python 2
3317 getattr(e, 'read', lambda: None)()
3320 getattr(e, 'read', lambda: None)()
3318 continue
3321 continue
3319
3322
3320 if res.headers.get('Content-Type') == 'application/mercurial-cbor':
3323 if res.headers.get('Content-Type') == 'application/mercurial-cbor':
3321 ui.write(_('cbor> %s\n') %
3324 ui.write(_('cbor> %s\n') %
3322 stringutil.pprint(cborutil.decodeall(body)[0],
3325 stringutil.pprint(cborutil.decodeall(body)[0],
3323 bprefix=True,
3326 bprefix=True,
3324 indent=2))
3327 indent=2))
3325
3328
3326 elif action == 'close':
3329 elif action == 'close':
3327 peer.close()
3330 peer.close()
3328 elif action == 'readavailable':
3331 elif action == 'readavailable':
3329 if not stdout or not stderr:
3332 if not stdout or not stderr:
3330 raise error.Abort(_('readavailable not available on this peer'))
3333 raise error.Abort(_('readavailable not available on this peer'))
3331
3334
3332 stdin.close()
3335 stdin.close()
3333 stdout.read()
3336 stdout.read()
3334 stderr.read()
3337 stderr.read()
3335
3338
3336 elif action == 'readline':
3339 elif action == 'readline':
3337 if not stdout:
3340 if not stdout:
3338 raise error.Abort(_('readline not available on this peer'))
3341 raise error.Abort(_('readline not available on this peer'))
3339 stdout.readline()
3342 stdout.readline()
3340 elif action == 'ereadline':
3343 elif action == 'ereadline':
3341 if not stderr:
3344 if not stderr:
3342 raise error.Abort(_('ereadline not available on this peer'))
3345 raise error.Abort(_('ereadline not available on this peer'))
3343 stderr.readline()
3346 stderr.readline()
3344 elif action.startswith('read '):
3347 elif action.startswith('read '):
3345 count = int(action.split(' ', 1)[1])
3348 count = int(action.split(' ', 1)[1])
3346 if not stdout:
3349 if not stdout:
3347 raise error.Abort(_('read not available on this peer'))
3350 raise error.Abort(_('read not available on this peer'))
3348 stdout.read(count)
3351 stdout.read(count)
3349 elif action.startswith('eread '):
3352 elif action.startswith('eread '):
3350 count = int(action.split(' ', 1)[1])
3353 count = int(action.split(' ', 1)[1])
3351 if not stderr:
3354 if not stderr:
3352 raise error.Abort(_('eread not available on this peer'))
3355 raise error.Abort(_('eread not available on this peer'))
3353 stderr.read(count)
3356 stderr.read(count)
3354 else:
3357 else:
3355 raise error.Abort(_('unknown action: %s') % action)
3358 raise error.Abort(_('unknown action: %s') % action)
3356
3359
3357 if batchedcommands is not None:
3360 if batchedcommands is not None:
3358 raise error.Abort(_('unclosed "batchbegin" request'))
3361 raise error.Abort(_('unclosed "batchbegin" request'))
3359
3362
3360 if peer:
3363 if peer:
3361 peer.close()
3364 peer.close()
3362
3365
3363 if proc:
3366 if proc:
3364 proc.kill()
3367 proc.kill()
@@ -1,763 +1,763 b''
1 $ hg init basic
1 $ hg init basic
2 $ cd basic
2 $ cd basic
3
3
4 should complain
4 should complain
5
5
6 $ hg backout
6 $ hg backout
7 abort: please specify a revision to backout
7 abort: please specify a revision to backout
8 [255]
8 [255]
9 $ hg backout -r 0 0
9 $ hg backout -r 0 0
10 abort: please specify just one revision
10 abort: please specify just one revision
11 [255]
11 [255]
12
12
13 basic operation
13 basic operation
14 (this also tests that editor is invoked if the commit message is not
14 (this also tests that editor is invoked if the commit message is not
15 specified explicitly)
15 specified explicitly)
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg commit -d '0 0' -A -m a
18 $ hg commit -d '0 0' -A -m a
19 adding a
19 adding a
20 $ echo b >> a
20 $ echo b >> a
21 $ hg commit -d '1 0' -m b
21 $ hg commit -d '1 0' -m b
22
22
23 $ hg status --rev tip --rev "tip^1"
23 $ hg status --rev tip --rev "tip^1"
24 M a
24 M a
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
26 reverting a
26 reverting a
27 Backed out changeset a820f4f40a57
27 Backed out changeset a820f4f40a57
28
28
29
29
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
31 HG: Leave message empty to abort commit.
31 HG: Leave message empty to abort commit.
32 HG: --
32 HG: --
33 HG: user: test
33 HG: user: test
34 HG: branch 'default'
34 HG: branch 'default'
35 HG: changed a
35 HG: changed a
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
37 $ cat a
37 $ cat a
38 a
38 a
39 $ hg summary
39 $ hg summary
40 parent: 2:2929462c3dff tip
40 parent: 2:2929462c3dff tip
41 Backed out changeset a820f4f40a57
41 Backed out changeset a820f4f40a57
42 branch: default
42 branch: default
43 commit: (clean)
43 commit: (clean)
44 update: (current)
44 update: (current)
45 phases: 3 draft
45 phases: 3 draft
46
46
47 commit option
47 commit option
48
48
49 $ cd ..
49 $ cd ..
50 $ hg init commit
50 $ hg init commit
51 $ cd commit
51 $ cd commit
52
52
53 $ echo tomatoes > a
53 $ echo tomatoes > a
54 $ hg add a
54 $ hg add a
55 $ hg commit -d '0 0' -m tomatoes
55 $ hg commit -d '0 0' -m tomatoes
56
56
57 $ echo chair > b
57 $ echo chair > b
58 $ hg add b
58 $ hg add b
59 $ hg commit -d '1 0' -m chair
59 $ hg commit -d '1 0' -m chair
60
60
61 $ echo grapes >> a
61 $ echo grapes >> a
62 $ hg commit -d '2 0' -m grapes
62 $ hg commit -d '2 0' -m grapes
63
63
64 $ hg backout -d '4 0' 1 --tool=:fail
64 $ hg backout -d '4 0' 1 --tool=:fail
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
67 $ hg summary
67 $ hg summary
68 parent: 3:1c2161e97c0a tip
68 parent: 3:1c2161e97c0a tip
69 Backed out changeset 22cb4f70d813
69 Backed out changeset 22cb4f70d813
70 branch: default
70 branch: default
71 commit: (clean)
71 commit: (clean)
72 update: (current)
72 update: (current)
73 phases: 4 draft
73 phases: 4 draft
74
74
75 $ echo ypples > a
75 $ echo ypples > a
76 $ hg commit -d '5 0' -m ypples
76 $ hg commit -d '5 0' -m ypples
77
77
78 $ hg backout -d '6 0' 2 --tool=:fail
78 $ hg backout -d '6 0' 2 --tool=:fail
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
80 use 'hg resolve' to retry unresolved file merges
80 use 'hg resolve' to retry unresolved file merges
81 [1]
81 [1]
82 $ hg summary
82 $ hg summary
83 parent: 4:ed99997b793d tip
83 parent: 4:ed99997b793d tip
84 ypples
84 ypples
85 branch: default
85 branch: default
86 commit: 1 unresolved (clean)
86 commit: 1 unresolved (clean)
87 update: (current)
87 update: (current)
88 phases: 5 draft
88 phases: 5 draft
89
89
90 file that was removed is recreated
90 file that was removed is recreated
91 (this also tests that editor is not invoked if the commit message is
91 (this also tests that editor is not invoked if the commit message is
92 specified explicitly)
92 specified explicitly)
93
93
94 $ cd ..
94 $ cd ..
95 $ hg init remove
95 $ hg init remove
96 $ cd remove
96 $ cd remove
97
97
98 $ echo content > a
98 $ echo content > a
99 $ hg commit -d '0 0' -A -m a
99 $ hg commit -d '0 0' -A -m a
100 adding a
100 adding a
101
101
102 $ hg rm a
102 $ hg rm a
103 $ hg commit -d '1 0' -m b
103 $ hg commit -d '1 0' -m b
104
104
105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
106 adding a
106 adding a
107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
108 $ cat a
108 $ cat a
109 content
109 content
110 $ hg summary
110 $ hg summary
111 parent: 2:de31bdc76c0d tip
111 parent: 2:de31bdc76c0d tip
112 Backed out changeset 76862dcce372
112 Backed out changeset 76862dcce372
113 branch: default
113 branch: default
114 commit: (clean)
114 commit: (clean)
115 update: (current)
115 update: (current)
116 phases: 3 draft
116 phases: 3 draft
117
117
118 backout of backout is as if nothing happened
118 backout of backout is as if nothing happened
119
119
120 $ hg backout -d '3 0' --merge tip --tool=true
120 $ hg backout -d '3 0' --merge tip --tool=true
121 removing a
121 removing a
122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
123 $ test -f a
123 $ test -f a
124 [1]
124 [1]
125 $ hg summary
125 $ hg summary
126 parent: 3:7f6d0f120113 tip
126 parent: 3:7f6d0f120113 tip
127 Backed out changeset de31bdc76c0d
127 Backed out changeset de31bdc76c0d
128 branch: default
128 branch: default
129 commit: (clean)
129 commit: (clean)
130 update: (current)
130 update: (current)
131 phases: 4 draft
131 phases: 4 draft
132
132
133 Test that 'hg rollback' restores dirstate just before opening
133 Test that 'hg rollback' restores dirstate just before opening
134 transaction: in-memory dirstate changes should be written into
134 transaction: in-memory dirstate changes should be written into
135 '.hg/journal.dirstate' as expected.
135 '.hg/journal.dirstate' as expected.
136
136
137 $ echo 'removed soon' > b
137 $ echo 'removed soon' > b
138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
139 adding b
139 adding b
140 $ echo 'newly added' > c
140 $ echo 'newly added' > c
141 $ hg add c
141 $ hg add c
142 $ hg remove b
142 $ hg remove b
143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
144 $ touch -t 200001010000 c
144 $ touch -t 200001010000 c
145 $ hg status -A
145 $ hg status -A
146 C c
146 C c
147 $ hg debugstate --nodates
147 $ hg debugstate --no-dates
148 n 644 12 set c
148 n 644 12 set c
149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
150 removing c
150 removing c
151 adding b
151 adding b
152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
153 $ hg rollback -q
153 $ hg rollback -q
154 $ hg status -A
154 $ hg status -A
155 A b
155 A b
156 R c
156 R c
157 $ hg debugstate --nodates
157 $ hg debugstate --no-dates
158 a 0 -1 unset b
158 a 0 -1 unset b
159 r 0 0 set c
159 r 0 0 set c
160
160
161 across branch
161 across branch
162
162
163 $ cd ..
163 $ cd ..
164 $ hg init branch
164 $ hg init branch
165 $ cd branch
165 $ cd branch
166 $ echo a > a
166 $ echo a > a
167 $ hg ci -Am0
167 $ hg ci -Am0
168 adding a
168 adding a
169 $ echo b > b
169 $ echo b > b
170 $ hg ci -Am1
170 $ hg ci -Am1
171 adding b
171 adding b
172 $ hg co -C 0
172 $ hg co -C 0
173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
174 $ hg summary
174 $ hg summary
175 parent: 0:f7b1eb17ad24
175 parent: 0:f7b1eb17ad24
176 0
176 0
177 branch: default
177 branch: default
178 commit: (clean)
178 commit: (clean)
179 update: 1 new changesets (update)
179 update: 1 new changesets (update)
180 phases: 2 draft
180 phases: 2 draft
181
181
182 should fail
182 should fail
183
183
184 $ hg backout 1
184 $ hg backout 1
185 abort: cannot backout change that is not an ancestor
185 abort: cannot backout change that is not an ancestor
186 [255]
186 [255]
187 $ echo c > c
187 $ echo c > c
188 $ hg ci -Am2
188 $ hg ci -Am2
189 adding c
189 adding c
190 created new head
190 created new head
191 $ hg summary
191 $ hg summary
192 parent: 2:db815d6d32e6 tip
192 parent: 2:db815d6d32e6 tip
193 2
193 2
194 branch: default
194 branch: default
195 commit: (clean)
195 commit: (clean)
196 update: 1 new changesets, 2 branch heads (merge)
196 update: 1 new changesets, 2 branch heads (merge)
197 phases: 3 draft
197 phases: 3 draft
198
198
199 should fail
199 should fail
200
200
201 $ hg backout 1
201 $ hg backout 1
202 abort: cannot backout change that is not an ancestor
202 abort: cannot backout change that is not an ancestor
203 [255]
203 [255]
204 $ hg summary
204 $ hg summary
205 parent: 2:db815d6d32e6 tip
205 parent: 2:db815d6d32e6 tip
206 2
206 2
207 branch: default
207 branch: default
208 commit: (clean)
208 commit: (clean)
209 update: 1 new changesets, 2 branch heads (merge)
209 update: 1 new changesets, 2 branch heads (merge)
210 phases: 3 draft
210 phases: 3 draft
211
211
212 backout with merge
212 backout with merge
213
213
214 $ cd ..
214 $ cd ..
215 $ hg init merge
215 $ hg init merge
216 $ cd merge
216 $ cd merge
217
217
218 $ echo line 1 > a
218 $ echo line 1 > a
219 $ echo line 2 >> a
219 $ echo line 2 >> a
220 $ hg commit -d '0 0' -A -m a
220 $ hg commit -d '0 0' -A -m a
221 adding a
221 adding a
222 $ hg summary
222 $ hg summary
223 parent: 0:59395513a13a tip
223 parent: 0:59395513a13a tip
224 a
224 a
225 branch: default
225 branch: default
226 commit: (clean)
226 commit: (clean)
227 update: (current)
227 update: (current)
228 phases: 1 draft
228 phases: 1 draft
229
229
230 remove line 1
230 remove line 1
231
231
232 $ echo line 2 > a
232 $ echo line 2 > a
233 $ hg commit -d '1 0' -m b
233 $ hg commit -d '1 0' -m b
234
234
235 $ echo line 3 >> a
235 $ echo line 3 >> a
236 $ hg commit -d '2 0' -m c
236 $ hg commit -d '2 0' -m c
237
237
238 $ hg backout --merge -d '3 0' 1 --tool=true
238 $ hg backout --merge -d '3 0' 1 --tool=true
239 reverting a
239 reverting a
240 created new head
240 created new head
241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
242 merging with changeset 3:26b8ccb9ad91
242 merging with changeset 3:26b8ccb9ad91
243 merging a
243 merging a
244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
245 (branch merge, don't forget to commit)
245 (branch merge, don't forget to commit)
246 $ hg commit -d '4 0' -m d
246 $ hg commit -d '4 0' -m d
247 $ hg summary
247 $ hg summary
248 parent: 4:c7df5e0b9c09 tip
248 parent: 4:c7df5e0b9c09 tip
249 d
249 d
250 branch: default
250 branch: default
251 commit: (clean)
251 commit: (clean)
252 update: (current)
252 update: (current)
253 phases: 5 draft
253 phases: 5 draft
254
254
255 check line 1 is back
255 check line 1 is back
256
256
257 $ cat a
257 $ cat a
258 line 1
258 line 1
259 line 2
259 line 2
260 line 3
260 line 3
261
261
262 Test visibility of in-memory dirstate changes outside transaction to
262 Test visibility of in-memory dirstate changes outside transaction to
263 external hook process
263 external hook process
264
264
265 $ cat > $TESTTMP/checkvisibility.sh <<EOF
265 $ cat > $TESTTMP/checkvisibility.sh <<EOF
266 > echo "==== \$1:"
266 > echo "==== \$1:"
267 > hg parents --template "{rev}:{node|short}\n"
267 > hg parents --template "{rev}:{node|short}\n"
268 > echo "===="
268 > echo "===="
269 > EOF
269 > EOF
270
270
271 "hg backout --merge REV1" at REV2 below implies steps below:
271 "hg backout --merge REV1" at REV2 below implies steps below:
272
272
273 (1) update to REV1 (REV2 => REV1)
273 (1) update to REV1 (REV2 => REV1)
274 (2) revert by REV1^1
274 (2) revert by REV1^1
275 (3) commit backing out revision (REV3)
275 (3) commit backing out revision (REV3)
276 (4) update to REV2 (REV3 => REV2)
276 (4) update to REV2 (REV3 => REV2)
277 (5) merge with REV3 (REV2 => REV2, REV3)
277 (5) merge with REV3 (REV2 => REV2, REV3)
278
278
279 == test visibility to external preupdate hook
279 == test visibility to external preupdate hook
280
280
281 $ hg update -q -C 2
281 $ hg update -q -C 2
282 $ hg --config extensions.strip= strip 3
282 $ hg --config extensions.strip= strip 3
283 saved backup bundle to * (glob)
283 saved backup bundle to * (glob)
284
284
285 $ cat >> .hg/hgrc <<EOF
285 $ cat >> .hg/hgrc <<EOF
286 > [hooks]
286 > [hooks]
287 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
287 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
288 > EOF
288 > EOF
289
289
290 ("-m" is needed to avoid writing dirstate changes out at other than
290 ("-m" is needed to avoid writing dirstate changes out at other than
291 invocation of the hook to be examined)
291 invocation of the hook to be examined)
292
292
293 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
293 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
294 ==== preupdate:
294 ==== preupdate:
295 2:6ea3f2a197a2
295 2:6ea3f2a197a2
296 ====
296 ====
297 reverting a
297 reverting a
298 created new head
298 created new head
299 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
299 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
300 ==== preupdate:
300 ==== preupdate:
301 3:d92a3f57f067
301 3:d92a3f57f067
302 ====
302 ====
303 merging with changeset 3:d92a3f57f067
303 merging with changeset 3:d92a3f57f067
304 ==== preupdate:
304 ==== preupdate:
305 2:6ea3f2a197a2
305 2:6ea3f2a197a2
306 ====
306 ====
307 merging a
307 merging a
308 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
308 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
309 (branch merge, don't forget to commit)
309 (branch merge, don't forget to commit)
310
310
311 $ cat >> .hg/hgrc <<EOF
311 $ cat >> .hg/hgrc <<EOF
312 > [hooks]
312 > [hooks]
313 > preupdate.visibility =
313 > preupdate.visibility =
314 > EOF
314 > EOF
315
315
316 == test visibility to external update hook
316 == test visibility to external update hook
317
317
318 $ hg update -q -C 2
318 $ hg update -q -C 2
319 $ hg --config extensions.strip= strip 3
319 $ hg --config extensions.strip= strip 3
320 saved backup bundle to * (glob)
320 saved backup bundle to * (glob)
321
321
322 $ cat >> .hg/hgrc <<EOF
322 $ cat >> .hg/hgrc <<EOF
323 > [hooks]
323 > [hooks]
324 > update.visibility = sh $TESTTMP/checkvisibility.sh update
324 > update.visibility = sh $TESTTMP/checkvisibility.sh update
325 > EOF
325 > EOF
326
326
327 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
327 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
328 ==== update:
328 ==== update:
329 1:5a50a024c182
329 1:5a50a024c182
330 ====
330 ====
331 reverting a
331 reverting a
332 created new head
332 created new head
333 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
333 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
334 ==== update:
334 ==== update:
335 2:6ea3f2a197a2
335 2:6ea3f2a197a2
336 ====
336 ====
337 merging with changeset 3:d92a3f57f067
337 merging with changeset 3:d92a3f57f067
338 merging a
338 merging a
339 ==== update:
339 ==== update:
340 2:6ea3f2a197a2
340 2:6ea3f2a197a2
341 3:d92a3f57f067
341 3:d92a3f57f067
342 ====
342 ====
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
344 (branch merge, don't forget to commit)
344 (branch merge, don't forget to commit)
345
345
346 $ cat >> .hg/hgrc <<EOF
346 $ cat >> .hg/hgrc <<EOF
347 > [hooks]
347 > [hooks]
348 > update.visibility =
348 > update.visibility =
349 > EOF
349 > EOF
350
350
351 $ cd ..
351 $ cd ..
352
352
353 backout should not back out subsequent changesets
353 backout should not back out subsequent changesets
354
354
355 $ hg init onecs
355 $ hg init onecs
356 $ cd onecs
356 $ cd onecs
357 $ echo 1 > a
357 $ echo 1 > a
358 $ hg commit -d '0 0' -A -m a
358 $ hg commit -d '0 0' -A -m a
359 adding a
359 adding a
360 $ echo 2 >> a
360 $ echo 2 >> a
361 $ hg commit -d '1 0' -m b
361 $ hg commit -d '1 0' -m b
362 $ echo 1 > b
362 $ echo 1 > b
363 $ hg commit -d '2 0' -A -m c
363 $ hg commit -d '2 0' -A -m c
364 adding b
364 adding b
365 $ hg summary
365 $ hg summary
366 parent: 2:882396649954 tip
366 parent: 2:882396649954 tip
367 c
367 c
368 branch: default
368 branch: default
369 commit: (clean)
369 commit: (clean)
370 update: (current)
370 update: (current)
371 phases: 3 draft
371 phases: 3 draft
372
372
373 without --merge
373 without --merge
374 $ hg backout --no-commit -d '3 0' 1 --tool=true
374 $ hg backout --no-commit -d '3 0' 1 --tool=true
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 changeset 22bca4c721e5 backed out, don't forget to commit.
376 changeset 22bca4c721e5 backed out, don't forget to commit.
377 $ hg locate b
377 $ hg locate b
378 b
378 b
379 $ hg update -C tip
379 $ hg update -C tip
380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 $ hg locate b
381 $ hg locate b
382 b
382 b
383 $ hg summary
383 $ hg summary
384 parent: 2:882396649954 tip
384 parent: 2:882396649954 tip
385 c
385 c
386 branch: default
386 branch: default
387 commit: (clean)
387 commit: (clean)
388 update: (current)
388 update: (current)
389 phases: 3 draft
389 phases: 3 draft
390
390
391 with --merge
391 with --merge
392 $ hg backout --merge -d '3 0' 1 --tool=true
392 $ hg backout --merge -d '3 0' 1 --tool=true
393 reverting a
393 reverting a
394 created new head
394 created new head
395 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
395 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
396 merging with changeset 3:3202beb76721
396 merging with changeset 3:3202beb76721
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 (branch merge, don't forget to commit)
398 (branch merge, don't forget to commit)
399 $ hg locate b
399 $ hg locate b
400 b
400 b
401 $ hg update -C tip
401 $ hg update -C tip
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
403 $ hg locate b
403 $ hg locate b
404 [1]
404 [1]
405
405
406 $ cd ..
406 $ cd ..
407 $ hg init m
407 $ hg init m
408 $ cd m
408 $ cd m
409 $ echo a > a
409 $ echo a > a
410 $ hg commit -d '0 0' -A -m a
410 $ hg commit -d '0 0' -A -m a
411 adding a
411 adding a
412 $ echo b > b
412 $ echo b > b
413 $ hg commit -d '1 0' -A -m b
413 $ hg commit -d '1 0' -A -m b
414 adding b
414 adding b
415 $ echo c > c
415 $ echo c > c
416 $ hg commit -d '2 0' -A -m b
416 $ hg commit -d '2 0' -A -m b
417 adding c
417 adding c
418 $ hg update 1
418 $ hg update 1
419 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
419 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
420 $ echo d > d
420 $ echo d > d
421 $ hg commit -d '3 0' -A -m c
421 $ hg commit -d '3 0' -A -m c
422 adding d
422 adding d
423 created new head
423 created new head
424 $ hg merge 2
424 $ hg merge 2
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 (branch merge, don't forget to commit)
426 (branch merge, don't forget to commit)
427 $ hg commit -d '4 0' -A -m d
427 $ hg commit -d '4 0' -A -m d
428 $ hg summary
428 $ hg summary
429 parent: 4:b2f3bb92043e tip
429 parent: 4:b2f3bb92043e tip
430 d
430 d
431 branch: default
431 branch: default
432 commit: (clean)
432 commit: (clean)
433 update: (current)
433 update: (current)
434 phases: 5 draft
434 phases: 5 draft
435
435
436 backout of merge should fail
436 backout of merge should fail
437
437
438 $ hg backout 4
438 $ hg backout 4
439 abort: cannot backout a merge changeset
439 abort: cannot backout a merge changeset
440 [255]
440 [255]
441
441
442 backout of merge with bad parent should fail
442 backout of merge with bad parent should fail
443
443
444 $ hg backout --parent 0 4
444 $ hg backout --parent 0 4
445 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
445 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
446 [255]
446 [255]
447
447
448 backout of non-merge with parent should fail
448 backout of non-merge with parent should fail
449
449
450 $ hg backout --parent 0 3
450 $ hg backout --parent 0 3
451 abort: cannot use --parent on non-merge changeset
451 abort: cannot use --parent on non-merge changeset
452 [255]
452 [255]
453
453
454 backout with valid parent should be ok
454 backout with valid parent should be ok
455
455
456 $ hg backout -d '5 0' --parent 2 4 --tool=true
456 $ hg backout -d '5 0' --parent 2 4 --tool=true
457 removing d
457 removing d
458 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
458 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
459 $ hg summary
459 $ hg summary
460 parent: 5:10e5328c8435 tip
460 parent: 5:10e5328c8435 tip
461 Backed out changeset b2f3bb92043e
461 Backed out changeset b2f3bb92043e
462 branch: default
462 branch: default
463 commit: (clean)
463 commit: (clean)
464 update: (current)
464 update: (current)
465 phases: 6 draft
465 phases: 6 draft
466
466
467 $ hg rollback
467 $ hg rollback
468 repository tip rolled back to revision 4 (undo commit)
468 repository tip rolled back to revision 4 (undo commit)
469 working directory now based on revision 4
469 working directory now based on revision 4
470 $ hg update -C
470 $ hg update -C
471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
472 $ hg summary
472 $ hg summary
473 parent: 4:b2f3bb92043e tip
473 parent: 4:b2f3bb92043e tip
474 d
474 d
475 branch: default
475 branch: default
476 commit: (clean)
476 commit: (clean)
477 update: (current)
477 update: (current)
478 phases: 5 draft
478 phases: 5 draft
479
479
480 $ hg backout -d '6 0' --parent 3 4 --tool=true
480 $ hg backout -d '6 0' --parent 3 4 --tool=true
481 removing c
481 removing c
482 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
482 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
483 $ hg summary
483 $ hg summary
484 parent: 5:033590168430 tip
484 parent: 5:033590168430 tip
485 Backed out changeset b2f3bb92043e
485 Backed out changeset b2f3bb92043e
486 branch: default
486 branch: default
487 commit: (clean)
487 commit: (clean)
488 update: (current)
488 update: (current)
489 phases: 6 draft
489 phases: 6 draft
490
490
491 $ cd ..
491 $ cd ..
492
492
493 named branches
493 named branches
494
494
495 $ hg init named_branches
495 $ hg init named_branches
496 $ cd named_branches
496 $ cd named_branches
497
497
498 $ echo default > default
498 $ echo default > default
499 $ hg ci -d '0 0' -Am default
499 $ hg ci -d '0 0' -Am default
500 adding default
500 adding default
501 $ hg branch branch1
501 $ hg branch branch1
502 marked working directory as branch branch1
502 marked working directory as branch branch1
503 (branches are permanent and global, did you want a bookmark?)
503 (branches are permanent and global, did you want a bookmark?)
504 $ echo branch1 > file1
504 $ echo branch1 > file1
505 $ hg ci -d '1 0' -Am file1
505 $ hg ci -d '1 0' -Am file1
506 adding file1
506 adding file1
507 $ hg branch branch2
507 $ hg branch branch2
508 marked working directory as branch branch2
508 marked working directory as branch branch2
509 $ echo branch2 > file2
509 $ echo branch2 > file2
510 $ hg ci -d '2 0' -Am file2
510 $ hg ci -d '2 0' -Am file2
511 adding file2
511 adding file2
512
512
513 without --merge
513 without --merge
514 $ hg backout --no-commit -r 1 --tool=true
514 $ hg backout --no-commit -r 1 --tool=true
515 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
515 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
516 changeset bf1602f437f3 backed out, don't forget to commit.
516 changeset bf1602f437f3 backed out, don't forget to commit.
517 $ hg branch
517 $ hg branch
518 branch2
518 branch2
519 $ hg status -A
519 $ hg status -A
520 R file1
520 R file1
521 C default
521 C default
522 C file2
522 C file2
523 $ hg summary
523 $ hg summary
524 parent: 2:45bbcd363bf0 tip
524 parent: 2:45bbcd363bf0 tip
525 file2
525 file2
526 branch: branch2
526 branch: branch2
527 commit: 1 removed
527 commit: 1 removed
528 update: (current)
528 update: (current)
529 phases: 3 draft
529 phases: 3 draft
530
530
531 with --merge
531 with --merge
532 (this also tests that editor is invoked if '--edit' is specified
532 (this also tests that editor is invoked if '--edit' is specified
533 explicitly regardless of '--message')
533 explicitly regardless of '--message')
534
534
535 $ hg update -qC
535 $ hg update -qC
536 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
536 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
537 removing file1
537 removing file1
538 backout on branch1
538 backout on branch1
539
539
540
540
541 HG: Enter commit message. Lines beginning with 'HG:' are removed.
541 HG: Enter commit message. Lines beginning with 'HG:' are removed.
542 HG: Leave message empty to abort commit.
542 HG: Leave message empty to abort commit.
543 HG: --
543 HG: --
544 HG: user: test
544 HG: user: test
545 HG: branch 'branch2'
545 HG: branch 'branch2'
546 HG: removed file1
546 HG: removed file1
547 created new head
547 created new head
548 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
548 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
549 merging with changeset 3:d4e8f6db59fb
549 merging with changeset 3:d4e8f6db59fb
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
551 (branch merge, don't forget to commit)
551 (branch merge, don't forget to commit)
552 $ hg summary
552 $ hg summary
553 parent: 2:45bbcd363bf0
553 parent: 2:45bbcd363bf0
554 file2
554 file2
555 parent: 3:d4e8f6db59fb tip
555 parent: 3:d4e8f6db59fb tip
556 backout on branch1
556 backout on branch1
557 branch: branch2
557 branch: branch2
558 commit: 1 removed (merge)
558 commit: 1 removed (merge)
559 update: (current)
559 update: (current)
560 phases: 4 draft
560 phases: 4 draft
561 $ hg update -q -C 2
561 $ hg update -q -C 2
562
562
563 on branch2 with branch1 not merged, so file1 should still exist:
563 on branch2 with branch1 not merged, so file1 should still exist:
564
564
565 $ hg id
565 $ hg id
566 45bbcd363bf0 (branch2)
566 45bbcd363bf0 (branch2)
567 $ hg st -A
567 $ hg st -A
568 C default
568 C default
569 C file1
569 C file1
570 C file2
570 C file2
571 $ hg summary
571 $ hg summary
572 parent: 2:45bbcd363bf0
572 parent: 2:45bbcd363bf0
573 file2
573 file2
574 branch: branch2
574 branch: branch2
575 commit: (clean)
575 commit: (clean)
576 update: 1 new changesets, 2 branch heads (merge)
576 update: 1 new changesets, 2 branch heads (merge)
577 phases: 4 draft
577 phases: 4 draft
578
578
579 on branch2 with branch1 merged, so file1 should be gone:
579 on branch2 with branch1 merged, so file1 should be gone:
580
580
581 $ hg merge
581 $ hg merge
582 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
582 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
583 (branch merge, don't forget to commit)
583 (branch merge, don't forget to commit)
584 $ hg ci -d '4 0' -m 'merge backout of branch1'
584 $ hg ci -d '4 0' -m 'merge backout of branch1'
585 $ hg id
585 $ hg id
586 22149cdde76d (branch2) tip
586 22149cdde76d (branch2) tip
587 $ hg st -A
587 $ hg st -A
588 C default
588 C default
589 C file2
589 C file2
590 $ hg summary
590 $ hg summary
591 parent: 4:22149cdde76d tip
591 parent: 4:22149cdde76d tip
592 merge backout of branch1
592 merge backout of branch1
593 branch: branch2
593 branch: branch2
594 commit: (clean)
594 commit: (clean)
595 update: (current)
595 update: (current)
596 phases: 5 draft
596 phases: 5 draft
597
597
598 on branch1, so no file1 and file2:
598 on branch1, so no file1 and file2:
599
599
600 $ hg co -C branch1
600 $ hg co -C branch1
601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
602 $ hg id
602 $ hg id
603 bf1602f437f3 (branch1)
603 bf1602f437f3 (branch1)
604 $ hg st -A
604 $ hg st -A
605 C default
605 C default
606 C file1
606 C file1
607 $ hg summary
607 $ hg summary
608 parent: 1:bf1602f437f3
608 parent: 1:bf1602f437f3
609 file1
609 file1
610 branch: branch1
610 branch: branch1
611 commit: (clean)
611 commit: (clean)
612 update: (current)
612 update: (current)
613 phases: 5 draft
613 phases: 5 draft
614
614
615 $ cd ..
615 $ cd ..
616
616
617 backout of empty changeset (issue4190)
617 backout of empty changeset (issue4190)
618
618
619 $ hg init emptycommit
619 $ hg init emptycommit
620 $ cd emptycommit
620 $ cd emptycommit
621
621
622 $ touch file1
622 $ touch file1
623 $ hg ci -Aqm file1
623 $ hg ci -Aqm file1
624 $ hg branch -q branch1
624 $ hg branch -q branch1
625 $ hg ci -qm branch1
625 $ hg ci -qm branch1
626 $ hg backout -v 1
626 $ hg backout -v 1
627 resolving manifests
627 resolving manifests
628 nothing changed
628 nothing changed
629 [1]
629 [1]
630
630
631 $ cd ..
631 $ cd ..
632
632
633
633
634 Test usage of `hg resolve` in case of conflict
634 Test usage of `hg resolve` in case of conflict
635 (issue4163)
635 (issue4163)
636
636
637 $ hg init issue4163
637 $ hg init issue4163
638 $ cd issue4163
638 $ cd issue4163
639 $ touch foo
639 $ touch foo
640 $ hg add foo
640 $ hg add foo
641 $ cat > foo << EOF
641 $ cat > foo << EOF
642 > one
642 > one
643 > two
643 > two
644 > three
644 > three
645 > four
645 > four
646 > five
646 > five
647 > six
647 > six
648 > seven
648 > seven
649 > height
649 > height
650 > nine
650 > nine
651 > ten
651 > ten
652 > EOF
652 > EOF
653 $ hg ci -m 'initial'
653 $ hg ci -m 'initial'
654 $ cat > foo << EOF
654 $ cat > foo << EOF
655 > one
655 > one
656 > two
656 > two
657 > THREE
657 > THREE
658 > four
658 > four
659 > five
659 > five
660 > six
660 > six
661 > seven
661 > seven
662 > height
662 > height
663 > nine
663 > nine
664 > ten
664 > ten
665 > EOF
665 > EOF
666 $ hg ci -m 'capital three'
666 $ hg ci -m 'capital three'
667 $ cat > foo << EOF
667 $ cat > foo << EOF
668 > one
668 > one
669 > two
669 > two
670 > THREE
670 > THREE
671 > four
671 > four
672 > five
672 > five
673 > six
673 > six
674 > seven
674 > seven
675 > height
675 > height
676 > nine
676 > nine
677 > TEN
677 > TEN
678 > EOF
678 > EOF
679 $ hg ci -m 'capital ten'
679 $ hg ci -m 'capital ten'
680 $ hg backout -r 'desc("capital three")' --tool internal:fail
680 $ hg backout -r 'desc("capital three")' --tool internal:fail
681 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
681 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
682 use 'hg resolve' to retry unresolved file merges
682 use 'hg resolve' to retry unresolved file merges
683 [1]
683 [1]
684 $ hg status
684 $ hg status
685 $ hg debugmergestate
685 $ hg debugmergestate
686 * version 2 records
686 * version 2 records
687 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
687 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
688 other: a30dd8addae3ce71b8667868478542bc417439e6
688 other: a30dd8addae3ce71b8667868478542bc417439e6
689 file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
689 file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
690 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
690 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
691 local path: foo (flags "")
691 local path: foo (flags "")
692 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
692 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
693 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
693 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
694 $ mv .hg/merge/state2 .hg/merge/state2-moved
694 $ mv .hg/merge/state2 .hg/merge/state2-moved
695 $ hg debugmergestate
695 $ hg debugmergestate
696 * version 1 records
696 * version 1 records
697 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
697 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
698 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
698 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
699 local path: foo (flags "")
699 local path: foo (flags "")
700 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
700 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
701 other path: foo (node not stored in v1 format)
701 other path: foo (node not stored in v1 format)
702 $ mv .hg/merge/state2-moved .hg/merge/state2
702 $ mv .hg/merge/state2-moved .hg/merge/state2
703 $ hg resolve -l # still unresolved
703 $ hg resolve -l # still unresolved
704 U foo
704 U foo
705 $ hg summary
705 $ hg summary
706 parent: 2:b71750c4b0fd tip
706 parent: 2:b71750c4b0fd tip
707 capital ten
707 capital ten
708 branch: default
708 branch: default
709 commit: 1 unresolved (clean)
709 commit: 1 unresolved (clean)
710 update: (current)
710 update: (current)
711 phases: 3 draft
711 phases: 3 draft
712 $ hg resolve --all --debug
712 $ hg resolve --all --debug
713 picked tool ':merge' for foo (binary False symlink False changedelete False)
713 picked tool ':merge' for foo (binary False symlink False changedelete False)
714 merging foo
714 merging foo
715 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
715 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
716 premerge successful
716 premerge successful
717 (no more unresolved files)
717 (no more unresolved files)
718 continue: hg commit
718 continue: hg commit
719 $ hg status
719 $ hg status
720 M foo
720 M foo
721 ? foo.orig
721 ? foo.orig
722 $ hg resolve -l
722 $ hg resolve -l
723 R foo
723 R foo
724 $ hg summary
724 $ hg summary
725 parent: 2:b71750c4b0fd tip
725 parent: 2:b71750c4b0fd tip
726 capital ten
726 capital ten
727 branch: default
727 branch: default
728 commit: 1 modified, 1 unknown
728 commit: 1 modified, 1 unknown
729 update: (current)
729 update: (current)
730 phases: 3 draft
730 phases: 3 draft
731 $ cat foo
731 $ cat foo
732 one
732 one
733 two
733 two
734 three
734 three
735 four
735 four
736 five
736 five
737 six
737 six
738 seven
738 seven
739 height
739 height
740 nine
740 nine
741 TEN
741 TEN
742
742
743 --no-commit shouldn't commit
743 --no-commit shouldn't commit
744
744
745 $ hg init a
745 $ hg init a
746 $ cd a
746 $ cd a
747 $ for i in 1 2 3; do
747 $ for i in 1 2 3; do
748 > touch $i
748 > touch $i
749 > hg ci -Am $i
749 > hg ci -Am $i
750 > done
750 > done
751 adding 1
751 adding 1
752 adding 2
752 adding 2
753 adding 3
753 adding 3
754 $ hg backout --no-commit .
754 $ hg backout --no-commit .
755 removing 3
755 removing 3
756 changeset cccc23d9d68f backed out, don't forget to commit.
756 changeset cccc23d9d68f backed out, don't forget to commit.
757 $ hg revert -aq
757 $ hg revert -aq
758
758
759 --no-commit can't be used with --merge
759 --no-commit can't be used with --merge
760
760
761 $ hg backout --merge --no-commit 2
761 $ hg backout --merge --no-commit 2
762 abort: cannot use --merge with --no-commit
762 abort: cannot use --merge with --no-commit
763 [255]
763 [255]
@@ -1,406 +1,406 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 config
16 config
17 copy
17 copy
18 diff
18 diff
19 export
19 export
20 files
20 files
21 forget
21 forget
22 graft
22 graft
23 grep
23 grep
24 heads
24 heads
25 help
25 help
26 identify
26 identify
27 import
27 import
28 incoming
28 incoming
29 init
29 init
30 locate
30 locate
31 log
31 log
32 manifest
32 manifest
33 merge
33 merge
34 outgoing
34 outgoing
35 parents
35 parents
36 paths
36 paths
37 phase
37 phase
38 pull
38 pull
39 push
39 push
40 recover
40 recover
41 remove
41 remove
42 rename
42 rename
43 resolve
43 resolve
44 revert
44 revert
45 rollback
45 rollback
46 root
46 root
47 serve
47 serve
48 status
48 status
49 summary
49 summary
50 tag
50 tag
51 tags
51 tags
52 tip
52 tip
53 unbundle
53 unbundle
54 update
54 update
55 verify
55 verify
56 version
56 version
57
57
58 Show all commands that start with "a"
58 Show all commands that start with "a"
59 $ hg debugcomplete a
59 $ hg debugcomplete a
60 add
60 add
61 addremove
61 addremove
62 annotate
62 annotate
63 archive
63 archive
64
64
65 Do not show debug commands if there are other candidates
65 Do not show debug commands if there are other candidates
66 $ hg debugcomplete d
66 $ hg debugcomplete d
67 diff
67 diff
68
68
69 Show debug commands if there are no other candidates
69 Show debug commands if there are no other candidates
70 $ hg debugcomplete debug
70 $ hg debugcomplete debug
71 debugancestor
71 debugancestor
72 debugapplystreamclonebundle
72 debugapplystreamclonebundle
73 debugbuilddag
73 debugbuilddag
74 debugbundle
74 debugbundle
75 debugcapabilities
75 debugcapabilities
76 debugcheckstate
76 debugcheckstate
77 debugcolor
77 debugcolor
78 debugcommands
78 debugcommands
79 debugcomplete
79 debugcomplete
80 debugconfig
80 debugconfig
81 debugcreatestreamclonebundle
81 debugcreatestreamclonebundle
82 debugdag
82 debugdag
83 debugdata
83 debugdata
84 debugdate
84 debugdate
85 debugdeltachain
85 debugdeltachain
86 debugdirstate
86 debugdirstate
87 debugdiscovery
87 debugdiscovery
88 debugdownload
88 debugdownload
89 debugextensions
89 debugextensions
90 debugfileset
90 debugfileset
91 debugformat
91 debugformat
92 debugfsinfo
92 debugfsinfo
93 debuggetbundle
93 debuggetbundle
94 debugignore
94 debugignore
95 debugindex
95 debugindex
96 debugindexdot
96 debugindexdot
97 debuginstall
97 debuginstall
98 debugknown
98 debugknown
99 debuglabelcomplete
99 debuglabelcomplete
100 debuglocks
100 debuglocks
101 debugmanifestfulltextcache
101 debugmanifestfulltextcache
102 debugmergestate
102 debugmergestate
103 debugnamecomplete
103 debugnamecomplete
104 debugobsolete
104 debugobsolete
105 debugpathcomplete
105 debugpathcomplete
106 debugpeer
106 debugpeer
107 debugpickmergetool
107 debugpickmergetool
108 debugpushkey
108 debugpushkey
109 debugpvec
109 debugpvec
110 debugrebuilddirstate
110 debugrebuilddirstate
111 debugrebuildfncache
111 debugrebuildfncache
112 debugrename
112 debugrename
113 debugrevlog
113 debugrevlog
114 debugrevlogindex
114 debugrevlogindex
115 debugrevspec
115 debugrevspec
116 debugserve
116 debugserve
117 debugsetparents
117 debugsetparents
118 debugssl
118 debugssl
119 debugsub
119 debugsub
120 debugsuccessorssets
120 debugsuccessorssets
121 debugtemplate
121 debugtemplate
122 debuguigetpass
122 debuguigetpass
123 debuguiprompt
123 debuguiprompt
124 debugupdatecaches
124 debugupdatecaches
125 debugupgraderepo
125 debugupgraderepo
126 debugwalk
126 debugwalk
127 debugwhyunstable
127 debugwhyunstable
128 debugwireargs
128 debugwireargs
129 debugwireproto
129 debugwireproto
130
130
131 Do not show the alias of a debug command if there are other candidates
131 Do not show the alias of a debug command if there are other candidates
132 (this should hide rawcommit)
132 (this should hide rawcommit)
133 $ hg debugcomplete r
133 $ hg debugcomplete r
134 recover
134 recover
135 remove
135 remove
136 rename
136 rename
137 resolve
137 resolve
138 revert
138 revert
139 rollback
139 rollback
140 root
140 root
141 Show the alias of a debug command if there are no other candidates
141 Show the alias of a debug command if there are no other candidates
142 $ hg debugcomplete rawc
142 $ hg debugcomplete rawc
143
143
144
144
145 Show the global options
145 Show the global options
146 $ hg debugcomplete --options | sort
146 $ hg debugcomplete --options | sort
147 --color
147 --color
148 --config
148 --config
149 --cwd
149 --cwd
150 --debug
150 --debug
151 --debugger
151 --debugger
152 --encoding
152 --encoding
153 --encodingmode
153 --encodingmode
154 --help
154 --help
155 --hidden
155 --hidden
156 --noninteractive
156 --noninteractive
157 --pager
157 --pager
158 --profile
158 --profile
159 --quiet
159 --quiet
160 --repository
160 --repository
161 --time
161 --time
162 --traceback
162 --traceback
163 --verbose
163 --verbose
164 --version
164 --version
165 -R
165 -R
166 -h
166 -h
167 -q
167 -q
168 -v
168 -v
169 -y
169 -y
170
170
171 Show the options for the "serve" command
171 Show the options for the "serve" command
172 $ hg debugcomplete --options serve | sort
172 $ hg debugcomplete --options serve | sort
173 --accesslog
173 --accesslog
174 --address
174 --address
175 --certificate
175 --certificate
176 --cmdserver
176 --cmdserver
177 --color
177 --color
178 --config
178 --config
179 --cwd
179 --cwd
180 --daemon
180 --daemon
181 --daemon-postexec
181 --daemon-postexec
182 --debug
182 --debug
183 --debugger
183 --debugger
184 --encoding
184 --encoding
185 --encodingmode
185 --encodingmode
186 --errorlog
186 --errorlog
187 --help
187 --help
188 --hidden
188 --hidden
189 --ipv6
189 --ipv6
190 --name
190 --name
191 --noninteractive
191 --noninteractive
192 --pager
192 --pager
193 --pid-file
193 --pid-file
194 --port
194 --port
195 --prefix
195 --prefix
196 --print-url
196 --print-url
197 --profile
197 --profile
198 --quiet
198 --quiet
199 --repository
199 --repository
200 --stdio
200 --stdio
201 --style
201 --style
202 --subrepos
202 --subrepos
203 --templates
203 --templates
204 --time
204 --time
205 --traceback
205 --traceback
206 --verbose
206 --verbose
207 --version
207 --version
208 --web-conf
208 --web-conf
209 -6
209 -6
210 -A
210 -A
211 -E
211 -E
212 -R
212 -R
213 -S
213 -S
214 -a
214 -a
215 -d
215 -d
216 -h
216 -h
217 -n
217 -n
218 -p
218 -p
219 -q
219 -q
220 -t
220 -t
221 -v
221 -v
222 -y
222 -y
223
223
224 Show an error if we use --options with an ambiguous abbreviation
224 Show an error if we use --options with an ambiguous abbreviation
225 $ hg debugcomplete --options s
225 $ hg debugcomplete --options s
226 hg: command 's' is ambiguous:
226 hg: command 's' is ambiguous:
227 serve showconfig status summary
227 serve showconfig status summary
228 [255]
228 [255]
229
229
230 Show all commands + options
230 Show all commands + options
231 $ hg debugcommands
231 $ hg debugcommands
232 add: include, exclude, subrepos, dry-run
232 add: include, exclude, subrepos, dry-run
233 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
233 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
234 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
234 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
235 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
235 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
236 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
236 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
237 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
237 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
238 forget: interactive, include, exclude, dry-run
238 forget: interactive, include, exclude, dry-run
239 init: ssh, remotecmd, insecure
239 init: ssh, remotecmd, insecure
240 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
240 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
241 merge: force, rev, preview, abort, tool
241 merge: force, rev, preview, abort, tool
242 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
242 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
243 push: force, rev, bookmark, branch, new-branch, pushvars, ssh, remotecmd, insecure
243 push: force, rev, bookmark, branch, new-branch, pushvars, ssh, remotecmd, insecure
244 remove: after, force, subrepos, include, exclude, dry-run
244 remove: after, force, subrepos, include, exclude, dry-run
245 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
245 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
246 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
246 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
247 summary: remote
247 summary: remote
248 update: clean, check, merge, date, rev, tool
248 update: clean, check, merge, date, rev, tool
249 addremove: similarity, subrepos, include, exclude, dry-run
249 addremove: similarity, subrepos, include, exclude, dry-run
250 archive: no-decode, prefix, rev, type, subrepos, include, exclude
250 archive: no-decode, prefix, rev, type, subrepos, include, exclude
251 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
251 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
252 bisect: reset, good, bad, skip, extend, command, noupdate
252 bisect: reset, good, bad, skip, extend, command, noupdate
253 bookmarks: force, rev, delete, rename, inactive, list, template
253 bookmarks: force, rev, delete, rename, inactive, list, template
254 branch: force, clean, rev
254 branch: force, clean, rev
255 branches: active, closed, template
255 branches: active, closed, template
256 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
256 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
257 cat: output, rev, decode, include, exclude, template
257 cat: output, rev, decode, include, exclude, template
258 config: untrusted, edit, local, global, template
258 config: untrusted, edit, local, global, template
259 copy: after, force, include, exclude, dry-run
259 copy: after, force, include, exclude, dry-run
260 debugancestor:
260 debugancestor:
261 debugapplystreamclonebundle:
261 debugapplystreamclonebundle:
262 debugbuilddag: mergeable-file, overwritten-file, new-file
262 debugbuilddag: mergeable-file, overwritten-file, new-file
263 debugbundle: all, part-type, spec
263 debugbundle: all, part-type, spec
264 debugcapabilities:
264 debugcapabilities:
265 debugcheckstate:
265 debugcheckstate:
266 debugcolor: style
266 debugcolor: style
267 debugcommands:
267 debugcommands:
268 debugcomplete: options
268 debugcomplete: options
269 debugcreatestreamclonebundle:
269 debugcreatestreamclonebundle:
270 debugdag: tags, branches, dots, spaces
270 debugdag: tags, branches, dots, spaces
271 debugdata: changelog, manifest, dir
271 debugdata: changelog, manifest, dir
272 debugdate: extended
272 debugdate: extended
273 debugdeltachain: changelog, manifest, dir, template
273 debugdeltachain: changelog, manifest, dir, template
274 debugdirstate: nodates, datesort
274 debugdirstate: nodates, dates, datesort
275 debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure
275 debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure
276 debugdownload: output
276 debugdownload: output
277 debugextensions: template
277 debugextensions: template
278 debugfileset: rev, all-files, show-matcher, show-stage
278 debugfileset: rev, all-files, show-matcher, show-stage
279 debugformat: template
279 debugformat: template
280 debugfsinfo:
280 debugfsinfo:
281 debuggetbundle: head, common, type
281 debuggetbundle: head, common, type
282 debugignore:
282 debugignore:
283 debugindex: changelog, manifest, dir, template
283 debugindex: changelog, manifest, dir, template
284 debugindexdot: changelog, manifest, dir
284 debugindexdot: changelog, manifest, dir
285 debuginstall: template
285 debuginstall: template
286 debugknown:
286 debugknown:
287 debuglabelcomplete:
287 debuglabelcomplete:
288 debuglocks: force-lock, force-wlock, set-lock, set-wlock
288 debuglocks: force-lock, force-wlock, set-lock, set-wlock
289 debugmanifestfulltextcache: clear, add
289 debugmanifestfulltextcache: clear, add
290 debugmergestate:
290 debugmergestate:
291 debugnamecomplete:
291 debugnamecomplete:
292 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
292 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
293 debugpathcomplete: full, normal, added, removed
293 debugpathcomplete: full, normal, added, removed
294 debugpeer:
294 debugpeer:
295 debugpickmergetool: rev, changedelete, include, exclude, tool
295 debugpickmergetool: rev, changedelete, include, exclude, tool
296 debugpushkey:
296 debugpushkey:
297 debugpvec:
297 debugpvec:
298 debugrebuilddirstate: rev, minimal
298 debugrebuilddirstate: rev, minimal
299 debugrebuildfncache:
299 debugrebuildfncache:
300 debugrename: rev
300 debugrename: rev
301 debugrevlog: changelog, manifest, dir, dump
301 debugrevlog: changelog, manifest, dir, dump
302 debugrevlogindex: changelog, manifest, dir, format
302 debugrevlogindex: changelog, manifest, dir, format
303 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
303 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
304 debugserve: sshstdio, logiofd, logiofile
304 debugserve: sshstdio, logiofd, logiofile
305 debugsetparents:
305 debugsetparents:
306 debugssl:
306 debugssl:
307 debugsub: rev
307 debugsub: rev
308 debugsuccessorssets: closest
308 debugsuccessorssets: closest
309 debugtemplate: rev, define
309 debugtemplate: rev, define
310 debuguigetpass: prompt
310 debuguigetpass: prompt
311 debuguiprompt: prompt
311 debuguiprompt: prompt
312 debugupdatecaches:
312 debugupdatecaches:
313 debugupgraderepo: optimize, run
313 debugupgraderepo: optimize, run
314 debugwalk: include, exclude
314 debugwalk: include, exclude
315 debugwhyunstable:
315 debugwhyunstable:
316 debugwireargs: three, four, five, ssh, remotecmd, insecure
316 debugwireargs: three, four, five, ssh, remotecmd, insecure
317 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
317 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
318 files: rev, print0, include, exclude, template, subrepos
318 files: rev, print0, include, exclude, template, subrepos
319 graft: rev, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
319 graft: rev, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
320 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
320 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
321 heads: rev, topo, active, closed, style, template
321 heads: rev, topo, active, closed, style, template
322 help: extension, command, keyword, system
322 help: extension, command, keyword, system
323 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
323 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
324 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
324 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
325 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
325 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
326 locate: rev, print0, fullpath, include, exclude
326 locate: rev, print0, fullpath, include, exclude
327 manifest: rev, all, template
327 manifest: rev, all, template
328 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
328 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
329 parents: rev, style, template
329 parents: rev, style, template
330 paths: template
330 paths: template
331 phase: public, draft, secret, force, rev
331 phase: public, draft, secret, force, rev
332 recover:
332 recover:
333 rename: after, force, include, exclude, dry-run
333 rename: after, force, include, exclude, dry-run
334 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
334 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
335 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
335 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
336 rollback: dry-run, force
336 rollback: dry-run, force
337 root:
337 root:
338 tag: force, local, rev, remove, edit, message, date, user
338 tag: force, local, rev, remove, edit, message, date, user
339 tags: template
339 tags: template
340 tip: patch, git, style, template
340 tip: patch, git, style, template
341 unbundle: update
341 unbundle: update
342 verify:
342 verify:
343 version: template
343 version: template
344
344
345 $ hg init a
345 $ hg init a
346 $ cd a
346 $ cd a
347 $ echo fee > fee
347 $ echo fee > fee
348 $ hg ci -q -Amfee
348 $ hg ci -q -Amfee
349 $ hg tag fee
349 $ hg tag fee
350 $ mkdir fie
350 $ mkdir fie
351 $ echo dead > fie/dead
351 $ echo dead > fie/dead
352 $ echo live > fie/live
352 $ echo live > fie/live
353 $ hg bookmark fo
353 $ hg bookmark fo
354 $ hg branch -q fie
354 $ hg branch -q fie
355 $ hg ci -q -Amfie
355 $ hg ci -q -Amfie
356 $ echo fo > fo
356 $ echo fo > fo
357 $ hg branch -qf default
357 $ hg branch -qf default
358 $ hg ci -q -Amfo
358 $ hg ci -q -Amfo
359 $ echo Fum > Fum
359 $ echo Fum > Fum
360 $ hg ci -q -AmFum
360 $ hg ci -q -AmFum
361 $ hg bookmark Fum
361 $ hg bookmark Fum
362
362
363 Test debugpathcomplete
363 Test debugpathcomplete
364
364
365 $ hg debugpathcomplete f
365 $ hg debugpathcomplete f
366 fee
366 fee
367 fie
367 fie
368 fo
368 fo
369 $ hg debugpathcomplete -f f
369 $ hg debugpathcomplete -f f
370 fee
370 fee
371 fie/dead
371 fie/dead
372 fie/live
372 fie/live
373 fo
373 fo
374
374
375 $ hg rm Fum
375 $ hg rm Fum
376 $ hg debugpathcomplete -r F
376 $ hg debugpathcomplete -r F
377 Fum
377 Fum
378
378
379 Test debugnamecomplete
379 Test debugnamecomplete
380
380
381 $ hg debugnamecomplete
381 $ hg debugnamecomplete
382 Fum
382 Fum
383 default
383 default
384 fee
384 fee
385 fie
385 fie
386 fo
386 fo
387 tip
387 tip
388 $ hg debugnamecomplete f
388 $ hg debugnamecomplete f
389 fee
389 fee
390 fie
390 fie
391 fo
391 fo
392
392
393 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
393 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
394 used for completions in some shells.
394 used for completions in some shells.
395
395
396 $ hg debuglabelcomplete
396 $ hg debuglabelcomplete
397 Fum
397 Fum
398 default
398 default
399 fee
399 fee
400 fie
400 fie
401 fo
401 fo
402 tip
402 tip
403 $ hg debuglabelcomplete f
403 $ hg debuglabelcomplete f
404 fee
404 fee
405 fie
405 fie
406 fo
406 fo
@@ -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 --no-dates | 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 linkrev nodeid p1 p2
76 rev linkrev nodeid p1 p2
77 0 0 cdca01651b96 000000000000 000000000000
77 0 0 cdca01651b96 000000000000 000000000000
78 1 1 f6718a9cb7f3 cdca01651b96 000000000000
78 1 1 f6718a9cb7f3 cdca01651b96 000000000000
79 2 2 bdd988058d16 cdca01651b96 000000000000
79 2 2 bdd988058d16 cdca01651b96 000000000000
80 3 3 d8a521142a3c f6718a9cb7f3 bdd988058d16
80 3 3 d8a521142a3c f6718a9cb7f3 bdd988058d16
81
81
82 log should show foo and quux changed:
82 log should show foo and quux changed:
83
83
84 $ hg log -v -r tip
84 $ hg log -v -r tip
85 changeset: 3:d8a521142a3c
85 changeset: 3:d8a521142a3c
86 tag: tip
86 tag: tip
87 parent: 1:f6718a9cb7f3
87 parent: 1:f6718a9cb7f3
88 parent: 2:bdd988058d16
88 parent: 2:bdd988058d16
89 user: test
89 user: test
90 date: Thu Jan 01 00:00:00 1970 +0000
90 date: Thu Jan 01 00:00:00 1970 +0000
91 files: foo quux
91 files: foo quux
92 description:
92 description:
93 merge
93 merge
94
94
95
95
96
96
97 foo: we should have a merge here:
97 foo: we should have a merge here:
98
98
99 $ hg debugindex foo
99 $ hg debugindex foo
100 rev linkrev nodeid p1 p2
100 rev linkrev nodeid p1 p2
101 0 0 b8e02f643373 000000000000 000000000000
101 0 0 b8e02f643373 000000000000 000000000000
102 1 1 2ffeddde1b65 b8e02f643373 000000000000
102 1 1 2ffeddde1b65 b8e02f643373 000000000000
103 2 2 33d1fb69067a b8e02f643373 000000000000
103 2 2 33d1fb69067a b8e02f643373 000000000000
104 3 3 aa27919ee430 2ffeddde1b65 33d1fb69067a
104 3 3 aa27919ee430 2ffeddde1b65 33d1fb69067a
105
105
106 bar: we should not have a merge here:
106 bar: we should not have a merge here:
107
107
108 $ hg debugindex bar
108 $ hg debugindex bar
109 rev linkrev nodeid p1 p2
109 rev linkrev nodeid p1 p2
110 0 0 b8e02f643373 000000000000 000000000000
110 0 0 b8e02f643373 000000000000 000000000000
111 1 2 33d1fb69067a b8e02f643373 000000000000
111 1 2 33d1fb69067a b8e02f643373 000000000000
112
112
113 baz: we should not have a merge here:
113 baz: we should not have a merge here:
114
114
115 $ hg debugindex baz
115 $ hg debugindex baz
116 rev linkrev nodeid p1 p2
116 rev linkrev nodeid p1 p2
117 0 0 b8e02f643373 000000000000 000000000000
117 0 0 b8e02f643373 000000000000 000000000000
118 1 1 2ffeddde1b65 b8e02f643373 000000000000
118 1 1 2ffeddde1b65 b8e02f643373 000000000000
119
119
120 quux: we should not have a merge here:
120 quux: we should not have a merge here:
121
121
122 $ hg debugindex quux
122 $ hg debugindex quux
123 rev linkrev nodeid p1 p2
123 rev linkrev nodeid p1 p2
124 0 0 b8e02f643373 000000000000 000000000000
124 0 0 b8e02f643373 000000000000 000000000000
125 1 3 6128c0f33108 b8e02f643373 000000000000
125 1 3 6128c0f33108 b8e02f643373 000000000000
126
126
127 Manifest entries should match tips of all files:
127 Manifest entries should match tips of all files:
128
128
129 $ hg manifest --debug
129 $ hg manifest --debug
130 33d1fb69067a0139622a3fa3b7ba1cdb1367972e 644 bar
130 33d1fb69067a0139622a3fa3b7ba1cdb1367972e 644 bar
131 2ffeddde1b65b4827f6746174a145474129fa2ce 644 baz
131 2ffeddde1b65b4827f6746174a145474129fa2ce 644 baz
132 aa27919ee4303cfd575e1fb932dd64d75aa08be4 644 foo
132 aa27919ee4303cfd575e1fb932dd64d75aa08be4 644 foo
133 6128c0f33108e8cfbb4e0824d13ae48b466d7280 644 quux
133 6128c0f33108e8cfbb4e0824d13ae48b466d7280 644 quux
134
134
135 Everything should be clean now:
135 Everything should be clean now:
136
136
137 $ hg status
137 $ hg status
138
138
139 $ hg verify
139 $ hg verify
140 checking changesets
140 checking changesets
141 checking manifests
141 checking manifests
142 crosschecking files in changesets and manifests
142 crosschecking files in changesets and manifests
143 checking files
143 checking files
144 checked 4 changesets with 10 changes to 4 files
144 checked 4 changesets with 10 changes to 4 files
145
145
146 $ cd ..
146 $ cd ..
@@ -1,795 +1,795 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 This file focuses mainly on updating largefiles in the working
3 This file focuses mainly on updating largefiles in the working
4 directory (and ".hg/largefiles/dirstate")
4 directory (and ".hg/largefiles/dirstate")
5
5
6 $ cat >> $HGRCPATH <<EOF
6 $ cat >> $HGRCPATH <<EOF
7 > [ui]
7 > [ui]
8 > merge = internal:fail
8 > merge = internal:fail
9 > [extensions]
9 > [extensions]
10 > largefiles =
10 > largefiles =
11 > [extdiff]
11 > [extdiff]
12 > # for portability:
12 > # for portability:
13 > pdiff = sh "$RUNTESTDIR/pdiff"
13 > pdiff = sh "$RUNTESTDIR/pdiff"
14 > EOF
14 > EOF
15
15
16 $ hg init repo
16 $ hg init repo
17 $ cd repo
17 $ cd repo
18
18
19 $ echo large1 > large1
19 $ echo large1 > large1
20 $ echo large2 > large2
20 $ echo large2 > large2
21 $ hg add --large large1 large2
21 $ hg add --large large1 large2
22 $ echo normal1 > normal1
22 $ echo normal1 > normal1
23 $ hg add normal1
23 $ hg add normal1
24 $ hg commit -m '#0'
24 $ hg commit -m '#0'
25 $ echo 'large1 in #1' > large1
25 $ echo 'large1 in #1' > large1
26 $ echo 'normal1 in #1' > normal1
26 $ echo 'normal1 in #1' > normal1
27 $ hg commit -m '#1'
27 $ hg commit -m '#1'
28 $ hg pdiff -r '.^' --config extensions.extdiff=
28 $ hg pdiff -r '.^' --config extensions.extdiff=
29 diff -Nru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1
29 diff -Nru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1
30 --- repo.0d9d9b8dc9a3/.hglf/large1 * (glob)
30 --- repo.0d9d9b8dc9a3/.hglf/large1 * (glob)
31 +++ repo/.hglf/large1 * (glob)
31 +++ repo/.hglf/large1 * (glob)
32 @@ -1* +1* @@ (glob)
32 @@ -1* +1* @@ (glob)
33 -4669e532d5b2c093a78eca010077e708a071bb64
33 -4669e532d5b2c093a78eca010077e708a071bb64
34 +58e24f733a964da346e2407a2bee99d9001184f5
34 +58e24f733a964da346e2407a2bee99d9001184f5
35 diff -Nru repo.0d9d9b8dc9a3/normal1 repo/normal1
35 diff -Nru repo.0d9d9b8dc9a3/normal1 repo/normal1
36 --- repo.0d9d9b8dc9a3/normal1 * (glob)
36 --- repo.0d9d9b8dc9a3/normal1 * (glob)
37 +++ repo/normal1 * (glob)
37 +++ repo/normal1 * (glob)
38 @@ -1* +1* @@ (glob)
38 @@ -1* +1* @@ (glob)
39 -normal1
39 -normal1
40 +normal1 in #1
40 +normal1 in #1
41 [1]
41 [1]
42 $ hg update -q -C 0
42 $ hg update -q -C 0
43 $ echo 'large2 in #2' > large2
43 $ echo 'large2 in #2' > large2
44 $ hg commit -m '#2'
44 $ hg commit -m '#2'
45 created new head
45 created new head
46
46
47 Test that update also updates the lfdirstate of 'unsure' largefiles after
47 Test that update also updates the lfdirstate of 'unsure' largefiles after
48 hashing them:
48 hashing them:
49
49
50 The previous operations will usually have left us with largefiles with a mtime
50 The previous operations will usually have left us with largefiles with a mtime
51 within the same second as the dirstate was written.
51 within the same second as the dirstate was written.
52 The lfdirstate entries will thus have been written with an invalidated/unset
52 The lfdirstate entries will thus have been written with an invalidated/unset
53 mtime to make sure further changes within the same second is detected.
53 mtime to make sure further changes within the same second is detected.
54 We will however occasionally be "lucky" and get a tick between writing
54 We will however occasionally be "lucky" and get a tick between writing
55 largefiles and writing dirstate so we get valid lfdirstate timestamps. The
55 largefiles and writing dirstate so we get valid lfdirstate timestamps. The
56 following verification is thus disabled but can be verified manually.
56 following verification is thus disabled but can be verified manually.
57
57
58 #if false
58 #if false
59 $ hg debugdirstate --large --nodate
59 $ hg debugdirstate --large --nodate
60 n 644 7 unset large1
60 n 644 7 unset large1
61 n 644 13 unset large2
61 n 644 13 unset large2
62 #endif
62 #endif
63
63
64 Wait to make sure we get a tick so the mtime of the largefiles become valid.
64 Wait to make sure we get a tick so the mtime of the largefiles become valid.
65
65
66 $ sleep 1
66 $ sleep 1
67
67
68 A linear merge will update standins before performing the actual merge. It will
68 A linear merge will update standins before performing the actual merge. It will
69 do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and
69 do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and
70 update the corresponding standins.
70 update the corresponding standins.
71 Verify that it actually marks the clean files as clean in lfdirstate so
71 Verify that it actually marks the clean files as clean in lfdirstate so
72 we don't have to hash them again next time we update.
72 we don't have to hash them again next time we update.
73
73
74 $ hg up
74 $ hg up
75 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
75 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
76 updated to "f74e50bd9e55: #2"
76 updated to "f74e50bd9e55: #2"
77 1 other heads for branch "default"
77 1 other heads for branch "default"
78 $ hg debugdirstate --large --nodate
78 $ hg debugdirstate --large --nodate
79 n 644 7 set large1
79 n 644 7 set large1
80 n 644 13 set large2
80 n 644 13 set large2
81
81
82 Test that lfdirstate keeps track of last modification of largefiles and
82 Test that lfdirstate keeps track of last modification of largefiles and
83 prevents unnecessary hashing of content - also after linear/noop update
83 prevents unnecessary hashing of content - also after linear/noop update
84
84
85 $ sleep 1
85 $ sleep 1
86 $ hg st
86 $ hg st
87 $ hg debugdirstate --large --nodate
87 $ hg debugdirstate --large --nodate
88 n 644 7 set large1
88 n 644 7 set large1
89 n 644 13 set large2
89 n 644 13 set large2
90 $ hg up
90 $ hg up
91 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 updated to "f74e50bd9e55: #2"
92 updated to "f74e50bd9e55: #2"
93 1 other heads for branch "default"
93 1 other heads for branch "default"
94 $ hg debugdirstate --large --nodate
94 $ hg debugdirstate --large --nodate
95 n 644 7 set large1
95 n 644 7 set large1
96 n 644 13 set large2
96 n 644 13 set large2
97
97
98 Test that "hg merge" updates largefiles from "other" correctly
98 Test that "hg merge" updates largefiles from "other" correctly
99
99
100 (getting largefiles from "other" normally)
100 (getting largefiles from "other" normally)
101
101
102 $ hg status -A large1
102 $ hg status -A large1
103 C large1
103 C large1
104 $ cat large1
104 $ cat large1
105 large1
105 large1
106 $ cat .hglf/large1
106 $ cat .hglf/large1
107 4669e532d5b2c093a78eca010077e708a071bb64
107 4669e532d5b2c093a78eca010077e708a071bb64
108 $ hg merge --config debug.dirstate.delaywrite=2
108 $ hg merge --config debug.dirstate.delaywrite=2
109 getting changed largefiles
109 getting changed largefiles
110 1 largefiles updated, 0 removed
110 1 largefiles updated, 0 removed
111 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 (branch merge, don't forget to commit)
112 (branch merge, don't forget to commit)
113 $ hg status -A large1
113 $ hg status -A large1
114 M large1
114 M large1
115 $ cat large1
115 $ cat large1
116 large1 in #1
116 large1 in #1
117 $ cat .hglf/large1
117 $ cat .hglf/large1
118 58e24f733a964da346e2407a2bee99d9001184f5
118 58e24f733a964da346e2407a2bee99d9001184f5
119 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
119 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
120 -4669e532d5b2c093a78eca010077e708a071bb64
120 -4669e532d5b2c093a78eca010077e708a071bb64
121 +58e24f733a964da346e2407a2bee99d9001184f5
121 +58e24f733a964da346e2407a2bee99d9001184f5
122
122
123 (getting largefiles from "other" via conflict prompt)
123 (getting largefiles from "other" via conflict prompt)
124
124
125 $ hg update -q -C 2
125 $ hg update -q -C 2
126 $ echo 'large1 in #3' > large1
126 $ echo 'large1 in #3' > large1
127 $ echo 'normal1 in #3' > normal1
127 $ echo 'normal1 in #3' > normal1
128 $ hg commit -m '#3'
128 $ hg commit -m '#3'
129 $ cat .hglf/large1
129 $ cat .hglf/large1
130 e5bb990443d6a92aaf7223813720f7566c9dd05b
130 e5bb990443d6a92aaf7223813720f7566c9dd05b
131 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
131 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
132 > o
132 > o
133 > EOF
133 > EOF
134 largefile large1 has a merge conflict
134 largefile large1 has a merge conflict
135 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
135 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
136 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
136 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
137 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
137 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
138 merging normal1
138 merging normal1
139 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
139 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
140 getting changed largefiles
140 getting changed largefiles
141 1 largefiles updated, 0 removed
141 1 largefiles updated, 0 removed
142 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
142 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
143 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
143 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
144 [1]
144 [1]
145 $ hg status -A large1
145 $ hg status -A large1
146 M large1
146 M large1
147 $ cat large1
147 $ cat large1
148 large1 in #1
148 large1 in #1
149 $ cat .hglf/large1
149 $ cat .hglf/large1
150 58e24f733a964da346e2407a2bee99d9001184f5
150 58e24f733a964da346e2407a2bee99d9001184f5
151 $ rm normal1.orig
151 $ rm normal1.orig
152
152
153 (merge non-existing largefiles from "other" via conflict prompt -
153 (merge non-existing largefiles from "other" via conflict prompt -
154 make sure the following commit doesn't abort in a confusing way when trying to
154 make sure the following commit doesn't abort in a confusing way when trying to
155 mark the non-existing file as normal in lfdirstate)
155 mark the non-existing file as normal in lfdirstate)
156
156
157 $ mv .hg/largefiles/58e24f733a964da346e2407a2bee99d9001184f5 .
157 $ mv .hg/largefiles/58e24f733a964da346e2407a2bee99d9001184f5 .
158 $ hg update -q -C 3
158 $ hg update -q -C 3
159 $ hg merge --config largefiles.usercache=not --config debug.dirstate.delaywrite=2 --tool :local --config ui.interactive=True <<EOF
159 $ hg merge --config largefiles.usercache=not --config debug.dirstate.delaywrite=2 --tool :local --config ui.interactive=True <<EOF
160 > o
160 > o
161 > EOF
161 > EOF
162 largefile large1 has a merge conflict
162 largefile large1 has a merge conflict
163 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
163 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
164 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
164 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
165 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
165 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
166 getting changed largefiles
166 getting changed largefiles
167 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
167 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
168 0 largefiles updated, 0 removed
168 0 largefiles updated, 0 removed
169 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
169 0 files updated, 2 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 $ hg commit -m '1-2-3 testing' --config largefiles.usercache=not
171 $ hg commit -m '1-2-3 testing' --config largefiles.usercache=not
172 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from local store
172 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from local store
173 $ hg up -C . --config largefiles.usercache=not
173 $ hg up -C . --config largefiles.usercache=not
174 getting changed largefiles
174 getting changed largefiles
175 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
175 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
176 0 largefiles updated, 0 removed
176 0 largefiles updated, 0 removed
177 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 $ hg st large1
178 $ hg st large1
179 ! large1
179 ! large1
180 $ hg rollback -q
180 $ hg rollback -q
181 $ mv 58e24f733a964da346e2407a2bee99d9001184f5 .hg/largefiles/
181 $ mv 58e24f733a964da346e2407a2bee99d9001184f5 .hg/largefiles/
182
182
183 Test that "hg revert -r REV" updates largefiles from "REV" correctly
183 Test that "hg revert -r REV" updates largefiles from "REV" correctly
184
184
185 $ hg update -q -C 3
185 $ hg update -q -C 3
186 $ hg status -A large1
186 $ hg status -A large1
187 C large1
187 C large1
188 $ cat large1
188 $ cat large1
189 large1 in #3
189 large1 in #3
190 $ cat .hglf/large1
190 $ cat .hglf/large1
191 e5bb990443d6a92aaf7223813720f7566c9dd05b
191 e5bb990443d6a92aaf7223813720f7566c9dd05b
192 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
192 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
193 -4669e532d5b2c093a78eca010077e708a071bb64
193 -4669e532d5b2c093a78eca010077e708a071bb64
194 +58e24f733a964da346e2407a2bee99d9001184f5
194 +58e24f733a964da346e2407a2bee99d9001184f5
195 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
195 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
196 $ hg status -A large1
196 $ hg status -A large1
197 M large1
197 M large1
198 $ cat large1
198 $ cat large1
199 large1 in #1
199 large1 in #1
200 $ cat .hglf/large1
200 $ cat .hglf/large1
201 58e24f733a964da346e2407a2bee99d9001184f5
201 58e24f733a964da346e2407a2bee99d9001184f5
202
202
203 Test that "hg rollback" restores status of largefiles correctly
203 Test that "hg rollback" restores status of largefiles correctly
204
204
205 $ hg update -C -q
205 $ hg update -C -q
206 $ hg remove large1
206 $ hg remove large1
207 $ test -f .hglf/large1
207 $ test -f .hglf/large1
208 [1]
208 [1]
209 $ hg forget large2
209 $ hg forget large2
210 $ test -f .hglf/large2
210 $ test -f .hglf/large2
211 [1]
211 [1]
212 $ echo largeX > largeX
212 $ echo largeX > largeX
213 $ hg add --large largeX
213 $ hg add --large largeX
214 $ cat .hglf/largeX
214 $ cat .hglf/largeX
215
215
216 $ hg commit -m 'will be rollback-ed soon'
216 $ hg commit -m 'will be rollback-ed soon'
217 $ echo largeY > largeY
217 $ echo largeY > largeY
218 $ hg add --large largeY
218 $ hg add --large largeY
219
219
220 $ hg status -A large1
220 $ hg status -A large1
221 large1: $ENOENT$
221 large1: $ENOENT$
222
222
223 $ hg status -A large2
223 $ hg status -A large2
224 ? large2
224 ? large2
225 $ hg status -A largeX
225 $ hg status -A largeX
226 C largeX
226 C largeX
227 $ hg status -A largeY
227 $ hg status -A largeY
228 A largeY
228 A largeY
229 $ hg rollback
229 $ hg rollback
230 repository tip rolled back to revision 3 (undo commit)
230 repository tip rolled back to revision 3 (undo commit)
231 working directory now based on revision 3
231 working directory now based on revision 3
232 $ hg status -A large1
232 $ hg status -A large1
233 R large1
233 R large1
234 $ test -f .hglf/large1
234 $ test -f .hglf/large1
235 [1]
235 [1]
236 $ hg status -A large2
236 $ hg status -A large2
237 R large2
237 R large2
238 $ test -f .hglf/large2
238 $ test -f .hglf/large2
239 [1]
239 [1]
240 $ hg status -A largeX
240 $ hg status -A largeX
241 A largeX
241 A largeX
242 $ cat .hglf/largeX
242 $ cat .hglf/largeX
243
243
244 $ hg status -A largeY
244 $ hg status -A largeY
245 ? largeY
245 ? largeY
246 $ test -f .hglf/largeY
246 $ test -f .hglf/largeY
247 [1]
247 [1]
248 $ rm largeY
248 $ rm largeY
249
249
250 Test that "hg rollback" restores standins correctly
250 Test that "hg rollback" restores standins correctly
251
251
252 $ hg commit -m 'will be rollback-ed soon'
252 $ hg commit -m 'will be rollback-ed soon'
253 $ hg update -q -C 2
253 $ hg update -q -C 2
254 $ cat large1
254 $ cat large1
255 large1
255 large1
256 $ cat .hglf/large1
256 $ cat .hglf/large1
257 4669e532d5b2c093a78eca010077e708a071bb64
257 4669e532d5b2c093a78eca010077e708a071bb64
258 $ cat large2
258 $ cat large2
259 large2 in #2
259 large2 in #2
260 $ cat .hglf/large2
260 $ cat .hglf/large2
261 3cfce6277e7668985707b6887ce56f9f62f6ccd9
261 3cfce6277e7668985707b6887ce56f9f62f6ccd9
262
262
263 $ hg rollback -q -f
263 $ hg rollback -q -f
264 $ cat large1
264 $ cat large1
265 large1
265 large1
266 $ cat .hglf/large1
266 $ cat .hglf/large1
267 4669e532d5b2c093a78eca010077e708a071bb64
267 4669e532d5b2c093a78eca010077e708a071bb64
268 $ cat large2
268 $ cat large2
269 large2 in #2
269 large2 in #2
270 $ cat .hglf/large2
270 $ cat .hglf/large2
271 3cfce6277e7668985707b6887ce56f9f62f6ccd9
271 3cfce6277e7668985707b6887ce56f9f62f6ccd9
272
272
273 (rollback the parent of the working directory, when the parent of it
273 (rollback the parent of the working directory, when the parent of it
274 is not branch-tip)
274 is not branch-tip)
275
275
276 $ hg update -q -C 1
276 $ hg update -q -C 1
277 $ cat .hglf/large1
277 $ cat .hglf/large1
278 58e24f733a964da346e2407a2bee99d9001184f5
278 58e24f733a964da346e2407a2bee99d9001184f5
279 $ cat .hglf/large2
279 $ cat .hglf/large2
280 1deebade43c8c498a3c8daddac0244dc55d1331d
280 1deebade43c8c498a3c8daddac0244dc55d1331d
281
281
282 $ echo normalX > normalX
282 $ echo normalX > normalX
283 $ hg add normalX
283 $ hg add normalX
284 $ hg commit -m 'will be rollback-ed soon'
284 $ hg commit -m 'will be rollback-ed soon'
285 $ hg rollback -q
285 $ hg rollback -q
286
286
287 $ cat .hglf/large1
287 $ cat .hglf/large1
288 58e24f733a964da346e2407a2bee99d9001184f5
288 58e24f733a964da346e2407a2bee99d9001184f5
289 $ cat .hglf/large2
289 $ cat .hglf/large2
290 1deebade43c8c498a3c8daddac0244dc55d1331d
290 1deebade43c8c498a3c8daddac0244dc55d1331d
291 $ rm normalX
291 $ rm normalX
292
292
293 Test that "hg status" shows status of largefiles correctly just after
293 Test that "hg status" shows status of largefiles correctly just after
294 automated commit like rebase/transplant
294 automated commit like rebase/transplant
295
295
296 $ cat >> .hg/hgrc <<EOF
296 $ cat >> .hg/hgrc <<EOF
297 > [extensions]
297 > [extensions]
298 > rebase =
298 > rebase =
299 > strip =
299 > strip =
300 > transplant =
300 > transplant =
301 > EOF
301 > EOF
302 $ hg update -q -C 1
302 $ hg update -q -C 1
303 $ hg remove large1
303 $ hg remove large1
304 $ echo largeX > largeX
304 $ echo largeX > largeX
305 $ hg add --large largeX
305 $ hg add --large largeX
306 $ hg commit -m '#4'
306 $ hg commit -m '#4'
307
307
308 $ hg rebase -s 1 -d 2 --keep
308 $ hg rebase -s 1 -d 2 --keep
309 rebasing 1:72518492caa6 "#1"
309 rebasing 1:72518492caa6 "#1"
310 rebasing 4:07d6153b5c04 "#4" (tip)
310 rebasing 4:07d6153b5c04 "#4" (tip)
311
311
312 $ hg status -A large1
312 $ hg status -A large1
313 large1: $ENOENT$
313 large1: $ENOENT$
314
314
315 $ hg status -A largeX
315 $ hg status -A largeX
316 C largeX
316 C largeX
317 $ hg strip -q 5
317 $ hg strip -q 5
318
318
319 $ hg update -q -C 2
319 $ hg update -q -C 2
320 $ hg transplant -q 1 4
320 $ hg transplant -q 1 4
321
321
322 $ hg status -A large1
322 $ hg status -A large1
323 large1: $ENOENT$
323 large1: $ENOENT$
324
324
325 $ hg status -A largeX
325 $ hg status -A largeX
326 C largeX
326 C largeX
327 $ hg strip -q 5
327 $ hg strip -q 5
328
328
329 $ hg update -q -C 2
329 $ hg update -q -C 2
330 $ hg transplant -q --merge 1 --merge 4
330 $ hg transplant -q --merge 1 --merge 4
331
331
332 $ hg status -A large1
332 $ hg status -A large1
333 large1: $ENOENT$
333 large1: $ENOENT$
334
334
335 $ hg status -A largeX
335 $ hg status -A largeX
336 C largeX
336 C largeX
337 $ hg strip -q 5
337 $ hg strip -q 5
338
338
339 Test that linear merge can detect modification (and conflict) correctly
339 Test that linear merge can detect modification (and conflict) correctly
340
340
341 (linear merge without conflict)
341 (linear merge without conflict)
342
342
343 $ echo 'large2 for linear merge (no conflict)' > large2
343 $ echo 'large2 for linear merge (no conflict)' > large2
344 $ hg update 3 --config debug.dirstate.delaywrite=2
344 $ hg update 3 --config debug.dirstate.delaywrite=2
345 getting changed largefiles
345 getting changed largefiles
346 1 largefiles updated, 0 removed
346 1 largefiles updated, 0 removed
347 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
347 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
348 $ hg status -A large2
348 $ hg status -A large2
349 M large2
349 M large2
350 $ cat large2
350 $ cat large2
351 large2 for linear merge (no conflict)
351 large2 for linear merge (no conflict)
352 $ cat .hglf/large2
352 $ cat .hglf/large2
353 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
353 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
354
354
355 (linear merge with conflict, choosing "other")
355 (linear merge with conflict, choosing "other")
356
356
357 $ hg update -q -C 2
357 $ hg update -q -C 2
358 $ echo 'large1 for linear merge (conflict)' > large1
358 $ echo 'large1 for linear merge (conflict)' > large1
359 $ hg update 3 --config ui.interactive=True <<EOF
359 $ hg update 3 --config ui.interactive=True <<EOF
360 > o
360 > o
361 > EOF
361 > EOF
362 largefile large1 has a merge conflict
362 largefile large1 has a merge conflict
363 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
363 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
364 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
364 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
365 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
365 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
366 getting changed largefiles
366 getting changed largefiles
367 1 largefiles updated, 0 removed
367 1 largefiles updated, 0 removed
368 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
368 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
369 $ hg status -A large1
369 $ hg status -A large1
370 C large1
370 C large1
371 $ cat large1
371 $ cat large1
372 large1 in #3
372 large1 in #3
373 $ cat .hglf/large1
373 $ cat .hglf/large1
374 e5bb990443d6a92aaf7223813720f7566c9dd05b
374 e5bb990443d6a92aaf7223813720f7566c9dd05b
375
375
376 (linear merge with conflict, choosing "local")
376 (linear merge with conflict, choosing "local")
377
377
378 $ hg update -q -C 2
378 $ hg update -q -C 2
379 $ echo 'large1 for linear merge (conflict)' > large1
379 $ echo 'large1 for linear merge (conflict)' > large1
380 $ hg update 3 --config debug.dirstate.delaywrite=2
380 $ hg update 3 --config debug.dirstate.delaywrite=2
381 largefile large1 has a merge conflict
381 largefile large1 has a merge conflict
382 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
382 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
383 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
383 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
384 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
384 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
385 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
385 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
386 $ hg status -A large1
386 $ hg status -A large1
387 M large1
387 M large1
388 $ cat large1
388 $ cat large1
389 large1 for linear merge (conflict)
389 large1 for linear merge (conflict)
390 $ cat .hglf/large1
390 $ cat .hglf/large1
391 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
391 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
392
392
393 Test a linear merge to a revision containing same-name normal file
393 Test a linear merge to a revision containing same-name normal file
394
394
395 $ hg update -q -C 3
395 $ hg update -q -C 3
396 $ hg remove large2
396 $ hg remove large2
397 $ echo 'large2 as normal file' > large2
397 $ echo 'large2 as normal file' > large2
398 $ hg add large2
398 $ hg add large2
399 $ echo 'large3 as normal file' > large3
399 $ echo 'large3 as normal file' > large3
400 $ hg add large3
400 $ hg add large3
401 $ hg commit -m '#5'
401 $ hg commit -m '#5'
402 $ hg manifest
402 $ hg manifest
403 .hglf/large1
403 .hglf/large1
404 large2
404 large2
405 large3
405 large3
406 normal1
406 normal1
407
407
408 (modified largefile is already switched to normal)
408 (modified largefile is already switched to normal)
409
409
410 $ hg update -q -C 2
410 $ hg update -q -C 2
411 $ echo 'modified large2 for linear merge' > large2
411 $ echo 'modified large2 for linear merge' > large2
412 $ hg update -q 5
412 $ hg update -q 5
413 remote turned local largefile large2 into a normal file
413 remote turned local largefile large2 into a normal file
414 keep (l)argefile or use (n)ormal file? l
414 keep (l)argefile or use (n)ormal file? l
415 $ hg debugdirstate --nodates | grep large2
415 $ hg debugdirstate --no-dates | grep large2
416 a 0 -1 unset .hglf/large2
416 a 0 -1 unset .hglf/large2
417 r 0 0 set large2
417 r 0 0 set large2
418 $ hg status -A large2
418 $ hg status -A large2
419 A large2
419 A large2
420 $ cat large2
420 $ cat large2
421 modified large2 for linear merge
421 modified large2 for linear merge
422
422
423 (added largefile is already committed as normal)
423 (added largefile is already committed as normal)
424
424
425 $ hg update -q -C 2
425 $ hg update -q -C 2
426 $ echo 'large3 as large file for linear merge' > large3
426 $ echo 'large3 as large file for linear merge' > large3
427 $ hg add --large large3
427 $ hg add --large large3
428 $ hg update -q 5
428 $ hg update -q 5
429 remote turned local largefile large3 into a normal file
429 remote turned local largefile large3 into a normal file
430 keep (l)argefile or use (n)ormal file? l
430 keep (l)argefile or use (n)ormal file? l
431 $ hg debugdirstate --nodates | grep large3
431 $ hg debugdirstate --no-dates | grep large3
432 a 0 -1 unset .hglf/large3
432 a 0 -1 unset .hglf/large3
433 r 0 0 set large3
433 r 0 0 set large3
434 $ hg status -A large3
434 $ hg status -A large3
435 A large3
435 A large3
436 $ cat large3
436 $ cat large3
437 large3 as large file for linear merge
437 large3 as large file for linear merge
438 $ rm -f large3 .hglf/large3
438 $ rm -f large3 .hglf/large3
439
439
440 Test that the internal linear merging works correctly
440 Test that the internal linear merging works correctly
441 (both heads are stripped to keep pairing of revision number and commit log)
441 (both heads are stripped to keep pairing of revision number and commit log)
442
442
443 $ hg update -q -C 2
443 $ hg update -q -C 2
444 $ hg strip 3 4
444 $ hg strip 3 4
445 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg
445 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg
446 $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP
446 $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP
447
447
448 (internal linear merging at "hg pull --update")
448 (internal linear merging at "hg pull --update")
449
449
450 $ echo 'large1 for linear merge (conflict)' > large1
450 $ echo 'large1 for linear merge (conflict)' > large1
451 $ echo 'large2 for linear merge (conflict with normal file)' > large2
451 $ echo 'large2 for linear merge (conflict with normal file)' > large2
452 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
452 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
453 pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg
453 pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg
454 searching for changes
454 searching for changes
455 adding changesets
455 adding changesets
456 adding manifests
456 adding manifests
457 adding file changes
457 adding file changes
458 added 3 changesets with 5 changes to 5 files
458 added 3 changesets with 5 changes to 5 files
459 new changesets 9530e27857f7:d65e59e952a9 (3 drafts)
459 new changesets 9530e27857f7:d65e59e952a9 (3 drafts)
460 remote turned local largefile large2 into a normal file
460 remote turned local largefile large2 into a normal file
461 keep (l)argefile or use (n)ormal file? l
461 keep (l)argefile or use (n)ormal file? l
462 largefile large1 has a merge conflict
462 largefile large1 has a merge conflict
463 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
463 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
464 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
464 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
465 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
465 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
466 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
466 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
467 updated to "d65e59e952a9: #5"
467 updated to "d65e59e952a9: #5"
468 1 other heads for branch "default"
468 1 other heads for branch "default"
469
469
470 $ hg status -A large1
470 $ hg status -A large1
471 M large1
471 M large1
472 $ cat large1
472 $ cat large1
473 large1 for linear merge (conflict)
473 large1 for linear merge (conflict)
474 $ cat .hglf/large1
474 $ cat .hglf/large1
475 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
475 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
476 $ hg status -A large2
476 $ hg status -A large2
477 A large2
477 A large2
478 $ cat large2
478 $ cat large2
479 large2 for linear merge (conflict with normal file)
479 large2 for linear merge (conflict with normal file)
480 $ cat .hglf/large2
480 $ cat .hglf/large2
481 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
481 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
482
482
483 (internal linear merging at "hg unbundle --update")
483 (internal linear merging at "hg unbundle --update")
484
484
485 $ hg update -q -C 2
485 $ hg update -q -C 2
486 $ hg rollback -q
486 $ hg rollback -q
487
487
488 $ echo 'large1 for linear merge (conflict)' > large1
488 $ echo 'large1 for linear merge (conflict)' > large1
489 $ echo 'large2 for linear merge (conflict with normal file)' > large2
489 $ echo 'large2 for linear merge (conflict with normal file)' > large2
490 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
490 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
491 adding changesets
491 adding changesets
492 adding manifests
492 adding manifests
493 adding file changes
493 adding file changes
494 added 3 changesets with 5 changes to 5 files
494 added 3 changesets with 5 changes to 5 files
495 new changesets 9530e27857f7:d65e59e952a9 (3 drafts)
495 new changesets 9530e27857f7:d65e59e952a9 (3 drafts)
496 remote turned local largefile large2 into a normal file
496 remote turned local largefile large2 into a normal file
497 keep (l)argefile or use (n)ormal file? l
497 keep (l)argefile or use (n)ormal file? l
498 largefile large1 has a merge conflict
498 largefile large1 has a merge conflict
499 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
499 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
500 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
500 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
501 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
501 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
502 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
502 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
503 updated to "d65e59e952a9: #5"
503 updated to "d65e59e952a9: #5"
504 1 other heads for branch "default"
504 1 other heads for branch "default"
505
505
506 $ hg status -A large1
506 $ hg status -A large1
507 M large1
507 M large1
508 $ cat large1
508 $ cat large1
509 large1 for linear merge (conflict)
509 large1 for linear merge (conflict)
510 $ cat .hglf/large1
510 $ cat .hglf/large1
511 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
511 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
512 $ hg status -A large2
512 $ hg status -A large2
513 A large2
513 A large2
514 $ cat large2
514 $ cat large2
515 large2 for linear merge (conflict with normal file)
515 large2 for linear merge (conflict with normal file)
516 $ cat .hglf/large2
516 $ cat .hglf/large2
517 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
517 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
518
518
519 (internal linear merging in subrepo at "hg update")
519 (internal linear merging in subrepo at "hg update")
520
520
521 $ cd ..
521 $ cd ..
522 $ hg init subparent
522 $ hg init subparent
523 $ cd subparent
523 $ cd subparent
524
524
525 $ hg clone -q -u 2 ../repo sub
525 $ hg clone -q -u 2 ../repo sub
526 $ cat > .hgsub <<EOF
526 $ cat > .hgsub <<EOF
527 > sub = sub
527 > sub = sub
528 > EOF
528 > EOF
529 $ hg add .hgsub
529 $ hg add .hgsub
530 $ hg commit -m '#0@parent'
530 $ hg commit -m '#0@parent'
531 $ cat .hgsubstate
531 $ cat .hgsubstate
532 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
532 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
533 $ hg -R sub update -q
533 $ hg -R sub update -q
534 $ hg commit -m '#1@parent'
534 $ hg commit -m '#1@parent'
535 $ cat .hgsubstate
535 $ cat .hgsubstate
536 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
536 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
537 $ hg update -q 0
537 $ hg update -q 0
538
538
539 $ echo 'large1 for linear merge (conflict)' > sub/large1
539 $ echo 'large1 for linear merge (conflict)' > sub/large1
540 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
540 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
541 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
541 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
542 > m
542 > m
543 > r
543 > r
544 > l
544 > l
545 > l
545 > l
546 > EOF
546 > EOF
547 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
547 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
548 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
548 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
549 subrepository sources for sub differ (in checked out version)
549 subrepository sources for sub differ (in checked out version)
550 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
550 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
551 remote turned local largefile large2 into a normal file
551 remote turned local largefile large2 into a normal file
552 keep (l)argefile or use (n)ormal file? l
552 keep (l)argefile or use (n)ormal file? l
553 largefile large1 has a merge conflict
553 largefile large1 has a merge conflict
554 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
554 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
555 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
555 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
556 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
556 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
557 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
557 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
558 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
558 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
559
559
560 $ hg -R sub status -A sub/large1
560 $ hg -R sub status -A sub/large1
561 M sub/large1
561 M sub/large1
562 $ cat sub/large1
562 $ cat sub/large1
563 large1 for linear merge (conflict)
563 large1 for linear merge (conflict)
564 $ cat sub/.hglf/large1
564 $ cat sub/.hglf/large1
565 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
565 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
566 $ hg -R sub status -A sub/large2
566 $ hg -R sub status -A sub/large2
567 A sub/large2
567 A sub/large2
568 $ cat sub/large2
568 $ cat sub/large2
569 large2 for linear merge (conflict with normal file)
569 large2 for linear merge (conflict with normal file)
570 $ cat sub/.hglf/large2
570 $ cat sub/.hglf/large2
571 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
571 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
572
572
573 $ cd ..
573 $ cd ..
574 $ cd repo
574 $ cd repo
575
575
576 Test that rebase updates largefiles in the working directory even if
576 Test that rebase updates largefiles in the working directory even if
577 it is aborted by conflict.
577 it is aborted by conflict.
578
578
579 $ hg update -q -C 3
579 $ hg update -q -C 3
580 $ cat .hglf/large1
580 $ cat .hglf/large1
581 e5bb990443d6a92aaf7223813720f7566c9dd05b
581 e5bb990443d6a92aaf7223813720f7566c9dd05b
582 $ cat large1
582 $ cat large1
583 large1 in #3
583 large1 in #3
584 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
584 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
585 > o
585 > o
586 > EOF
586 > EOF
587 rebasing 1:72518492caa6 "#1"
587 rebasing 1:72518492caa6 "#1"
588 largefile large1 has a merge conflict
588 largefile large1 has a merge conflict
589 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
589 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
590 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
590 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
591 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
591 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
592 merging normal1
592 merging normal1
593 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
593 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
594 unresolved conflicts (see hg resolve, then hg rebase --continue)
594 unresolved conflicts (see hg resolve, then hg rebase --continue)
595 [1]
595 [1]
596 $ cat .hglf/large1
596 $ cat .hglf/large1
597 58e24f733a964da346e2407a2bee99d9001184f5
597 58e24f733a964da346e2407a2bee99d9001184f5
598 $ cat large1
598 $ cat large1
599 large1 in #1
599 large1 in #1
600 $ rm normal1.orig
600 $ rm normal1.orig
601
601
602 Test that rebase updates standins for manually modified largefiles at
602 Test that rebase updates standins for manually modified largefiles at
603 the 1st commit of resuming.
603 the 1st commit of resuming.
604
604
605 $ echo "manually modified before 'hg rebase --continue'" > large1
605 $ echo "manually modified before 'hg rebase --continue'" > large1
606 $ hg resolve -m normal1
606 $ hg resolve -m normal1
607 (no more unresolved files)
607 (no more unresolved files)
608 continue: hg rebase --continue
608 continue: hg rebase --continue
609 $ hg rebase --continue --config ui.interactive=True <<EOF
609 $ hg rebase --continue --config ui.interactive=True <<EOF
610 > c
610 > c
611 > EOF
611 > EOF
612 rebasing 1:72518492caa6 "#1"
612 rebasing 1:72518492caa6 "#1"
613 rebasing 4:07d6153b5c04 "#4"
613 rebasing 4:07d6153b5c04 "#4"
614 file '.hglf/large1' was deleted in other [source] but was modified in local [dest].
614 file '.hglf/large1' was deleted in other [source] but was modified in local [dest].
615 What do you want to do?
615 What do you want to do?
616 use (c)hanged version, (d)elete, or leave (u)nresolved? c
616 use (c)hanged version, (d)elete, or leave (u)nresolved? c
617
617
618 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
618 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
619 -e5bb990443d6a92aaf7223813720f7566c9dd05b
619 -e5bb990443d6a92aaf7223813720f7566c9dd05b
620 +8a4f783556e7dea21139ca0466eafce954c75c13
620 +8a4f783556e7dea21139ca0466eafce954c75c13
621 $ rm -f large1
621 $ rm -f large1
622 $ hg update -q -C tip
622 $ hg update -q -C tip
623 $ cat large1
623 $ cat large1
624 manually modified before 'hg rebase --continue'
624 manually modified before 'hg rebase --continue'
625
625
626 Test that transplant updates largefiles, of which standins are safely
626 Test that transplant updates largefiles, of which standins are safely
627 changed, even if it is aborted by conflict of other.
627 changed, even if it is aborted by conflict of other.
628
628
629 $ hg update -q -C 5
629 $ hg update -q -C 5
630 $ cat .hglf/large1
630 $ cat .hglf/large1
631 e5bb990443d6a92aaf7223813720f7566c9dd05b
631 e5bb990443d6a92aaf7223813720f7566c9dd05b
632 $ cat large1
632 $ cat large1
633 large1 in #3
633 large1 in #3
634 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
634 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
635 +fa44618ea25181aff4f48b70428294790cec9f61
635 +fa44618ea25181aff4f48b70428294790cec9f61
636 $ hg transplant 4
636 $ hg transplant 4
637 applying 07d6153b5c04
637 applying 07d6153b5c04
638 patching file .hglf/large1
638 patching file .hglf/large1
639 Hunk #1 FAILED at 0
639 Hunk #1 FAILED at 0
640 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
640 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
641 patch failed to apply
641 patch failed to apply
642 abort: fix up the working directory and run hg transplant --continue
642 abort: fix up the working directory and run hg transplant --continue
643 [255]
643 [255]
644 $ hg status -A large1
644 $ hg status -A large1
645 C large1
645 C large1
646 $ cat .hglf/large1
646 $ cat .hglf/large1
647 e5bb990443d6a92aaf7223813720f7566c9dd05b
647 e5bb990443d6a92aaf7223813720f7566c9dd05b
648 $ cat large1
648 $ cat large1
649 large1 in #3
649 large1 in #3
650 $ hg status -A largeX
650 $ hg status -A largeX
651 A largeX
651 A largeX
652 $ cat .hglf/largeX
652 $ cat .hglf/largeX
653 fa44618ea25181aff4f48b70428294790cec9f61
653 fa44618ea25181aff4f48b70428294790cec9f61
654 $ cat largeX
654 $ cat largeX
655 largeX
655 largeX
656
656
657 Test that transplant updates standins for manually modified largefiles
657 Test that transplant updates standins for manually modified largefiles
658 at the 1st commit of resuming.
658 at the 1st commit of resuming.
659
659
660 $ echo "manually modified before 'hg transplant --continue'" > large1
660 $ echo "manually modified before 'hg transplant --continue'" > large1
661 $ hg transplant --continue
661 $ hg transplant --continue
662 07d6153b5c04 transplanted as f1bf30eb88cc
662 07d6153b5c04 transplanted as f1bf30eb88cc
663 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
663 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
664 -e5bb990443d6a92aaf7223813720f7566c9dd05b
664 -e5bb990443d6a92aaf7223813720f7566c9dd05b
665 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
665 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
666 $ rm -f large1
666 $ rm -f large1
667 $ hg update -q -C tip
667 $ hg update -q -C tip
668 $ cat large1
668 $ cat large1
669 manually modified before 'hg transplant --continue'
669 manually modified before 'hg transplant --continue'
670
670
671 Test that "hg status" doesn't show removal of largefiles not managed
671 Test that "hg status" doesn't show removal of largefiles not managed
672 in the target context.
672 in the target context.
673
673
674 $ hg update -q -C 4
674 $ hg update -q -C 4
675 $ hg remove largeX
675 $ hg remove largeX
676 $ hg status -A largeX
676 $ hg status -A largeX
677 R largeX
677 R largeX
678 $ hg status -A --rev '.^1' largeX
678 $ hg status -A --rev '.^1' largeX
679
679
680 #if execbit
680 #if execbit
681
681
682 Test that "hg status" against revisions other than parent notices exec
682 Test that "hg status" against revisions other than parent notices exec
683 bit changes of largefiles.
683 bit changes of largefiles.
684
684
685 $ hg update -q -C 4
685 $ hg update -q -C 4
686
686
687 (the case that large2 doesn't have exec bit in the target context but
687 (the case that large2 doesn't have exec bit in the target context but
688 in the working context)
688 in the working context)
689
689
690 $ chmod +x large2
690 $ chmod +x large2
691 $ hg status -A --rev 0 large2
691 $ hg status -A --rev 0 large2
692 M large2
692 M large2
693 $ hg commit -m 'chmod +x large2'
693 $ hg commit -m 'chmod +x large2'
694
694
695 (the case that large2 has exec bit in the target context but not in
695 (the case that large2 has exec bit in the target context but not in
696 the working context)
696 the working context)
697
697
698 $ echo dummy > dummy
698 $ echo dummy > dummy
699 $ hg add dummy
699 $ hg add dummy
700 $ hg commit -m 'revision for separation'
700 $ hg commit -m 'revision for separation'
701 $ chmod -x large2
701 $ chmod -x large2
702 $ hg status -A --rev '.^1' large2
702 $ hg status -A --rev '.^1' large2
703 M large2
703 M large2
704
704
705 #else
705 #else
706
706
707 Test that "hg status" against revisions other than parent ignores exec
707 Test that "hg status" against revisions other than parent ignores exec
708 bit correctly on the platform being unaware of it.
708 bit correctly on the platform being unaware of it.
709
709
710 $ hg update -q -C 4
710 $ hg update -q -C 4
711
711
712 $ cat > ../exec-bit.patch <<EOF
712 $ cat > ../exec-bit.patch <<EOF
713 > # HG changeset patch
713 > # HG changeset patch
714 > # User test
714 > # User test
715 > # Date 0 0
715 > # Date 0 0
716 > # Thu Jan 01 00:00:00 1970 +0000
716 > # Thu Jan 01 00:00:00 1970 +0000
717 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
717 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
718 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
718 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
719 > chmod +x large2
719 > chmod +x large2
720 >
720 >
721 > diff --git a/.hglf/large2 b/.hglf/large2
721 > diff --git a/.hglf/large2 b/.hglf/large2
722 > old mode 100644
722 > old mode 100644
723 > new mode 100755
723 > new mode 100755
724 > EOF
724 > EOF
725 $ hg import --exact --bypass ../exec-bit.patch
725 $ hg import --exact --bypass ../exec-bit.patch
726 applying ../exec-bit.patch
726 applying ../exec-bit.patch
727 $ hg status -A --rev tip large2
727 $ hg status -A --rev tip large2
728 C large2
728 C large2
729
729
730 #endif
730 #endif
731
731
732 The fileset revset is evaluated for each revision, instead of once on wdir(),
732 The fileset revset is evaluated for each revision, instead of once on wdir(),
733 and then patterns matched on each revision. Here, no exec bits are set in
733 and then patterns matched on each revision. Here, no exec bits are set in
734 wdir(), but a matching revision is detected.
734 wdir(), but a matching revision is detected.
735
735
736 (Teach large2 is not an executable. Maybe this is a bug of largefiles.)
736 (Teach large2 is not an executable. Maybe this is a bug of largefiles.)
737 #if execbit
737 #if execbit
738 $ chmod -x .hglf/large2
738 $ chmod -x .hglf/large2
739 #endif
739 #endif
740
740
741 $ hg files 'set:exec()'
741 $ hg files 'set:exec()'
742 [1]
742 [1]
743 $ hg log -qr 'file("set:exec()")'
743 $ hg log -qr 'file("set:exec()")'
744 9:be1b433a65b1
744 9:be1b433a65b1
745
745
746 Test a fatal error interrupting an update. Verify that status report dirty
746 Test a fatal error interrupting an update. Verify that status report dirty
747 files correctly after an interrupted update. Also verify that checking all
747 files correctly after an interrupted update. Also verify that checking all
748 hashes reveals it isn't clean.
748 hashes reveals it isn't clean.
749
749
750 Start with clean dirstates:
750 Start with clean dirstates:
751 $ hg up --quiet --clean --rev "8^"
751 $ hg up --quiet --clean --rev "8^"
752 $ sleep 1
752 $ sleep 1
753 $ hg st
753 $ hg st
754 Update standins without updating largefiles - large1 is modified and largeX is
754 Update standins without updating largefiles - large1 is modified and largeX is
755 added:
755 added:
756 $ cat << EOF > ../crashupdatelfiles.py
756 $ cat << EOF > ../crashupdatelfiles.py
757 > import hgext.largefiles.lfutil
757 > import hgext.largefiles.lfutil
758 > def getlfilestoupdate(oldstandins, newstandins):
758 > def getlfilestoupdate(oldstandins, newstandins):
759 > raise SystemExit(7)
759 > raise SystemExit(7)
760 > hgext.largefiles.lfutil.getlfilestoupdate = getlfilestoupdate
760 > hgext.largefiles.lfutil.getlfilestoupdate = getlfilestoupdate
761 > EOF
761 > EOF
762 $ hg up -Cr "8" --config extensions.crashupdatelfiles=../crashupdatelfiles.py
762 $ hg up -Cr "8" --config extensions.crashupdatelfiles=../crashupdatelfiles.py
763 [7]
763 [7]
764 Check large1 content and status ... and that update will undo modifications:
764 Check large1 content and status ... and that update will undo modifications:
765 $ cat large1
765 $ cat large1
766 large1 in #3
766 large1 in #3
767 $ hg st
767 $ hg st
768 M large1
768 M large1
769 ! largeX
769 ! largeX
770 $ hg up -Cr .
770 $ hg up -Cr .
771 getting changed largefiles
771 getting changed largefiles
772 2 largefiles updated, 0 removed
772 2 largefiles updated, 0 removed
773 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
773 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
774 $ cat large1
774 $ cat large1
775 manually modified before 'hg transplant --continue'
775 manually modified before 'hg transplant --continue'
776 $ hg st
776 $ hg st
777 Force largefiles rehashing and check that all changes have been caught by
777 Force largefiles rehashing and check that all changes have been caught by
778 status and update:
778 status and update:
779 $ rm .hg/largefiles/dirstate
779 $ rm .hg/largefiles/dirstate
780 $ hg st
780 $ hg st
781
781
782 $ cd ..
782 $ cd ..
783
783
784 Test that "hg convert" avoids copying largefiles from the working
784 Test that "hg convert" avoids copying largefiles from the working
785 directory into store, because "hg convert" doesn't update largefiles
785 directory into store, because "hg convert" doesn't update largefiles
786 in the working directory (removing files under ".cache/largefiles"
786 in the working directory (removing files under ".cache/largefiles"
787 forces "hg convert" to copy corresponding largefiles)
787 forces "hg convert" to copy corresponding largefiles)
788
788
789 $ cat >> $HGRCPATH <<EOF
789 $ cat >> $HGRCPATH <<EOF
790 > [extensions]
790 > [extensions]
791 > convert =
791 > convert =
792 > EOF
792 > EOF
793
793
794 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
794 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
795 $ hg convert -q repo repo.converted
795 $ hg convert -q repo repo.converted
@@ -1,1889 +1,1889 b''
1 This file used to contains all largefile tests.
1 This file used to contains all largefile tests.
2 Do not add any new tests in this file as it his already far too long to run.
2 Do not add any new tests in this file as it his already far too long to run.
3
3
4 It contains all the testing of the basic concepts of large file in a single block.
4 It contains all the testing of the basic concepts of large file in a single block.
5
5
6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
7 $ mkdir "${USERCACHE}"
7 $ mkdir "${USERCACHE}"
8 $ cat >> $HGRCPATH <<EOF
8 $ cat >> $HGRCPATH <<EOF
9 > [extensions]
9 > [extensions]
10 > largefiles=
10 > largefiles=
11 > purge=
11 > purge=
12 > rebase=
12 > rebase=
13 > transplant=
13 > transplant=
14 > [phases]
14 > [phases]
15 > publish=False
15 > publish=False
16 > [largefiles]
16 > [largefiles]
17 > minsize=2
17 > minsize=2
18 > patterns=glob:**.dat
18 > patterns=glob:**.dat
19 > usercache=${USERCACHE}
19 > usercache=${USERCACHE}
20 > [hooks]
20 > [hooks]
21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
22 > EOF
22 > EOF
23
23
24 Create the repo with a couple of revisions of both large and normal
24 Create the repo with a couple of revisions of both large and normal
25 files.
25 files.
26 Test status and dirstate of largefiles and that summary output is correct.
26 Test status and dirstate of largefiles and that summary output is correct.
27
27
28 $ hg init a
28 $ hg init a
29 $ cd a
29 $ cd a
30 $ mkdir sub
30 $ mkdir sub
31 $ echo normal1 > normal1
31 $ echo normal1 > normal1
32 $ echo normal2 > sub/normal2
32 $ echo normal2 > sub/normal2
33 $ echo large1 > large1
33 $ echo large1 > large1
34 $ echo large2 > sub/large2
34 $ echo large2 > sub/large2
35 $ hg add normal1 sub/normal2
35 $ hg add normal1 sub/normal2
36 $ hg add --large large1 sub/large2
36 $ hg add --large large1 sub/large2
37 $ hg commit -m "add files"
37 $ hg commit -m "add files"
38 Invoking status precommit hook
38 Invoking status precommit hook
39 A large1
39 A large1
40 A normal1
40 A normal1
41 A sub/large2
41 A sub/large2
42 A sub/normal2
42 A sub/normal2
43 $ touch large1 sub/large2
43 $ touch large1 sub/large2
44 $ sleep 1
44 $ sleep 1
45 $ hg st
45 $ hg st
46 $ hg debugstate --nodates
46 $ hg debugstate --no-dates
47 n 644 41 set .hglf/large1
47 n 644 41 set .hglf/large1
48 n 644 41 set .hglf/sub/large2
48 n 644 41 set .hglf/sub/large2
49 n 644 8 set normal1
49 n 644 8 set normal1
50 n 644 8 set sub/normal2
50 n 644 8 set sub/normal2
51 $ hg debugstate --large --nodates
51 $ hg debugstate --large --no-dates
52 n 644 7 set large1
52 n 644 7 set large1
53 n 644 7 set sub/large2
53 n 644 7 set sub/large2
54 $ echo normal11 > normal1
54 $ echo normal11 > normal1
55 $ echo normal22 > sub/normal2
55 $ echo normal22 > sub/normal2
56 $ echo large11 > large1
56 $ echo large11 > large1
57 $ echo large22 > sub/large2
57 $ echo large22 > sub/large2
58 $ hg commit -m "edit files"
58 $ hg commit -m "edit files"
59 Invoking status precommit hook
59 Invoking status precommit hook
60 M large1
60 M large1
61 M normal1
61 M normal1
62 M sub/large2
62 M sub/large2
63 M sub/normal2
63 M sub/normal2
64 $ hg sum --large
64 $ hg sum --large
65 parent: 1:ce8896473775 tip
65 parent: 1:ce8896473775 tip
66 edit files
66 edit files
67 branch: default
67 branch: default
68 commit: (clean)
68 commit: (clean)
69 update: (current)
69 update: (current)
70 phases: 2 draft
70 phases: 2 draft
71 largefiles: (no remote repo)
71 largefiles: (no remote repo)
72
72
73 Commit preserved largefile contents.
73 Commit preserved largefile contents.
74
74
75 $ cat normal1
75 $ cat normal1
76 normal11
76 normal11
77 $ cat large1
77 $ cat large1
78 large11
78 large11
79 $ cat sub/normal2
79 $ cat sub/normal2
80 normal22
80 normal22
81 $ cat sub/large2
81 $ cat sub/large2
82 large22
82 large22
83
83
84 Test status, subdir and unknown files
84 Test status, subdir and unknown files
85
85
86 $ echo unknown > sub/unknown
86 $ echo unknown > sub/unknown
87 $ hg st --all
87 $ hg st --all
88 ? sub/unknown
88 ? sub/unknown
89 C large1
89 C large1
90 C normal1
90 C normal1
91 C sub/large2
91 C sub/large2
92 C sub/normal2
92 C sub/normal2
93 $ hg st --all sub
93 $ hg st --all sub
94 ? sub/unknown
94 ? sub/unknown
95 C sub/large2
95 C sub/large2
96 C sub/normal2
96 C sub/normal2
97 $ rm sub/unknown
97 $ rm sub/unknown
98
98
99 Test messages and exit codes for remove warning cases
99 Test messages and exit codes for remove warning cases
100
100
101 $ hg remove -A large1
101 $ hg remove -A large1
102 not removing large1: file still exists
102 not removing large1: file still exists
103 [1]
103 [1]
104 $ echo 'modified' > large1
104 $ echo 'modified' > large1
105 $ hg remove large1
105 $ hg remove large1
106 not removing large1: file is modified (use -f to force removal)
106 not removing large1: file is modified (use -f to force removal)
107 [1]
107 [1]
108 $ echo 'new' > normalnew
108 $ echo 'new' > normalnew
109 $ hg add normalnew
109 $ hg add normalnew
110 $ echo 'new' > largenew
110 $ echo 'new' > largenew
111 $ hg add --large normalnew
111 $ hg add --large normalnew
112 normalnew already tracked!
112 normalnew already tracked!
113 $ hg remove normalnew largenew
113 $ hg remove normalnew largenew
114 not removing largenew: file is untracked
114 not removing largenew: file is untracked
115 not removing normalnew: file has been marked for add (use 'hg forget' to undo add)
115 not removing normalnew: file has been marked for add (use 'hg forget' to undo add)
116 [1]
116 [1]
117 $ rm normalnew largenew
117 $ rm normalnew largenew
118 $ hg up -Cq
118 $ hg up -Cq
119
119
120 Remove both largefiles and normal files.
120 Remove both largefiles and normal files.
121
121
122 $ hg remove normal1 large1
122 $ hg remove normal1 large1
123 $ hg status large1
123 $ hg status large1
124 R large1
124 R large1
125 $ hg commit -m "remove files"
125 $ hg commit -m "remove files"
126 Invoking status precommit hook
126 Invoking status precommit hook
127 R large1
127 R large1
128 R normal1
128 R normal1
129 $ ls
129 $ ls
130 sub
130 sub
131 $ echo "testlargefile" > large1-test
131 $ echo "testlargefile" > large1-test
132 $ hg add --large large1-test
132 $ hg add --large large1-test
133 $ hg st
133 $ hg st
134 A large1-test
134 A large1-test
135 $ hg rm large1-test
135 $ hg rm large1-test
136 not removing large1-test: file has been marked for add (use forget to undo)
136 not removing large1-test: file has been marked for add (use forget to undo)
137 [1]
137 [1]
138 $ hg st
138 $ hg st
139 A large1-test
139 A large1-test
140 $ hg forget large1-test
140 $ hg forget large1-test
141 $ hg st
141 $ hg st
142 ? large1-test
142 ? large1-test
143 $ hg remove large1-test
143 $ hg remove large1-test
144 not removing large1-test: file is untracked
144 not removing large1-test: file is untracked
145 [1]
145 [1]
146 $ hg forget large1-test
146 $ hg forget large1-test
147 not removing large1-test: file is already untracked
147 not removing large1-test: file is already untracked
148 [1]
148 [1]
149 $ rm large1-test
149 $ rm large1-test
150
150
151 Copy both largefiles and normal files (testing that status output is correct).
151 Copy both largefiles and normal files (testing that status output is correct).
152
152
153 $ hg cp sub/normal2 normal1
153 $ hg cp sub/normal2 normal1
154 $ hg cp sub/large2 large1
154 $ hg cp sub/large2 large1
155 $ hg commit -m "copy files"
155 $ hg commit -m "copy files"
156 Invoking status precommit hook
156 Invoking status precommit hook
157 A large1
157 A large1
158 A normal1
158 A normal1
159 $ cat normal1
159 $ cat normal1
160 normal22
160 normal22
161 $ cat large1
161 $ cat large1
162 large22
162 large22
163
163
164 Test moving largefiles and verify that normal files are also unaffected.
164 Test moving largefiles and verify that normal files are also unaffected.
165
165
166 $ hg mv normal1 normal3
166 $ hg mv normal1 normal3
167 $ hg mv large1 large3
167 $ hg mv large1 large3
168 $ hg mv sub/normal2 sub/normal4
168 $ hg mv sub/normal2 sub/normal4
169 $ hg mv sub/large2 sub/large4
169 $ hg mv sub/large2 sub/large4
170 $ hg commit -m "move files"
170 $ hg commit -m "move files"
171 Invoking status precommit hook
171 Invoking status precommit hook
172 A large3
172 A large3
173 A normal3
173 A normal3
174 A sub/large4
174 A sub/large4
175 A sub/normal4
175 A sub/normal4
176 R large1
176 R large1
177 R normal1
177 R normal1
178 R sub/large2
178 R sub/large2
179 R sub/normal2
179 R sub/normal2
180 $ cat normal3
180 $ cat normal3
181 normal22
181 normal22
182 $ cat large3
182 $ cat large3
183 large22
183 large22
184 $ cat sub/normal4
184 $ cat sub/normal4
185 normal22
185 normal22
186 $ cat sub/large4
186 $ cat sub/large4
187 large22
187 large22
188
188
189
189
190 #if serve
190 #if serve
191 Test display of largefiles in hgweb
191 Test display of largefiles in hgweb
192
192
193 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
193 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
194 $ cat ../hg.pid >> $DAEMON_PIDS
194 $ cat ../hg.pid >> $DAEMON_PIDS
195 $ get-with-headers.py $LOCALIP:$HGPORT 'file/tip/?style=raw'
195 $ get-with-headers.py $LOCALIP:$HGPORT 'file/tip/?style=raw'
196 200 Script output follows
196 200 Script output follows
197
197
198
198
199 drwxr-xr-x sub
199 drwxr-xr-x sub
200 -rw-r--r-- 41 large3
200 -rw-r--r-- 41 large3
201 -rw-r--r-- 9 normal3
201 -rw-r--r-- 9 normal3
202
202
203
203
204 $ get-with-headers.py $LOCALIP:$HGPORT 'file/tip/sub/?style=raw'
204 $ get-with-headers.py $LOCALIP:$HGPORT 'file/tip/sub/?style=raw'
205 200 Script output follows
205 200 Script output follows
206
206
207
207
208 -rw-r--r-- 41 large4
208 -rw-r--r-- 41 large4
209 -rw-r--r-- 9 normal4
209 -rw-r--r-- 9 normal4
210
210
211
211
212 $ killdaemons.py
212 $ killdaemons.py
213 #endif
213 #endif
214
214
215 Test largefiles can be loaded in hgweb (wrapcommand() shouldn't fail)
215 Test largefiles can be loaded in hgweb (wrapcommand() shouldn't fail)
216
216
217 $ cat <<EOF > "$TESTTMP/hgweb.cgi"
217 $ cat <<EOF > "$TESTTMP/hgweb.cgi"
218 > #!$PYTHON
218 > #!$PYTHON
219 > from mercurial import demandimport; demandimport.enable()
219 > from mercurial import demandimport; demandimport.enable()
220 > from mercurial.hgweb import hgweb
220 > from mercurial.hgweb import hgweb
221 > from mercurial.hgweb import wsgicgi
221 > from mercurial.hgweb import wsgicgi
222 > application = hgweb(b'.', b'test repo')
222 > application = hgweb(b'.', b'test repo')
223 > wsgicgi.launch(application)
223 > wsgicgi.launch(application)
224 > EOF
224 > EOF
225 $ . "$TESTDIR/cgienv"
225 $ . "$TESTDIR/cgienv"
226
226
227 $ SCRIPT_NAME='' \
227 $ SCRIPT_NAME='' \
228 > "$PYTHON" "$TESTTMP/hgweb.cgi" > /dev/null
228 > "$PYTHON" "$TESTTMP/hgweb.cgi" > /dev/null
229
229
230 Test archiving the various revisions. These hit corner cases known with
230 Test archiving the various revisions. These hit corner cases known with
231 archiving.
231 archiving.
232
232
233 $ hg archive -r 0 ../archive0
233 $ hg archive -r 0 ../archive0
234 $ hg archive -r 1 ../archive1
234 $ hg archive -r 1 ../archive1
235 $ hg archive -r 2 ../archive2
235 $ hg archive -r 2 ../archive2
236 $ hg archive -r 3 ../archive3
236 $ hg archive -r 3 ../archive3
237 $ hg archive -r 4 ../archive4
237 $ hg archive -r 4 ../archive4
238 $ cd ../archive0
238 $ cd ../archive0
239 $ cat normal1
239 $ cat normal1
240 normal1
240 normal1
241 $ cat large1
241 $ cat large1
242 large1
242 large1
243 $ cat sub/normal2
243 $ cat sub/normal2
244 normal2
244 normal2
245 $ cat sub/large2
245 $ cat sub/large2
246 large2
246 large2
247 $ cd ../archive1
247 $ cd ../archive1
248 $ cat normal1
248 $ cat normal1
249 normal11
249 normal11
250 $ cat large1
250 $ cat large1
251 large11
251 large11
252 $ cat sub/normal2
252 $ cat sub/normal2
253 normal22
253 normal22
254 $ cat sub/large2
254 $ cat sub/large2
255 large22
255 large22
256 $ cd ../archive2
256 $ cd ../archive2
257 $ ls
257 $ ls
258 sub
258 sub
259 $ cat sub/normal2
259 $ cat sub/normal2
260 normal22
260 normal22
261 $ cat sub/large2
261 $ cat sub/large2
262 large22
262 large22
263 $ cd ../archive3
263 $ cd ../archive3
264 $ cat normal1
264 $ cat normal1
265 normal22
265 normal22
266 $ cat large1
266 $ cat large1
267 large22
267 large22
268 $ cat sub/normal2
268 $ cat sub/normal2
269 normal22
269 normal22
270 $ cat sub/large2
270 $ cat sub/large2
271 large22
271 large22
272 $ cd ../archive4
272 $ cd ../archive4
273 $ cat normal3
273 $ cat normal3
274 normal22
274 normal22
275 $ cat large3
275 $ cat large3
276 large22
276 large22
277 $ cat sub/normal4
277 $ cat sub/normal4
278 normal22
278 normal22
279 $ cat sub/large4
279 $ cat sub/large4
280 large22
280 large22
281
281
282 Commit corner case: specify files to commit.
282 Commit corner case: specify files to commit.
283
283
284 $ cd ../a
284 $ cd ../a
285 $ echo normal3 > normal3
285 $ echo normal3 > normal3
286 $ echo large3 > large3
286 $ echo large3 > large3
287 $ echo normal4 > sub/normal4
287 $ echo normal4 > sub/normal4
288 $ echo large4 > sub/large4
288 $ echo large4 > sub/large4
289 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
289 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
290 Invoking status precommit hook
290 Invoking status precommit hook
291 M large3
291 M large3
292 M normal3
292 M normal3
293 M sub/large4
293 M sub/large4
294 M sub/normal4
294 M sub/normal4
295 $ cat normal3
295 $ cat normal3
296 normal3
296 normal3
297 $ cat large3
297 $ cat large3
298 large3
298 large3
299 $ cat sub/normal4
299 $ cat sub/normal4
300 normal4
300 normal4
301 $ cat sub/large4
301 $ cat sub/large4
302 large4
302 large4
303
303
304 One more commit corner case: commit from a subdirectory.
304 One more commit corner case: commit from a subdirectory.
305
305
306 $ cd ../a
306 $ cd ../a
307 $ echo normal33 > normal3
307 $ echo normal33 > normal3
308 $ echo large33 > large3
308 $ echo large33 > large3
309 $ echo normal44 > sub/normal4
309 $ echo normal44 > sub/normal4
310 $ echo large44 > sub/large4
310 $ echo large44 > sub/large4
311 $ cd sub
311 $ cd sub
312 $ hg commit -m "edit files yet again"
312 $ hg commit -m "edit files yet again"
313 Invoking status precommit hook
313 Invoking status precommit hook
314 M large3
314 M large3
315 M normal3
315 M normal3
316 M sub/large4
316 M sub/large4
317 M sub/normal4
317 M sub/normal4
318 $ cat ../normal3
318 $ cat ../normal3
319 normal33
319 normal33
320 $ cat ../large3
320 $ cat ../large3
321 large33
321 large33
322 $ cat normal4
322 $ cat normal4
323 normal44
323 normal44
324 $ cat large4
324 $ cat large4
325 large44
325 large44
326
326
327 Committing standins is not allowed.
327 Committing standins is not allowed.
328
328
329 $ cd ..
329 $ cd ..
330 $ echo large3 > large3
330 $ echo large3 > large3
331 $ hg commit .hglf/large3 -m "try to commit standin"
331 $ hg commit .hglf/large3 -m "try to commit standin"
332 abort: file ".hglf/large3" is a largefile standin
332 abort: file ".hglf/large3" is a largefile standin
333 (commit the largefile itself instead)
333 (commit the largefile itself instead)
334 [255]
334 [255]
335
335
336 Corner cases for adding largefiles.
336 Corner cases for adding largefiles.
337
337
338 $ echo large5 > large5
338 $ echo large5 > large5
339 $ hg add --large large5
339 $ hg add --large large5
340 $ hg add --large large5
340 $ hg add --large large5
341 large5 already a largefile
341 large5 already a largefile
342 $ mkdir sub2
342 $ mkdir sub2
343 $ echo large6 > sub2/large6
343 $ echo large6 > sub2/large6
344 $ echo large7 > sub2/large7
344 $ echo large7 > sub2/large7
345 $ hg add --large sub2
345 $ hg add --large sub2
346 adding sub2/large6 as a largefile
346 adding sub2/large6 as a largefile
347 adding sub2/large7 as a largefile
347 adding sub2/large7 as a largefile
348 $ hg st
348 $ hg st
349 M large3
349 M large3
350 A large5
350 A large5
351 A sub2/large6
351 A sub2/large6
352 A sub2/large7
352 A sub2/large7
353
353
354 Committing directories containing only largefiles.
354 Committing directories containing only largefiles.
355
355
356 $ mkdir -p z/y/x/m
356 $ mkdir -p z/y/x/m
357 $ touch z/y/x/m/large1
357 $ touch z/y/x/m/large1
358 $ touch z/y/x/large2
358 $ touch z/y/x/large2
359 $ hg add --large z/y/x/m/large1 z/y/x/large2
359 $ hg add --large z/y/x/m/large1 z/y/x/large2
360 $ hg commit -m "Subdir with directory only containing largefiles" z
360 $ hg commit -m "Subdir with directory only containing largefiles" z
361 Invoking status precommit hook
361 Invoking status precommit hook
362 M large3
362 M large3
363 A large5
363 A large5
364 A sub2/large6
364 A sub2/large6
365 A sub2/large7
365 A sub2/large7
366 A z/y/x/large2
366 A z/y/x/large2
367 A z/y/x/m/large1
367 A z/y/x/m/large1
368
368
369 (and a bit of log testing)
369 (and a bit of log testing)
370
370
371 $ hg log -T '{rev}\n' z/y/x/m/large1
371 $ hg log -T '{rev}\n' z/y/x/m/large1
372 7
372 7
373 $ hg log -T '{rev}\n' z/y/x/m # with only a largefile
373 $ hg log -T '{rev}\n' z/y/x/m # with only a largefile
374 7
374 7
375
375
376 $ hg rollback --quiet
376 $ hg rollback --quiet
377 $ touch z/y/x/m/normal
377 $ touch z/y/x/m/normal
378 $ hg add z/y/x/m/normal
378 $ hg add z/y/x/m/normal
379 $ hg commit -m "Subdir with mixed contents" z
379 $ hg commit -m "Subdir with mixed contents" z
380 Invoking status precommit hook
380 Invoking status precommit hook
381 M large3
381 M large3
382 A large5
382 A large5
383 A sub2/large6
383 A sub2/large6
384 A sub2/large7
384 A sub2/large7
385 A z/y/x/large2
385 A z/y/x/large2
386 A z/y/x/m/large1
386 A z/y/x/m/large1
387 A z/y/x/m/normal
387 A z/y/x/m/normal
388 $ hg st
388 $ hg st
389 M large3
389 M large3
390 A large5
390 A large5
391 A sub2/large6
391 A sub2/large6
392 A sub2/large7
392 A sub2/large7
393 $ hg rollback --quiet
393 $ hg rollback --quiet
394 $ hg revert z/y/x/large2 z/y/x/m/large1
394 $ hg revert z/y/x/large2 z/y/x/m/large1
395 $ rm z/y/x/large2 z/y/x/m/large1
395 $ rm z/y/x/large2 z/y/x/m/large1
396 $ hg commit -m "Subdir with normal contents" z
396 $ hg commit -m "Subdir with normal contents" z
397 Invoking status precommit hook
397 Invoking status precommit hook
398 M large3
398 M large3
399 A large5
399 A large5
400 A sub2/large6
400 A sub2/large6
401 A sub2/large7
401 A sub2/large7
402 A z/y/x/m/normal
402 A z/y/x/m/normal
403 $ hg st
403 $ hg st
404 M large3
404 M large3
405 A large5
405 A large5
406 A sub2/large6
406 A sub2/large6
407 A sub2/large7
407 A sub2/large7
408 $ hg rollback --quiet
408 $ hg rollback --quiet
409 $ hg revert --quiet z
409 $ hg revert --quiet z
410 $ hg commit -m "Empty subdir" z
410 $ hg commit -m "Empty subdir" z
411 abort: z: no match under directory!
411 abort: z: no match under directory!
412 [255]
412 [255]
413 $ rm -rf z
413 $ rm -rf z
414 $ hg ci -m "standin" .hglf
414 $ hg ci -m "standin" .hglf
415 abort: file ".hglf" is a largefile standin
415 abort: file ".hglf" is a largefile standin
416 (commit the largefile itself instead)
416 (commit the largefile itself instead)
417 [255]
417 [255]
418
418
419 Test "hg status" with combination of 'file pattern' and 'directory
419 Test "hg status" with combination of 'file pattern' and 'directory
420 pattern' for largefiles:
420 pattern' for largefiles:
421
421
422 $ hg status sub2/large6 sub2
422 $ hg status sub2/large6 sub2
423 A sub2/large6
423 A sub2/large6
424 A sub2/large7
424 A sub2/large7
425
425
426 Config settings (pattern **.dat, minsize 2 MB) are respected.
426 Config settings (pattern **.dat, minsize 2 MB) are respected.
427
427
428 $ echo testdata > test.dat
428 $ echo testdata > test.dat
429 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
429 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
430 $ hg add
430 $ hg add
431 adding reallylarge as a largefile
431 adding reallylarge as a largefile
432 adding test.dat as a largefile
432 adding test.dat as a largefile
433
433
434 Test that minsize and --lfsize handle float values;
434 Test that minsize and --lfsize handle float values;
435 also tests that --lfsize overrides largefiles.minsize.
435 also tests that --lfsize overrides largefiles.minsize.
436 (0.250 MB = 256 kB = 262144 B)
436 (0.250 MB = 256 kB = 262144 B)
437
437
438 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
438 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
439 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
439 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
440 $ hg --config largefiles.minsize=.25 add
440 $ hg --config largefiles.minsize=.25 add
441 adding ratherlarge as a largefile
441 adding ratherlarge as a largefile
442 adding medium
442 adding medium
443 $ hg forget medium
443 $ hg forget medium
444 $ hg --config largefiles.minsize=.25 add --lfsize=.125
444 $ hg --config largefiles.minsize=.25 add --lfsize=.125
445 adding medium as a largefile
445 adding medium as a largefile
446 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
446 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
447 $ hg --config largefiles.minsize=.25 add --lfsize=.125
447 $ hg --config largefiles.minsize=.25 add --lfsize=.125
448 adding notlarge
448 adding notlarge
449 $ hg forget notlarge
449 $ hg forget notlarge
450
450
451 Test forget on largefiles.
451 Test forget on largefiles.
452
452
453 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
453 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
454 $ hg commit -m "add/edit more largefiles"
454 $ hg commit -m "add/edit more largefiles"
455 Invoking status precommit hook
455 Invoking status precommit hook
456 A sub2/large6
456 A sub2/large6
457 A sub2/large7
457 A sub2/large7
458 R large3
458 R large3
459 ? large5
459 ? large5
460 ? medium
460 ? medium
461 ? notlarge
461 ? notlarge
462 ? ratherlarge
462 ? ratherlarge
463 ? reallylarge
463 ? reallylarge
464 ? test.dat
464 ? test.dat
465 $ hg st
465 $ hg st
466 ? large3
466 ? large3
467 ? large5
467 ? large5
468 ? medium
468 ? medium
469 ? notlarge
469 ? notlarge
470 ? ratherlarge
470 ? ratherlarge
471 ? reallylarge
471 ? reallylarge
472 ? test.dat
472 ? test.dat
473
473
474 Purge with largefiles: verify that largefiles are still in the working
474 Purge with largefiles: verify that largefiles are still in the working
475 dir after a purge.
475 dir after a purge.
476
476
477 $ hg purge --all
477 $ hg purge --all
478 $ cat sub/large4
478 $ cat sub/large4
479 large44
479 large44
480 $ cat sub2/large6
480 $ cat sub2/large6
481 large6
481 large6
482 $ cat sub2/large7
482 $ cat sub2/large7
483 large7
483 large7
484
484
485 Test addremove: verify that files that should be added as largefiles are added as
485 Test addremove: verify that files that should be added as largefiles are added as
486 such and that already-existing largefiles are not added as normal files by
486 such and that already-existing largefiles are not added as normal files by
487 accident.
487 accident.
488
488
489 $ rm normal3
489 $ rm normal3
490 $ rm sub/large4
490 $ rm sub/large4
491 $ echo "testing addremove with patterns" > testaddremove.dat
491 $ echo "testing addremove with patterns" > testaddremove.dat
492 $ echo "normaladdremove" > normaladdremove
492 $ echo "normaladdremove" > normaladdremove
493 $ hg addremove
493 $ hg addremove
494 removing sub/large4
494 removing sub/large4
495 adding testaddremove.dat as a largefile
495 adding testaddremove.dat as a largefile
496 removing normal3
496 removing normal3
497 adding normaladdremove
497 adding normaladdremove
498
498
499 Test addremove with -R
499 Test addremove with -R
500
500
501 $ hg up -C
501 $ hg up -C
502 getting changed largefiles
502 getting changed largefiles
503 1 largefiles updated, 0 removed
503 1 largefiles updated, 0 removed
504 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
504 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
505 $ rm normal3
505 $ rm normal3
506 $ rm sub/large4
506 $ rm sub/large4
507 $ echo "testing addremove with patterns" > testaddremove.dat
507 $ echo "testing addremove with patterns" > testaddremove.dat
508 $ echo "normaladdremove" > normaladdremove
508 $ echo "normaladdremove" > normaladdremove
509 $ cd ..
509 $ cd ..
510 $ hg -R a -v addremove
510 $ hg -R a -v addremove
511 removing sub/large4
511 removing sub/large4
512 adding testaddremove.dat as a largefile
512 adding testaddremove.dat as a largefile
513 removing normal3
513 removing normal3
514 adding normaladdremove
514 adding normaladdremove
515 $ cd a
515 $ cd a
516
516
517 Test 3364
517 Test 3364
518 $ hg clone . ../addrm
518 $ hg clone . ../addrm
519 updating to branch default
519 updating to branch default
520 getting changed largefiles
520 getting changed largefiles
521 3 largefiles updated, 0 removed
521 3 largefiles updated, 0 removed
522 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
522 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
523 $ cd ../addrm
523 $ cd ../addrm
524 $ cat >> .hg/hgrc <<EOF
524 $ cat >> .hg/hgrc <<EOF
525 > [hooks]
525 > [hooks]
526 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
526 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
527 > EOF
527 > EOF
528 $ touch foo
528 $ touch foo
529 $ hg add --large foo
529 $ hg add --large foo
530 $ hg ci -m "add foo"
530 $ hg ci -m "add foo"
531 Invoking status precommit hook
531 Invoking status precommit hook
532 A foo
532 A foo
533 Invoking status postcommit hook
533 Invoking status postcommit hook
534 C foo
534 C foo
535 C normal3
535 C normal3
536 C sub/large4
536 C sub/large4
537 C sub/normal4
537 C sub/normal4
538 C sub2/large6
538 C sub2/large6
539 C sub2/large7
539 C sub2/large7
540 $ rm foo
540 $ rm foo
541 $ hg st
541 $ hg st
542 ! foo
542 ! foo
543 hmm.. no precommit invoked, but there is a postcommit??
543 hmm.. no precommit invoked, but there is a postcommit??
544 $ hg ci -m "will not checkin"
544 $ hg ci -m "will not checkin"
545 nothing changed (1 missing files, see 'hg status')
545 nothing changed (1 missing files, see 'hg status')
546 Invoking status postcommit hook
546 Invoking status postcommit hook
547 ! foo
547 ! foo
548 C normal3
548 C normal3
549 C sub/large4
549 C sub/large4
550 C sub/normal4
550 C sub/normal4
551 C sub2/large6
551 C sub2/large6
552 C sub2/large7
552 C sub2/large7
553 [1]
553 [1]
554 $ hg addremove
554 $ hg addremove
555 removing foo
555 removing foo
556 $ hg st
556 $ hg st
557 R foo
557 R foo
558 $ hg ci -m "used to say nothing changed"
558 $ hg ci -m "used to say nothing changed"
559 Invoking status precommit hook
559 Invoking status precommit hook
560 R foo
560 R foo
561 Invoking status postcommit hook
561 Invoking status postcommit hook
562 C normal3
562 C normal3
563 C sub/large4
563 C sub/large4
564 C sub/normal4
564 C sub/normal4
565 C sub2/large6
565 C sub2/large6
566 C sub2/large7
566 C sub2/large7
567 $ hg st
567 $ hg st
568
568
569 Test 3507 (both normal files and largefiles were a problem)
569 Test 3507 (both normal files and largefiles were a problem)
570
570
571 $ touch normal
571 $ touch normal
572 $ touch large
572 $ touch large
573 $ hg add normal
573 $ hg add normal
574 $ hg add --large large
574 $ hg add --large large
575 $ hg ci -m "added"
575 $ hg ci -m "added"
576 Invoking status precommit hook
576 Invoking status precommit hook
577 A large
577 A large
578 A normal
578 A normal
579 Invoking status postcommit hook
579 Invoking status postcommit hook
580 C large
580 C large
581 C normal
581 C normal
582 C normal3
582 C normal3
583 C sub/large4
583 C sub/large4
584 C sub/normal4
584 C sub/normal4
585 C sub2/large6
585 C sub2/large6
586 C sub2/large7
586 C sub2/large7
587 $ hg remove normal
587 $ hg remove normal
588 $ hg addremove --traceback
588 $ hg addremove --traceback
589 $ hg ci -m "addremoved normal"
589 $ hg ci -m "addremoved normal"
590 Invoking status precommit hook
590 Invoking status precommit hook
591 R normal
591 R normal
592 Invoking status postcommit hook
592 Invoking status postcommit hook
593 C large
593 C large
594 C normal3
594 C normal3
595 C sub/large4
595 C sub/large4
596 C sub/normal4
596 C sub/normal4
597 C sub2/large6
597 C sub2/large6
598 C sub2/large7
598 C sub2/large7
599 $ hg up -C '.^'
599 $ hg up -C '.^'
600 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
600 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
601 $ hg remove large
601 $ hg remove large
602 $ hg addremove --traceback
602 $ hg addremove --traceback
603 $ hg ci -m "removed large"
603 $ hg ci -m "removed large"
604 Invoking status precommit hook
604 Invoking status precommit hook
605 R large
605 R large
606 created new head
606 created new head
607 Invoking status postcommit hook
607 Invoking status postcommit hook
608 C normal
608 C normal
609 C normal3
609 C normal3
610 C sub/large4
610 C sub/large4
611 C sub/normal4
611 C sub/normal4
612 C sub2/large6
612 C sub2/large6
613 C sub2/large7
613 C sub2/large7
614
614
615 Test commit -A (issue3542)
615 Test commit -A (issue3542)
616 $ echo large8 > large8
616 $ echo large8 > large8
617 $ hg add --large large8
617 $ hg add --large large8
618 $ hg ci -Am 'this used to add large8 as normal and commit both'
618 $ hg ci -Am 'this used to add large8 as normal and commit both'
619 Invoking status precommit hook
619 Invoking status precommit hook
620 A large8
620 A large8
621 Invoking status postcommit hook
621 Invoking status postcommit hook
622 C large8
622 C large8
623 C normal
623 C normal
624 C normal3
624 C normal3
625 C sub/large4
625 C sub/large4
626 C sub/normal4
626 C sub/normal4
627 C sub2/large6
627 C sub2/large6
628 C sub2/large7
628 C sub2/large7
629 $ rm large8
629 $ rm large8
630 $ hg ci -Am 'this used to not notice the rm'
630 $ hg ci -Am 'this used to not notice the rm'
631 removing large8
631 removing large8
632 Invoking status precommit hook
632 Invoking status precommit hook
633 R large8
633 R large8
634 Invoking status postcommit hook
634 Invoking status postcommit hook
635 C normal
635 C normal
636 C normal3
636 C normal3
637 C sub/large4
637 C sub/large4
638 C sub/normal4
638 C sub/normal4
639 C sub2/large6
639 C sub2/large6
640 C sub2/large7
640 C sub2/large7
641
641
642 Test that a standin can't be added as a large file
642 Test that a standin can't be added as a large file
643
643
644 $ touch large
644 $ touch large
645 $ hg add --large large
645 $ hg add --large large
646 $ hg ci -m "add"
646 $ hg ci -m "add"
647 Invoking status precommit hook
647 Invoking status precommit hook
648 A large
648 A large
649 Invoking status postcommit hook
649 Invoking status postcommit hook
650 C large
650 C large
651 C normal
651 C normal
652 C normal3
652 C normal3
653 C sub/large4
653 C sub/large4
654 C sub/normal4
654 C sub/normal4
655 C sub2/large6
655 C sub2/large6
656 C sub2/large7
656 C sub2/large7
657 $ hg remove large
657 $ hg remove large
658 $ touch large
658 $ touch large
659 $ hg addremove --config largefiles.patterns=**large --traceback
659 $ hg addremove --config largefiles.patterns=**large --traceback
660 adding large as a largefile
660 adding large as a largefile
661
661
662 Test that outgoing --large works (with revsets too)
662 Test that outgoing --large works (with revsets too)
663 $ hg outgoing --rev '.^' --large
663 $ hg outgoing --rev '.^' --large
664 comparing with $TESTTMP/a
664 comparing with $TESTTMP/a
665 searching for changes
665 searching for changes
666 changeset: 8:c02fd3b77ec4
666 changeset: 8:c02fd3b77ec4
667 user: test
667 user: test
668 date: Thu Jan 01 00:00:00 1970 +0000
668 date: Thu Jan 01 00:00:00 1970 +0000
669 summary: add foo
669 summary: add foo
670
670
671 changeset: 9:289dd08c9bbb
671 changeset: 9:289dd08c9bbb
672 user: test
672 user: test
673 date: Thu Jan 01 00:00:00 1970 +0000
673 date: Thu Jan 01 00:00:00 1970 +0000
674 summary: used to say nothing changed
674 summary: used to say nothing changed
675
675
676 changeset: 10:34f23ac6ac12
676 changeset: 10:34f23ac6ac12
677 user: test
677 user: test
678 date: Thu Jan 01 00:00:00 1970 +0000
678 date: Thu Jan 01 00:00:00 1970 +0000
679 summary: added
679 summary: added
680
680
681 changeset: 12:710c1b2f523c
681 changeset: 12:710c1b2f523c
682 parent: 10:34f23ac6ac12
682 parent: 10:34f23ac6ac12
683 user: test
683 user: test
684 date: Thu Jan 01 00:00:00 1970 +0000
684 date: Thu Jan 01 00:00:00 1970 +0000
685 summary: removed large
685 summary: removed large
686
686
687 changeset: 13:0a3e75774479
687 changeset: 13:0a3e75774479
688 user: test
688 user: test
689 date: Thu Jan 01 00:00:00 1970 +0000
689 date: Thu Jan 01 00:00:00 1970 +0000
690 summary: this used to add large8 as normal and commit both
690 summary: this used to add large8 as normal and commit both
691
691
692 changeset: 14:84f3d378175c
692 changeset: 14:84f3d378175c
693 user: test
693 user: test
694 date: Thu Jan 01 00:00:00 1970 +0000
694 date: Thu Jan 01 00:00:00 1970 +0000
695 summary: this used to not notice the rm
695 summary: this used to not notice the rm
696
696
697 largefiles to upload (1 entities):
697 largefiles to upload (1 entities):
698 large8
698 large8
699
699
700 $ cd ../a
700 $ cd ../a
701
701
702 Clone a largefiles repo.
702 Clone a largefiles repo.
703
703
704 $ hg clone . ../b
704 $ hg clone . ../b
705 updating to branch default
705 updating to branch default
706 getting changed largefiles
706 getting changed largefiles
707 3 largefiles updated, 0 removed
707 3 largefiles updated, 0 removed
708 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
708 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
709 $ cd ../b
709 $ cd ../b
710 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
710 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
711 7:daea875e9014 add/edit more largefiles
711 7:daea875e9014 add/edit more largefiles
712 6:4355d653f84f edit files yet again
712 6:4355d653f84f edit files yet again
713 5:9d5af5072dbd edit files again
713 5:9d5af5072dbd edit files again
714 4:74c02385b94c move files
714 4:74c02385b94c move files
715 3:9e8fbc4bce62 copy files
715 3:9e8fbc4bce62 copy files
716 2:51a0ae4d5864 remove files
716 2:51a0ae4d5864 remove files
717 1:ce8896473775 edit files
717 1:ce8896473775 edit files
718 0:30d30fe6a5be add files
718 0:30d30fe6a5be add files
719 $ cat normal3
719 $ cat normal3
720 normal33
720 normal33
721
721
722 Test graph log
722 Test graph log
723
723
724 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
724 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
725 @ 7:daea875e9014 add/edit more largefiles
725 @ 7:daea875e9014 add/edit more largefiles
726 |
726 |
727 o 6:4355d653f84f edit files yet again
727 o 6:4355d653f84f edit files yet again
728 |
728 |
729 o 5:9d5af5072dbd edit files again
729 o 5:9d5af5072dbd edit files again
730 |
730 |
731 o 4:74c02385b94c move files
731 o 4:74c02385b94c move files
732 |
732 |
733 o 3:9e8fbc4bce62 copy files
733 o 3:9e8fbc4bce62 copy files
734 |
734 |
735 o 2:51a0ae4d5864 remove files
735 o 2:51a0ae4d5864 remove files
736 |
736 |
737 o 1:ce8896473775 edit files
737 o 1:ce8896473775 edit files
738 |
738 |
739 o 0:30d30fe6a5be add files
739 o 0:30d30fe6a5be add files
740
740
741
741
742 Test log with --patch
742 Test log with --patch
743
743
744 $ hg log --patch -r 6::7
744 $ hg log --patch -r 6::7
745 changeset: 6:4355d653f84f
745 changeset: 6:4355d653f84f
746 user: test
746 user: test
747 date: Thu Jan 01 00:00:00 1970 +0000
747 date: Thu Jan 01 00:00:00 1970 +0000
748 summary: edit files yet again
748 summary: edit files yet again
749
749
750 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
750 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
751 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
751 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
752 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
752 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
753 @@ -1,1 +1,1 @@
753 @@ -1,1 +1,1 @@
754 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
754 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
755 +7838695e10da2bb75ac1156565f40a2595fa2fa0
755 +7838695e10da2bb75ac1156565f40a2595fa2fa0
756 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
756 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
757 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
757 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
758 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
758 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
759 @@ -1,1 +1,1 @@
759 @@ -1,1 +1,1 @@
760 -aeb2210d19f02886dde00dac279729a48471e2f9
760 -aeb2210d19f02886dde00dac279729a48471e2f9
761 +971fb41e78fea4f8e0ba5244784239371cb00591
761 +971fb41e78fea4f8e0ba5244784239371cb00591
762 diff -r 9d5af5072dbd -r 4355d653f84f normal3
762 diff -r 9d5af5072dbd -r 4355d653f84f normal3
763 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
763 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
764 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
764 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
765 @@ -1,1 +1,1 @@
765 @@ -1,1 +1,1 @@
766 -normal3
766 -normal3
767 +normal33
767 +normal33
768 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
768 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
769 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
769 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
770 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
770 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
771 @@ -1,1 +1,1 @@
771 @@ -1,1 +1,1 @@
772 -normal4
772 -normal4
773 +normal44
773 +normal44
774
774
775 changeset: 7:daea875e9014
775 changeset: 7:daea875e9014
776 tag: tip
776 tag: tip
777 user: test
777 user: test
778 date: Thu Jan 01 00:00:00 1970 +0000
778 date: Thu Jan 01 00:00:00 1970 +0000
779 summary: add/edit more largefiles
779 summary: add/edit more largefiles
780
780
781 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
781 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
782 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
782 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
783 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
783 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
784 @@ -1,1 +0,0 @@
784 @@ -1,1 +0,0 @@
785 -7838695e10da2bb75ac1156565f40a2595fa2fa0
785 -7838695e10da2bb75ac1156565f40a2595fa2fa0
786 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
786 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
787 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
787 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
788 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
788 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
789 @@ -0,0 +1,1 @@
789 @@ -0,0 +1,1 @@
790 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
790 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
791 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
791 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
792 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
792 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
793 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
793 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
794 @@ -0,0 +1,1 @@
794 @@ -0,0 +1,1 @@
795 +bb3151689acb10f0c3125c560d5e63df914bc1af
795 +bb3151689acb10f0c3125c560d5e63df914bc1af
796
796
797
797
798 $ hg log --patch -r 6::7 sub/
798 $ hg log --patch -r 6::7 sub/
799 changeset: 6:4355d653f84f
799 changeset: 6:4355d653f84f
800 user: test
800 user: test
801 date: Thu Jan 01 00:00:00 1970 +0000
801 date: Thu Jan 01 00:00:00 1970 +0000
802 summary: edit files yet again
802 summary: edit files yet again
803
803
804 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
804 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
805 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
805 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
806 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
806 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
807 @@ -1,1 +1,1 @@
807 @@ -1,1 +1,1 @@
808 -aeb2210d19f02886dde00dac279729a48471e2f9
808 -aeb2210d19f02886dde00dac279729a48471e2f9
809 +971fb41e78fea4f8e0ba5244784239371cb00591
809 +971fb41e78fea4f8e0ba5244784239371cb00591
810 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
810 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
811 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
811 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
812 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
812 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
813 @@ -1,1 +1,1 @@
813 @@ -1,1 +1,1 @@
814 -normal4
814 -normal4
815 +normal44
815 +normal44
816
816
817
817
818 log with both --follow and --patch
818 log with both --follow and --patch
819
819
820 $ hg log --follow --patch --limit 2
820 $ hg log --follow --patch --limit 2
821 changeset: 7:daea875e9014
821 changeset: 7:daea875e9014
822 tag: tip
822 tag: tip
823 user: test
823 user: test
824 date: Thu Jan 01 00:00:00 1970 +0000
824 date: Thu Jan 01 00:00:00 1970 +0000
825 summary: add/edit more largefiles
825 summary: add/edit more largefiles
826
826
827 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
827 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
828 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
828 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
829 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
829 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
830 @@ -1,1 +0,0 @@
830 @@ -1,1 +0,0 @@
831 -7838695e10da2bb75ac1156565f40a2595fa2fa0
831 -7838695e10da2bb75ac1156565f40a2595fa2fa0
832 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
832 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
833 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
833 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
834 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
834 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
835 @@ -0,0 +1,1 @@
835 @@ -0,0 +1,1 @@
836 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
836 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
837 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
837 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
838 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
838 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
839 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
839 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
840 @@ -0,0 +1,1 @@
840 @@ -0,0 +1,1 @@
841 +bb3151689acb10f0c3125c560d5e63df914bc1af
841 +bb3151689acb10f0c3125c560d5e63df914bc1af
842
842
843 changeset: 6:4355d653f84f
843 changeset: 6:4355d653f84f
844 user: test
844 user: test
845 date: Thu Jan 01 00:00:00 1970 +0000
845 date: Thu Jan 01 00:00:00 1970 +0000
846 summary: edit files yet again
846 summary: edit files yet again
847
847
848 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
848 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
849 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
849 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
850 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
850 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
851 @@ -1,1 +1,1 @@
851 @@ -1,1 +1,1 @@
852 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
852 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
853 +7838695e10da2bb75ac1156565f40a2595fa2fa0
853 +7838695e10da2bb75ac1156565f40a2595fa2fa0
854 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
854 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
855 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
855 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
856 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
856 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
857 @@ -1,1 +1,1 @@
857 @@ -1,1 +1,1 @@
858 -aeb2210d19f02886dde00dac279729a48471e2f9
858 -aeb2210d19f02886dde00dac279729a48471e2f9
859 +971fb41e78fea4f8e0ba5244784239371cb00591
859 +971fb41e78fea4f8e0ba5244784239371cb00591
860 diff -r 9d5af5072dbd -r 4355d653f84f normal3
860 diff -r 9d5af5072dbd -r 4355d653f84f normal3
861 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
861 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
862 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
862 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
863 @@ -1,1 +1,1 @@
863 @@ -1,1 +1,1 @@
864 -normal3
864 -normal3
865 +normal33
865 +normal33
866 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
866 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
867 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
867 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
868 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
868 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
869 @@ -1,1 +1,1 @@
869 @@ -1,1 +1,1 @@
870 -normal4
870 -normal4
871 +normal44
871 +normal44
872
872
873 $ hg log --follow --patch sub/large4
873 $ hg log --follow --patch sub/large4
874 changeset: 6:4355d653f84f
874 changeset: 6:4355d653f84f
875 user: test
875 user: test
876 date: Thu Jan 01 00:00:00 1970 +0000
876 date: Thu Jan 01 00:00:00 1970 +0000
877 summary: edit files yet again
877 summary: edit files yet again
878
878
879 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
879 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
880 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
880 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
881 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
881 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
882 @@ -1,1 +1,1 @@
882 @@ -1,1 +1,1 @@
883 -aeb2210d19f02886dde00dac279729a48471e2f9
883 -aeb2210d19f02886dde00dac279729a48471e2f9
884 +971fb41e78fea4f8e0ba5244784239371cb00591
884 +971fb41e78fea4f8e0ba5244784239371cb00591
885
885
886 changeset: 5:9d5af5072dbd
886 changeset: 5:9d5af5072dbd
887 user: test
887 user: test
888 date: Thu Jan 01 00:00:00 1970 +0000
888 date: Thu Jan 01 00:00:00 1970 +0000
889 summary: edit files again
889 summary: edit files again
890
890
891 diff -r 74c02385b94c -r 9d5af5072dbd .hglf/sub/large4
891 diff -r 74c02385b94c -r 9d5af5072dbd .hglf/sub/large4
892 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
892 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
893 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
893 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
894 @@ -1,1 +1,1 @@
894 @@ -1,1 +1,1 @@
895 -eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
895 -eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
896 +aeb2210d19f02886dde00dac279729a48471e2f9
896 +aeb2210d19f02886dde00dac279729a48471e2f9
897
897
898 changeset: 4:74c02385b94c
898 changeset: 4:74c02385b94c
899 user: test
899 user: test
900 date: Thu Jan 01 00:00:00 1970 +0000
900 date: Thu Jan 01 00:00:00 1970 +0000
901 summary: move files
901 summary: move files
902
902
903 diff -r 9e8fbc4bce62 -r 74c02385b94c .hglf/sub/large4
903 diff -r 9e8fbc4bce62 -r 74c02385b94c .hglf/sub/large4
904 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
904 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
905 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
905 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
906 @@ -0,0 +1,1 @@
906 @@ -0,0 +1,1 @@
907 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
907 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
908
908
909 changeset: 1:ce8896473775
909 changeset: 1:ce8896473775
910 user: test
910 user: test
911 date: Thu Jan 01 00:00:00 1970 +0000
911 date: Thu Jan 01 00:00:00 1970 +0000
912 summary: edit files
912 summary: edit files
913
913
914 diff -r 30d30fe6a5be -r ce8896473775 .hglf/sub/large2
914 diff -r 30d30fe6a5be -r ce8896473775 .hglf/sub/large2
915 --- a/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
915 --- a/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
916 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
916 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
917 @@ -1,1 +1,1 @@
917 @@ -1,1 +1,1 @@
918 -1deebade43c8c498a3c8daddac0244dc55d1331d
918 -1deebade43c8c498a3c8daddac0244dc55d1331d
919 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
919 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
920
920
921 changeset: 0:30d30fe6a5be
921 changeset: 0:30d30fe6a5be
922 user: test
922 user: test
923 date: Thu Jan 01 00:00:00 1970 +0000
923 date: Thu Jan 01 00:00:00 1970 +0000
924 summary: add files
924 summary: add files
925
925
926 diff -r 000000000000 -r 30d30fe6a5be .hglf/sub/large2
926 diff -r 000000000000 -r 30d30fe6a5be .hglf/sub/large2
927 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
927 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
928 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
928 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
929 @@ -0,0 +1,1 @@
929 @@ -0,0 +1,1 @@
930 +1deebade43c8c498a3c8daddac0244dc55d1331d
930 +1deebade43c8c498a3c8daddac0244dc55d1331d
931
931
932 $ cat sub/normal4
932 $ cat sub/normal4
933 normal44
933 normal44
934 $ cat sub/large4
934 $ cat sub/large4
935 large44
935 large44
936 $ cat sub2/large6
936 $ cat sub2/large6
937 large6
937 large6
938 $ cat sub2/large7
938 $ cat sub2/large7
939 large7
939 large7
940 $ hg log -qf sub2/large7
940 $ hg log -qf sub2/large7
941 7:daea875e9014
941 7:daea875e9014
942 $ hg log -Gqf sub2/large7
942 $ hg log -Gqf sub2/large7
943 @ 7:daea875e9014
943 @ 7:daea875e9014
944 |
944 |
945 ~
945 ~
946 $ cd ..
946 $ cd ..
947
947
948 Test log from outside repo
948 Test log from outside repo
949
949
950 $ hg log b/sub -T '{rev}:{node|short} {desc|firstline}\n'
950 $ hg log b/sub -T '{rev}:{node|short} {desc|firstline}\n'
951 6:4355d653f84f edit files yet again
951 6:4355d653f84f edit files yet again
952 5:9d5af5072dbd edit files again
952 5:9d5af5072dbd edit files again
953 4:74c02385b94c move files
953 4:74c02385b94c move files
954 1:ce8896473775 edit files
954 1:ce8896473775 edit files
955 0:30d30fe6a5be add files
955 0:30d30fe6a5be add files
956
956
957 Test clone at revision
957 Test clone at revision
958
958
959 $ hg clone a -r 3 c
959 $ hg clone a -r 3 c
960 adding changesets
960 adding changesets
961 adding manifests
961 adding manifests
962 adding file changes
962 adding file changes
963 added 4 changesets with 10 changes to 4 files
963 added 4 changesets with 10 changes to 4 files
964 new changesets 30d30fe6a5be:9e8fbc4bce62 (4 drafts)
964 new changesets 30d30fe6a5be:9e8fbc4bce62 (4 drafts)
965 updating to branch default
965 updating to branch default
966 getting changed largefiles
966 getting changed largefiles
967 2 largefiles updated, 0 removed
967 2 largefiles updated, 0 removed
968 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
968 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
969 $ cd c
969 $ cd c
970 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
970 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
971 3:9e8fbc4bce62 copy files
971 3:9e8fbc4bce62 copy files
972 2:51a0ae4d5864 remove files
972 2:51a0ae4d5864 remove files
973 1:ce8896473775 edit files
973 1:ce8896473775 edit files
974 0:30d30fe6a5be add files
974 0:30d30fe6a5be add files
975 $ cat normal1
975 $ cat normal1
976 normal22
976 normal22
977 $ cat large1
977 $ cat large1
978 large22
978 large22
979 $ cat sub/normal2
979 $ cat sub/normal2
980 normal22
980 normal22
981 $ cat sub/large2
981 $ cat sub/large2
982 large22
982 large22
983
983
984 Old revisions of a clone have correct largefiles content (this also
984 Old revisions of a clone have correct largefiles content (this also
985 tests update).
985 tests update).
986
986
987 $ hg update -r 1
987 $ hg update -r 1
988 getting changed largefiles
988 getting changed largefiles
989 1 largefiles updated, 0 removed
989 1 largefiles updated, 0 removed
990 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
990 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
991 $ cat large1
991 $ cat large1
992 large11
992 large11
993 $ cat sub/large2
993 $ cat sub/large2
994 large22
994 large22
995 $ cd ..
995 $ cd ..
996
996
997 Test cloning with --all-largefiles flag
997 Test cloning with --all-largefiles flag
998
998
999 $ rm "${USERCACHE}"/*
999 $ rm "${USERCACHE}"/*
1000 $ hg clone --all-largefiles a a-backup
1000 $ hg clone --all-largefiles a a-backup
1001 updating to branch default
1001 updating to branch default
1002 getting changed largefiles
1002 getting changed largefiles
1003 3 largefiles updated, 0 removed
1003 3 largefiles updated, 0 removed
1004 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1004 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1005 8 additional largefiles cached
1005 8 additional largefiles cached
1006
1006
1007 $ rm "${USERCACHE}"/*
1007 $ rm "${USERCACHE}"/*
1008 $ hg clone --all-largefiles -u 0 a a-clone0
1008 $ hg clone --all-largefiles -u 0 a a-clone0
1009 updating to branch default
1009 updating to branch default
1010 getting changed largefiles
1010 getting changed largefiles
1011 2 largefiles updated, 0 removed
1011 2 largefiles updated, 0 removed
1012 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1012 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1013 9 additional largefiles cached
1013 9 additional largefiles cached
1014 $ hg -R a-clone0 sum
1014 $ hg -R a-clone0 sum
1015 parent: 0:30d30fe6a5be
1015 parent: 0:30d30fe6a5be
1016 add files
1016 add files
1017 branch: default
1017 branch: default
1018 commit: (clean)
1018 commit: (clean)
1019 update: 7 new changesets (update)
1019 update: 7 new changesets (update)
1020 phases: 8 draft
1020 phases: 8 draft
1021
1021
1022 $ rm "${USERCACHE}"/*
1022 $ rm "${USERCACHE}"/*
1023 $ hg clone --all-largefiles -u 1 a a-clone1
1023 $ hg clone --all-largefiles -u 1 a a-clone1
1024 updating to branch default
1024 updating to branch default
1025 getting changed largefiles
1025 getting changed largefiles
1026 2 largefiles updated, 0 removed
1026 2 largefiles updated, 0 removed
1027 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1027 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1028 8 additional largefiles cached
1028 8 additional largefiles cached
1029 $ hg -R a-clone1 verify --large --lfa --lfc
1029 $ hg -R a-clone1 verify --large --lfa --lfc
1030 checking changesets
1030 checking changesets
1031 checking manifests
1031 checking manifests
1032 crosschecking files in changesets and manifests
1032 crosschecking files in changesets and manifests
1033 checking files
1033 checking files
1034 checked 8 changesets with 24 changes to 10 files
1034 checked 8 changesets with 24 changes to 10 files
1035 searching 8 changesets for largefiles
1035 searching 8 changesets for largefiles
1036 verified contents of 13 revisions of 6 largefiles
1036 verified contents of 13 revisions of 6 largefiles
1037 $ hg -R a-clone1 sum
1037 $ hg -R a-clone1 sum
1038 parent: 1:ce8896473775
1038 parent: 1:ce8896473775
1039 edit files
1039 edit files
1040 branch: default
1040 branch: default
1041 commit: (clean)
1041 commit: (clean)
1042 update: 6 new changesets (update)
1042 update: 6 new changesets (update)
1043 phases: 8 draft
1043 phases: 8 draft
1044
1044
1045 $ rm "${USERCACHE}"/*
1045 $ rm "${USERCACHE}"/*
1046 $ hg clone --all-largefiles -U a a-clone-u
1046 $ hg clone --all-largefiles -U a a-clone-u
1047 11 additional largefiles cached
1047 11 additional largefiles cached
1048 $ hg -R a-clone-u sum
1048 $ hg -R a-clone-u sum
1049 parent: -1:000000000000 (no revision checked out)
1049 parent: -1:000000000000 (no revision checked out)
1050 branch: default
1050 branch: default
1051 commit: (clean)
1051 commit: (clean)
1052 update: 8 new changesets (update)
1052 update: 8 new changesets (update)
1053 phases: 8 draft
1053 phases: 8 draft
1054
1054
1055 Show computed destination directory:
1055 Show computed destination directory:
1056
1056
1057 $ mkdir xyz
1057 $ mkdir xyz
1058 $ cd xyz
1058 $ cd xyz
1059 $ hg clone ../a
1059 $ hg clone ../a
1060 destination directory: a
1060 destination directory: a
1061 updating to branch default
1061 updating to branch default
1062 getting changed largefiles
1062 getting changed largefiles
1063 3 largefiles updated, 0 removed
1063 3 largefiles updated, 0 removed
1064 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1064 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1065 $ cd ..
1065 $ cd ..
1066
1066
1067 Clone URL without path:
1067 Clone URL without path:
1068
1068
1069 $ hg clone file://
1069 $ hg clone file://
1070 abort: repository / not found!
1070 abort: repository / not found!
1071 [255]
1071 [255]
1072
1072
1073 Ensure base clone command argument validation
1073 Ensure base clone command argument validation
1074
1074
1075 $ hg clone -U -u 0 a a-clone-failure
1075 $ hg clone -U -u 0 a a-clone-failure
1076 abort: cannot specify both --noupdate and --updaterev
1076 abort: cannot specify both --noupdate and --updaterev
1077 [255]
1077 [255]
1078
1078
1079 $ hg clone --all-largefiles a ssh://localhost/a
1079 $ hg clone --all-largefiles a ssh://localhost/a
1080 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
1080 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
1081 [255]
1081 [255]
1082
1082
1083 Test pulling with --all-largefiles flag. Also test that the largefiles are
1083 Test pulling with --all-largefiles flag. Also test that the largefiles are
1084 downloaded from 'default' instead of 'default-push' when no source is specified
1084 downloaded from 'default' instead of 'default-push' when no source is specified
1085 (issue3584)
1085 (issue3584)
1086
1086
1087 $ rm -Rf a-backup
1087 $ rm -Rf a-backup
1088 $ hg clone -r 1 a a-backup
1088 $ hg clone -r 1 a a-backup
1089 adding changesets
1089 adding changesets
1090 adding manifests
1090 adding manifests
1091 adding file changes
1091 adding file changes
1092 added 2 changesets with 8 changes to 4 files
1092 added 2 changesets with 8 changes to 4 files
1093 new changesets 30d30fe6a5be:ce8896473775 (2 drafts)
1093 new changesets 30d30fe6a5be:ce8896473775 (2 drafts)
1094 updating to branch default
1094 updating to branch default
1095 getting changed largefiles
1095 getting changed largefiles
1096 2 largefiles updated, 0 removed
1096 2 largefiles updated, 0 removed
1097 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1097 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1098 $ rm "${USERCACHE}"/*
1098 $ rm "${USERCACHE}"/*
1099 $ cd a-backup
1099 $ cd a-backup
1100 $ hg pull --all-largefiles --config paths.default-push=bogus/path
1100 $ hg pull --all-largefiles --config paths.default-push=bogus/path
1101 pulling from $TESTTMP/a
1101 pulling from $TESTTMP/a
1102 searching for changes
1102 searching for changes
1103 adding changesets
1103 adding changesets
1104 adding manifests
1104 adding manifests
1105 adding file changes
1105 adding file changes
1106 added 6 changesets with 16 changes to 8 files
1106 added 6 changesets with 16 changes to 8 files
1107 new changesets 51a0ae4d5864:daea875e9014 (6 drafts)
1107 new changesets 51a0ae4d5864:daea875e9014 (6 drafts)
1108 (run 'hg update' to get a working copy)
1108 (run 'hg update' to get a working copy)
1109 6 largefiles cached
1109 6 largefiles cached
1110
1110
1111 redo pull with --lfrev and check it pulls largefiles for the right revs
1111 redo pull with --lfrev and check it pulls largefiles for the right revs
1112
1112
1113 $ hg rollback
1113 $ hg rollback
1114 repository tip rolled back to revision 1 (undo pull)
1114 repository tip rolled back to revision 1 (undo pull)
1115 $ hg pull -v --lfrev 'heads(pulled())+min(pulled())'
1115 $ hg pull -v --lfrev 'heads(pulled())+min(pulled())'
1116 pulling from $TESTTMP/a
1116 pulling from $TESTTMP/a
1117 searching for changes
1117 searching for changes
1118 all local heads known remotely
1118 all local heads known remotely
1119 6 changesets found
1119 6 changesets found
1120 uncompressed size of bundle content:
1120 uncompressed size of bundle content:
1121 1389 (changelog)
1121 1389 (changelog)
1122 1599 (manifests)
1122 1599 (manifests)
1123 254 .hglf/large1
1123 254 .hglf/large1
1124 564 .hglf/large3
1124 564 .hglf/large3
1125 572 .hglf/sub/large4
1125 572 .hglf/sub/large4
1126 182 .hglf/sub2/large6
1126 182 .hglf/sub2/large6
1127 182 .hglf/sub2/large7
1127 182 .hglf/sub2/large7
1128 212 normal1
1128 212 normal1
1129 457 normal3
1129 457 normal3
1130 465 sub/normal4
1130 465 sub/normal4
1131 adding changesets
1131 adding changesets
1132 adding manifests
1132 adding manifests
1133 adding file changes
1133 adding file changes
1134 added 6 changesets with 16 changes to 8 files
1134 added 6 changesets with 16 changes to 8 files
1135 new changesets 51a0ae4d5864:daea875e9014 (6 drafts)
1135 new changesets 51a0ae4d5864:daea875e9014 (6 drafts)
1136 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
1136 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
1137 (run 'hg update' to get a working copy)
1137 (run 'hg update' to get a working copy)
1138 pulling largefiles for revision 7
1138 pulling largefiles for revision 7
1139 found 971fb41e78fea4f8e0ba5244784239371cb00591 in store
1139 found 971fb41e78fea4f8e0ba5244784239371cb00591 in store
1140 found 0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30 in store
1140 found 0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30 in store
1141 found bb3151689acb10f0c3125c560d5e63df914bc1af in store
1141 found bb3151689acb10f0c3125c560d5e63df914bc1af in store
1142 pulling largefiles for revision 2
1142 pulling largefiles for revision 2
1143 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1143 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1144 0 largefiles cached
1144 0 largefiles cached
1145
1145
1146 lfpull
1146 lfpull
1147
1147
1148 $ hg lfpull -r : --config largefiles.usercache=usercache-lfpull
1148 $ hg lfpull -r : --config largefiles.usercache=usercache-lfpull
1149 2 largefiles cached
1149 2 largefiles cached
1150 $ hg lfpull -v -r 4+2 --config largefiles.usercache=usercache-lfpull
1150 $ hg lfpull -v -r 4+2 --config largefiles.usercache=usercache-lfpull
1151 pulling largefiles for revision 4
1151 pulling largefiles for revision 4
1152 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1152 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1153 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1153 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1154 pulling largefiles for revision 2
1154 pulling largefiles for revision 2
1155 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1155 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1156 0 largefiles cached
1156 0 largefiles cached
1157
1157
1158 $ ls usercache-lfpull/* | sort
1158 $ ls usercache-lfpull/* | sort
1159 usercache-lfpull/1deebade43c8c498a3c8daddac0244dc55d1331d
1159 usercache-lfpull/1deebade43c8c498a3c8daddac0244dc55d1331d
1160 usercache-lfpull/4669e532d5b2c093a78eca010077e708a071bb64
1160 usercache-lfpull/4669e532d5b2c093a78eca010077e708a071bb64
1161
1161
1162 $ cd ..
1162 $ cd ..
1163
1163
1164 Rebasing between two repositories does not revert largefiles to old
1164 Rebasing between two repositories does not revert largefiles to old
1165 revisions (this was a very bad bug that took a lot of work to fix).
1165 revisions (this was a very bad bug that took a lot of work to fix).
1166
1166
1167 $ hg clone a d
1167 $ hg clone a d
1168 updating to branch default
1168 updating to branch default
1169 getting changed largefiles
1169 getting changed largefiles
1170 3 largefiles updated, 0 removed
1170 3 largefiles updated, 0 removed
1171 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1171 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1172 $ cd b
1172 $ cd b
1173 $ echo large4-modified > sub/large4
1173 $ echo large4-modified > sub/large4
1174 $ echo normal3-modified > normal3
1174 $ echo normal3-modified > normal3
1175 $ hg commit -m "modify normal file and largefile in repo b"
1175 $ hg commit -m "modify normal file and largefile in repo b"
1176 Invoking status precommit hook
1176 Invoking status precommit hook
1177 M normal3
1177 M normal3
1178 M sub/large4
1178 M sub/large4
1179 $ cd ../d
1179 $ cd ../d
1180 $ echo large6-modified > sub2/large6
1180 $ echo large6-modified > sub2/large6
1181 $ echo normal4-modified > sub/normal4
1181 $ echo normal4-modified > sub/normal4
1182 $ hg commit -m "modify normal file largefile in repo d"
1182 $ hg commit -m "modify normal file largefile in repo d"
1183 Invoking status precommit hook
1183 Invoking status precommit hook
1184 M sub/normal4
1184 M sub/normal4
1185 M sub2/large6
1185 M sub2/large6
1186 $ cd ..
1186 $ cd ..
1187 $ hg clone d e
1187 $ hg clone d e
1188 updating to branch default
1188 updating to branch default
1189 getting changed largefiles
1189 getting changed largefiles
1190 3 largefiles updated, 0 removed
1190 3 largefiles updated, 0 removed
1191 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1191 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1192 $ cd d
1192 $ cd d
1193
1193
1194 More rebase testing, but also test that the largefiles are downloaded from
1194 More rebase testing, but also test that the largefiles are downloaded from
1195 'default-push' when no source is specified (issue3584). (The largefile from the
1195 'default-push' when no source is specified (issue3584). (The largefile from the
1196 pulled revision is however not downloaded but found in the local cache.)
1196 pulled revision is however not downloaded but found in the local cache.)
1197 Largefiles are fetched for the new pulled revision, not for existing revisions,
1197 Largefiles are fetched for the new pulled revision, not for existing revisions,
1198 rebased or not.
1198 rebased or not.
1199
1199
1200 $ [ ! -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1200 $ [ ! -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1201 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
1201 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
1202 pulling from $TESTTMP/b
1202 pulling from $TESTTMP/b
1203 searching for changes
1203 searching for changes
1204 adding changesets
1204 adding changesets
1205 adding manifests
1205 adding manifests
1206 adding file changes
1206 adding file changes
1207 added 1 changesets with 2 changes to 2 files (+1 heads)
1207 added 1 changesets with 2 changes to 2 files (+1 heads)
1208 new changesets a381d2c8c80e (1 drafts)
1208 new changesets a381d2c8c80e (1 drafts)
1209 rebasing 8:f574fb32bb45 "modify normal file largefile in repo d"
1209 rebasing 8:f574fb32bb45 "modify normal file largefile in repo d"
1210 Invoking status precommit hook
1210 Invoking status precommit hook
1211 M sub/normal4
1211 M sub/normal4
1212 M sub2/large6
1212 M sub2/large6
1213 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-dd1d9f80-rebase.hg
1213 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-dd1d9f80-rebase.hg
1214 0 largefiles cached
1214 0 largefiles cached
1215 $ [ -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1215 $ [ -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1216 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1216 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1217 9:598410d3eb9a modify normal file largefile in repo d
1217 9:598410d3eb9a modify normal file largefile in repo d
1218 8:a381d2c8c80e modify normal file and largefile in repo b
1218 8:a381d2c8c80e modify normal file and largefile in repo b
1219 7:daea875e9014 add/edit more largefiles
1219 7:daea875e9014 add/edit more largefiles
1220 6:4355d653f84f edit files yet again
1220 6:4355d653f84f edit files yet again
1221 5:9d5af5072dbd edit files again
1221 5:9d5af5072dbd edit files again
1222 4:74c02385b94c move files
1222 4:74c02385b94c move files
1223 3:9e8fbc4bce62 copy files
1223 3:9e8fbc4bce62 copy files
1224 2:51a0ae4d5864 remove files
1224 2:51a0ae4d5864 remove files
1225 1:ce8896473775 edit files
1225 1:ce8896473775 edit files
1226 0:30d30fe6a5be add files
1226 0:30d30fe6a5be add files
1227 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
1227 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
1228 @ 9:598410d3eb9a modify normal file largefile in repo d
1228 @ 9:598410d3eb9a modify normal file largefile in repo d
1229 |
1229 |
1230 o 8:a381d2c8c80e modify normal file and largefile in repo b
1230 o 8:a381d2c8c80e modify normal file and largefile in repo b
1231 |
1231 |
1232 o 7:daea875e9014 add/edit more largefiles
1232 o 7:daea875e9014 add/edit more largefiles
1233 |
1233 |
1234 o 6:4355d653f84f edit files yet again
1234 o 6:4355d653f84f edit files yet again
1235 |
1235 |
1236 o 5:9d5af5072dbd edit files again
1236 o 5:9d5af5072dbd edit files again
1237 |
1237 |
1238 o 4:74c02385b94c move files
1238 o 4:74c02385b94c move files
1239 |
1239 |
1240 o 3:9e8fbc4bce62 copy files
1240 o 3:9e8fbc4bce62 copy files
1241 |
1241 |
1242 o 2:51a0ae4d5864 remove files
1242 o 2:51a0ae4d5864 remove files
1243 |
1243 |
1244 o 1:ce8896473775 edit files
1244 o 1:ce8896473775 edit files
1245 |
1245 |
1246 o 0:30d30fe6a5be add files
1246 o 0:30d30fe6a5be add files
1247
1247
1248 $ cat normal3
1248 $ cat normal3
1249 normal3-modified
1249 normal3-modified
1250 $ cat sub/normal4
1250 $ cat sub/normal4
1251 normal4-modified
1251 normal4-modified
1252 $ cat sub/large4
1252 $ cat sub/large4
1253 large4-modified
1253 large4-modified
1254 $ cat sub2/large6
1254 $ cat sub2/large6
1255 large6-modified
1255 large6-modified
1256 $ cat sub2/large7
1256 $ cat sub2/large7
1257 large7
1257 large7
1258 $ cd ../e
1258 $ cd ../e
1259 $ hg pull ../b
1259 $ hg pull ../b
1260 pulling from ../b
1260 pulling from ../b
1261 searching for changes
1261 searching for changes
1262 adding changesets
1262 adding changesets
1263 adding manifests
1263 adding manifests
1264 adding file changes
1264 adding file changes
1265 added 1 changesets with 2 changes to 2 files (+1 heads)
1265 added 1 changesets with 2 changes to 2 files (+1 heads)
1266 new changesets a381d2c8c80e (1 drafts)
1266 new changesets a381d2c8c80e (1 drafts)
1267 (run 'hg heads' to see heads, 'hg merge' to merge)
1267 (run 'hg heads' to see heads, 'hg merge' to merge)
1268 $ hg rebase
1268 $ hg rebase
1269 rebasing 8:f574fb32bb45 "modify normal file largefile in repo d"
1269 rebasing 8:f574fb32bb45 "modify normal file largefile in repo d"
1270 Invoking status precommit hook
1270 Invoking status precommit hook
1271 M sub/normal4
1271 M sub/normal4
1272 M sub2/large6
1272 M sub2/large6
1273 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-dd1d9f80-rebase.hg
1273 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-dd1d9f80-rebase.hg
1274 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1274 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1275 9:598410d3eb9a modify normal file largefile in repo d
1275 9:598410d3eb9a modify normal file largefile in repo d
1276 8:a381d2c8c80e modify normal file and largefile in repo b
1276 8:a381d2c8c80e modify normal file and largefile in repo b
1277 7:daea875e9014 add/edit more largefiles
1277 7:daea875e9014 add/edit more largefiles
1278 6:4355d653f84f edit files yet again
1278 6:4355d653f84f edit files yet again
1279 5:9d5af5072dbd edit files again
1279 5:9d5af5072dbd edit files again
1280 4:74c02385b94c move files
1280 4:74c02385b94c move files
1281 3:9e8fbc4bce62 copy files
1281 3:9e8fbc4bce62 copy files
1282 2:51a0ae4d5864 remove files
1282 2:51a0ae4d5864 remove files
1283 1:ce8896473775 edit files
1283 1:ce8896473775 edit files
1284 0:30d30fe6a5be add files
1284 0:30d30fe6a5be add files
1285 $ cat normal3
1285 $ cat normal3
1286 normal3-modified
1286 normal3-modified
1287 $ cat sub/normal4
1287 $ cat sub/normal4
1288 normal4-modified
1288 normal4-modified
1289 $ cat sub/large4
1289 $ cat sub/large4
1290 large4-modified
1290 large4-modified
1291 $ cat sub2/large6
1291 $ cat sub2/large6
1292 large6-modified
1292 large6-modified
1293 $ cat sub2/large7
1293 $ cat sub2/large7
1294 large7
1294 large7
1295
1295
1296 Log on largefiles
1296 Log on largefiles
1297
1297
1298 - same output
1298 - same output
1299 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1299 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1300 8:a381d2c8c80e modify normal file and largefile in repo b
1300 8:a381d2c8c80e modify normal file and largefile in repo b
1301 6:4355d653f84f edit files yet again
1301 6:4355d653f84f edit files yet again
1302 5:9d5af5072dbd edit files again
1302 5:9d5af5072dbd edit files again
1303 4:74c02385b94c move files
1303 4:74c02385b94c move files
1304 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1304 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1305 o 8:a381d2c8c80e modify normal file and largefile in repo b
1305 o 8:a381d2c8c80e modify normal file and largefile in repo b
1306 :
1306 :
1307 o 6:4355d653f84f edit files yet again
1307 o 6:4355d653f84f edit files yet again
1308 |
1308 |
1309 o 5:9d5af5072dbd edit files again
1309 o 5:9d5af5072dbd edit files again
1310 |
1310 |
1311 o 4:74c02385b94c move files
1311 o 4:74c02385b94c move files
1312 |
1312 |
1313 ~
1313 ~
1314 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
1314 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
1315 8:a381d2c8c80e modify normal file and largefile in repo b
1315 8:a381d2c8c80e modify normal file and largefile in repo b
1316 6:4355d653f84f edit files yet again
1316 6:4355d653f84f edit files yet again
1317 5:9d5af5072dbd edit files again
1317 5:9d5af5072dbd edit files again
1318 4:74c02385b94c move files
1318 4:74c02385b94c move files
1319 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1319 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1320 o 8:a381d2c8c80e modify normal file and largefile in repo b
1320 o 8:a381d2c8c80e modify normal file and largefile in repo b
1321 :
1321 :
1322 o 6:4355d653f84f edit files yet again
1322 o 6:4355d653f84f edit files yet again
1323 |
1323 |
1324 o 5:9d5af5072dbd edit files again
1324 o 5:9d5af5072dbd edit files again
1325 |
1325 |
1326 o 4:74c02385b94c move files
1326 o 4:74c02385b94c move files
1327 |
1327 |
1328 ~
1328 ~
1329
1329
1330 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1330 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1331 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1331 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1332 8:a381d2c8c80e modify normal file and largefile in repo b
1332 8:a381d2c8c80e modify normal file and largefile in repo b
1333 6:4355d653f84f edit files yet again
1333 6:4355d653f84f edit files yet again
1334 5:9d5af5072dbd edit files again
1334 5:9d5af5072dbd edit files again
1335 4:74c02385b94c move files
1335 4:74c02385b94c move files
1336 1:ce8896473775 edit files
1336 1:ce8896473775 edit files
1337 0:30d30fe6a5be add files
1337 0:30d30fe6a5be add files
1338 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1338 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1339 o 8:a381d2c8c80e modify normal file and largefile in repo b
1339 o 8:a381d2c8c80e modify normal file and largefile in repo b
1340 :
1340 :
1341 o 6:4355d653f84f edit files yet again
1341 o 6:4355d653f84f edit files yet again
1342 |
1342 |
1343 o 5:9d5af5072dbd edit files again
1343 o 5:9d5af5072dbd edit files again
1344 |
1344 |
1345 o 4:74c02385b94c move files
1345 o 4:74c02385b94c move files
1346 :
1346 :
1347 o 1:ce8896473775 edit files
1347 o 1:ce8896473775 edit files
1348 |
1348 |
1349 o 0:30d30fe6a5be add files
1349 o 0:30d30fe6a5be add files
1350
1350
1351 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1351 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1352 9:598410d3eb9a modify normal file largefile in repo d
1352 9:598410d3eb9a modify normal file largefile in repo d
1353 8:a381d2c8c80e modify normal file and largefile in repo b
1353 8:a381d2c8c80e modify normal file and largefile in repo b
1354 6:4355d653f84f edit files yet again
1354 6:4355d653f84f edit files yet again
1355 5:9d5af5072dbd edit files again
1355 5:9d5af5072dbd edit files again
1356 4:74c02385b94c move files
1356 4:74c02385b94c move files
1357 1:ce8896473775 edit files
1357 1:ce8896473775 edit files
1358 0:30d30fe6a5be add files
1358 0:30d30fe6a5be add files
1359 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' sub
1359 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' sub
1360 @ 9:598410d3eb9a modify normal file largefile in repo d
1360 @ 9:598410d3eb9a modify normal file largefile in repo d
1361 |
1361 |
1362 o 8:a381d2c8c80e modify normal file and largefile in repo b
1362 o 8:a381d2c8c80e modify normal file and largefile in repo b
1363 :
1363 :
1364 o 6:4355d653f84f edit files yet again
1364 o 6:4355d653f84f edit files yet again
1365 |
1365 |
1366 o 5:9d5af5072dbd edit files again
1366 o 5:9d5af5072dbd edit files again
1367 |
1367 |
1368 o 4:74c02385b94c move files
1368 o 4:74c02385b94c move files
1369 :
1369 :
1370 o 1:ce8896473775 edit files
1370 o 1:ce8896473775 edit files
1371 |
1371 |
1372 o 0:30d30fe6a5be add files
1372 o 0:30d30fe6a5be add files
1373
1373
1374 - globbing gives same result
1374 - globbing gives same result
1375 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1375 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1376 9:598410d3eb9a modify normal file largefile in repo d
1376 9:598410d3eb9a modify normal file largefile in repo d
1377 8:a381d2c8c80e modify normal file and largefile in repo b
1377 8:a381d2c8c80e modify normal file and largefile in repo b
1378 6:4355d653f84f edit files yet again
1378 6:4355d653f84f edit files yet again
1379 5:9d5af5072dbd edit files again
1379 5:9d5af5072dbd edit files again
1380 4:74c02385b94c move files
1380 4:74c02385b94c move files
1381 1:ce8896473775 edit files
1381 1:ce8896473775 edit files
1382 0:30d30fe6a5be add files
1382 0:30d30fe6a5be add files
1383 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1383 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1384 @ 9:598410d3eb9a modify normal file largefile in repo d
1384 @ 9:598410d3eb9a modify normal file largefile in repo d
1385 |
1385 |
1386 o 8:a381d2c8c80e modify normal file and largefile in repo b
1386 o 8:a381d2c8c80e modify normal file and largefile in repo b
1387 :
1387 :
1388 o 6:4355d653f84f edit files yet again
1388 o 6:4355d653f84f edit files yet again
1389 |
1389 |
1390 o 5:9d5af5072dbd edit files again
1390 o 5:9d5af5072dbd edit files again
1391 |
1391 |
1392 o 4:74c02385b94c move files
1392 o 4:74c02385b94c move files
1393 :
1393 :
1394 o 1:ce8896473775 edit files
1394 o 1:ce8896473775 edit files
1395 |
1395 |
1396 o 0:30d30fe6a5be add files
1396 o 0:30d30fe6a5be add files
1397
1397
1398 Rollback on largefiles.
1398 Rollback on largefiles.
1399
1399
1400 $ echo large4-modified-again > sub/large4
1400 $ echo large4-modified-again > sub/large4
1401 $ hg commit -m "Modify large4 again"
1401 $ hg commit -m "Modify large4 again"
1402 Invoking status precommit hook
1402 Invoking status precommit hook
1403 M sub/large4
1403 M sub/large4
1404 $ hg rollback
1404 $ hg rollback
1405 repository tip rolled back to revision 9 (undo commit)
1405 repository tip rolled back to revision 9 (undo commit)
1406 working directory now based on revision 9
1406 working directory now based on revision 9
1407 $ hg st
1407 $ hg st
1408 M sub/large4
1408 M sub/large4
1409 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1409 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1410 9:598410d3eb9a modify normal file largefile in repo d
1410 9:598410d3eb9a modify normal file largefile in repo d
1411 8:a381d2c8c80e modify normal file and largefile in repo b
1411 8:a381d2c8c80e modify normal file and largefile in repo b
1412 7:daea875e9014 add/edit more largefiles
1412 7:daea875e9014 add/edit more largefiles
1413 6:4355d653f84f edit files yet again
1413 6:4355d653f84f edit files yet again
1414 5:9d5af5072dbd edit files again
1414 5:9d5af5072dbd edit files again
1415 4:74c02385b94c move files
1415 4:74c02385b94c move files
1416 3:9e8fbc4bce62 copy files
1416 3:9e8fbc4bce62 copy files
1417 2:51a0ae4d5864 remove files
1417 2:51a0ae4d5864 remove files
1418 1:ce8896473775 edit files
1418 1:ce8896473775 edit files
1419 0:30d30fe6a5be add files
1419 0:30d30fe6a5be add files
1420 $ cat sub/large4
1420 $ cat sub/large4
1421 large4-modified-again
1421 large4-modified-again
1422
1422
1423 "update --check" refuses to update with uncommitted changes.
1423 "update --check" refuses to update with uncommitted changes.
1424 $ hg update --check 8
1424 $ hg update --check 8
1425 abort: uncommitted changes
1425 abort: uncommitted changes
1426 [255]
1426 [255]
1427
1427
1428 "update --clean" leaves correct largefiles in working copy, even when there is
1428 "update --clean" leaves correct largefiles in working copy, even when there is
1429 .orig files from revert in .hglf.
1429 .orig files from revert in .hglf.
1430
1430
1431 $ echo mistake > sub2/large7
1431 $ echo mistake > sub2/large7
1432 $ hg revert sub2/large7
1432 $ hg revert sub2/large7
1433 $ cat sub2/large7
1433 $ cat sub2/large7
1434 large7
1434 large7
1435 $ cat sub2/large7.orig
1435 $ cat sub2/large7.orig
1436 mistake
1436 mistake
1437 $ test ! -f .hglf/sub2/large7.orig
1437 $ test ! -f .hglf/sub2/large7.orig
1438
1438
1439 $ hg -q update --clean -r null
1439 $ hg -q update --clean -r null
1440 $ hg update --clean
1440 $ hg update --clean
1441 getting changed largefiles
1441 getting changed largefiles
1442 3 largefiles updated, 0 removed
1442 3 largefiles updated, 0 removed
1443 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1443 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1444 $ cat normal3
1444 $ cat normal3
1445 normal3-modified
1445 normal3-modified
1446 $ cat sub/normal4
1446 $ cat sub/normal4
1447 normal4-modified
1447 normal4-modified
1448 $ cat sub/large4
1448 $ cat sub/large4
1449 large4-modified
1449 large4-modified
1450 $ cat sub2/large6
1450 $ cat sub2/large6
1451 large6-modified
1451 large6-modified
1452 $ cat sub2/large7
1452 $ cat sub2/large7
1453 large7
1453 large7
1454 $ cat sub2/large7.orig
1454 $ cat sub2/large7.orig
1455 mistake
1455 mistake
1456 $ test ! -f .hglf/sub2/large7.orig
1456 $ test ! -f .hglf/sub2/large7.orig
1457
1457
1458 verify that largefile .orig file no longer is overwritten on every update -C:
1458 verify that largefile .orig file no longer is overwritten on every update -C:
1459 $ hg update --clean
1459 $ hg update --clean
1460 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1460 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1461 $ cat sub2/large7.orig
1461 $ cat sub2/large7.orig
1462 mistake
1462 mistake
1463 $ rm sub2/large7.orig
1463 $ rm sub2/large7.orig
1464
1464
1465 Now "update check" is happy.
1465 Now "update check" is happy.
1466 $ hg update --check 8
1466 $ hg update --check 8
1467 getting changed largefiles
1467 getting changed largefiles
1468 1 largefiles updated, 0 removed
1468 1 largefiles updated, 0 removed
1469 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1469 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1470 $ hg update --check
1470 $ hg update --check
1471 getting changed largefiles
1471 getting changed largefiles
1472 1 largefiles updated, 0 removed
1472 1 largefiles updated, 0 removed
1473 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1473 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1474
1474
1475 Test removing empty largefiles directories on update
1475 Test removing empty largefiles directories on update
1476 $ test -d sub2 && echo "sub2 exists"
1476 $ test -d sub2 && echo "sub2 exists"
1477 sub2 exists
1477 sub2 exists
1478 $ hg update -q null
1478 $ hg update -q null
1479 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1479 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1480 [1]
1480 [1]
1481 $ hg update -q
1481 $ hg update -q
1482
1482
1483 Test hg remove removes empty largefiles directories
1483 Test hg remove removes empty largefiles directories
1484 $ test -d sub2 && echo "sub2 exists"
1484 $ test -d sub2 && echo "sub2 exists"
1485 sub2 exists
1485 sub2 exists
1486 $ hg remove sub2/*
1486 $ hg remove sub2/*
1487 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1487 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1488 [1]
1488 [1]
1489 $ hg revert sub2/large6 sub2/large7
1489 $ hg revert sub2/large6 sub2/large7
1490
1490
1491 "revert" works on largefiles (and normal files too).
1491 "revert" works on largefiles (and normal files too).
1492 $ echo hack3 >> normal3
1492 $ echo hack3 >> normal3
1493 $ echo hack4 >> sub/normal4
1493 $ echo hack4 >> sub/normal4
1494 $ echo hack4 >> sub/large4
1494 $ echo hack4 >> sub/large4
1495 $ rm sub2/large6
1495 $ rm sub2/large6
1496 $ hg revert sub2/large6
1496 $ hg revert sub2/large6
1497 $ hg rm sub2/large6
1497 $ hg rm sub2/large6
1498 $ echo new >> sub2/large8
1498 $ echo new >> sub2/large8
1499 $ hg add --large sub2/large8
1499 $ hg add --large sub2/large8
1500 # XXX we don't really want to report that we're reverting the standin;
1500 # XXX we don't really want to report that we're reverting the standin;
1501 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1501 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1502 $ hg revert sub
1502 $ hg revert sub
1503 reverting .hglf/sub/large4
1503 reverting .hglf/sub/large4
1504 reverting sub/normal4
1504 reverting sub/normal4
1505 $ hg status
1505 $ hg status
1506 M normal3
1506 M normal3
1507 A sub2/large8
1507 A sub2/large8
1508 R sub2/large6
1508 R sub2/large6
1509 ? sub/large4.orig
1509 ? sub/large4.orig
1510 ? sub/normal4.orig
1510 ? sub/normal4.orig
1511 $ cat sub/normal4
1511 $ cat sub/normal4
1512 normal4-modified
1512 normal4-modified
1513 $ cat sub/large4
1513 $ cat sub/large4
1514 large4-modified
1514 large4-modified
1515 $ hg revert -a --no-backup
1515 $ hg revert -a --no-backup
1516 forgetting .hglf/sub2/large8
1516 forgetting .hglf/sub2/large8
1517 reverting normal3
1517 reverting normal3
1518 undeleting .hglf/sub2/large6
1518 undeleting .hglf/sub2/large6
1519 $ hg status
1519 $ hg status
1520 ? sub/large4.orig
1520 ? sub/large4.orig
1521 ? sub/normal4.orig
1521 ? sub/normal4.orig
1522 ? sub2/large8
1522 ? sub2/large8
1523 $ cat normal3
1523 $ cat normal3
1524 normal3-modified
1524 normal3-modified
1525 $ cat sub2/large6
1525 $ cat sub2/large6
1526 large6-modified
1526 large6-modified
1527 $ rm sub/*.orig sub2/large8
1527 $ rm sub/*.orig sub2/large8
1528
1528
1529 revert some files to an older revision
1529 revert some files to an older revision
1530 $ hg revert --no-backup -r 8 sub2
1530 $ hg revert --no-backup -r 8 sub2
1531 reverting .hglf/sub2/large6
1531 reverting .hglf/sub2/large6
1532 $ cat sub2/large6
1532 $ cat sub2/large6
1533 large6
1533 large6
1534 $ hg revert --no-backup -C -r '.^' sub2
1534 $ hg revert --no-backup -C -r '.^' sub2
1535 $ hg revert --no-backup sub2
1535 $ hg revert --no-backup sub2
1536 reverting .hglf/sub2/large6
1536 reverting .hglf/sub2/large6
1537 $ hg status
1537 $ hg status
1538
1538
1539 "verify --large" actually verifies largefiles
1539 "verify --large" actually verifies largefiles
1540
1540
1541 - Where Do We Come From? What Are We? Where Are We Going?
1541 - Where Do We Come From? What Are We? Where Are We Going?
1542 $ pwd
1542 $ pwd
1543 $TESTTMP/e
1543 $TESTTMP/e
1544 $ hg paths
1544 $ hg paths
1545 default = $TESTTMP/d
1545 default = $TESTTMP/d
1546
1546
1547 $ hg verify --large
1547 $ hg verify --large
1548 checking changesets
1548 checking changesets
1549 checking manifests
1549 checking manifests
1550 crosschecking files in changesets and manifests
1550 crosschecking files in changesets and manifests
1551 checking files
1551 checking files
1552 checked 10 changesets with 28 changes to 10 files
1552 checked 10 changesets with 28 changes to 10 files
1553 searching 1 changesets for largefiles
1553 searching 1 changesets for largefiles
1554 verified existence of 3 revisions of 3 largefiles
1554 verified existence of 3 revisions of 3 largefiles
1555
1555
1556 - introduce missing blob in local store repo and remote store
1556 - introduce missing blob in local store repo and remote store
1557 and make sure that this is caught:
1557 and make sure that this is caught:
1558
1558
1559 $ mv $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 .
1559 $ mv $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 .
1560 $ rm .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1560 $ rm .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1561 $ hg verify --large
1561 $ hg verify --large
1562 checking changesets
1562 checking changesets
1563 checking manifests
1563 checking manifests
1564 crosschecking files in changesets and manifests
1564 crosschecking files in changesets and manifests
1565 checking files
1565 checking files
1566 checked 10 changesets with 28 changes to 10 files
1566 checked 10 changesets with 28 changes to 10 files
1567 searching 1 changesets for largefiles
1567 searching 1 changesets for largefiles
1568 changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1568 changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1569 verified existence of 3 revisions of 3 largefiles
1569 verified existence of 3 revisions of 3 largefiles
1570 [1]
1570 [1]
1571
1571
1572 - introduce corruption and make sure that it is caught when checking content:
1572 - introduce corruption and make sure that it is caught when checking content:
1573 $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1573 $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1574 $ hg verify -q --large --lfc
1574 $ hg verify -q --large --lfc
1575 changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1575 changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1576 [1]
1576 [1]
1577
1577
1578 - cleanup
1578 - cleanup
1579 $ cp e166e74c7303192238d60af5a9c4ce9bef0b7928 $TESTTMP/d/.hg/largefiles/
1579 $ cp e166e74c7303192238d60af5a9c4ce9bef0b7928 $TESTTMP/d/.hg/largefiles/
1580 $ mv e166e74c7303192238d60af5a9c4ce9bef0b7928 .hg/largefiles/
1580 $ mv e166e74c7303192238d60af5a9c4ce9bef0b7928 .hg/largefiles/
1581
1581
1582 - verifying all revisions will fail because we didn't clone all largefiles to d:
1582 - verifying all revisions will fail because we didn't clone all largefiles to d:
1583 $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1583 $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1584 $ hg verify -q --lfa --lfc
1584 $ hg verify -q --lfa --lfc
1585 changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64
1585 changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64
1586 changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d
1586 changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d
1587 changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f
1587 changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f
1588 changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1588 changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1589 changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1589 changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1590 changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1590 changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1591 changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1591 changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1592 changeset 5:9d5af5072dbd: large3 references missing $TESTTMP/d/.hg/largefiles/baaf12afde9d8d67f25dab6dced0d2bf77dba47c
1592 changeset 5:9d5af5072dbd: large3 references missing $TESTTMP/d/.hg/largefiles/baaf12afde9d8d67f25dab6dced0d2bf77dba47c
1593 changeset 5:9d5af5072dbd: sub/large4 references missing $TESTTMP/d/.hg/largefiles/aeb2210d19f02886dde00dac279729a48471e2f9
1593 changeset 5:9d5af5072dbd: sub/large4 references missing $TESTTMP/d/.hg/largefiles/aeb2210d19f02886dde00dac279729a48471e2f9
1594 changeset 6:4355d653f84f: large3 references missing $TESTTMP/d/.hg/largefiles/7838695e10da2bb75ac1156565f40a2595fa2fa0
1594 changeset 6:4355d653f84f: large3 references missing $TESTTMP/d/.hg/largefiles/7838695e10da2bb75ac1156565f40a2595fa2fa0
1595 [1]
1595 [1]
1596
1596
1597 - cleanup
1597 - cleanup
1598 $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1598 $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1599 $ rm -f .hglf/sub/*.orig
1599 $ rm -f .hglf/sub/*.orig
1600
1600
1601 Update to revision with missing largefile - and make sure it really is missing
1601 Update to revision with missing largefile - and make sure it really is missing
1602
1602
1603 $ rm ${USERCACHE}/7838695e10da2bb75ac1156565f40a2595fa2fa0
1603 $ rm ${USERCACHE}/7838695e10da2bb75ac1156565f40a2595fa2fa0
1604 $ hg up -r 6
1604 $ hg up -r 6
1605 getting changed largefiles
1605 getting changed largefiles
1606 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1606 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1607 1 largefiles updated, 2 removed
1607 1 largefiles updated, 2 removed
1608 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
1608 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
1609 $ rm normal3
1609 $ rm normal3
1610 $ echo >> sub/normal4
1610 $ echo >> sub/normal4
1611 $ hg ci -m 'commit with missing files'
1611 $ hg ci -m 'commit with missing files'
1612 Invoking status precommit hook
1612 Invoking status precommit hook
1613 M sub/normal4
1613 M sub/normal4
1614 ! large3
1614 ! large3
1615 ! normal3
1615 ! normal3
1616 created new head
1616 created new head
1617 $ hg st
1617 $ hg st
1618 ! large3
1618 ! large3
1619 ! normal3
1619 ! normal3
1620 $ hg up -r.
1620 $ hg up -r.
1621 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1621 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1622 $ hg st
1622 $ hg st
1623 ! large3
1623 ! large3
1624 ! normal3
1624 ! normal3
1625 $ hg up -Cr.
1625 $ hg up -Cr.
1626 getting changed largefiles
1626 getting changed largefiles
1627 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1627 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1628 0 largefiles updated, 0 removed
1628 0 largefiles updated, 0 removed
1629 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1629 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1630 $ hg st
1630 $ hg st
1631 ! large3
1631 ! large3
1632 $ hg rollback
1632 $ hg rollback
1633 repository tip rolled back to revision 9 (undo commit)
1633 repository tip rolled back to revision 9 (undo commit)
1634 working directory now based on revision 6
1634 working directory now based on revision 6
1635
1635
1636 Merge with revision with missing largefile - and make sure it tries to fetch it.
1636 Merge with revision with missing largefile - and make sure it tries to fetch it.
1637
1637
1638 $ hg up -Cqr null
1638 $ hg up -Cqr null
1639 $ echo f > f
1639 $ echo f > f
1640 $ hg ci -Am branch
1640 $ hg ci -Am branch
1641 adding f
1641 adding f
1642 Invoking status precommit hook
1642 Invoking status precommit hook
1643 A f
1643 A f
1644 created new head
1644 created new head
1645 $ hg merge -r 6
1645 $ hg merge -r 6
1646 getting changed largefiles
1646 getting changed largefiles
1647 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1647 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1648 1 largefiles updated, 0 removed
1648 1 largefiles updated, 0 removed
1649 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1649 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1650 (branch merge, don't forget to commit)
1650 (branch merge, don't forget to commit)
1651
1651
1652 $ hg rollback -q
1652 $ hg rollback -q
1653 $ hg up -Cq
1653 $ hg up -Cq
1654
1654
1655 Pulling 0 revisions with --all-largefiles should not fetch for all revisions
1655 Pulling 0 revisions with --all-largefiles should not fetch for all revisions
1656
1656
1657 $ hg pull --all-largefiles
1657 $ hg pull --all-largefiles
1658 pulling from $TESTTMP/d
1658 pulling from $TESTTMP/d
1659 searching for changes
1659 searching for changes
1660 no changes found
1660 no changes found
1661
1661
1662 Merging does not revert to old versions of largefiles and also check
1662 Merging does not revert to old versions of largefiles and also check
1663 that merging after having pulled from a non-default remote works
1663 that merging after having pulled from a non-default remote works
1664 correctly.
1664 correctly.
1665
1665
1666 $ cd ..
1666 $ cd ..
1667 $ hg clone -r 7 e temp
1667 $ hg clone -r 7 e temp
1668 adding changesets
1668 adding changesets
1669 adding manifests
1669 adding manifests
1670 adding file changes
1670 adding file changes
1671 added 8 changesets with 24 changes to 10 files
1671 added 8 changesets with 24 changes to 10 files
1672 new changesets 30d30fe6a5be:daea875e9014 (8 drafts)
1672 new changesets 30d30fe6a5be:daea875e9014 (8 drafts)
1673 updating to branch default
1673 updating to branch default
1674 getting changed largefiles
1674 getting changed largefiles
1675 3 largefiles updated, 0 removed
1675 3 largefiles updated, 0 removed
1676 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1676 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1677 $ hg clone temp f
1677 $ hg clone temp f
1678 updating to branch default
1678 updating to branch default
1679 getting changed largefiles
1679 getting changed largefiles
1680 3 largefiles updated, 0 removed
1680 3 largefiles updated, 0 removed
1681 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1681 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1682 # Delete the largefiles in the largefiles system cache so that we have an
1682 # Delete the largefiles in the largefiles system cache so that we have an
1683 # opportunity to test that caching after a pull works.
1683 # opportunity to test that caching after a pull works.
1684 $ rm "${USERCACHE}"/*
1684 $ rm "${USERCACHE}"/*
1685 $ cd f
1685 $ cd f
1686 $ echo "large4-merge-test" > sub/large4
1686 $ echo "large4-merge-test" > sub/large4
1687 $ hg commit -m "Modify large4 to test merge"
1687 $ hg commit -m "Modify large4 to test merge"
1688 Invoking status precommit hook
1688 Invoking status precommit hook
1689 M sub/large4
1689 M sub/large4
1690 # Test --cache-largefiles flag
1690 # Test --cache-largefiles flag
1691 $ hg pull --lfrev 'heads(pulled())' ../e
1691 $ hg pull --lfrev 'heads(pulled())' ../e
1692 pulling from ../e
1692 pulling from ../e
1693 searching for changes
1693 searching for changes
1694 adding changesets
1694 adding changesets
1695 adding manifests
1695 adding manifests
1696 adding file changes
1696 adding file changes
1697 added 2 changesets with 4 changes to 4 files (+1 heads)
1697 added 2 changesets with 4 changes to 4 files (+1 heads)
1698 new changesets a381d2c8c80e:598410d3eb9a (2 drafts)
1698 new changesets a381d2c8c80e:598410d3eb9a (2 drafts)
1699 (run 'hg heads' to see heads, 'hg merge' to merge)
1699 (run 'hg heads' to see heads, 'hg merge' to merge)
1700 2 largefiles cached
1700 2 largefiles cached
1701 $ hg merge
1701 $ hg merge
1702 largefile sub/large4 has a merge conflict
1702 largefile sub/large4 has a merge conflict
1703 ancestor was 971fb41e78fea4f8e0ba5244784239371cb00591
1703 ancestor was 971fb41e78fea4f8e0ba5244784239371cb00591
1704 keep (l)ocal d846f26643bfa8ec210be40cc93cc6b7ff1128ea or
1704 keep (l)ocal d846f26643bfa8ec210be40cc93cc6b7ff1128ea or
1705 take (o)ther e166e74c7303192238d60af5a9c4ce9bef0b7928? l
1705 take (o)ther e166e74c7303192238d60af5a9c4ce9bef0b7928? l
1706 getting changed largefiles
1706 getting changed largefiles
1707 1 largefiles updated, 0 removed
1707 1 largefiles updated, 0 removed
1708 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1708 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1709 (branch merge, don't forget to commit)
1709 (branch merge, don't forget to commit)
1710 $ hg commit -m "Merge repos e and f"
1710 $ hg commit -m "Merge repos e and f"
1711 Invoking status precommit hook
1711 Invoking status precommit hook
1712 M normal3
1712 M normal3
1713 M sub/normal4
1713 M sub/normal4
1714 M sub2/large6
1714 M sub2/large6
1715 $ cat normal3
1715 $ cat normal3
1716 normal3-modified
1716 normal3-modified
1717 $ cat sub/normal4
1717 $ cat sub/normal4
1718 normal4-modified
1718 normal4-modified
1719 $ cat sub/large4
1719 $ cat sub/large4
1720 large4-merge-test
1720 large4-merge-test
1721 $ cat sub2/large6
1721 $ cat sub2/large6
1722 large6-modified
1722 large6-modified
1723 $ cat sub2/large7
1723 $ cat sub2/large7
1724 large7
1724 large7
1725
1725
1726 Test status after merging with a branch that introduces a new largefile:
1726 Test status after merging with a branch that introduces a new largefile:
1727
1727
1728 $ echo large > large
1728 $ echo large > large
1729 $ hg add --large large
1729 $ hg add --large large
1730 $ hg commit -m 'add largefile'
1730 $ hg commit -m 'add largefile'
1731 Invoking status precommit hook
1731 Invoking status precommit hook
1732 A large
1732 A large
1733 $ hg update -q ".^"
1733 $ hg update -q ".^"
1734 $ echo change >> normal3
1734 $ echo change >> normal3
1735 $ hg commit -m 'some change'
1735 $ hg commit -m 'some change'
1736 Invoking status precommit hook
1736 Invoking status precommit hook
1737 M normal3
1737 M normal3
1738 created new head
1738 created new head
1739 $ hg merge
1739 $ hg merge
1740 getting changed largefiles
1740 getting changed largefiles
1741 1 largefiles updated, 0 removed
1741 1 largefiles updated, 0 removed
1742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1743 (branch merge, don't forget to commit)
1743 (branch merge, don't forget to commit)
1744 $ hg status
1744 $ hg status
1745 M large
1745 M large
1746
1746
1747 - make sure update of merge with removed largefiles fails as expected
1747 - make sure update of merge with removed largefiles fails as expected
1748 $ hg rm sub2/large6
1748 $ hg rm sub2/large6
1749 $ hg up -r.
1749 $ hg up -r.
1750 abort: outstanding uncommitted merge
1750 abort: outstanding uncommitted merge
1751 [255]
1751 [255]
1752
1752
1753 - revert should be able to revert files introduced in a pending merge
1753 - revert should be able to revert files introduced in a pending merge
1754 $ hg revert --all -r .
1754 $ hg revert --all -r .
1755 removing .hglf/large
1755 removing .hglf/large
1756 undeleting .hglf/sub2/large6
1756 undeleting .hglf/sub2/large6
1757
1757
1758 Test that a normal file and a largefile with the same name and path cannot
1758 Test that a normal file and a largefile with the same name and path cannot
1759 coexist.
1759 coexist.
1760
1760
1761 $ rm sub2/large7
1761 $ rm sub2/large7
1762 $ echo "largeasnormal" > sub2/large7
1762 $ echo "largeasnormal" > sub2/large7
1763 $ hg add sub2/large7
1763 $ hg add sub2/large7
1764 sub2/large7 already a largefile
1764 sub2/large7 already a largefile
1765
1765
1766 Test that transplanting a largefile change works correctly.
1766 Test that transplanting a largefile change works correctly.
1767
1767
1768 $ cd ..
1768 $ cd ..
1769 $ hg clone -r 8 d g
1769 $ hg clone -r 8 d g
1770 adding changesets
1770 adding changesets
1771 adding manifests
1771 adding manifests
1772 adding file changes
1772 adding file changes
1773 added 9 changesets with 26 changes to 10 files
1773 added 9 changesets with 26 changes to 10 files
1774 new changesets 30d30fe6a5be:a381d2c8c80e (9 drafts)
1774 new changesets 30d30fe6a5be:a381d2c8c80e (9 drafts)
1775 updating to branch default
1775 updating to branch default
1776 getting changed largefiles
1776 getting changed largefiles
1777 3 largefiles updated, 0 removed
1777 3 largefiles updated, 0 removed
1778 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1778 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1779 $ cd g
1779 $ cd g
1780 $ hg transplant -s ../d 598410d3eb9a
1780 $ hg transplant -s ../d 598410d3eb9a
1781 searching for changes
1781 searching for changes
1782 searching for changes
1782 searching for changes
1783 adding changesets
1783 adding changesets
1784 adding manifests
1784 adding manifests
1785 adding file changes
1785 adding file changes
1786 added 1 changesets with 2 changes to 2 files
1786 added 1 changesets with 2 changes to 2 files
1787 new changesets 598410d3eb9a (1 drafts)
1787 new changesets 598410d3eb9a (1 drafts)
1788 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1788 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1789 9:598410d3eb9a modify normal file largefile in repo d
1789 9:598410d3eb9a modify normal file largefile in repo d
1790 8:a381d2c8c80e modify normal file and largefile in repo b
1790 8:a381d2c8c80e modify normal file and largefile in repo b
1791 7:daea875e9014 add/edit more largefiles
1791 7:daea875e9014 add/edit more largefiles
1792 6:4355d653f84f edit files yet again
1792 6:4355d653f84f edit files yet again
1793 5:9d5af5072dbd edit files again
1793 5:9d5af5072dbd edit files again
1794 4:74c02385b94c move files
1794 4:74c02385b94c move files
1795 3:9e8fbc4bce62 copy files
1795 3:9e8fbc4bce62 copy files
1796 2:51a0ae4d5864 remove files
1796 2:51a0ae4d5864 remove files
1797 1:ce8896473775 edit files
1797 1:ce8896473775 edit files
1798 0:30d30fe6a5be add files
1798 0:30d30fe6a5be add files
1799 $ cat normal3
1799 $ cat normal3
1800 normal3-modified
1800 normal3-modified
1801 $ cat sub/normal4
1801 $ cat sub/normal4
1802 normal4-modified
1802 normal4-modified
1803 $ cat sub/large4
1803 $ cat sub/large4
1804 large4-modified
1804 large4-modified
1805 $ cat sub2/large6
1805 $ cat sub2/large6
1806 large6-modified
1806 large6-modified
1807 $ cat sub2/large7
1807 $ cat sub2/large7
1808 large7
1808 large7
1809
1809
1810 Cat a largefile
1810 Cat a largefile
1811 $ hg cat normal3
1811 $ hg cat normal3
1812 normal3-modified
1812 normal3-modified
1813 $ hg cat sub/large4
1813 $ hg cat sub/large4
1814 large4-modified
1814 large4-modified
1815 $ rm "${USERCACHE}"/*
1815 $ rm "${USERCACHE}"/*
1816 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1816 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1817 $ cat cat.out
1817 $ cat cat.out
1818 large4-modified
1818 large4-modified
1819 $ rm cat.out
1819 $ rm cat.out
1820 $ hg cat -r a381d2c8c80e normal3
1820 $ hg cat -r a381d2c8c80e normal3
1821 normal3-modified
1821 normal3-modified
1822 $ hg cat -r '.^' normal3
1822 $ hg cat -r '.^' normal3
1823 normal3-modified
1823 normal3-modified
1824 $ hg cat -r '.^' sub/large4 doesntexist
1824 $ hg cat -r '.^' sub/large4 doesntexist
1825 large4-modified
1825 large4-modified
1826 doesntexist: no such file in rev a381d2c8c80e
1826 doesntexist: no such file in rev a381d2c8c80e
1827 $ hg --cwd sub cat -r '.^' large4
1827 $ hg --cwd sub cat -r '.^' large4
1828 large4-modified
1828 large4-modified
1829 $ hg --cwd sub cat -r '.^' ../normal3
1829 $ hg --cwd sub cat -r '.^' ../normal3
1830 normal3-modified
1830 normal3-modified
1831 Cat a standin
1831 Cat a standin
1832 $ hg cat .hglf/sub/large4
1832 $ hg cat .hglf/sub/large4
1833 e166e74c7303192238d60af5a9c4ce9bef0b7928
1833 e166e74c7303192238d60af5a9c4ce9bef0b7928
1834 $ hg cat .hglf/normal3
1834 $ hg cat .hglf/normal3
1835 .hglf/normal3: no such file in rev 598410d3eb9a
1835 .hglf/normal3: no such file in rev 598410d3eb9a
1836 [1]
1836 [1]
1837
1837
1838 Test that renaming a largefile results in correct output for status
1838 Test that renaming a largefile results in correct output for status
1839
1839
1840 $ hg rename sub/large4 large4-renamed
1840 $ hg rename sub/large4 large4-renamed
1841 $ hg commit -m "test rename output"
1841 $ hg commit -m "test rename output"
1842 Invoking status precommit hook
1842 Invoking status precommit hook
1843 A large4-renamed
1843 A large4-renamed
1844 R sub/large4
1844 R sub/large4
1845 $ cat large4-renamed
1845 $ cat large4-renamed
1846 large4-modified
1846 large4-modified
1847 $ cd sub2
1847 $ cd sub2
1848 $ hg rename large6 large6-renamed
1848 $ hg rename large6 large6-renamed
1849 $ hg st
1849 $ hg st
1850 A sub2/large6-renamed
1850 A sub2/large6-renamed
1851 R sub2/large6
1851 R sub2/large6
1852 $ cd ..
1852 $ cd ..
1853
1853
1854 Test --normal flag
1854 Test --normal flag
1855
1855
1856 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1856 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1857 $ hg add --normal --large new-largefile
1857 $ hg add --normal --large new-largefile
1858 abort: --normal cannot be used with --large
1858 abort: --normal cannot be used with --large
1859 [255]
1859 [255]
1860 $ hg add --normal new-largefile
1860 $ hg add --normal new-largefile
1861 new-largefile: up to 69 MB of RAM may be required to manage this file
1861 new-largefile: up to 69 MB of RAM may be required to manage this file
1862 (use 'hg revert new-largefile' to cancel the pending addition)
1862 (use 'hg revert new-largefile' to cancel the pending addition)
1863 $ hg revert new-largefile
1863 $ hg revert new-largefile
1864 $ hg --config ui.large-file-limit=22M add --normal new-largefile
1864 $ hg --config ui.large-file-limit=22M add --normal new-largefile
1865
1865
1866 Test explicit commit of switch between normal and largefile - make sure both
1866 Test explicit commit of switch between normal and largefile - make sure both
1867 the add and the remove is committed.
1867 the add and the remove is committed.
1868
1868
1869 $ hg up -qC
1869 $ hg up -qC
1870 $ hg forget normal3 large4-renamed
1870 $ hg forget normal3 large4-renamed
1871 $ hg add --large normal3
1871 $ hg add --large normal3
1872 $ hg add large4-renamed
1872 $ hg add large4-renamed
1873 $ hg commit -m 'swap' normal3 large4-renamed
1873 $ hg commit -m 'swap' normal3 large4-renamed
1874 Invoking status precommit hook
1874 Invoking status precommit hook
1875 A large4-renamed
1875 A large4-renamed
1876 A normal3
1876 A normal3
1877 ? new-largefile
1877 ? new-largefile
1878 ? sub2/large6-renamed
1878 ? sub2/large6-renamed
1879 $ hg mani
1879 $ hg mani
1880 .hglf/normal3
1880 .hglf/normal3
1881 .hglf/sub2/large6
1881 .hglf/sub2/large6
1882 .hglf/sub2/large7
1882 .hglf/sub2/large7
1883 large4-renamed
1883 large4-renamed
1884 sub/normal4
1884 sub/normal4
1885
1885
1886 $ cd ..
1886 $ cd ..
1887
1887
1888
1888
1889
1889
@@ -1,116 +1,116 b''
1 $ hg init
1 $ hg init
2
2
3 $ echo foo > foo
3 $ echo foo > foo
4 $ echo bar > bar
4 $ echo bar > bar
5 $ hg ci -qAm 'add foo bar'
5 $ hg ci -qAm 'add foo bar'
6
6
7 $ echo foo2 >> foo
7 $ echo foo2 >> foo
8 $ echo bleh > bar
8 $ echo bleh > bar
9 $ hg ci -m 'change foo bar'
9 $ hg ci -m 'change foo bar'
10
10
11 $ hg up -qC 0
11 $ hg up -qC 0
12 $ hg mv foo foo1
12 $ hg mv foo foo1
13 $ echo foo1 > foo1
13 $ echo foo1 > foo1
14 $ hg cat foo >> foo1
14 $ hg cat foo >> foo1
15 $ hg ci -m 'mv foo foo1'
15 $ hg ci -m 'mv foo foo1'
16 created new head
16 created new head
17
17
18 $ hg merge
18 $ hg merge
19 merging foo1 and foo to foo1
19 merging foo1 and foo to foo1
20 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
20 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
21 (branch merge, don't forget to commit)
21 (branch merge, don't forget to commit)
22
22
23 $ hg debugstate --nodates
23 $ hg debugstate --no-dates
24 m 0 -2 unset bar
24 m 0 -2 unset bar
25 m 0 -2 unset foo1
25 m 0 -2 unset foo1
26 copy: foo -> foo1
26 copy: foo -> foo1
27
27
28 $ hg st -q
28 $ hg st -q
29 M bar
29 M bar
30 M foo1
30 M foo1
31
31
32
32
33 Removing foo1 and bar:
33 Removing foo1 and bar:
34
34
35 $ cp foo1 F
35 $ cp foo1 F
36 $ cp bar B
36 $ cp bar B
37 $ hg rm -f foo1 bar
37 $ hg rm -f foo1 bar
38
38
39 $ hg debugstate --nodates
39 $ hg debugstate --no-dates
40 r 0 -1 set bar
40 r 0 -1 set bar
41 r 0 -1 set foo1
41 r 0 -1 set foo1
42 copy: foo -> foo1
42 copy: foo -> foo1
43
43
44 $ hg st -qC
44 $ hg st -qC
45 R bar
45 R bar
46 R foo1
46 R foo1
47
47
48
48
49 Re-adding foo1 and bar:
49 Re-adding foo1 and bar:
50
50
51 $ cp F foo1
51 $ cp F foo1
52 $ cp B bar
52 $ cp B bar
53 $ hg add -v foo1 bar
53 $ hg add -v foo1 bar
54 adding bar
54 adding bar
55 adding foo1
55 adding foo1
56
56
57 $ hg debugstate --nodates
57 $ hg debugstate --no-dates
58 n 0 -2 unset bar
58 n 0 -2 unset bar
59 n 0 -2 unset foo1
59 n 0 -2 unset foo1
60 copy: foo -> foo1
60 copy: foo -> foo1
61
61
62 $ hg st -qC
62 $ hg st -qC
63 M bar
63 M bar
64 M foo1
64 M foo1
65 foo
65 foo
66
66
67
67
68 Reverting foo1 and bar:
68 Reverting foo1 and bar:
69
69
70 $ hg revert -vr . foo1 bar
70 $ hg revert -vr . foo1 bar
71 saving current version of bar as bar.orig
71 saving current version of bar as bar.orig
72 saving current version of foo1 as foo1.orig
72 saving current version of foo1 as foo1.orig
73 reverting bar
73 reverting bar
74 reverting foo1
74 reverting foo1
75
75
76 $ hg debugstate --nodates
76 $ hg debugstate --no-dates
77 n 0 -2 unset bar
77 n 0 -2 unset bar
78 n 0 -2 unset foo1
78 n 0 -2 unset foo1
79 copy: foo -> foo1
79 copy: foo -> foo1
80
80
81 $ hg st -qC
81 $ hg st -qC
82 M bar
82 M bar
83 M foo1
83 M foo1
84 foo
84 foo
85
85
86 $ hg diff
86 $ hg diff
87
87
88 Merge should not overwrite local file that is untracked after remove
88 Merge should not overwrite local file that is untracked after remove
89
89
90 $ rm *
90 $ rm *
91 $ hg up -qC
91 $ hg up -qC
92 $ hg rm bar
92 $ hg rm bar
93 $ hg ci -m 'remove bar'
93 $ hg ci -m 'remove bar'
94 $ echo 'memories of buried pirate treasure' > bar
94 $ echo 'memories of buried pirate treasure' > bar
95 $ hg merge
95 $ hg merge
96 bar: untracked file differs
96 bar: untracked file differs
97 abort: untracked files in working directory differ from files in requested revision
97 abort: untracked files in working directory differ from files in requested revision
98 [255]
98 [255]
99 $ cat bar
99 $ cat bar
100 memories of buried pirate treasure
100 memories of buried pirate treasure
101
101
102 Those who use force will lose
102 Those who use force will lose
103
103
104 $ hg merge -f
104 $ hg merge -f
105 file 'bar' was deleted in local [working copy] but was modified in other [merge rev].
105 file 'bar' was deleted in local [working copy] but was modified in other [merge rev].
106 What do you want to do?
106 What do you want to do?
107 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
107 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
108 merging foo1 and foo to foo1
108 merging foo1 and foo to foo1
109 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
109 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
110 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
110 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
111 [1]
111 [1]
112 $ cat bar
112 $ cat bar
113 bleh
113 bleh
114 $ hg st
114 $ hg st
115 M bar
115 M bar
116 M foo1
116 M foo1
@@ -1,107 +1,107 b''
1 #testcases flat tree
1 #testcases flat tree
2
2
3 $ . "$TESTDIR/narrow-library.sh"
3 $ . "$TESTDIR/narrow-library.sh"
4
4
5 #if tree
5 #if tree
6 $ cat << EOF >> $HGRCPATH
6 $ cat << EOF >> $HGRCPATH
7 > [experimental]
7 > [experimental]
8 > treemanifest = 1
8 > treemanifest = 1
9 > EOF
9 > EOF
10 #endif
10 #endif
11
11
12 create full repo
12 create full repo
13
13
14 $ hg init master
14 $ hg init master
15 $ cd master
15 $ cd master
16
16
17 $ mkdir inside
17 $ mkdir inside
18 $ echo inside > inside/f1
18 $ echo inside > inside/f1
19 $ mkdir outside
19 $ mkdir outside
20 $ echo outside > outside/f1
20 $ echo outside > outside/f1
21 $ hg ci -Aqm 'initial'
21 $ hg ci -Aqm 'initial'
22
22
23 $ echo modified > inside/f1
23 $ echo modified > inside/f1
24 $ hg ci -qm 'modify inside'
24 $ hg ci -qm 'modify inside'
25
25
26 $ echo modified > outside/f1
26 $ echo modified > outside/f1
27 $ hg ci -qm 'modify outside'
27 $ hg ci -qm 'modify outside'
28
28
29 $ cd ..
29 $ cd ..
30
30
31 (The lfs extension does nothing here, but this test ensures that its hook that
31 (The lfs extension does nothing here, but this test ensures that its hook that
32 determines whether to add the lfs requirement, respects the narrow boundaries.)
32 determines whether to add the lfs requirement, respects the narrow boundaries.)
33
33
34 $ hg --config extensions.lfs= clone --narrow ssh://user@dummy/master narrow \
34 $ hg --config extensions.lfs= clone --narrow ssh://user@dummy/master narrow \
35 > --include inside
35 > --include inside
36 requesting all changes
36 requesting all changes
37 adding changesets
37 adding changesets
38 adding manifests
38 adding manifests
39 adding file changes
39 adding file changes
40 added 3 changesets with 2 changes to 1 files
40 added 3 changesets with 2 changes to 1 files
41 new changesets *:* (glob)
41 new changesets *:* (glob)
42 updating to branch default
42 updating to branch default
43 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 $ cd narrow
44 $ cd narrow
45
45
46 $ hg update -q 0
46 $ hg update -q 0
47
47
48 Can not modify dirstate outside
48 Can not modify dirstate outside
49
49
50 $ mkdir outside
50 $ mkdir outside
51 $ touch outside/f1
51 $ touch outside/f1
52 $ hg debugwalk -v -I 'relglob:f1'
52 $ hg debugwalk -v -I 'relglob:f1'
53 * matcher:
53 * matcher:
54 <includematcher includes='(?:(?:|.*/)f1(?:/|$))'>
54 <includematcher includes='(?:(?:|.*/)f1(?:/|$))'>
55 f inside/f1 inside/f1
55 f inside/f1 inside/f1
56 $ hg add outside/f1
56 $ hg add outside/f1
57 abort: cannot track 'outside/f1' - it is outside the narrow clone
57 abort: cannot track 'outside/f1' - it is outside the narrow clone
58 [255]
58 [255]
59 $ touch outside/f3
59 $ touch outside/f3
60 $ hg add outside/f3
60 $ hg add outside/f3
61 abort: cannot track 'outside/f3' - it is outside the narrow clone
61 abort: cannot track 'outside/f3' - it is outside the narrow clone
62 [255]
62 [255]
63
63
64 But adding a truly excluded file shouldn't count
64 But adding a truly excluded file shouldn't count
65
65
66 $ hg add outside/f3 -X outside/f3
66 $ hg add outside/f3 -X outside/f3
67
67
68 $ rm -r outside
68 $ rm -r outside
69
69
70 Can modify dirstate inside
70 Can modify dirstate inside
71
71
72 $ echo modified > inside/f1
72 $ echo modified > inside/f1
73 $ touch inside/f3
73 $ touch inside/f3
74 $ hg add inside/f3
74 $ hg add inside/f3
75 $ hg status
75 $ hg status
76 M inside/f1
76 M inside/f1
77 A inside/f3
77 A inside/f3
78 $ hg revert -qC .
78 $ hg revert -qC .
79 $ rm inside/f3
79 $ rm inside/f3
80
80
81 Can commit changes inside. Leaves outside unchanged.
81 Can commit changes inside. Leaves outside unchanged.
82
82
83 $ hg update -q 'desc("initial")'
83 $ hg update -q 'desc("initial")'
84 $ echo modified2 > inside/f1
84 $ echo modified2 > inside/f1
85 $ hg manifest --debug
85 $ hg manifest --debug
86 4d6a634d5ba06331a60c29ee0db8412490a54fcd 644 inside/f1
86 4d6a634d5ba06331a60c29ee0db8412490a54fcd 644 inside/f1
87 7fb3bb6356d28d4dc352c5ba52d7350a81b6bd46 644 outside/f1 (flat !)
87 7fb3bb6356d28d4dc352c5ba52d7350a81b6bd46 644 outside/f1 (flat !)
88 d0f2f706468ab0e8bec7af87446835fb1b13511b 755 d outside/ (tree !)
88 d0f2f706468ab0e8bec7af87446835fb1b13511b 755 d outside/ (tree !)
89 $ hg commit -m 'modify inside/f1'
89 $ hg commit -m 'modify inside/f1'
90 created new head
90 created new head
91 $ hg files -r .
91 $ hg files -r .
92 inside/f1
92 inside/f1
93 outside/f1 (flat !)
93 outside/f1 (flat !)
94 outside/ (tree !)
94 outside/ (tree !)
95 $ hg manifest --debug
95 $ hg manifest --debug
96 3f4197b4a11b9016e77ebc47fe566944885fd11b 644 inside/f1
96 3f4197b4a11b9016e77ebc47fe566944885fd11b 644 inside/f1
97 7fb3bb6356d28d4dc352c5ba52d7350a81b6bd46 644 outside/f1 (flat !)
97 7fb3bb6356d28d4dc352c5ba52d7350a81b6bd46 644 outside/f1 (flat !)
98 d0f2f706468ab0e8bec7af87446835fb1b13511b 755 d outside/ (tree !)
98 d0f2f706468ab0e8bec7af87446835fb1b13511b 755 d outside/ (tree !)
99 Some filesystems (notably FAT/exFAT only store timestamps with 2
99 Some filesystems (notably FAT/exFAT only store timestamps with 2
100 seconds of precision, so by sleeping for 3 seconds, we can ensure that
100 seconds of precision, so by sleeping for 3 seconds, we can ensure that
101 the timestamps of files stored by dirstate will appear older than the
101 the timestamps of files stored by dirstate will appear older than the
102 dirstate file, and therefore we'll be able to get stable output from
102 dirstate file, and therefore we'll be able to get stable output from
103 debugdirstate. If we don't do this, the test can be slightly flaky.
103 debugdirstate. If we don't do this, the test can be slightly flaky.
104 $ sleep 3
104 $ sleep 3
105 $ hg status
105 $ hg status
106 $ hg debugdirstate --nodates
106 $ hg debugdirstate --no-dates
107 n 644 10 set inside/f1
107 n 644 10 set inside/f1
@@ -1,125 +1,125 b''
1
1
2 $ cat > adddrop.py <<EOF
2 $ cat > adddrop.py <<EOF
3 > from mercurial import registrar
3 > from mercurial import registrar
4 > cmdtable = {}
4 > cmdtable = {}
5 > command = registrar.command(cmdtable)
5 > command = registrar.command(cmdtable)
6 > @command(b'debugadddrop',
6 > @command(b'debugadddrop',
7 > [(b'', b'drop', False, b'drop file from dirstate', b'FILE'),
7 > [(b'', b'drop', False, b'drop file from dirstate', b'FILE'),
8 > (b'', b'normal-lookup', False, b'add file to dirstate', b'FILE')],
8 > (b'', b'normal-lookup', False, b'add file to dirstate', b'FILE')],
9 > b'hg debugadddrop')
9 > b'hg debugadddrop')
10 > def debugadddrop(ui, repo, *pats, **opts):
10 > def debugadddrop(ui, repo, *pats, **opts):
11 > '''Add or drop unnamed arguments to or from the dirstate'''
11 > '''Add or drop unnamed arguments to or from the dirstate'''
12 > drop = opts.get('drop')
12 > drop = opts.get('drop')
13 > nl = opts.get('normal_lookup')
13 > nl = opts.get('normal_lookup')
14 > if nl and drop:
14 > if nl and drop:
15 > raise error.Abort('drop and normal-lookup are mutually exclusive')
15 > raise error.Abort('drop and normal-lookup are mutually exclusive')
16 > wlock = repo.wlock()
16 > wlock = repo.wlock()
17 > try:
17 > try:
18 > for file in pats:
18 > for file in pats:
19 > if opts.get('normal_lookup'):
19 > if opts.get('normal_lookup'):
20 > repo.dirstate.normallookup(file)
20 > repo.dirstate.normallookup(file)
21 > else:
21 > else:
22 > repo.dirstate.drop(file)
22 > repo.dirstate.drop(file)
23 >
23 >
24 > repo.dirstate.write(repo.currenttransaction())
24 > repo.dirstate.write(repo.currenttransaction())
25 > finally:
25 > finally:
26 > wlock.release()
26 > wlock.release()
27 > EOF
27 > EOF
28
28
29 $ echo "[extensions]" >> $HGRCPATH
29 $ echo "[extensions]" >> $HGRCPATH
30 $ echo "debugadddrop=`pwd`/adddrop.py" >> $HGRCPATH
30 $ echo "debugadddrop=`pwd`/adddrop.py" >> $HGRCPATH
31
31
32 basic test for hg debugrebuildstate
32 basic test for hg debugrebuildstate
33
33
34 $ hg init repo
34 $ hg init repo
35 $ cd repo
35 $ cd repo
36
36
37 $ touch foo bar
37 $ touch foo bar
38 $ hg ci -Am 'add foo bar'
38 $ hg ci -Am 'add foo bar'
39 adding bar
39 adding bar
40 adding foo
40 adding foo
41
41
42 $ touch baz
42 $ touch baz
43 $ hg add baz
43 $ hg add baz
44 $ hg rm bar
44 $ hg rm bar
45
45
46 $ hg debugrebuildstate
46 $ hg debugrebuildstate
47
47
48 state dump after
48 state dump after
49
49
50 $ hg debugstate --nodates | sort
50 $ hg debugstate --no-dates | sort
51 n 0 -1 unset bar
51 n 0 -1 unset bar
52 n 0 -1 unset foo
52 n 0 -1 unset foo
53
53
54 $ hg debugadddrop --normal-lookup file1 file2
54 $ hg debugadddrop --normal-lookup file1 file2
55 $ hg debugadddrop --drop bar
55 $ hg debugadddrop --drop bar
56 $ hg debugadddrop --drop
56 $ hg debugadddrop --drop
57 $ hg debugstate --nodates
57 $ hg debugstate --no-dates
58 n 0 -1 unset file1
58 n 0 -1 unset file1
59 n 0 -1 unset file2
59 n 0 -1 unset file2
60 n 0 -1 unset foo
60 n 0 -1 unset foo
61 $ hg debugrebuildstate
61 $ hg debugrebuildstate
62
62
63 status
63 status
64
64
65 $ hg st -A
65 $ hg st -A
66 ! bar
66 ! bar
67 ? baz
67 ? baz
68 C foo
68 C foo
69
69
70 Test debugdirstate --minimal where a file is not in parent manifest
70 Test debugdirstate --minimal where a file is not in parent manifest
71 but in the dirstate
71 but in the dirstate
72 $ touch foo bar qux
72 $ touch foo bar qux
73 $ hg add qux
73 $ hg add qux
74 $ hg remove bar
74 $ hg remove bar
75 $ hg status -A
75 $ hg status -A
76 A qux
76 A qux
77 R bar
77 R bar
78 ? baz
78 ? baz
79 C foo
79 C foo
80 $ hg debugadddrop --normal-lookup baz
80 $ hg debugadddrop --normal-lookup baz
81 $ hg debugdirstate --nodates
81 $ hg debugdirstate --no-dates
82 r 0 0 * bar (glob)
82 r 0 0 * bar (glob)
83 n 0 -1 * baz (glob)
83 n 0 -1 * baz (glob)
84 n 644 0 * foo (glob)
84 n 644 0 * foo (glob)
85 a 0 -1 * qux (glob)
85 a 0 -1 * qux (glob)
86 $ hg debugrebuilddirstate --minimal
86 $ hg debugrebuilddirstate --minimal
87 $ hg debugdirstate --nodates
87 $ hg debugdirstate --no-dates
88 r 0 0 * bar (glob)
88 r 0 0 * bar (glob)
89 n 644 0 * foo (glob)
89 n 644 0 * foo (glob)
90 a 0 -1 * qux (glob)
90 a 0 -1 * qux (glob)
91 $ hg status -A
91 $ hg status -A
92 A qux
92 A qux
93 R bar
93 R bar
94 ? baz
94 ? baz
95 C foo
95 C foo
96
96
97 Test debugdirstate --minimal where file is in the parent manifest but not the
97 Test debugdirstate --minimal where file is in the parent manifest but not the
98 dirstate
98 dirstate
99 $ hg manifest
99 $ hg manifest
100 bar
100 bar
101 foo
101 foo
102 $ hg status -A
102 $ hg status -A
103 A qux
103 A qux
104 R bar
104 R bar
105 ? baz
105 ? baz
106 C foo
106 C foo
107 $ hg debugdirstate --nodates
107 $ hg debugdirstate --no-dates
108 r 0 0 * bar (glob)
108 r 0 0 * bar (glob)
109 n 644 0 * foo (glob)
109 n 644 0 * foo (glob)
110 a 0 -1 * qux (glob)
110 a 0 -1 * qux (glob)
111 $ hg debugadddrop --drop foo
111 $ hg debugadddrop --drop foo
112 $ hg debugdirstate --nodates
112 $ hg debugdirstate --no-dates
113 r 0 0 * bar (glob)
113 r 0 0 * bar (glob)
114 a 0 -1 * qux (glob)
114 a 0 -1 * qux (glob)
115 $ hg debugrebuilddirstate --minimal
115 $ hg debugrebuilddirstate --minimal
116 $ hg debugdirstate --nodates
116 $ hg debugdirstate --no-dates
117 r 0 0 * bar (glob)
117 r 0 0 * bar (glob)
118 n 0 -1 * foo (glob)
118 n 0 -1 * foo (glob)
119 a 0 -1 * qux (glob)
119 a 0 -1 * qux (glob)
120 $ hg status -A
120 $ hg status -A
121 A qux
121 A qux
122 R bar
122 R bar
123 ? baz
123 ? baz
124 C foo
124 C foo
125
125
@@ -1,422 +1,422 b''
1 test sparse
1 test sparse
2
2
3 $ hg init myrepo
3 $ hg init myrepo
4 $ cd myrepo
4 $ cd myrepo
5 $ cat > .hg/hgrc <<EOF
5 $ cat > .hg/hgrc <<EOF
6 > [extensions]
6 > [extensions]
7 > sparse=
7 > sparse=
8 > strip=
8 > strip=
9 > EOF
9 > EOF
10
10
11 $ echo a > show
11 $ echo a > show
12 $ echo x > hide
12 $ echo x > hide
13 $ hg ci -Aqm 'initial'
13 $ hg ci -Aqm 'initial'
14
14
15 $ echo b > show
15 $ echo b > show
16 $ echo y > hide
16 $ echo y > hide
17 $ echo aa > show2
17 $ echo aa > show2
18 $ echo xx > hide2
18 $ echo xx > hide2
19 $ hg ci -Aqm 'two'
19 $ hg ci -Aqm 'two'
20
20
21 Verify basic --include
21 Verify basic --include
22
22
23 $ hg up -q 0
23 $ hg up -q 0
24 $ hg debugsparse --include 'hide'
24 $ hg debugsparse --include 'hide'
25 $ ls
25 $ ls
26 hide
26 hide
27
27
28 Absolute paths outside the repo should just be rejected
28 Absolute paths outside the repo should just be rejected
29
29
30 #if no-windows
30 #if no-windows
31 $ hg debugsparse --include /foo/bar
31 $ hg debugsparse --include /foo/bar
32 abort: paths cannot be absolute
32 abort: paths cannot be absolute
33 [255]
33 [255]
34 $ hg debugsparse --include '$TESTTMP/myrepo/hide'
34 $ hg debugsparse --include '$TESTTMP/myrepo/hide'
35
35
36 $ hg debugsparse --include '/root'
36 $ hg debugsparse --include '/root'
37 abort: paths cannot be absolute
37 abort: paths cannot be absolute
38 [255]
38 [255]
39 #else
39 #else
40 TODO: See if this can be made to fail the same way as on Unix
40 TODO: See if this can be made to fail the same way as on Unix
41 $ hg debugsparse --include /c/foo/bar
41 $ hg debugsparse --include /c/foo/bar
42 abort: paths cannot be absolute
42 abort: paths cannot be absolute
43 [255]
43 [255]
44 $ hg debugsparse --include '$TESTTMP/myrepo/hide'
44 $ hg debugsparse --include '$TESTTMP/myrepo/hide'
45
45
46 $ hg debugsparse --include '/c/root'
46 $ hg debugsparse --include '/c/root'
47 abort: paths cannot be absolute
47 abort: paths cannot be absolute
48 [255]
48 [255]
49 #endif
49 #endif
50
50
51 Paths should be treated as cwd-relative, not repo-root-relative
51 Paths should be treated as cwd-relative, not repo-root-relative
52 $ mkdir subdir && cd subdir
52 $ mkdir subdir && cd subdir
53 $ hg debugsparse --include path
53 $ hg debugsparse --include path
54 $ hg debugsparse
54 $ hg debugsparse
55 [include]
55 [include]
56 $TESTTMP/myrepo/hide
56 $TESTTMP/myrepo/hide
57 hide
57 hide
58 subdir/path
58 subdir/path
59
59
60 $ cd ..
60 $ cd ..
61 $ echo hello > subdir/file2.ext
61 $ echo hello > subdir/file2.ext
62 $ cd subdir
62 $ cd subdir
63 $ hg debugsparse --include '**.ext' # let us test globs
63 $ hg debugsparse --include '**.ext' # let us test globs
64 $ hg debugsparse --include 'path:abspath' # and a path: pattern
64 $ hg debugsparse --include 'path:abspath' # and a path: pattern
65 $ cd ..
65 $ cd ..
66 $ hg debugsparse
66 $ hg debugsparse
67 [include]
67 [include]
68 $TESTTMP/myrepo/hide
68 $TESTTMP/myrepo/hide
69 hide
69 hide
70 path:abspath
70 path:abspath
71 subdir/**.ext
71 subdir/**.ext
72 subdir/path
72 subdir/path
73
73
74 $ rm -rf subdir
74 $ rm -rf subdir
75
75
76 Verify commiting while sparse includes other files
76 Verify commiting while sparse includes other files
77
77
78 $ echo z > hide
78 $ echo z > hide
79 $ hg ci -Aqm 'edit hide'
79 $ hg ci -Aqm 'edit hide'
80 $ ls
80 $ ls
81 hide
81 hide
82 $ hg manifest
82 $ hg manifest
83 hide
83 hide
84 show
84 show
85
85
86 Verify --reset brings files back
86 Verify --reset brings files back
87
87
88 $ hg debugsparse --reset
88 $ hg debugsparse --reset
89 $ ls
89 $ ls
90 hide
90 hide
91 show
91 show
92 $ cat hide
92 $ cat hide
93 z
93 z
94 $ cat show
94 $ cat show
95 a
95 a
96
96
97 Verify 'hg debugsparse' default output
97 Verify 'hg debugsparse' default output
98
98
99 $ hg up -q null
99 $ hg up -q null
100 $ hg debugsparse --include 'show*'
100 $ hg debugsparse --include 'show*'
101
101
102 $ hg debugsparse
102 $ hg debugsparse
103 [include]
103 [include]
104 show*
104 show*
105
105
106 Verify update only writes included files
106 Verify update only writes included files
107
107
108 $ hg up -q 0
108 $ hg up -q 0
109 $ ls
109 $ ls
110 show
110 show
111
111
112 $ hg up -q 1
112 $ hg up -q 1
113 $ ls
113 $ ls
114 show
114 show
115 show2
115 show2
116
116
117 Verify status only shows included files
117 Verify status only shows included files
118
118
119 $ touch hide
119 $ touch hide
120 $ touch hide3
120 $ touch hide3
121 $ echo c > show
121 $ echo c > show
122 $ hg status
122 $ hg status
123 M show
123 M show
124
124
125 Adding an excluded file should fail
125 Adding an excluded file should fail
126
126
127 $ hg add hide3
127 $ hg add hide3
128 abort: cannot add 'hide3' - it is outside the sparse checkout
128 abort: cannot add 'hide3' - it is outside the sparse checkout
129 (include file with `hg debugsparse --include <pattern>` or use `hg add -s <file>` to include file directory while adding)
129 (include file with `hg debugsparse --include <pattern>` or use `hg add -s <file>` to include file directory while adding)
130 [255]
130 [255]
131
131
132 But adding a truly excluded file shouldn't count
132 But adding a truly excluded file shouldn't count
133
133
134 $ hg add hide3 -X hide3
134 $ hg add hide3 -X hide3
135
135
136 Verify deleting sparseness while a file has changes fails
136 Verify deleting sparseness while a file has changes fails
137
137
138 $ hg debugsparse --delete 'show*'
138 $ hg debugsparse --delete 'show*'
139 pending changes to 'hide'
139 pending changes to 'hide'
140 abort: cannot change sparseness due to pending changes (delete the files or use --force to bring them back dirty)
140 abort: cannot change sparseness due to pending changes (delete the files or use --force to bring them back dirty)
141 [255]
141 [255]
142
142
143 Verify deleting sparseness with --force brings back files
143 Verify deleting sparseness with --force brings back files
144
144
145 $ hg debugsparse --delete -f 'show*'
145 $ hg debugsparse --delete -f 'show*'
146 pending changes to 'hide'
146 pending changes to 'hide'
147 $ ls
147 $ ls
148 hide
148 hide
149 hide2
149 hide2
150 hide3
150 hide3
151 show
151 show
152 show2
152 show2
153 $ hg st
153 $ hg st
154 M hide
154 M hide
155 M show
155 M show
156 ? hide3
156 ? hide3
157
157
158 Verify editing sparseness fails if pending changes
158 Verify editing sparseness fails if pending changes
159
159
160 $ hg debugsparse --include 'show*'
160 $ hg debugsparse --include 'show*'
161 pending changes to 'hide'
161 pending changes to 'hide'
162 abort: could not update sparseness due to pending changes
162 abort: could not update sparseness due to pending changes
163 [255]
163 [255]
164
164
165 Verify adding sparseness hides files
165 Verify adding sparseness hides files
166
166
167 $ hg debugsparse --exclude -f 'hide*'
167 $ hg debugsparse --exclude -f 'hide*'
168 pending changes to 'hide'
168 pending changes to 'hide'
169 $ ls
169 $ ls
170 hide
170 hide
171 hide3
171 hide3
172 show
172 show
173 show2
173 show2
174 $ hg st
174 $ hg st
175 M show
175 M show
176
176
177 $ hg up -qC .
177 $ hg up -qC .
178 TODO: add an option to purge to also purge files outside the sparse config?
178 TODO: add an option to purge to also purge files outside the sparse config?
179 $ hg purge --all --config extensions.purge=
179 $ hg purge --all --config extensions.purge=
180 $ ls
180 $ ls
181 hide
181 hide
182 hide3
182 hide3
183 show
183 show
184 show2
184 show2
185 For now, manually remove the files
185 For now, manually remove the files
186 $ rm hide hide3
186 $ rm hide hide3
187
187
188 Verify rebase temporarily includes excluded files
188 Verify rebase temporarily includes excluded files
189
189
190 $ hg rebase -d 1 -r 2 --config extensions.rebase=
190 $ hg rebase -d 1 -r 2 --config extensions.rebase=
191 rebasing 2:b91df4f39e75 "edit hide" (tip)
191 rebasing 2:b91df4f39e75 "edit hide" (tip)
192 temporarily included 2 file(s) in the sparse checkout for merging
192 temporarily included 2 file(s) in the sparse checkout for merging
193 merging hide
193 merging hide
194 warning: conflicts while merging hide! (edit, then use 'hg resolve --mark')
194 warning: conflicts while merging hide! (edit, then use 'hg resolve --mark')
195 unresolved conflicts (see hg resolve, then hg rebase --continue)
195 unresolved conflicts (see hg resolve, then hg rebase --continue)
196 [1]
196 [1]
197
197
198 $ hg debugsparse
198 $ hg debugsparse
199 [exclude]
199 [exclude]
200 hide*
200 hide*
201
201
202 Temporarily Included Files (for merge/rebase):
202 Temporarily Included Files (for merge/rebase):
203 hide
203 hide
204
204
205 $ cat hide
205 $ cat hide
206 <<<<<<< dest: 39278f7c08a9 - test: two
206 <<<<<<< dest: 39278f7c08a9 - test: two
207 y
207 y
208 =======
208 =======
209 z
209 z
210 >>>>>>> source: b91df4f39e75 - test: edit hide
210 >>>>>>> source: b91df4f39e75 - test: edit hide
211
211
212 Verify aborting a rebase cleans up temporary files
212 Verify aborting a rebase cleans up temporary files
213
213
214 $ hg rebase --abort --config extensions.rebase=
214 $ hg rebase --abort --config extensions.rebase=
215 cleaned up 1 temporarily added file(s) from the sparse checkout
215 cleaned up 1 temporarily added file(s) from the sparse checkout
216 rebase aborted
216 rebase aborted
217 $ rm hide.orig
217 $ rm hide.orig
218
218
219 $ ls
219 $ ls
220 show
220 show
221 show2
221 show2
222
222
223 Verify merge fails if merging excluded files
223 Verify merge fails if merging excluded files
224
224
225 $ hg up -q 1
225 $ hg up -q 1
226 $ hg merge -r 2
226 $ hg merge -r 2
227 temporarily included 2 file(s) in the sparse checkout for merging
227 temporarily included 2 file(s) in the sparse checkout for merging
228 merging hide
228 merging hide
229 warning: conflicts while merging hide! (edit, then use 'hg resolve --mark')
229 warning: conflicts while merging hide! (edit, then use 'hg resolve --mark')
230 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
230 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
231 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
231 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
232 [1]
232 [1]
233 $ hg debugsparse
233 $ hg debugsparse
234 [exclude]
234 [exclude]
235 hide*
235 hide*
236
236
237 Temporarily Included Files (for merge/rebase):
237 Temporarily Included Files (for merge/rebase):
238 hide
238 hide
239
239
240 $ hg up -C .
240 $ hg up -C .
241 cleaned up 1 temporarily added file(s) from the sparse checkout
241 cleaned up 1 temporarily added file(s) from the sparse checkout
242 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
242 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
243 $ hg debugsparse
243 $ hg debugsparse
244 [exclude]
244 [exclude]
245 hide*
245 hide*
246
246
247
247
248 Verify strip -k resets dirstate correctly
248 Verify strip -k resets dirstate correctly
249
249
250 $ hg status
250 $ hg status
251 $ hg debugsparse
251 $ hg debugsparse
252 [exclude]
252 [exclude]
253 hide*
253 hide*
254
254
255 $ hg log -r . -T '{rev}\n' --stat
255 $ hg log -r . -T '{rev}\n' --stat
256 1
256 1
257 hide | 2 +-
257 hide | 2 +-
258 hide2 | 1 +
258 hide2 | 1 +
259 show | 2 +-
259 show | 2 +-
260 show2 | 1 +
260 show2 | 1 +
261 4 files changed, 4 insertions(+), 2 deletions(-)
261 4 files changed, 4 insertions(+), 2 deletions(-)
262
262
263 $ hg strip -r . -k
263 $ hg strip -r . -k
264 saved backup bundle to $TESTTMP/myrepo/.hg/strip-backup/39278f7c08a9-ce59e002-backup.hg
264 saved backup bundle to $TESTTMP/myrepo/.hg/strip-backup/39278f7c08a9-ce59e002-backup.hg
265 $ hg status
265 $ hg status
266 M show
266 M show
267 ? show2
267 ? show2
268
268
269 Verify rebase succeeds if all changed files are in sparse checkout
269 Verify rebase succeeds if all changed files are in sparse checkout
270
270
271 $ hg commit -Aqm "add show2"
271 $ hg commit -Aqm "add show2"
272 $ hg rebase -d 1 --config extensions.rebase=
272 $ hg rebase -d 1 --config extensions.rebase=
273 rebasing 2:bdde55290160 "add show2" (tip)
273 rebasing 2:bdde55290160 "add show2" (tip)
274 saved backup bundle to $TESTTMP/myrepo/.hg/strip-backup/bdde55290160-216ed9c6-rebase.hg
274 saved backup bundle to $TESTTMP/myrepo/.hg/strip-backup/bdde55290160-216ed9c6-rebase.hg
275
275
276 Verify log --sparse only shows commits that affect the sparse checkout
276 Verify log --sparse only shows commits that affect the sparse checkout
277
277
278 $ hg log -T '{rev} '
278 $ hg log -T '{rev} '
279 2 1 0 (no-eol)
279 2 1 0 (no-eol)
280 $ hg log --sparse -T '{rev} '
280 $ hg log --sparse -T '{rev} '
281 2 0 (no-eol)
281 2 0 (no-eol)
282
282
283 Test status on a file in a subdir
283 Test status on a file in a subdir
284
284
285 $ mkdir -p dir1/dir2
285 $ mkdir -p dir1/dir2
286 $ touch dir1/dir2/file
286 $ touch dir1/dir2/file
287 $ hg debugsparse -I dir1/dir2
287 $ hg debugsparse -I dir1/dir2
288 $ hg status
288 $ hg status
289 ? dir1/dir2/file
289 ? dir1/dir2/file
290
290
291 Mix files and subdirectories, both "glob:" and unprefixed
291 Mix files and subdirectories, both "glob:" and unprefixed
292
292
293 $ hg debugsparse --reset
293 $ hg debugsparse --reset
294 $ touch dir1/notshown
294 $ touch dir1/notshown
295 $ hg commit -A dir1/notshown -m "notshown"
295 $ hg commit -A dir1/notshown -m "notshown"
296 $ hg debugsparse --include 'dir1/dir2'
296 $ hg debugsparse --include 'dir1/dir2'
297 $ "$PYTHON" $TESTDIR/list-tree.py . | egrep -v '\.[\/]\.hg'
297 $ "$PYTHON" $TESTDIR/list-tree.py . | egrep -v '\.[\/]\.hg'
298 ./
298 ./
299 ./dir1/
299 ./dir1/
300 ./dir1/dir2/
300 ./dir1/dir2/
301 ./dir1/dir2/file
301 ./dir1/dir2/file
302 ./hide.orig
302 ./hide.orig
303 $ hg debugsparse --delete 'dir1/dir2'
303 $ hg debugsparse --delete 'dir1/dir2'
304 $ hg debugsparse --include 'glob:dir1/dir2'
304 $ hg debugsparse --include 'glob:dir1/dir2'
305 $ "$PYTHON" $TESTDIR/list-tree.py . | egrep -v '\.[\/]\.hg'
305 $ "$PYTHON" $TESTDIR/list-tree.py . | egrep -v '\.[\/]\.hg'
306 ./
306 ./
307 ./dir1/
307 ./dir1/
308 ./dir1/dir2/
308 ./dir1/dir2/
309 ./dir1/dir2/file
309 ./dir1/dir2/file
310 ./hide.orig
310 ./hide.orig
311
311
312 Test that add -s adds dirs to sparse profile
312 Test that add -s adds dirs to sparse profile
313
313
314 $ hg debugsparse --reset
314 $ hg debugsparse --reset
315 $ hg debugsparse --include empty
315 $ hg debugsparse --include empty
316 $ hg debugsparse
316 $ hg debugsparse
317 [include]
317 [include]
318 empty
318 empty
319
319
320
320
321 $ mkdir add
321 $ mkdir add
322 $ touch add/foo
322 $ touch add/foo
323 $ touch add/bar
323 $ touch add/bar
324 $ hg add add/foo
324 $ hg add add/foo
325 abort: cannot add 'add/foo' - it is outside the sparse checkout
325 abort: cannot add 'add/foo' - it is outside the sparse checkout
326 (include file with `hg debugsparse --include <pattern>` or use `hg add -s <file>` to include file directory while adding)
326 (include file with `hg debugsparse --include <pattern>` or use `hg add -s <file>` to include file directory while adding)
327 [255]
327 [255]
328 $ hg add -s add/foo
328 $ hg add -s add/foo
329 $ hg st
329 $ hg st
330 A add/foo
330 A add/foo
331 ? add/bar
331 ? add/bar
332 $ hg debugsparse
332 $ hg debugsparse
333 [include]
333 [include]
334 add
334 add
335 empty
335 empty
336
336
337 $ hg add -s add/*
337 $ hg add -s add/*
338 add/foo already tracked!
338 add/foo already tracked!
339 $ hg st
339 $ hg st
340 A add/bar
340 A add/bar
341 A add/foo
341 A add/foo
342 $ hg debugsparse
342 $ hg debugsparse
343 [include]
343 [include]
344 add
344 add
345 empty
345 empty
346
346
347
347
348 $ cd ..
348 $ cd ..
349
349
350 Test non-sparse repos work while sparse is loaded
350 Test non-sparse repos work while sparse is loaded
351 $ hg init sparserepo
351 $ hg init sparserepo
352 $ hg init nonsparserepo
352 $ hg init nonsparserepo
353 $ cd sparserepo
353 $ cd sparserepo
354 $ cat > .hg/hgrc <<EOF
354 $ cat > .hg/hgrc <<EOF
355 > [extensions]
355 > [extensions]
356 > sparse=
356 > sparse=
357 > EOF
357 > EOF
358 $ cd ../nonsparserepo
358 $ cd ../nonsparserepo
359 $ echo x > x && hg add x && hg commit -qAm x
359 $ echo x > x && hg add x && hg commit -qAm x
360 $ cd ../sparserepo
360 $ cd ../sparserepo
361 $ hg clone ../nonsparserepo ../nonsparserepo2
361 $ hg clone ../nonsparserepo ../nonsparserepo2
362 updating to branch default
362 updating to branch default
363 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
364
364
365 Test debugrebuilddirstate
365 Test debugrebuilddirstate
366 $ cd ../sparserepo
366 $ cd ../sparserepo
367 $ touch included
367 $ touch included
368 $ touch excluded
368 $ touch excluded
369 $ hg add included excluded
369 $ hg add included excluded
370 $ hg commit -m 'a commit' -q
370 $ hg commit -m 'a commit' -q
371 $ cp .hg/dirstate ../dirstateboth
371 $ cp .hg/dirstate ../dirstateboth
372 $ hg debugsparse -X excluded
372 $ hg debugsparse -X excluded
373 $ cp ../dirstateboth .hg/dirstate
373 $ cp ../dirstateboth .hg/dirstate
374 $ hg debugrebuilddirstate
374 $ hg debugrebuilddirstate
375 $ hg debugdirstate
375 $ hg debugdirstate
376 n 0 -1 unset included
376 n 0 -1 unset included
377
377
378 Test debugdirstate --minimal where file is in the parent manifest but not the
378 Test debugdirstate --minimal where file is in the parent manifest but not the
379 dirstate
379 dirstate
380 $ hg debugsparse -X included
380 $ hg debugsparse -X included
381 $ hg debugdirstate
381 $ hg debugdirstate
382 $ cp .hg/dirstate ../dirstateallexcluded
382 $ cp .hg/dirstate ../dirstateallexcluded
383 $ hg debugsparse --reset
383 $ hg debugsparse --reset
384 $ hg debugsparse -X excluded
384 $ hg debugsparse -X excluded
385 $ cp ../dirstateallexcluded .hg/dirstate
385 $ cp ../dirstateallexcluded .hg/dirstate
386 $ touch includedadded
386 $ touch includedadded
387 $ hg add includedadded
387 $ hg add includedadded
388 $ hg debugdirstate --nodates
388 $ hg debugdirstate --no-dates
389 a 0 -1 unset includedadded
389 a 0 -1 unset includedadded
390 $ hg debugrebuilddirstate --minimal
390 $ hg debugrebuilddirstate --minimal
391 $ hg debugdirstate --nodates
391 $ hg debugdirstate --no-dates
392 n 0 -1 unset included
392 n 0 -1 unset included
393 a 0 -1 * includedadded (glob)
393 a 0 -1 * includedadded (glob)
394
394
395 Test debugdirstate --minimal where a file is not in parent manifest
395 Test debugdirstate --minimal where a file is not in parent manifest
396 but in the dirstate. This should take into account excluded files in the
396 but in the dirstate. This should take into account excluded files in the
397 manifest
397 manifest
398 $ cp ../dirstateboth .hg/dirstate
398 $ cp ../dirstateboth .hg/dirstate
399 $ touch includedadded
399 $ touch includedadded
400 $ hg add includedadded
400 $ hg add includedadded
401 $ touch excludednomanifest
401 $ touch excludednomanifest
402 $ hg add excludednomanifest
402 $ hg add excludednomanifest
403 $ cp .hg/dirstate ../moreexcluded
403 $ cp .hg/dirstate ../moreexcluded
404 $ hg forget excludednomanifest
404 $ hg forget excludednomanifest
405 $ rm excludednomanifest
405 $ rm excludednomanifest
406 $ hg debugsparse -X excludednomanifest
406 $ hg debugsparse -X excludednomanifest
407 $ cp ../moreexcluded .hg/dirstate
407 $ cp ../moreexcluded .hg/dirstate
408 $ hg manifest
408 $ hg manifest
409 excluded
409 excluded
410 included
410 included
411 We have files in the dirstate that are included and excluded. Some are in the
411 We have files in the dirstate that are included and excluded. Some are in the
412 manifest and some are not.
412 manifest and some are not.
413 $ hg debugdirstate --nodates
413 $ hg debugdirstate --no-dates
414 n 644 0 * excluded (glob)
414 n 644 0 * excluded (glob)
415 a 0 -1 * excludednomanifest (glob)
415 a 0 -1 * excludednomanifest (glob)
416 n 644 0 * included (glob)
416 n 644 0 * included (glob)
417 a 0 -1 * includedadded (glob)
417 a 0 -1 * includedadded (glob)
418 $ hg debugrebuilddirstate --minimal
418 $ hg debugrebuilddirstate --minimal
419 $ hg debugdirstate --nodates
419 $ hg debugdirstate --no-dates
420 n 644 0 * included (glob)
420 n 644 0 * included (glob)
421 a 0 -1 * includedadded (glob)
421 a 0 -1 * includedadded (glob)
422
422
General Comments 0
You need to be logged in to leave comments. Login now