##// END OF EJS Templates
commands: support consuming stream clone bundles...
Gregory Szorc -
r26758:bde7ef23 default
parent child Browse files
Show More
@@ -1,6704 +1,6716 b''
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from node import hex, bin, nullid, nullrev, short
9 9 from lock import release
10 10 from i18n import _
11 11 import os, re, difflib, time, tempfile, errno, shlex
12 12 import sys, socket
13 13 import hg, scmutil, util, revlog, copies, error, bookmarks
14 14 import patch, help, encoding, templatekw, discovery
15 15 import archival, changegroup, cmdutil, hbisect
16 16 import sshserver, hgweb
17 17 import extensions
18 18 from hgweb import server as hgweb_server
19 19 import merge as mergemod
20 20 import minirst, revset, fileset
21 21 import dagparser, context, simplemerge, graphmod, copies
22 22 import random, operator
23 23 import setdiscovery, treediscovery, dagutil, pvec, localrepo, destutil
24 24 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
25 25 import ui as uimod
26 26 import streamclone
27 27
28 28 table = {}
29 29
30 30 command = cmdutil.command(table)
31 31
32 32 # Space delimited list of commands that don't require local repositories.
33 33 # This should be populated by passing norepo=True into the @command decorator.
34 34 norepo = ''
35 35 # Space delimited list of commands that optionally require local repositories.
36 36 # This should be populated by passing optionalrepo=True into the @command
37 37 # decorator.
38 38 optionalrepo = ''
39 39 # Space delimited list of commands that will examine arguments looking for
40 40 # a repository. This should be populated by passing inferrepo=True into the
41 41 # @command decorator.
42 42 inferrepo = ''
43 43
44 44 # label constants
45 45 # until 3.5, bookmarks.current was the advertised name, not
46 46 # bookmarks.active, so we must use both to avoid breaking old
47 47 # custom styles
48 48 activebookmarklabel = 'bookmarks.active bookmarks.current'
49 49
50 50 # common command options
51 51
52 52 globalopts = [
53 53 ('R', 'repository', '',
54 54 _('repository root directory or name of overlay bundle file'),
55 55 _('REPO')),
56 56 ('', 'cwd', '',
57 57 _('change working directory'), _('DIR')),
58 58 ('y', 'noninteractive', None,
59 59 _('do not prompt, automatically pick the first choice for all prompts')),
60 60 ('q', 'quiet', None, _('suppress output')),
61 61 ('v', 'verbose', None, _('enable additional output')),
62 62 ('', 'config', [],
63 63 _('set/override config option (use \'section.name=value\')'),
64 64 _('CONFIG')),
65 65 ('', 'debug', None, _('enable debugging output')),
66 66 ('', 'debugger', None, _('start debugger')),
67 67 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
68 68 _('ENCODE')),
69 69 ('', 'encodingmode', encoding.encodingmode,
70 70 _('set the charset encoding mode'), _('MODE')),
71 71 ('', 'traceback', None, _('always print a traceback on exception')),
72 72 ('', 'time', None, _('time how long the command takes')),
73 73 ('', 'profile', None, _('print command execution profile')),
74 74 ('', 'version', None, _('output version information and exit')),
75 75 ('h', 'help', None, _('display help and exit')),
76 76 ('', 'hidden', False, _('consider hidden changesets')),
77 77 ]
78 78
79 79 dryrunopts = [('n', 'dry-run', None,
80 80 _('do not perform actions, just print output'))]
81 81
82 82 remoteopts = [
83 83 ('e', 'ssh', '',
84 84 _('specify ssh command to use'), _('CMD')),
85 85 ('', 'remotecmd', '',
86 86 _('specify hg command to run on the remote side'), _('CMD')),
87 87 ('', 'insecure', None,
88 88 _('do not verify server certificate (ignoring web.cacerts config)')),
89 89 ]
90 90
91 91 walkopts = [
92 92 ('I', 'include', [],
93 93 _('include names matching the given patterns'), _('PATTERN')),
94 94 ('X', 'exclude', [],
95 95 _('exclude names matching the given patterns'), _('PATTERN')),
96 96 ]
97 97
98 98 commitopts = [
99 99 ('m', 'message', '',
100 100 _('use text as commit message'), _('TEXT')),
101 101 ('l', 'logfile', '',
102 102 _('read commit message from file'), _('FILE')),
103 103 ]
104 104
105 105 commitopts2 = [
106 106 ('d', 'date', '',
107 107 _('record the specified date as commit date'), _('DATE')),
108 108 ('u', 'user', '',
109 109 _('record the specified user as committer'), _('USER')),
110 110 ]
111 111
112 112 # hidden for now
113 113 formatteropts = [
114 114 ('T', 'template', '',
115 115 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
116 116 ]
117 117
118 118 templateopts = [
119 119 ('', 'style', '',
120 120 _('display using template map file (DEPRECATED)'), _('STYLE')),
121 121 ('T', 'template', '',
122 122 _('display with template'), _('TEMPLATE')),
123 123 ]
124 124
125 125 logopts = [
126 126 ('p', 'patch', None, _('show patch')),
127 127 ('g', 'git', None, _('use git extended diff format')),
128 128 ('l', 'limit', '',
129 129 _('limit number of changes displayed'), _('NUM')),
130 130 ('M', 'no-merges', None, _('do not show merges')),
131 131 ('', 'stat', None, _('output diffstat-style summary of changes')),
132 132 ('G', 'graph', None, _("show the revision DAG")),
133 133 ] + templateopts
134 134
135 135 diffopts = [
136 136 ('a', 'text', None, _('treat all files as text')),
137 137 ('g', 'git', None, _('use git extended diff format')),
138 138 ('', 'nodates', None, _('omit dates from diff headers'))
139 139 ]
140 140
141 141 diffwsopts = [
142 142 ('w', 'ignore-all-space', None,
143 143 _('ignore white space when comparing lines')),
144 144 ('b', 'ignore-space-change', None,
145 145 _('ignore changes in the amount of white space')),
146 146 ('B', 'ignore-blank-lines', None,
147 147 _('ignore changes whose lines are all blank')),
148 148 ]
149 149
150 150 diffopts2 = [
151 151 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
152 152 ('p', 'show-function', None, _('show which function each change is in')),
153 153 ('', 'reverse', None, _('produce a diff that undoes the changes')),
154 154 ] + diffwsopts + [
155 155 ('U', 'unified', '',
156 156 _('number of lines of context to show'), _('NUM')),
157 157 ('', 'stat', None, _('output diffstat-style summary of changes')),
158 158 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
159 159 ]
160 160
161 161 mergetoolopts = [
162 162 ('t', 'tool', '', _('specify merge tool')),
163 163 ]
164 164
165 165 similarityopts = [
166 166 ('s', 'similarity', '',
167 167 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
168 168 ]
169 169
170 170 subrepoopts = [
171 171 ('S', 'subrepos', None,
172 172 _('recurse into subrepositories'))
173 173 ]
174 174
175 175 # Commands start here, listed alphabetically
176 176
177 177 @command('^add',
178 178 walkopts + subrepoopts + dryrunopts,
179 179 _('[OPTION]... [FILE]...'),
180 180 inferrepo=True)
181 181 def add(ui, repo, *pats, **opts):
182 182 """add the specified files on the next commit
183 183
184 184 Schedule files to be version controlled and added to the
185 185 repository.
186 186
187 187 The files will be added to the repository at the next commit. To
188 188 undo an add before that, see :hg:`forget`.
189 189
190 190 If no names are given, add all files to the repository.
191 191
192 192 .. container:: verbose
193 193
194 194 An example showing how new (unknown) files are added
195 195 automatically by :hg:`add`::
196 196
197 197 $ ls
198 198 foo.c
199 199 $ hg status
200 200 ? foo.c
201 201 $ hg add
202 202 adding foo.c
203 203 $ hg status
204 204 A foo.c
205 205
206 206 Returns 0 if all files are successfully added.
207 207 """
208 208
209 209 m = scmutil.match(repo[None], pats, opts)
210 210 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
211 211 return rejected and 1 or 0
212 212
213 213 @command('addremove',
214 214 similarityopts + subrepoopts + walkopts + dryrunopts,
215 215 _('[OPTION]... [FILE]...'),
216 216 inferrepo=True)
217 217 def addremove(ui, repo, *pats, **opts):
218 218 """add all new files, delete all missing files
219 219
220 220 Add all new files and remove all missing files from the
221 221 repository.
222 222
223 223 New files are ignored if they match any of the patterns in
224 224 ``.hgignore``. As with add, these changes take effect at the next
225 225 commit.
226 226
227 227 Use the -s/--similarity option to detect renamed files. This
228 228 option takes a percentage between 0 (disabled) and 100 (files must
229 229 be identical) as its parameter. With a parameter greater than 0,
230 230 this compares every removed file with every added file and records
231 231 those similar enough as renames. Detecting renamed files this way
232 232 can be expensive. After using this option, :hg:`status -C` can be
233 233 used to check which files were identified as moved or renamed. If
234 234 not specified, -s/--similarity defaults to 100 and only renames of
235 235 identical files are detected.
236 236
237 237 Returns 0 if all files are successfully added.
238 238 """
239 239 try:
240 240 sim = float(opts.get('similarity') or 100)
241 241 except ValueError:
242 242 raise error.Abort(_('similarity must be a number'))
243 243 if sim < 0 or sim > 100:
244 244 raise error.Abort(_('similarity must be between 0 and 100'))
245 245 matcher = scmutil.match(repo[None], pats, opts)
246 246 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
247 247
248 248 @command('^annotate|blame',
249 249 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
250 250 ('', 'follow', None,
251 251 _('follow copies/renames and list the filename (DEPRECATED)')),
252 252 ('', 'no-follow', None, _("don't follow copies and renames")),
253 253 ('a', 'text', None, _('treat all files as text')),
254 254 ('u', 'user', None, _('list the author (long with -v)')),
255 255 ('f', 'file', None, _('list the filename')),
256 256 ('d', 'date', None, _('list the date (short with -q)')),
257 257 ('n', 'number', None, _('list the revision number (default)')),
258 258 ('c', 'changeset', None, _('list the changeset')),
259 259 ('l', 'line-number', None, _('show line number at the first appearance'))
260 260 ] + diffwsopts + walkopts + formatteropts,
261 261 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
262 262 inferrepo=True)
263 263 def annotate(ui, repo, *pats, **opts):
264 264 """show changeset information by line for each file
265 265
266 266 List changes in files, showing the revision id responsible for
267 267 each line
268 268
269 269 This command is useful for discovering when a change was made and
270 270 by whom.
271 271
272 272 Without the -a/--text option, annotate will avoid processing files
273 273 it detects as binary. With -a, annotate will annotate the file
274 274 anyway, although the results will probably be neither useful
275 275 nor desirable.
276 276
277 277 Returns 0 on success.
278 278 """
279 279 if not pats:
280 280 raise error.Abort(_('at least one filename or pattern is required'))
281 281
282 282 if opts.get('follow'):
283 283 # --follow is deprecated and now just an alias for -f/--file
284 284 # to mimic the behavior of Mercurial before version 1.5
285 285 opts['file'] = True
286 286
287 287 ctx = scmutil.revsingle(repo, opts.get('rev'))
288 288
289 289 fm = ui.formatter('annotate', opts)
290 290 if ui.quiet:
291 291 datefunc = util.shortdate
292 292 else:
293 293 datefunc = util.datestr
294 294 if ctx.rev() is None:
295 295 def hexfn(node):
296 296 if node is None:
297 297 return None
298 298 else:
299 299 return fm.hexfunc(node)
300 300 if opts.get('changeset'):
301 301 # omit "+" suffix which is appended to node hex
302 302 def formatrev(rev):
303 303 if rev is None:
304 304 return '%d' % ctx.p1().rev()
305 305 else:
306 306 return '%d' % rev
307 307 else:
308 308 def formatrev(rev):
309 309 if rev is None:
310 310 return '%d+' % ctx.p1().rev()
311 311 else:
312 312 return '%d ' % rev
313 313 def formathex(hex):
314 314 if hex is None:
315 315 return '%s+' % fm.hexfunc(ctx.p1().node())
316 316 else:
317 317 return '%s ' % hex
318 318 else:
319 319 hexfn = fm.hexfunc
320 320 formatrev = formathex = str
321 321
322 322 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
323 323 ('number', ' ', lambda x: x[0].rev(), formatrev),
324 324 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
325 325 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
326 326 ('file', ' ', lambda x: x[0].path(), str),
327 327 ('line_number', ':', lambda x: x[1], str),
328 328 ]
329 329 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
330 330
331 331 if (not opts.get('user') and not opts.get('changeset')
332 332 and not opts.get('date') and not opts.get('file')):
333 333 opts['number'] = True
334 334
335 335 linenumber = opts.get('line_number') is not None
336 336 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
337 337 raise error.Abort(_('at least one of -n/-c is required for -l'))
338 338
339 339 if fm:
340 340 def makefunc(get, fmt):
341 341 return get
342 342 else:
343 343 def makefunc(get, fmt):
344 344 return lambda x: fmt(get(x))
345 345 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
346 346 if opts.get(op)]
347 347 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
348 348 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
349 349 if opts.get(op))
350 350
351 351 def bad(x, y):
352 352 raise error.Abort("%s: %s" % (x, y))
353 353
354 354 m = scmutil.match(ctx, pats, opts, badfn=bad)
355 355
356 356 follow = not opts.get('no_follow')
357 357 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
358 358 whitespace=True)
359 359 for abs in ctx.walk(m):
360 360 fctx = ctx[abs]
361 361 if not opts.get('text') and util.binary(fctx.data()):
362 362 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
363 363 continue
364 364
365 365 lines = fctx.annotate(follow=follow, linenumber=linenumber,
366 366 diffopts=diffopts)
367 367 formats = []
368 368 pieces = []
369 369
370 370 for f, sep in funcmap:
371 371 l = [f(n) for n, dummy in lines]
372 372 if l:
373 373 if fm:
374 374 formats.append(['%s' for x in l])
375 375 else:
376 376 sizes = [encoding.colwidth(x) for x in l]
377 377 ml = max(sizes)
378 378 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
379 379 pieces.append(l)
380 380
381 381 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
382 382 fm.startitem()
383 383 fm.write(fields, "".join(f), *p)
384 384 fm.write('line', ": %s", l[1])
385 385
386 386 if lines and not lines[-1][1].endswith('\n'):
387 387 fm.plain('\n')
388 388
389 389 fm.end()
390 390
391 391 @command('archive',
392 392 [('', 'no-decode', None, _('do not pass files through decoders')),
393 393 ('p', 'prefix', '', _('directory prefix for files in archive'),
394 394 _('PREFIX')),
395 395 ('r', 'rev', '', _('revision to distribute'), _('REV')),
396 396 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
397 397 ] + subrepoopts + walkopts,
398 398 _('[OPTION]... DEST'))
399 399 def archive(ui, repo, dest, **opts):
400 400 '''create an unversioned archive of a repository revision
401 401
402 402 By default, the revision used is the parent of the working
403 403 directory; use -r/--rev to specify a different revision.
404 404
405 405 The archive type is automatically detected based on file
406 406 extension (or override using -t/--type).
407 407
408 408 .. container:: verbose
409 409
410 410 Examples:
411 411
412 412 - create a zip file containing the 1.0 release::
413 413
414 414 hg archive -r 1.0 project-1.0.zip
415 415
416 416 - create a tarball excluding .hg files::
417 417
418 418 hg archive project.tar.gz -X ".hg*"
419 419
420 420 Valid types are:
421 421
422 422 :``files``: a directory full of files (default)
423 423 :``tar``: tar archive, uncompressed
424 424 :``tbz2``: tar archive, compressed using bzip2
425 425 :``tgz``: tar archive, compressed using gzip
426 426 :``uzip``: zip archive, uncompressed
427 427 :``zip``: zip archive, compressed using deflate
428 428
429 429 The exact name of the destination archive or directory is given
430 430 using a format string; see :hg:`help export` for details.
431 431
432 432 Each member added to an archive file has a directory prefix
433 433 prepended. Use -p/--prefix to specify a format string for the
434 434 prefix. The default is the basename of the archive, with suffixes
435 435 removed.
436 436
437 437 Returns 0 on success.
438 438 '''
439 439
440 440 ctx = scmutil.revsingle(repo, opts.get('rev'))
441 441 if not ctx:
442 442 raise error.Abort(_('no working directory: please specify a revision'))
443 443 node = ctx.node()
444 444 dest = cmdutil.makefilename(repo, dest, node)
445 445 if os.path.realpath(dest) == repo.root:
446 446 raise error.Abort(_('repository root cannot be destination'))
447 447
448 448 kind = opts.get('type') or archival.guesskind(dest) or 'files'
449 449 prefix = opts.get('prefix')
450 450
451 451 if dest == '-':
452 452 if kind == 'files':
453 453 raise error.Abort(_('cannot archive plain files to stdout'))
454 454 dest = cmdutil.makefileobj(repo, dest)
455 455 if not prefix:
456 456 prefix = os.path.basename(repo.root) + '-%h'
457 457
458 458 prefix = cmdutil.makefilename(repo, prefix, node)
459 459 matchfn = scmutil.match(ctx, [], opts)
460 460 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
461 461 matchfn, prefix, subrepos=opts.get('subrepos'))
462 462
463 463 @command('backout',
464 464 [('', 'merge', None, _('merge with old dirstate parent after backout')),
465 465 ('', 'commit', None, _('commit if no conflicts were encountered')),
466 466 ('', 'parent', '',
467 467 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
468 468 ('r', 'rev', '', _('revision to backout'), _('REV')),
469 469 ('e', 'edit', False, _('invoke editor on commit messages')),
470 470 ] + mergetoolopts + walkopts + commitopts + commitopts2,
471 471 _('[OPTION]... [-r] REV'))
472 472 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
473 473 '''reverse effect of earlier changeset
474 474
475 475 Prepare a new changeset with the effect of REV undone in the
476 476 current working directory.
477 477
478 478 If REV is the parent of the working directory, then this new changeset
479 479 is committed automatically. Otherwise, hg needs to merge the
480 480 changes and the merged result is left uncommitted.
481 481
482 482 .. note::
483 483
484 484 backout cannot be used to fix either an unwanted or
485 485 incorrect merge.
486 486
487 487 .. container:: verbose
488 488
489 489 By default, the pending changeset will have one parent,
490 490 maintaining a linear history. With --merge, the pending
491 491 changeset will instead have two parents: the old parent of the
492 492 working directory and a new child of REV that simply undoes REV.
493 493
494 494 Before version 1.7, the behavior without --merge was equivalent
495 495 to specifying --merge followed by :hg:`update --clean .` to
496 496 cancel the merge and leave the child of REV as a head to be
497 497 merged separately.
498 498
499 499 See :hg:`help dates` for a list of formats valid for -d/--date.
500 500
501 501 See :hg:`help revert` for a way to restore files to the state
502 502 of another revision.
503 503
504 504 Returns 0 on success, 1 if nothing to backout or there are unresolved
505 505 files.
506 506 '''
507 507 if rev and node:
508 508 raise error.Abort(_("please specify just one revision"))
509 509
510 510 if not rev:
511 511 rev = node
512 512
513 513 if not rev:
514 514 raise error.Abort(_("please specify a revision to backout"))
515 515
516 516 date = opts.get('date')
517 517 if date:
518 518 opts['date'] = util.parsedate(date)
519 519
520 520 cmdutil.checkunfinished(repo)
521 521 cmdutil.bailifchanged(repo)
522 522 node = scmutil.revsingle(repo, rev).node()
523 523
524 524 op1, op2 = repo.dirstate.parents()
525 525 if not repo.changelog.isancestor(node, op1):
526 526 raise error.Abort(_('cannot backout change that is not an ancestor'))
527 527
528 528 p1, p2 = repo.changelog.parents(node)
529 529 if p1 == nullid:
530 530 raise error.Abort(_('cannot backout a change with no parents'))
531 531 if p2 != nullid:
532 532 if not opts.get('parent'):
533 533 raise error.Abort(_('cannot backout a merge changeset'))
534 534 p = repo.lookup(opts['parent'])
535 535 if p not in (p1, p2):
536 536 raise error.Abort(_('%s is not a parent of %s') %
537 537 (short(p), short(node)))
538 538 parent = p
539 539 else:
540 540 if opts.get('parent'):
541 541 raise error.Abort(_('cannot use --parent on non-merge changeset'))
542 542 parent = p1
543 543
544 544 # the backout should appear on the same branch
545 545 wlock = repo.wlock()
546 546 try:
547 547 branch = repo.dirstate.branch()
548 548 bheads = repo.branchheads(branch)
549 549 rctx = scmutil.revsingle(repo, hex(parent))
550 550 if not opts.get('merge') and op1 != node:
551 551 dsguard = cmdutil.dirstateguard(repo, 'backout')
552 552 try:
553 553 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
554 554 'backout')
555 555 stats = mergemod.update(repo, parent, True, True, False,
556 556 node, False)
557 557 repo.setparents(op1, op2)
558 558 dsguard.close()
559 559 hg._showstats(repo, stats)
560 560 if stats[3]:
561 561 repo.ui.status(_("use 'hg resolve' to retry unresolved "
562 562 "file merges\n"))
563 563 return 1
564 564 elif not commit:
565 565 msg = _("changeset %s backed out, "
566 566 "don't forget to commit.\n")
567 567 ui.status(msg % short(node))
568 568 return 0
569 569 finally:
570 570 ui.setconfig('ui', 'forcemerge', '', '')
571 571 lockmod.release(dsguard)
572 572 else:
573 573 hg.clean(repo, node, show_stats=False)
574 574 repo.dirstate.setbranch(branch)
575 575 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
576 576
577 577
578 578 def commitfunc(ui, repo, message, match, opts):
579 579 editform = 'backout'
580 580 e = cmdutil.getcommiteditor(editform=editform, **opts)
581 581 if not message:
582 582 # we don't translate commit messages
583 583 message = "Backed out changeset %s" % short(node)
584 584 e = cmdutil.getcommiteditor(edit=True, editform=editform)
585 585 return repo.commit(message, opts.get('user'), opts.get('date'),
586 586 match, editor=e)
587 587 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
588 588 if not newnode:
589 589 ui.status(_("nothing changed\n"))
590 590 return 1
591 591 cmdutil.commitstatus(repo, newnode, branch, bheads)
592 592
593 593 def nice(node):
594 594 return '%d:%s' % (repo.changelog.rev(node), short(node))
595 595 ui.status(_('changeset %s backs out changeset %s\n') %
596 596 (nice(repo.changelog.tip()), nice(node)))
597 597 if opts.get('merge') and op1 != node:
598 598 hg.clean(repo, op1, show_stats=False)
599 599 ui.status(_('merging with changeset %s\n')
600 600 % nice(repo.changelog.tip()))
601 601 try:
602 602 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
603 603 'backout')
604 604 return hg.merge(repo, hex(repo.changelog.tip()))
605 605 finally:
606 606 ui.setconfig('ui', 'forcemerge', '', '')
607 607 finally:
608 608 wlock.release()
609 609 return 0
610 610
611 611 @command('bisect',
612 612 [('r', 'reset', False, _('reset bisect state')),
613 613 ('g', 'good', False, _('mark changeset good')),
614 614 ('b', 'bad', False, _('mark changeset bad')),
615 615 ('s', 'skip', False, _('skip testing changeset')),
616 616 ('e', 'extend', False, _('extend the bisect range')),
617 617 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
618 618 ('U', 'noupdate', False, _('do not update to target'))],
619 619 _("[-gbsr] [-U] [-c CMD] [REV]"))
620 620 def bisect(ui, repo, rev=None, extra=None, command=None,
621 621 reset=None, good=None, bad=None, skip=None, extend=None,
622 622 noupdate=None):
623 623 """subdivision search of changesets
624 624
625 625 This command helps to find changesets which introduce problems. To
626 626 use, mark the earliest changeset you know exhibits the problem as
627 627 bad, then mark the latest changeset which is free from the problem
628 628 as good. Bisect will update your working directory to a revision
629 629 for testing (unless the -U/--noupdate option is specified). Once
630 630 you have performed tests, mark the working directory as good or
631 631 bad, and bisect will either update to another candidate changeset
632 632 or announce that it has found the bad revision.
633 633
634 634 As a shortcut, you can also use the revision argument to mark a
635 635 revision as good or bad without checking it out first.
636 636
637 637 If you supply a command, it will be used for automatic bisection.
638 638 The environment variable HG_NODE will contain the ID of the
639 639 changeset being tested. The exit status of the command will be
640 640 used to mark revisions as good or bad: status 0 means good, 125
641 641 means to skip the revision, 127 (command not found) will abort the
642 642 bisection, and any other non-zero exit status means the revision
643 643 is bad.
644 644
645 645 .. container:: verbose
646 646
647 647 Some examples:
648 648
649 649 - start a bisection with known bad revision 34, and good revision 12::
650 650
651 651 hg bisect --bad 34
652 652 hg bisect --good 12
653 653
654 654 - advance the current bisection by marking current revision as good or
655 655 bad::
656 656
657 657 hg bisect --good
658 658 hg bisect --bad
659 659
660 660 - mark the current revision, or a known revision, to be skipped (e.g. if
661 661 that revision is not usable because of another issue)::
662 662
663 663 hg bisect --skip
664 664 hg bisect --skip 23
665 665
666 666 - skip all revisions that do not touch directories ``foo`` or ``bar``::
667 667
668 668 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
669 669
670 670 - forget the current bisection::
671 671
672 672 hg bisect --reset
673 673
674 674 - use 'make && make tests' to automatically find the first broken
675 675 revision::
676 676
677 677 hg bisect --reset
678 678 hg bisect --bad 34
679 679 hg bisect --good 12
680 680 hg bisect --command "make && make tests"
681 681
682 682 - see all changesets whose states are already known in the current
683 683 bisection::
684 684
685 685 hg log -r "bisect(pruned)"
686 686
687 687 - see the changeset currently being bisected (especially useful
688 688 if running with -U/--noupdate)::
689 689
690 690 hg log -r "bisect(current)"
691 691
692 692 - see all changesets that took part in the current bisection::
693 693
694 694 hg log -r "bisect(range)"
695 695
696 696 - you can even get a nice graph::
697 697
698 698 hg log --graph -r "bisect(range)"
699 699
700 700 See :hg:`help revsets` for more about the `bisect()` keyword.
701 701
702 702 Returns 0 on success.
703 703 """
704 704 def extendbisectrange(nodes, good):
705 705 # bisect is incomplete when it ends on a merge node and
706 706 # one of the parent was not checked.
707 707 parents = repo[nodes[0]].parents()
708 708 if len(parents) > 1:
709 709 if good:
710 710 side = state['bad']
711 711 else:
712 712 side = state['good']
713 713 num = len(set(i.node() for i in parents) & set(side))
714 714 if num == 1:
715 715 return parents[0].ancestor(parents[1])
716 716 return None
717 717
718 718 def print_result(nodes, good):
719 719 displayer = cmdutil.show_changeset(ui, repo, {})
720 720 if len(nodes) == 1:
721 721 # narrowed it down to a single revision
722 722 if good:
723 723 ui.write(_("The first good revision is:\n"))
724 724 else:
725 725 ui.write(_("The first bad revision is:\n"))
726 726 displayer.show(repo[nodes[0]])
727 727 extendnode = extendbisectrange(nodes, good)
728 728 if extendnode is not None:
729 729 ui.write(_('Not all ancestors of this changeset have been'
730 730 ' checked.\nUse bisect --extend to continue the '
731 731 'bisection from\nthe common ancestor, %s.\n')
732 732 % extendnode)
733 733 else:
734 734 # multiple possible revisions
735 735 if good:
736 736 ui.write(_("Due to skipped revisions, the first "
737 737 "good revision could be any of:\n"))
738 738 else:
739 739 ui.write(_("Due to skipped revisions, the first "
740 740 "bad revision could be any of:\n"))
741 741 for n in nodes:
742 742 displayer.show(repo[n])
743 743 displayer.close()
744 744
745 745 def check_state(state, interactive=True):
746 746 if not state['good'] or not state['bad']:
747 747 if (good or bad or skip or reset) and interactive:
748 748 return
749 749 if not state['good']:
750 750 raise error.Abort(_('cannot bisect (no known good revisions)'))
751 751 else:
752 752 raise error.Abort(_('cannot bisect (no known bad revisions)'))
753 753 return True
754 754
755 755 # backward compatibility
756 756 if rev in "good bad reset init".split():
757 757 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
758 758 cmd, rev, extra = rev, extra, None
759 759 if cmd == "good":
760 760 good = True
761 761 elif cmd == "bad":
762 762 bad = True
763 763 else:
764 764 reset = True
765 765 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
766 766 raise error.Abort(_('incompatible arguments'))
767 767
768 768 cmdutil.checkunfinished(repo)
769 769
770 770 if reset:
771 771 p = repo.join("bisect.state")
772 772 if os.path.exists(p):
773 773 os.unlink(p)
774 774 return
775 775
776 776 state = hbisect.load_state(repo)
777 777
778 778 if command:
779 779 changesets = 1
780 780 if noupdate:
781 781 try:
782 782 node = state['current'][0]
783 783 except LookupError:
784 784 raise error.Abort(_('current bisect revision is unknown - '
785 785 'start a new bisect to fix'))
786 786 else:
787 787 node, p2 = repo.dirstate.parents()
788 788 if p2 != nullid:
789 789 raise error.Abort(_('current bisect revision is a merge'))
790 790 try:
791 791 while changesets:
792 792 # update state
793 793 state['current'] = [node]
794 794 hbisect.save_state(repo, state)
795 795 status = ui.system(command, environ={'HG_NODE': hex(node)})
796 796 if status == 125:
797 797 transition = "skip"
798 798 elif status == 0:
799 799 transition = "good"
800 800 # status < 0 means process was killed
801 801 elif status == 127:
802 802 raise error.Abort(_("failed to execute %s") % command)
803 803 elif status < 0:
804 804 raise error.Abort(_("%s killed") % command)
805 805 else:
806 806 transition = "bad"
807 807 ctx = scmutil.revsingle(repo, rev, node)
808 808 rev = None # clear for future iterations
809 809 state[transition].append(ctx.node())
810 810 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
811 811 check_state(state, interactive=False)
812 812 # bisect
813 813 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
814 814 # update to next check
815 815 node = nodes[0]
816 816 if not noupdate:
817 817 cmdutil.bailifchanged(repo)
818 818 hg.clean(repo, node, show_stats=False)
819 819 finally:
820 820 state['current'] = [node]
821 821 hbisect.save_state(repo, state)
822 822 print_result(nodes, bgood)
823 823 return
824 824
825 825 # update state
826 826
827 827 if rev:
828 828 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
829 829 else:
830 830 nodes = [repo.lookup('.')]
831 831
832 832 if good or bad or skip:
833 833 if good:
834 834 state['good'] += nodes
835 835 elif bad:
836 836 state['bad'] += nodes
837 837 elif skip:
838 838 state['skip'] += nodes
839 839 hbisect.save_state(repo, state)
840 840
841 841 if not check_state(state):
842 842 return
843 843
844 844 # actually bisect
845 845 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
846 846 if extend:
847 847 if not changesets:
848 848 extendnode = extendbisectrange(nodes, good)
849 849 if extendnode is not None:
850 850 ui.write(_("Extending search to changeset %d:%s\n")
851 851 % (extendnode.rev(), extendnode))
852 852 state['current'] = [extendnode.node()]
853 853 hbisect.save_state(repo, state)
854 854 if noupdate:
855 855 return
856 856 cmdutil.bailifchanged(repo)
857 857 return hg.clean(repo, extendnode.node())
858 858 raise error.Abort(_("nothing to extend"))
859 859
860 860 if changesets == 0:
861 861 print_result(nodes, good)
862 862 else:
863 863 assert len(nodes) == 1 # only a single node can be tested next
864 864 node = nodes[0]
865 865 # compute the approximate number of remaining tests
866 866 tests, size = 0, 2
867 867 while size <= changesets:
868 868 tests, size = tests + 1, size * 2
869 869 rev = repo.changelog.rev(node)
870 870 ui.write(_("Testing changeset %d:%s "
871 871 "(%d changesets remaining, ~%d tests)\n")
872 872 % (rev, short(node), changesets, tests))
873 873 state['current'] = [node]
874 874 hbisect.save_state(repo, state)
875 875 if not noupdate:
876 876 cmdutil.bailifchanged(repo)
877 877 return hg.clean(repo, node)
878 878
879 879 @command('bookmarks|bookmark',
880 880 [('f', 'force', False, _('force')),
881 881 ('r', 'rev', '', _('revision'), _('REV')),
882 882 ('d', 'delete', False, _('delete a given bookmark')),
883 883 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
884 884 ('i', 'inactive', False, _('mark a bookmark inactive')),
885 885 ] + formatteropts,
886 886 _('hg bookmarks [OPTIONS]... [NAME]...'))
887 887 def bookmark(ui, repo, *names, **opts):
888 888 '''create a new bookmark or list existing bookmarks
889 889
890 890 Bookmarks are labels on changesets to help track lines of development.
891 891 Bookmarks are unversioned and can be moved, renamed and deleted.
892 892 Deleting or moving a bookmark has no effect on the associated changesets.
893 893
894 894 Creating or updating to a bookmark causes it to be marked as 'active'.
895 895 The active bookmark is indicated with a '*'.
896 896 When a commit is made, the active bookmark will advance to the new commit.
897 897 A plain :hg:`update` will also advance an active bookmark, if possible.
898 898 Updating away from a bookmark will cause it to be deactivated.
899 899
900 900 Bookmarks can be pushed and pulled between repositories (see
901 901 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
902 902 diverged, a new 'divergent bookmark' of the form 'name@path' will
903 903 be created. Using :hg:`merge` will resolve the divergence.
904 904
905 905 A bookmark named '@' has the special property that :hg:`clone` will
906 906 check it out by default if it exists.
907 907
908 908 .. container:: verbose
909 909
910 910 Examples:
911 911
912 912 - create an active bookmark for a new line of development::
913 913
914 914 hg book new-feature
915 915
916 916 - create an inactive bookmark as a place marker::
917 917
918 918 hg book -i reviewed
919 919
920 920 - create an inactive bookmark on another changeset::
921 921
922 922 hg book -r .^ tested
923 923
924 924 - rename bookmark turkey to dinner::
925 925
926 926 hg book -m turkey dinner
927 927
928 928 - move the '@' bookmark from another branch::
929 929
930 930 hg book -f @
931 931 '''
932 932 force = opts.get('force')
933 933 rev = opts.get('rev')
934 934 delete = opts.get('delete')
935 935 rename = opts.get('rename')
936 936 inactive = opts.get('inactive')
937 937
938 938 def checkformat(mark):
939 939 mark = mark.strip()
940 940 if not mark:
941 941 raise error.Abort(_("bookmark names cannot consist entirely of "
942 942 "whitespace"))
943 943 scmutil.checknewlabel(repo, mark, 'bookmark')
944 944 return mark
945 945
946 946 def checkconflict(repo, mark, cur, force=False, target=None):
947 947 if mark in marks and not force:
948 948 if target:
949 949 if marks[mark] == target and target == cur:
950 950 # re-activating a bookmark
951 951 return
952 952 anc = repo.changelog.ancestors([repo[target].rev()])
953 953 bmctx = repo[marks[mark]]
954 954 divs = [repo[b].node() for b in marks
955 955 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
956 956
957 957 # allow resolving a single divergent bookmark even if moving
958 958 # the bookmark across branches when a revision is specified
959 959 # that contains a divergent bookmark
960 960 if bmctx.rev() not in anc and target in divs:
961 961 bookmarks.deletedivergent(repo, [target], mark)
962 962 return
963 963
964 964 deletefrom = [b for b in divs
965 965 if repo[b].rev() in anc or b == target]
966 966 bookmarks.deletedivergent(repo, deletefrom, mark)
967 967 if bookmarks.validdest(repo, bmctx, repo[target]):
968 968 ui.status(_("moving bookmark '%s' forward from %s\n") %
969 969 (mark, short(bmctx.node())))
970 970 return
971 971 raise error.Abort(_("bookmark '%s' already exists "
972 972 "(use -f to force)") % mark)
973 973 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
974 974 and not force):
975 975 raise error.Abort(
976 976 _("a bookmark cannot have the name of an existing branch"))
977 977
978 978 if delete and rename:
979 979 raise error.Abort(_("--delete and --rename are incompatible"))
980 980 if delete and rev:
981 981 raise error.Abort(_("--rev is incompatible with --delete"))
982 982 if rename and rev:
983 983 raise error.Abort(_("--rev is incompatible with --rename"))
984 984 if not names and (delete or rev):
985 985 raise error.Abort(_("bookmark name required"))
986 986
987 987 if delete or rename or names or inactive:
988 988 wlock = lock = tr = None
989 989 try:
990 990 wlock = repo.wlock()
991 991 lock = repo.lock()
992 992 cur = repo.changectx('.').node()
993 993 marks = repo._bookmarks
994 994 if delete:
995 995 tr = repo.transaction('bookmark')
996 996 for mark in names:
997 997 if mark not in marks:
998 998 raise error.Abort(_("bookmark '%s' does not exist") %
999 999 mark)
1000 1000 if mark == repo._activebookmark:
1001 1001 bookmarks.deactivate(repo)
1002 1002 del marks[mark]
1003 1003
1004 1004 elif rename:
1005 1005 tr = repo.transaction('bookmark')
1006 1006 if not names:
1007 1007 raise error.Abort(_("new bookmark name required"))
1008 1008 elif len(names) > 1:
1009 1009 raise error.Abort(_("only one new bookmark name allowed"))
1010 1010 mark = checkformat(names[0])
1011 1011 if rename not in marks:
1012 1012 raise error.Abort(_("bookmark '%s' does not exist")
1013 1013 % rename)
1014 1014 checkconflict(repo, mark, cur, force)
1015 1015 marks[mark] = marks[rename]
1016 1016 if repo._activebookmark == rename and not inactive:
1017 1017 bookmarks.activate(repo, mark)
1018 1018 del marks[rename]
1019 1019 elif names:
1020 1020 tr = repo.transaction('bookmark')
1021 1021 newact = None
1022 1022 for mark in names:
1023 1023 mark = checkformat(mark)
1024 1024 if newact is None:
1025 1025 newact = mark
1026 1026 if inactive and mark == repo._activebookmark:
1027 1027 bookmarks.deactivate(repo)
1028 1028 return
1029 1029 tgt = cur
1030 1030 if rev:
1031 1031 tgt = scmutil.revsingle(repo, rev).node()
1032 1032 checkconflict(repo, mark, cur, force, tgt)
1033 1033 marks[mark] = tgt
1034 1034 if not inactive and cur == marks[newact] and not rev:
1035 1035 bookmarks.activate(repo, newact)
1036 1036 elif cur != tgt and newact == repo._activebookmark:
1037 1037 bookmarks.deactivate(repo)
1038 1038 elif inactive:
1039 1039 if len(marks) == 0:
1040 1040 ui.status(_("no bookmarks set\n"))
1041 1041 elif not repo._activebookmark:
1042 1042 ui.status(_("no active bookmark\n"))
1043 1043 else:
1044 1044 bookmarks.deactivate(repo)
1045 1045 if tr is not None:
1046 1046 marks.recordchange(tr)
1047 1047 tr.close()
1048 1048 finally:
1049 1049 lockmod.release(tr, lock, wlock)
1050 1050 else: # show bookmarks
1051 1051 fm = ui.formatter('bookmarks', opts)
1052 1052 hexfn = fm.hexfunc
1053 1053 marks = repo._bookmarks
1054 1054 if len(marks) == 0 and not fm:
1055 1055 ui.status(_("no bookmarks set\n"))
1056 1056 for bmark, n in sorted(marks.iteritems()):
1057 1057 active = repo._activebookmark
1058 1058 if bmark == active:
1059 1059 prefix, label = '*', activebookmarklabel
1060 1060 else:
1061 1061 prefix, label = ' ', ''
1062 1062
1063 1063 fm.startitem()
1064 1064 if not ui.quiet:
1065 1065 fm.plain(' %s ' % prefix, label=label)
1066 1066 fm.write('bookmark', '%s', bmark, label=label)
1067 1067 pad = " " * (25 - encoding.colwidth(bmark))
1068 1068 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1069 1069 repo.changelog.rev(n), hexfn(n), label=label)
1070 1070 fm.data(active=(bmark == active))
1071 1071 fm.plain('\n')
1072 1072 fm.end()
1073 1073
1074 1074 @command('branch',
1075 1075 [('f', 'force', None,
1076 1076 _('set branch name even if it shadows an existing branch')),
1077 1077 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1078 1078 _('[-fC] [NAME]'))
1079 1079 def branch(ui, repo, label=None, **opts):
1080 1080 """set or show the current branch name
1081 1081
1082 1082 .. note::
1083 1083
1084 1084 Branch names are permanent and global. Use :hg:`bookmark` to create a
1085 1085 light-weight bookmark instead. See :hg:`help glossary` for more
1086 1086 information about named branches and bookmarks.
1087 1087
1088 1088 With no argument, show the current branch name. With one argument,
1089 1089 set the working directory branch name (the branch will not exist
1090 1090 in the repository until the next commit). Standard practice
1091 1091 recommends that primary development take place on the 'default'
1092 1092 branch.
1093 1093
1094 1094 Unless -f/--force is specified, branch will not let you set a
1095 1095 branch name that already exists.
1096 1096
1097 1097 Use -C/--clean to reset the working directory branch to that of
1098 1098 the parent of the working directory, negating a previous branch
1099 1099 change.
1100 1100
1101 1101 Use the command :hg:`update` to switch to an existing branch. Use
1102 1102 :hg:`commit --close-branch` to mark this branch head as closed.
1103 1103 When all heads of the branch are closed, the branch will be
1104 1104 considered closed.
1105 1105
1106 1106 Returns 0 on success.
1107 1107 """
1108 1108 if label:
1109 1109 label = label.strip()
1110 1110
1111 1111 if not opts.get('clean') and not label:
1112 1112 ui.write("%s\n" % repo.dirstate.branch())
1113 1113 return
1114 1114
1115 1115 wlock = repo.wlock()
1116 1116 try:
1117 1117 if opts.get('clean'):
1118 1118 label = repo[None].p1().branch()
1119 1119 repo.dirstate.setbranch(label)
1120 1120 ui.status(_('reset working directory to branch %s\n') % label)
1121 1121 elif label:
1122 1122 if not opts.get('force') and label in repo.branchmap():
1123 1123 if label not in [p.branch() for p in repo.parents()]:
1124 1124 raise error.Abort(_('a branch of the same name already'
1125 1125 ' exists'),
1126 1126 # i18n: "it" refers to an existing branch
1127 1127 hint=_("use 'hg update' to switch to it"))
1128 1128 scmutil.checknewlabel(repo, label, 'branch')
1129 1129 repo.dirstate.setbranch(label)
1130 1130 ui.status(_('marked working directory as branch %s\n') % label)
1131 1131
1132 1132 # find any open named branches aside from default
1133 1133 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1134 1134 if n != "default" and not c]
1135 1135 if not others:
1136 1136 ui.status(_('(branches are permanent and global, '
1137 1137 'did you want a bookmark?)\n'))
1138 1138 finally:
1139 1139 wlock.release()
1140 1140
1141 1141 @command('branches',
1142 1142 [('a', 'active', False,
1143 1143 _('show only branches that have unmerged heads (DEPRECATED)')),
1144 1144 ('c', 'closed', False, _('show normal and closed branches')),
1145 1145 ] + formatteropts,
1146 1146 _('[-ac]'))
1147 1147 def branches(ui, repo, active=False, closed=False, **opts):
1148 1148 """list repository named branches
1149 1149
1150 1150 List the repository's named branches, indicating which ones are
1151 1151 inactive. If -c/--closed is specified, also list branches which have
1152 1152 been marked closed (see :hg:`commit --close-branch`).
1153 1153
1154 1154 Use the command :hg:`update` to switch to an existing branch.
1155 1155
1156 1156 Returns 0.
1157 1157 """
1158 1158
1159 1159 fm = ui.formatter('branches', opts)
1160 1160 hexfunc = fm.hexfunc
1161 1161
1162 1162 allheads = set(repo.heads())
1163 1163 branches = []
1164 1164 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1165 1165 isactive = not isclosed and bool(set(heads) & allheads)
1166 1166 branches.append((tag, repo[tip], isactive, not isclosed))
1167 1167 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1168 1168 reverse=True)
1169 1169
1170 1170 for tag, ctx, isactive, isopen in branches:
1171 1171 if active and not isactive:
1172 1172 continue
1173 1173 if isactive:
1174 1174 label = 'branches.active'
1175 1175 notice = ''
1176 1176 elif not isopen:
1177 1177 if not closed:
1178 1178 continue
1179 1179 label = 'branches.closed'
1180 1180 notice = _(' (closed)')
1181 1181 else:
1182 1182 label = 'branches.inactive'
1183 1183 notice = _(' (inactive)')
1184 1184 current = (tag == repo.dirstate.branch())
1185 1185 if current:
1186 1186 label = 'branches.current'
1187 1187
1188 1188 fm.startitem()
1189 1189 fm.write('branch', '%s', tag, label=label)
1190 1190 rev = ctx.rev()
1191 1191 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1192 1192 fmt = ' ' * padsize + ' %d:%s'
1193 1193 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1194 1194 label='log.changeset changeset.%s' % ctx.phasestr())
1195 1195 fm.data(active=isactive, closed=not isopen, current=current)
1196 1196 if not ui.quiet:
1197 1197 fm.plain(notice)
1198 1198 fm.plain('\n')
1199 1199 fm.end()
1200 1200
1201 1201 @command('bundle',
1202 1202 [('f', 'force', None, _('run even when the destination is unrelated')),
1203 1203 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1204 1204 _('REV')),
1205 1205 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1206 1206 _('BRANCH')),
1207 1207 ('', 'base', [],
1208 1208 _('a base changeset assumed to be available at the destination'),
1209 1209 _('REV')),
1210 1210 ('a', 'all', None, _('bundle all changesets in the repository')),
1211 1211 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1212 1212 ] + remoteopts,
1213 1213 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1214 1214 def bundle(ui, repo, fname, dest=None, **opts):
1215 1215 """create a changegroup file
1216 1216
1217 1217 Generate a compressed changegroup file collecting changesets not
1218 1218 known to be in another repository.
1219 1219
1220 1220 If you omit the destination repository, then hg assumes the
1221 1221 destination will have all the nodes you specify with --base
1222 1222 parameters. To create a bundle containing all changesets, use
1223 1223 -a/--all (or --base null).
1224 1224
1225 1225 You can change bundle format with the -t/--type option. You can
1226 1226 specify a compression, a bundle version or both using a dash
1227 1227 (comp-version). The available compression methods are: none, bzip2,
1228 1228 and gzip (by default, bundles are compressed using bzip2). The
1229 1229 available format are: v1, v2 (default to most suitable).
1230 1230
1231 1231 The bundle file can then be transferred using conventional means
1232 1232 and applied to another repository with the unbundle or pull
1233 1233 command. This is useful when direct push and pull are not
1234 1234 available or when exporting an entire repository is undesirable.
1235 1235
1236 1236 Applying bundles preserves all changeset contents including
1237 1237 permissions, copy/rename information, and revision history.
1238 1238
1239 1239 Returns 0 on success, 1 if no changes found.
1240 1240 """
1241 1241 revs = None
1242 1242 if 'rev' in opts:
1243 1243 revs = scmutil.revrange(repo, opts['rev'])
1244 1244
1245 1245 bundletype = opts.get('type', 'bzip2').lower()
1246 1246 try:
1247 1247 bcompression, cgversion = exchange.parsebundlespec(
1248 1248 repo, bundletype, strict=False)
1249 1249 except error.UnsupportedBundleSpecification as e:
1250 1250 raise error.Abort(str(e),
1251 1251 hint=_('see "hg help bundle" for supported '
1252 1252 'values for --type'))
1253 1253
1254 1254 # Packed bundles are a pseudo bundle format for now.
1255 1255 if cgversion == 's1':
1256 1256 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1257 1257 hint=_('use "hg debugcreatestreamclonebundle"'))
1258 1258
1259 1259 if opts.get('all'):
1260 1260 base = ['null']
1261 1261 else:
1262 1262 base = scmutil.revrange(repo, opts.get('base'))
1263 1263 # TODO: get desired bundlecaps from command line.
1264 1264 bundlecaps = None
1265 1265 if base:
1266 1266 if dest:
1267 1267 raise error.Abort(_("--base is incompatible with specifying "
1268 1268 "a destination"))
1269 1269 common = [repo.lookup(rev) for rev in base]
1270 1270 heads = revs and map(repo.lookup, revs) or revs
1271 1271 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1272 1272 common=common, bundlecaps=bundlecaps,
1273 1273 version=cgversion)
1274 1274 outgoing = None
1275 1275 else:
1276 1276 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1277 1277 dest, branches = hg.parseurl(dest, opts.get('branch'))
1278 1278 other = hg.peer(repo, opts, dest)
1279 1279 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1280 1280 heads = revs and map(repo.lookup, revs) or revs
1281 1281 outgoing = discovery.findcommonoutgoing(repo, other,
1282 1282 onlyheads=heads,
1283 1283 force=opts.get('force'),
1284 1284 portable=True)
1285 1285 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1286 1286 bundlecaps, version=cgversion)
1287 1287 if not cg:
1288 1288 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1289 1289 return 1
1290 1290
1291 1291 if cgversion == '01': #bundle1
1292 1292 if bcompression is None:
1293 1293 bcompression = 'UN'
1294 1294 bversion = 'HG10' + bcompression
1295 1295 bcompression = None
1296 1296 else:
1297 1297 assert cgversion == '02'
1298 1298 bversion = 'HG20'
1299 1299
1300 1300
1301 1301 changegroup.writebundle(ui, cg, fname, bversion, compression=bcompression)
1302 1302
1303 1303 @command('cat',
1304 1304 [('o', 'output', '',
1305 1305 _('print output to file with formatted name'), _('FORMAT')),
1306 1306 ('r', 'rev', '', _('print the given revision'), _('REV')),
1307 1307 ('', 'decode', None, _('apply any matching decode filter')),
1308 1308 ] + walkopts,
1309 1309 _('[OPTION]... FILE...'),
1310 1310 inferrepo=True)
1311 1311 def cat(ui, repo, file1, *pats, **opts):
1312 1312 """output the current or given revision of files
1313 1313
1314 1314 Print the specified files as they were at the given revision. If
1315 1315 no revision is given, the parent of the working directory is used.
1316 1316
1317 1317 Output may be to a file, in which case the name of the file is
1318 1318 given using a format string. The formatting rules as follows:
1319 1319
1320 1320 :``%%``: literal "%" character
1321 1321 :``%s``: basename of file being printed
1322 1322 :``%d``: dirname of file being printed, or '.' if in repository root
1323 1323 :``%p``: root-relative path name of file being printed
1324 1324 :``%H``: changeset hash (40 hexadecimal digits)
1325 1325 :``%R``: changeset revision number
1326 1326 :``%h``: short-form changeset hash (12 hexadecimal digits)
1327 1327 :``%r``: zero-padded changeset revision number
1328 1328 :``%b``: basename of the exporting repository
1329 1329
1330 1330 Returns 0 on success.
1331 1331 """
1332 1332 ctx = scmutil.revsingle(repo, opts.get('rev'))
1333 1333 m = scmutil.match(ctx, (file1,) + pats, opts)
1334 1334
1335 1335 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1336 1336
1337 1337 @command('^clone',
1338 1338 [('U', 'noupdate', None, _('the clone will include an empty working '
1339 1339 'directory (only a repository)')),
1340 1340 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1341 1341 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1342 1342 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1343 1343 ('', 'pull', None, _('use pull protocol to copy metadata')),
1344 1344 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1345 1345 ] + remoteopts,
1346 1346 _('[OPTION]... SOURCE [DEST]'),
1347 1347 norepo=True)
1348 1348 def clone(ui, source, dest=None, **opts):
1349 1349 """make a copy of an existing repository
1350 1350
1351 1351 Create a copy of an existing repository in a new directory.
1352 1352
1353 1353 If no destination directory name is specified, it defaults to the
1354 1354 basename of the source.
1355 1355
1356 1356 The location of the source is added to the new repository's
1357 1357 ``.hg/hgrc`` file, as the default to be used for future pulls.
1358 1358
1359 1359 Only local paths and ``ssh://`` URLs are supported as
1360 1360 destinations. For ``ssh://`` destinations, no working directory or
1361 1361 ``.hg/hgrc`` will be created on the remote side.
1362 1362
1363 1363 To pull only a subset of changesets, specify one or more revisions
1364 1364 identifiers with -r/--rev or branches with -b/--branch. The
1365 1365 resulting clone will contain only the specified changesets and
1366 1366 their ancestors. These options (or 'clone src#rev dest') imply
1367 1367 --pull, even for local source repositories. Note that specifying a
1368 1368 tag will include the tagged changeset but not the changeset
1369 1369 containing the tag.
1370 1370
1371 1371 If the source repository has a bookmark called '@' set, that
1372 1372 revision will be checked out in the new repository by default.
1373 1373
1374 1374 To check out a particular version, use -u/--update, or
1375 1375 -U/--noupdate to create a clone with no working directory.
1376 1376
1377 1377 .. container:: verbose
1378 1378
1379 1379 For efficiency, hardlinks are used for cloning whenever the
1380 1380 source and destination are on the same filesystem (note this
1381 1381 applies only to the repository data, not to the working
1382 1382 directory). Some filesystems, such as AFS, implement hardlinking
1383 1383 incorrectly, but do not report errors. In these cases, use the
1384 1384 --pull option to avoid hardlinking.
1385 1385
1386 1386 In some cases, you can clone repositories and the working
1387 1387 directory using full hardlinks with ::
1388 1388
1389 1389 $ cp -al REPO REPOCLONE
1390 1390
1391 1391 This is the fastest way to clone, but it is not always safe. The
1392 1392 operation is not atomic (making sure REPO is not modified during
1393 1393 the operation is up to you) and you have to make sure your
1394 1394 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1395 1395 so). Also, this is not compatible with certain extensions that
1396 1396 place their metadata under the .hg directory, such as mq.
1397 1397
1398 1398 Mercurial will update the working directory to the first applicable
1399 1399 revision from this list:
1400 1400
1401 1401 a) null if -U or the source repository has no changesets
1402 1402 b) if -u . and the source repository is local, the first parent of
1403 1403 the source repository's working directory
1404 1404 c) the changeset specified with -u (if a branch name, this means the
1405 1405 latest head of that branch)
1406 1406 d) the changeset specified with -r
1407 1407 e) the tipmost head specified with -b
1408 1408 f) the tipmost head specified with the url#branch source syntax
1409 1409 g) the revision marked with the '@' bookmark, if present
1410 1410 h) the tipmost head of the default branch
1411 1411 i) tip
1412 1412
1413 1413 Examples:
1414 1414
1415 1415 - clone a remote repository to a new directory named hg/::
1416 1416
1417 1417 hg clone http://selenic.com/hg
1418 1418
1419 1419 - create a lightweight local clone::
1420 1420
1421 1421 hg clone project/ project-feature/
1422 1422
1423 1423 - clone from an absolute path on an ssh server (note double-slash)::
1424 1424
1425 1425 hg clone ssh://user@server//home/projects/alpha/
1426 1426
1427 1427 - do a high-speed clone over a LAN while checking out a
1428 1428 specified version::
1429 1429
1430 1430 hg clone --uncompressed http://server/repo -u 1.5
1431 1431
1432 1432 - create a repository without changesets after a particular revision::
1433 1433
1434 1434 hg clone -r 04e544 experimental/ good/
1435 1435
1436 1436 - clone (and track) a particular named branch::
1437 1437
1438 1438 hg clone http://selenic.com/hg#stable
1439 1439
1440 1440 See :hg:`help urls` for details on specifying URLs.
1441 1441
1442 1442 Returns 0 on success.
1443 1443 """
1444 1444 if opts.get('noupdate') and opts.get('updaterev'):
1445 1445 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1446 1446
1447 1447 r = hg.clone(ui, opts, source, dest,
1448 1448 pull=opts.get('pull'),
1449 1449 stream=opts.get('uncompressed'),
1450 1450 rev=opts.get('rev'),
1451 1451 update=opts.get('updaterev') or not opts.get('noupdate'),
1452 1452 branch=opts.get('branch'),
1453 1453 shareopts=opts.get('shareopts'))
1454 1454
1455 1455 return r is None
1456 1456
1457 1457 @command('^commit|ci',
1458 1458 [('A', 'addremove', None,
1459 1459 _('mark new/missing files as added/removed before committing')),
1460 1460 ('', 'close-branch', None,
1461 1461 _('mark a branch head as closed')),
1462 1462 ('', 'amend', None, _('amend the parent of the working directory')),
1463 1463 ('s', 'secret', None, _('use the secret phase for committing')),
1464 1464 ('e', 'edit', None, _('invoke editor on commit messages')),
1465 1465 ('i', 'interactive', None, _('use interactive mode')),
1466 1466 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1467 1467 _('[OPTION]... [FILE]...'),
1468 1468 inferrepo=True)
1469 1469 def commit(ui, repo, *pats, **opts):
1470 1470 """commit the specified files or all outstanding changes
1471 1471
1472 1472 Commit changes to the given files into the repository. Unlike a
1473 1473 centralized SCM, this operation is a local operation. See
1474 1474 :hg:`push` for a way to actively distribute your changes.
1475 1475
1476 1476 If a list of files is omitted, all changes reported by :hg:`status`
1477 1477 will be committed.
1478 1478
1479 1479 If you are committing the result of a merge, do not provide any
1480 1480 filenames or -I/-X filters.
1481 1481
1482 1482 If no commit message is specified, Mercurial starts your
1483 1483 configured editor where you can enter a message. In case your
1484 1484 commit fails, you will find a backup of your message in
1485 1485 ``.hg/last-message.txt``.
1486 1486
1487 1487 The --close-branch flag can be used to mark the current branch
1488 1488 head closed. When all heads of a branch are closed, the branch
1489 1489 will be considered closed and no longer listed.
1490 1490
1491 1491 The --amend flag can be used to amend the parent of the
1492 1492 working directory with a new commit that contains the changes
1493 1493 in the parent in addition to those currently reported by :hg:`status`,
1494 1494 if there are any. The old commit is stored in a backup bundle in
1495 1495 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1496 1496 on how to restore it).
1497 1497
1498 1498 Message, user and date are taken from the amended commit unless
1499 1499 specified. When a message isn't specified on the command line,
1500 1500 the editor will open with the message of the amended commit.
1501 1501
1502 1502 It is not possible to amend public changesets (see :hg:`help phases`)
1503 1503 or changesets that have children.
1504 1504
1505 1505 See :hg:`help dates` for a list of formats valid for -d/--date.
1506 1506
1507 1507 Returns 0 on success, 1 if nothing changed.
1508 1508 """
1509 1509 if opts.get('interactive'):
1510 1510 opts.pop('interactive')
1511 1511 cmdutil.dorecord(ui, repo, commit, None, False,
1512 1512 cmdutil.recordfilter, *pats, **opts)
1513 1513 return
1514 1514
1515 1515 if opts.get('subrepos'):
1516 1516 if opts.get('amend'):
1517 1517 raise error.Abort(_('cannot amend with --subrepos'))
1518 1518 # Let --subrepos on the command line override config setting.
1519 1519 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1520 1520
1521 1521 cmdutil.checkunfinished(repo, commit=True)
1522 1522
1523 1523 branch = repo[None].branch()
1524 1524 bheads = repo.branchheads(branch)
1525 1525
1526 1526 extra = {}
1527 1527 if opts.get('close_branch'):
1528 1528 extra['close'] = 1
1529 1529
1530 1530 if not bheads:
1531 1531 raise error.Abort(_('can only close branch heads'))
1532 1532 elif opts.get('amend'):
1533 1533 if repo.parents()[0].p1().branch() != branch and \
1534 1534 repo.parents()[0].p2().branch() != branch:
1535 1535 raise error.Abort(_('can only close branch heads'))
1536 1536
1537 1537 if opts.get('amend'):
1538 1538 if ui.configbool('ui', 'commitsubrepos'):
1539 1539 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1540 1540
1541 1541 old = repo['.']
1542 1542 if not old.mutable():
1543 1543 raise error.Abort(_('cannot amend public changesets'))
1544 1544 if len(repo[None].parents()) > 1:
1545 1545 raise error.Abort(_('cannot amend while merging'))
1546 1546 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1547 1547 if not allowunstable and old.children():
1548 1548 raise error.Abort(_('cannot amend changeset with children'))
1549 1549
1550 1550 # commitfunc is used only for temporary amend commit by cmdutil.amend
1551 1551 def commitfunc(ui, repo, message, match, opts):
1552 1552 return repo.commit(message,
1553 1553 opts.get('user') or old.user(),
1554 1554 opts.get('date') or old.date(),
1555 1555 match,
1556 1556 extra=extra)
1557 1557
1558 1558 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1559 1559 if node == old.node():
1560 1560 ui.status(_("nothing changed\n"))
1561 1561 return 1
1562 1562 else:
1563 1563 def commitfunc(ui, repo, message, match, opts):
1564 1564 backup = ui.backupconfig('phases', 'new-commit')
1565 1565 baseui = repo.baseui
1566 1566 basebackup = baseui.backupconfig('phases', 'new-commit')
1567 1567 try:
1568 1568 if opts.get('secret'):
1569 1569 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1570 1570 # Propagate to subrepos
1571 1571 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1572 1572
1573 1573 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1574 1574 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1575 1575 return repo.commit(message, opts.get('user'), opts.get('date'),
1576 1576 match,
1577 1577 editor=editor,
1578 1578 extra=extra)
1579 1579 finally:
1580 1580 ui.restoreconfig(backup)
1581 1581 repo.baseui.restoreconfig(basebackup)
1582 1582
1583 1583
1584 1584 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1585 1585
1586 1586 if not node:
1587 1587 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1588 1588 if stat[3]:
1589 1589 ui.status(_("nothing changed (%d missing files, see "
1590 1590 "'hg status')\n") % len(stat[3]))
1591 1591 else:
1592 1592 ui.status(_("nothing changed\n"))
1593 1593 return 1
1594 1594
1595 1595 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1596 1596
1597 1597 @command('config|showconfig|debugconfig',
1598 1598 [('u', 'untrusted', None, _('show untrusted configuration options')),
1599 1599 ('e', 'edit', None, _('edit user config')),
1600 1600 ('l', 'local', None, _('edit repository config')),
1601 1601 ('g', 'global', None, _('edit global config'))],
1602 1602 _('[-u] [NAME]...'),
1603 1603 optionalrepo=True)
1604 1604 def config(ui, repo, *values, **opts):
1605 1605 """show combined config settings from all hgrc files
1606 1606
1607 1607 With no arguments, print names and values of all config items.
1608 1608
1609 1609 With one argument of the form section.name, print just the value
1610 1610 of that config item.
1611 1611
1612 1612 With multiple arguments, print names and values of all config
1613 1613 items with matching section names.
1614 1614
1615 1615 With --edit, start an editor on the user-level config file. With
1616 1616 --global, edit the system-wide config file. With --local, edit the
1617 1617 repository-level config file.
1618 1618
1619 1619 With --debug, the source (filename and line number) is printed
1620 1620 for each config item.
1621 1621
1622 1622 See :hg:`help config` for more information about config files.
1623 1623
1624 1624 Returns 0 on success, 1 if NAME does not exist.
1625 1625
1626 1626 """
1627 1627
1628 1628 if opts.get('edit') or opts.get('local') or opts.get('global'):
1629 1629 if opts.get('local') and opts.get('global'):
1630 1630 raise error.Abort(_("can't use --local and --global together"))
1631 1631
1632 1632 if opts.get('local'):
1633 1633 if not repo:
1634 1634 raise error.Abort(_("can't use --local outside a repository"))
1635 1635 paths = [repo.join('hgrc')]
1636 1636 elif opts.get('global'):
1637 1637 paths = scmutil.systemrcpath()
1638 1638 else:
1639 1639 paths = scmutil.userrcpath()
1640 1640
1641 1641 for f in paths:
1642 1642 if os.path.exists(f):
1643 1643 break
1644 1644 else:
1645 1645 if opts.get('global'):
1646 1646 samplehgrc = uimod.samplehgrcs['global']
1647 1647 elif opts.get('local'):
1648 1648 samplehgrc = uimod.samplehgrcs['local']
1649 1649 else:
1650 1650 samplehgrc = uimod.samplehgrcs['user']
1651 1651
1652 1652 f = paths[0]
1653 1653 fp = open(f, "w")
1654 1654 fp.write(samplehgrc)
1655 1655 fp.close()
1656 1656
1657 1657 editor = ui.geteditor()
1658 1658 ui.system("%s \"%s\"" % (editor, f),
1659 1659 onerr=error.Abort, errprefix=_("edit failed"))
1660 1660 return
1661 1661
1662 1662 for f in scmutil.rcpath():
1663 1663 ui.debug('read config from: %s\n' % f)
1664 1664 untrusted = bool(opts.get('untrusted'))
1665 1665 if values:
1666 1666 sections = [v for v in values if '.' not in v]
1667 1667 items = [v for v in values if '.' in v]
1668 1668 if len(items) > 1 or items and sections:
1669 1669 raise error.Abort(_('only one config item permitted'))
1670 1670 matched = False
1671 1671 for section, name, value in ui.walkconfig(untrusted=untrusted):
1672 1672 value = str(value).replace('\n', '\\n')
1673 1673 sectname = section + '.' + name
1674 1674 if values:
1675 1675 for v in values:
1676 1676 if v == section:
1677 1677 ui.debug('%s: ' %
1678 1678 ui.configsource(section, name, untrusted))
1679 1679 ui.write('%s=%s\n' % (sectname, value))
1680 1680 matched = True
1681 1681 elif v == sectname:
1682 1682 ui.debug('%s: ' %
1683 1683 ui.configsource(section, name, untrusted))
1684 1684 ui.write(value, '\n')
1685 1685 matched = True
1686 1686 else:
1687 1687 ui.debug('%s: ' %
1688 1688 ui.configsource(section, name, untrusted))
1689 1689 ui.write('%s=%s\n' % (sectname, value))
1690 1690 matched = True
1691 1691 if matched:
1692 1692 return 0
1693 1693 return 1
1694 1694
1695 1695 @command('copy|cp',
1696 1696 [('A', 'after', None, _('record a copy that has already occurred')),
1697 1697 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1698 1698 ] + walkopts + dryrunopts,
1699 1699 _('[OPTION]... [SOURCE]... DEST'))
1700 1700 def copy(ui, repo, *pats, **opts):
1701 1701 """mark files as copied for the next commit
1702 1702
1703 1703 Mark dest as having copies of source files. If dest is a
1704 1704 directory, copies are put in that directory. If dest is a file,
1705 1705 the source must be a single file.
1706 1706
1707 1707 By default, this command copies the contents of files as they
1708 1708 exist in the working directory. If invoked with -A/--after, the
1709 1709 operation is recorded, but no copying is performed.
1710 1710
1711 1711 This command takes effect with the next commit. To undo a copy
1712 1712 before that, see :hg:`revert`.
1713 1713
1714 1714 Returns 0 on success, 1 if errors are encountered.
1715 1715 """
1716 1716 wlock = repo.wlock(False)
1717 1717 try:
1718 1718 return cmdutil.copy(ui, repo, pats, opts)
1719 1719 finally:
1720 1720 wlock.release()
1721 1721
1722 1722 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1723 1723 def debugancestor(ui, repo, *args):
1724 1724 """find the ancestor revision of two revisions in a given index"""
1725 1725 if len(args) == 3:
1726 1726 index, rev1, rev2 = args
1727 1727 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1728 1728 lookup = r.lookup
1729 1729 elif len(args) == 2:
1730 1730 if not repo:
1731 1731 raise error.Abort(_("there is no Mercurial repository here "
1732 1732 "(.hg not found)"))
1733 1733 rev1, rev2 = args
1734 1734 r = repo.changelog
1735 1735 lookup = repo.lookup
1736 1736 else:
1737 1737 raise error.Abort(_('either two or three arguments required'))
1738 1738 a = r.ancestor(lookup(rev1), lookup(rev2))
1739 1739 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1740 1740
1741 1741 @command('debugbuilddag',
1742 1742 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1743 1743 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1744 1744 ('n', 'new-file', None, _('add new file at each rev'))],
1745 1745 _('[OPTION]... [TEXT]'))
1746 1746 def debugbuilddag(ui, repo, text=None,
1747 1747 mergeable_file=False,
1748 1748 overwritten_file=False,
1749 1749 new_file=False):
1750 1750 """builds a repo with a given DAG from scratch in the current empty repo
1751 1751
1752 1752 The description of the DAG is read from stdin if not given on the
1753 1753 command line.
1754 1754
1755 1755 Elements:
1756 1756
1757 1757 - "+n" is a linear run of n nodes based on the current default parent
1758 1758 - "." is a single node based on the current default parent
1759 1759 - "$" resets the default parent to null (implied at the start);
1760 1760 otherwise the default parent is always the last node created
1761 1761 - "<p" sets the default parent to the backref p
1762 1762 - "*p" is a fork at parent p, which is a backref
1763 1763 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1764 1764 - "/p2" is a merge of the preceding node and p2
1765 1765 - ":tag" defines a local tag for the preceding node
1766 1766 - "@branch" sets the named branch for subsequent nodes
1767 1767 - "#...\\n" is a comment up to the end of the line
1768 1768
1769 1769 Whitespace between the above elements is ignored.
1770 1770
1771 1771 A backref is either
1772 1772
1773 1773 - a number n, which references the node curr-n, where curr is the current
1774 1774 node, or
1775 1775 - the name of a local tag you placed earlier using ":tag", or
1776 1776 - empty to denote the default parent.
1777 1777
1778 1778 All string valued-elements are either strictly alphanumeric, or must
1779 1779 be enclosed in double quotes ("..."), with "\\" as escape character.
1780 1780 """
1781 1781
1782 1782 if text is None:
1783 1783 ui.status(_("reading DAG from stdin\n"))
1784 1784 text = ui.fin.read()
1785 1785
1786 1786 cl = repo.changelog
1787 1787 if len(cl) > 0:
1788 1788 raise error.Abort(_('repository is not empty'))
1789 1789
1790 1790 # determine number of revs in DAG
1791 1791 total = 0
1792 1792 for type, data in dagparser.parsedag(text):
1793 1793 if type == 'n':
1794 1794 total += 1
1795 1795
1796 1796 if mergeable_file:
1797 1797 linesperrev = 2
1798 1798 # make a file with k lines per rev
1799 1799 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1800 1800 initialmergedlines.append("")
1801 1801
1802 1802 tags = []
1803 1803
1804 1804 lock = tr = None
1805 1805 try:
1806 1806 lock = repo.lock()
1807 1807 tr = repo.transaction("builddag")
1808 1808
1809 1809 at = -1
1810 1810 atbranch = 'default'
1811 1811 nodeids = []
1812 1812 id = 0
1813 1813 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1814 1814 for type, data in dagparser.parsedag(text):
1815 1815 if type == 'n':
1816 1816 ui.note(('node %s\n' % str(data)))
1817 1817 id, ps = data
1818 1818
1819 1819 files = []
1820 1820 fctxs = {}
1821 1821
1822 1822 p2 = None
1823 1823 if mergeable_file:
1824 1824 fn = "mf"
1825 1825 p1 = repo[ps[0]]
1826 1826 if len(ps) > 1:
1827 1827 p2 = repo[ps[1]]
1828 1828 pa = p1.ancestor(p2)
1829 1829 base, local, other = [x[fn].data() for x in (pa, p1,
1830 1830 p2)]
1831 1831 m3 = simplemerge.Merge3Text(base, local, other)
1832 1832 ml = [l.strip() for l in m3.merge_lines()]
1833 1833 ml.append("")
1834 1834 elif at > 0:
1835 1835 ml = p1[fn].data().split("\n")
1836 1836 else:
1837 1837 ml = initialmergedlines
1838 1838 ml[id * linesperrev] += " r%i" % id
1839 1839 mergedtext = "\n".join(ml)
1840 1840 files.append(fn)
1841 1841 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1842 1842
1843 1843 if overwritten_file:
1844 1844 fn = "of"
1845 1845 files.append(fn)
1846 1846 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1847 1847
1848 1848 if new_file:
1849 1849 fn = "nf%i" % id
1850 1850 files.append(fn)
1851 1851 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1852 1852 if len(ps) > 1:
1853 1853 if not p2:
1854 1854 p2 = repo[ps[1]]
1855 1855 for fn in p2:
1856 1856 if fn.startswith("nf"):
1857 1857 files.append(fn)
1858 1858 fctxs[fn] = p2[fn]
1859 1859
1860 1860 def fctxfn(repo, cx, path):
1861 1861 return fctxs.get(path)
1862 1862
1863 1863 if len(ps) == 0 or ps[0] < 0:
1864 1864 pars = [None, None]
1865 1865 elif len(ps) == 1:
1866 1866 pars = [nodeids[ps[0]], None]
1867 1867 else:
1868 1868 pars = [nodeids[p] for p in ps]
1869 1869 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1870 1870 date=(id, 0),
1871 1871 user="debugbuilddag",
1872 1872 extra={'branch': atbranch})
1873 1873 nodeid = repo.commitctx(cx)
1874 1874 nodeids.append(nodeid)
1875 1875 at = id
1876 1876 elif type == 'l':
1877 1877 id, name = data
1878 1878 ui.note(('tag %s\n' % name))
1879 1879 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1880 1880 elif type == 'a':
1881 1881 ui.note(('branch %s\n' % data))
1882 1882 atbranch = data
1883 1883 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1884 1884 tr.close()
1885 1885
1886 1886 if tags:
1887 1887 repo.vfs.write("localtags", "".join(tags))
1888 1888 finally:
1889 1889 ui.progress(_('building'), None)
1890 1890 release(tr, lock)
1891 1891
1892 1892 @command('debugbundle',
1893 1893 [('a', 'all', None, _('show all details'))],
1894 1894 _('FILE'),
1895 1895 norepo=True)
1896 1896 def debugbundle(ui, bundlepath, all=None, **opts):
1897 1897 """lists the contents of a bundle"""
1898 1898 f = hg.openpath(ui, bundlepath)
1899 1899 try:
1900 1900 gen = exchange.readbundle(ui, f, bundlepath)
1901 1901 if isinstance(gen, bundle2.unbundle20):
1902 1902 return _debugbundle2(ui, gen, all=all, **opts)
1903 1903 if all:
1904 1904 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1905 1905
1906 1906 def showchunks(named):
1907 1907 ui.write("\n%s\n" % named)
1908 1908 chain = None
1909 1909 while True:
1910 1910 chunkdata = gen.deltachunk(chain)
1911 1911 if not chunkdata:
1912 1912 break
1913 1913 node = chunkdata['node']
1914 1914 p1 = chunkdata['p1']
1915 1915 p2 = chunkdata['p2']
1916 1916 cs = chunkdata['cs']
1917 1917 deltabase = chunkdata['deltabase']
1918 1918 delta = chunkdata['delta']
1919 1919 ui.write("%s %s %s %s %s %s\n" %
1920 1920 (hex(node), hex(p1), hex(p2),
1921 1921 hex(cs), hex(deltabase), len(delta)))
1922 1922 chain = node
1923 1923
1924 1924 chunkdata = gen.changelogheader()
1925 1925 showchunks("changelog")
1926 1926 chunkdata = gen.manifestheader()
1927 1927 showchunks("manifest")
1928 1928 while True:
1929 1929 chunkdata = gen.filelogheader()
1930 1930 if not chunkdata:
1931 1931 break
1932 1932 fname = chunkdata['filename']
1933 1933 showchunks(fname)
1934 1934 else:
1935 1935 if isinstance(gen, bundle2.unbundle20):
1936 1936 raise error.Abort(_('use debugbundle2 for this file'))
1937 1937 chunkdata = gen.changelogheader()
1938 1938 chain = None
1939 1939 while True:
1940 1940 chunkdata = gen.deltachunk(chain)
1941 1941 if not chunkdata:
1942 1942 break
1943 1943 node = chunkdata['node']
1944 1944 ui.write("%s\n" % hex(node))
1945 1945 chain = node
1946 1946 finally:
1947 1947 f.close()
1948 1948
1949 1949 def _debugbundle2(ui, gen, **opts):
1950 1950 """lists the contents of a bundle2"""
1951 1951 if not isinstance(gen, bundle2.unbundle20):
1952 1952 raise error.Abort(_('not a bundle2 file'))
1953 1953 ui.write(('Stream params: %s\n' % repr(gen.params)))
1954 1954 for part in gen.iterparts():
1955 1955 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1956 1956 if part.type == 'changegroup':
1957 1957 version = part.params.get('version', '01')
1958 1958 cg = changegroup.packermap[version][1](part, 'UN')
1959 1959 chunkdata = cg.changelogheader()
1960 1960 chain = None
1961 1961 while True:
1962 1962 chunkdata = cg.deltachunk(chain)
1963 1963 if not chunkdata:
1964 1964 break
1965 1965 node = chunkdata['node']
1966 1966 ui.write(" %s\n" % hex(node))
1967 1967 chain = node
1968 1968
1969 1969 @command('debugcreatestreamclonebundle', [], 'FILE')
1970 1970 def debugcreatestreamclonebundle(ui, repo, fname):
1971 1971 """create a stream clone bundle file
1972 1972
1973 1973 Stream bundles are special bundles that are essentially archives of
1974 1974 revlog files. They are commonly used for cloning very quickly.
1975 1975 """
1976 1976 requirements, gen = streamclone.generatebundlev1(repo)
1977 1977 changegroup.writechunks(ui, gen, fname)
1978 1978
1979 1979 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
1980 1980
1981 @command('debugapplystreamclonebundle', [], 'FILE')
1982 def debugapplystreamclonebundle(ui, repo, fname):
1983 """apply a stream clone bundle file"""
1984 f = hg.openpath(ui, fname)
1985 gen = exchange.readbundle(ui, f, fname)
1986 gen.apply(repo)
1987
1981 1988 @command('debugcheckstate', [], '')
1982 1989 def debugcheckstate(ui, repo):
1983 1990 """validate the correctness of the current dirstate"""
1984 1991 parent1, parent2 = repo.dirstate.parents()
1985 1992 m1 = repo[parent1].manifest()
1986 1993 m2 = repo[parent2].manifest()
1987 1994 errors = 0
1988 1995 for f in repo.dirstate:
1989 1996 state = repo.dirstate[f]
1990 1997 if state in "nr" and f not in m1:
1991 1998 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1992 1999 errors += 1
1993 2000 if state in "a" and f in m1:
1994 2001 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1995 2002 errors += 1
1996 2003 if state in "m" and f not in m1 and f not in m2:
1997 2004 ui.warn(_("%s in state %s, but not in either manifest\n") %
1998 2005 (f, state))
1999 2006 errors += 1
2000 2007 for f in m1:
2001 2008 state = repo.dirstate[f]
2002 2009 if state not in "nrm":
2003 2010 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
2004 2011 errors += 1
2005 2012 if errors:
2006 2013 error = _(".hg/dirstate inconsistent with current parent's manifest")
2007 2014 raise error.Abort(error)
2008 2015
2009 2016 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
2010 2017 def debugcommands(ui, cmd='', *args):
2011 2018 """list all available commands and options"""
2012 2019 for cmd, vals in sorted(table.iteritems()):
2013 2020 cmd = cmd.split('|')[0].strip('^')
2014 2021 opts = ', '.join([i[1] for i in vals[1]])
2015 2022 ui.write('%s: %s\n' % (cmd, opts))
2016 2023
2017 2024 @command('debugcomplete',
2018 2025 [('o', 'options', None, _('show the command options'))],
2019 2026 _('[-o] CMD'),
2020 2027 norepo=True)
2021 2028 def debugcomplete(ui, cmd='', **opts):
2022 2029 """returns the completion list associated with the given command"""
2023 2030
2024 2031 if opts.get('options'):
2025 2032 options = []
2026 2033 otables = [globalopts]
2027 2034 if cmd:
2028 2035 aliases, entry = cmdutil.findcmd(cmd, table, False)
2029 2036 otables.append(entry[1])
2030 2037 for t in otables:
2031 2038 for o in t:
2032 2039 if "(DEPRECATED)" in o[3]:
2033 2040 continue
2034 2041 if o[0]:
2035 2042 options.append('-%s' % o[0])
2036 2043 options.append('--%s' % o[1])
2037 2044 ui.write("%s\n" % "\n".join(options))
2038 2045 return
2039 2046
2040 2047 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2041 2048 if ui.verbose:
2042 2049 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2043 2050 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2044 2051
2045 2052 @command('debugdag',
2046 2053 [('t', 'tags', None, _('use tags as labels')),
2047 2054 ('b', 'branches', None, _('annotate with branch names')),
2048 2055 ('', 'dots', None, _('use dots for runs')),
2049 2056 ('s', 'spaces', None, _('separate elements by spaces'))],
2050 2057 _('[OPTION]... [FILE [REV]...]'),
2051 2058 optionalrepo=True)
2052 2059 def debugdag(ui, repo, file_=None, *revs, **opts):
2053 2060 """format the changelog or an index DAG as a concise textual description
2054 2061
2055 2062 If you pass a revlog index, the revlog's DAG is emitted. If you list
2056 2063 revision numbers, they get labeled in the output as rN.
2057 2064
2058 2065 Otherwise, the changelog DAG of the current repo is emitted.
2059 2066 """
2060 2067 spaces = opts.get('spaces')
2061 2068 dots = opts.get('dots')
2062 2069 if file_:
2063 2070 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2064 2071 revs = set((int(r) for r in revs))
2065 2072 def events():
2066 2073 for r in rlog:
2067 2074 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2068 2075 if p != -1))
2069 2076 if r in revs:
2070 2077 yield 'l', (r, "r%i" % r)
2071 2078 elif repo:
2072 2079 cl = repo.changelog
2073 2080 tags = opts.get('tags')
2074 2081 branches = opts.get('branches')
2075 2082 if tags:
2076 2083 labels = {}
2077 2084 for l, n in repo.tags().items():
2078 2085 labels.setdefault(cl.rev(n), []).append(l)
2079 2086 def events():
2080 2087 b = "default"
2081 2088 for r in cl:
2082 2089 if branches:
2083 2090 newb = cl.read(cl.node(r))[5]['branch']
2084 2091 if newb != b:
2085 2092 yield 'a', newb
2086 2093 b = newb
2087 2094 yield 'n', (r, list(p for p in cl.parentrevs(r)
2088 2095 if p != -1))
2089 2096 if tags:
2090 2097 ls = labels.get(r)
2091 2098 if ls:
2092 2099 for l in ls:
2093 2100 yield 'l', (r, l)
2094 2101 else:
2095 2102 raise error.Abort(_('need repo for changelog dag'))
2096 2103
2097 2104 for line in dagparser.dagtextlines(events(),
2098 2105 addspaces=spaces,
2099 2106 wraplabels=True,
2100 2107 wrapannotations=True,
2101 2108 wrapnonlinear=dots,
2102 2109 usedots=dots,
2103 2110 maxlinewidth=70):
2104 2111 ui.write(line)
2105 2112 ui.write("\n")
2106 2113
2107 2114 @command('debugdata',
2108 2115 [('c', 'changelog', False, _('open changelog')),
2109 2116 ('m', 'manifest', False, _('open manifest')),
2110 2117 ('', 'dir', False, _('open directory manifest'))],
2111 2118 _('-c|-m|FILE REV'))
2112 2119 def debugdata(ui, repo, file_, rev=None, **opts):
2113 2120 """dump the contents of a data file revision"""
2114 2121 if opts.get('changelog') or opts.get('manifest'):
2115 2122 file_, rev = None, file_
2116 2123 elif rev is None:
2117 2124 raise error.CommandError('debugdata', _('invalid arguments'))
2118 2125 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2119 2126 try:
2120 2127 ui.write(r.revision(r.lookup(rev)))
2121 2128 except KeyError:
2122 2129 raise error.Abort(_('invalid revision identifier %s') % rev)
2123 2130
2124 2131 @command('debugdate',
2125 2132 [('e', 'extended', None, _('try extended date formats'))],
2126 2133 _('[-e] DATE [RANGE]'),
2127 2134 norepo=True, optionalrepo=True)
2128 2135 def debugdate(ui, date, range=None, **opts):
2129 2136 """parse and display a date"""
2130 2137 if opts["extended"]:
2131 2138 d = util.parsedate(date, util.extendeddateformats)
2132 2139 else:
2133 2140 d = util.parsedate(date)
2134 2141 ui.write(("internal: %s %s\n") % d)
2135 2142 ui.write(("standard: %s\n") % util.datestr(d))
2136 2143 if range:
2137 2144 m = util.matchdate(range)
2138 2145 ui.write(("match: %s\n") % m(d[0]))
2139 2146
2140 2147 @command('debugdiscovery',
2141 2148 [('', 'old', None, _('use old-style discovery')),
2142 2149 ('', 'nonheads', None,
2143 2150 _('use old-style discovery with non-heads included')),
2144 2151 ] + remoteopts,
2145 2152 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2146 2153 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2147 2154 """runs the changeset discovery protocol in isolation"""
2148 2155 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2149 2156 opts.get('branch'))
2150 2157 remote = hg.peer(repo, opts, remoteurl)
2151 2158 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2152 2159
2153 2160 # make sure tests are repeatable
2154 2161 random.seed(12323)
2155 2162
2156 2163 def doit(localheads, remoteheads, remote=remote):
2157 2164 if opts.get('old'):
2158 2165 if localheads:
2159 2166 raise error.Abort('cannot use localheads with old style '
2160 2167 'discovery')
2161 2168 if not util.safehasattr(remote, 'branches'):
2162 2169 # enable in-client legacy support
2163 2170 remote = localrepo.locallegacypeer(remote.local())
2164 2171 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2165 2172 force=True)
2166 2173 common = set(common)
2167 2174 if not opts.get('nonheads'):
2168 2175 ui.write(("unpruned common: %s\n") %
2169 2176 " ".join(sorted(short(n) for n in common)))
2170 2177 dag = dagutil.revlogdag(repo.changelog)
2171 2178 all = dag.ancestorset(dag.internalizeall(common))
2172 2179 common = dag.externalizeall(dag.headsetofconnecteds(all))
2173 2180 else:
2174 2181 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2175 2182 common = set(common)
2176 2183 rheads = set(hds)
2177 2184 lheads = set(repo.heads())
2178 2185 ui.write(("common heads: %s\n") %
2179 2186 " ".join(sorted(short(n) for n in common)))
2180 2187 if lheads <= common:
2181 2188 ui.write(("local is subset\n"))
2182 2189 elif rheads <= common:
2183 2190 ui.write(("remote is subset\n"))
2184 2191
2185 2192 serverlogs = opts.get('serverlog')
2186 2193 if serverlogs:
2187 2194 for filename in serverlogs:
2188 2195 logfile = open(filename, 'r')
2189 2196 try:
2190 2197 line = logfile.readline()
2191 2198 while line:
2192 2199 parts = line.strip().split(';')
2193 2200 op = parts[1]
2194 2201 if op == 'cg':
2195 2202 pass
2196 2203 elif op == 'cgss':
2197 2204 doit(parts[2].split(' '), parts[3].split(' '))
2198 2205 elif op == 'unb':
2199 2206 doit(parts[3].split(' '), parts[2].split(' '))
2200 2207 line = logfile.readline()
2201 2208 finally:
2202 2209 logfile.close()
2203 2210
2204 2211 else:
2205 2212 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2206 2213 opts.get('remote_head'))
2207 2214 localrevs = opts.get('local_head')
2208 2215 doit(localrevs, remoterevs)
2209 2216
2210 2217 @command('debugextensions', formatteropts, [], norepo=True)
2211 2218 def debugextensions(ui, **opts):
2212 2219 '''show information about active extensions'''
2213 2220 exts = extensions.extensions(ui)
2214 2221 fm = ui.formatter('debugextensions', opts)
2215 2222 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
2216 2223 extsource = extmod.__file__
2217 2224 exttestedwith = getattr(extmod, 'testedwith', None)
2218 2225 if exttestedwith is not None:
2219 2226 exttestedwith = exttestedwith.split()
2220 2227 extbuglink = getattr(extmod, 'buglink', None)
2221 2228
2222 2229 fm.startitem()
2223 2230
2224 2231 if ui.quiet or ui.verbose:
2225 2232 fm.write('name', '%s\n', extname)
2226 2233 else:
2227 2234 fm.write('name', '%s', extname)
2228 2235 if not exttestedwith:
2229 2236 fm.plain(_(' (untested!)\n'))
2230 2237 else:
2231 2238 if exttestedwith == ['internal'] or \
2232 2239 util.version() in exttestedwith:
2233 2240 fm.plain('\n')
2234 2241 else:
2235 2242 lasttestedversion = exttestedwith[-1]
2236 2243 fm.plain(' (%s!)\n' % lasttestedversion)
2237 2244
2238 2245 fm.condwrite(ui.verbose and extsource, 'source',
2239 2246 _(' location: %s\n'), extsource or "")
2240 2247
2241 2248 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
2242 2249 _(' tested with: %s\n'), ' '.join(exttestedwith or []))
2243 2250
2244 2251 fm.condwrite(ui.verbose and extbuglink, 'buglink',
2245 2252 _(' bug reporting: %s\n'), extbuglink or "")
2246 2253
2247 2254 fm.end()
2248 2255
2249 2256 @command('debugfileset',
2250 2257 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2251 2258 _('[-r REV] FILESPEC'))
2252 2259 def debugfileset(ui, repo, expr, **opts):
2253 2260 '''parse and apply a fileset specification'''
2254 2261 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2255 2262 if ui.verbose:
2256 2263 tree = fileset.parse(expr)
2257 2264 ui.note(fileset.prettyformat(tree), "\n")
2258 2265
2259 2266 for f in ctx.getfileset(expr):
2260 2267 ui.write("%s\n" % f)
2261 2268
2262 2269 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2263 2270 def debugfsinfo(ui, path="."):
2264 2271 """show information detected about current filesystem"""
2265 2272 util.writefile('.debugfsinfo', '')
2266 2273 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2267 2274 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2268 2275 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2269 2276 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2270 2277 and 'yes' or 'no'))
2271 2278 os.unlink('.debugfsinfo')
2272 2279
2273 2280 @command('debuggetbundle',
2274 2281 [('H', 'head', [], _('id of head node'), _('ID')),
2275 2282 ('C', 'common', [], _('id of common node'), _('ID')),
2276 2283 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2277 2284 _('REPO FILE [-H|-C ID]...'),
2278 2285 norepo=True)
2279 2286 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2280 2287 """retrieves a bundle from a repo
2281 2288
2282 2289 Every ID must be a full-length hex node id string. Saves the bundle to the
2283 2290 given file.
2284 2291 """
2285 2292 repo = hg.peer(ui, opts, repopath)
2286 2293 if not repo.capable('getbundle'):
2287 2294 raise error.Abort("getbundle() not supported by target repository")
2288 2295 args = {}
2289 2296 if common:
2290 2297 args['common'] = [bin(s) for s in common]
2291 2298 if head:
2292 2299 args['heads'] = [bin(s) for s in head]
2293 2300 # TODO: get desired bundlecaps from command line.
2294 2301 args['bundlecaps'] = None
2295 2302 bundle = repo.getbundle('debug', **args)
2296 2303
2297 2304 bundletype = opts.get('type', 'bzip2').lower()
2298 2305 btypes = {'none': 'HG10UN',
2299 2306 'bzip2': 'HG10BZ',
2300 2307 'gzip': 'HG10GZ',
2301 2308 'bundle2': 'HG20'}
2302 2309 bundletype = btypes.get(bundletype)
2303 2310 if bundletype not in changegroup.bundletypes:
2304 2311 raise error.Abort(_('unknown bundle type specified with --type'))
2305 2312 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2306 2313
2307 2314 @command('debugignore', [], '')
2308 2315 def debugignore(ui, repo, *values, **opts):
2309 2316 """display the combined ignore pattern"""
2310 2317 ignore = repo.dirstate._ignore
2311 2318 includepat = getattr(ignore, 'includepat', None)
2312 2319 if includepat is not None:
2313 2320 ui.write("%s\n" % includepat)
2314 2321 else:
2315 2322 raise error.Abort(_("no ignore patterns found"))
2316 2323
2317 2324 @command('debugindex',
2318 2325 [('c', 'changelog', False, _('open changelog')),
2319 2326 ('m', 'manifest', False, _('open manifest')),
2320 2327 ('', 'dir', False, _('open directory manifest')),
2321 2328 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2322 2329 _('[-f FORMAT] -c|-m|FILE'),
2323 2330 optionalrepo=True)
2324 2331 def debugindex(ui, repo, file_=None, **opts):
2325 2332 """dump the contents of an index file"""
2326 2333 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2327 2334 format = opts.get('format', 0)
2328 2335 if format not in (0, 1):
2329 2336 raise error.Abort(_("unknown format %d") % format)
2330 2337
2331 2338 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2332 2339 if generaldelta:
2333 2340 basehdr = ' delta'
2334 2341 else:
2335 2342 basehdr = ' base'
2336 2343
2337 2344 if ui.debugflag:
2338 2345 shortfn = hex
2339 2346 else:
2340 2347 shortfn = short
2341 2348
2342 2349 # There might not be anything in r, so have a sane default
2343 2350 idlen = 12
2344 2351 for i in r:
2345 2352 idlen = len(shortfn(r.node(i)))
2346 2353 break
2347 2354
2348 2355 if format == 0:
2349 2356 ui.write(" rev offset length " + basehdr + " linkrev"
2350 2357 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2351 2358 elif format == 1:
2352 2359 ui.write(" rev flag offset length"
2353 2360 " size " + basehdr + " link p1 p2"
2354 2361 " %s\n" % "nodeid".rjust(idlen))
2355 2362
2356 2363 for i in r:
2357 2364 node = r.node(i)
2358 2365 if generaldelta:
2359 2366 base = r.deltaparent(i)
2360 2367 else:
2361 2368 base = r.chainbase(i)
2362 2369 if format == 0:
2363 2370 try:
2364 2371 pp = r.parents(node)
2365 2372 except Exception:
2366 2373 pp = [nullid, nullid]
2367 2374 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2368 2375 i, r.start(i), r.length(i), base, r.linkrev(i),
2369 2376 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2370 2377 elif format == 1:
2371 2378 pr = r.parentrevs(i)
2372 2379 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2373 2380 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2374 2381 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2375 2382
2376 2383 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2377 2384 def debugindexdot(ui, repo, file_):
2378 2385 """dump an index DAG as a graphviz dot file"""
2379 2386 r = None
2380 2387 if repo:
2381 2388 filelog = repo.file(file_)
2382 2389 if len(filelog):
2383 2390 r = filelog
2384 2391 if not r:
2385 2392 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2386 2393 ui.write(("digraph G {\n"))
2387 2394 for i in r:
2388 2395 node = r.node(i)
2389 2396 pp = r.parents(node)
2390 2397 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2391 2398 if pp[1] != nullid:
2392 2399 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2393 2400 ui.write("}\n")
2394 2401
2395 2402 @command('debuginstall', [], '', norepo=True)
2396 2403 def debuginstall(ui):
2397 2404 '''test Mercurial installation
2398 2405
2399 2406 Returns 0 on success.
2400 2407 '''
2401 2408
2402 2409 def writetemp(contents):
2403 2410 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2404 2411 f = os.fdopen(fd, "wb")
2405 2412 f.write(contents)
2406 2413 f.close()
2407 2414 return name
2408 2415
2409 2416 problems = 0
2410 2417
2411 2418 # encoding
2412 2419 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2413 2420 try:
2414 2421 encoding.fromlocal("test")
2415 2422 except error.Abort as inst:
2416 2423 ui.write(" %s\n" % inst)
2417 2424 ui.write(_(" (check that your locale is properly set)\n"))
2418 2425 problems += 1
2419 2426
2420 2427 # Python
2421 2428 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2422 2429 ui.status(_("checking Python version (%s)\n")
2423 2430 % ("%s.%s.%s" % sys.version_info[:3]))
2424 2431 ui.status(_("checking Python lib (%s)...\n")
2425 2432 % os.path.dirname(os.__file__))
2426 2433
2427 2434 # compiled modules
2428 2435 ui.status(_("checking installed modules (%s)...\n")
2429 2436 % os.path.dirname(__file__))
2430 2437 try:
2431 2438 import bdiff, mpatch, base85, osutil
2432 2439 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2433 2440 except Exception as inst:
2434 2441 ui.write(" %s\n" % inst)
2435 2442 ui.write(_(" One or more extensions could not be found"))
2436 2443 ui.write(_(" (check that you compiled the extensions)\n"))
2437 2444 problems += 1
2438 2445
2439 2446 # templates
2440 2447 import templater
2441 2448 p = templater.templatepaths()
2442 2449 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2443 2450 if p:
2444 2451 m = templater.templatepath("map-cmdline.default")
2445 2452 if m:
2446 2453 # template found, check if it is working
2447 2454 try:
2448 2455 templater.templater(m)
2449 2456 except Exception as inst:
2450 2457 ui.write(" %s\n" % inst)
2451 2458 p = None
2452 2459 else:
2453 2460 ui.write(_(" template 'default' not found\n"))
2454 2461 p = None
2455 2462 else:
2456 2463 ui.write(_(" no template directories found\n"))
2457 2464 if not p:
2458 2465 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2459 2466 problems += 1
2460 2467
2461 2468 # editor
2462 2469 ui.status(_("checking commit editor...\n"))
2463 2470 editor = ui.geteditor()
2464 2471 editor = util.expandpath(editor)
2465 2472 cmdpath = util.findexe(shlex.split(editor)[0])
2466 2473 if not cmdpath:
2467 2474 if editor == 'vi':
2468 2475 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2469 2476 ui.write(_(" (specify a commit editor in your configuration"
2470 2477 " file)\n"))
2471 2478 else:
2472 2479 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2473 2480 ui.write(_(" (specify a commit editor in your configuration"
2474 2481 " file)\n"))
2475 2482 problems += 1
2476 2483
2477 2484 # check username
2478 2485 ui.status(_("checking username...\n"))
2479 2486 try:
2480 2487 ui.username()
2481 2488 except error.Abort as e:
2482 2489 ui.write(" %s\n" % e)
2483 2490 ui.write(_(" (specify a username in your configuration file)\n"))
2484 2491 problems += 1
2485 2492
2486 2493 if not problems:
2487 2494 ui.status(_("no problems detected\n"))
2488 2495 else:
2489 2496 ui.write(_("%s problems detected,"
2490 2497 " please check your install!\n") % problems)
2491 2498
2492 2499 return problems
2493 2500
2494 2501 @command('debugknown', [], _('REPO ID...'), norepo=True)
2495 2502 def debugknown(ui, repopath, *ids, **opts):
2496 2503 """test whether node ids are known to a repo
2497 2504
2498 2505 Every ID must be a full-length hex node id string. Returns a list of 0s
2499 2506 and 1s indicating unknown/known.
2500 2507 """
2501 2508 repo = hg.peer(ui, opts, repopath)
2502 2509 if not repo.capable('known'):
2503 2510 raise error.Abort("known() not supported by target repository")
2504 2511 flags = repo.known([bin(s) for s in ids])
2505 2512 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2506 2513
2507 2514 @command('debuglabelcomplete', [], _('LABEL...'))
2508 2515 def debuglabelcomplete(ui, repo, *args):
2509 2516 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2510 2517 debugnamecomplete(ui, repo, *args)
2511 2518
2512 2519 @command('debugmergestate', [], '')
2513 2520 def debugmergestate(ui, repo, *args):
2514 2521 """print merge state
2515 2522
2516 2523 Use --verbose to print out information about whether v1 or v2 merge state
2517 2524 was chosen."""
2518 2525 def printrecords(version):
2519 2526 ui.write(('* version %s records\n') % version)
2520 2527 if version == 1:
2521 2528 records = v1records
2522 2529 else:
2523 2530 records = v2records
2524 2531
2525 2532 for rtype, record in records:
2526 2533 # pretty print some record types
2527 2534 if rtype == 'L':
2528 2535 ui.write(('local: %s\n') % record)
2529 2536 elif rtype == 'O':
2530 2537 ui.write(('other: %s\n') % record)
2531 2538 elif rtype == 'm':
2532 2539 driver, mdstate = record.split('\0', 1)
2533 2540 ui.write(('merge driver: %s (state "%s")\n')
2534 2541 % (driver, mdstate))
2535 2542 elif rtype in 'FD':
2536 2543 r = record.split('\0')
2537 2544 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2538 2545 if version == 1:
2539 2546 onode = 'not stored in v1 format'
2540 2547 flags = r[7]
2541 2548 else:
2542 2549 onode, flags = r[7:9]
2543 2550 ui.write(('file: %s (state "%s", hash %s)\n')
2544 2551 % (f, state, hash))
2545 2552 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2546 2553 ui.write((' ancestor path: %s (node %s)\n') % (afile, anode))
2547 2554 ui.write((' other path: %s (node %s)\n') % (ofile, onode))
2548 2555 else:
2549 2556 ui.write(('unrecognized entry: %s\t%s\n')
2550 2557 % (rtype, record.replace('\0', '\t')))
2551 2558
2552 2559 ms = mergemod.mergestate(repo)
2553 2560
2554 2561 # sort so that reasonable information is on top
2555 2562 v1records = ms._readrecordsv1()
2556 2563 v2records = ms._readrecordsv2()
2557 2564 order = 'LOm'
2558 2565 def key(r):
2559 2566 idx = order.find(r[0])
2560 2567 if idx == -1:
2561 2568 return (1, r[1])
2562 2569 else:
2563 2570 return (0, idx)
2564 2571 v1records.sort(key=key)
2565 2572 v2records.sort(key=key)
2566 2573
2567 2574 if not v1records and not v2records:
2568 2575 ui.write(('no merge state found\n'))
2569 2576 elif not v2records:
2570 2577 ui.note(('no version 2 merge state\n'))
2571 2578 printrecords(1)
2572 2579 elif ms._v1v2match(v1records, v2records):
2573 2580 ui.note(('v1 and v2 states match: using v2\n'))
2574 2581 printrecords(2)
2575 2582 else:
2576 2583 ui.note(('v1 and v2 states mismatch: using v1\n'))
2577 2584 printrecords(1)
2578 2585 if ui.verbose:
2579 2586 printrecords(2)
2580 2587
2581 2588 @command('debugnamecomplete', [], _('NAME...'))
2582 2589 def debugnamecomplete(ui, repo, *args):
2583 2590 '''complete "names" - tags, open branch names, bookmark names'''
2584 2591
2585 2592 names = set()
2586 2593 # since we previously only listed open branches, we will handle that
2587 2594 # specially (after this for loop)
2588 2595 for name, ns in repo.names.iteritems():
2589 2596 if name != 'branches':
2590 2597 names.update(ns.listnames(repo))
2591 2598 names.update(tag for (tag, heads, tip, closed)
2592 2599 in repo.branchmap().iterbranches() if not closed)
2593 2600 completions = set()
2594 2601 if not args:
2595 2602 args = ['']
2596 2603 for a in args:
2597 2604 completions.update(n for n in names if n.startswith(a))
2598 2605 ui.write('\n'.join(sorted(completions)))
2599 2606 ui.write('\n')
2600 2607
2601 2608 @command('debuglocks',
2602 2609 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2603 2610 ('W', 'force-wlock', None,
2604 2611 _('free the working state lock (DANGEROUS)'))],
2605 2612 _('[OPTION]...'))
2606 2613 def debuglocks(ui, repo, **opts):
2607 2614 """show or modify state of locks
2608 2615
2609 2616 By default, this command will show which locks are held. This
2610 2617 includes the user and process holding the lock, the amount of time
2611 2618 the lock has been held, and the machine name where the process is
2612 2619 running if it's not local.
2613 2620
2614 2621 Locks protect the integrity of Mercurial's data, so should be
2615 2622 treated with care. System crashes or other interruptions may cause
2616 2623 locks to not be properly released, though Mercurial will usually
2617 2624 detect and remove such stale locks automatically.
2618 2625
2619 2626 However, detecting stale locks may not always be possible (for
2620 2627 instance, on a shared filesystem). Removing locks may also be
2621 2628 blocked by filesystem permissions.
2622 2629
2623 2630 Returns 0 if no locks are held.
2624 2631
2625 2632 """
2626 2633
2627 2634 if opts.get('force_lock'):
2628 2635 repo.svfs.unlink('lock')
2629 2636 if opts.get('force_wlock'):
2630 2637 repo.vfs.unlink('wlock')
2631 2638 if opts.get('force_lock') or opts.get('force_lock'):
2632 2639 return 0
2633 2640
2634 2641 now = time.time()
2635 2642 held = 0
2636 2643
2637 2644 def report(vfs, name, method):
2638 2645 # this causes stale locks to get reaped for more accurate reporting
2639 2646 try:
2640 2647 l = method(False)
2641 2648 except error.LockHeld:
2642 2649 l = None
2643 2650
2644 2651 if l:
2645 2652 l.release()
2646 2653 else:
2647 2654 try:
2648 2655 stat = vfs.lstat(name)
2649 2656 age = now - stat.st_mtime
2650 2657 user = util.username(stat.st_uid)
2651 2658 locker = vfs.readlock(name)
2652 2659 if ":" in locker:
2653 2660 host, pid = locker.split(':')
2654 2661 if host == socket.gethostname():
2655 2662 locker = 'user %s, process %s' % (user, pid)
2656 2663 else:
2657 2664 locker = 'user %s, process %s, host %s' \
2658 2665 % (user, pid, host)
2659 2666 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2660 2667 return 1
2661 2668 except OSError as e:
2662 2669 if e.errno != errno.ENOENT:
2663 2670 raise
2664 2671
2665 2672 ui.write("%-6s free\n" % (name + ":"))
2666 2673 return 0
2667 2674
2668 2675 held += report(repo.svfs, "lock", repo.lock)
2669 2676 held += report(repo.vfs, "wlock", repo.wlock)
2670 2677
2671 2678 return held
2672 2679
2673 2680 @command('debugobsolete',
2674 2681 [('', 'flags', 0, _('markers flag')),
2675 2682 ('', 'record-parents', False,
2676 2683 _('record parent information for the precursor')),
2677 2684 ('r', 'rev', [], _('display markers relevant to REV')),
2678 2685 ] + commitopts2,
2679 2686 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2680 2687 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2681 2688 """create arbitrary obsolete marker
2682 2689
2683 2690 With no arguments, displays the list of obsolescence markers."""
2684 2691
2685 2692 def parsenodeid(s):
2686 2693 try:
2687 2694 # We do not use revsingle/revrange functions here to accept
2688 2695 # arbitrary node identifiers, possibly not present in the
2689 2696 # local repository.
2690 2697 n = bin(s)
2691 2698 if len(n) != len(nullid):
2692 2699 raise TypeError()
2693 2700 return n
2694 2701 except TypeError:
2695 2702 raise error.Abort('changeset references must be full hexadecimal '
2696 2703 'node identifiers')
2697 2704
2698 2705 if precursor is not None:
2699 2706 if opts['rev']:
2700 2707 raise error.Abort('cannot select revision when creating marker')
2701 2708 metadata = {}
2702 2709 metadata['user'] = opts['user'] or ui.username()
2703 2710 succs = tuple(parsenodeid(succ) for succ in successors)
2704 2711 l = repo.lock()
2705 2712 try:
2706 2713 tr = repo.transaction('debugobsolete')
2707 2714 try:
2708 2715 date = opts.get('date')
2709 2716 if date:
2710 2717 date = util.parsedate(date)
2711 2718 else:
2712 2719 date = None
2713 2720 prec = parsenodeid(precursor)
2714 2721 parents = None
2715 2722 if opts['record_parents']:
2716 2723 if prec not in repo.unfiltered():
2717 2724 raise error.Abort('cannot used --record-parents on '
2718 2725 'unknown changesets')
2719 2726 parents = repo.unfiltered()[prec].parents()
2720 2727 parents = tuple(p.node() for p in parents)
2721 2728 repo.obsstore.create(tr, prec, succs, opts['flags'],
2722 2729 parents=parents, date=date,
2723 2730 metadata=metadata)
2724 2731 tr.close()
2725 2732 except ValueError as exc:
2726 2733 raise error.Abort(_('bad obsmarker input: %s') % exc)
2727 2734 finally:
2728 2735 tr.release()
2729 2736 finally:
2730 2737 l.release()
2731 2738 else:
2732 2739 if opts['rev']:
2733 2740 revs = scmutil.revrange(repo, opts['rev'])
2734 2741 nodes = [repo[r].node() for r in revs]
2735 2742 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2736 2743 markers.sort(key=lambda x: x._data)
2737 2744 else:
2738 2745 markers = obsolete.getmarkers(repo)
2739 2746
2740 2747 for m in markers:
2741 2748 cmdutil.showmarker(ui, m)
2742 2749
2743 2750 @command('debugpathcomplete',
2744 2751 [('f', 'full', None, _('complete an entire path')),
2745 2752 ('n', 'normal', None, _('show only normal files')),
2746 2753 ('a', 'added', None, _('show only added files')),
2747 2754 ('r', 'removed', None, _('show only removed files'))],
2748 2755 _('FILESPEC...'))
2749 2756 def debugpathcomplete(ui, repo, *specs, **opts):
2750 2757 '''complete part or all of a tracked path
2751 2758
2752 2759 This command supports shells that offer path name completion. It
2753 2760 currently completes only files already known to the dirstate.
2754 2761
2755 2762 Completion extends only to the next path segment unless
2756 2763 --full is specified, in which case entire paths are used.'''
2757 2764
2758 2765 def complete(path, acceptable):
2759 2766 dirstate = repo.dirstate
2760 2767 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2761 2768 rootdir = repo.root + os.sep
2762 2769 if spec != repo.root and not spec.startswith(rootdir):
2763 2770 return [], []
2764 2771 if os.path.isdir(spec):
2765 2772 spec += '/'
2766 2773 spec = spec[len(rootdir):]
2767 2774 fixpaths = os.sep != '/'
2768 2775 if fixpaths:
2769 2776 spec = spec.replace(os.sep, '/')
2770 2777 speclen = len(spec)
2771 2778 fullpaths = opts['full']
2772 2779 files, dirs = set(), set()
2773 2780 adddir, addfile = dirs.add, files.add
2774 2781 for f, st in dirstate.iteritems():
2775 2782 if f.startswith(spec) and st[0] in acceptable:
2776 2783 if fixpaths:
2777 2784 f = f.replace('/', os.sep)
2778 2785 if fullpaths:
2779 2786 addfile(f)
2780 2787 continue
2781 2788 s = f.find(os.sep, speclen)
2782 2789 if s >= 0:
2783 2790 adddir(f[:s])
2784 2791 else:
2785 2792 addfile(f)
2786 2793 return files, dirs
2787 2794
2788 2795 acceptable = ''
2789 2796 if opts['normal']:
2790 2797 acceptable += 'nm'
2791 2798 if opts['added']:
2792 2799 acceptable += 'a'
2793 2800 if opts['removed']:
2794 2801 acceptable += 'r'
2795 2802 cwd = repo.getcwd()
2796 2803 if not specs:
2797 2804 specs = ['.']
2798 2805
2799 2806 files, dirs = set(), set()
2800 2807 for spec in specs:
2801 2808 f, d = complete(spec, acceptable or 'nmar')
2802 2809 files.update(f)
2803 2810 dirs.update(d)
2804 2811 files.update(dirs)
2805 2812 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2806 2813 ui.write('\n')
2807 2814
2808 2815 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2809 2816 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2810 2817 '''access the pushkey key/value protocol
2811 2818
2812 2819 With two args, list the keys in the given namespace.
2813 2820
2814 2821 With five args, set a key to new if it currently is set to old.
2815 2822 Reports success or failure.
2816 2823 '''
2817 2824
2818 2825 target = hg.peer(ui, {}, repopath)
2819 2826 if keyinfo:
2820 2827 key, old, new = keyinfo
2821 2828 r = target.pushkey(namespace, key, old, new)
2822 2829 ui.status(str(r) + '\n')
2823 2830 return not r
2824 2831 else:
2825 2832 for k, v in sorted(target.listkeys(namespace).iteritems()):
2826 2833 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2827 2834 v.encode('string-escape')))
2828 2835
2829 2836 @command('debugpvec', [], _('A B'))
2830 2837 def debugpvec(ui, repo, a, b=None):
2831 2838 ca = scmutil.revsingle(repo, a)
2832 2839 cb = scmutil.revsingle(repo, b)
2833 2840 pa = pvec.ctxpvec(ca)
2834 2841 pb = pvec.ctxpvec(cb)
2835 2842 if pa == pb:
2836 2843 rel = "="
2837 2844 elif pa > pb:
2838 2845 rel = ">"
2839 2846 elif pa < pb:
2840 2847 rel = "<"
2841 2848 elif pa | pb:
2842 2849 rel = "|"
2843 2850 ui.write(_("a: %s\n") % pa)
2844 2851 ui.write(_("b: %s\n") % pb)
2845 2852 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2846 2853 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2847 2854 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2848 2855 pa.distance(pb), rel))
2849 2856
2850 2857 @command('debugrebuilddirstate|debugrebuildstate',
2851 2858 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
2852 2859 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
2853 2860 'the working copy parent')),
2854 2861 ],
2855 2862 _('[-r REV]'))
2856 2863 def debugrebuilddirstate(ui, repo, rev, **opts):
2857 2864 """rebuild the dirstate as it would look like for the given revision
2858 2865
2859 2866 If no revision is specified the first current parent will be used.
2860 2867
2861 2868 The dirstate will be set to the files of the given revision.
2862 2869 The actual working directory content or existing dirstate
2863 2870 information such as adds or removes is not considered.
2864 2871
2865 2872 ``minimal`` will only rebuild the dirstate status for files that claim to be
2866 2873 tracked but are not in the parent manifest, or that exist in the parent
2867 2874 manifest but are not in the dirstate. It will not change adds, removes, or
2868 2875 modified files that are in the working copy parent.
2869 2876
2870 2877 One use of this command is to make the next :hg:`status` invocation
2871 2878 check the actual file content.
2872 2879 """
2873 2880 ctx = scmutil.revsingle(repo, rev)
2874 2881 wlock = repo.wlock()
2875 2882 try:
2876 2883 dirstate = repo.dirstate
2877 2884
2878 2885 # See command doc for what minimal does.
2879 2886 if opts.get('minimal'):
2880 2887 dirstatefiles = set(dirstate)
2881 2888 ctxfiles = set(ctx.manifest().keys())
2882 2889 for file in (dirstatefiles | ctxfiles):
2883 2890 indirstate = file in dirstatefiles
2884 2891 inctx = file in ctxfiles
2885 2892
2886 2893 if indirstate and not inctx and dirstate[file] != 'a':
2887 2894 dirstate.drop(file)
2888 2895 elif inctx and not indirstate:
2889 2896 dirstate.normallookup(file)
2890 2897 else:
2891 2898 dirstate.rebuild(ctx.node(), ctx.manifest())
2892 2899 finally:
2893 2900 wlock.release()
2894 2901
2895 2902 @command('debugrebuildfncache', [], '')
2896 2903 def debugrebuildfncache(ui, repo):
2897 2904 """rebuild the fncache file"""
2898 2905 repair.rebuildfncache(ui, repo)
2899 2906
2900 2907 @command('debugrename',
2901 2908 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2902 2909 _('[-r REV] FILE'))
2903 2910 def debugrename(ui, repo, file1, *pats, **opts):
2904 2911 """dump rename information"""
2905 2912
2906 2913 ctx = scmutil.revsingle(repo, opts.get('rev'))
2907 2914 m = scmutil.match(ctx, (file1,) + pats, opts)
2908 2915 for abs in ctx.walk(m):
2909 2916 fctx = ctx[abs]
2910 2917 o = fctx.filelog().renamed(fctx.filenode())
2911 2918 rel = m.rel(abs)
2912 2919 if o:
2913 2920 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2914 2921 else:
2915 2922 ui.write(_("%s not renamed\n") % rel)
2916 2923
2917 2924 @command('debugrevlog',
2918 2925 [('c', 'changelog', False, _('open changelog')),
2919 2926 ('m', 'manifest', False, _('open manifest')),
2920 2927 ('', 'dir', False, _('open directory manifest')),
2921 2928 ('d', 'dump', False, _('dump index data'))],
2922 2929 _('-c|-m|FILE'),
2923 2930 optionalrepo=True)
2924 2931 def debugrevlog(ui, repo, file_=None, **opts):
2925 2932 """show data and statistics about a revlog"""
2926 2933 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2927 2934
2928 2935 if opts.get("dump"):
2929 2936 numrevs = len(r)
2930 2937 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2931 2938 " rawsize totalsize compression heads chainlen\n")
2932 2939 ts = 0
2933 2940 heads = set()
2934 2941
2935 2942 for rev in xrange(numrevs):
2936 2943 dbase = r.deltaparent(rev)
2937 2944 if dbase == -1:
2938 2945 dbase = rev
2939 2946 cbase = r.chainbase(rev)
2940 2947 clen = r.chainlen(rev)
2941 2948 p1, p2 = r.parentrevs(rev)
2942 2949 rs = r.rawsize(rev)
2943 2950 ts = ts + rs
2944 2951 heads -= set(r.parentrevs(rev))
2945 2952 heads.add(rev)
2946 2953 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2947 2954 "%11d %5d %8d\n" %
2948 2955 (rev, p1, p2, r.start(rev), r.end(rev),
2949 2956 r.start(dbase), r.start(cbase),
2950 2957 r.start(p1), r.start(p2),
2951 2958 rs, ts, ts / r.end(rev), len(heads), clen))
2952 2959 return 0
2953 2960
2954 2961 v = r.version
2955 2962 format = v & 0xFFFF
2956 2963 flags = []
2957 2964 gdelta = False
2958 2965 if v & revlog.REVLOGNGINLINEDATA:
2959 2966 flags.append('inline')
2960 2967 if v & revlog.REVLOGGENERALDELTA:
2961 2968 gdelta = True
2962 2969 flags.append('generaldelta')
2963 2970 if not flags:
2964 2971 flags = ['(none)']
2965 2972
2966 2973 nummerges = 0
2967 2974 numfull = 0
2968 2975 numprev = 0
2969 2976 nump1 = 0
2970 2977 nump2 = 0
2971 2978 numother = 0
2972 2979 nump1prev = 0
2973 2980 nump2prev = 0
2974 2981 chainlengths = []
2975 2982
2976 2983 datasize = [None, 0, 0L]
2977 2984 fullsize = [None, 0, 0L]
2978 2985 deltasize = [None, 0, 0L]
2979 2986
2980 2987 def addsize(size, l):
2981 2988 if l[0] is None or size < l[0]:
2982 2989 l[0] = size
2983 2990 if size > l[1]:
2984 2991 l[1] = size
2985 2992 l[2] += size
2986 2993
2987 2994 numrevs = len(r)
2988 2995 for rev in xrange(numrevs):
2989 2996 p1, p2 = r.parentrevs(rev)
2990 2997 delta = r.deltaparent(rev)
2991 2998 if format > 0:
2992 2999 addsize(r.rawsize(rev), datasize)
2993 3000 if p2 != nullrev:
2994 3001 nummerges += 1
2995 3002 size = r.length(rev)
2996 3003 if delta == nullrev:
2997 3004 chainlengths.append(0)
2998 3005 numfull += 1
2999 3006 addsize(size, fullsize)
3000 3007 else:
3001 3008 chainlengths.append(chainlengths[delta] + 1)
3002 3009 addsize(size, deltasize)
3003 3010 if delta == rev - 1:
3004 3011 numprev += 1
3005 3012 if delta == p1:
3006 3013 nump1prev += 1
3007 3014 elif delta == p2:
3008 3015 nump2prev += 1
3009 3016 elif delta == p1:
3010 3017 nump1 += 1
3011 3018 elif delta == p2:
3012 3019 nump2 += 1
3013 3020 elif delta != nullrev:
3014 3021 numother += 1
3015 3022
3016 3023 # Adjust size min value for empty cases
3017 3024 for size in (datasize, fullsize, deltasize):
3018 3025 if size[0] is None:
3019 3026 size[0] = 0
3020 3027
3021 3028 numdeltas = numrevs - numfull
3022 3029 numoprev = numprev - nump1prev - nump2prev
3023 3030 totalrawsize = datasize[2]
3024 3031 datasize[2] /= numrevs
3025 3032 fulltotal = fullsize[2]
3026 3033 fullsize[2] /= numfull
3027 3034 deltatotal = deltasize[2]
3028 3035 if numrevs - numfull > 0:
3029 3036 deltasize[2] /= numrevs - numfull
3030 3037 totalsize = fulltotal + deltatotal
3031 3038 avgchainlen = sum(chainlengths) / numrevs
3032 3039 maxchainlen = max(chainlengths)
3033 3040 compratio = totalrawsize / totalsize
3034 3041
3035 3042 basedfmtstr = '%%%dd\n'
3036 3043 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
3037 3044
3038 3045 def dfmtstr(max):
3039 3046 return basedfmtstr % len(str(max))
3040 3047 def pcfmtstr(max, padding=0):
3041 3048 return basepcfmtstr % (len(str(max)), ' ' * padding)
3042 3049
3043 3050 def pcfmt(value, total):
3044 3051 return (value, 100 * float(value) / total)
3045 3052
3046 3053 ui.write(('format : %d\n') % format)
3047 3054 ui.write(('flags : %s\n') % ', '.join(flags))
3048 3055
3049 3056 ui.write('\n')
3050 3057 fmt = pcfmtstr(totalsize)
3051 3058 fmt2 = dfmtstr(totalsize)
3052 3059 ui.write(('revisions : ') + fmt2 % numrevs)
3053 3060 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
3054 3061 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
3055 3062 ui.write(('revisions : ') + fmt2 % numrevs)
3056 3063 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
3057 3064 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
3058 3065 ui.write(('revision size : ') + fmt2 % totalsize)
3059 3066 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
3060 3067 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
3061 3068
3062 3069 ui.write('\n')
3063 3070 fmt = dfmtstr(max(avgchainlen, compratio))
3064 3071 ui.write(('avg chain length : ') + fmt % avgchainlen)
3065 3072 ui.write(('max chain length : ') + fmt % maxchainlen)
3066 3073 ui.write(('compression ratio : ') + fmt % compratio)
3067 3074
3068 3075 if format > 0:
3069 3076 ui.write('\n')
3070 3077 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
3071 3078 % tuple(datasize))
3072 3079 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
3073 3080 % tuple(fullsize))
3074 3081 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
3075 3082 % tuple(deltasize))
3076 3083
3077 3084 if numdeltas > 0:
3078 3085 ui.write('\n')
3079 3086 fmt = pcfmtstr(numdeltas)
3080 3087 fmt2 = pcfmtstr(numdeltas, 4)
3081 3088 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
3082 3089 if numprev > 0:
3083 3090 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
3084 3091 numprev))
3085 3092 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
3086 3093 numprev))
3087 3094 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
3088 3095 numprev))
3089 3096 if gdelta:
3090 3097 ui.write(('deltas against p1 : ')
3091 3098 + fmt % pcfmt(nump1, numdeltas))
3092 3099 ui.write(('deltas against p2 : ')
3093 3100 + fmt % pcfmt(nump2, numdeltas))
3094 3101 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
3095 3102 numdeltas))
3096 3103
3097 3104 @command('debugrevspec',
3098 3105 [('', 'optimize', None, _('print parsed tree after optimizing'))],
3099 3106 ('REVSPEC'))
3100 3107 def debugrevspec(ui, repo, expr, **opts):
3101 3108 """parse and apply a revision specification
3102 3109
3103 3110 Use --verbose to print the parsed tree before and after aliases
3104 3111 expansion.
3105 3112 """
3106 3113 if ui.verbose:
3107 3114 tree = revset.parse(expr, lookup=repo.__contains__)
3108 3115 ui.note(revset.prettyformat(tree), "\n")
3109 3116 newtree = revset.findaliases(ui, tree)
3110 3117 if newtree != tree:
3111 3118 ui.note(revset.prettyformat(newtree), "\n")
3112 3119 tree = newtree
3113 3120 newtree = revset.foldconcat(tree)
3114 3121 if newtree != tree:
3115 3122 ui.note(revset.prettyformat(newtree), "\n")
3116 3123 if opts["optimize"]:
3117 3124 weight, optimizedtree = revset.optimize(newtree, True)
3118 3125 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
3119 3126 func = revset.match(ui, expr, repo)
3120 3127 revs = func(repo)
3121 3128 if ui.verbose:
3122 3129 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
3123 3130 for c in revs:
3124 3131 ui.write("%s\n" % c)
3125 3132
3126 3133 @command('debugsetparents', [], _('REV1 [REV2]'))
3127 3134 def debugsetparents(ui, repo, rev1, rev2=None):
3128 3135 """manually set the parents of the current working directory
3129 3136
3130 3137 This is useful for writing repository conversion tools, but should
3131 3138 be used with care. For example, neither the working directory nor the
3132 3139 dirstate is updated, so file status may be incorrect after running this
3133 3140 command.
3134 3141
3135 3142 Returns 0 on success.
3136 3143 """
3137 3144
3138 3145 r1 = scmutil.revsingle(repo, rev1).node()
3139 3146 r2 = scmutil.revsingle(repo, rev2, 'null').node()
3140 3147
3141 3148 wlock = repo.wlock()
3142 3149 try:
3143 3150 repo.dirstate.beginparentchange()
3144 3151 repo.setparents(r1, r2)
3145 3152 repo.dirstate.endparentchange()
3146 3153 finally:
3147 3154 wlock.release()
3148 3155
3149 3156 @command('debugdirstate|debugstate',
3150 3157 [('', 'nodates', None, _('do not display the saved mtime')),
3151 3158 ('', 'datesort', None, _('sort by saved mtime'))],
3152 3159 _('[OPTION]...'))
3153 3160 def debugstate(ui, repo, nodates=None, datesort=None):
3154 3161 """show the contents of the current dirstate"""
3155 3162 timestr = ""
3156 3163 if datesort:
3157 3164 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
3158 3165 else:
3159 3166 keyfunc = None # sort by filename
3160 3167 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
3161 3168 if ent[3] == -1:
3162 3169 timestr = 'unset '
3163 3170 elif nodates:
3164 3171 timestr = 'set '
3165 3172 else:
3166 3173 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
3167 3174 time.localtime(ent[3]))
3168 3175 if ent[1] & 0o20000:
3169 3176 mode = 'lnk'
3170 3177 else:
3171 3178 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3172 3179 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3173 3180 for f in repo.dirstate.copies():
3174 3181 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3175 3182
3176 3183 @command('debugsub',
3177 3184 [('r', 'rev', '',
3178 3185 _('revision to check'), _('REV'))],
3179 3186 _('[-r REV] [REV]'))
3180 3187 def debugsub(ui, repo, rev=None):
3181 3188 ctx = scmutil.revsingle(repo, rev, None)
3182 3189 for k, v in sorted(ctx.substate.items()):
3183 3190 ui.write(('path %s\n') % k)
3184 3191 ui.write((' source %s\n') % v[0])
3185 3192 ui.write((' revision %s\n') % v[1])
3186 3193
3187 3194 @command('debugsuccessorssets',
3188 3195 [],
3189 3196 _('[REV]'))
3190 3197 def debugsuccessorssets(ui, repo, *revs):
3191 3198 """show set of successors for revision
3192 3199
3193 3200 A successors set of changeset A is a consistent group of revisions that
3194 3201 succeed A. It contains non-obsolete changesets only.
3195 3202
3196 3203 In most cases a changeset A has a single successors set containing a single
3197 3204 successor (changeset A replaced by A').
3198 3205
3199 3206 A changeset that is made obsolete with no successors are called "pruned".
3200 3207 Such changesets have no successors sets at all.
3201 3208
3202 3209 A changeset that has been "split" will have a successors set containing
3203 3210 more than one successor.
3204 3211
3205 3212 A changeset that has been rewritten in multiple different ways is called
3206 3213 "divergent". Such changesets have multiple successor sets (each of which
3207 3214 may also be split, i.e. have multiple successors).
3208 3215
3209 3216 Results are displayed as follows::
3210 3217
3211 3218 <rev1>
3212 3219 <successors-1A>
3213 3220 <rev2>
3214 3221 <successors-2A>
3215 3222 <successors-2B1> <successors-2B2> <successors-2B3>
3216 3223
3217 3224 Here rev2 has two possible (i.e. divergent) successors sets. The first
3218 3225 holds one element, whereas the second holds three (i.e. the changeset has
3219 3226 been split).
3220 3227 """
3221 3228 # passed to successorssets caching computation from one call to another
3222 3229 cache = {}
3223 3230 ctx2str = str
3224 3231 node2str = short
3225 3232 if ui.debug():
3226 3233 def ctx2str(ctx):
3227 3234 return ctx.hex()
3228 3235 node2str = hex
3229 3236 for rev in scmutil.revrange(repo, revs):
3230 3237 ctx = repo[rev]
3231 3238 ui.write('%s\n'% ctx2str(ctx))
3232 3239 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3233 3240 if succsset:
3234 3241 ui.write(' ')
3235 3242 ui.write(node2str(succsset[0]))
3236 3243 for node in succsset[1:]:
3237 3244 ui.write(' ')
3238 3245 ui.write(node2str(node))
3239 3246 ui.write('\n')
3240 3247
3241 3248 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3242 3249 def debugwalk(ui, repo, *pats, **opts):
3243 3250 """show how files match on given patterns"""
3244 3251 m = scmutil.match(repo[None], pats, opts)
3245 3252 items = list(repo.walk(m))
3246 3253 if not items:
3247 3254 return
3248 3255 f = lambda fn: fn
3249 3256 if ui.configbool('ui', 'slash') and os.sep != '/':
3250 3257 f = lambda fn: util.normpath(fn)
3251 3258 fmt = 'f %%-%ds %%-%ds %%s' % (
3252 3259 max([len(abs) for abs in items]),
3253 3260 max([len(m.rel(abs)) for abs in items]))
3254 3261 for abs in items:
3255 3262 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3256 3263 ui.write("%s\n" % line.rstrip())
3257 3264
3258 3265 @command('debugwireargs',
3259 3266 [('', 'three', '', 'three'),
3260 3267 ('', 'four', '', 'four'),
3261 3268 ('', 'five', '', 'five'),
3262 3269 ] + remoteopts,
3263 3270 _('REPO [OPTIONS]... [ONE [TWO]]'),
3264 3271 norepo=True)
3265 3272 def debugwireargs(ui, repopath, *vals, **opts):
3266 3273 repo = hg.peer(ui, opts, repopath)
3267 3274 for opt in remoteopts:
3268 3275 del opts[opt[1]]
3269 3276 args = {}
3270 3277 for k, v in opts.iteritems():
3271 3278 if v:
3272 3279 args[k] = v
3273 3280 # run twice to check that we don't mess up the stream for the next command
3274 3281 res1 = repo.debugwireargs(*vals, **args)
3275 3282 res2 = repo.debugwireargs(*vals, **args)
3276 3283 ui.write("%s\n" % res1)
3277 3284 if res1 != res2:
3278 3285 ui.warn("%s\n" % res2)
3279 3286
3280 3287 @command('^diff',
3281 3288 [('r', 'rev', [], _('revision'), _('REV')),
3282 3289 ('c', 'change', '', _('change made by revision'), _('REV'))
3283 3290 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3284 3291 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3285 3292 inferrepo=True)
3286 3293 def diff(ui, repo, *pats, **opts):
3287 3294 """diff repository (or selected files)
3288 3295
3289 3296 Show differences between revisions for the specified files.
3290 3297
3291 3298 Differences between files are shown using the unified diff format.
3292 3299
3293 3300 .. note::
3294 3301
3295 3302 diff may generate unexpected results for merges, as it will
3296 3303 default to comparing against the working directory's first
3297 3304 parent changeset if no revisions are specified.
3298 3305
3299 3306 When two revision arguments are given, then changes are shown
3300 3307 between those revisions. If only one revision is specified then
3301 3308 that revision is compared to the working directory, and, when no
3302 3309 revisions are specified, the working directory files are compared
3303 3310 to its parent.
3304 3311
3305 3312 Alternatively you can specify -c/--change with a revision to see
3306 3313 the changes in that changeset relative to its first parent.
3307 3314
3308 3315 Without the -a/--text option, diff will avoid generating diffs of
3309 3316 files it detects as binary. With -a, diff will generate a diff
3310 3317 anyway, probably with undesirable results.
3311 3318
3312 3319 Use the -g/--git option to generate diffs in the git extended diff
3313 3320 format. For more information, read :hg:`help diffs`.
3314 3321
3315 3322 .. container:: verbose
3316 3323
3317 3324 Examples:
3318 3325
3319 3326 - compare a file in the current working directory to its parent::
3320 3327
3321 3328 hg diff foo.c
3322 3329
3323 3330 - compare two historical versions of a directory, with rename info::
3324 3331
3325 3332 hg diff --git -r 1.0:1.2 lib/
3326 3333
3327 3334 - get change stats relative to the last change on some date::
3328 3335
3329 3336 hg diff --stat -r "date('may 2')"
3330 3337
3331 3338 - diff all newly-added files that contain a keyword::
3332 3339
3333 3340 hg diff "set:added() and grep(GNU)"
3334 3341
3335 3342 - compare a revision and its parents::
3336 3343
3337 3344 hg diff -c 9353 # compare against first parent
3338 3345 hg diff -r 9353^:9353 # same using revset syntax
3339 3346 hg diff -r 9353^2:9353 # compare against the second parent
3340 3347
3341 3348 Returns 0 on success.
3342 3349 """
3343 3350
3344 3351 revs = opts.get('rev')
3345 3352 change = opts.get('change')
3346 3353 stat = opts.get('stat')
3347 3354 reverse = opts.get('reverse')
3348 3355
3349 3356 if revs and change:
3350 3357 msg = _('cannot specify --rev and --change at the same time')
3351 3358 raise error.Abort(msg)
3352 3359 elif change:
3353 3360 node2 = scmutil.revsingle(repo, change, None).node()
3354 3361 node1 = repo[node2].p1().node()
3355 3362 else:
3356 3363 node1, node2 = scmutil.revpair(repo, revs)
3357 3364
3358 3365 if reverse:
3359 3366 node1, node2 = node2, node1
3360 3367
3361 3368 diffopts = patch.diffallopts(ui, opts)
3362 3369 m = scmutil.match(repo[node2], pats, opts)
3363 3370 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3364 3371 listsubrepos=opts.get('subrepos'),
3365 3372 root=opts.get('root'))
3366 3373
3367 3374 @command('^export',
3368 3375 [('o', 'output', '',
3369 3376 _('print output to file with formatted name'), _('FORMAT')),
3370 3377 ('', 'switch-parent', None, _('diff against the second parent')),
3371 3378 ('r', 'rev', [], _('revisions to export'), _('REV')),
3372 3379 ] + diffopts,
3373 3380 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3374 3381 def export(ui, repo, *changesets, **opts):
3375 3382 """dump the header and diffs for one or more changesets
3376 3383
3377 3384 Print the changeset header and diffs for one or more revisions.
3378 3385 If no revision is given, the parent of the working directory is used.
3379 3386
3380 3387 The information shown in the changeset header is: author, date,
3381 3388 branch name (if non-default), changeset hash, parent(s) and commit
3382 3389 comment.
3383 3390
3384 3391 .. note::
3385 3392
3386 3393 export may generate unexpected diff output for merge
3387 3394 changesets, as it will compare the merge changeset against its
3388 3395 first parent only.
3389 3396
3390 3397 Output may be to a file, in which case the name of the file is
3391 3398 given using a format string. The formatting rules are as follows:
3392 3399
3393 3400 :``%%``: literal "%" character
3394 3401 :``%H``: changeset hash (40 hexadecimal digits)
3395 3402 :``%N``: number of patches being generated
3396 3403 :``%R``: changeset revision number
3397 3404 :``%b``: basename of the exporting repository
3398 3405 :``%h``: short-form changeset hash (12 hexadecimal digits)
3399 3406 :``%m``: first line of the commit message (only alphanumeric characters)
3400 3407 :``%n``: zero-padded sequence number, starting at 1
3401 3408 :``%r``: zero-padded changeset revision number
3402 3409
3403 3410 Without the -a/--text option, export will avoid generating diffs
3404 3411 of files it detects as binary. With -a, export will generate a
3405 3412 diff anyway, probably with undesirable results.
3406 3413
3407 3414 Use the -g/--git option to generate diffs in the git extended diff
3408 3415 format. See :hg:`help diffs` for more information.
3409 3416
3410 3417 With the --switch-parent option, the diff will be against the
3411 3418 second parent. It can be useful to review a merge.
3412 3419
3413 3420 .. container:: verbose
3414 3421
3415 3422 Examples:
3416 3423
3417 3424 - use export and import to transplant a bugfix to the current
3418 3425 branch::
3419 3426
3420 3427 hg export -r 9353 | hg import -
3421 3428
3422 3429 - export all the changesets between two revisions to a file with
3423 3430 rename information::
3424 3431
3425 3432 hg export --git -r 123:150 > changes.txt
3426 3433
3427 3434 - split outgoing changes into a series of patches with
3428 3435 descriptive names::
3429 3436
3430 3437 hg export -r "outgoing()" -o "%n-%m.patch"
3431 3438
3432 3439 Returns 0 on success.
3433 3440 """
3434 3441 changesets += tuple(opts.get('rev', []))
3435 3442 if not changesets:
3436 3443 changesets = ['.']
3437 3444 revs = scmutil.revrange(repo, changesets)
3438 3445 if not revs:
3439 3446 raise error.Abort(_("export requires at least one changeset"))
3440 3447 if len(revs) > 1:
3441 3448 ui.note(_('exporting patches:\n'))
3442 3449 else:
3443 3450 ui.note(_('exporting patch:\n'))
3444 3451 cmdutil.export(repo, revs, template=opts.get('output'),
3445 3452 switch_parent=opts.get('switch_parent'),
3446 3453 opts=patch.diffallopts(ui, opts))
3447 3454
3448 3455 @command('files',
3449 3456 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3450 3457 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3451 3458 ] + walkopts + formatteropts + subrepoopts,
3452 3459 _('[OPTION]... [PATTERN]...'))
3453 3460 def files(ui, repo, *pats, **opts):
3454 3461 """list tracked files
3455 3462
3456 3463 Print files under Mercurial control in the working directory or
3457 3464 specified revision whose names match the given patterns (excluding
3458 3465 removed files).
3459 3466
3460 3467 If no patterns are given to match, this command prints the names
3461 3468 of all files under Mercurial control in the working directory.
3462 3469
3463 3470 .. container:: verbose
3464 3471
3465 3472 Examples:
3466 3473
3467 3474 - list all files under the current directory::
3468 3475
3469 3476 hg files .
3470 3477
3471 3478 - shows sizes and flags for current revision::
3472 3479
3473 3480 hg files -vr .
3474 3481
3475 3482 - list all files named README::
3476 3483
3477 3484 hg files -I "**/README"
3478 3485
3479 3486 - list all binary files::
3480 3487
3481 3488 hg files "set:binary()"
3482 3489
3483 3490 - find files containing a regular expression::
3484 3491
3485 3492 hg files "set:grep('bob')"
3486 3493
3487 3494 - search tracked file contents with xargs and grep::
3488 3495
3489 3496 hg files -0 | xargs -0 grep foo
3490 3497
3491 3498 See :hg:`help patterns` and :hg:`help filesets` for more information
3492 3499 on specifying file patterns.
3493 3500
3494 3501 Returns 0 if a match is found, 1 otherwise.
3495 3502
3496 3503 """
3497 3504 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3498 3505
3499 3506 end = '\n'
3500 3507 if opts.get('print0'):
3501 3508 end = '\0'
3502 3509 fm = ui.formatter('files', opts)
3503 3510 fmt = '%s' + end
3504 3511
3505 3512 m = scmutil.match(ctx, pats, opts)
3506 3513 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3507 3514
3508 3515 fm.end()
3509 3516
3510 3517 return ret
3511 3518
3512 3519 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3513 3520 def forget(ui, repo, *pats, **opts):
3514 3521 """forget the specified files on the next commit
3515 3522
3516 3523 Mark the specified files so they will no longer be tracked
3517 3524 after the next commit.
3518 3525
3519 3526 This only removes files from the current branch, not from the
3520 3527 entire project history, and it does not delete them from the
3521 3528 working directory.
3522 3529
3523 3530 To delete the file from the working directory, see :hg:`remove`.
3524 3531
3525 3532 To undo a forget before the next commit, see :hg:`add`.
3526 3533
3527 3534 .. container:: verbose
3528 3535
3529 3536 Examples:
3530 3537
3531 3538 - forget newly-added binary files::
3532 3539
3533 3540 hg forget "set:added() and binary()"
3534 3541
3535 3542 - forget files that would be excluded by .hgignore::
3536 3543
3537 3544 hg forget "set:hgignore()"
3538 3545
3539 3546 Returns 0 on success.
3540 3547 """
3541 3548
3542 3549 if not pats:
3543 3550 raise error.Abort(_('no files specified'))
3544 3551
3545 3552 m = scmutil.match(repo[None], pats, opts)
3546 3553 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3547 3554 return rejected and 1 or 0
3548 3555
3549 3556 @command(
3550 3557 'graft',
3551 3558 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3552 3559 ('c', 'continue', False, _('resume interrupted graft')),
3553 3560 ('e', 'edit', False, _('invoke editor on commit messages')),
3554 3561 ('', 'log', None, _('append graft info to log message')),
3555 3562 ('f', 'force', False, _('force graft')),
3556 3563 ('D', 'currentdate', False,
3557 3564 _('record the current date as commit date')),
3558 3565 ('U', 'currentuser', False,
3559 3566 _('record the current user as committer'), _('DATE'))]
3560 3567 + commitopts2 + mergetoolopts + dryrunopts,
3561 3568 _('[OPTION]... [-r] REV...'))
3562 3569 def graft(ui, repo, *revs, **opts):
3563 3570 '''copy changes from other branches onto the current branch
3564 3571
3565 3572 This command uses Mercurial's merge logic to copy individual
3566 3573 changes from other branches without merging branches in the
3567 3574 history graph. This is sometimes known as 'backporting' or
3568 3575 'cherry-picking'. By default, graft will copy user, date, and
3569 3576 description from the source changesets.
3570 3577
3571 3578 Changesets that are ancestors of the current revision, that have
3572 3579 already been grafted, or that are merges will be skipped.
3573 3580
3574 3581 If --log is specified, log messages will have a comment appended
3575 3582 of the form::
3576 3583
3577 3584 (grafted from CHANGESETHASH)
3578 3585
3579 3586 If --force is specified, revisions will be grafted even if they
3580 3587 are already ancestors of or have been grafted to the destination.
3581 3588 This is useful when the revisions have since been backed out.
3582 3589
3583 3590 If a graft merge results in conflicts, the graft process is
3584 3591 interrupted so that the current merge can be manually resolved.
3585 3592 Once all conflicts are addressed, the graft process can be
3586 3593 continued with the -c/--continue option.
3587 3594
3588 3595 .. note::
3589 3596
3590 3597 The -c/--continue option does not reapply earlier options, except
3591 3598 for --force.
3592 3599
3593 3600 .. container:: verbose
3594 3601
3595 3602 Examples:
3596 3603
3597 3604 - copy a single change to the stable branch and edit its description::
3598 3605
3599 3606 hg update stable
3600 3607 hg graft --edit 9393
3601 3608
3602 3609 - graft a range of changesets with one exception, updating dates::
3603 3610
3604 3611 hg graft -D "2085::2093 and not 2091"
3605 3612
3606 3613 - continue a graft after resolving conflicts::
3607 3614
3608 3615 hg graft -c
3609 3616
3610 3617 - show the source of a grafted changeset::
3611 3618
3612 3619 hg log --debug -r .
3613 3620
3614 3621 See :hg:`help revisions` and :hg:`help revsets` for more about
3615 3622 specifying revisions.
3616 3623
3617 3624 Returns 0 on successful completion.
3618 3625 '''
3619 3626
3620 3627 revs = list(revs)
3621 3628 revs.extend(opts['rev'])
3622 3629
3623 3630 if not opts.get('user') and opts.get('currentuser'):
3624 3631 opts['user'] = ui.username()
3625 3632 if not opts.get('date') and opts.get('currentdate'):
3626 3633 opts['date'] = "%d %d" % util.makedate()
3627 3634
3628 3635 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3629 3636
3630 3637 cont = False
3631 3638 if opts['continue']:
3632 3639 cont = True
3633 3640 if revs:
3634 3641 raise error.Abort(_("can't specify --continue and revisions"))
3635 3642 # read in unfinished revisions
3636 3643 try:
3637 3644 nodes = repo.vfs.read('graftstate').splitlines()
3638 3645 revs = [repo[node].rev() for node in nodes]
3639 3646 except IOError as inst:
3640 3647 if inst.errno != errno.ENOENT:
3641 3648 raise
3642 3649 raise error.Abort(_("no graft state found, can't continue"))
3643 3650 else:
3644 3651 cmdutil.checkunfinished(repo)
3645 3652 cmdutil.bailifchanged(repo)
3646 3653 if not revs:
3647 3654 raise error.Abort(_('no revisions specified'))
3648 3655 revs = scmutil.revrange(repo, revs)
3649 3656
3650 3657 skipped = set()
3651 3658 # check for merges
3652 3659 for rev in repo.revs('%ld and merge()', revs):
3653 3660 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3654 3661 skipped.add(rev)
3655 3662 revs = [r for r in revs if r not in skipped]
3656 3663 if not revs:
3657 3664 return -1
3658 3665
3659 3666 # Don't check in the --continue case, in effect retaining --force across
3660 3667 # --continues. That's because without --force, any revisions we decided to
3661 3668 # skip would have been filtered out here, so they wouldn't have made their
3662 3669 # way to the graftstate. With --force, any revisions we would have otherwise
3663 3670 # skipped would not have been filtered out, and if they hadn't been applied
3664 3671 # already, they'd have been in the graftstate.
3665 3672 if not (cont or opts.get('force')):
3666 3673 # check for ancestors of dest branch
3667 3674 crev = repo['.'].rev()
3668 3675 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3669 3676 # Cannot use x.remove(y) on smart set, this has to be a list.
3670 3677 # XXX make this lazy in the future
3671 3678 revs = list(revs)
3672 3679 # don't mutate while iterating, create a copy
3673 3680 for rev in list(revs):
3674 3681 if rev in ancestors:
3675 3682 ui.warn(_('skipping ancestor revision %d:%s\n') %
3676 3683 (rev, repo[rev]))
3677 3684 # XXX remove on list is slow
3678 3685 revs.remove(rev)
3679 3686 if not revs:
3680 3687 return -1
3681 3688
3682 3689 # analyze revs for earlier grafts
3683 3690 ids = {}
3684 3691 for ctx in repo.set("%ld", revs):
3685 3692 ids[ctx.hex()] = ctx.rev()
3686 3693 n = ctx.extra().get('source')
3687 3694 if n:
3688 3695 ids[n] = ctx.rev()
3689 3696
3690 3697 # check ancestors for earlier grafts
3691 3698 ui.debug('scanning for duplicate grafts\n')
3692 3699
3693 3700 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3694 3701 ctx = repo[rev]
3695 3702 n = ctx.extra().get('source')
3696 3703 if n in ids:
3697 3704 try:
3698 3705 r = repo[n].rev()
3699 3706 except error.RepoLookupError:
3700 3707 r = None
3701 3708 if r in revs:
3702 3709 ui.warn(_('skipping revision %d:%s '
3703 3710 '(already grafted to %d:%s)\n')
3704 3711 % (r, repo[r], rev, ctx))
3705 3712 revs.remove(r)
3706 3713 elif ids[n] in revs:
3707 3714 if r is None:
3708 3715 ui.warn(_('skipping already grafted revision %d:%s '
3709 3716 '(%d:%s also has unknown origin %s)\n')
3710 3717 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3711 3718 else:
3712 3719 ui.warn(_('skipping already grafted revision %d:%s '
3713 3720 '(%d:%s also has origin %d:%s)\n')
3714 3721 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3715 3722 revs.remove(ids[n])
3716 3723 elif ctx.hex() in ids:
3717 3724 r = ids[ctx.hex()]
3718 3725 ui.warn(_('skipping already grafted revision %d:%s '
3719 3726 '(was grafted from %d:%s)\n') %
3720 3727 (r, repo[r], rev, ctx))
3721 3728 revs.remove(r)
3722 3729 if not revs:
3723 3730 return -1
3724 3731
3725 3732 wlock = repo.wlock()
3726 3733 try:
3727 3734 for pos, ctx in enumerate(repo.set("%ld", revs)):
3728 3735 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3729 3736 ctx.description().split('\n', 1)[0])
3730 3737 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3731 3738 if names:
3732 3739 desc += ' (%s)' % ' '.join(names)
3733 3740 ui.status(_('grafting %s\n') % desc)
3734 3741 if opts.get('dry_run'):
3735 3742 continue
3736 3743
3737 3744 source = ctx.extra().get('source')
3738 3745 extra = {}
3739 3746 if source:
3740 3747 extra['source'] = source
3741 3748 extra['intermediate-source'] = ctx.hex()
3742 3749 else:
3743 3750 extra['source'] = ctx.hex()
3744 3751 user = ctx.user()
3745 3752 if opts.get('user'):
3746 3753 user = opts['user']
3747 3754 date = ctx.date()
3748 3755 if opts.get('date'):
3749 3756 date = opts['date']
3750 3757 message = ctx.description()
3751 3758 if opts.get('log'):
3752 3759 message += '\n(grafted from %s)' % ctx.hex()
3753 3760
3754 3761 # we don't merge the first commit when continuing
3755 3762 if not cont:
3756 3763 # perform the graft merge with p1(rev) as 'ancestor'
3757 3764 try:
3758 3765 # ui.forcemerge is an internal variable, do not document
3759 3766 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3760 3767 'graft')
3761 3768 stats = mergemod.graft(repo, ctx, ctx.p1(),
3762 3769 ['local', 'graft'])
3763 3770 finally:
3764 3771 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3765 3772 # report any conflicts
3766 3773 if stats and stats[3] > 0:
3767 3774 # write out state for --continue
3768 3775 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3769 3776 repo.vfs.write('graftstate', ''.join(nodelines))
3770 3777 raise error.Abort(
3771 3778 _("unresolved conflicts, can't continue"),
3772 3779 hint=_('use hg resolve and hg graft --continue'))
3773 3780 else:
3774 3781 cont = False
3775 3782
3776 3783 # commit
3777 3784 node = repo.commit(text=message, user=user,
3778 3785 date=date, extra=extra, editor=editor)
3779 3786 if node is None:
3780 3787 ui.warn(
3781 3788 _('note: graft of %d:%s created no changes to commit\n') %
3782 3789 (ctx.rev(), ctx))
3783 3790 finally:
3784 3791 wlock.release()
3785 3792
3786 3793 # remove state when we complete successfully
3787 3794 if not opts.get('dry_run'):
3788 3795 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3789 3796
3790 3797 return 0
3791 3798
3792 3799 @command('grep',
3793 3800 [('0', 'print0', None, _('end fields with NUL')),
3794 3801 ('', 'all', None, _('print all revisions that match')),
3795 3802 ('a', 'text', None, _('treat all files as text')),
3796 3803 ('f', 'follow', None,
3797 3804 _('follow changeset history,'
3798 3805 ' or file history across copies and renames')),
3799 3806 ('i', 'ignore-case', None, _('ignore case when matching')),
3800 3807 ('l', 'files-with-matches', None,
3801 3808 _('print only filenames and revisions that match')),
3802 3809 ('n', 'line-number', None, _('print matching line numbers')),
3803 3810 ('r', 'rev', [],
3804 3811 _('only search files changed within revision range'), _('REV')),
3805 3812 ('u', 'user', None, _('list the author (long with -v)')),
3806 3813 ('d', 'date', None, _('list the date (short with -q)')),
3807 3814 ] + walkopts,
3808 3815 _('[OPTION]... PATTERN [FILE]...'),
3809 3816 inferrepo=True)
3810 3817 def grep(ui, repo, pattern, *pats, **opts):
3811 3818 """search for a pattern in specified files and revisions
3812 3819
3813 3820 Search revisions of files for a regular expression.
3814 3821
3815 3822 This command behaves differently than Unix grep. It only accepts
3816 3823 Python/Perl regexps. It searches repository history, not the
3817 3824 working directory. It always prints the revision number in which a
3818 3825 match appears.
3819 3826
3820 3827 By default, grep only prints output for the first revision of a
3821 3828 file in which it finds a match. To get it to print every revision
3822 3829 that contains a change in match status ("-" for a match that
3823 3830 becomes a non-match, or "+" for a non-match that becomes a match),
3824 3831 use the --all flag.
3825 3832
3826 3833 Returns 0 if a match is found, 1 otherwise.
3827 3834 """
3828 3835 reflags = re.M
3829 3836 if opts.get('ignore_case'):
3830 3837 reflags |= re.I
3831 3838 try:
3832 3839 regexp = util.re.compile(pattern, reflags)
3833 3840 except re.error as inst:
3834 3841 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3835 3842 return 1
3836 3843 sep, eol = ':', '\n'
3837 3844 if opts.get('print0'):
3838 3845 sep = eol = '\0'
3839 3846
3840 3847 getfile = util.lrucachefunc(repo.file)
3841 3848
3842 3849 def matchlines(body):
3843 3850 begin = 0
3844 3851 linenum = 0
3845 3852 while begin < len(body):
3846 3853 match = regexp.search(body, begin)
3847 3854 if not match:
3848 3855 break
3849 3856 mstart, mend = match.span()
3850 3857 linenum += body.count('\n', begin, mstart) + 1
3851 3858 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3852 3859 begin = body.find('\n', mend) + 1 or len(body) + 1
3853 3860 lend = begin - 1
3854 3861 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3855 3862
3856 3863 class linestate(object):
3857 3864 def __init__(self, line, linenum, colstart, colend):
3858 3865 self.line = line
3859 3866 self.linenum = linenum
3860 3867 self.colstart = colstart
3861 3868 self.colend = colend
3862 3869
3863 3870 def __hash__(self):
3864 3871 return hash((self.linenum, self.line))
3865 3872
3866 3873 def __eq__(self, other):
3867 3874 return self.line == other.line
3868 3875
3869 3876 def __iter__(self):
3870 3877 yield (self.line[:self.colstart], '')
3871 3878 yield (self.line[self.colstart:self.colend], 'grep.match')
3872 3879 rest = self.line[self.colend:]
3873 3880 while rest != '':
3874 3881 match = regexp.search(rest)
3875 3882 if not match:
3876 3883 yield (rest, '')
3877 3884 break
3878 3885 mstart, mend = match.span()
3879 3886 yield (rest[:mstart], '')
3880 3887 yield (rest[mstart:mend], 'grep.match')
3881 3888 rest = rest[mend:]
3882 3889
3883 3890 matches = {}
3884 3891 copies = {}
3885 3892 def grepbody(fn, rev, body):
3886 3893 matches[rev].setdefault(fn, [])
3887 3894 m = matches[rev][fn]
3888 3895 for lnum, cstart, cend, line in matchlines(body):
3889 3896 s = linestate(line, lnum, cstart, cend)
3890 3897 m.append(s)
3891 3898
3892 3899 def difflinestates(a, b):
3893 3900 sm = difflib.SequenceMatcher(None, a, b)
3894 3901 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3895 3902 if tag == 'insert':
3896 3903 for i in xrange(blo, bhi):
3897 3904 yield ('+', b[i])
3898 3905 elif tag == 'delete':
3899 3906 for i in xrange(alo, ahi):
3900 3907 yield ('-', a[i])
3901 3908 elif tag == 'replace':
3902 3909 for i in xrange(alo, ahi):
3903 3910 yield ('-', a[i])
3904 3911 for i in xrange(blo, bhi):
3905 3912 yield ('+', b[i])
3906 3913
3907 3914 def display(fn, ctx, pstates, states):
3908 3915 rev = ctx.rev()
3909 3916 if ui.quiet:
3910 3917 datefunc = util.shortdate
3911 3918 else:
3912 3919 datefunc = util.datestr
3913 3920 found = False
3914 3921 @util.cachefunc
3915 3922 def binary():
3916 3923 flog = getfile(fn)
3917 3924 return util.binary(flog.read(ctx.filenode(fn)))
3918 3925
3919 3926 if opts.get('all'):
3920 3927 iter = difflinestates(pstates, states)
3921 3928 else:
3922 3929 iter = [('', l) for l in states]
3923 3930 for change, l in iter:
3924 3931 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3925 3932
3926 3933 if opts.get('line_number'):
3927 3934 cols.append((str(l.linenum), 'grep.linenumber'))
3928 3935 if opts.get('all'):
3929 3936 cols.append((change, 'grep.change'))
3930 3937 if opts.get('user'):
3931 3938 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3932 3939 if opts.get('date'):
3933 3940 cols.append((datefunc(ctx.date()), 'grep.date'))
3934 3941 for col, label in cols[:-1]:
3935 3942 ui.write(col, label=label)
3936 3943 ui.write(sep, label='grep.sep')
3937 3944 ui.write(cols[-1][0], label=cols[-1][1])
3938 3945 if not opts.get('files_with_matches'):
3939 3946 ui.write(sep, label='grep.sep')
3940 3947 if not opts.get('text') and binary():
3941 3948 ui.write(" Binary file matches")
3942 3949 else:
3943 3950 for s, label in l:
3944 3951 ui.write(s, label=label)
3945 3952 ui.write(eol)
3946 3953 found = True
3947 3954 if opts.get('files_with_matches'):
3948 3955 break
3949 3956 return found
3950 3957
3951 3958 skip = {}
3952 3959 revfiles = {}
3953 3960 matchfn = scmutil.match(repo[None], pats, opts)
3954 3961 found = False
3955 3962 follow = opts.get('follow')
3956 3963
3957 3964 def prep(ctx, fns):
3958 3965 rev = ctx.rev()
3959 3966 pctx = ctx.p1()
3960 3967 parent = pctx.rev()
3961 3968 matches.setdefault(rev, {})
3962 3969 matches.setdefault(parent, {})
3963 3970 files = revfiles.setdefault(rev, [])
3964 3971 for fn in fns:
3965 3972 flog = getfile(fn)
3966 3973 try:
3967 3974 fnode = ctx.filenode(fn)
3968 3975 except error.LookupError:
3969 3976 continue
3970 3977
3971 3978 copied = flog.renamed(fnode)
3972 3979 copy = follow and copied and copied[0]
3973 3980 if copy:
3974 3981 copies.setdefault(rev, {})[fn] = copy
3975 3982 if fn in skip:
3976 3983 if copy:
3977 3984 skip[copy] = True
3978 3985 continue
3979 3986 files.append(fn)
3980 3987
3981 3988 if fn not in matches[rev]:
3982 3989 grepbody(fn, rev, flog.read(fnode))
3983 3990
3984 3991 pfn = copy or fn
3985 3992 if pfn not in matches[parent]:
3986 3993 try:
3987 3994 fnode = pctx.filenode(pfn)
3988 3995 grepbody(pfn, parent, flog.read(fnode))
3989 3996 except error.LookupError:
3990 3997 pass
3991 3998
3992 3999 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3993 4000 rev = ctx.rev()
3994 4001 parent = ctx.p1().rev()
3995 4002 for fn in sorted(revfiles.get(rev, [])):
3996 4003 states = matches[rev][fn]
3997 4004 copy = copies.get(rev, {}).get(fn)
3998 4005 if fn in skip:
3999 4006 if copy:
4000 4007 skip[copy] = True
4001 4008 continue
4002 4009 pstates = matches.get(parent, {}).get(copy or fn, [])
4003 4010 if pstates or states:
4004 4011 r = display(fn, ctx, pstates, states)
4005 4012 found = found or r
4006 4013 if r and not opts.get('all'):
4007 4014 skip[fn] = True
4008 4015 if copy:
4009 4016 skip[copy] = True
4010 4017 del matches[rev]
4011 4018 del revfiles[rev]
4012 4019
4013 4020 return not found
4014 4021
4015 4022 @command('heads',
4016 4023 [('r', 'rev', '',
4017 4024 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
4018 4025 ('t', 'topo', False, _('show topological heads only')),
4019 4026 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
4020 4027 ('c', 'closed', False, _('show normal and closed branch heads')),
4021 4028 ] + templateopts,
4022 4029 _('[-ct] [-r STARTREV] [REV]...'))
4023 4030 def heads(ui, repo, *branchrevs, **opts):
4024 4031 """show branch heads
4025 4032
4026 4033 With no arguments, show all open branch heads in the repository.
4027 4034 Branch heads are changesets that have no descendants on the
4028 4035 same branch. They are where development generally takes place and
4029 4036 are the usual targets for update and merge operations.
4030 4037
4031 4038 If one or more REVs are given, only open branch heads on the
4032 4039 branches associated with the specified changesets are shown. This
4033 4040 means that you can use :hg:`heads .` to see the heads on the
4034 4041 currently checked-out branch.
4035 4042
4036 4043 If -c/--closed is specified, also show branch heads marked closed
4037 4044 (see :hg:`commit --close-branch`).
4038 4045
4039 4046 If STARTREV is specified, only those heads that are descendants of
4040 4047 STARTREV will be displayed.
4041 4048
4042 4049 If -t/--topo is specified, named branch mechanics will be ignored and only
4043 4050 topological heads (changesets with no children) will be shown.
4044 4051
4045 4052 Returns 0 if matching heads are found, 1 if not.
4046 4053 """
4047 4054
4048 4055 start = None
4049 4056 if 'rev' in opts:
4050 4057 start = scmutil.revsingle(repo, opts['rev'], None).node()
4051 4058
4052 4059 if opts.get('topo'):
4053 4060 heads = [repo[h] for h in repo.heads(start)]
4054 4061 else:
4055 4062 heads = []
4056 4063 for branch in repo.branchmap():
4057 4064 heads += repo.branchheads(branch, start, opts.get('closed'))
4058 4065 heads = [repo[h] for h in heads]
4059 4066
4060 4067 if branchrevs:
4061 4068 branches = set(repo[br].branch() for br in branchrevs)
4062 4069 heads = [h for h in heads if h.branch() in branches]
4063 4070
4064 4071 if opts.get('active') and branchrevs:
4065 4072 dagheads = repo.heads(start)
4066 4073 heads = [h for h in heads if h.node() in dagheads]
4067 4074
4068 4075 if branchrevs:
4069 4076 haveheads = set(h.branch() for h in heads)
4070 4077 if branches - haveheads:
4071 4078 headless = ', '.join(b for b in branches - haveheads)
4072 4079 msg = _('no open branch heads found on branches %s')
4073 4080 if opts.get('rev'):
4074 4081 msg += _(' (started at %s)') % opts['rev']
4075 4082 ui.warn((msg + '\n') % headless)
4076 4083
4077 4084 if not heads:
4078 4085 return 1
4079 4086
4080 4087 heads = sorted(heads, key=lambda x: -x.rev())
4081 4088 displayer = cmdutil.show_changeset(ui, repo, opts)
4082 4089 for ctx in heads:
4083 4090 displayer.show(ctx)
4084 4091 displayer.close()
4085 4092
4086 4093 @command('help',
4087 4094 [('e', 'extension', None, _('show only help for extensions')),
4088 4095 ('c', 'command', None, _('show only help for commands')),
4089 4096 ('k', 'keyword', None, _('show topics matching keyword')),
4090 4097 ],
4091 4098 _('[-eck] [TOPIC]'),
4092 4099 norepo=True)
4093 4100 def help_(ui, name=None, **opts):
4094 4101 """show help for a given topic or a help overview
4095 4102
4096 4103 With no arguments, print a list of commands with short help messages.
4097 4104
4098 4105 Given a topic, extension, or command name, print help for that
4099 4106 topic.
4100 4107
4101 4108 Returns 0 if successful.
4102 4109 """
4103 4110
4104 4111 textwidth = min(ui.termwidth(), 80) - 2
4105 4112
4106 4113 keep = []
4107 4114 if ui.verbose:
4108 4115 keep.append('verbose')
4109 4116 if sys.platform.startswith('win'):
4110 4117 keep.append('windows')
4111 4118 elif sys.platform == 'OpenVMS':
4112 4119 keep.append('vms')
4113 4120 elif sys.platform == 'plan9':
4114 4121 keep.append('plan9')
4115 4122 else:
4116 4123 keep.append('unix')
4117 4124 keep.append(sys.platform.lower())
4118 4125
4119 4126 section = None
4120 4127 if name and '.' in name:
4121 4128 name, section = name.split('.', 1)
4122 4129 section = section.lower()
4123 4130
4124 4131 text = help.help_(ui, name, **opts)
4125 4132
4126 4133 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4127 4134 section=section)
4128 4135
4129 4136 # We could have been given a weird ".foo" section without a name
4130 4137 # to look for, or we could have simply failed to found "foo.bar"
4131 4138 # because bar isn't a section of foo
4132 4139 if section and not (formatted and name):
4133 4140 raise error.Abort(_("help section not found"))
4134 4141
4135 4142 if 'verbose' in pruned:
4136 4143 keep.append('omitted')
4137 4144 else:
4138 4145 keep.append('notomitted')
4139 4146 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4140 4147 section=section)
4141 4148 ui.write(formatted)
4142 4149
4143 4150
4144 4151 @command('identify|id',
4145 4152 [('r', 'rev', '',
4146 4153 _('identify the specified revision'), _('REV')),
4147 4154 ('n', 'num', None, _('show local revision number')),
4148 4155 ('i', 'id', None, _('show global revision id')),
4149 4156 ('b', 'branch', None, _('show branch')),
4150 4157 ('t', 'tags', None, _('show tags')),
4151 4158 ('B', 'bookmarks', None, _('show bookmarks')),
4152 4159 ] + remoteopts,
4153 4160 _('[-nibtB] [-r REV] [SOURCE]'),
4154 4161 optionalrepo=True)
4155 4162 def identify(ui, repo, source=None, rev=None,
4156 4163 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
4157 4164 """identify the working directory or specified revision
4158 4165
4159 4166 Print a summary identifying the repository state at REV using one or
4160 4167 two parent hash identifiers, followed by a "+" if the working
4161 4168 directory has uncommitted changes, the branch name (if not default),
4162 4169 a list of tags, and a list of bookmarks.
4163 4170
4164 4171 When REV is not given, print a summary of the current state of the
4165 4172 repository.
4166 4173
4167 4174 Specifying a path to a repository root or Mercurial bundle will
4168 4175 cause lookup to operate on that repository/bundle.
4169 4176
4170 4177 .. container:: verbose
4171 4178
4172 4179 Examples:
4173 4180
4174 4181 - generate a build identifier for the working directory::
4175 4182
4176 4183 hg id --id > build-id.dat
4177 4184
4178 4185 - find the revision corresponding to a tag::
4179 4186
4180 4187 hg id -n -r 1.3
4181 4188
4182 4189 - check the most recent revision of a remote repository::
4183 4190
4184 4191 hg id -r tip http://selenic.com/hg/
4185 4192
4186 4193 Returns 0 if successful.
4187 4194 """
4188 4195
4189 4196 if not repo and not source:
4190 4197 raise error.Abort(_("there is no Mercurial repository here "
4191 4198 "(.hg not found)"))
4192 4199
4193 4200 if ui.debugflag:
4194 4201 hexfunc = hex
4195 4202 else:
4196 4203 hexfunc = short
4197 4204 default = not (num or id or branch or tags or bookmarks)
4198 4205 output = []
4199 4206 revs = []
4200 4207
4201 4208 if source:
4202 4209 source, branches = hg.parseurl(ui.expandpath(source))
4203 4210 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4204 4211 repo = peer.local()
4205 4212 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4206 4213
4207 4214 if not repo:
4208 4215 if num or branch or tags:
4209 4216 raise error.Abort(
4210 4217 _("can't query remote revision number, branch, or tags"))
4211 4218 if not rev and revs:
4212 4219 rev = revs[0]
4213 4220 if not rev:
4214 4221 rev = "tip"
4215 4222
4216 4223 remoterev = peer.lookup(rev)
4217 4224 if default or id:
4218 4225 output = [hexfunc(remoterev)]
4219 4226
4220 4227 def getbms():
4221 4228 bms = []
4222 4229
4223 4230 if 'bookmarks' in peer.listkeys('namespaces'):
4224 4231 hexremoterev = hex(remoterev)
4225 4232 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4226 4233 if bmr == hexremoterev]
4227 4234
4228 4235 return sorted(bms)
4229 4236
4230 4237 if bookmarks:
4231 4238 output.extend(getbms())
4232 4239 elif default and not ui.quiet:
4233 4240 # multiple bookmarks for a single parent separated by '/'
4234 4241 bm = '/'.join(getbms())
4235 4242 if bm:
4236 4243 output.append(bm)
4237 4244 else:
4238 4245 ctx = scmutil.revsingle(repo, rev, None)
4239 4246
4240 4247 if ctx.rev() is None:
4241 4248 ctx = repo[None]
4242 4249 parents = ctx.parents()
4243 4250 taglist = []
4244 4251 for p in parents:
4245 4252 taglist.extend(p.tags())
4246 4253
4247 4254 changed = ""
4248 4255 if default or id or num:
4249 4256 if (any(repo.status())
4250 4257 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4251 4258 changed = '+'
4252 4259 if default or id:
4253 4260 output = ["%s%s" %
4254 4261 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4255 4262 if num:
4256 4263 output.append("%s%s" %
4257 4264 ('+'.join([str(p.rev()) for p in parents]), changed))
4258 4265 else:
4259 4266 if default or id:
4260 4267 output = [hexfunc(ctx.node())]
4261 4268 if num:
4262 4269 output.append(str(ctx.rev()))
4263 4270 taglist = ctx.tags()
4264 4271
4265 4272 if default and not ui.quiet:
4266 4273 b = ctx.branch()
4267 4274 if b != 'default':
4268 4275 output.append("(%s)" % b)
4269 4276
4270 4277 # multiple tags for a single parent separated by '/'
4271 4278 t = '/'.join(taglist)
4272 4279 if t:
4273 4280 output.append(t)
4274 4281
4275 4282 # multiple bookmarks for a single parent separated by '/'
4276 4283 bm = '/'.join(ctx.bookmarks())
4277 4284 if bm:
4278 4285 output.append(bm)
4279 4286 else:
4280 4287 if branch:
4281 4288 output.append(ctx.branch())
4282 4289
4283 4290 if tags:
4284 4291 output.extend(taglist)
4285 4292
4286 4293 if bookmarks:
4287 4294 output.extend(ctx.bookmarks())
4288 4295
4289 4296 ui.write("%s\n" % ' '.join(output))
4290 4297
4291 4298 @command('import|patch',
4292 4299 [('p', 'strip', 1,
4293 4300 _('directory strip option for patch. This has the same '
4294 4301 'meaning as the corresponding patch option'), _('NUM')),
4295 4302 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4296 4303 ('e', 'edit', False, _('invoke editor on commit messages')),
4297 4304 ('f', 'force', None,
4298 4305 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4299 4306 ('', 'no-commit', None,
4300 4307 _("don't commit, just update the working directory")),
4301 4308 ('', 'bypass', None,
4302 4309 _("apply patch without touching the working directory")),
4303 4310 ('', 'partial', None,
4304 4311 _('commit even if some hunks fail')),
4305 4312 ('', 'exact', None,
4306 4313 _('apply patch to the nodes from which it was generated')),
4307 4314 ('', 'prefix', '',
4308 4315 _('apply patch to subdirectory'), _('DIR')),
4309 4316 ('', 'import-branch', None,
4310 4317 _('use any branch information in patch (implied by --exact)'))] +
4311 4318 commitopts + commitopts2 + similarityopts,
4312 4319 _('[OPTION]... PATCH...'))
4313 4320 def import_(ui, repo, patch1=None, *patches, **opts):
4314 4321 """import an ordered set of patches
4315 4322
4316 4323 Import a list of patches and commit them individually (unless
4317 4324 --no-commit is specified).
4318 4325
4319 4326 Because import first applies changes to the working directory,
4320 4327 import will abort if there are outstanding changes.
4321 4328
4322 4329 You can import a patch straight from a mail message. Even patches
4323 4330 as attachments work (to use the body part, it must have type
4324 4331 text/plain or text/x-patch). From and Subject headers of email
4325 4332 message are used as default committer and commit message. All
4326 4333 text/plain body parts before first diff are added to commit
4327 4334 message.
4328 4335
4329 4336 If the imported patch was generated by :hg:`export`, user and
4330 4337 description from patch override values from message headers and
4331 4338 body. Values given on command line with -m/--message and -u/--user
4332 4339 override these.
4333 4340
4334 4341 If --exact is specified, import will set the working directory to
4335 4342 the parent of each patch before applying it, and will abort if the
4336 4343 resulting changeset has a different ID than the one recorded in
4337 4344 the patch. This may happen due to character set problems or other
4338 4345 deficiencies in the text patch format.
4339 4346
4340 4347 Use --bypass to apply and commit patches directly to the
4341 4348 repository, not touching the working directory. Without --exact,
4342 4349 patches will be applied on top of the working directory parent
4343 4350 revision.
4344 4351
4345 4352 With -s/--similarity, hg will attempt to discover renames and
4346 4353 copies in the patch in the same way as :hg:`addremove`.
4347 4354
4348 4355 Use --partial to ensure a changeset will be created from the patch
4349 4356 even if some hunks fail to apply. Hunks that fail to apply will be
4350 4357 written to a <target-file>.rej file. Conflicts can then be resolved
4351 4358 by hand before :hg:`commit --amend` is run to update the created
4352 4359 changeset. This flag exists to let people import patches that
4353 4360 partially apply without losing the associated metadata (author,
4354 4361 date, description, ...). Note that when none of the hunk applies
4355 4362 cleanly, :hg:`import --partial` will create an empty changeset,
4356 4363 importing only the patch metadata.
4357 4364
4358 4365 It is possible to use external patch programs to perform the patch
4359 4366 by setting the ``ui.patch`` configuration option. For the default
4360 4367 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4361 4368 See :hg:`help config` for more information about configuration
4362 4369 files and how to use these options.
4363 4370
4364 4371 To read a patch from standard input, use "-" as the patch name. If
4365 4372 a URL is specified, the patch will be downloaded from it.
4366 4373 See :hg:`help dates` for a list of formats valid for -d/--date.
4367 4374
4368 4375 .. container:: verbose
4369 4376
4370 4377 Examples:
4371 4378
4372 4379 - import a traditional patch from a website and detect renames::
4373 4380
4374 4381 hg import -s 80 http://example.com/bugfix.patch
4375 4382
4376 4383 - import a changeset from an hgweb server::
4377 4384
4378 4385 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4379 4386
4380 4387 - import all the patches in an Unix-style mbox::
4381 4388
4382 4389 hg import incoming-patches.mbox
4383 4390
4384 4391 - attempt to exactly restore an exported changeset (not always
4385 4392 possible)::
4386 4393
4387 4394 hg import --exact proposed-fix.patch
4388 4395
4389 4396 - use an external tool to apply a patch which is too fuzzy for
4390 4397 the default internal tool.
4391 4398
4392 4399 hg import --config ui.patch="patch --merge" fuzzy.patch
4393 4400
4394 4401 - change the default fuzzing from 2 to a less strict 7
4395 4402
4396 4403 hg import --config ui.fuzz=7 fuzz.patch
4397 4404
4398 4405 Returns 0 on success, 1 on partial success (see --partial).
4399 4406 """
4400 4407
4401 4408 if not patch1:
4402 4409 raise error.Abort(_('need at least one patch to import'))
4403 4410
4404 4411 patches = (patch1,) + patches
4405 4412
4406 4413 date = opts.get('date')
4407 4414 if date:
4408 4415 opts['date'] = util.parsedate(date)
4409 4416
4410 4417 update = not opts.get('bypass')
4411 4418 if not update and opts.get('no_commit'):
4412 4419 raise error.Abort(_('cannot use --no-commit with --bypass'))
4413 4420 try:
4414 4421 sim = float(opts.get('similarity') or 0)
4415 4422 except ValueError:
4416 4423 raise error.Abort(_('similarity must be a number'))
4417 4424 if sim < 0 or sim > 100:
4418 4425 raise error.Abort(_('similarity must be between 0 and 100'))
4419 4426 if sim and not update:
4420 4427 raise error.Abort(_('cannot use --similarity with --bypass'))
4421 4428 if opts.get('exact') and opts.get('edit'):
4422 4429 raise error.Abort(_('cannot use --exact with --edit'))
4423 4430 if opts.get('exact') and opts.get('prefix'):
4424 4431 raise error.Abort(_('cannot use --exact with --prefix'))
4425 4432
4426 4433 if update:
4427 4434 cmdutil.checkunfinished(repo)
4428 4435 if (opts.get('exact') or not opts.get('force')) and update:
4429 4436 cmdutil.bailifchanged(repo)
4430 4437
4431 4438 base = opts["base"]
4432 4439 wlock = dsguard = lock = tr = None
4433 4440 msgs = []
4434 4441 ret = 0
4435 4442
4436 4443
4437 4444 try:
4438 4445 try:
4439 4446 wlock = repo.wlock()
4440 4447 if not opts.get('no_commit'):
4441 4448 lock = repo.lock()
4442 4449 tr = repo.transaction('import')
4443 4450 else:
4444 4451 dsguard = cmdutil.dirstateguard(repo, 'import')
4445 4452 parents = repo.parents()
4446 4453 for patchurl in patches:
4447 4454 if patchurl == '-':
4448 4455 ui.status(_('applying patch from stdin\n'))
4449 4456 patchfile = ui.fin
4450 4457 patchurl = 'stdin' # for error message
4451 4458 else:
4452 4459 patchurl = os.path.join(base, patchurl)
4453 4460 ui.status(_('applying %s\n') % patchurl)
4454 4461 patchfile = hg.openpath(ui, patchurl)
4455 4462
4456 4463 haspatch = False
4457 4464 for hunk in patch.split(patchfile):
4458 4465 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4459 4466 parents, opts,
4460 4467 msgs, hg.clean)
4461 4468 if msg:
4462 4469 haspatch = True
4463 4470 ui.note(msg + '\n')
4464 4471 if update or opts.get('exact'):
4465 4472 parents = repo.parents()
4466 4473 else:
4467 4474 parents = [repo[node]]
4468 4475 if rej:
4469 4476 ui.write_err(_("patch applied partially\n"))
4470 4477 ui.write_err(_("(fix the .rej files and run "
4471 4478 "`hg commit --amend`)\n"))
4472 4479 ret = 1
4473 4480 break
4474 4481
4475 4482 if not haspatch:
4476 4483 raise error.Abort(_('%s: no diffs found') % patchurl)
4477 4484
4478 4485 if tr:
4479 4486 tr.close()
4480 4487 if msgs:
4481 4488 repo.savecommitmessage('\n* * *\n'.join(msgs))
4482 4489 if dsguard:
4483 4490 dsguard.close()
4484 4491 return ret
4485 4492 finally:
4486 4493 # TODO: get rid of this meaningless try/finally enclosing.
4487 4494 # this is kept only to reduce changes in a patch.
4488 4495 pass
4489 4496 finally:
4490 4497 if tr:
4491 4498 tr.release()
4492 4499 release(lock, dsguard, wlock)
4493 4500
4494 4501 @command('incoming|in',
4495 4502 [('f', 'force', None,
4496 4503 _('run even if remote repository is unrelated')),
4497 4504 ('n', 'newest-first', None, _('show newest record first')),
4498 4505 ('', 'bundle', '',
4499 4506 _('file to store the bundles into'), _('FILE')),
4500 4507 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4501 4508 ('B', 'bookmarks', False, _("compare bookmarks")),
4502 4509 ('b', 'branch', [],
4503 4510 _('a specific branch you would like to pull'), _('BRANCH')),
4504 4511 ] + logopts + remoteopts + subrepoopts,
4505 4512 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4506 4513 def incoming(ui, repo, source="default", **opts):
4507 4514 """show new changesets found in source
4508 4515
4509 4516 Show new changesets found in the specified path/URL or the default
4510 4517 pull location. These are the changesets that would have been pulled
4511 4518 if a pull at the time you issued this command.
4512 4519
4513 4520 See pull for valid source format details.
4514 4521
4515 4522 .. container:: verbose
4516 4523
4517 4524 With -B/--bookmarks, the result of bookmark comparison between
4518 4525 local and remote repositories is displayed. With -v/--verbose,
4519 4526 status is also displayed for each bookmark like below::
4520 4527
4521 4528 BM1 01234567890a added
4522 4529 BM2 1234567890ab advanced
4523 4530 BM3 234567890abc diverged
4524 4531 BM4 34567890abcd changed
4525 4532
4526 4533 The action taken locally when pulling depends on the
4527 4534 status of each bookmark:
4528 4535
4529 4536 :``added``: pull will create it
4530 4537 :``advanced``: pull will update it
4531 4538 :``diverged``: pull will create a divergent bookmark
4532 4539 :``changed``: result depends on remote changesets
4533 4540
4534 4541 From the point of view of pulling behavior, bookmark
4535 4542 existing only in the remote repository are treated as ``added``,
4536 4543 even if it is in fact locally deleted.
4537 4544
4538 4545 .. container:: verbose
4539 4546
4540 4547 For remote repository, using --bundle avoids downloading the
4541 4548 changesets twice if the incoming is followed by a pull.
4542 4549
4543 4550 Examples:
4544 4551
4545 4552 - show incoming changes with patches and full description::
4546 4553
4547 4554 hg incoming -vp
4548 4555
4549 4556 - show incoming changes excluding merges, store a bundle::
4550 4557
4551 4558 hg in -vpM --bundle incoming.hg
4552 4559 hg pull incoming.hg
4553 4560
4554 4561 - briefly list changes inside a bundle::
4555 4562
4556 4563 hg in changes.hg -T "{desc|firstline}\\n"
4557 4564
4558 4565 Returns 0 if there are incoming changes, 1 otherwise.
4559 4566 """
4560 4567 if opts.get('graph'):
4561 4568 cmdutil.checkunsupportedgraphflags([], opts)
4562 4569 def display(other, chlist, displayer):
4563 4570 revdag = cmdutil.graphrevs(other, chlist, opts)
4564 4571 showparents = [ctx.node() for ctx in repo[None].parents()]
4565 4572 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4566 4573 graphmod.asciiedges)
4567 4574
4568 4575 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4569 4576 return 0
4570 4577
4571 4578 if opts.get('bundle') and opts.get('subrepos'):
4572 4579 raise error.Abort(_('cannot combine --bundle and --subrepos'))
4573 4580
4574 4581 if opts.get('bookmarks'):
4575 4582 source, branches = hg.parseurl(ui.expandpath(source),
4576 4583 opts.get('branch'))
4577 4584 other = hg.peer(repo, opts, source)
4578 4585 if 'bookmarks' not in other.listkeys('namespaces'):
4579 4586 ui.warn(_("remote doesn't support bookmarks\n"))
4580 4587 return 0
4581 4588 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4582 4589 return bookmarks.incoming(ui, repo, other)
4583 4590
4584 4591 repo._subtoppath = ui.expandpath(source)
4585 4592 try:
4586 4593 return hg.incoming(ui, repo, source, opts)
4587 4594 finally:
4588 4595 del repo._subtoppath
4589 4596
4590 4597
4591 4598 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4592 4599 norepo=True)
4593 4600 def init(ui, dest=".", **opts):
4594 4601 """create a new repository in the given directory
4595 4602
4596 4603 Initialize a new repository in the given directory. If the given
4597 4604 directory does not exist, it will be created.
4598 4605
4599 4606 If no directory is given, the current directory is used.
4600 4607
4601 4608 It is possible to specify an ``ssh://`` URL as the destination.
4602 4609 See :hg:`help urls` for more information.
4603 4610
4604 4611 Returns 0 on success.
4605 4612 """
4606 4613 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4607 4614
4608 4615 @command('locate',
4609 4616 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4610 4617 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4611 4618 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4612 4619 ] + walkopts,
4613 4620 _('[OPTION]... [PATTERN]...'))
4614 4621 def locate(ui, repo, *pats, **opts):
4615 4622 """locate files matching specific patterns (DEPRECATED)
4616 4623
4617 4624 Print files under Mercurial control in the working directory whose
4618 4625 names match the given patterns.
4619 4626
4620 4627 By default, this command searches all directories in the working
4621 4628 directory. To search just the current directory and its
4622 4629 subdirectories, use "--include .".
4623 4630
4624 4631 If no patterns are given to match, this command prints the names
4625 4632 of all files under Mercurial control in the working directory.
4626 4633
4627 4634 If you want to feed the output of this command into the "xargs"
4628 4635 command, use the -0 option to both this command and "xargs". This
4629 4636 will avoid the problem of "xargs" treating single filenames that
4630 4637 contain whitespace as multiple filenames.
4631 4638
4632 4639 See :hg:`help files` for a more versatile command.
4633 4640
4634 4641 Returns 0 if a match is found, 1 otherwise.
4635 4642 """
4636 4643 if opts.get('print0'):
4637 4644 end = '\0'
4638 4645 else:
4639 4646 end = '\n'
4640 4647 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4641 4648
4642 4649 ret = 1
4643 4650 ctx = repo[rev]
4644 4651 m = scmutil.match(ctx, pats, opts, default='relglob',
4645 4652 badfn=lambda x, y: False)
4646 4653
4647 4654 for abs in ctx.matches(m):
4648 4655 if opts.get('fullpath'):
4649 4656 ui.write(repo.wjoin(abs), end)
4650 4657 else:
4651 4658 ui.write(((pats and m.rel(abs)) or abs), end)
4652 4659 ret = 0
4653 4660
4654 4661 return ret
4655 4662
4656 4663 @command('^log|history',
4657 4664 [('f', 'follow', None,
4658 4665 _('follow changeset history, or file history across copies and renames')),
4659 4666 ('', 'follow-first', None,
4660 4667 _('only follow the first parent of merge changesets (DEPRECATED)')),
4661 4668 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4662 4669 ('C', 'copies', None, _('show copied files')),
4663 4670 ('k', 'keyword', [],
4664 4671 _('do case-insensitive search for a given text'), _('TEXT')),
4665 4672 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4666 4673 ('', 'removed', None, _('include revisions where files were removed')),
4667 4674 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4668 4675 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4669 4676 ('', 'only-branch', [],
4670 4677 _('show only changesets within the given named branch (DEPRECATED)'),
4671 4678 _('BRANCH')),
4672 4679 ('b', 'branch', [],
4673 4680 _('show changesets within the given named branch'), _('BRANCH')),
4674 4681 ('P', 'prune', [],
4675 4682 _('do not display revision or any of its ancestors'), _('REV')),
4676 4683 ] + logopts + walkopts,
4677 4684 _('[OPTION]... [FILE]'),
4678 4685 inferrepo=True)
4679 4686 def log(ui, repo, *pats, **opts):
4680 4687 """show revision history of entire repository or files
4681 4688
4682 4689 Print the revision history of the specified files or the entire
4683 4690 project.
4684 4691
4685 4692 If no revision range is specified, the default is ``tip:0`` unless
4686 4693 --follow is set, in which case the working directory parent is
4687 4694 used as the starting revision.
4688 4695
4689 4696 File history is shown without following rename or copy history of
4690 4697 files. Use -f/--follow with a filename to follow history across
4691 4698 renames and copies. --follow without a filename will only show
4692 4699 ancestors or descendants of the starting revision.
4693 4700
4694 4701 By default this command prints revision number and changeset id,
4695 4702 tags, non-trivial parents, user, date and time, and a summary for
4696 4703 each commit. When the -v/--verbose switch is used, the list of
4697 4704 changed files and full commit message are shown.
4698 4705
4699 4706 With --graph the revisions are shown as an ASCII art DAG with the most
4700 4707 recent changeset at the top.
4701 4708 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4702 4709 and '+' represents a fork where the changeset from the lines below is a
4703 4710 parent of the 'o' merge on the same line.
4704 4711
4705 4712 .. note::
4706 4713
4707 4714 log -p/--patch may generate unexpected diff output for merge
4708 4715 changesets, as it will only compare the merge changeset against
4709 4716 its first parent. Also, only files different from BOTH parents
4710 4717 will appear in files:.
4711 4718
4712 4719 .. note::
4713 4720
4714 4721 for performance reasons, log FILE may omit duplicate changes
4715 4722 made on branches and will not show removals or mode changes. To
4716 4723 see all such changes, use the --removed switch.
4717 4724
4718 4725 .. container:: verbose
4719 4726
4720 4727 Some examples:
4721 4728
4722 4729 - changesets with full descriptions and file lists::
4723 4730
4724 4731 hg log -v
4725 4732
4726 4733 - changesets ancestral to the working directory::
4727 4734
4728 4735 hg log -f
4729 4736
4730 4737 - last 10 commits on the current branch::
4731 4738
4732 4739 hg log -l 10 -b .
4733 4740
4734 4741 - changesets showing all modifications of a file, including removals::
4735 4742
4736 4743 hg log --removed file.c
4737 4744
4738 4745 - all changesets that touch a directory, with diffs, excluding merges::
4739 4746
4740 4747 hg log -Mp lib/
4741 4748
4742 4749 - all revision numbers that match a keyword::
4743 4750
4744 4751 hg log -k bug --template "{rev}\\n"
4745 4752
4746 4753 - list available log templates::
4747 4754
4748 4755 hg log -T list
4749 4756
4750 4757 - check if a given changeset is included in a tagged release::
4751 4758
4752 4759 hg log -r "a21ccf and ancestor(1.9)"
4753 4760
4754 4761 - find all changesets by some user in a date range::
4755 4762
4756 4763 hg log -k alice -d "may 2008 to jul 2008"
4757 4764
4758 4765 - summary of all changesets after the last tag::
4759 4766
4760 4767 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4761 4768
4762 4769 See :hg:`help dates` for a list of formats valid for -d/--date.
4763 4770
4764 4771 See :hg:`help revisions` and :hg:`help revsets` for more about
4765 4772 specifying revisions.
4766 4773
4767 4774 See :hg:`help templates` for more about pre-packaged styles and
4768 4775 specifying custom templates.
4769 4776
4770 4777 Returns 0 on success.
4771 4778
4772 4779 """
4773 4780 if opts.get('follow') and opts.get('rev'):
4774 4781 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4775 4782 del opts['follow']
4776 4783
4777 4784 if opts.get('graph'):
4778 4785 return cmdutil.graphlog(ui, repo, *pats, **opts)
4779 4786
4780 4787 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4781 4788 limit = cmdutil.loglimit(opts)
4782 4789 count = 0
4783 4790
4784 4791 getrenamed = None
4785 4792 if opts.get('copies'):
4786 4793 endrev = None
4787 4794 if opts.get('rev'):
4788 4795 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4789 4796 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4790 4797
4791 4798 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4792 4799 for rev in revs:
4793 4800 if count == limit:
4794 4801 break
4795 4802 ctx = repo[rev]
4796 4803 copies = None
4797 4804 if getrenamed is not None and rev:
4798 4805 copies = []
4799 4806 for fn in ctx.files():
4800 4807 rename = getrenamed(fn, rev)
4801 4808 if rename:
4802 4809 copies.append((fn, rename[0]))
4803 4810 if filematcher:
4804 4811 revmatchfn = filematcher(ctx.rev())
4805 4812 else:
4806 4813 revmatchfn = None
4807 4814 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4808 4815 if displayer.flush(ctx):
4809 4816 count += 1
4810 4817
4811 4818 displayer.close()
4812 4819
4813 4820 @command('manifest',
4814 4821 [('r', 'rev', '', _('revision to display'), _('REV')),
4815 4822 ('', 'all', False, _("list files from all revisions"))]
4816 4823 + formatteropts,
4817 4824 _('[-r REV]'))
4818 4825 def manifest(ui, repo, node=None, rev=None, **opts):
4819 4826 """output the current or given revision of the project manifest
4820 4827
4821 4828 Print a list of version controlled files for the given revision.
4822 4829 If no revision is given, the first parent of the working directory
4823 4830 is used, or the null revision if no revision is checked out.
4824 4831
4825 4832 With -v, print file permissions, symlink and executable bits.
4826 4833 With --debug, print file revision hashes.
4827 4834
4828 4835 If option --all is specified, the list of all files from all revisions
4829 4836 is printed. This includes deleted and renamed files.
4830 4837
4831 4838 Returns 0 on success.
4832 4839 """
4833 4840
4834 4841 fm = ui.formatter('manifest', opts)
4835 4842
4836 4843 if opts.get('all'):
4837 4844 if rev or node:
4838 4845 raise error.Abort(_("can't specify a revision with --all"))
4839 4846
4840 4847 res = []
4841 4848 prefix = "data/"
4842 4849 suffix = ".i"
4843 4850 plen = len(prefix)
4844 4851 slen = len(suffix)
4845 4852 lock = repo.lock()
4846 4853 try:
4847 4854 for fn, b, size in repo.store.datafiles():
4848 4855 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4849 4856 res.append(fn[plen:-slen])
4850 4857 finally:
4851 4858 lock.release()
4852 4859 for f in res:
4853 4860 fm.startitem()
4854 4861 fm.write("path", '%s\n', f)
4855 4862 fm.end()
4856 4863 return
4857 4864
4858 4865 if rev and node:
4859 4866 raise error.Abort(_("please specify just one revision"))
4860 4867
4861 4868 if not node:
4862 4869 node = rev
4863 4870
4864 4871 char = {'l': '@', 'x': '*', '': ''}
4865 4872 mode = {'l': '644', 'x': '755', '': '644'}
4866 4873 ctx = scmutil.revsingle(repo, node)
4867 4874 mf = ctx.manifest()
4868 4875 for f in ctx:
4869 4876 fm.startitem()
4870 4877 fl = ctx[f].flags()
4871 4878 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4872 4879 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4873 4880 fm.write('path', '%s\n', f)
4874 4881 fm.end()
4875 4882
4876 4883 @command('^merge',
4877 4884 [('f', 'force', None,
4878 4885 _('force a merge including outstanding changes (DEPRECATED)')),
4879 4886 ('r', 'rev', '', _('revision to merge'), _('REV')),
4880 4887 ('P', 'preview', None,
4881 4888 _('review revisions to merge (no merge is performed)'))
4882 4889 ] + mergetoolopts,
4883 4890 _('[-P] [-f] [[-r] REV]'))
4884 4891 def merge(ui, repo, node=None, **opts):
4885 4892 """merge another revision into working directory
4886 4893
4887 4894 The current working directory is updated with all changes made in
4888 4895 the requested revision since the last common predecessor revision.
4889 4896
4890 4897 Files that changed between either parent are marked as changed for
4891 4898 the next commit and a commit must be performed before any further
4892 4899 updates to the repository are allowed. The next commit will have
4893 4900 two parents.
4894 4901
4895 4902 ``--tool`` can be used to specify the merge tool used for file
4896 4903 merges. It overrides the HGMERGE environment variable and your
4897 4904 configuration files. See :hg:`help merge-tools` for options.
4898 4905
4899 4906 If no revision is specified, the working directory's parent is a
4900 4907 head revision, and the current branch contains exactly one other
4901 4908 head, the other head is merged with by default. Otherwise, an
4902 4909 explicit revision with which to merge with must be provided.
4903 4910
4904 4911 :hg:`resolve` must be used to resolve unresolved files.
4905 4912
4906 4913 To undo an uncommitted merge, use :hg:`update --clean .` which
4907 4914 will check out a clean copy of the original merge parent, losing
4908 4915 all changes.
4909 4916
4910 4917 Returns 0 on success, 1 if there are unresolved files.
4911 4918 """
4912 4919
4913 4920 if opts.get('rev') and node:
4914 4921 raise error.Abort(_("please specify just one revision"))
4915 4922 if not node:
4916 4923 node = opts.get('rev')
4917 4924
4918 4925 if node:
4919 4926 node = scmutil.revsingle(repo, node).node()
4920 4927
4921 4928 if not node:
4922 4929 node = repo[destutil.destmerge(repo)].node()
4923 4930
4924 4931 if opts.get('preview'):
4925 4932 # find nodes that are ancestors of p2 but not of p1
4926 4933 p1 = repo.lookup('.')
4927 4934 p2 = repo.lookup(node)
4928 4935 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4929 4936
4930 4937 displayer = cmdutil.show_changeset(ui, repo, opts)
4931 4938 for node in nodes:
4932 4939 displayer.show(repo[node])
4933 4940 displayer.close()
4934 4941 return 0
4935 4942
4936 4943 try:
4937 4944 # ui.forcemerge is an internal variable, do not document
4938 4945 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4939 4946 return hg.merge(repo, node, force=opts.get('force'))
4940 4947 finally:
4941 4948 ui.setconfig('ui', 'forcemerge', '', 'merge')
4942 4949
4943 4950 @command('outgoing|out',
4944 4951 [('f', 'force', None, _('run even when the destination is unrelated')),
4945 4952 ('r', 'rev', [],
4946 4953 _('a changeset intended to be included in the destination'), _('REV')),
4947 4954 ('n', 'newest-first', None, _('show newest record first')),
4948 4955 ('B', 'bookmarks', False, _('compare bookmarks')),
4949 4956 ('b', 'branch', [], _('a specific branch you would like to push'),
4950 4957 _('BRANCH')),
4951 4958 ] + logopts + remoteopts + subrepoopts,
4952 4959 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4953 4960 def outgoing(ui, repo, dest=None, **opts):
4954 4961 """show changesets not found in the destination
4955 4962
4956 4963 Show changesets not found in the specified destination repository
4957 4964 or the default push location. These are the changesets that would
4958 4965 be pushed if a push was requested.
4959 4966
4960 4967 See pull for details of valid destination formats.
4961 4968
4962 4969 .. container:: verbose
4963 4970
4964 4971 With -B/--bookmarks, the result of bookmark comparison between
4965 4972 local and remote repositories is displayed. With -v/--verbose,
4966 4973 status is also displayed for each bookmark like below::
4967 4974
4968 4975 BM1 01234567890a added
4969 4976 BM2 deleted
4970 4977 BM3 234567890abc advanced
4971 4978 BM4 34567890abcd diverged
4972 4979 BM5 4567890abcde changed
4973 4980
4974 4981 The action taken when pushing depends on the
4975 4982 status of each bookmark:
4976 4983
4977 4984 :``added``: push with ``-B`` will create it
4978 4985 :``deleted``: push with ``-B`` will delete it
4979 4986 :``advanced``: push will update it
4980 4987 :``diverged``: push with ``-B`` will update it
4981 4988 :``changed``: push with ``-B`` will update it
4982 4989
4983 4990 From the point of view of pushing behavior, bookmarks
4984 4991 existing only in the remote repository are treated as
4985 4992 ``deleted``, even if it is in fact added remotely.
4986 4993
4987 4994 Returns 0 if there are outgoing changes, 1 otherwise.
4988 4995 """
4989 4996 if opts.get('graph'):
4990 4997 cmdutil.checkunsupportedgraphflags([], opts)
4991 4998 o, other = hg._outgoing(ui, repo, dest, opts)
4992 4999 if not o:
4993 5000 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4994 5001 return
4995 5002
4996 5003 revdag = cmdutil.graphrevs(repo, o, opts)
4997 5004 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4998 5005 showparents = [ctx.node() for ctx in repo[None].parents()]
4999 5006 cmdutil.displaygraph(ui, revdag, displayer, showparents,
5000 5007 graphmod.asciiedges)
5001 5008 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5002 5009 return 0
5003 5010
5004 5011 if opts.get('bookmarks'):
5005 5012 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5006 5013 dest, branches = hg.parseurl(dest, opts.get('branch'))
5007 5014 other = hg.peer(repo, opts, dest)
5008 5015 if 'bookmarks' not in other.listkeys('namespaces'):
5009 5016 ui.warn(_("remote doesn't support bookmarks\n"))
5010 5017 return 0
5011 5018 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
5012 5019 return bookmarks.outgoing(ui, repo, other)
5013 5020
5014 5021 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
5015 5022 try:
5016 5023 return hg.outgoing(ui, repo, dest, opts)
5017 5024 finally:
5018 5025 del repo._subtoppath
5019 5026
5020 5027 @command('parents',
5021 5028 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
5022 5029 ] + templateopts,
5023 5030 _('[-r REV] [FILE]'),
5024 5031 inferrepo=True)
5025 5032 def parents(ui, repo, file_=None, **opts):
5026 5033 """show the parents of the working directory or revision (DEPRECATED)
5027 5034
5028 5035 Print the working directory's parent revisions. If a revision is
5029 5036 given via -r/--rev, the parent of that revision will be printed.
5030 5037 If a file argument is given, the revision in which the file was
5031 5038 last changed (before the working directory revision or the
5032 5039 argument to --rev if given) is printed.
5033 5040
5034 5041 See :hg:`summary` and :hg:`help revsets` for related information.
5035 5042
5036 5043 Returns 0 on success.
5037 5044 """
5038 5045
5039 5046 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
5040 5047
5041 5048 if file_:
5042 5049 m = scmutil.match(ctx, (file_,), opts)
5043 5050 if m.anypats() or len(m.files()) != 1:
5044 5051 raise error.Abort(_('can only specify an explicit filename'))
5045 5052 file_ = m.files()[0]
5046 5053 filenodes = []
5047 5054 for cp in ctx.parents():
5048 5055 if not cp:
5049 5056 continue
5050 5057 try:
5051 5058 filenodes.append(cp.filenode(file_))
5052 5059 except error.LookupError:
5053 5060 pass
5054 5061 if not filenodes:
5055 5062 raise error.Abort(_("'%s' not found in manifest!") % file_)
5056 5063 p = []
5057 5064 for fn in filenodes:
5058 5065 fctx = repo.filectx(file_, fileid=fn)
5059 5066 p.append(fctx.node())
5060 5067 else:
5061 5068 p = [cp.node() for cp in ctx.parents()]
5062 5069
5063 5070 displayer = cmdutil.show_changeset(ui, repo, opts)
5064 5071 for n in p:
5065 5072 if n != nullid:
5066 5073 displayer.show(repo[n])
5067 5074 displayer.close()
5068 5075
5069 5076 @command('paths', [], _('[NAME]'), optionalrepo=True)
5070 5077 def paths(ui, repo, search=None):
5071 5078 """show aliases for remote repositories
5072 5079
5073 5080 Show definition of symbolic path name NAME. If no name is given,
5074 5081 show definition of all available names.
5075 5082
5076 5083 Option -q/--quiet suppresses all output when searching for NAME
5077 5084 and shows only the path names when listing all definitions.
5078 5085
5079 5086 Path names are defined in the [paths] section of your
5080 5087 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5081 5088 repository, ``.hg/hgrc`` is used, too.
5082 5089
5083 5090 The path names ``default`` and ``default-push`` have a special
5084 5091 meaning. When performing a push or pull operation, they are used
5085 5092 as fallbacks if no location is specified on the command-line.
5086 5093 When ``default-push`` is set, it will be used for push and
5087 5094 ``default`` will be used for pull; otherwise ``default`` is used
5088 5095 as the fallback for both. When cloning a repository, the clone
5089 5096 source is written as ``default`` in ``.hg/hgrc``. Note that
5090 5097 ``default`` and ``default-push`` apply to all inbound (e.g.
5091 5098 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
5092 5099 :hg:`bundle`) operations.
5093 5100
5094 5101 See :hg:`help urls` for more information.
5095 5102
5096 5103 Returns 0 on success.
5097 5104 """
5098 5105 if search:
5099 5106 for name, path in sorted(ui.paths.iteritems()):
5100 5107 if name == search:
5101 5108 ui.status("%s\n" % util.hidepassword(path.loc))
5102 5109 return
5103 5110 if not ui.quiet:
5104 5111 ui.warn(_("not found!\n"))
5105 5112 return 1
5106 5113 else:
5107 5114 for name, path in sorted(ui.paths.iteritems()):
5108 5115 if ui.quiet:
5109 5116 ui.write("%s\n" % name)
5110 5117 else:
5111 5118 ui.write("%s = %s\n" % (name,
5112 5119 util.hidepassword(path.loc)))
5113 5120
5114 5121 @command('phase',
5115 5122 [('p', 'public', False, _('set changeset phase to public')),
5116 5123 ('d', 'draft', False, _('set changeset phase to draft')),
5117 5124 ('s', 'secret', False, _('set changeset phase to secret')),
5118 5125 ('f', 'force', False, _('allow to move boundary backward')),
5119 5126 ('r', 'rev', [], _('target revision'), _('REV')),
5120 5127 ],
5121 5128 _('[-p|-d|-s] [-f] [-r] [REV...]'))
5122 5129 def phase(ui, repo, *revs, **opts):
5123 5130 """set or show the current phase name
5124 5131
5125 5132 With no argument, show the phase name of the current revision(s).
5126 5133
5127 5134 With one of -p/--public, -d/--draft or -s/--secret, change the
5128 5135 phase value of the specified revisions.
5129 5136
5130 5137 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5131 5138 lower phase to an higher phase. Phases are ordered as follows::
5132 5139
5133 5140 public < draft < secret
5134 5141
5135 5142 Returns 0 on success, 1 if some phases could not be changed.
5136 5143
5137 5144 (For more information about the phases concept, see :hg:`help phases`.)
5138 5145 """
5139 5146 # search for a unique phase argument
5140 5147 targetphase = None
5141 5148 for idx, name in enumerate(phases.phasenames):
5142 5149 if opts[name]:
5143 5150 if targetphase is not None:
5144 5151 raise error.Abort(_('only one phase can be specified'))
5145 5152 targetphase = idx
5146 5153
5147 5154 # look for specified revision
5148 5155 revs = list(revs)
5149 5156 revs.extend(opts['rev'])
5150 5157 if not revs:
5151 5158 # display both parents as the second parent phase can influence
5152 5159 # the phase of a merge commit
5153 5160 revs = [c.rev() for c in repo[None].parents()]
5154 5161
5155 5162 revs = scmutil.revrange(repo, revs)
5156 5163
5157 5164 lock = None
5158 5165 ret = 0
5159 5166 if targetphase is None:
5160 5167 # display
5161 5168 for r in revs:
5162 5169 ctx = repo[r]
5163 5170 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5164 5171 else:
5165 5172 tr = None
5166 5173 lock = repo.lock()
5167 5174 try:
5168 5175 tr = repo.transaction("phase")
5169 5176 # set phase
5170 5177 if not revs:
5171 5178 raise error.Abort(_('empty revision set'))
5172 5179 nodes = [repo[r].node() for r in revs]
5173 5180 # moving revision from public to draft may hide them
5174 5181 # We have to check result on an unfiltered repository
5175 5182 unfi = repo.unfiltered()
5176 5183 getphase = unfi._phasecache.phase
5177 5184 olddata = [getphase(unfi, r) for r in unfi]
5178 5185 phases.advanceboundary(repo, tr, targetphase, nodes)
5179 5186 if opts['force']:
5180 5187 phases.retractboundary(repo, tr, targetphase, nodes)
5181 5188 tr.close()
5182 5189 finally:
5183 5190 if tr is not None:
5184 5191 tr.release()
5185 5192 lock.release()
5186 5193 getphase = unfi._phasecache.phase
5187 5194 newdata = [getphase(unfi, r) for r in unfi]
5188 5195 changes = sum(newdata[r] != olddata[r] for r in unfi)
5189 5196 cl = unfi.changelog
5190 5197 rejected = [n for n in nodes
5191 5198 if newdata[cl.rev(n)] < targetphase]
5192 5199 if rejected:
5193 5200 ui.warn(_('cannot move %i changesets to a higher '
5194 5201 'phase, use --force\n') % len(rejected))
5195 5202 ret = 1
5196 5203 if changes:
5197 5204 msg = _('phase changed for %i changesets\n') % changes
5198 5205 if ret:
5199 5206 ui.status(msg)
5200 5207 else:
5201 5208 ui.note(msg)
5202 5209 else:
5203 5210 ui.warn(_('no phases changed\n'))
5204 5211 return ret
5205 5212
5206 5213 def postincoming(ui, repo, modheads, optupdate, checkout):
5207 5214 if modheads == 0:
5208 5215 return
5209 5216 if optupdate:
5210 5217 try:
5211 5218 brev = checkout
5212 5219 movemarkfrom = None
5213 5220 if not checkout:
5214 5221 updata = destutil.destupdate(repo)
5215 5222 checkout, movemarkfrom, brev = updata
5216 5223 ret = hg.update(repo, checkout)
5217 5224 except error.UpdateAbort as inst:
5218 5225 ui.warn(_("not updating: %s\n") % str(inst))
5219 5226 if inst.hint:
5220 5227 ui.warn(_("(%s)\n") % inst.hint)
5221 5228 return 0
5222 5229 if not ret and not checkout:
5223 5230 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5224 5231 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5225 5232 return ret
5226 5233 if modheads > 1:
5227 5234 currentbranchheads = len(repo.branchheads())
5228 5235 if currentbranchheads == modheads:
5229 5236 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5230 5237 elif currentbranchheads > 1:
5231 5238 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5232 5239 "merge)\n"))
5233 5240 else:
5234 5241 ui.status(_("(run 'hg heads' to see heads)\n"))
5235 5242 else:
5236 5243 ui.status(_("(run 'hg update' to get a working copy)\n"))
5237 5244
5238 5245 @command('^pull',
5239 5246 [('u', 'update', None,
5240 5247 _('update to new branch head if changesets were pulled')),
5241 5248 ('f', 'force', None, _('run even when remote repository is unrelated')),
5242 5249 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5243 5250 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5244 5251 ('b', 'branch', [], _('a specific branch you would like to pull'),
5245 5252 _('BRANCH')),
5246 5253 ] + remoteopts,
5247 5254 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5248 5255 def pull(ui, repo, source="default", **opts):
5249 5256 """pull changes from the specified source
5250 5257
5251 5258 Pull changes from a remote repository to a local one.
5252 5259
5253 5260 This finds all changes from the repository at the specified path
5254 5261 or URL and adds them to a local repository (the current one unless
5255 5262 -R is specified). By default, this does not update the copy of the
5256 5263 project in the working directory.
5257 5264
5258 5265 Use :hg:`incoming` if you want to see what would have been added
5259 5266 by a pull at the time you issued this command. If you then decide
5260 5267 to add those changes to the repository, you should use :hg:`pull
5261 5268 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5262 5269
5263 5270 If SOURCE is omitted, the 'default' path will be used.
5264 5271 See :hg:`help urls` for more information.
5265 5272
5266 5273 Returns 0 on success, 1 if an update had unresolved files.
5267 5274 """
5268 5275 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5269 5276 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5270 5277 other = hg.peer(repo, opts, source)
5271 5278 try:
5272 5279 revs, checkout = hg.addbranchrevs(repo, other, branches,
5273 5280 opts.get('rev'))
5274 5281
5275 5282
5276 5283 pullopargs = {}
5277 5284 if opts.get('bookmark'):
5278 5285 if not revs:
5279 5286 revs = []
5280 5287 # The list of bookmark used here is not the one used to actually
5281 5288 # update the bookmark name. This can result in the revision pulled
5282 5289 # not ending up with the name of the bookmark because of a race
5283 5290 # condition on the server. (See issue 4689 for details)
5284 5291 remotebookmarks = other.listkeys('bookmarks')
5285 5292 pullopargs['remotebookmarks'] = remotebookmarks
5286 5293 for b in opts['bookmark']:
5287 5294 if b not in remotebookmarks:
5288 5295 raise error.Abort(_('remote bookmark %s not found!') % b)
5289 5296 revs.append(remotebookmarks[b])
5290 5297
5291 5298 if revs:
5292 5299 try:
5293 5300 # When 'rev' is a bookmark name, we cannot guarantee that it
5294 5301 # will be updated with that name because of a race condition
5295 5302 # server side. (See issue 4689 for details)
5296 5303 oldrevs = revs
5297 5304 revs = [] # actually, nodes
5298 5305 for r in oldrevs:
5299 5306 node = other.lookup(r)
5300 5307 revs.append(node)
5301 5308 if r == checkout:
5302 5309 checkout = node
5303 5310 except error.CapabilityError:
5304 5311 err = _("other repository doesn't support revision lookup, "
5305 5312 "so a rev cannot be specified.")
5306 5313 raise error.Abort(err)
5307 5314
5308 5315 modheads = exchange.pull(repo, other, heads=revs,
5309 5316 force=opts.get('force'),
5310 5317 bookmarks=opts.get('bookmark', ()),
5311 5318 opargs=pullopargs).cgresult
5312 5319 if checkout:
5313 5320 checkout = str(repo.changelog.rev(checkout))
5314 5321 repo._subtoppath = source
5315 5322 try:
5316 5323 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5317 5324
5318 5325 finally:
5319 5326 del repo._subtoppath
5320 5327
5321 5328 finally:
5322 5329 other.close()
5323 5330 return ret
5324 5331
5325 5332 @command('^push',
5326 5333 [('f', 'force', None, _('force push')),
5327 5334 ('r', 'rev', [],
5328 5335 _('a changeset intended to be included in the destination'),
5329 5336 _('REV')),
5330 5337 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5331 5338 ('b', 'branch', [],
5332 5339 _('a specific branch you would like to push'), _('BRANCH')),
5333 5340 ('', 'new-branch', False, _('allow pushing a new branch')),
5334 5341 ] + remoteopts,
5335 5342 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5336 5343 def push(ui, repo, dest=None, **opts):
5337 5344 """push changes to the specified destination
5338 5345
5339 5346 Push changesets from the local repository to the specified
5340 5347 destination.
5341 5348
5342 5349 This operation is symmetrical to pull: it is identical to a pull
5343 5350 in the destination repository from the current one.
5344 5351
5345 5352 By default, push will not allow creation of new heads at the
5346 5353 destination, since multiple heads would make it unclear which head
5347 5354 to use. In this situation, it is recommended to pull and merge
5348 5355 before pushing.
5349 5356
5350 5357 Use --new-branch if you want to allow push to create a new named
5351 5358 branch that is not present at the destination. This allows you to
5352 5359 only create a new branch without forcing other changes.
5353 5360
5354 5361 .. note::
5355 5362
5356 5363 Extra care should be taken with the -f/--force option,
5357 5364 which will push all new heads on all branches, an action which will
5358 5365 almost always cause confusion for collaborators.
5359 5366
5360 5367 If -r/--rev is used, the specified revision and all its ancestors
5361 5368 will be pushed to the remote repository.
5362 5369
5363 5370 If -B/--bookmark is used, the specified bookmarked revision, its
5364 5371 ancestors, and the bookmark will be pushed to the remote
5365 5372 repository.
5366 5373
5367 5374 Please see :hg:`help urls` for important details about ``ssh://``
5368 5375 URLs. If DESTINATION is omitted, a default path will be used.
5369 5376
5370 5377 Returns 0 if push was successful, 1 if nothing to push.
5371 5378 """
5372 5379
5373 5380 if opts.get('bookmark'):
5374 5381 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5375 5382 for b in opts['bookmark']:
5376 5383 # translate -B options to -r so changesets get pushed
5377 5384 if b in repo._bookmarks:
5378 5385 opts.setdefault('rev', []).append(b)
5379 5386 else:
5380 5387 # if we try to push a deleted bookmark, translate it to null
5381 5388 # this lets simultaneous -r, -b options continue working
5382 5389 opts.setdefault('rev', []).append("null")
5383 5390
5384 5391 path = ui.paths.getpath(dest, default='default')
5385 5392 if not path:
5386 5393 raise error.Abort(_('default repository not configured!'),
5387 5394 hint=_('see the "path" section in "hg help config"'))
5388 5395 dest, branches = path.pushloc, (path.branch, opts.get('branch') or [])
5389 5396 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5390 5397 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5391 5398 other = hg.peer(repo, opts, dest)
5392 5399
5393 5400 if revs:
5394 5401 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5395 5402 if not revs:
5396 5403 raise error.Abort(_("specified revisions evaluate to an empty set"),
5397 5404 hint=_("use different revision arguments"))
5398 5405
5399 5406 repo._subtoppath = dest
5400 5407 try:
5401 5408 # push subrepos depth-first for coherent ordering
5402 5409 c = repo['']
5403 5410 subs = c.substate # only repos that are committed
5404 5411 for s in sorted(subs):
5405 5412 result = c.sub(s).push(opts)
5406 5413 if result == 0:
5407 5414 return not result
5408 5415 finally:
5409 5416 del repo._subtoppath
5410 5417 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5411 5418 newbranch=opts.get('new_branch'),
5412 5419 bookmarks=opts.get('bookmark', ()))
5413 5420
5414 5421 result = not pushop.cgresult
5415 5422
5416 5423 if pushop.bkresult is not None:
5417 5424 if pushop.bkresult == 2:
5418 5425 result = 2
5419 5426 elif not result and pushop.bkresult:
5420 5427 result = 2
5421 5428
5422 5429 return result
5423 5430
5424 5431 @command('recover', [])
5425 5432 def recover(ui, repo):
5426 5433 """roll back an interrupted transaction
5427 5434
5428 5435 Recover from an interrupted commit or pull.
5429 5436
5430 5437 This command tries to fix the repository status after an
5431 5438 interrupted operation. It should only be necessary when Mercurial
5432 5439 suggests it.
5433 5440
5434 5441 Returns 0 if successful, 1 if nothing to recover or verify fails.
5435 5442 """
5436 5443 if repo.recover():
5437 5444 return hg.verify(repo)
5438 5445 return 1
5439 5446
5440 5447 @command('^remove|rm',
5441 5448 [('A', 'after', None, _('record delete for missing files')),
5442 5449 ('f', 'force', None,
5443 5450 _('remove (and delete) file even if added or modified')),
5444 5451 ] + subrepoopts + walkopts,
5445 5452 _('[OPTION]... FILE...'),
5446 5453 inferrepo=True)
5447 5454 def remove(ui, repo, *pats, **opts):
5448 5455 """remove the specified files on the next commit
5449 5456
5450 5457 Schedule the indicated files for removal from the current branch.
5451 5458
5452 5459 This command schedules the files to be removed at the next commit.
5453 5460 To undo a remove before that, see :hg:`revert`. To undo added
5454 5461 files, see :hg:`forget`.
5455 5462
5456 5463 .. container:: verbose
5457 5464
5458 5465 -A/--after can be used to remove only files that have already
5459 5466 been deleted, -f/--force can be used to force deletion, and -Af
5460 5467 can be used to remove files from the next revision without
5461 5468 deleting them from the working directory.
5462 5469
5463 5470 The following table details the behavior of remove for different
5464 5471 file states (columns) and option combinations (rows). The file
5465 5472 states are Added [A], Clean [C], Modified [M] and Missing [!]
5466 5473 (as reported by :hg:`status`). The actions are Warn, Remove
5467 5474 (from branch) and Delete (from disk):
5468 5475
5469 5476 ========= == == == ==
5470 5477 opt/state A C M !
5471 5478 ========= == == == ==
5472 5479 none W RD W R
5473 5480 -f R RD RD R
5474 5481 -A W W W R
5475 5482 -Af R R R R
5476 5483 ========= == == == ==
5477 5484
5478 5485 Note that remove never deletes files in Added [A] state from the
5479 5486 working directory, not even if option --force is specified.
5480 5487
5481 5488 Returns 0 on success, 1 if any warnings encountered.
5482 5489 """
5483 5490
5484 5491 after, force = opts.get('after'), opts.get('force')
5485 5492 if not pats and not after:
5486 5493 raise error.Abort(_('no files specified'))
5487 5494
5488 5495 m = scmutil.match(repo[None], pats, opts)
5489 5496 subrepos = opts.get('subrepos')
5490 5497 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5491 5498
5492 5499 @command('rename|move|mv',
5493 5500 [('A', 'after', None, _('record a rename that has already occurred')),
5494 5501 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5495 5502 ] + walkopts + dryrunopts,
5496 5503 _('[OPTION]... SOURCE... DEST'))
5497 5504 def rename(ui, repo, *pats, **opts):
5498 5505 """rename files; equivalent of copy + remove
5499 5506
5500 5507 Mark dest as copies of sources; mark sources for deletion. If dest
5501 5508 is a directory, copies are put in that directory. If dest is a
5502 5509 file, there can only be one source.
5503 5510
5504 5511 By default, this command copies the contents of files as they
5505 5512 exist in the working directory. If invoked with -A/--after, the
5506 5513 operation is recorded, but no copying is performed.
5507 5514
5508 5515 This command takes effect at the next commit. To undo a rename
5509 5516 before that, see :hg:`revert`.
5510 5517
5511 5518 Returns 0 on success, 1 if errors are encountered.
5512 5519 """
5513 5520 wlock = repo.wlock(False)
5514 5521 try:
5515 5522 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5516 5523 finally:
5517 5524 wlock.release()
5518 5525
5519 5526 @command('resolve',
5520 5527 [('a', 'all', None, _('select all unresolved files')),
5521 5528 ('l', 'list', None, _('list state of files needing merge')),
5522 5529 ('m', 'mark', None, _('mark files as resolved')),
5523 5530 ('u', 'unmark', None, _('mark files as unresolved')),
5524 5531 ('n', 'no-status', None, _('hide status prefix'))]
5525 5532 + mergetoolopts + walkopts + formatteropts,
5526 5533 _('[OPTION]... [FILE]...'),
5527 5534 inferrepo=True)
5528 5535 def resolve(ui, repo, *pats, **opts):
5529 5536 """redo merges or set/view the merge status of files
5530 5537
5531 5538 Merges with unresolved conflicts are often the result of
5532 5539 non-interactive merging using the ``internal:merge`` configuration
5533 5540 setting, or a command-line merge tool like ``diff3``. The resolve
5534 5541 command is used to manage the files involved in a merge, after
5535 5542 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5536 5543 working directory must have two parents). See :hg:`help
5537 5544 merge-tools` for information on configuring merge tools.
5538 5545
5539 5546 The resolve command can be used in the following ways:
5540 5547
5541 5548 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5542 5549 files, discarding any previous merge attempts. Re-merging is not
5543 5550 performed for files already marked as resolved. Use ``--all/-a``
5544 5551 to select all unresolved files. ``--tool`` can be used to specify
5545 5552 the merge tool used for the given files. It overrides the HGMERGE
5546 5553 environment variable and your configuration files. Previous file
5547 5554 contents are saved with a ``.orig`` suffix.
5548 5555
5549 5556 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5550 5557 (e.g. after having manually fixed-up the files). The default is
5551 5558 to mark all unresolved files.
5552 5559
5553 5560 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5554 5561 default is to mark all resolved files.
5555 5562
5556 5563 - :hg:`resolve -l`: list files which had or still have conflicts.
5557 5564 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5558 5565
5559 5566 Note that Mercurial will not let you commit files with unresolved
5560 5567 merge conflicts. You must use :hg:`resolve -m ...` before you can
5561 5568 commit after a conflicting merge.
5562 5569
5563 5570 Returns 0 on success, 1 if any files fail a resolve attempt.
5564 5571 """
5565 5572
5566 5573 all, mark, unmark, show, nostatus = \
5567 5574 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5568 5575
5569 5576 if (show and (mark or unmark)) or (mark and unmark):
5570 5577 raise error.Abort(_("too many options specified"))
5571 5578 if pats and all:
5572 5579 raise error.Abort(_("can't specify --all and patterns"))
5573 5580 if not (all or pats or show or mark or unmark):
5574 5581 raise error.Abort(_('no files or directories specified'),
5575 5582 hint=('use --all to re-merge all unresolved files'))
5576 5583
5577 5584 if show:
5578 5585 fm = ui.formatter('resolve', opts)
5579 5586 ms = mergemod.mergestate(repo)
5580 5587 m = scmutil.match(repo[None], pats, opts)
5581 5588 for f in ms:
5582 5589 if not m(f):
5583 5590 continue
5584 5591 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved'}[ms[f]]
5585 5592 fm.startitem()
5586 5593 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5587 5594 fm.write('path', '%s\n', f, label=l)
5588 5595 fm.end()
5589 5596 return 0
5590 5597
5591 5598 wlock = repo.wlock()
5592 5599 try:
5593 5600 ms = mergemod.mergestate(repo)
5594 5601
5595 5602 if not (ms.active() or repo.dirstate.p2() != nullid):
5596 5603 raise error.Abort(
5597 5604 _('resolve command not applicable when not merging'))
5598 5605
5599 5606 m = scmutil.match(repo[None], pats, opts)
5600 5607 ret = 0
5601 5608 didwork = False
5602 5609
5603 5610 tocomplete = []
5604 5611 for f in ms:
5605 5612 if not m(f):
5606 5613 continue
5607 5614
5608 5615 didwork = True
5609 5616
5610 5617 if mark:
5611 5618 ms.mark(f, "r")
5612 5619 elif unmark:
5613 5620 ms.mark(f, "u")
5614 5621 else:
5615 5622 wctx = repo[None]
5616 5623
5617 5624 # backup pre-resolve (merge uses .orig for its own purposes)
5618 5625 a = repo.wjoin(f)
5619 5626 util.copyfile(a, a + ".resolve")
5620 5627
5621 5628 try:
5622 5629 # preresolve file
5623 5630 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5624 5631 'resolve')
5625 5632 complete, r = ms.preresolve(f, wctx)
5626 5633 if not complete:
5627 5634 tocomplete.append(f)
5628 5635 elif r:
5629 5636 ret = 1
5630 5637 finally:
5631 5638 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5632 5639 ms.commit()
5633 5640
5634 5641 # replace filemerge's .orig file with our resolve file
5635 5642 # for files in tocomplete, ms.resolve will not overwrite
5636 5643 # .orig -- only preresolve does
5637 5644 util.rename(a + ".resolve", a + ".orig")
5638 5645
5639 5646 for f in tocomplete:
5640 5647 try:
5641 5648 # resolve file
5642 5649 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5643 5650 'resolve')
5644 5651 r = ms.resolve(f, wctx)
5645 5652 if r:
5646 5653 ret = 1
5647 5654 finally:
5648 5655 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5649 5656 ms.commit()
5650 5657
5651 5658 ms.commit()
5652 5659
5653 5660 if not didwork and pats:
5654 5661 ui.warn(_("arguments do not match paths that need resolving\n"))
5655 5662
5656 5663 finally:
5657 5664 wlock.release()
5658 5665
5659 5666 # Nudge users into finishing an unfinished operation
5660 5667 if not list(ms.unresolved()):
5661 5668 ui.status(_('(no more unresolved files)\n'))
5662 5669
5663 5670 return ret
5664 5671
5665 5672 @command('revert',
5666 5673 [('a', 'all', None, _('revert all changes when no arguments given')),
5667 5674 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5668 5675 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5669 5676 ('C', 'no-backup', None, _('do not save backup copies of files')),
5670 5677 ('i', 'interactive', None,
5671 5678 _('interactively select the changes (EXPERIMENTAL)')),
5672 5679 ] + walkopts + dryrunopts,
5673 5680 _('[OPTION]... [-r REV] [NAME]...'))
5674 5681 def revert(ui, repo, *pats, **opts):
5675 5682 """restore files to their checkout state
5676 5683
5677 5684 .. note::
5678 5685
5679 5686 To check out earlier revisions, you should use :hg:`update REV`.
5680 5687 To cancel an uncommitted merge (and lose your changes),
5681 5688 use :hg:`update --clean .`.
5682 5689
5683 5690 With no revision specified, revert the specified files or directories
5684 5691 to the contents they had in the parent of the working directory.
5685 5692 This restores the contents of files to an unmodified
5686 5693 state and unschedules adds, removes, copies, and renames. If the
5687 5694 working directory has two parents, you must explicitly specify a
5688 5695 revision.
5689 5696
5690 5697 Using the -r/--rev or -d/--date options, revert the given files or
5691 5698 directories to their states as of a specific revision. Because
5692 5699 revert does not change the working directory parents, this will
5693 5700 cause these files to appear modified. This can be helpful to "back
5694 5701 out" some or all of an earlier change. See :hg:`backout` for a
5695 5702 related method.
5696 5703
5697 5704 Modified files are saved with a .orig suffix before reverting.
5698 5705 To disable these backups, use --no-backup.
5699 5706
5700 5707 See :hg:`help dates` for a list of formats valid for -d/--date.
5701 5708
5702 5709 See :hg:`help backout` for a way to reverse the effect of an
5703 5710 earlier changeset.
5704 5711
5705 5712 Returns 0 on success.
5706 5713 """
5707 5714
5708 5715 if opts.get("date"):
5709 5716 if opts.get("rev"):
5710 5717 raise error.Abort(_("you can't specify a revision and a date"))
5711 5718 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5712 5719
5713 5720 parent, p2 = repo.dirstate.parents()
5714 5721 if not opts.get('rev') and p2 != nullid:
5715 5722 # revert after merge is a trap for new users (issue2915)
5716 5723 raise error.Abort(_('uncommitted merge with no revision specified'),
5717 5724 hint=_('use "hg update" or see "hg help revert"'))
5718 5725
5719 5726 ctx = scmutil.revsingle(repo, opts.get('rev'))
5720 5727
5721 5728 if (not (pats or opts.get('include') or opts.get('exclude') or
5722 5729 opts.get('all') or opts.get('interactive'))):
5723 5730 msg = _("no files or directories specified")
5724 5731 if p2 != nullid:
5725 5732 hint = _("uncommitted merge, use --all to discard all changes,"
5726 5733 " or 'hg update -C .' to abort the merge")
5727 5734 raise error.Abort(msg, hint=hint)
5728 5735 dirty = any(repo.status())
5729 5736 node = ctx.node()
5730 5737 if node != parent:
5731 5738 if dirty:
5732 5739 hint = _("uncommitted changes, use --all to discard all"
5733 5740 " changes, or 'hg update %s' to update") % ctx.rev()
5734 5741 else:
5735 5742 hint = _("use --all to revert all files,"
5736 5743 " or 'hg update %s' to update") % ctx.rev()
5737 5744 elif dirty:
5738 5745 hint = _("uncommitted changes, use --all to discard all changes")
5739 5746 else:
5740 5747 hint = _("use --all to revert all files")
5741 5748 raise error.Abort(msg, hint=hint)
5742 5749
5743 5750 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5744 5751
5745 5752 @command('rollback', dryrunopts +
5746 5753 [('f', 'force', False, _('ignore safety measures'))])
5747 5754 def rollback(ui, repo, **opts):
5748 5755 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5749 5756
5750 5757 Please use :hg:`commit --amend` instead of rollback to correct
5751 5758 mistakes in the last commit.
5752 5759
5753 5760 This command should be used with care. There is only one level of
5754 5761 rollback, and there is no way to undo a rollback. It will also
5755 5762 restore the dirstate at the time of the last transaction, losing
5756 5763 any dirstate changes since that time. This command does not alter
5757 5764 the working directory.
5758 5765
5759 5766 Transactions are used to encapsulate the effects of all commands
5760 5767 that create new changesets or propagate existing changesets into a
5761 5768 repository.
5762 5769
5763 5770 .. container:: verbose
5764 5771
5765 5772 For example, the following commands are transactional, and their
5766 5773 effects can be rolled back:
5767 5774
5768 5775 - commit
5769 5776 - import
5770 5777 - pull
5771 5778 - push (with this repository as the destination)
5772 5779 - unbundle
5773 5780
5774 5781 To avoid permanent data loss, rollback will refuse to rollback a
5775 5782 commit transaction if it isn't checked out. Use --force to
5776 5783 override this protection.
5777 5784
5778 5785 This command is not intended for use on public repositories. Once
5779 5786 changes are visible for pull by other users, rolling a transaction
5780 5787 back locally is ineffective (someone else may already have pulled
5781 5788 the changes). Furthermore, a race is possible with readers of the
5782 5789 repository; for example an in-progress pull from the repository
5783 5790 may fail if a rollback is performed.
5784 5791
5785 5792 Returns 0 on success, 1 if no rollback data is available.
5786 5793 """
5787 5794 return repo.rollback(dryrun=opts.get('dry_run'),
5788 5795 force=opts.get('force'))
5789 5796
5790 5797 @command('root', [])
5791 5798 def root(ui, repo):
5792 5799 """print the root (top) of the current working directory
5793 5800
5794 5801 Print the root directory of the current repository.
5795 5802
5796 5803 Returns 0 on success.
5797 5804 """
5798 5805 ui.write(repo.root + "\n")
5799 5806
5800 5807 @command('^serve',
5801 5808 [('A', 'accesslog', '', _('name of access log file to write to'),
5802 5809 _('FILE')),
5803 5810 ('d', 'daemon', None, _('run server in background')),
5804 5811 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5805 5812 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5806 5813 # use string type, then we can check if something was passed
5807 5814 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5808 5815 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5809 5816 _('ADDR')),
5810 5817 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5811 5818 _('PREFIX')),
5812 5819 ('n', 'name', '',
5813 5820 _('name to show in web pages (default: working directory)'), _('NAME')),
5814 5821 ('', 'web-conf', '',
5815 5822 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5816 5823 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5817 5824 _('FILE')),
5818 5825 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5819 5826 ('', 'stdio', None, _('for remote clients')),
5820 5827 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5821 5828 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5822 5829 ('', 'style', '', _('template style to use'), _('STYLE')),
5823 5830 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5824 5831 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5825 5832 _('[OPTION]...'),
5826 5833 optionalrepo=True)
5827 5834 def serve(ui, repo, **opts):
5828 5835 """start stand-alone webserver
5829 5836
5830 5837 Start a local HTTP repository browser and pull server. You can use
5831 5838 this for ad-hoc sharing and browsing of repositories. It is
5832 5839 recommended to use a real web server to serve a repository for
5833 5840 longer periods of time.
5834 5841
5835 5842 Please note that the server does not implement access control.
5836 5843 This means that, by default, anybody can read from the server and
5837 5844 nobody can write to it by default. Set the ``web.allow_push``
5838 5845 option to ``*`` to allow everybody to push to the server. You
5839 5846 should use a real web server if you need to authenticate users.
5840 5847
5841 5848 By default, the server logs accesses to stdout and errors to
5842 5849 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5843 5850 files.
5844 5851
5845 5852 To have the server choose a free port number to listen on, specify
5846 5853 a port number of 0; in this case, the server will print the port
5847 5854 number it uses.
5848 5855
5849 5856 Returns 0 on success.
5850 5857 """
5851 5858
5852 5859 if opts["stdio"] and opts["cmdserver"]:
5853 5860 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5854 5861
5855 5862 if opts["stdio"]:
5856 5863 if repo is None:
5857 5864 raise error.RepoError(_("there is no Mercurial repository here"
5858 5865 " (.hg not found)"))
5859 5866 s = sshserver.sshserver(ui, repo)
5860 5867 s.serve_forever()
5861 5868
5862 5869 if opts["cmdserver"]:
5863 5870 import commandserver
5864 5871 service = commandserver.createservice(ui, repo, opts)
5865 5872 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5866 5873
5867 5874 # this way we can check if something was given in the command-line
5868 5875 if opts.get('port'):
5869 5876 opts['port'] = util.getport(opts.get('port'))
5870 5877
5871 5878 if repo:
5872 5879 baseui = repo.baseui
5873 5880 else:
5874 5881 baseui = ui
5875 5882 optlist = ("name templates style address port prefix ipv6"
5876 5883 " accesslog errorlog certificate encoding")
5877 5884 for o in optlist.split():
5878 5885 val = opts.get(o, '')
5879 5886 if val in (None, ''): # should check against default options instead
5880 5887 continue
5881 5888 baseui.setconfig("web", o, val, 'serve')
5882 5889 if repo and repo.ui != baseui:
5883 5890 repo.ui.setconfig("web", o, val, 'serve')
5884 5891
5885 5892 o = opts.get('web_conf') or opts.get('webdir_conf')
5886 5893 if not o:
5887 5894 if not repo:
5888 5895 raise error.RepoError(_("there is no Mercurial repository"
5889 5896 " here (.hg not found)"))
5890 5897 o = repo
5891 5898
5892 5899 app = hgweb.hgweb(o, baseui=baseui)
5893 5900 service = httpservice(ui, app, opts)
5894 5901 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5895 5902
5896 5903 class httpservice(object):
5897 5904 def __init__(self, ui, app, opts):
5898 5905 self.ui = ui
5899 5906 self.app = app
5900 5907 self.opts = opts
5901 5908
5902 5909 def init(self):
5903 5910 util.setsignalhandler()
5904 5911 self.httpd = hgweb_server.create_server(self.ui, self.app)
5905 5912
5906 5913 if self.opts['port'] and not self.ui.verbose:
5907 5914 return
5908 5915
5909 5916 if self.httpd.prefix:
5910 5917 prefix = self.httpd.prefix.strip('/') + '/'
5911 5918 else:
5912 5919 prefix = ''
5913 5920
5914 5921 port = ':%d' % self.httpd.port
5915 5922 if port == ':80':
5916 5923 port = ''
5917 5924
5918 5925 bindaddr = self.httpd.addr
5919 5926 if bindaddr == '0.0.0.0':
5920 5927 bindaddr = '*'
5921 5928 elif ':' in bindaddr: # IPv6
5922 5929 bindaddr = '[%s]' % bindaddr
5923 5930
5924 5931 fqaddr = self.httpd.fqaddr
5925 5932 if ':' in fqaddr:
5926 5933 fqaddr = '[%s]' % fqaddr
5927 5934 if self.opts['port']:
5928 5935 write = self.ui.status
5929 5936 else:
5930 5937 write = self.ui.write
5931 5938 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5932 5939 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5933 5940 self.ui.flush() # avoid buffering of status message
5934 5941
5935 5942 def run(self):
5936 5943 self.httpd.serve_forever()
5937 5944
5938 5945
5939 5946 @command('^status|st',
5940 5947 [('A', 'all', None, _('show status of all files')),
5941 5948 ('m', 'modified', None, _('show only modified files')),
5942 5949 ('a', 'added', None, _('show only added files')),
5943 5950 ('r', 'removed', None, _('show only removed files')),
5944 5951 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5945 5952 ('c', 'clean', None, _('show only files without changes')),
5946 5953 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5947 5954 ('i', 'ignored', None, _('show only ignored files')),
5948 5955 ('n', 'no-status', None, _('hide status prefix')),
5949 5956 ('C', 'copies', None, _('show source of copied files')),
5950 5957 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5951 5958 ('', 'rev', [], _('show difference from revision'), _('REV')),
5952 5959 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5953 5960 ] + walkopts + subrepoopts + formatteropts,
5954 5961 _('[OPTION]... [FILE]...'),
5955 5962 inferrepo=True)
5956 5963 def status(ui, repo, *pats, **opts):
5957 5964 """show changed files in the working directory
5958 5965
5959 5966 Show status of files in the repository. If names are given, only
5960 5967 files that match are shown. Files that are clean or ignored or
5961 5968 the source of a copy/move operation, are not listed unless
5962 5969 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5963 5970 Unless options described with "show only ..." are given, the
5964 5971 options -mardu are used.
5965 5972
5966 5973 Option -q/--quiet hides untracked (unknown and ignored) files
5967 5974 unless explicitly requested with -u/--unknown or -i/--ignored.
5968 5975
5969 5976 .. note::
5970 5977
5971 5978 status may appear to disagree with diff if permissions have
5972 5979 changed or a merge has occurred. The standard diff format does
5973 5980 not report permission changes and diff only reports changes
5974 5981 relative to one merge parent.
5975 5982
5976 5983 If one revision is given, it is used as the base revision.
5977 5984 If two revisions are given, the differences between them are
5978 5985 shown. The --change option can also be used as a shortcut to list
5979 5986 the changed files of a revision from its first parent.
5980 5987
5981 5988 The codes used to show the status of files are::
5982 5989
5983 5990 M = modified
5984 5991 A = added
5985 5992 R = removed
5986 5993 C = clean
5987 5994 ! = missing (deleted by non-hg command, but still tracked)
5988 5995 ? = not tracked
5989 5996 I = ignored
5990 5997 = origin of the previous file (with --copies)
5991 5998
5992 5999 .. container:: verbose
5993 6000
5994 6001 Examples:
5995 6002
5996 6003 - show changes in the working directory relative to a
5997 6004 changeset::
5998 6005
5999 6006 hg status --rev 9353
6000 6007
6001 6008 - show changes in the working directory relative to the
6002 6009 current directory (see :hg:`help patterns` for more information)::
6003 6010
6004 6011 hg status re:
6005 6012
6006 6013 - show all changes including copies in an existing changeset::
6007 6014
6008 6015 hg status --copies --change 9353
6009 6016
6010 6017 - get a NUL separated list of added files, suitable for xargs::
6011 6018
6012 6019 hg status -an0
6013 6020
6014 6021 Returns 0 on success.
6015 6022 """
6016 6023
6017 6024 revs = opts.get('rev')
6018 6025 change = opts.get('change')
6019 6026
6020 6027 if revs and change:
6021 6028 msg = _('cannot specify --rev and --change at the same time')
6022 6029 raise error.Abort(msg)
6023 6030 elif change:
6024 6031 node2 = scmutil.revsingle(repo, change, None).node()
6025 6032 node1 = repo[node2].p1().node()
6026 6033 else:
6027 6034 node1, node2 = scmutil.revpair(repo, revs)
6028 6035
6029 6036 if pats:
6030 6037 cwd = repo.getcwd()
6031 6038 else:
6032 6039 cwd = ''
6033 6040
6034 6041 if opts.get('print0'):
6035 6042 end = '\0'
6036 6043 else:
6037 6044 end = '\n'
6038 6045 copy = {}
6039 6046 states = 'modified added removed deleted unknown ignored clean'.split()
6040 6047 show = [k for k in states if opts.get(k)]
6041 6048 if opts.get('all'):
6042 6049 show += ui.quiet and (states[:4] + ['clean']) or states
6043 6050 if not show:
6044 6051 if ui.quiet:
6045 6052 show = states[:4]
6046 6053 else:
6047 6054 show = states[:5]
6048 6055
6049 6056 m = scmutil.match(repo[node2], pats, opts)
6050 6057 stat = repo.status(node1, node2, m,
6051 6058 'ignored' in show, 'clean' in show, 'unknown' in show,
6052 6059 opts.get('subrepos'))
6053 6060 changestates = zip(states, 'MAR!?IC', stat)
6054 6061
6055 6062 if (opts.get('all') or opts.get('copies')
6056 6063 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
6057 6064 copy = copies.pathcopies(repo[node1], repo[node2], m)
6058 6065
6059 6066 fm = ui.formatter('status', opts)
6060 6067 fmt = '%s' + end
6061 6068 showchar = not opts.get('no_status')
6062 6069
6063 6070 for state, char, files in changestates:
6064 6071 if state in show:
6065 6072 label = 'status.' + state
6066 6073 for f in files:
6067 6074 fm.startitem()
6068 6075 fm.condwrite(showchar, 'status', '%s ', char, label=label)
6069 6076 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
6070 6077 if f in copy:
6071 6078 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
6072 6079 label='status.copied')
6073 6080 fm.end()
6074 6081
6075 6082 @command('^summary|sum',
6076 6083 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
6077 6084 def summary(ui, repo, **opts):
6078 6085 """summarize working directory state
6079 6086
6080 6087 This generates a brief summary of the working directory state,
6081 6088 including parents, branch, commit status, phase and available updates.
6082 6089
6083 6090 With the --remote option, this will check the default paths for
6084 6091 incoming and outgoing changes. This can be time-consuming.
6085 6092
6086 6093 Returns 0 on success.
6087 6094 """
6088 6095
6089 6096 ctx = repo[None]
6090 6097 parents = ctx.parents()
6091 6098 pnode = parents[0].node()
6092 6099 marks = []
6093 6100
6094 6101 for p in parents:
6095 6102 # label with log.changeset (instead of log.parent) since this
6096 6103 # shows a working directory parent *changeset*:
6097 6104 # i18n: column positioning for "hg summary"
6098 6105 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
6099 6106 label='log.changeset changeset.%s' % p.phasestr())
6100 6107 ui.write(' '.join(p.tags()), label='log.tag')
6101 6108 if p.bookmarks():
6102 6109 marks.extend(p.bookmarks())
6103 6110 if p.rev() == -1:
6104 6111 if not len(repo):
6105 6112 ui.write(_(' (empty repository)'))
6106 6113 else:
6107 6114 ui.write(_(' (no revision checked out)'))
6108 6115 ui.write('\n')
6109 6116 if p.description():
6110 6117 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
6111 6118 label='log.summary')
6112 6119
6113 6120 branch = ctx.branch()
6114 6121 bheads = repo.branchheads(branch)
6115 6122 # i18n: column positioning for "hg summary"
6116 6123 m = _('branch: %s\n') % branch
6117 6124 if branch != 'default':
6118 6125 ui.write(m, label='log.branch')
6119 6126 else:
6120 6127 ui.status(m, label='log.branch')
6121 6128
6122 6129 if marks:
6123 6130 active = repo._activebookmark
6124 6131 # i18n: column positioning for "hg summary"
6125 6132 ui.write(_('bookmarks:'), label='log.bookmark')
6126 6133 if active is not None:
6127 6134 if active in marks:
6128 6135 ui.write(' *' + active, label=activebookmarklabel)
6129 6136 marks.remove(active)
6130 6137 else:
6131 6138 ui.write(' [%s]' % active, label=activebookmarklabel)
6132 6139 for m in marks:
6133 6140 ui.write(' ' + m, label='log.bookmark')
6134 6141 ui.write('\n', label='log.bookmark')
6135 6142
6136 6143 status = repo.status(unknown=True)
6137 6144
6138 6145 c = repo.dirstate.copies()
6139 6146 copied, renamed = [], []
6140 6147 for d, s in c.iteritems():
6141 6148 if s in status.removed:
6142 6149 status.removed.remove(s)
6143 6150 renamed.append(d)
6144 6151 else:
6145 6152 copied.append(d)
6146 6153 if d in status.added:
6147 6154 status.added.remove(d)
6148 6155
6149 6156 ms = mergemod.mergestate(repo)
6150 6157 unresolved = [f for f in ms if ms[f] == 'u']
6151 6158
6152 6159 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6153 6160
6154 6161 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6155 6162 (ui.label(_('%d added'), 'status.added'), status.added),
6156 6163 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6157 6164 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6158 6165 (ui.label(_('%d copied'), 'status.copied'), copied),
6159 6166 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6160 6167 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6161 6168 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6162 6169 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6163 6170 t = []
6164 6171 for l, s in labels:
6165 6172 if s:
6166 6173 t.append(l % len(s))
6167 6174
6168 6175 t = ', '.join(t)
6169 6176 cleanworkdir = False
6170 6177
6171 6178 if repo.vfs.exists('updatestate'):
6172 6179 t += _(' (interrupted update)')
6173 6180 elif len(parents) > 1:
6174 6181 t += _(' (merge)')
6175 6182 elif branch != parents[0].branch():
6176 6183 t += _(' (new branch)')
6177 6184 elif (parents[0].closesbranch() and
6178 6185 pnode in repo.branchheads(branch, closed=True)):
6179 6186 t += _(' (head closed)')
6180 6187 elif not (status.modified or status.added or status.removed or renamed or
6181 6188 copied or subs):
6182 6189 t += _(' (clean)')
6183 6190 cleanworkdir = True
6184 6191 elif pnode not in bheads:
6185 6192 t += _(' (new branch head)')
6186 6193
6187 6194 if parents:
6188 6195 pendingphase = max(p.phase() for p in parents)
6189 6196 else:
6190 6197 pendingphase = phases.public
6191 6198
6192 6199 if pendingphase > phases.newcommitphase(ui):
6193 6200 t += ' (%s)' % phases.phasenames[pendingphase]
6194 6201
6195 6202 if cleanworkdir:
6196 6203 # i18n: column positioning for "hg summary"
6197 6204 ui.status(_('commit: %s\n') % t.strip())
6198 6205 else:
6199 6206 # i18n: column positioning for "hg summary"
6200 6207 ui.write(_('commit: %s\n') % t.strip())
6201 6208
6202 6209 # all ancestors of branch heads - all ancestors of parent = new csets
6203 6210 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6204 6211 bheads))
6205 6212
6206 6213 if new == 0:
6207 6214 # i18n: column positioning for "hg summary"
6208 6215 ui.status(_('update: (current)\n'))
6209 6216 elif pnode not in bheads:
6210 6217 # i18n: column positioning for "hg summary"
6211 6218 ui.write(_('update: %d new changesets (update)\n') % new)
6212 6219 else:
6213 6220 # i18n: column positioning for "hg summary"
6214 6221 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6215 6222 (new, len(bheads)))
6216 6223
6217 6224 t = []
6218 6225 draft = len(repo.revs('draft()'))
6219 6226 if draft:
6220 6227 t.append(_('%d draft') % draft)
6221 6228 secret = len(repo.revs('secret()'))
6222 6229 if secret:
6223 6230 t.append(_('%d secret') % secret)
6224 6231
6225 6232 if draft or secret:
6226 6233 ui.status(_('phases: %s\n') % ', '.join(t))
6227 6234
6228 6235 cmdutil.summaryhooks(ui, repo)
6229 6236
6230 6237 if opts.get('remote'):
6231 6238 needsincoming, needsoutgoing = True, True
6232 6239 else:
6233 6240 needsincoming, needsoutgoing = False, False
6234 6241 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6235 6242 if i:
6236 6243 needsincoming = True
6237 6244 if o:
6238 6245 needsoutgoing = True
6239 6246 if not needsincoming and not needsoutgoing:
6240 6247 return
6241 6248
6242 6249 def getincoming():
6243 6250 source, branches = hg.parseurl(ui.expandpath('default'))
6244 6251 sbranch = branches[0]
6245 6252 try:
6246 6253 other = hg.peer(repo, {}, source)
6247 6254 except error.RepoError:
6248 6255 if opts.get('remote'):
6249 6256 raise
6250 6257 return source, sbranch, None, None, None
6251 6258 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6252 6259 if revs:
6253 6260 revs = [other.lookup(rev) for rev in revs]
6254 6261 ui.debug('comparing with %s\n' % util.hidepassword(source))
6255 6262 repo.ui.pushbuffer()
6256 6263 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6257 6264 repo.ui.popbuffer()
6258 6265 return source, sbranch, other, commoninc, commoninc[1]
6259 6266
6260 6267 if needsincoming:
6261 6268 source, sbranch, sother, commoninc, incoming = getincoming()
6262 6269 else:
6263 6270 source = sbranch = sother = commoninc = incoming = None
6264 6271
6265 6272 def getoutgoing():
6266 6273 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6267 6274 dbranch = branches[0]
6268 6275 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6269 6276 if source != dest:
6270 6277 try:
6271 6278 dother = hg.peer(repo, {}, dest)
6272 6279 except error.RepoError:
6273 6280 if opts.get('remote'):
6274 6281 raise
6275 6282 return dest, dbranch, None, None
6276 6283 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6277 6284 elif sother is None:
6278 6285 # there is no explicit destination peer, but source one is invalid
6279 6286 return dest, dbranch, None, None
6280 6287 else:
6281 6288 dother = sother
6282 6289 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6283 6290 common = None
6284 6291 else:
6285 6292 common = commoninc
6286 6293 if revs:
6287 6294 revs = [repo.lookup(rev) for rev in revs]
6288 6295 repo.ui.pushbuffer()
6289 6296 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6290 6297 commoninc=common)
6291 6298 repo.ui.popbuffer()
6292 6299 return dest, dbranch, dother, outgoing
6293 6300
6294 6301 if needsoutgoing:
6295 6302 dest, dbranch, dother, outgoing = getoutgoing()
6296 6303 else:
6297 6304 dest = dbranch = dother = outgoing = None
6298 6305
6299 6306 if opts.get('remote'):
6300 6307 t = []
6301 6308 if incoming:
6302 6309 t.append(_('1 or more incoming'))
6303 6310 o = outgoing.missing
6304 6311 if o:
6305 6312 t.append(_('%d outgoing') % len(o))
6306 6313 other = dother or sother
6307 6314 if 'bookmarks' in other.listkeys('namespaces'):
6308 6315 counts = bookmarks.summary(repo, other)
6309 6316 if counts[0] > 0:
6310 6317 t.append(_('%d incoming bookmarks') % counts[0])
6311 6318 if counts[1] > 0:
6312 6319 t.append(_('%d outgoing bookmarks') % counts[1])
6313 6320
6314 6321 if t:
6315 6322 # i18n: column positioning for "hg summary"
6316 6323 ui.write(_('remote: %s\n') % (', '.join(t)))
6317 6324 else:
6318 6325 # i18n: column positioning for "hg summary"
6319 6326 ui.status(_('remote: (synced)\n'))
6320 6327
6321 6328 cmdutil.summaryremotehooks(ui, repo, opts,
6322 6329 ((source, sbranch, sother, commoninc),
6323 6330 (dest, dbranch, dother, outgoing)))
6324 6331
6325 6332 @command('tag',
6326 6333 [('f', 'force', None, _('force tag')),
6327 6334 ('l', 'local', None, _('make the tag local')),
6328 6335 ('r', 'rev', '', _('revision to tag'), _('REV')),
6329 6336 ('', 'remove', None, _('remove a tag')),
6330 6337 # -l/--local is already there, commitopts cannot be used
6331 6338 ('e', 'edit', None, _('invoke editor on commit messages')),
6332 6339 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6333 6340 ] + commitopts2,
6334 6341 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6335 6342 def tag(ui, repo, name1, *names, **opts):
6336 6343 """add one or more tags for the current or given revision
6337 6344
6338 6345 Name a particular revision using <name>.
6339 6346
6340 6347 Tags are used to name particular revisions of the repository and are
6341 6348 very useful to compare different revisions, to go back to significant
6342 6349 earlier versions or to mark branch points as releases, etc. Changing
6343 6350 an existing tag is normally disallowed; use -f/--force to override.
6344 6351
6345 6352 If no revision is given, the parent of the working directory is
6346 6353 used.
6347 6354
6348 6355 To facilitate version control, distribution, and merging of tags,
6349 6356 they are stored as a file named ".hgtags" which is managed similarly
6350 6357 to other project files and can be hand-edited if necessary. This
6351 6358 also means that tagging creates a new commit. The file
6352 6359 ".hg/localtags" is used for local tags (not shared among
6353 6360 repositories).
6354 6361
6355 6362 Tag commits are usually made at the head of a branch. If the parent
6356 6363 of the working directory is not a branch head, :hg:`tag` aborts; use
6357 6364 -f/--force to force the tag commit to be based on a non-head
6358 6365 changeset.
6359 6366
6360 6367 See :hg:`help dates` for a list of formats valid for -d/--date.
6361 6368
6362 6369 Since tag names have priority over branch names during revision
6363 6370 lookup, using an existing branch name as a tag name is discouraged.
6364 6371
6365 6372 Returns 0 on success.
6366 6373 """
6367 6374 wlock = lock = None
6368 6375 try:
6369 6376 wlock = repo.wlock()
6370 6377 lock = repo.lock()
6371 6378 rev_ = "."
6372 6379 names = [t.strip() for t in (name1,) + names]
6373 6380 if len(names) != len(set(names)):
6374 6381 raise error.Abort(_('tag names must be unique'))
6375 6382 for n in names:
6376 6383 scmutil.checknewlabel(repo, n, 'tag')
6377 6384 if not n:
6378 6385 raise error.Abort(_('tag names cannot consist entirely of '
6379 6386 'whitespace'))
6380 6387 if opts.get('rev') and opts.get('remove'):
6381 6388 raise error.Abort(_("--rev and --remove are incompatible"))
6382 6389 if opts.get('rev'):
6383 6390 rev_ = opts['rev']
6384 6391 message = opts.get('message')
6385 6392 if opts.get('remove'):
6386 6393 if opts.get('local'):
6387 6394 expectedtype = 'local'
6388 6395 else:
6389 6396 expectedtype = 'global'
6390 6397
6391 6398 for n in names:
6392 6399 if not repo.tagtype(n):
6393 6400 raise error.Abort(_("tag '%s' does not exist") % n)
6394 6401 if repo.tagtype(n) != expectedtype:
6395 6402 if expectedtype == 'global':
6396 6403 raise error.Abort(_("tag '%s' is not a global tag") % n)
6397 6404 else:
6398 6405 raise error.Abort(_("tag '%s' is not a local tag") % n)
6399 6406 rev_ = 'null'
6400 6407 if not message:
6401 6408 # we don't translate commit messages
6402 6409 message = 'Removed tag %s' % ', '.join(names)
6403 6410 elif not opts.get('force'):
6404 6411 for n in names:
6405 6412 if n in repo.tags():
6406 6413 raise error.Abort(_("tag '%s' already exists "
6407 6414 "(use -f to force)") % n)
6408 6415 if not opts.get('local'):
6409 6416 p1, p2 = repo.dirstate.parents()
6410 6417 if p2 != nullid:
6411 6418 raise error.Abort(_('uncommitted merge'))
6412 6419 bheads = repo.branchheads()
6413 6420 if not opts.get('force') and bheads and p1 not in bheads:
6414 6421 raise error.Abort(_('not at a branch head (use -f to force)'))
6415 6422 r = scmutil.revsingle(repo, rev_).node()
6416 6423
6417 6424 if not message:
6418 6425 # we don't translate commit messages
6419 6426 message = ('Added tag %s for changeset %s' %
6420 6427 (', '.join(names), short(r)))
6421 6428
6422 6429 date = opts.get('date')
6423 6430 if date:
6424 6431 date = util.parsedate(date)
6425 6432
6426 6433 if opts.get('remove'):
6427 6434 editform = 'tag.remove'
6428 6435 else:
6429 6436 editform = 'tag.add'
6430 6437 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6431 6438
6432 6439 # don't allow tagging the null rev
6433 6440 if (not opts.get('remove') and
6434 6441 scmutil.revsingle(repo, rev_).rev() == nullrev):
6435 6442 raise error.Abort(_("cannot tag null revision"))
6436 6443
6437 6444 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6438 6445 editor=editor)
6439 6446 finally:
6440 6447 release(lock, wlock)
6441 6448
6442 6449 @command('tags', formatteropts, '')
6443 6450 def tags(ui, repo, **opts):
6444 6451 """list repository tags
6445 6452
6446 6453 This lists both regular and local tags. When the -v/--verbose
6447 6454 switch is used, a third column "local" is printed for local tags.
6448 6455
6449 6456 Returns 0 on success.
6450 6457 """
6451 6458
6452 6459 fm = ui.formatter('tags', opts)
6453 6460 hexfunc = fm.hexfunc
6454 6461 tagtype = ""
6455 6462
6456 6463 for t, n in reversed(repo.tagslist()):
6457 6464 hn = hexfunc(n)
6458 6465 label = 'tags.normal'
6459 6466 tagtype = ''
6460 6467 if repo.tagtype(t) == 'local':
6461 6468 label = 'tags.local'
6462 6469 tagtype = 'local'
6463 6470
6464 6471 fm.startitem()
6465 6472 fm.write('tag', '%s', t, label=label)
6466 6473 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6467 6474 fm.condwrite(not ui.quiet, 'rev node', fmt,
6468 6475 repo.changelog.rev(n), hn, label=label)
6469 6476 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6470 6477 tagtype, label=label)
6471 6478 fm.plain('\n')
6472 6479 fm.end()
6473 6480
6474 6481 @command('tip',
6475 6482 [('p', 'patch', None, _('show patch')),
6476 6483 ('g', 'git', None, _('use git extended diff format')),
6477 6484 ] + templateopts,
6478 6485 _('[-p] [-g]'))
6479 6486 def tip(ui, repo, **opts):
6480 6487 """show the tip revision (DEPRECATED)
6481 6488
6482 6489 The tip revision (usually just called the tip) is the changeset
6483 6490 most recently added to the repository (and therefore the most
6484 6491 recently changed head).
6485 6492
6486 6493 If you have just made a commit, that commit will be the tip. If
6487 6494 you have just pulled changes from another repository, the tip of
6488 6495 that repository becomes the current tip. The "tip" tag is special
6489 6496 and cannot be renamed or assigned to a different changeset.
6490 6497
6491 6498 This command is deprecated, please use :hg:`heads` instead.
6492 6499
6493 6500 Returns 0 on success.
6494 6501 """
6495 6502 displayer = cmdutil.show_changeset(ui, repo, opts)
6496 6503 displayer.show(repo['tip'])
6497 6504 displayer.close()
6498 6505
6499 6506 @command('unbundle',
6500 6507 [('u', 'update', None,
6501 6508 _('update to new branch head if changesets were unbundled'))],
6502 6509 _('[-u] FILE...'))
6503 6510 def unbundle(ui, repo, fname1, *fnames, **opts):
6504 6511 """apply one or more changegroup files
6505 6512
6506 6513 Apply one or more compressed changegroup files generated by the
6507 6514 bundle command.
6508 6515
6509 6516 Returns 0 on success, 1 if an update has unresolved files.
6510 6517 """
6511 6518 fnames = (fname1,) + fnames
6512 6519
6513 6520 lock = repo.lock()
6514 6521 try:
6515 6522 for fname in fnames:
6516 6523 f = hg.openpath(ui, fname)
6517 6524 gen = exchange.readbundle(ui, f, fname)
6518 6525 if isinstance(gen, bundle2.unbundle20):
6519 6526 tr = repo.transaction('unbundle')
6520 6527 try:
6521 6528 op = bundle2.processbundle(repo, gen, lambda: tr)
6522 6529 tr.close()
6523 6530 except error.BundleUnknownFeatureError as exc:
6524 6531 raise error.Abort(_('%s: unknown bundle feature, %s')
6525 6532 % (fname, exc),
6526 6533 hint=_("see https://mercurial-scm.org/"
6527 6534 "wiki/BundleFeature for more "
6528 6535 "information"))
6529 6536 finally:
6530 6537 if tr:
6531 6538 tr.release()
6532 6539 changes = [r.get('return', 0)
6533 6540 for r in op.records['changegroup']]
6534 6541 modheads = changegroup.combineresults(changes)
6542 elif isinstance(gen, streamclone.streamcloneapplier):
6543 raise error.Abort(
6544 _('packed bundles cannot be applied with '
6545 '"hg unbundle"'),
6546 hint=_('use "hg debugapplystreamclonebundle"'))
6535 6547 else:
6536 6548 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
6537 6549 finally:
6538 6550 lock.release()
6539 6551
6540 6552 return postincoming(ui, repo, modheads, opts.get('update'), None)
6541 6553
6542 6554 @command('^update|up|checkout|co',
6543 6555 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6544 6556 ('c', 'check', None,
6545 6557 _('update across branches if no uncommitted changes')),
6546 6558 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6547 6559 ('r', 'rev', '', _('revision'), _('REV'))
6548 6560 ] + mergetoolopts,
6549 6561 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6550 6562 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6551 6563 tool=None):
6552 6564 """update working directory (or switch revisions)
6553 6565
6554 6566 Update the repository's working directory to the specified
6555 6567 changeset. If no changeset is specified, update to the tip of the
6556 6568 current named branch and move the active bookmark (see :hg:`help
6557 6569 bookmarks`).
6558 6570
6559 6571 Update sets the working directory's parent revision to the specified
6560 6572 changeset (see :hg:`help parents`).
6561 6573
6562 6574 If the changeset is not a descendant or ancestor of the working
6563 6575 directory's parent, the update is aborted. With the -c/--check
6564 6576 option, the working directory is checked for uncommitted changes; if
6565 6577 none are found, the working directory is updated to the specified
6566 6578 changeset.
6567 6579
6568 6580 .. container:: verbose
6569 6581
6570 6582 The following rules apply when the working directory contains
6571 6583 uncommitted changes:
6572 6584
6573 6585 1. If neither -c/--check nor -C/--clean is specified, and if
6574 6586 the requested changeset is an ancestor or descendant of
6575 6587 the working directory's parent, the uncommitted changes
6576 6588 are merged into the requested changeset and the merged
6577 6589 result is left uncommitted. If the requested changeset is
6578 6590 not an ancestor or descendant (that is, it is on another
6579 6591 branch), the update is aborted and the uncommitted changes
6580 6592 are preserved.
6581 6593
6582 6594 2. With the -c/--check option, the update is aborted and the
6583 6595 uncommitted changes are preserved.
6584 6596
6585 6597 3. With the -C/--clean option, uncommitted changes are discarded and
6586 6598 the working directory is updated to the requested changeset.
6587 6599
6588 6600 To cancel an uncommitted merge (and lose your changes), use
6589 6601 :hg:`update --clean .`.
6590 6602
6591 6603 Use null as the changeset to remove the working directory (like
6592 6604 :hg:`clone -U`).
6593 6605
6594 6606 If you want to revert just one file to an older revision, use
6595 6607 :hg:`revert [-r REV] NAME`.
6596 6608
6597 6609 See :hg:`help dates` for a list of formats valid for -d/--date.
6598 6610
6599 6611 Returns 0 on success, 1 if there are unresolved files.
6600 6612 """
6601 6613 movemarkfrom = None
6602 6614 if rev and node:
6603 6615 raise error.Abort(_("please specify just one revision"))
6604 6616
6605 6617 if rev is None or rev == '':
6606 6618 rev = node
6607 6619
6608 6620 wlock = repo.wlock()
6609 6621 try:
6610 6622 cmdutil.clearunfinished(repo)
6611 6623
6612 6624 if date:
6613 6625 if rev is not None:
6614 6626 raise error.Abort(_("you can't specify a revision and a date"))
6615 6627 rev = cmdutil.finddate(ui, repo, date)
6616 6628
6617 6629 # if we defined a bookmark, we have to remember the original name
6618 6630 brev = rev
6619 6631 rev = scmutil.revsingle(repo, rev, rev).rev()
6620 6632
6621 6633 if check and clean:
6622 6634 raise error.Abort(_("cannot specify both -c/--check and -C/--clean")
6623 6635 )
6624 6636
6625 6637 if check:
6626 6638 cmdutil.bailifchanged(repo, merge=False)
6627 6639 if rev is None:
6628 6640 updata = destutil.destupdate(repo, clean=clean, check=check)
6629 6641 rev, movemarkfrom, brev = updata
6630 6642
6631 6643 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6632 6644
6633 6645 if clean:
6634 6646 ret = hg.clean(repo, rev)
6635 6647 else:
6636 6648 ret = hg.update(repo, rev)
6637 6649
6638 6650 if not ret and movemarkfrom:
6639 6651 if movemarkfrom == repo['.'].node():
6640 6652 pass # no-op update
6641 6653 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6642 6654 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6643 6655 else:
6644 6656 # this can happen with a non-linear update
6645 6657 ui.status(_("(leaving bookmark %s)\n") %
6646 6658 repo._activebookmark)
6647 6659 bookmarks.deactivate(repo)
6648 6660 elif brev in repo._bookmarks:
6649 6661 bookmarks.activate(repo, brev)
6650 6662 ui.status(_("(activating bookmark %s)\n") % brev)
6651 6663 elif brev:
6652 6664 if repo._activebookmark:
6653 6665 ui.status(_("(leaving bookmark %s)\n") %
6654 6666 repo._activebookmark)
6655 6667 bookmarks.deactivate(repo)
6656 6668 finally:
6657 6669 wlock.release()
6658 6670
6659 6671 return ret
6660 6672
6661 6673 @command('verify', [])
6662 6674 def verify(ui, repo):
6663 6675 """verify the integrity of the repository
6664 6676
6665 6677 Verify the integrity of the current repository.
6666 6678
6667 6679 This will perform an extensive check of the repository's
6668 6680 integrity, validating the hashes and checksums of each entry in
6669 6681 the changelog, manifest, and tracked files, as well as the
6670 6682 integrity of their crosslinks and indices.
6671 6683
6672 6684 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6673 6685 for more information about recovery from corruption of the
6674 6686 repository.
6675 6687
6676 6688 Returns 0 on success, 1 if errors are encountered.
6677 6689 """
6678 6690 return hg.verify(repo)
6679 6691
6680 6692 @command('version', [], norepo=True)
6681 6693 def version_(ui):
6682 6694 """output version and copyright information"""
6683 6695 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6684 6696 % util.version())
6685 6697 ui.status(_(
6686 6698 "(see https://mercurial-scm.org for more information)\n"
6687 6699 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6688 6700 "This is free software; see the source for copying conditions. "
6689 6701 "There is NO\nwarranty; "
6690 6702 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6691 6703 ))
6692 6704
6693 6705 ui.note(_("\nEnabled extensions:\n\n"))
6694 6706 if ui.verbose:
6695 6707 # format names and versions into columns
6696 6708 names = []
6697 6709 vers = []
6698 6710 for name, module in extensions.extensions():
6699 6711 names.append(name)
6700 6712 vers.append(extensions.moduleversion(module))
6701 6713 if names:
6702 6714 maxnamelen = max(len(n) for n in names)
6703 6715 for i, name in enumerate(names):
6704 6716 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
@@ -1,697 +1,717 b''
1 1 Setting up test
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo 0 > afile
6 6 $ hg add afile
7 7 $ hg commit -m "0.0"
8 8 $ echo 1 >> afile
9 9 $ hg commit -m "0.1"
10 10 $ echo 2 >> afile
11 11 $ hg commit -m "0.2"
12 12 $ echo 3 >> afile
13 13 $ hg commit -m "0.3"
14 14 $ hg update -C 0
15 15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 16 $ echo 1 >> afile
17 17 $ hg commit -m "1.1"
18 18 created new head
19 19 $ echo 2 >> afile
20 20 $ hg commit -m "1.2"
21 21 $ echo "a line" > fred
22 22 $ echo 3 >> afile
23 23 $ hg add fred
24 24 $ hg commit -m "1.3"
25 25 $ hg mv afile adifferentfile
26 26 $ hg commit -m "1.3m"
27 27 $ hg update -C 3
28 28 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
29 29 $ hg mv afile anotherfile
30 30 $ hg commit -m "0.3m"
31 31 $ hg verify
32 32 checking changesets
33 33 checking manifests
34 34 crosschecking files in changesets and manifests
35 35 checking files
36 36 4 files, 9 changesets, 7 total revisions
37 37 $ cd ..
38 38 $ hg init empty
39 39
40 40 Bundle and phase
41 41
42 42 $ hg -R test phase --force --secret 0
43 43 $ hg -R test bundle phase.hg empty
44 44 searching for changes
45 45 no changes found (ignored 9 secret changesets)
46 46 [1]
47 47 $ hg -R test phase --draft -r 'head()'
48 48
49 49 Bundle --all
50 50
51 51 $ hg -R test bundle --all all.hg
52 52 9 changesets found
53 53
54 54 Bundle test to full.hg
55 55
56 56 $ hg -R test bundle full.hg empty
57 57 searching for changes
58 58 9 changesets found
59 59
60 60 Unbundle full.hg in test
61 61
62 62 $ hg -R test unbundle full.hg
63 63 adding changesets
64 64 adding manifests
65 65 adding file changes
66 66 added 0 changesets with 0 changes to 4 files
67 67 (run 'hg update' to get a working copy)
68 68
69 69 Verify empty
70 70
71 71 $ hg -R empty heads
72 72 [1]
73 73 $ hg -R empty verify
74 74 checking changesets
75 75 checking manifests
76 76 crosschecking files in changesets and manifests
77 77 checking files
78 78 0 files, 0 changesets, 0 total revisions
79 79
80 80 Pull full.hg into test (using --cwd)
81 81
82 82 $ hg --cwd test pull ../full.hg
83 83 pulling from ../full.hg
84 84 searching for changes
85 85 no changes found
86 86
87 87 Verify that there are no leaked temporary files after pull (issue2797)
88 88
89 89 $ ls test/.hg | grep .hg10un
90 90 [1]
91 91
92 92 Pull full.hg into empty (using --cwd)
93 93
94 94 $ hg --cwd empty pull ../full.hg
95 95 pulling from ../full.hg
96 96 requesting all changes
97 97 adding changesets
98 98 adding manifests
99 99 adding file changes
100 100 added 9 changesets with 7 changes to 4 files (+1 heads)
101 101 (run 'hg heads' to see heads, 'hg merge' to merge)
102 102
103 103 Rollback empty
104 104
105 105 $ hg -R empty rollback
106 106 repository tip rolled back to revision -1 (undo pull)
107 107
108 108 Pull full.hg into empty again (using --cwd)
109 109
110 110 $ hg --cwd empty pull ../full.hg
111 111 pulling from ../full.hg
112 112 requesting all changes
113 113 adding changesets
114 114 adding manifests
115 115 adding file changes
116 116 added 9 changesets with 7 changes to 4 files (+1 heads)
117 117 (run 'hg heads' to see heads, 'hg merge' to merge)
118 118
119 119 Pull full.hg into test (using -R)
120 120
121 121 $ hg -R test pull full.hg
122 122 pulling from full.hg
123 123 searching for changes
124 124 no changes found
125 125
126 126 Pull full.hg into empty (using -R)
127 127
128 128 $ hg -R empty pull full.hg
129 129 pulling from full.hg
130 130 searching for changes
131 131 no changes found
132 132
133 133 Rollback empty
134 134
135 135 $ hg -R empty rollback
136 136 repository tip rolled back to revision -1 (undo pull)
137 137
138 138 Pull full.hg into empty again (using -R)
139 139
140 140 $ hg -R empty pull full.hg
141 141 pulling from full.hg
142 142 requesting all changes
143 143 adding changesets
144 144 adding manifests
145 145 adding file changes
146 146 added 9 changesets with 7 changes to 4 files (+1 heads)
147 147 (run 'hg heads' to see heads, 'hg merge' to merge)
148 148
149 149 Log -R full.hg in fresh empty
150 150
151 151 $ rm -r empty
152 152 $ hg init empty
153 153 $ cd empty
154 154 $ hg -R bundle://../full.hg log
155 155 changeset: 8:aa35859c02ea
156 156 tag: tip
157 157 parent: 3:eebf5a27f8ca
158 158 user: test
159 159 date: Thu Jan 01 00:00:00 1970 +0000
160 160 summary: 0.3m
161 161
162 162 changeset: 7:a6a34bfa0076
163 163 user: test
164 164 date: Thu Jan 01 00:00:00 1970 +0000
165 165 summary: 1.3m
166 166
167 167 changeset: 6:7373c1169842
168 168 user: test
169 169 date: Thu Jan 01 00:00:00 1970 +0000
170 170 summary: 1.3
171 171
172 172 changeset: 5:1bb50a9436a7
173 173 user: test
174 174 date: Thu Jan 01 00:00:00 1970 +0000
175 175 summary: 1.2
176 176
177 177 changeset: 4:095197eb4973
178 178 parent: 0:f9ee2f85a263
179 179 user: test
180 180 date: Thu Jan 01 00:00:00 1970 +0000
181 181 summary: 1.1
182 182
183 183 changeset: 3:eebf5a27f8ca
184 184 user: test
185 185 date: Thu Jan 01 00:00:00 1970 +0000
186 186 summary: 0.3
187 187
188 188 changeset: 2:e38ba6f5b7e0
189 189 user: test
190 190 date: Thu Jan 01 00:00:00 1970 +0000
191 191 summary: 0.2
192 192
193 193 changeset: 1:34c2bf6b0626
194 194 user: test
195 195 date: Thu Jan 01 00:00:00 1970 +0000
196 196 summary: 0.1
197 197
198 198 changeset: 0:f9ee2f85a263
199 199 user: test
200 200 date: Thu Jan 01 00:00:00 1970 +0000
201 201 summary: 0.0
202 202
203 203 Make sure bundlerepo doesn't leak tempfiles (issue2491)
204 204
205 205 $ ls .hg
206 206 00changelog.i
207 207 cache
208 208 requires
209 209 store
210 210
211 211 Pull ../full.hg into empty (with hook)
212 212
213 213 $ echo "[hooks]" >> .hg/hgrc
214 214 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
215 215
216 216 doesn't work (yet ?)
217 217
218 218 hg -R bundle://../full.hg verify
219 219
220 220 $ hg pull bundle://../full.hg
221 221 pulling from bundle:../full.hg
222 222 requesting all changes
223 223 adding changesets
224 224 adding manifests
225 225 adding file changes
226 226 added 9 changesets with 7 changes to 4 files (+1 heads)
227 227 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
228 228 (run 'hg heads' to see heads, 'hg merge' to merge)
229 229
230 230 Rollback empty
231 231
232 232 $ hg rollback
233 233 repository tip rolled back to revision -1 (undo pull)
234 234 $ cd ..
235 235
236 236 Log -R bundle:empty+full.hg
237 237
238 238 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
239 239 8 7 6 5 4 3 2 1 0
240 240
241 241 Pull full.hg into empty again (using -R; with hook)
242 242
243 243 $ hg -R empty pull full.hg
244 244 pulling from full.hg
245 245 requesting all changes
246 246 adding changesets
247 247 adding manifests
248 248 adding file changes
249 249 added 9 changesets with 7 changes to 4 files (+1 heads)
250 250 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
251 251 (run 'hg heads' to see heads, 'hg merge' to merge)
252 252
253 253 Cannot produce streaming clone bundles with "hg bundle"
254 254
255 255 $ hg -R test bundle -t packed1 packed.hg
256 256 abort: packed bundles cannot be produced by "hg bundle"
257 257 (use "hg debugcreatestreamclonebundle")
258 258 [255]
259 259
260 260 packed1 is produced properly
261 261
262 262 $ hg -R test debugcreatestreamclonebundle packed.hg
263 263 writing 2608 bytes for 6 files
264 264 bundle requirements: revlogv1
265 265
266 266 $ f -B 64 --size --sha1 --hexdump packed.hg
267 267 packed.hg: size=2758, sha1=864c1c7b490bac9f2950ef5a660668378ac0524e
268 268 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
269 269 0010: 00 00 00 00 0a 30 00 09 72 65 76 6c 6f 67 76 31 |.....0..revlogv1|
270 270 0020: 00 64 61 74 61 2f 61 64 69 66 66 65 72 65 6e 74 |.data/adifferent|
271 271 0030: 66 69 6c 65 2e 69 00 31 33 39 0a 00 01 00 01 00 |file.i.139......|
272 272
273 273 generaldelta requirement is listed in stream clone bundles
274 274
275 275 $ hg --config format.generaldelta=true init testgd
276 276 $ cd testgd
277 277 $ touch foo
278 278 $ hg -q commit -A -m initial
279 279 $ cd ..
280 280 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
281 281 writing 301 bytes for 3 files
282 282 bundle requirements: generaldelta, revlogv1
283 283
284 284 $ f -B 64 --size --sha1 --hexdump packedgd.hg
285 285 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
286 286 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
287 287 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
288 288 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
289 289 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
290 290
291 Unpacking packed1 bundles with "hg unbundle" isn't allowed
292
293 $ hg init packed
294 $ hg -R packed unbundle packed.hg
295 abort: packed bundles cannot be applied with "hg unbundle"
296 (use "hg debugapplystreamclonebundle")
297 [255]
298
299 packed1 can be consumed from debug command
300
301 $ hg -R packed debugapplystreamclonebundle packed.hg
302 6 files to transfer, 2.55 KB of data
303 transferred 2.55 KB in *.* seconds (*) (glob)
304
305 Does not work on non-empty repo
306
307 $ hg -R packed debugapplystreamclonebundle packed.hg
308 abort: cannot apply stream clone bundle on non-empty repo
309 [255]
310
291 311 Create partial clones
292 312
293 313 $ rm -r empty
294 314 $ hg init empty
295 315 $ hg clone -r 3 test partial
296 316 adding changesets
297 317 adding manifests
298 318 adding file changes
299 319 added 4 changesets with 4 changes to 1 files
300 320 updating to branch default
301 321 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 322 $ hg clone partial partial2
303 323 updating to branch default
304 324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
305 325 $ cd partial
306 326
307 327 Log -R full.hg in partial
308 328
309 329 $ hg -R bundle://../full.hg log -T phases
310 330 changeset: 8:aa35859c02ea
311 331 tag: tip
312 332 phase: draft
313 333 parent: 3:eebf5a27f8ca
314 334 user: test
315 335 date: Thu Jan 01 00:00:00 1970 +0000
316 336 summary: 0.3m
317 337
318 338 changeset: 7:a6a34bfa0076
319 339 phase: draft
320 340 user: test
321 341 date: Thu Jan 01 00:00:00 1970 +0000
322 342 summary: 1.3m
323 343
324 344 changeset: 6:7373c1169842
325 345 phase: draft
326 346 user: test
327 347 date: Thu Jan 01 00:00:00 1970 +0000
328 348 summary: 1.3
329 349
330 350 changeset: 5:1bb50a9436a7
331 351 phase: draft
332 352 user: test
333 353 date: Thu Jan 01 00:00:00 1970 +0000
334 354 summary: 1.2
335 355
336 356 changeset: 4:095197eb4973
337 357 phase: draft
338 358 parent: 0:f9ee2f85a263
339 359 user: test
340 360 date: Thu Jan 01 00:00:00 1970 +0000
341 361 summary: 1.1
342 362
343 363 changeset: 3:eebf5a27f8ca
344 364 phase: public
345 365 user: test
346 366 date: Thu Jan 01 00:00:00 1970 +0000
347 367 summary: 0.3
348 368
349 369 changeset: 2:e38ba6f5b7e0
350 370 phase: public
351 371 user: test
352 372 date: Thu Jan 01 00:00:00 1970 +0000
353 373 summary: 0.2
354 374
355 375 changeset: 1:34c2bf6b0626
356 376 phase: public
357 377 user: test
358 378 date: Thu Jan 01 00:00:00 1970 +0000
359 379 summary: 0.1
360 380
361 381 changeset: 0:f9ee2f85a263
362 382 phase: public
363 383 user: test
364 384 date: Thu Jan 01 00:00:00 1970 +0000
365 385 summary: 0.0
366 386
367 387
368 388 Incoming full.hg in partial
369 389
370 390 $ hg incoming bundle://../full.hg
371 391 comparing with bundle:../full.hg
372 392 searching for changes
373 393 changeset: 4:095197eb4973
374 394 parent: 0:f9ee2f85a263
375 395 user: test
376 396 date: Thu Jan 01 00:00:00 1970 +0000
377 397 summary: 1.1
378 398
379 399 changeset: 5:1bb50a9436a7
380 400 user: test
381 401 date: Thu Jan 01 00:00:00 1970 +0000
382 402 summary: 1.2
383 403
384 404 changeset: 6:7373c1169842
385 405 user: test
386 406 date: Thu Jan 01 00:00:00 1970 +0000
387 407 summary: 1.3
388 408
389 409 changeset: 7:a6a34bfa0076
390 410 user: test
391 411 date: Thu Jan 01 00:00:00 1970 +0000
392 412 summary: 1.3m
393 413
394 414 changeset: 8:aa35859c02ea
395 415 tag: tip
396 416 parent: 3:eebf5a27f8ca
397 417 user: test
398 418 date: Thu Jan 01 00:00:00 1970 +0000
399 419 summary: 0.3m
400 420
401 421
402 422 Outgoing -R full.hg vs partial2 in partial
403 423
404 424 $ hg -R bundle://../full.hg outgoing ../partial2
405 425 comparing with ../partial2
406 426 searching for changes
407 427 changeset: 4:095197eb4973
408 428 parent: 0:f9ee2f85a263
409 429 user: test
410 430 date: Thu Jan 01 00:00:00 1970 +0000
411 431 summary: 1.1
412 432
413 433 changeset: 5:1bb50a9436a7
414 434 user: test
415 435 date: Thu Jan 01 00:00:00 1970 +0000
416 436 summary: 1.2
417 437
418 438 changeset: 6:7373c1169842
419 439 user: test
420 440 date: Thu Jan 01 00:00:00 1970 +0000
421 441 summary: 1.3
422 442
423 443 changeset: 7:a6a34bfa0076
424 444 user: test
425 445 date: Thu Jan 01 00:00:00 1970 +0000
426 446 summary: 1.3m
427 447
428 448 changeset: 8:aa35859c02ea
429 449 tag: tip
430 450 parent: 3:eebf5a27f8ca
431 451 user: test
432 452 date: Thu Jan 01 00:00:00 1970 +0000
433 453 summary: 0.3m
434 454
435 455
436 456 Outgoing -R does-not-exist.hg vs partial2 in partial
437 457
438 458 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
439 459 abort: *../does-not-exist.hg* (glob)
440 460 [255]
441 461 $ cd ..
442 462
443 463 hide outer repo
444 464 $ hg init
445 465
446 466 Direct clone from bundle (all-history)
447 467
448 468 $ hg clone full.hg full-clone
449 469 requesting all changes
450 470 adding changesets
451 471 adding manifests
452 472 adding file changes
453 473 added 9 changesets with 7 changes to 4 files (+1 heads)
454 474 updating to branch default
455 475 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 476 $ hg -R full-clone heads
457 477 changeset: 8:aa35859c02ea
458 478 tag: tip
459 479 parent: 3:eebf5a27f8ca
460 480 user: test
461 481 date: Thu Jan 01 00:00:00 1970 +0000
462 482 summary: 0.3m
463 483
464 484 changeset: 7:a6a34bfa0076
465 485 user: test
466 486 date: Thu Jan 01 00:00:00 1970 +0000
467 487 summary: 1.3m
468 488
469 489 $ rm -r full-clone
470 490
471 491 When cloning from a non-copiable repository into '', do not
472 492 recurse infinitely (issue2528)
473 493
474 494 $ hg clone full.hg ''
475 495 abort: empty destination path is not valid
476 496 [255]
477 497
478 498 test for https://bz.mercurial-scm.org/216
479 499
480 500 Unbundle incremental bundles into fresh empty in one go
481 501
482 502 $ rm -r empty
483 503 $ hg init empty
484 504 $ hg -R test bundle --base null -r 0 ../0.hg
485 505 1 changesets found
486 506 $ hg -R test bundle --base 0 -r 1 ../1.hg
487 507 1 changesets found
488 508 $ hg -R empty unbundle -u ../0.hg ../1.hg
489 509 adding changesets
490 510 adding manifests
491 511 adding file changes
492 512 added 1 changesets with 1 changes to 1 files
493 513 adding changesets
494 514 adding manifests
495 515 adding file changes
496 516 added 1 changesets with 1 changes to 1 files
497 517 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 518
499 519 View full contents of the bundle
500 520 $ hg -R test bundle --base null -r 3 ../partial.hg
501 521 4 changesets found
502 522 $ cd test
503 523 $ hg -R ../../partial.hg log -r "bundle()"
504 524 changeset: 0:f9ee2f85a263
505 525 user: test
506 526 date: Thu Jan 01 00:00:00 1970 +0000
507 527 summary: 0.0
508 528
509 529 changeset: 1:34c2bf6b0626
510 530 user: test
511 531 date: Thu Jan 01 00:00:00 1970 +0000
512 532 summary: 0.1
513 533
514 534 changeset: 2:e38ba6f5b7e0
515 535 user: test
516 536 date: Thu Jan 01 00:00:00 1970 +0000
517 537 summary: 0.2
518 538
519 539 changeset: 3:eebf5a27f8ca
520 540 user: test
521 541 date: Thu Jan 01 00:00:00 1970 +0000
522 542 summary: 0.3
523 543
524 544 $ cd ..
525 545
526 546 test for 540d1059c802
527 547
528 548 test for 540d1059c802
529 549
530 550 $ hg init orig
531 551 $ cd orig
532 552 $ echo foo > foo
533 553 $ hg add foo
534 554 $ hg ci -m 'add foo'
535 555
536 556 $ hg clone . ../copy
537 557 updating to branch default
538 558 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
539 559 $ hg tag foo
540 560
541 561 $ cd ../copy
542 562 $ echo >> foo
543 563 $ hg ci -m 'change foo'
544 564 $ hg bundle ../bundle.hg ../orig
545 565 searching for changes
546 566 1 changesets found
547 567
548 568 $ cd ../orig
549 569 $ hg incoming ../bundle.hg
550 570 comparing with ../bundle.hg
551 571 searching for changes
552 572 changeset: 2:ed1b79f46b9a
553 573 tag: tip
554 574 parent: 0:bbd179dfa0a7
555 575 user: test
556 576 date: Thu Jan 01 00:00:00 1970 +0000
557 577 summary: change foo
558 578
559 579 $ cd ..
560 580
561 581 test bundle with # in the filename (issue2154):
562 582
563 583 $ cp bundle.hg 'test#bundle.hg'
564 584 $ cd orig
565 585 $ hg incoming '../test#bundle.hg'
566 586 comparing with ../test
567 587 abort: unknown revision 'bundle.hg'!
568 588 [255]
569 589
570 590 note that percent encoding is not handled:
571 591
572 592 $ hg incoming ../test%23bundle.hg
573 593 abort: repository ../test%23bundle.hg not found!
574 594 [255]
575 595 $ cd ..
576 596
577 597 test to bundle revisions on the newly created branch (issue3828):
578 598
579 599 $ hg -q clone -U test test-clone
580 600 $ cd test
581 601
582 602 $ hg -q branch foo
583 603 $ hg commit -m "create foo branch"
584 604 $ hg -q outgoing ../test-clone
585 605 9:b4f5acb1ee27
586 606 $ hg -q bundle --branch foo foo.hg ../test-clone
587 607 $ hg -R foo.hg -q log -r "bundle()"
588 608 9:b4f5acb1ee27
589 609
590 610 $ cd ..
591 611
592 612 test for https://bz.mercurial-scm.org/1144
593 613
594 614 test that verify bundle does not traceback
595 615
596 616 partial history bundle, fails w/ unknown parent
597 617
598 618 $ hg -R bundle.hg verify
599 619 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
600 620 [255]
601 621
602 622 full history bundle, refuses to verify non-local repo
603 623
604 624 $ hg -R all.hg verify
605 625 abort: cannot verify bundle or remote repos
606 626 [255]
607 627
608 628 but, regular verify must continue to work
609 629
610 630 $ hg -R orig verify
611 631 checking changesets
612 632 checking manifests
613 633 crosschecking files in changesets and manifests
614 634 checking files
615 635 2 files, 2 changesets, 2 total revisions
616 636
617 637 diff against bundle
618 638
619 639 $ hg init b
620 640 $ cd b
621 641 $ hg -R ../all.hg diff -r tip
622 642 diff -r aa35859c02ea anotherfile
623 643 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
624 644 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
625 645 @@ -1,4 +0,0 @@
626 646 -0
627 647 -1
628 648 -2
629 649 -3
630 650 $ cd ..
631 651
632 652 bundle single branch
633 653
634 654 $ hg init branchy
635 655 $ cd branchy
636 656 $ echo a >a
637 657 $ echo x >x
638 658 $ hg ci -Ama
639 659 adding a
640 660 adding x
641 661 $ echo c >c
642 662 $ echo xx >x
643 663 $ hg ci -Amc
644 664 adding c
645 665 $ echo c1 >c1
646 666 $ hg ci -Amc1
647 667 adding c1
648 668 $ hg up 0
649 669 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
650 670 $ echo b >b
651 671 $ hg ci -Amb
652 672 adding b
653 673 created new head
654 674 $ echo b1 >b1
655 675 $ echo xx >x
656 676 $ hg ci -Amb1
657 677 adding b1
658 678 $ hg clone -q -r2 . part
659 679
660 680 == bundling via incoming
661 681
662 682 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
663 683 comparing with .
664 684 searching for changes
665 685 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
666 686 057f4db07f61970e1c11e83be79e9d08adc4dc31
667 687
668 688 == bundling
669 689
670 690 $ hg bundle bundle.hg part --debug --config progress.debug=true
671 691 query 1; heads
672 692 searching for changes
673 693 all remote heads known locally
674 694 2 changesets found
675 695 list of changesets:
676 696 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
677 697 057f4db07f61970e1c11e83be79e9d08adc4dc31
678 698 bundling: 1/2 changesets (50.00%)
679 699 bundling: 2/2 changesets (100.00%)
680 700 bundling: 1/2 manifests (50.00%)
681 701 bundling: 2/2 manifests (100.00%)
682 702 bundling: b 1/3 files (33.33%)
683 703 bundling: b1 2/3 files (66.67%)
684 704 bundling: x 3/3 files (100.00%)
685 705
686 706 == Test for issue3441
687 707
688 708 $ hg clone -q -r0 . part2
689 709 $ hg -q -R part2 pull bundle.hg
690 710 $ hg -R part2 verify
691 711 checking changesets
692 712 checking manifests
693 713 crosschecking files in changesets and manifests
694 714 checking files
695 715 4 files, 3 changesets, 5 total revisions
696 716
697 717 $ cd ..
@@ -1,346 +1,348 b''
1 1 Show all commands except debug commands
2 2 $ hg debugcomplete
3 3 add
4 4 addremove
5 5 annotate
6 6 archive
7 7 backout
8 8 bisect
9 9 bookmarks
10 10 branch
11 11 branches
12 12 bundle
13 13 cat
14 14 clone
15 15 commit
16 16 config
17 17 copy
18 18 diff
19 19 export
20 20 files
21 21 forget
22 22 graft
23 23 grep
24 24 heads
25 25 help
26 26 identify
27 27 import
28 28 incoming
29 29 init
30 30 locate
31 31 log
32 32 manifest
33 33 merge
34 34 outgoing
35 35 parents
36 36 paths
37 37 phase
38 38 pull
39 39 push
40 40 recover
41 41 remove
42 42 rename
43 43 resolve
44 44 revert
45 45 rollback
46 46 root
47 47 serve
48 48 status
49 49 summary
50 50 tag
51 51 tags
52 52 tip
53 53 unbundle
54 54 update
55 55 verify
56 56 version
57 57
58 58 Show all commands that start with "a"
59 59 $ hg debugcomplete a
60 60 add
61 61 addremove
62 62 annotate
63 63 archive
64 64
65 65 Do not show debug commands if there are other candidates
66 66 $ hg debugcomplete d
67 67 diff
68 68
69 69 Show debug commands if there are no other candidates
70 70 $ hg debugcomplete debug
71 71 debugancestor
72 debugapplystreamclonebundle
72 73 debugbuilddag
73 74 debugbundle
74 75 debugcheckstate
75 76 debugcommands
76 77 debugcomplete
77 78 debugconfig
78 79 debugcreatestreamclonebundle
79 80 debugdag
80 81 debugdata
81 82 debugdate
82 83 debugdirstate
83 84 debugdiscovery
84 85 debugextensions
85 86 debugfileset
86 87 debugfsinfo
87 88 debuggetbundle
88 89 debugignore
89 90 debugindex
90 91 debugindexdot
91 92 debuginstall
92 93 debugknown
93 94 debuglabelcomplete
94 95 debuglocks
95 96 debugmergestate
96 97 debugnamecomplete
97 98 debugobsolete
98 99 debugpathcomplete
99 100 debugpushkey
100 101 debugpvec
101 102 debugrebuilddirstate
102 103 debugrebuildfncache
103 104 debugrename
104 105 debugrevlog
105 106 debugrevspec
106 107 debugsetparents
107 108 debugsub
108 109 debugsuccessorssets
109 110 debugwalk
110 111 debugwireargs
111 112
112 113 Do not show the alias of a debug command if there are other candidates
113 114 (this should hide rawcommit)
114 115 $ hg debugcomplete r
115 116 recover
116 117 remove
117 118 rename
118 119 resolve
119 120 revert
120 121 rollback
121 122 root
122 123 Show the alias of a debug command if there are no other candidates
123 124 $ hg debugcomplete rawc
124 125
125 126
126 127 Show the global options
127 128 $ hg debugcomplete --options | sort
128 129 --config
129 130 --cwd
130 131 --debug
131 132 --debugger
132 133 --encoding
133 134 --encodingmode
134 135 --help
135 136 --hidden
136 137 --noninteractive
137 138 --profile
138 139 --quiet
139 140 --repository
140 141 --time
141 142 --traceback
142 143 --verbose
143 144 --version
144 145 -R
145 146 -h
146 147 -q
147 148 -v
148 149 -y
149 150
150 151 Show the options for the "serve" command
151 152 $ hg debugcomplete --options serve | sort
152 153 --accesslog
153 154 --address
154 155 --certificate
155 156 --cmdserver
156 157 --config
157 158 --cwd
158 159 --daemon
159 160 --daemon-pipefds
160 161 --debug
161 162 --debugger
162 163 --encoding
163 164 --encodingmode
164 165 --errorlog
165 166 --help
166 167 --hidden
167 168 --ipv6
168 169 --name
169 170 --noninteractive
170 171 --pid-file
171 172 --port
172 173 --prefix
173 174 --profile
174 175 --quiet
175 176 --repository
176 177 --stdio
177 178 --style
178 179 --templates
179 180 --time
180 181 --traceback
181 182 --verbose
182 183 --version
183 184 --web-conf
184 185 -6
185 186 -A
186 187 -E
187 188 -R
188 189 -a
189 190 -d
190 191 -h
191 192 -n
192 193 -p
193 194 -q
194 195 -t
195 196 -v
196 197 -y
197 198
198 199 Show an error if we use --options with an ambiguous abbreviation
199 200 $ hg debugcomplete --options s
200 201 hg: command 's' is ambiguous:
201 202 serve showconfig status summary
202 203 [255]
203 204
204 205 Show all commands + options
205 206 $ hg debugcommands
206 207 add: include, exclude, subrepos, dry-run
207 208 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude, template
208 209 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
209 210 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
210 211 diff: rev, change, text, git, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, root, include, exclude, subrepos
211 212 export: output, switch-parent, rev, text, git, nodates
212 213 forget: include, exclude
213 214 init: ssh, remotecmd, insecure
214 215 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
215 216 merge: force, rev, preview, tool
216 217 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
217 218 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
218 219 remove: after, force, subrepos, include, exclude
219 220 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
220 221 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
221 222 summary: remote
222 223 update: clean, check, date, rev, tool
223 224 addremove: similarity, subrepos, include, exclude, dry-run
224 225 archive: no-decode, prefix, rev, type, subrepos, include, exclude
225 226 backout: merge, commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
226 227 bisect: reset, good, bad, skip, extend, command, noupdate
227 228 bookmarks: force, rev, delete, rename, inactive, template
228 229 branch: force, clean
229 230 branches: active, closed, template
230 231 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
231 232 cat: output, rev, decode, include, exclude
232 233 config: untrusted, edit, local, global
233 234 copy: after, force, include, exclude, dry-run
234 235 debugancestor:
236 debugapplystreamclonebundle:
235 237 debugbuilddag: mergeable-file, overwritten-file, new-file
236 238 debugbundle: all
237 239 debugcheckstate:
238 240 debugcommands:
239 241 debugcomplete: options
240 242 debugcreatestreamclonebundle:
241 243 debugdag: tags, branches, dots, spaces
242 244 debugdata: changelog, manifest, dir
243 245 debugdate: extended
244 246 debugdirstate: nodates, datesort
245 247 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
246 248 debugextensions: template
247 249 debugfileset: rev
248 250 debugfsinfo:
249 251 debuggetbundle: head, common, type
250 252 debugignore:
251 253 debugindex: changelog, manifest, dir, format
252 254 debugindexdot:
253 255 debuginstall:
254 256 debugknown:
255 257 debuglabelcomplete:
256 258 debuglocks: force-lock, force-wlock
257 259 debugmergestate:
258 260 debugnamecomplete:
259 261 debugobsolete: flags, record-parents, rev, date, user
260 262 debugpathcomplete: full, normal, added, removed
261 263 debugpushkey:
262 264 debugpvec:
263 265 debugrebuilddirstate: rev, minimal
264 266 debugrebuildfncache:
265 267 debugrename: rev
266 268 debugrevlog: changelog, manifest, dir, dump
267 269 debugrevspec: optimize
268 270 debugsetparents:
269 271 debugsub: rev
270 272 debugsuccessorssets:
271 273 debugwalk: include, exclude
272 274 debugwireargs: three, four, five, ssh, remotecmd, insecure
273 275 files: rev, print0, include, exclude, template, subrepos
274 276 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
275 277 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
276 278 heads: rev, topo, active, closed, style, template
277 279 help: extension, command, keyword
278 280 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
279 281 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
280 282 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
281 283 locate: rev, print0, fullpath, include, exclude
282 284 manifest: rev, all, template
283 285 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
284 286 parents: rev, style, template
285 287 paths:
286 288 phase: public, draft, secret, force, rev
287 289 recover:
288 290 rename: after, force, include, exclude, dry-run
289 291 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
290 292 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
291 293 rollback: dry-run, force
292 294 root:
293 295 tag: force, local, rev, remove, edit, message, date, user
294 296 tags: template
295 297 tip: patch, git, style, template
296 298 unbundle: update
297 299 verify:
298 300 version:
299 301
300 302 $ hg init a
301 303 $ cd a
302 304 $ echo fee > fee
303 305 $ hg ci -q -Amfee
304 306 $ hg tag fee
305 307 $ mkdir fie
306 308 $ echo dead > fie/dead
307 309 $ echo live > fie/live
308 310 $ hg bookmark fo
309 311 $ hg branch -q fie
310 312 $ hg ci -q -Amfie
311 313 $ echo fo > fo
312 314 $ hg branch -qf default
313 315 $ hg ci -q -Amfo
314 316 $ echo Fum > Fum
315 317 $ hg ci -q -AmFum
316 318 $ hg bookmark Fum
317 319
318 320 Test debugpathcomplete
319 321
320 322 $ hg debugpathcomplete f
321 323 fee
322 324 fie
323 325 fo
324 326 $ hg debugpathcomplete -f f
325 327 fee
326 328 fie/dead
327 329 fie/live
328 330 fo
329 331
330 332 $ hg rm Fum
331 333 $ hg debugpathcomplete -r F
332 334 Fum
333 335
334 336 Test debugnamecomplete
335 337
336 338 $ hg debugnamecomplete
337 339 Fum
338 340 default
339 341 fee
340 342 fie
341 343 fo
342 344 tip
343 345 $ hg debugnamecomplete f
344 346 fee
345 347 fie
346 348 fo
@@ -1,2384 +1,2387 b''
1 1 Short help:
2 2
3 3 $ hg
4 4 Mercurial Distributed SCM
5 5
6 6 basic commands:
7 7
8 8 add add the specified files on the next commit
9 9 annotate show changeset information by line for each file
10 10 clone make a copy of an existing repository
11 11 commit commit the specified files or all outstanding changes
12 12 diff diff repository (or selected files)
13 13 export dump the header and diffs for one or more changesets
14 14 forget forget the specified files on the next commit
15 15 init create a new repository in the given directory
16 16 log show revision history of entire repository or files
17 17 merge merge another revision into working directory
18 18 pull pull changes from the specified source
19 19 push push changes to the specified destination
20 20 remove remove the specified files on the next commit
21 21 serve start stand-alone webserver
22 22 status show changed files in the working directory
23 23 summary summarize working directory state
24 24 update update working directory (or switch revisions)
25 25
26 26 (use "hg help" for the full list of commands or "hg -v" for details)
27 27
28 28 $ hg -q
29 29 add add the specified files on the next commit
30 30 annotate show changeset information by line for each file
31 31 clone make a copy of an existing repository
32 32 commit commit the specified files or all outstanding changes
33 33 diff diff repository (or selected files)
34 34 export dump the header and diffs for one or more changesets
35 35 forget forget the specified files on the next commit
36 36 init create a new repository in the given directory
37 37 log show revision history of entire repository or files
38 38 merge merge another revision into working directory
39 39 pull pull changes from the specified source
40 40 push push changes to the specified destination
41 41 remove remove the specified files on the next commit
42 42 serve start stand-alone webserver
43 43 status show changed files in the working directory
44 44 summary summarize working directory state
45 45 update update working directory (or switch revisions)
46 46
47 47 $ hg help
48 48 Mercurial Distributed SCM
49 49
50 50 list of commands:
51 51
52 52 add add the specified files on the next commit
53 53 addremove add all new files, delete all missing files
54 54 annotate show changeset information by line for each file
55 55 archive create an unversioned archive of a repository revision
56 56 backout reverse effect of earlier changeset
57 57 bisect subdivision search of changesets
58 58 bookmarks create a new bookmark or list existing bookmarks
59 59 branch set or show the current branch name
60 60 branches list repository named branches
61 61 bundle create a changegroup file
62 62 cat output the current or given revision of files
63 63 clone make a copy of an existing repository
64 64 commit commit the specified files or all outstanding changes
65 65 config show combined config settings from all hgrc files
66 66 copy mark files as copied for the next commit
67 67 diff diff repository (or selected files)
68 68 export dump the header and diffs for one or more changesets
69 69 files list tracked files
70 70 forget forget the specified files on the next commit
71 71 graft copy changes from other branches onto the current branch
72 72 grep search for a pattern in specified files and revisions
73 73 heads show branch heads
74 74 help show help for a given topic or a help overview
75 75 identify identify the working directory or specified revision
76 76 import import an ordered set of patches
77 77 incoming show new changesets found in source
78 78 init create a new repository in the given directory
79 79 log show revision history of entire repository or files
80 80 manifest output the current or given revision of the project manifest
81 81 merge merge another revision into working directory
82 82 outgoing show changesets not found in the destination
83 83 paths show aliases for remote repositories
84 84 phase set or show the current phase name
85 85 pull pull changes from the specified source
86 86 push push changes to the specified destination
87 87 recover roll back an interrupted transaction
88 88 remove remove the specified files on the next commit
89 89 rename rename files; equivalent of copy + remove
90 90 resolve redo merges or set/view the merge status of files
91 91 revert restore files to their checkout state
92 92 root print the root (top) of the current working directory
93 93 serve start stand-alone webserver
94 94 status show changed files in the working directory
95 95 summary summarize working directory state
96 96 tag add one or more tags for the current or given revision
97 97 tags list repository tags
98 98 unbundle apply one or more changegroup files
99 99 update update working directory (or switch revisions)
100 100 verify verify the integrity of the repository
101 101 version output version and copyright information
102 102
103 103 additional help topics:
104 104
105 105 config Configuration Files
106 106 dates Date Formats
107 107 diffs Diff Formats
108 108 environment Environment Variables
109 109 extensions Using Additional Features
110 110 filesets Specifying File Sets
111 111 glossary Glossary
112 112 hgignore Syntax for Mercurial Ignore Files
113 113 hgweb Configuring hgweb
114 114 merge-tools Merge Tools
115 115 multirevs Specifying Multiple Revisions
116 116 patterns File Name Patterns
117 117 phases Working with Phases
118 118 revisions Specifying Single Revisions
119 119 revsets Specifying Revision Sets
120 120 scripting Using Mercurial from scripts and automation
121 121 subrepos Subrepositories
122 122 templating Template Usage
123 123 urls URL Paths
124 124
125 125 (use "hg help -v" to show built-in aliases and global options)
126 126
127 127 $ hg -q help
128 128 add add the specified files on the next commit
129 129 addremove add all new files, delete all missing files
130 130 annotate show changeset information by line for each file
131 131 archive create an unversioned archive of a repository revision
132 132 backout reverse effect of earlier changeset
133 133 bisect subdivision search of changesets
134 134 bookmarks create a new bookmark or list existing bookmarks
135 135 branch set or show the current branch name
136 136 branches list repository named branches
137 137 bundle create a changegroup file
138 138 cat output the current or given revision of files
139 139 clone make a copy of an existing repository
140 140 commit commit the specified files or all outstanding changes
141 141 config show combined config settings from all hgrc files
142 142 copy mark files as copied for the next commit
143 143 diff diff repository (or selected files)
144 144 export dump the header and diffs for one or more changesets
145 145 files list tracked files
146 146 forget forget the specified files on the next commit
147 147 graft copy changes from other branches onto the current branch
148 148 grep search for a pattern in specified files and revisions
149 149 heads show branch heads
150 150 help show help for a given topic or a help overview
151 151 identify identify the working directory or specified revision
152 152 import import an ordered set of patches
153 153 incoming show new changesets found in source
154 154 init create a new repository in the given directory
155 155 log show revision history of entire repository or files
156 156 manifest output the current or given revision of the project manifest
157 157 merge merge another revision into working directory
158 158 outgoing show changesets not found in the destination
159 159 paths show aliases for remote repositories
160 160 phase set or show the current phase name
161 161 pull pull changes from the specified source
162 162 push push changes to the specified destination
163 163 recover roll back an interrupted transaction
164 164 remove remove the specified files on the next commit
165 165 rename rename files; equivalent of copy + remove
166 166 resolve redo merges or set/view the merge status of files
167 167 revert restore files to their checkout state
168 168 root print the root (top) of the current working directory
169 169 serve start stand-alone webserver
170 170 status show changed files in the working directory
171 171 summary summarize working directory state
172 172 tag add one or more tags for the current or given revision
173 173 tags list repository tags
174 174 unbundle apply one or more changegroup files
175 175 update update working directory (or switch revisions)
176 176 verify verify the integrity of the repository
177 177 version output version and copyright information
178 178
179 179 additional help topics:
180 180
181 181 config Configuration Files
182 182 dates Date Formats
183 183 diffs Diff Formats
184 184 environment Environment Variables
185 185 extensions Using Additional Features
186 186 filesets Specifying File Sets
187 187 glossary Glossary
188 188 hgignore Syntax for Mercurial Ignore Files
189 189 hgweb Configuring hgweb
190 190 merge-tools Merge Tools
191 191 multirevs Specifying Multiple Revisions
192 192 patterns File Name Patterns
193 193 phases Working with Phases
194 194 revisions Specifying Single Revisions
195 195 revsets Specifying Revision Sets
196 196 scripting Using Mercurial from scripts and automation
197 197 subrepos Subrepositories
198 198 templating Template Usage
199 199 urls URL Paths
200 200
201 201 Test extension help:
202 202 $ hg help extensions --config extensions.rebase= --config extensions.children=
203 203 Using Additional Features
204 204 """""""""""""""""""""""""
205 205
206 206 Mercurial has the ability to add new features through the use of
207 207 extensions. Extensions may add new commands, add options to existing
208 208 commands, change the default behavior of commands, or implement hooks.
209 209
210 210 To enable the "foo" extension, either shipped with Mercurial or in the
211 211 Python search path, create an entry for it in your configuration file,
212 212 like this:
213 213
214 214 [extensions]
215 215 foo =
216 216
217 217 You may also specify the full path to an extension:
218 218
219 219 [extensions]
220 220 myfeature = ~/.hgext/myfeature.py
221 221
222 222 See "hg help config" for more information on configuration files.
223 223
224 224 Extensions are not loaded by default for a variety of reasons: they can
225 225 increase startup overhead; they may be meant for advanced usage only; they
226 226 may provide potentially dangerous abilities (such as letting you destroy
227 227 or modify history); they might not be ready for prime time; or they may
228 228 alter some usual behaviors of stock Mercurial. It is thus up to the user
229 229 to activate extensions as needed.
230 230
231 231 To explicitly disable an extension enabled in a configuration file of
232 232 broader scope, prepend its path with !:
233 233
234 234 [extensions]
235 235 # disabling extension bar residing in /path/to/extension/bar.py
236 236 bar = !/path/to/extension/bar.py
237 237 # ditto, but no path was supplied for extension baz
238 238 baz = !
239 239
240 240 enabled extensions:
241 241
242 242 children command to display child changesets (DEPRECATED)
243 243 rebase command to move sets of revisions to a different ancestor
244 244
245 245 disabled extensions:
246 246
247 247 acl hooks for controlling repository access
248 248 blackbox log repository events to a blackbox for debugging
249 249 bugzilla hooks for integrating with the Bugzilla bug tracker
250 250 censor erase file content at a given revision
251 251 churn command to display statistics about repository history
252 252 clonebundles server side extension to advertise pre-generated bundles to
253 253 seed clones.
254 254 color colorize output from some commands
255 255 convert import revisions from foreign VCS repositories into
256 256 Mercurial
257 257 eol automatically manage newlines in repository files
258 258 extdiff command to allow external programs to compare revisions
259 259 factotum http authentication with factotum
260 260 gpg commands to sign and verify changesets
261 261 hgcia hooks for integrating with the CIA.vc notification service
262 262 hgk browse the repository in a graphical way
263 263 highlight syntax highlighting for hgweb (requires Pygments)
264 264 histedit interactive history editing
265 265 keyword expand keywords in tracked files
266 266 largefiles track large binary files
267 267 mq manage a stack of patches
268 268 notify hooks for sending email push notifications
269 269 pager browse command output with an external pager
270 270 patchbomb command to send changesets as (a series of) patch emails
271 271 purge command to delete untracked files from the working
272 272 directory
273 273 record commands to interactively select changes for
274 274 commit/qrefresh
275 275 relink recreates hardlinks between repository clones
276 276 schemes extend schemes with shortcuts to repository swarms
277 277 share share a common history between several working directories
278 278 shelve save and restore changes to the working directory
279 279 strip strip changesets and their descendants from history
280 280 transplant command to transplant changesets from another branch
281 281 win32mbcs allow the use of MBCS paths with problematic encodings
282 282 zeroconf discover and advertise repositories on the local network
283 283
284 284 Verify that extension keywords appear in help templates
285 285
286 286 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
287 287
288 288 Test short command list with verbose option
289 289
290 290 $ hg -v help shortlist
291 291 Mercurial Distributed SCM
292 292
293 293 basic commands:
294 294
295 295 add add the specified files on the next commit
296 296 annotate, blame
297 297 show changeset information by line for each file
298 298 clone make a copy of an existing repository
299 299 commit, ci commit the specified files or all outstanding changes
300 300 diff diff repository (or selected files)
301 301 export dump the header and diffs for one or more changesets
302 302 forget forget the specified files on the next commit
303 303 init create a new repository in the given directory
304 304 log, history show revision history of entire repository or files
305 305 merge merge another revision into working directory
306 306 pull pull changes from the specified source
307 307 push push changes to the specified destination
308 308 remove, rm remove the specified files on the next commit
309 309 serve start stand-alone webserver
310 310 status, st show changed files in the working directory
311 311 summary, sum summarize working directory state
312 312 update, up, checkout, co
313 313 update working directory (or switch revisions)
314 314
315 315 global options ([+] can be repeated):
316 316
317 317 -R --repository REPO repository root directory or name of overlay bundle
318 318 file
319 319 --cwd DIR change working directory
320 320 -y --noninteractive do not prompt, automatically pick the first choice for
321 321 all prompts
322 322 -q --quiet suppress output
323 323 -v --verbose enable additional output
324 324 --config CONFIG [+] set/override config option (use 'section.name=value')
325 325 --debug enable debugging output
326 326 --debugger start debugger
327 327 --encoding ENCODE set the charset encoding (default: ascii)
328 328 --encodingmode MODE set the charset encoding mode (default: strict)
329 329 --traceback always print a traceback on exception
330 330 --time time how long the command takes
331 331 --profile print command execution profile
332 332 --version output version information and exit
333 333 -h --help display help and exit
334 334 --hidden consider hidden changesets
335 335
336 336 (use "hg help" for the full list of commands)
337 337
338 338 $ hg add -h
339 339 hg add [OPTION]... [FILE]...
340 340
341 341 add the specified files on the next commit
342 342
343 343 Schedule files to be version controlled and added to the repository.
344 344
345 345 The files will be added to the repository at the next commit. To undo an
346 346 add before that, see "hg forget".
347 347
348 348 If no names are given, add all files to the repository.
349 349
350 350 Returns 0 if all files are successfully added.
351 351
352 352 options ([+] can be repeated):
353 353
354 354 -I --include PATTERN [+] include names matching the given patterns
355 355 -X --exclude PATTERN [+] exclude names matching the given patterns
356 356 -S --subrepos recurse into subrepositories
357 357 -n --dry-run do not perform actions, just print output
358 358
359 359 (some details hidden, use --verbose to show complete help)
360 360
361 361 Verbose help for add
362 362
363 363 $ hg add -hv
364 364 hg add [OPTION]... [FILE]...
365 365
366 366 add the specified files on the next commit
367 367
368 368 Schedule files to be version controlled and added to the repository.
369 369
370 370 The files will be added to the repository at the next commit. To undo an
371 371 add before that, see "hg forget".
372 372
373 373 If no names are given, add all files to the repository.
374 374
375 375 An example showing how new (unknown) files are added automatically by "hg
376 376 add":
377 377
378 378 $ ls
379 379 foo.c
380 380 $ hg status
381 381 ? foo.c
382 382 $ hg add
383 383 adding foo.c
384 384 $ hg status
385 385 A foo.c
386 386
387 387 Returns 0 if all files are successfully added.
388 388
389 389 options ([+] can be repeated):
390 390
391 391 -I --include PATTERN [+] include names matching the given patterns
392 392 -X --exclude PATTERN [+] exclude names matching the given patterns
393 393 -S --subrepos recurse into subrepositories
394 394 -n --dry-run do not perform actions, just print output
395 395
396 396 global options ([+] can be repeated):
397 397
398 398 -R --repository REPO repository root directory or name of overlay bundle
399 399 file
400 400 --cwd DIR change working directory
401 401 -y --noninteractive do not prompt, automatically pick the first choice for
402 402 all prompts
403 403 -q --quiet suppress output
404 404 -v --verbose enable additional output
405 405 --config CONFIG [+] set/override config option (use 'section.name=value')
406 406 --debug enable debugging output
407 407 --debugger start debugger
408 408 --encoding ENCODE set the charset encoding (default: ascii)
409 409 --encodingmode MODE set the charset encoding mode (default: strict)
410 410 --traceback always print a traceback on exception
411 411 --time time how long the command takes
412 412 --profile print command execution profile
413 413 --version output version information and exit
414 414 -h --help display help and exit
415 415 --hidden consider hidden changesets
416 416
417 417 Test help option with version option
418 418
419 419 $ hg add -h --version
420 420 Mercurial Distributed SCM (version *) (glob)
421 421 (see https://mercurial-scm.org for more information)
422 422
423 423 Copyright (C) 2005-2015 Matt Mackall and others
424 424 This is free software; see the source for copying conditions. There is NO
425 425 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
426 426
427 427 $ hg add --skjdfks
428 428 hg add: option --skjdfks not recognized
429 429 hg add [OPTION]... [FILE]...
430 430
431 431 add the specified files on the next commit
432 432
433 433 options ([+] can be repeated):
434 434
435 435 -I --include PATTERN [+] include names matching the given patterns
436 436 -X --exclude PATTERN [+] exclude names matching the given patterns
437 437 -S --subrepos recurse into subrepositories
438 438 -n --dry-run do not perform actions, just print output
439 439
440 440 (use "hg add -h" to show more help)
441 441 [255]
442 442
443 443 Test ambiguous command help
444 444
445 445 $ hg help ad
446 446 list of commands:
447 447
448 448 add add the specified files on the next commit
449 449 addremove add all new files, delete all missing files
450 450
451 451 (use "hg help -v ad" to show built-in aliases and global options)
452 452
453 453 Test command without options
454 454
455 455 $ hg help verify
456 456 hg verify
457 457
458 458 verify the integrity of the repository
459 459
460 460 Verify the integrity of the current repository.
461 461
462 462 This will perform an extensive check of the repository's integrity,
463 463 validating the hashes and checksums of each entry in the changelog,
464 464 manifest, and tracked files, as well as the integrity of their crosslinks
465 465 and indices.
466 466
467 467 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
468 468 information about recovery from corruption of the repository.
469 469
470 470 Returns 0 on success, 1 if errors are encountered.
471 471
472 472 (some details hidden, use --verbose to show complete help)
473 473
474 474 $ hg help diff
475 475 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
476 476
477 477 diff repository (or selected files)
478 478
479 479 Show differences between revisions for the specified files.
480 480
481 481 Differences between files are shown using the unified diff format.
482 482
483 483 Note:
484 484 diff may generate unexpected results for merges, as it will default to
485 485 comparing against the working directory's first parent changeset if no
486 486 revisions are specified.
487 487
488 488 When two revision arguments are given, then changes are shown between
489 489 those revisions. If only one revision is specified then that revision is
490 490 compared to the working directory, and, when no revisions are specified,
491 491 the working directory files are compared to its parent.
492 492
493 493 Alternatively you can specify -c/--change with a revision to see the
494 494 changes in that changeset relative to its first parent.
495 495
496 496 Without the -a/--text option, diff will avoid generating diffs of files it
497 497 detects as binary. With -a, diff will generate a diff anyway, probably
498 498 with undesirable results.
499 499
500 500 Use the -g/--git option to generate diffs in the git extended diff format.
501 501 For more information, read "hg help diffs".
502 502
503 503 Returns 0 on success.
504 504
505 505 options ([+] can be repeated):
506 506
507 507 -r --rev REV [+] revision
508 508 -c --change REV change made by revision
509 509 -a --text treat all files as text
510 510 -g --git use git extended diff format
511 511 --nodates omit dates from diff headers
512 512 --noprefix omit a/ and b/ prefixes from filenames
513 513 -p --show-function show which function each change is in
514 514 --reverse produce a diff that undoes the changes
515 515 -w --ignore-all-space ignore white space when comparing lines
516 516 -b --ignore-space-change ignore changes in the amount of white space
517 517 -B --ignore-blank-lines ignore changes whose lines are all blank
518 518 -U --unified NUM number of lines of context to show
519 519 --stat output diffstat-style summary of changes
520 520 --root DIR produce diffs relative to subdirectory
521 521 -I --include PATTERN [+] include names matching the given patterns
522 522 -X --exclude PATTERN [+] exclude names matching the given patterns
523 523 -S --subrepos recurse into subrepositories
524 524
525 525 (some details hidden, use --verbose to show complete help)
526 526
527 527 $ hg help status
528 528 hg status [OPTION]... [FILE]...
529 529
530 530 aliases: st
531 531
532 532 show changed files in the working directory
533 533
534 534 Show status of files in the repository. If names are given, only files
535 535 that match are shown. Files that are clean or ignored or the source of a
536 536 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
537 537 -C/--copies or -A/--all are given. Unless options described with "show
538 538 only ..." are given, the options -mardu are used.
539 539
540 540 Option -q/--quiet hides untracked (unknown and ignored) files unless
541 541 explicitly requested with -u/--unknown or -i/--ignored.
542 542
543 543 Note:
544 544 status may appear to disagree with diff if permissions have changed or
545 545 a merge has occurred. The standard diff format does not report
546 546 permission changes and diff only reports changes relative to one merge
547 547 parent.
548 548
549 549 If one revision is given, it is used as the base revision. If two
550 550 revisions are given, the differences between them are shown. The --change
551 551 option can also be used as a shortcut to list the changed files of a
552 552 revision from its first parent.
553 553
554 554 The codes used to show the status of files are:
555 555
556 556 M = modified
557 557 A = added
558 558 R = removed
559 559 C = clean
560 560 ! = missing (deleted by non-hg command, but still tracked)
561 561 ? = not tracked
562 562 I = ignored
563 563 = origin of the previous file (with --copies)
564 564
565 565 Returns 0 on success.
566 566
567 567 options ([+] can be repeated):
568 568
569 569 -A --all show status of all files
570 570 -m --modified show only modified files
571 571 -a --added show only added files
572 572 -r --removed show only removed files
573 573 -d --deleted show only deleted (but tracked) files
574 574 -c --clean show only files without changes
575 575 -u --unknown show only unknown (not tracked) files
576 576 -i --ignored show only ignored files
577 577 -n --no-status hide status prefix
578 578 -C --copies show source of copied files
579 579 -0 --print0 end filenames with NUL, for use with xargs
580 580 --rev REV [+] show difference from revision
581 581 --change REV list the changed files of a revision
582 582 -I --include PATTERN [+] include names matching the given patterns
583 583 -X --exclude PATTERN [+] exclude names matching the given patterns
584 584 -S --subrepos recurse into subrepositories
585 585
586 586 (some details hidden, use --verbose to show complete help)
587 587
588 588 $ hg -q help status
589 589 hg status [OPTION]... [FILE]...
590 590
591 591 show changed files in the working directory
592 592
593 593 $ hg help foo
594 594 abort: no such help topic: foo
595 595 (try "hg help --keyword foo")
596 596 [255]
597 597
598 598 $ hg skjdfks
599 599 hg: unknown command 'skjdfks'
600 600 Mercurial Distributed SCM
601 601
602 602 basic commands:
603 603
604 604 add add the specified files on the next commit
605 605 annotate show changeset information by line for each file
606 606 clone make a copy of an existing repository
607 607 commit commit the specified files or all outstanding changes
608 608 diff diff repository (or selected files)
609 609 export dump the header and diffs for one or more changesets
610 610 forget forget the specified files on the next commit
611 611 init create a new repository in the given directory
612 612 log show revision history of entire repository or files
613 613 merge merge another revision into working directory
614 614 pull pull changes from the specified source
615 615 push push changes to the specified destination
616 616 remove remove the specified files on the next commit
617 617 serve start stand-alone webserver
618 618 status show changed files in the working directory
619 619 summary summarize working directory state
620 620 update update working directory (or switch revisions)
621 621
622 622 (use "hg help" for the full list of commands or "hg -v" for details)
623 623 [255]
624 624
625 625
626 626 Make sure that we don't run afoul of the help system thinking that
627 627 this is a section and erroring out weirdly.
628 628
629 629 $ hg .log
630 630 hg: unknown command '.log'
631 631 (did you mean one of log?)
632 632 [255]
633 633
634 634 $ hg log.
635 635 hg: unknown command 'log.'
636 636 (did you mean one of log?)
637 637 [255]
638 638 $ hg pu.lh
639 639 hg: unknown command 'pu.lh'
640 640 (did you mean one of pull, push?)
641 641 [255]
642 642
643 643 $ cat > helpext.py <<EOF
644 644 > import os
645 645 > from mercurial import cmdutil, commands
646 646 >
647 647 > cmdtable = {}
648 648 > command = cmdutil.command(cmdtable)
649 649 >
650 650 > @command('nohelp',
651 651 > [('', 'longdesc', 3, 'x'*90),
652 652 > ('n', '', None, 'normal desc'),
653 653 > ('', 'newline', '', 'line1\nline2')],
654 654 > 'hg nohelp',
655 655 > norepo=True)
656 656 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
657 657 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
658 658 > def nohelp(ui, *args, **kwargs):
659 659 > pass
660 660 >
661 661 > EOF
662 662 $ echo '[extensions]' >> $HGRCPATH
663 663 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
664 664
665 665 Test command with no help text
666 666
667 667 $ hg help nohelp
668 668 hg nohelp
669 669
670 670 (no help text available)
671 671
672 672 options:
673 673
674 674 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
675 675 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
676 676 -n -- normal desc
677 677 --newline VALUE line1 line2
678 678
679 679 (some details hidden, use --verbose to show complete help)
680 680
681 681 $ hg help -k nohelp
682 682 Commands:
683 683
684 684 nohelp hg nohelp
685 685
686 686 Extension Commands:
687 687
688 688 nohelp (no help text available)
689 689
690 690 Test that default list of commands omits extension commands
691 691
692 692 $ hg help
693 693 Mercurial Distributed SCM
694 694
695 695 list of commands:
696 696
697 697 add add the specified files on the next commit
698 698 addremove add all new files, delete all missing files
699 699 annotate show changeset information by line for each file
700 700 archive create an unversioned archive of a repository revision
701 701 backout reverse effect of earlier changeset
702 702 bisect subdivision search of changesets
703 703 bookmarks create a new bookmark or list existing bookmarks
704 704 branch set or show the current branch name
705 705 branches list repository named branches
706 706 bundle create a changegroup file
707 707 cat output the current or given revision of files
708 708 clone make a copy of an existing repository
709 709 commit commit the specified files or all outstanding changes
710 710 config show combined config settings from all hgrc files
711 711 copy mark files as copied for the next commit
712 712 diff diff repository (or selected files)
713 713 export dump the header and diffs for one or more changesets
714 714 files list tracked files
715 715 forget forget the specified files on the next commit
716 716 graft copy changes from other branches onto the current branch
717 717 grep search for a pattern in specified files and revisions
718 718 heads show branch heads
719 719 help show help for a given topic or a help overview
720 720 identify identify the working directory or specified revision
721 721 import import an ordered set of patches
722 722 incoming show new changesets found in source
723 723 init create a new repository in the given directory
724 724 log show revision history of entire repository or files
725 725 manifest output the current or given revision of the project manifest
726 726 merge merge another revision into working directory
727 727 outgoing show changesets not found in the destination
728 728 paths show aliases for remote repositories
729 729 phase set or show the current phase name
730 730 pull pull changes from the specified source
731 731 push push changes to the specified destination
732 732 recover roll back an interrupted transaction
733 733 remove remove the specified files on the next commit
734 734 rename rename files; equivalent of copy + remove
735 735 resolve redo merges or set/view the merge status of files
736 736 revert restore files to their checkout state
737 737 root print the root (top) of the current working directory
738 738 serve start stand-alone webserver
739 739 status show changed files in the working directory
740 740 summary summarize working directory state
741 741 tag add one or more tags for the current or given revision
742 742 tags list repository tags
743 743 unbundle apply one or more changegroup files
744 744 update update working directory (or switch revisions)
745 745 verify verify the integrity of the repository
746 746 version output version and copyright information
747 747
748 748 enabled extensions:
749 749
750 750 helpext (no help text available)
751 751
752 752 additional help topics:
753 753
754 754 config Configuration Files
755 755 dates Date Formats
756 756 diffs Diff Formats
757 757 environment Environment Variables
758 758 extensions Using Additional Features
759 759 filesets Specifying File Sets
760 760 glossary Glossary
761 761 hgignore Syntax for Mercurial Ignore Files
762 762 hgweb Configuring hgweb
763 763 merge-tools Merge Tools
764 764 multirevs Specifying Multiple Revisions
765 765 patterns File Name Patterns
766 766 phases Working with Phases
767 767 revisions Specifying Single Revisions
768 768 revsets Specifying Revision Sets
769 769 scripting Using Mercurial from scripts and automation
770 770 subrepos Subrepositories
771 771 templating Template Usage
772 772 urls URL Paths
773 773
774 774 (use "hg help -v" to show built-in aliases and global options)
775 775
776 776
777 777 Test list of internal help commands
778 778
779 779 $ hg help debug
780 780 debug commands (internal and unsupported):
781 781
782 782 debugancestor
783 783 find the ancestor revision of two revisions in a given index
784 debugapplystreamclonebundle
785 apply a stream clone bundle file
784 786 debugbuilddag
785 787 builds a repo with a given DAG from scratch in the current
786 788 empty repo
787 789 debugbundle lists the contents of a bundle
788 790 debugcheckstate
789 791 validate the correctness of the current dirstate
790 792 debugcommands
791 793 list all available commands and options
792 794 debugcomplete
793 795 returns the completion list associated with the given command
794 796 debugcreatestreamclonebundle
795 797 create a stream clone bundle file
796 798 debugdag format the changelog or an index DAG as a concise textual
797 799 description
798 800 debugdata dump the contents of a data file revision
799 801 debugdate parse and display a date
800 802 debugdirstate
801 803 show the contents of the current dirstate
802 804 debugdiscovery
803 805 runs the changeset discovery protocol in isolation
804 806 debugextensions
805 807 show information about active extensions
806 808 debugfileset parse and apply a fileset specification
807 809 debugfsinfo show information detected about current filesystem
808 810 debuggetbundle
809 811 retrieves a bundle from a repo
810 812 debugignore display the combined ignore pattern
811 813 debugindex dump the contents of an index file
812 814 debugindexdot
813 815 dump an index DAG as a graphviz dot file
814 816 debuginstall test Mercurial installation
815 817 debugknown test whether node ids are known to a repo
816 818 debuglocks show or modify state of locks
817 819 debugmergestate
818 820 print merge state
819 821 debugnamecomplete
820 822 complete "names" - tags, open branch names, bookmark names
821 823 debugobsolete
822 824 create arbitrary obsolete marker
823 825 debugoptDEP (no help text available)
824 826 debugoptEXP (no help text available)
825 827 debugpathcomplete
826 828 complete part or all of a tracked path
827 829 debugpushkey access the pushkey key/value protocol
828 830 debugpvec (no help text available)
829 831 debugrebuilddirstate
830 832 rebuild the dirstate as it would look like for the given
831 833 revision
832 834 debugrebuildfncache
833 835 rebuild the fncache file
834 836 debugrename dump rename information
835 837 debugrevlog show data and statistics about a revlog
836 838 debugrevspec parse and apply a revision specification
837 839 debugsetparents
838 840 manually set the parents of the current working directory
839 841 debugsub (no help text available)
840 842 debugsuccessorssets
841 843 show set of successors for revision
842 844 debugwalk show how files match on given patterns
843 845 debugwireargs
844 846 (no help text available)
845 847
846 848 (use "hg help -v debug" to show built-in aliases and global options)
847 849
848 850
849 851 Test list of commands with command with no help text
850 852
851 853 $ hg help helpext
852 854 helpext extension - no help text available
853 855
854 856 list of commands:
855 857
856 858 nohelp (no help text available)
857 859
858 860 (use "hg help -v helpext" to show built-in aliases and global options)
859 861
860 862
861 863 test deprecated and experimental options are hidden in command help
862 864 $ hg help debugoptDEP
863 865 hg debugoptDEP
864 866
865 867 (no help text available)
866 868
867 869 options:
868 870
869 871 (some details hidden, use --verbose to show complete help)
870 872
871 873 $ hg help debugoptEXP
872 874 hg debugoptEXP
873 875
874 876 (no help text available)
875 877
876 878 options:
877 879
878 880 (some details hidden, use --verbose to show complete help)
879 881
880 882 test deprecated and experimental options is shown with -v
881 883 $ hg help -v debugoptDEP | grep dopt
882 884 --dopt option is (DEPRECATED)
883 885 $ hg help -v debugoptEXP | grep eopt
884 886 --eopt option is (EXPERIMENTAL)
885 887
886 888 #if gettext
887 889 test deprecated option is hidden with translation with untranslated description
888 890 (use many globy for not failing on changed transaction)
889 891 $ LANGUAGE=sv hg help debugoptDEP
890 892 hg debugoptDEP
891 893
892 894 (*) (glob)
893 895
894 896 options:
895 897
896 898 (some details hidden, use --verbose to show complete help)
897 899 #endif
898 900
899 901 Test commands that collide with topics (issue4240)
900 902
901 903 $ hg config -hq
902 904 hg config [-u] [NAME]...
903 905
904 906 show combined config settings from all hgrc files
905 907 $ hg showconfig -hq
906 908 hg config [-u] [NAME]...
907 909
908 910 show combined config settings from all hgrc files
909 911
910 912 Test a help topic
911 913
912 914 $ hg help revs
913 915 Specifying Single Revisions
914 916 """""""""""""""""""""""""""
915 917
916 918 Mercurial supports several ways to specify individual revisions.
917 919
918 920 A plain integer is treated as a revision number. Negative integers are
919 921 treated as sequential offsets from the tip, with -1 denoting the tip, -2
920 922 denoting the revision prior to the tip, and so forth.
921 923
922 924 A 40-digit hexadecimal string is treated as a unique revision identifier.
923 925
924 926 A hexadecimal string less than 40 characters long is treated as a unique
925 927 revision identifier and is referred to as a short-form identifier. A
926 928 short-form identifier is only valid if it is the prefix of exactly one
927 929 full-length identifier.
928 930
929 931 Any other string is treated as a bookmark, tag, or branch name. A bookmark
930 932 is a movable pointer to a revision. A tag is a permanent name associated
931 933 with a revision. A branch name denotes the tipmost open branch head of
932 934 that branch - or if they are all closed, the tipmost closed head of the
933 935 branch. Bookmark, tag, and branch names must not contain the ":"
934 936 character.
935 937
936 938 The reserved name "tip" always identifies the most recent revision.
937 939
938 940 The reserved name "null" indicates the null revision. This is the revision
939 941 of an empty repository, and the parent of revision 0.
940 942
941 943 The reserved name "." indicates the working directory parent. If no
942 944 working directory is checked out, it is equivalent to null. If an
943 945 uncommitted merge is in progress, "." is the revision of the first parent.
944 946
945 947 Test repeated config section name
946 948
947 949 $ hg help config.host
948 950 "http_proxy.host"
949 951 Host name and (optional) port of the proxy server, for example
950 952 "myproxy:8000".
951 953
952 954 "smtp.host"
953 955 Host name of mail server, e.g. "mail.example.com".
954 956
955 957 Unrelated trailing paragraphs shouldn't be included
956 958
957 959 $ hg help config.extramsg | grep '^$'
958 960
959 961
960 962 Test capitalized section name
961 963
962 964 $ hg help scripting.HGPLAIN > /dev/null
963 965
964 966 Help subsection:
965 967
966 968 $ hg help config.charsets |grep "Email example:" > /dev/null
967 969 [1]
968 970
969 971 Show nested definitions
970 972 ("profiling.type"[break]"ls"[break]"stat"[break])
971 973
972 974 $ hg help config.type | egrep '^$'|wc -l
973 975 \s*3 (re)
974 976
975 977 Last item in help config.*:
976 978
977 979 $ hg help config.`hg help config|grep '^ "'| \
978 980 > tail -1|sed 's![ "]*!!g'`| \
979 981 > grep "hg help -c config" > /dev/null
980 982 [1]
981 983
982 984 note to use help -c for general hg help config:
983 985
984 986 $ hg help config |grep "hg help -c config" > /dev/null
985 987
986 988 Test templating help
987 989
988 990 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
989 991 desc String. The text of the changeset description.
990 992 diffstat String. Statistics of changes with the following format:
991 993 firstline Any text. Returns the first line of text.
992 994 nonempty Any text. Returns '(none)' if the string is empty.
993 995
994 996 Test deprecated items
995 997
996 998 $ hg help -v templating | grep currentbookmark
997 999 currentbookmark
998 1000 $ hg help templating | (grep currentbookmark || true)
999 1001
1000 1002 Test help hooks
1001 1003
1002 1004 $ cat > helphook1.py <<EOF
1003 1005 > from mercurial import help
1004 1006 >
1005 1007 > def rewrite(ui, topic, doc):
1006 1008 > return doc + '\nhelphook1\n'
1007 1009 >
1008 1010 > def extsetup(ui):
1009 1011 > help.addtopichook('revsets', rewrite)
1010 1012 > EOF
1011 1013 $ cat > helphook2.py <<EOF
1012 1014 > from mercurial import help
1013 1015 >
1014 1016 > def rewrite(ui, topic, doc):
1015 1017 > return doc + '\nhelphook2\n'
1016 1018 >
1017 1019 > def extsetup(ui):
1018 1020 > help.addtopichook('revsets', rewrite)
1019 1021 > EOF
1020 1022 $ echo '[extensions]' >> $HGRCPATH
1021 1023 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1022 1024 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1023 1025 $ hg help revsets | grep helphook
1024 1026 helphook1
1025 1027 helphook2
1026 1028
1027 1029 Test -e / -c / -k combinations
1028 1030
1029 1031 $ hg help -c progress
1030 1032 abort: no such help topic: progress
1031 1033 (try "hg help --keyword progress")
1032 1034 [255]
1033 1035 $ hg help -e progress |head -1
1034 1036 progress extension - show progress bars for some actions (DEPRECATED)
1035 1037 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1036 1038 Commands:
1037 1039 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1038 1040 Extensions:
1039 1041 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1040 1042 Extensions:
1041 1043 Commands:
1042 1044 $ hg help -c commit > /dev/null
1043 1045 $ hg help -e -c commit > /dev/null
1044 1046 $ hg help -e commit > /dev/null
1045 1047 abort: no such help topic: commit
1046 1048 (try "hg help --keyword commit")
1047 1049 [255]
1048 1050
1049 1051 Test keyword search help
1050 1052
1051 1053 $ cat > prefixedname.py <<EOF
1052 1054 > '''matched against word "clone"
1053 1055 > '''
1054 1056 > EOF
1055 1057 $ echo '[extensions]' >> $HGRCPATH
1056 1058 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1057 1059 $ hg help -k clone
1058 1060 Topics:
1059 1061
1060 1062 config Configuration Files
1061 1063 extensions Using Additional Features
1062 1064 glossary Glossary
1063 1065 phases Working with Phases
1064 1066 subrepos Subrepositories
1065 1067 urls URL Paths
1066 1068
1067 1069 Commands:
1068 1070
1069 1071 bookmarks create a new bookmark or list existing bookmarks
1070 1072 clone make a copy of an existing repository
1073 debugapplystreamclonebundle apply a stream clone bundle file
1071 1074 debugcreatestreamclonebundle create a stream clone bundle file
1072 1075 paths show aliases for remote repositories
1073 1076 update update working directory (or switch revisions)
1074 1077
1075 1078 Extensions:
1076 1079
1077 1080 clonebundles server side extension to advertise pre-generated bundles to seed
1078 1081 clones.
1079 1082 prefixedname matched against word "clone"
1080 1083 relink recreates hardlinks between repository clones
1081 1084
1082 1085 Extension Commands:
1083 1086
1084 1087 qclone clone main and patch repository at same time
1085 1088
1086 1089 Test unfound topic
1087 1090
1088 1091 $ hg help nonexistingtopicthatwillneverexisteverever
1089 1092 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1090 1093 (try "hg help --keyword nonexistingtopicthatwillneverexisteverever")
1091 1094 [255]
1092 1095
1093 1096 Test unfound keyword
1094 1097
1095 1098 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1096 1099 abort: no matches
1097 1100 (try "hg help" for a list of topics)
1098 1101 [255]
1099 1102
1100 1103 Test omit indicating for help
1101 1104
1102 1105 $ cat > addverboseitems.py <<EOF
1103 1106 > '''extension to test omit indicating.
1104 1107 >
1105 1108 > This paragraph is never omitted (for extension)
1106 1109 >
1107 1110 > .. container:: verbose
1108 1111 >
1109 1112 > This paragraph is omitted,
1110 1113 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1111 1114 >
1112 1115 > This paragraph is never omitted, too (for extension)
1113 1116 > '''
1114 1117 >
1115 1118 > from mercurial import help, commands
1116 1119 > testtopic = """This paragraph is never omitted (for topic).
1117 1120 >
1118 1121 > .. container:: verbose
1119 1122 >
1120 1123 > This paragraph is omitted,
1121 1124 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1122 1125 >
1123 1126 > This paragraph is never omitted, too (for topic)
1124 1127 > """
1125 1128 > def extsetup(ui):
1126 1129 > help.helptable.append((["topic-containing-verbose"],
1127 1130 > "This is the topic to test omit indicating.",
1128 1131 > lambda ui: testtopic))
1129 1132 > EOF
1130 1133 $ echo '[extensions]' >> $HGRCPATH
1131 1134 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1132 1135 $ hg help addverboseitems
1133 1136 addverboseitems extension - extension to test omit indicating.
1134 1137
1135 1138 This paragraph is never omitted (for extension)
1136 1139
1137 1140 This paragraph is never omitted, too (for extension)
1138 1141
1139 1142 (some details hidden, use --verbose to show complete help)
1140 1143
1141 1144 no commands defined
1142 1145 $ hg help -v addverboseitems
1143 1146 addverboseitems extension - extension to test omit indicating.
1144 1147
1145 1148 This paragraph is never omitted (for extension)
1146 1149
1147 1150 This paragraph is omitted, if "hg help" is invoked without "-v" (for
1148 1151 extension)
1149 1152
1150 1153 This paragraph is never omitted, too (for extension)
1151 1154
1152 1155 no commands defined
1153 1156 $ hg help topic-containing-verbose
1154 1157 This is the topic to test omit indicating.
1155 1158 """"""""""""""""""""""""""""""""""""""""""
1156 1159
1157 1160 This paragraph is never omitted (for topic).
1158 1161
1159 1162 This paragraph is never omitted, too (for topic)
1160 1163
1161 1164 (some details hidden, use --verbose to show complete help)
1162 1165 $ hg help -v topic-containing-verbose
1163 1166 This is the topic to test omit indicating.
1164 1167 """"""""""""""""""""""""""""""""""""""""""
1165 1168
1166 1169 This paragraph is never omitted (for topic).
1167 1170
1168 1171 This paragraph is omitted, if "hg help" is invoked without "-v" (for
1169 1172 topic)
1170 1173
1171 1174 This paragraph is never omitted, too (for topic)
1172 1175
1173 1176 Test section lookup
1174 1177
1175 1178 $ hg help revset.merge
1176 1179 "merge()"
1177 1180 Changeset is a merge changeset.
1178 1181
1179 1182 $ hg help glossary.dag
1180 1183 DAG
1181 1184 The repository of changesets of a distributed version control system
1182 1185 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1183 1186 of nodes and edges, where nodes correspond to changesets and edges
1184 1187 imply a parent -> child relation. This graph can be visualized by
1185 1188 graphical tools such as "hg log --graph". In Mercurial, the DAG is
1186 1189 limited by the requirement for children to have at most two parents.
1187 1190
1188 1191
1189 1192 $ hg help hgrc.paths
1190 1193 "paths"
1191 1194 -------
1192 1195
1193 1196 Assigns symbolic names to repositories. The left side is the symbolic
1194 1197 name, and the right gives the directory or URL that is the location of the
1195 1198 repository. Default paths can be declared by setting the following
1196 1199 entries.
1197 1200
1198 1201 "default"
1199 1202 Directory or URL to use when pulling if no source is specified.
1200 1203 (default: repository from which the current repository was cloned)
1201 1204
1202 1205 "default-push"
1203 1206 Optional. Directory or URL to use when pushing if no destination is
1204 1207 specified.
1205 1208
1206 1209 Custom paths can be defined by assigning the path to a name that later can
1207 1210 be used from the command line. Example:
1208 1211
1209 1212 [paths]
1210 1213 my_path = http://example.com/path
1211 1214
1212 1215 To push to the path defined in "my_path" run the command:
1213 1216
1214 1217 hg push my_path
1215 1218
1216 1219 $ hg help glossary.mcguffin
1217 1220 abort: help section not found
1218 1221 [255]
1219 1222
1220 1223 $ hg help glossary.mc.guffin
1221 1224 abort: help section not found
1222 1225 [255]
1223 1226
1224 1227 $ hg help template.files
1225 1228 files List of strings. All files modified, added, or removed by
1226 1229 this changeset.
1227 1230
1228 1231 Test dynamic list of merge tools only shows up once
1229 1232 $ hg help merge-tools
1230 1233 Merge Tools
1231 1234 """""""""""
1232 1235
1233 1236 To merge files Mercurial uses merge tools.
1234 1237
1235 1238 A merge tool combines two different versions of a file into a merged file.
1236 1239 Merge tools are given the two files and the greatest common ancestor of
1237 1240 the two file versions, so they can determine the changes made on both
1238 1241 branches.
1239 1242
1240 1243 Merge tools are used both for "hg resolve", "hg merge", "hg update", "hg
1241 1244 backout" and in several extensions.
1242 1245
1243 1246 Usually, the merge tool tries to automatically reconcile the files by
1244 1247 combining all non-overlapping changes that occurred separately in the two
1245 1248 different evolutions of the same initial base file. Furthermore, some
1246 1249 interactive merge programs make it easier to manually resolve conflicting
1247 1250 merges, either in a graphical way, or by inserting some conflict markers.
1248 1251 Mercurial does not include any interactive merge programs but relies on
1249 1252 external tools for that.
1250 1253
1251 1254 Available merge tools
1252 1255 =====================
1253 1256
1254 1257 External merge tools and their properties are configured in the merge-
1255 1258 tools configuration section - see hgrc(5) - but they can often just be
1256 1259 named by their executable.
1257 1260
1258 1261 A merge tool is generally usable if its executable can be found on the
1259 1262 system and if it can handle the merge. The executable is found if it is an
1260 1263 absolute or relative executable path or the name of an application in the
1261 1264 executable search path. The tool is assumed to be able to handle the merge
1262 1265 if it can handle symlinks if the file is a symlink, if it can handle
1263 1266 binary files if the file is binary, and if a GUI is available if the tool
1264 1267 requires a GUI.
1265 1268
1266 1269 There are some internal merge tools which can be used. The internal merge
1267 1270 tools are:
1268 1271
1269 1272 ":dump"
1270 1273 Creates three versions of the files to merge, containing the contents of
1271 1274 local, other and base. These files can then be used to perform a merge
1272 1275 manually. If the file to be merged is named "a.txt", these files will
1273 1276 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1274 1277 they will be placed in the same directory as "a.txt".
1275 1278
1276 1279 ":fail"
1277 1280 Rather than attempting to merge files that were modified on both
1278 1281 branches, it marks them as unresolved. The resolve command must be used
1279 1282 to resolve these conflicts.
1280 1283
1281 1284 ":local"
1282 1285 Uses the local version of files as the merged version.
1283 1286
1284 1287 ":merge"
1285 1288 Uses the internal non-interactive simple merge algorithm for merging
1286 1289 files. It will fail if there are any conflicts and leave markers in the
1287 1290 partially merged file. Markers will have two sections, one for each side
1288 1291 of merge.
1289 1292
1290 1293 ":merge-local"
1291 1294 Like :merge, but resolve all conflicts non-interactively in favor of the
1292 1295 local changes.
1293 1296
1294 1297 ":merge-other"
1295 1298 Like :merge, but resolve all conflicts non-interactively in favor of the
1296 1299 other changes.
1297 1300
1298 1301 ":merge3"
1299 1302 Uses the internal non-interactive simple merge algorithm for merging
1300 1303 files. It will fail if there are any conflicts and leave markers in the
1301 1304 partially merged file. Marker will have three sections, one from each
1302 1305 side of the merge and one for the base content.
1303 1306
1304 1307 ":other"
1305 1308 Uses the other version of files as the merged version.
1306 1309
1307 1310 ":prompt"
1308 1311 Asks the user which of the local or the other version to keep as the
1309 1312 merged version.
1310 1313
1311 1314 ":tagmerge"
1312 1315 Uses the internal tag merge algorithm (experimental).
1313 1316
1314 1317 ":union"
1315 1318 Uses the internal non-interactive simple merge algorithm for merging
1316 1319 files. It will use both left and right sides for conflict regions. No
1317 1320 markers are inserted.
1318 1321
1319 1322 Internal tools are always available and do not require a GUI but will by
1320 1323 default not handle symlinks or binary files.
1321 1324
1322 1325 Choosing a merge tool
1323 1326 =====================
1324 1327
1325 1328 Mercurial uses these rules when deciding which merge tool to use:
1326 1329
1327 1330 1. If a tool has been specified with the --tool option to merge or
1328 1331 resolve, it is used. If it is the name of a tool in the merge-tools
1329 1332 configuration, its configuration is used. Otherwise the specified tool
1330 1333 must be executable by the shell.
1331 1334 2. If the "HGMERGE" environment variable is present, its value is used and
1332 1335 must be executable by the shell.
1333 1336 3. If the filename of the file to be merged matches any of the patterns in
1334 1337 the merge-patterns configuration section, the first usable merge tool
1335 1338 corresponding to a matching pattern is used. Here, binary capabilities
1336 1339 of the merge tool are not considered.
1337 1340 4. If ui.merge is set it will be considered next. If the value is not the
1338 1341 name of a configured tool, the specified value is used and must be
1339 1342 executable by the shell. Otherwise the named tool is used if it is
1340 1343 usable.
1341 1344 5. If any usable merge tools are present in the merge-tools configuration
1342 1345 section, the one with the highest priority is used.
1343 1346 6. If a program named "hgmerge" can be found on the system, it is used -
1344 1347 but it will by default not be used for symlinks and binary files.
1345 1348 7. If the file to be merged is not binary and is not a symlink, then
1346 1349 internal ":merge" is used.
1347 1350 8. The merge of the file fails and must be resolved before commit.
1348 1351
1349 1352 Note:
1350 1353 After selecting a merge program, Mercurial will by default attempt to
1351 1354 merge the files using a simple merge algorithm first. Only if it
1352 1355 doesn't succeed because of conflicting changes Mercurial will actually
1353 1356 execute the merge program. Whether to use the simple merge algorithm
1354 1357 first can be controlled by the premerge setting of the merge tool.
1355 1358 Premerge is enabled by default unless the file is binary or a symlink.
1356 1359
1357 1360 See the merge-tools and ui sections of hgrc(5) for details on the
1358 1361 configuration of merge tools.
1359 1362
1360 1363 Test usage of section marks in help documents
1361 1364
1362 1365 $ cd "$TESTDIR"/../doc
1363 1366 $ python check-seclevel.py
1364 1367 $ cd $TESTTMP
1365 1368
1366 1369 #if serve
1367 1370
1368 1371 Test the help pages in hgweb.
1369 1372
1370 1373 Dish up an empty repo; serve it cold.
1371 1374
1372 1375 $ hg init "$TESTTMP/test"
1373 1376 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1374 1377 $ cat hg.pid >> $DAEMON_PIDS
1375 1378
1376 1379 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1377 1380 200 Script output follows
1378 1381
1379 1382 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1380 1383 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1381 1384 <head>
1382 1385 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1383 1386 <meta name="robots" content="index, nofollow" />
1384 1387 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1385 1388 <script type="text/javascript" src="/static/mercurial.js"></script>
1386 1389
1387 1390 <title>Help: Index</title>
1388 1391 </head>
1389 1392 <body>
1390 1393
1391 1394 <div class="container">
1392 1395 <div class="menu">
1393 1396 <div class="logo">
1394 1397 <a href="https://mercurial-scm.org/">
1395 1398 <img src="/static/hglogo.png" alt="mercurial" /></a>
1396 1399 </div>
1397 1400 <ul>
1398 1401 <li><a href="/shortlog">log</a></li>
1399 1402 <li><a href="/graph">graph</a></li>
1400 1403 <li><a href="/tags">tags</a></li>
1401 1404 <li><a href="/bookmarks">bookmarks</a></li>
1402 1405 <li><a href="/branches">branches</a></li>
1403 1406 </ul>
1404 1407 <ul>
1405 1408 <li class="active">help</li>
1406 1409 </ul>
1407 1410 </div>
1408 1411
1409 1412 <div class="main">
1410 1413 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1411 1414 <form class="search" action="/log">
1412 1415
1413 1416 <p><input name="rev" id="search1" type="text" size="30" /></p>
1414 1417 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1415 1418 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1416 1419 </form>
1417 1420 <table class="bigtable">
1418 1421 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
1419 1422
1420 1423 <tr><td>
1421 1424 <a href="/help/config">
1422 1425 config
1423 1426 </a>
1424 1427 </td><td>
1425 1428 Configuration Files
1426 1429 </td></tr>
1427 1430 <tr><td>
1428 1431 <a href="/help/dates">
1429 1432 dates
1430 1433 </a>
1431 1434 </td><td>
1432 1435 Date Formats
1433 1436 </td></tr>
1434 1437 <tr><td>
1435 1438 <a href="/help/diffs">
1436 1439 diffs
1437 1440 </a>
1438 1441 </td><td>
1439 1442 Diff Formats
1440 1443 </td></tr>
1441 1444 <tr><td>
1442 1445 <a href="/help/environment">
1443 1446 environment
1444 1447 </a>
1445 1448 </td><td>
1446 1449 Environment Variables
1447 1450 </td></tr>
1448 1451 <tr><td>
1449 1452 <a href="/help/extensions">
1450 1453 extensions
1451 1454 </a>
1452 1455 </td><td>
1453 1456 Using Additional Features
1454 1457 </td></tr>
1455 1458 <tr><td>
1456 1459 <a href="/help/filesets">
1457 1460 filesets
1458 1461 </a>
1459 1462 </td><td>
1460 1463 Specifying File Sets
1461 1464 </td></tr>
1462 1465 <tr><td>
1463 1466 <a href="/help/glossary">
1464 1467 glossary
1465 1468 </a>
1466 1469 </td><td>
1467 1470 Glossary
1468 1471 </td></tr>
1469 1472 <tr><td>
1470 1473 <a href="/help/hgignore">
1471 1474 hgignore
1472 1475 </a>
1473 1476 </td><td>
1474 1477 Syntax for Mercurial Ignore Files
1475 1478 </td></tr>
1476 1479 <tr><td>
1477 1480 <a href="/help/hgweb">
1478 1481 hgweb
1479 1482 </a>
1480 1483 </td><td>
1481 1484 Configuring hgweb
1482 1485 </td></tr>
1483 1486 <tr><td>
1484 1487 <a href="/help/merge-tools">
1485 1488 merge-tools
1486 1489 </a>
1487 1490 </td><td>
1488 1491 Merge Tools
1489 1492 </td></tr>
1490 1493 <tr><td>
1491 1494 <a href="/help/multirevs">
1492 1495 multirevs
1493 1496 </a>
1494 1497 </td><td>
1495 1498 Specifying Multiple Revisions
1496 1499 </td></tr>
1497 1500 <tr><td>
1498 1501 <a href="/help/patterns">
1499 1502 patterns
1500 1503 </a>
1501 1504 </td><td>
1502 1505 File Name Patterns
1503 1506 </td></tr>
1504 1507 <tr><td>
1505 1508 <a href="/help/phases">
1506 1509 phases
1507 1510 </a>
1508 1511 </td><td>
1509 1512 Working with Phases
1510 1513 </td></tr>
1511 1514 <tr><td>
1512 1515 <a href="/help/revisions">
1513 1516 revisions
1514 1517 </a>
1515 1518 </td><td>
1516 1519 Specifying Single Revisions
1517 1520 </td></tr>
1518 1521 <tr><td>
1519 1522 <a href="/help/revsets">
1520 1523 revsets
1521 1524 </a>
1522 1525 </td><td>
1523 1526 Specifying Revision Sets
1524 1527 </td></tr>
1525 1528 <tr><td>
1526 1529 <a href="/help/scripting">
1527 1530 scripting
1528 1531 </a>
1529 1532 </td><td>
1530 1533 Using Mercurial from scripts and automation
1531 1534 </td></tr>
1532 1535 <tr><td>
1533 1536 <a href="/help/subrepos">
1534 1537 subrepos
1535 1538 </a>
1536 1539 </td><td>
1537 1540 Subrepositories
1538 1541 </td></tr>
1539 1542 <tr><td>
1540 1543 <a href="/help/templating">
1541 1544 templating
1542 1545 </a>
1543 1546 </td><td>
1544 1547 Template Usage
1545 1548 </td></tr>
1546 1549 <tr><td>
1547 1550 <a href="/help/urls">
1548 1551 urls
1549 1552 </a>
1550 1553 </td><td>
1551 1554 URL Paths
1552 1555 </td></tr>
1553 1556 <tr><td>
1554 1557 <a href="/help/topic-containing-verbose">
1555 1558 topic-containing-verbose
1556 1559 </a>
1557 1560 </td><td>
1558 1561 This is the topic to test omit indicating.
1559 1562 </td></tr>
1560 1563
1561 1564 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1562 1565
1563 1566 <tr><td>
1564 1567 <a href="/help/add">
1565 1568 add
1566 1569 </a>
1567 1570 </td><td>
1568 1571 add the specified files on the next commit
1569 1572 </td></tr>
1570 1573 <tr><td>
1571 1574 <a href="/help/annotate">
1572 1575 annotate
1573 1576 </a>
1574 1577 </td><td>
1575 1578 show changeset information by line for each file
1576 1579 </td></tr>
1577 1580 <tr><td>
1578 1581 <a href="/help/clone">
1579 1582 clone
1580 1583 </a>
1581 1584 </td><td>
1582 1585 make a copy of an existing repository
1583 1586 </td></tr>
1584 1587 <tr><td>
1585 1588 <a href="/help/commit">
1586 1589 commit
1587 1590 </a>
1588 1591 </td><td>
1589 1592 commit the specified files or all outstanding changes
1590 1593 </td></tr>
1591 1594 <tr><td>
1592 1595 <a href="/help/diff">
1593 1596 diff
1594 1597 </a>
1595 1598 </td><td>
1596 1599 diff repository (or selected files)
1597 1600 </td></tr>
1598 1601 <tr><td>
1599 1602 <a href="/help/export">
1600 1603 export
1601 1604 </a>
1602 1605 </td><td>
1603 1606 dump the header and diffs for one or more changesets
1604 1607 </td></tr>
1605 1608 <tr><td>
1606 1609 <a href="/help/forget">
1607 1610 forget
1608 1611 </a>
1609 1612 </td><td>
1610 1613 forget the specified files on the next commit
1611 1614 </td></tr>
1612 1615 <tr><td>
1613 1616 <a href="/help/init">
1614 1617 init
1615 1618 </a>
1616 1619 </td><td>
1617 1620 create a new repository in the given directory
1618 1621 </td></tr>
1619 1622 <tr><td>
1620 1623 <a href="/help/log">
1621 1624 log
1622 1625 </a>
1623 1626 </td><td>
1624 1627 show revision history of entire repository or files
1625 1628 </td></tr>
1626 1629 <tr><td>
1627 1630 <a href="/help/merge">
1628 1631 merge
1629 1632 </a>
1630 1633 </td><td>
1631 1634 merge another revision into working directory
1632 1635 </td></tr>
1633 1636 <tr><td>
1634 1637 <a href="/help/pull">
1635 1638 pull
1636 1639 </a>
1637 1640 </td><td>
1638 1641 pull changes from the specified source
1639 1642 </td></tr>
1640 1643 <tr><td>
1641 1644 <a href="/help/push">
1642 1645 push
1643 1646 </a>
1644 1647 </td><td>
1645 1648 push changes to the specified destination
1646 1649 </td></tr>
1647 1650 <tr><td>
1648 1651 <a href="/help/remove">
1649 1652 remove
1650 1653 </a>
1651 1654 </td><td>
1652 1655 remove the specified files on the next commit
1653 1656 </td></tr>
1654 1657 <tr><td>
1655 1658 <a href="/help/serve">
1656 1659 serve
1657 1660 </a>
1658 1661 </td><td>
1659 1662 start stand-alone webserver
1660 1663 </td></tr>
1661 1664 <tr><td>
1662 1665 <a href="/help/status">
1663 1666 status
1664 1667 </a>
1665 1668 </td><td>
1666 1669 show changed files in the working directory
1667 1670 </td></tr>
1668 1671 <tr><td>
1669 1672 <a href="/help/summary">
1670 1673 summary
1671 1674 </a>
1672 1675 </td><td>
1673 1676 summarize working directory state
1674 1677 </td></tr>
1675 1678 <tr><td>
1676 1679 <a href="/help/update">
1677 1680 update
1678 1681 </a>
1679 1682 </td><td>
1680 1683 update working directory (or switch revisions)
1681 1684 </td></tr>
1682 1685
1683 1686 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1684 1687
1685 1688 <tr><td>
1686 1689 <a href="/help/addremove">
1687 1690 addremove
1688 1691 </a>
1689 1692 </td><td>
1690 1693 add all new files, delete all missing files
1691 1694 </td></tr>
1692 1695 <tr><td>
1693 1696 <a href="/help/archive">
1694 1697 archive
1695 1698 </a>
1696 1699 </td><td>
1697 1700 create an unversioned archive of a repository revision
1698 1701 </td></tr>
1699 1702 <tr><td>
1700 1703 <a href="/help/backout">
1701 1704 backout
1702 1705 </a>
1703 1706 </td><td>
1704 1707 reverse effect of earlier changeset
1705 1708 </td></tr>
1706 1709 <tr><td>
1707 1710 <a href="/help/bisect">
1708 1711 bisect
1709 1712 </a>
1710 1713 </td><td>
1711 1714 subdivision search of changesets
1712 1715 </td></tr>
1713 1716 <tr><td>
1714 1717 <a href="/help/bookmarks">
1715 1718 bookmarks
1716 1719 </a>
1717 1720 </td><td>
1718 1721 create a new bookmark or list existing bookmarks
1719 1722 </td></tr>
1720 1723 <tr><td>
1721 1724 <a href="/help/branch">
1722 1725 branch
1723 1726 </a>
1724 1727 </td><td>
1725 1728 set or show the current branch name
1726 1729 </td></tr>
1727 1730 <tr><td>
1728 1731 <a href="/help/branches">
1729 1732 branches
1730 1733 </a>
1731 1734 </td><td>
1732 1735 list repository named branches
1733 1736 </td></tr>
1734 1737 <tr><td>
1735 1738 <a href="/help/bundle">
1736 1739 bundle
1737 1740 </a>
1738 1741 </td><td>
1739 1742 create a changegroup file
1740 1743 </td></tr>
1741 1744 <tr><td>
1742 1745 <a href="/help/cat">
1743 1746 cat
1744 1747 </a>
1745 1748 </td><td>
1746 1749 output the current or given revision of files
1747 1750 </td></tr>
1748 1751 <tr><td>
1749 1752 <a href="/help/config">
1750 1753 config
1751 1754 </a>
1752 1755 </td><td>
1753 1756 show combined config settings from all hgrc files
1754 1757 </td></tr>
1755 1758 <tr><td>
1756 1759 <a href="/help/copy">
1757 1760 copy
1758 1761 </a>
1759 1762 </td><td>
1760 1763 mark files as copied for the next commit
1761 1764 </td></tr>
1762 1765 <tr><td>
1763 1766 <a href="/help/files">
1764 1767 files
1765 1768 </a>
1766 1769 </td><td>
1767 1770 list tracked files
1768 1771 </td></tr>
1769 1772 <tr><td>
1770 1773 <a href="/help/graft">
1771 1774 graft
1772 1775 </a>
1773 1776 </td><td>
1774 1777 copy changes from other branches onto the current branch
1775 1778 </td></tr>
1776 1779 <tr><td>
1777 1780 <a href="/help/grep">
1778 1781 grep
1779 1782 </a>
1780 1783 </td><td>
1781 1784 search for a pattern in specified files and revisions
1782 1785 </td></tr>
1783 1786 <tr><td>
1784 1787 <a href="/help/heads">
1785 1788 heads
1786 1789 </a>
1787 1790 </td><td>
1788 1791 show branch heads
1789 1792 </td></tr>
1790 1793 <tr><td>
1791 1794 <a href="/help/help">
1792 1795 help
1793 1796 </a>
1794 1797 </td><td>
1795 1798 show help for a given topic or a help overview
1796 1799 </td></tr>
1797 1800 <tr><td>
1798 1801 <a href="/help/identify">
1799 1802 identify
1800 1803 </a>
1801 1804 </td><td>
1802 1805 identify the working directory or specified revision
1803 1806 </td></tr>
1804 1807 <tr><td>
1805 1808 <a href="/help/import">
1806 1809 import
1807 1810 </a>
1808 1811 </td><td>
1809 1812 import an ordered set of patches
1810 1813 </td></tr>
1811 1814 <tr><td>
1812 1815 <a href="/help/incoming">
1813 1816 incoming
1814 1817 </a>
1815 1818 </td><td>
1816 1819 show new changesets found in source
1817 1820 </td></tr>
1818 1821 <tr><td>
1819 1822 <a href="/help/manifest">
1820 1823 manifest
1821 1824 </a>
1822 1825 </td><td>
1823 1826 output the current or given revision of the project manifest
1824 1827 </td></tr>
1825 1828 <tr><td>
1826 1829 <a href="/help/nohelp">
1827 1830 nohelp
1828 1831 </a>
1829 1832 </td><td>
1830 1833 (no help text available)
1831 1834 </td></tr>
1832 1835 <tr><td>
1833 1836 <a href="/help/outgoing">
1834 1837 outgoing
1835 1838 </a>
1836 1839 </td><td>
1837 1840 show changesets not found in the destination
1838 1841 </td></tr>
1839 1842 <tr><td>
1840 1843 <a href="/help/paths">
1841 1844 paths
1842 1845 </a>
1843 1846 </td><td>
1844 1847 show aliases for remote repositories
1845 1848 </td></tr>
1846 1849 <tr><td>
1847 1850 <a href="/help/phase">
1848 1851 phase
1849 1852 </a>
1850 1853 </td><td>
1851 1854 set or show the current phase name
1852 1855 </td></tr>
1853 1856 <tr><td>
1854 1857 <a href="/help/recover">
1855 1858 recover
1856 1859 </a>
1857 1860 </td><td>
1858 1861 roll back an interrupted transaction
1859 1862 </td></tr>
1860 1863 <tr><td>
1861 1864 <a href="/help/rename">
1862 1865 rename
1863 1866 </a>
1864 1867 </td><td>
1865 1868 rename files; equivalent of copy + remove
1866 1869 </td></tr>
1867 1870 <tr><td>
1868 1871 <a href="/help/resolve">
1869 1872 resolve
1870 1873 </a>
1871 1874 </td><td>
1872 1875 redo merges or set/view the merge status of files
1873 1876 </td></tr>
1874 1877 <tr><td>
1875 1878 <a href="/help/revert">
1876 1879 revert
1877 1880 </a>
1878 1881 </td><td>
1879 1882 restore files to their checkout state
1880 1883 </td></tr>
1881 1884 <tr><td>
1882 1885 <a href="/help/root">
1883 1886 root
1884 1887 </a>
1885 1888 </td><td>
1886 1889 print the root (top) of the current working directory
1887 1890 </td></tr>
1888 1891 <tr><td>
1889 1892 <a href="/help/tag">
1890 1893 tag
1891 1894 </a>
1892 1895 </td><td>
1893 1896 add one or more tags for the current or given revision
1894 1897 </td></tr>
1895 1898 <tr><td>
1896 1899 <a href="/help/tags">
1897 1900 tags
1898 1901 </a>
1899 1902 </td><td>
1900 1903 list repository tags
1901 1904 </td></tr>
1902 1905 <tr><td>
1903 1906 <a href="/help/unbundle">
1904 1907 unbundle
1905 1908 </a>
1906 1909 </td><td>
1907 1910 apply one or more changegroup files
1908 1911 </td></tr>
1909 1912 <tr><td>
1910 1913 <a href="/help/verify">
1911 1914 verify
1912 1915 </a>
1913 1916 </td><td>
1914 1917 verify the integrity of the repository
1915 1918 </td></tr>
1916 1919 <tr><td>
1917 1920 <a href="/help/version">
1918 1921 version
1919 1922 </a>
1920 1923 </td><td>
1921 1924 output version and copyright information
1922 1925 </td></tr>
1923 1926 </table>
1924 1927 </div>
1925 1928 </div>
1926 1929
1927 1930 <script type="text/javascript">process_dates()</script>
1928 1931
1929 1932
1930 1933 </body>
1931 1934 </html>
1932 1935
1933 1936
1934 1937 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
1935 1938 200 Script output follows
1936 1939
1937 1940 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1938 1941 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1939 1942 <head>
1940 1943 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1941 1944 <meta name="robots" content="index, nofollow" />
1942 1945 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1943 1946 <script type="text/javascript" src="/static/mercurial.js"></script>
1944 1947
1945 1948 <title>Help: add</title>
1946 1949 </head>
1947 1950 <body>
1948 1951
1949 1952 <div class="container">
1950 1953 <div class="menu">
1951 1954 <div class="logo">
1952 1955 <a href="https://mercurial-scm.org/">
1953 1956 <img src="/static/hglogo.png" alt="mercurial" /></a>
1954 1957 </div>
1955 1958 <ul>
1956 1959 <li><a href="/shortlog">log</a></li>
1957 1960 <li><a href="/graph">graph</a></li>
1958 1961 <li><a href="/tags">tags</a></li>
1959 1962 <li><a href="/bookmarks">bookmarks</a></li>
1960 1963 <li><a href="/branches">branches</a></li>
1961 1964 </ul>
1962 1965 <ul>
1963 1966 <li class="active"><a href="/help">help</a></li>
1964 1967 </ul>
1965 1968 </div>
1966 1969
1967 1970 <div class="main">
1968 1971 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1969 1972 <h3>Help: add</h3>
1970 1973
1971 1974 <form class="search" action="/log">
1972 1975
1973 1976 <p><input name="rev" id="search1" type="text" size="30" /></p>
1974 1977 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1975 1978 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1976 1979 </form>
1977 1980 <div id="doc">
1978 1981 <p>
1979 1982 hg add [OPTION]... [FILE]...
1980 1983 </p>
1981 1984 <p>
1982 1985 add the specified files on the next commit
1983 1986 </p>
1984 1987 <p>
1985 1988 Schedule files to be version controlled and added to the
1986 1989 repository.
1987 1990 </p>
1988 1991 <p>
1989 1992 The files will be added to the repository at the next commit. To
1990 1993 undo an add before that, see &quot;hg forget&quot;.
1991 1994 </p>
1992 1995 <p>
1993 1996 If no names are given, add all files to the repository.
1994 1997 </p>
1995 1998 <p>
1996 1999 An example showing how new (unknown) files are added
1997 2000 automatically by &quot;hg add&quot;:
1998 2001 </p>
1999 2002 <pre>
2000 2003 \$ ls (re)
2001 2004 foo.c
2002 2005 \$ hg status (re)
2003 2006 ? foo.c
2004 2007 \$ hg add (re)
2005 2008 adding foo.c
2006 2009 \$ hg status (re)
2007 2010 A foo.c
2008 2011 </pre>
2009 2012 <p>
2010 2013 Returns 0 if all files are successfully added.
2011 2014 </p>
2012 2015 <p>
2013 2016 options ([+] can be repeated):
2014 2017 </p>
2015 2018 <table>
2016 2019 <tr><td>-I</td>
2017 2020 <td>--include PATTERN [+]</td>
2018 2021 <td>include names matching the given patterns</td></tr>
2019 2022 <tr><td>-X</td>
2020 2023 <td>--exclude PATTERN [+]</td>
2021 2024 <td>exclude names matching the given patterns</td></tr>
2022 2025 <tr><td>-S</td>
2023 2026 <td>--subrepos</td>
2024 2027 <td>recurse into subrepositories</td></tr>
2025 2028 <tr><td>-n</td>
2026 2029 <td>--dry-run</td>
2027 2030 <td>do not perform actions, just print output</td></tr>
2028 2031 </table>
2029 2032 <p>
2030 2033 global options ([+] can be repeated):
2031 2034 </p>
2032 2035 <table>
2033 2036 <tr><td>-R</td>
2034 2037 <td>--repository REPO</td>
2035 2038 <td>repository root directory or name of overlay bundle file</td></tr>
2036 2039 <tr><td></td>
2037 2040 <td>--cwd DIR</td>
2038 2041 <td>change working directory</td></tr>
2039 2042 <tr><td>-y</td>
2040 2043 <td>--noninteractive</td>
2041 2044 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2042 2045 <tr><td>-q</td>
2043 2046 <td>--quiet</td>
2044 2047 <td>suppress output</td></tr>
2045 2048 <tr><td>-v</td>
2046 2049 <td>--verbose</td>
2047 2050 <td>enable additional output</td></tr>
2048 2051 <tr><td></td>
2049 2052 <td>--config CONFIG [+]</td>
2050 2053 <td>set/override config option (use 'section.name=value')</td></tr>
2051 2054 <tr><td></td>
2052 2055 <td>--debug</td>
2053 2056 <td>enable debugging output</td></tr>
2054 2057 <tr><td></td>
2055 2058 <td>--debugger</td>
2056 2059 <td>start debugger</td></tr>
2057 2060 <tr><td></td>
2058 2061 <td>--encoding ENCODE</td>
2059 2062 <td>set the charset encoding (default: ascii)</td></tr>
2060 2063 <tr><td></td>
2061 2064 <td>--encodingmode MODE</td>
2062 2065 <td>set the charset encoding mode (default: strict)</td></tr>
2063 2066 <tr><td></td>
2064 2067 <td>--traceback</td>
2065 2068 <td>always print a traceback on exception</td></tr>
2066 2069 <tr><td></td>
2067 2070 <td>--time</td>
2068 2071 <td>time how long the command takes</td></tr>
2069 2072 <tr><td></td>
2070 2073 <td>--profile</td>
2071 2074 <td>print command execution profile</td></tr>
2072 2075 <tr><td></td>
2073 2076 <td>--version</td>
2074 2077 <td>output version information and exit</td></tr>
2075 2078 <tr><td>-h</td>
2076 2079 <td>--help</td>
2077 2080 <td>display help and exit</td></tr>
2078 2081 <tr><td></td>
2079 2082 <td>--hidden</td>
2080 2083 <td>consider hidden changesets</td></tr>
2081 2084 </table>
2082 2085
2083 2086 </div>
2084 2087 </div>
2085 2088 </div>
2086 2089
2087 2090 <script type="text/javascript">process_dates()</script>
2088 2091
2089 2092
2090 2093 </body>
2091 2094 </html>
2092 2095
2093 2096
2094 2097 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2095 2098 200 Script output follows
2096 2099
2097 2100 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2098 2101 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2099 2102 <head>
2100 2103 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2101 2104 <meta name="robots" content="index, nofollow" />
2102 2105 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2103 2106 <script type="text/javascript" src="/static/mercurial.js"></script>
2104 2107
2105 2108 <title>Help: remove</title>
2106 2109 </head>
2107 2110 <body>
2108 2111
2109 2112 <div class="container">
2110 2113 <div class="menu">
2111 2114 <div class="logo">
2112 2115 <a href="https://mercurial-scm.org/">
2113 2116 <img src="/static/hglogo.png" alt="mercurial" /></a>
2114 2117 </div>
2115 2118 <ul>
2116 2119 <li><a href="/shortlog">log</a></li>
2117 2120 <li><a href="/graph">graph</a></li>
2118 2121 <li><a href="/tags">tags</a></li>
2119 2122 <li><a href="/bookmarks">bookmarks</a></li>
2120 2123 <li><a href="/branches">branches</a></li>
2121 2124 </ul>
2122 2125 <ul>
2123 2126 <li class="active"><a href="/help">help</a></li>
2124 2127 </ul>
2125 2128 </div>
2126 2129
2127 2130 <div class="main">
2128 2131 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2129 2132 <h3>Help: remove</h3>
2130 2133
2131 2134 <form class="search" action="/log">
2132 2135
2133 2136 <p><input name="rev" id="search1" type="text" size="30" /></p>
2134 2137 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2135 2138 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2136 2139 </form>
2137 2140 <div id="doc">
2138 2141 <p>
2139 2142 hg remove [OPTION]... FILE...
2140 2143 </p>
2141 2144 <p>
2142 2145 aliases: rm
2143 2146 </p>
2144 2147 <p>
2145 2148 remove the specified files on the next commit
2146 2149 </p>
2147 2150 <p>
2148 2151 Schedule the indicated files for removal from the current branch.
2149 2152 </p>
2150 2153 <p>
2151 2154 This command schedules the files to be removed at the next commit.
2152 2155 To undo a remove before that, see &quot;hg revert&quot;. To undo added
2153 2156 files, see &quot;hg forget&quot;.
2154 2157 </p>
2155 2158 <p>
2156 2159 -A/--after can be used to remove only files that have already
2157 2160 been deleted, -f/--force can be used to force deletion, and -Af
2158 2161 can be used to remove files from the next revision without
2159 2162 deleting them from the working directory.
2160 2163 </p>
2161 2164 <p>
2162 2165 The following table details the behavior of remove for different
2163 2166 file states (columns) and option combinations (rows). The file
2164 2167 states are Added [A], Clean [C], Modified [M] and Missing [!]
2165 2168 (as reported by &quot;hg status&quot;). The actions are Warn, Remove
2166 2169 (from branch) and Delete (from disk):
2167 2170 </p>
2168 2171 <table>
2169 2172 <tr><td>opt/state</td>
2170 2173 <td>A</td>
2171 2174 <td>C</td>
2172 2175 <td>M</td>
2173 2176 <td>!</td></tr>
2174 2177 <tr><td>none</td>
2175 2178 <td>W</td>
2176 2179 <td>RD</td>
2177 2180 <td>W</td>
2178 2181 <td>R</td></tr>
2179 2182 <tr><td>-f</td>
2180 2183 <td>R</td>
2181 2184 <td>RD</td>
2182 2185 <td>RD</td>
2183 2186 <td>R</td></tr>
2184 2187 <tr><td>-A</td>
2185 2188 <td>W</td>
2186 2189 <td>W</td>
2187 2190 <td>W</td>
2188 2191 <td>R</td></tr>
2189 2192 <tr><td>-Af</td>
2190 2193 <td>R</td>
2191 2194 <td>R</td>
2192 2195 <td>R</td>
2193 2196 <td>R</td></tr>
2194 2197 </table>
2195 2198 <p>
2196 2199 Note that remove never deletes files in Added [A] state from the
2197 2200 working directory, not even if option --force is specified.
2198 2201 </p>
2199 2202 <p>
2200 2203 Returns 0 on success, 1 if any warnings encountered.
2201 2204 </p>
2202 2205 <p>
2203 2206 options ([+] can be repeated):
2204 2207 </p>
2205 2208 <table>
2206 2209 <tr><td>-A</td>
2207 2210 <td>--after</td>
2208 2211 <td>record delete for missing files</td></tr>
2209 2212 <tr><td>-f</td>
2210 2213 <td>--force</td>
2211 2214 <td>remove (and delete) file even if added or modified</td></tr>
2212 2215 <tr><td>-S</td>
2213 2216 <td>--subrepos</td>
2214 2217 <td>recurse into subrepositories</td></tr>
2215 2218 <tr><td>-I</td>
2216 2219 <td>--include PATTERN [+]</td>
2217 2220 <td>include names matching the given patterns</td></tr>
2218 2221 <tr><td>-X</td>
2219 2222 <td>--exclude PATTERN [+]</td>
2220 2223 <td>exclude names matching the given patterns</td></tr>
2221 2224 </table>
2222 2225 <p>
2223 2226 global options ([+] can be repeated):
2224 2227 </p>
2225 2228 <table>
2226 2229 <tr><td>-R</td>
2227 2230 <td>--repository REPO</td>
2228 2231 <td>repository root directory or name of overlay bundle file</td></tr>
2229 2232 <tr><td></td>
2230 2233 <td>--cwd DIR</td>
2231 2234 <td>change working directory</td></tr>
2232 2235 <tr><td>-y</td>
2233 2236 <td>--noninteractive</td>
2234 2237 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2235 2238 <tr><td>-q</td>
2236 2239 <td>--quiet</td>
2237 2240 <td>suppress output</td></tr>
2238 2241 <tr><td>-v</td>
2239 2242 <td>--verbose</td>
2240 2243 <td>enable additional output</td></tr>
2241 2244 <tr><td></td>
2242 2245 <td>--config CONFIG [+]</td>
2243 2246 <td>set/override config option (use 'section.name=value')</td></tr>
2244 2247 <tr><td></td>
2245 2248 <td>--debug</td>
2246 2249 <td>enable debugging output</td></tr>
2247 2250 <tr><td></td>
2248 2251 <td>--debugger</td>
2249 2252 <td>start debugger</td></tr>
2250 2253 <tr><td></td>
2251 2254 <td>--encoding ENCODE</td>
2252 2255 <td>set the charset encoding (default: ascii)</td></tr>
2253 2256 <tr><td></td>
2254 2257 <td>--encodingmode MODE</td>
2255 2258 <td>set the charset encoding mode (default: strict)</td></tr>
2256 2259 <tr><td></td>
2257 2260 <td>--traceback</td>
2258 2261 <td>always print a traceback on exception</td></tr>
2259 2262 <tr><td></td>
2260 2263 <td>--time</td>
2261 2264 <td>time how long the command takes</td></tr>
2262 2265 <tr><td></td>
2263 2266 <td>--profile</td>
2264 2267 <td>print command execution profile</td></tr>
2265 2268 <tr><td></td>
2266 2269 <td>--version</td>
2267 2270 <td>output version information and exit</td></tr>
2268 2271 <tr><td>-h</td>
2269 2272 <td>--help</td>
2270 2273 <td>display help and exit</td></tr>
2271 2274 <tr><td></td>
2272 2275 <td>--hidden</td>
2273 2276 <td>consider hidden changesets</td></tr>
2274 2277 </table>
2275 2278
2276 2279 </div>
2277 2280 </div>
2278 2281 </div>
2279 2282
2280 2283 <script type="text/javascript">process_dates()</script>
2281 2284
2282 2285
2283 2286 </body>
2284 2287 </html>
2285 2288
2286 2289
2287 2290 $ get-with-headers.py 127.0.0.1:$HGPORT "help/revisions"
2288 2291 200 Script output follows
2289 2292
2290 2293 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2291 2294 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2292 2295 <head>
2293 2296 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2294 2297 <meta name="robots" content="index, nofollow" />
2295 2298 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2296 2299 <script type="text/javascript" src="/static/mercurial.js"></script>
2297 2300
2298 2301 <title>Help: revisions</title>
2299 2302 </head>
2300 2303 <body>
2301 2304
2302 2305 <div class="container">
2303 2306 <div class="menu">
2304 2307 <div class="logo">
2305 2308 <a href="https://mercurial-scm.org/">
2306 2309 <img src="/static/hglogo.png" alt="mercurial" /></a>
2307 2310 </div>
2308 2311 <ul>
2309 2312 <li><a href="/shortlog">log</a></li>
2310 2313 <li><a href="/graph">graph</a></li>
2311 2314 <li><a href="/tags">tags</a></li>
2312 2315 <li><a href="/bookmarks">bookmarks</a></li>
2313 2316 <li><a href="/branches">branches</a></li>
2314 2317 </ul>
2315 2318 <ul>
2316 2319 <li class="active"><a href="/help">help</a></li>
2317 2320 </ul>
2318 2321 </div>
2319 2322
2320 2323 <div class="main">
2321 2324 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2322 2325 <h3>Help: revisions</h3>
2323 2326
2324 2327 <form class="search" action="/log">
2325 2328
2326 2329 <p><input name="rev" id="search1" type="text" size="30" /></p>
2327 2330 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2328 2331 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2329 2332 </form>
2330 2333 <div id="doc">
2331 2334 <h1>Specifying Single Revisions</h1>
2332 2335 <p>
2333 2336 Mercurial supports several ways to specify individual revisions.
2334 2337 </p>
2335 2338 <p>
2336 2339 A plain integer is treated as a revision number. Negative integers are
2337 2340 treated as sequential offsets from the tip, with -1 denoting the tip,
2338 2341 -2 denoting the revision prior to the tip, and so forth.
2339 2342 </p>
2340 2343 <p>
2341 2344 A 40-digit hexadecimal string is treated as a unique revision
2342 2345 identifier.
2343 2346 </p>
2344 2347 <p>
2345 2348 A hexadecimal string less than 40 characters long is treated as a
2346 2349 unique revision identifier and is referred to as a short-form
2347 2350 identifier. A short-form identifier is only valid if it is the prefix
2348 2351 of exactly one full-length identifier.
2349 2352 </p>
2350 2353 <p>
2351 2354 Any other string is treated as a bookmark, tag, or branch name. A
2352 2355 bookmark is a movable pointer to a revision. A tag is a permanent name
2353 2356 associated with a revision. A branch name denotes the tipmost open branch head
2354 2357 of that branch - or if they are all closed, the tipmost closed head of the
2355 2358 branch. Bookmark, tag, and branch names must not contain the &quot;:&quot; character.
2356 2359 </p>
2357 2360 <p>
2358 2361 The reserved name &quot;tip&quot; always identifies the most recent revision.
2359 2362 </p>
2360 2363 <p>
2361 2364 The reserved name &quot;null&quot; indicates the null revision. This is the
2362 2365 revision of an empty repository, and the parent of revision 0.
2363 2366 </p>
2364 2367 <p>
2365 2368 The reserved name &quot;.&quot; indicates the working directory parent. If no
2366 2369 working directory is checked out, it is equivalent to null. If an
2367 2370 uncommitted merge is in progress, &quot;.&quot; is the revision of the first
2368 2371 parent.
2369 2372 </p>
2370 2373
2371 2374 </div>
2372 2375 </div>
2373 2376 </div>
2374 2377
2375 2378 <script type="text/javascript">process_dates()</script>
2376 2379
2377 2380
2378 2381 </body>
2379 2382 </html>
2380 2383
2381 2384
2382 2385 $ killdaemons.py
2383 2386
2384 2387 #endif
General Comments 0
You need to be logged in to leave comments. Login now