##// END OF EJS Templates
commands: add a new debug command to print merge state...
Siddharth Agarwal -
r26501:0748083f default
parent child Browse files
Show More
@@ -1,6577 +1,6642 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
24 24 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
25 25 import ui as uimod
26 26
27 27 table = {}
28 28
29 29 command = cmdutil.command(table)
30 30
31 31 # Space delimited list of commands that don't require local repositories.
32 32 # This should be populated by passing norepo=True into the @command decorator.
33 33 norepo = ''
34 34 # Space delimited list of commands that optionally require local repositories.
35 35 # This should be populated by passing optionalrepo=True into the @command
36 36 # decorator.
37 37 optionalrepo = ''
38 38 # Space delimited list of commands that will examine arguments looking for
39 39 # a repository. This should be populated by passing inferrepo=True into the
40 40 # @command decorator.
41 41 inferrepo = ''
42 42
43 43 # label constants
44 44 # until 3.5, bookmarks.current was the advertised name, not
45 45 # bookmarks.active, so we must use both to avoid breaking old
46 46 # custom styles
47 47 activebookmarklabel = 'bookmarks.active bookmarks.current'
48 48
49 49 # common command options
50 50
51 51 globalopts = [
52 52 ('R', 'repository', '',
53 53 _('repository root directory or name of overlay bundle file'),
54 54 _('REPO')),
55 55 ('', 'cwd', '',
56 56 _('change working directory'), _('DIR')),
57 57 ('y', 'noninteractive', None,
58 58 _('do not prompt, automatically pick the first choice for all prompts')),
59 59 ('q', 'quiet', None, _('suppress output')),
60 60 ('v', 'verbose', None, _('enable additional output')),
61 61 ('', 'config', [],
62 62 _('set/override config option (use \'section.name=value\')'),
63 63 _('CONFIG')),
64 64 ('', 'debug', None, _('enable debugging output')),
65 65 ('', 'debugger', None, _('start debugger')),
66 66 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
67 67 _('ENCODE')),
68 68 ('', 'encodingmode', encoding.encodingmode,
69 69 _('set the charset encoding mode'), _('MODE')),
70 70 ('', 'traceback', None, _('always print a traceback on exception')),
71 71 ('', 'time', None, _('time how long the command takes')),
72 72 ('', 'profile', None, _('print command execution profile')),
73 73 ('', 'version', None, _('output version information and exit')),
74 74 ('h', 'help', None, _('display help and exit')),
75 75 ('', 'hidden', False, _('consider hidden changesets')),
76 76 ]
77 77
78 78 dryrunopts = [('n', 'dry-run', None,
79 79 _('do not perform actions, just print output'))]
80 80
81 81 remoteopts = [
82 82 ('e', 'ssh', '',
83 83 _('specify ssh command to use'), _('CMD')),
84 84 ('', 'remotecmd', '',
85 85 _('specify hg command to run on the remote side'), _('CMD')),
86 86 ('', 'insecure', None,
87 87 _('do not verify server certificate (ignoring web.cacerts config)')),
88 88 ]
89 89
90 90 walkopts = [
91 91 ('I', 'include', [],
92 92 _('include names matching the given patterns'), _('PATTERN')),
93 93 ('X', 'exclude', [],
94 94 _('exclude names matching the given patterns'), _('PATTERN')),
95 95 ]
96 96
97 97 commitopts = [
98 98 ('m', 'message', '',
99 99 _('use text as commit message'), _('TEXT')),
100 100 ('l', 'logfile', '',
101 101 _('read commit message from file'), _('FILE')),
102 102 ]
103 103
104 104 commitopts2 = [
105 105 ('d', 'date', '',
106 106 _('record the specified date as commit date'), _('DATE')),
107 107 ('u', 'user', '',
108 108 _('record the specified user as committer'), _('USER')),
109 109 ]
110 110
111 111 # hidden for now
112 112 formatteropts = [
113 113 ('T', 'template', '',
114 114 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
115 115 ]
116 116
117 117 templateopts = [
118 118 ('', 'style', '',
119 119 _('display using template map file (DEPRECATED)'), _('STYLE')),
120 120 ('T', 'template', '',
121 121 _('display with template'), _('TEMPLATE')),
122 122 ]
123 123
124 124 logopts = [
125 125 ('p', 'patch', None, _('show patch')),
126 126 ('g', 'git', None, _('use git extended diff format')),
127 127 ('l', 'limit', '',
128 128 _('limit number of changes displayed'), _('NUM')),
129 129 ('M', 'no-merges', None, _('do not show merges')),
130 130 ('', 'stat', None, _('output diffstat-style summary of changes')),
131 131 ('G', 'graph', None, _("show the revision DAG")),
132 132 ] + templateopts
133 133
134 134 diffopts = [
135 135 ('a', 'text', None, _('treat all files as text')),
136 136 ('g', 'git', None, _('use git extended diff format')),
137 137 ('', 'nodates', None, _('omit dates from diff headers'))
138 138 ]
139 139
140 140 diffwsopts = [
141 141 ('w', 'ignore-all-space', None,
142 142 _('ignore white space when comparing lines')),
143 143 ('b', 'ignore-space-change', None,
144 144 _('ignore changes in the amount of white space')),
145 145 ('B', 'ignore-blank-lines', None,
146 146 _('ignore changes whose lines are all blank')),
147 147 ]
148 148
149 149 diffopts2 = [
150 150 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
151 151 ('p', 'show-function', None, _('show which function each change is in')),
152 152 ('', 'reverse', None, _('produce a diff that undoes the changes')),
153 153 ] + diffwsopts + [
154 154 ('U', 'unified', '',
155 155 _('number of lines of context to show'), _('NUM')),
156 156 ('', 'stat', None, _('output diffstat-style summary of changes')),
157 157 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
158 158 ]
159 159
160 160 mergetoolopts = [
161 161 ('t', 'tool', '', _('specify merge tool')),
162 162 ]
163 163
164 164 similarityopts = [
165 165 ('s', 'similarity', '',
166 166 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
167 167 ]
168 168
169 169 subrepoopts = [
170 170 ('S', 'subrepos', None,
171 171 _('recurse into subrepositories'))
172 172 ]
173 173
174 174 # Commands start here, listed alphabetically
175 175
176 176 @command('^add',
177 177 walkopts + subrepoopts + dryrunopts,
178 178 _('[OPTION]... [FILE]...'),
179 179 inferrepo=True)
180 180 def add(ui, repo, *pats, **opts):
181 181 """add the specified files on the next commit
182 182
183 183 Schedule files to be version controlled and added to the
184 184 repository.
185 185
186 186 The files will be added to the repository at the next commit. To
187 187 undo an add before that, see :hg:`forget`.
188 188
189 189 If no names are given, add all files to the repository.
190 190
191 191 .. container:: verbose
192 192
193 193 An example showing how new (unknown) files are added
194 194 automatically by :hg:`add`::
195 195
196 196 $ ls
197 197 foo.c
198 198 $ hg status
199 199 ? foo.c
200 200 $ hg add
201 201 adding foo.c
202 202 $ hg status
203 203 A foo.c
204 204
205 205 Returns 0 if all files are successfully added.
206 206 """
207 207
208 208 m = scmutil.match(repo[None], pats, opts)
209 209 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
210 210 return rejected and 1 or 0
211 211
212 212 @command('addremove',
213 213 similarityopts + subrepoopts + walkopts + dryrunopts,
214 214 _('[OPTION]... [FILE]...'),
215 215 inferrepo=True)
216 216 def addremove(ui, repo, *pats, **opts):
217 217 """add all new files, delete all missing files
218 218
219 219 Add all new files and remove all missing files from the
220 220 repository.
221 221
222 222 New files are ignored if they match any of the patterns in
223 223 ``.hgignore``. As with add, these changes take effect at the next
224 224 commit.
225 225
226 226 Use the -s/--similarity option to detect renamed files. This
227 227 option takes a percentage between 0 (disabled) and 100 (files must
228 228 be identical) as its parameter. With a parameter greater than 0,
229 229 this compares every removed file with every added file and records
230 230 those similar enough as renames. Detecting renamed files this way
231 231 can be expensive. After using this option, :hg:`status -C` can be
232 232 used to check which files were identified as moved or renamed. If
233 233 not specified, -s/--similarity defaults to 100 and only renames of
234 234 identical files are detected.
235 235
236 236 Returns 0 if all files are successfully added.
237 237 """
238 238 try:
239 239 sim = float(opts.get('similarity') or 100)
240 240 except ValueError:
241 241 raise util.Abort(_('similarity must be a number'))
242 242 if sim < 0 or sim > 100:
243 243 raise util.Abort(_('similarity must be between 0 and 100'))
244 244 matcher = scmutil.match(repo[None], pats, opts)
245 245 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
246 246
247 247 @command('^annotate|blame',
248 248 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
249 249 ('', 'follow', None,
250 250 _('follow copies/renames and list the filename (DEPRECATED)')),
251 251 ('', 'no-follow', None, _("don't follow copies and renames")),
252 252 ('a', 'text', None, _('treat all files as text')),
253 253 ('u', 'user', None, _('list the author (long with -v)')),
254 254 ('f', 'file', None, _('list the filename')),
255 255 ('d', 'date', None, _('list the date (short with -q)')),
256 256 ('n', 'number', None, _('list the revision number (default)')),
257 257 ('c', 'changeset', None, _('list the changeset')),
258 258 ('l', 'line-number', None, _('show line number at the first appearance'))
259 259 ] + diffwsopts + walkopts + formatteropts,
260 260 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
261 261 inferrepo=True)
262 262 def annotate(ui, repo, *pats, **opts):
263 263 """show changeset information by line for each file
264 264
265 265 List changes in files, showing the revision id responsible for
266 266 each line
267 267
268 268 This command is useful for discovering when a change was made and
269 269 by whom.
270 270
271 271 Without the -a/--text option, annotate will avoid processing files
272 272 it detects as binary. With -a, annotate will annotate the file
273 273 anyway, although the results will probably be neither useful
274 274 nor desirable.
275 275
276 276 Returns 0 on success.
277 277 """
278 278 if not pats:
279 279 raise util.Abort(_('at least one filename or pattern is required'))
280 280
281 281 if opts.get('follow'):
282 282 # --follow is deprecated and now just an alias for -f/--file
283 283 # to mimic the behavior of Mercurial before version 1.5
284 284 opts['file'] = True
285 285
286 286 ctx = scmutil.revsingle(repo, opts.get('rev'))
287 287
288 288 fm = ui.formatter('annotate', opts)
289 289 if ui.quiet:
290 290 datefunc = util.shortdate
291 291 else:
292 292 datefunc = util.datestr
293 293 if ctx.rev() is None:
294 294 def hexfn(node):
295 295 if node is None:
296 296 return None
297 297 else:
298 298 return fm.hexfunc(node)
299 299 if opts.get('changeset'):
300 300 # omit "+" suffix which is appended to node hex
301 301 def formatrev(rev):
302 302 if rev is None:
303 303 return '%d' % ctx.p1().rev()
304 304 else:
305 305 return '%d' % rev
306 306 else:
307 307 def formatrev(rev):
308 308 if rev is None:
309 309 return '%d+' % ctx.p1().rev()
310 310 else:
311 311 return '%d ' % rev
312 312 def formathex(hex):
313 313 if hex is None:
314 314 return '%s+' % fm.hexfunc(ctx.p1().node())
315 315 else:
316 316 return '%s ' % hex
317 317 else:
318 318 hexfn = fm.hexfunc
319 319 formatrev = formathex = str
320 320
321 321 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
322 322 ('number', ' ', lambda x: x[0].rev(), formatrev),
323 323 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
324 324 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
325 325 ('file', ' ', lambda x: x[0].path(), str),
326 326 ('line_number', ':', lambda x: x[1], str),
327 327 ]
328 328 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
329 329
330 330 if (not opts.get('user') and not opts.get('changeset')
331 331 and not opts.get('date') and not opts.get('file')):
332 332 opts['number'] = True
333 333
334 334 linenumber = opts.get('line_number') is not None
335 335 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
336 336 raise util.Abort(_('at least one of -n/-c is required for -l'))
337 337
338 338 if fm:
339 339 def makefunc(get, fmt):
340 340 return get
341 341 else:
342 342 def makefunc(get, fmt):
343 343 return lambda x: fmt(get(x))
344 344 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
345 345 if opts.get(op)]
346 346 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
347 347 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
348 348 if opts.get(op))
349 349
350 350 def bad(x, y):
351 351 raise util.Abort("%s: %s" % (x, y))
352 352
353 353 m = scmutil.match(ctx, pats, opts, badfn=bad)
354 354
355 355 follow = not opts.get('no_follow')
356 356 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
357 357 whitespace=True)
358 358 for abs in ctx.walk(m):
359 359 fctx = ctx[abs]
360 360 if not opts.get('text') and util.binary(fctx.data()):
361 361 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
362 362 continue
363 363
364 364 lines = fctx.annotate(follow=follow, linenumber=linenumber,
365 365 diffopts=diffopts)
366 366 formats = []
367 367 pieces = []
368 368
369 369 for f, sep in funcmap:
370 370 l = [f(n) for n, dummy in lines]
371 371 if l:
372 372 if fm:
373 373 formats.append(['%s' for x in l])
374 374 else:
375 375 sizes = [encoding.colwidth(x) for x in l]
376 376 ml = max(sizes)
377 377 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
378 378 pieces.append(l)
379 379
380 380 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
381 381 fm.startitem()
382 382 fm.write(fields, "".join(f), *p)
383 383 fm.write('line', ": %s", l[1])
384 384
385 385 if lines and not lines[-1][1].endswith('\n'):
386 386 fm.plain('\n')
387 387
388 388 fm.end()
389 389
390 390 @command('archive',
391 391 [('', 'no-decode', None, _('do not pass files through decoders')),
392 392 ('p', 'prefix', '', _('directory prefix for files in archive'),
393 393 _('PREFIX')),
394 394 ('r', 'rev', '', _('revision to distribute'), _('REV')),
395 395 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
396 396 ] + subrepoopts + walkopts,
397 397 _('[OPTION]... DEST'))
398 398 def archive(ui, repo, dest, **opts):
399 399 '''create an unversioned archive of a repository revision
400 400
401 401 By default, the revision used is the parent of the working
402 402 directory; use -r/--rev to specify a different revision.
403 403
404 404 The archive type is automatically detected based on file
405 405 extension (or override using -t/--type).
406 406
407 407 .. container:: verbose
408 408
409 409 Examples:
410 410
411 411 - create a zip file containing the 1.0 release::
412 412
413 413 hg archive -r 1.0 project-1.0.zip
414 414
415 415 - create a tarball excluding .hg files::
416 416
417 417 hg archive project.tar.gz -X ".hg*"
418 418
419 419 Valid types are:
420 420
421 421 :``files``: a directory full of files (default)
422 422 :``tar``: tar archive, uncompressed
423 423 :``tbz2``: tar archive, compressed using bzip2
424 424 :``tgz``: tar archive, compressed using gzip
425 425 :``uzip``: zip archive, uncompressed
426 426 :``zip``: zip archive, compressed using deflate
427 427
428 428 The exact name of the destination archive or directory is given
429 429 using a format string; see :hg:`help export` for details.
430 430
431 431 Each member added to an archive file has a directory prefix
432 432 prepended. Use -p/--prefix to specify a format string for the
433 433 prefix. The default is the basename of the archive, with suffixes
434 434 removed.
435 435
436 436 Returns 0 on success.
437 437 '''
438 438
439 439 ctx = scmutil.revsingle(repo, opts.get('rev'))
440 440 if not ctx:
441 441 raise util.Abort(_('no working directory: please specify a revision'))
442 442 node = ctx.node()
443 443 dest = cmdutil.makefilename(repo, dest, node)
444 444 if os.path.realpath(dest) == repo.root:
445 445 raise util.Abort(_('repository root cannot be destination'))
446 446
447 447 kind = opts.get('type') or archival.guesskind(dest) or 'files'
448 448 prefix = opts.get('prefix')
449 449
450 450 if dest == '-':
451 451 if kind == 'files':
452 452 raise util.Abort(_('cannot archive plain files to stdout'))
453 453 dest = cmdutil.makefileobj(repo, dest)
454 454 if not prefix:
455 455 prefix = os.path.basename(repo.root) + '-%h'
456 456
457 457 prefix = cmdutil.makefilename(repo, prefix, node)
458 458 matchfn = scmutil.match(ctx, [], opts)
459 459 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
460 460 matchfn, prefix, subrepos=opts.get('subrepos'))
461 461
462 462 @command('backout',
463 463 [('', 'merge', None, _('merge with old dirstate parent after backout')),
464 464 ('', 'commit', None, _('commit if no conflicts were encountered')),
465 465 ('', 'parent', '',
466 466 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
467 467 ('r', 'rev', '', _('revision to backout'), _('REV')),
468 468 ('e', 'edit', False, _('invoke editor on commit messages')),
469 469 ] + mergetoolopts + walkopts + commitopts + commitopts2,
470 470 _('[OPTION]... [-r] REV'))
471 471 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
472 472 '''reverse effect of earlier changeset
473 473
474 474 Prepare a new changeset with the effect of REV undone in the
475 475 current working directory.
476 476
477 477 If REV is the parent of the working directory, then this new changeset
478 478 is committed automatically. Otherwise, hg needs to merge the
479 479 changes and the merged result is left uncommitted.
480 480
481 481 .. note::
482 482
483 483 backout cannot be used to fix either an unwanted or
484 484 incorrect merge.
485 485
486 486 .. container:: verbose
487 487
488 488 By default, the pending changeset will have one parent,
489 489 maintaining a linear history. With --merge, the pending
490 490 changeset will instead have two parents: the old parent of the
491 491 working directory and a new child of REV that simply undoes REV.
492 492
493 493 Before version 1.7, the behavior without --merge was equivalent
494 494 to specifying --merge followed by :hg:`update --clean .` to
495 495 cancel the merge and leave the child of REV as a head to be
496 496 merged separately.
497 497
498 498 See :hg:`help dates` for a list of formats valid for -d/--date.
499 499
500 500 See :hg:`help revert` for a way to restore files to the state
501 501 of another revision.
502 502
503 503 Returns 0 on success, 1 if nothing to backout or there are unresolved
504 504 files.
505 505 '''
506 506 if rev and node:
507 507 raise util.Abort(_("please specify just one revision"))
508 508
509 509 if not rev:
510 510 rev = node
511 511
512 512 if not rev:
513 513 raise util.Abort(_("please specify a revision to backout"))
514 514
515 515 date = opts.get('date')
516 516 if date:
517 517 opts['date'] = util.parsedate(date)
518 518
519 519 cmdutil.checkunfinished(repo)
520 520 cmdutil.bailifchanged(repo)
521 521 node = scmutil.revsingle(repo, rev).node()
522 522
523 523 op1, op2 = repo.dirstate.parents()
524 524 if not repo.changelog.isancestor(node, op1):
525 525 raise util.Abort(_('cannot backout change that is not an ancestor'))
526 526
527 527 p1, p2 = repo.changelog.parents(node)
528 528 if p1 == nullid:
529 529 raise util.Abort(_('cannot backout a change with no parents'))
530 530 if p2 != nullid:
531 531 if not opts.get('parent'):
532 532 raise util.Abort(_('cannot backout a merge changeset'))
533 533 p = repo.lookup(opts['parent'])
534 534 if p not in (p1, p2):
535 535 raise util.Abort(_('%s is not a parent of %s') %
536 536 (short(p), short(node)))
537 537 parent = p
538 538 else:
539 539 if opts.get('parent'):
540 540 raise util.Abort(_('cannot use --parent on non-merge changeset'))
541 541 parent = p1
542 542
543 543 # the backout should appear on the same branch
544 544 wlock = repo.wlock()
545 545 try:
546 546 branch = repo.dirstate.branch()
547 547 bheads = repo.branchheads(branch)
548 548 rctx = scmutil.revsingle(repo, hex(parent))
549 549 if not opts.get('merge') and op1 != node:
550 550 try:
551 551 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
552 552 'backout')
553 553 repo.dirstate.beginparentchange()
554 554 stats = mergemod.update(repo, parent, True, True, False,
555 555 node, False)
556 556 repo.setparents(op1, op2)
557 557 repo.dirstate.endparentchange()
558 558 hg._showstats(repo, stats)
559 559 if stats[3]:
560 560 repo.ui.status(_("use 'hg resolve' to retry unresolved "
561 561 "file merges\n"))
562 562 return 1
563 563 elif not commit:
564 564 msg = _("changeset %s backed out, "
565 565 "don't forget to commit.\n")
566 566 ui.status(msg % short(node))
567 567 return 0
568 568 finally:
569 569 ui.setconfig('ui', 'forcemerge', '', '')
570 570 else:
571 571 hg.clean(repo, node, show_stats=False)
572 572 repo.dirstate.setbranch(branch)
573 573 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
574 574
575 575
576 576 def commitfunc(ui, repo, message, match, opts):
577 577 editform = 'backout'
578 578 e = cmdutil.getcommiteditor(editform=editform, **opts)
579 579 if not message:
580 580 # we don't translate commit messages
581 581 message = "Backed out changeset %s" % short(node)
582 582 e = cmdutil.getcommiteditor(edit=True, editform=editform)
583 583 return repo.commit(message, opts.get('user'), opts.get('date'),
584 584 match, editor=e)
585 585 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
586 586 if not newnode:
587 587 ui.status(_("nothing changed\n"))
588 588 return 1
589 589 cmdutil.commitstatus(repo, newnode, branch, bheads)
590 590
591 591 def nice(node):
592 592 return '%d:%s' % (repo.changelog.rev(node), short(node))
593 593 ui.status(_('changeset %s backs out changeset %s\n') %
594 594 (nice(repo.changelog.tip()), nice(node)))
595 595 if opts.get('merge') and op1 != node:
596 596 hg.clean(repo, op1, show_stats=False)
597 597 ui.status(_('merging with changeset %s\n')
598 598 % nice(repo.changelog.tip()))
599 599 try:
600 600 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
601 601 'backout')
602 602 return hg.merge(repo, hex(repo.changelog.tip()))
603 603 finally:
604 604 ui.setconfig('ui', 'forcemerge', '', '')
605 605 finally:
606 606 wlock.release()
607 607 return 0
608 608
609 609 @command('bisect',
610 610 [('r', 'reset', False, _('reset bisect state')),
611 611 ('g', 'good', False, _('mark changeset good')),
612 612 ('b', 'bad', False, _('mark changeset bad')),
613 613 ('s', 'skip', False, _('skip testing changeset')),
614 614 ('e', 'extend', False, _('extend the bisect range')),
615 615 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
616 616 ('U', 'noupdate', False, _('do not update to target'))],
617 617 _("[-gbsr] [-U] [-c CMD] [REV]"))
618 618 def bisect(ui, repo, rev=None, extra=None, command=None,
619 619 reset=None, good=None, bad=None, skip=None, extend=None,
620 620 noupdate=None):
621 621 """subdivision search of changesets
622 622
623 623 This command helps to find changesets which introduce problems. To
624 624 use, mark the earliest changeset you know exhibits the problem as
625 625 bad, then mark the latest changeset which is free from the problem
626 626 as good. Bisect will update your working directory to a revision
627 627 for testing (unless the -U/--noupdate option is specified). Once
628 628 you have performed tests, mark the working directory as good or
629 629 bad, and bisect will either update to another candidate changeset
630 630 or announce that it has found the bad revision.
631 631
632 632 As a shortcut, you can also use the revision argument to mark a
633 633 revision as good or bad without checking it out first.
634 634
635 635 If you supply a command, it will be used for automatic bisection.
636 636 The environment variable HG_NODE will contain the ID of the
637 637 changeset being tested. The exit status of the command will be
638 638 used to mark revisions as good or bad: status 0 means good, 125
639 639 means to skip the revision, 127 (command not found) will abort the
640 640 bisection, and any other non-zero exit status means the revision
641 641 is bad.
642 642
643 643 .. container:: verbose
644 644
645 645 Some examples:
646 646
647 647 - start a bisection with known bad revision 34, and good revision 12::
648 648
649 649 hg bisect --bad 34
650 650 hg bisect --good 12
651 651
652 652 - advance the current bisection by marking current revision as good or
653 653 bad::
654 654
655 655 hg bisect --good
656 656 hg bisect --bad
657 657
658 658 - mark the current revision, or a known revision, to be skipped (e.g. if
659 659 that revision is not usable because of another issue)::
660 660
661 661 hg bisect --skip
662 662 hg bisect --skip 23
663 663
664 664 - skip all revisions that do not touch directories ``foo`` or ``bar``::
665 665
666 666 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
667 667
668 668 - forget the current bisection::
669 669
670 670 hg bisect --reset
671 671
672 672 - use 'make && make tests' to automatically find the first broken
673 673 revision::
674 674
675 675 hg bisect --reset
676 676 hg bisect --bad 34
677 677 hg bisect --good 12
678 678 hg bisect --command "make && make tests"
679 679
680 680 - see all changesets whose states are already known in the current
681 681 bisection::
682 682
683 683 hg log -r "bisect(pruned)"
684 684
685 685 - see the changeset currently being bisected (especially useful
686 686 if running with -U/--noupdate)::
687 687
688 688 hg log -r "bisect(current)"
689 689
690 690 - see all changesets that took part in the current bisection::
691 691
692 692 hg log -r "bisect(range)"
693 693
694 694 - you can even get a nice graph::
695 695
696 696 hg log --graph -r "bisect(range)"
697 697
698 698 See :hg:`help revsets` for more about the `bisect()` keyword.
699 699
700 700 Returns 0 on success.
701 701 """
702 702 def extendbisectrange(nodes, good):
703 703 # bisect is incomplete when it ends on a merge node and
704 704 # one of the parent was not checked.
705 705 parents = repo[nodes[0]].parents()
706 706 if len(parents) > 1:
707 707 if good:
708 708 side = state['bad']
709 709 else:
710 710 side = state['good']
711 711 num = len(set(i.node() for i in parents) & set(side))
712 712 if num == 1:
713 713 return parents[0].ancestor(parents[1])
714 714 return None
715 715
716 716 def print_result(nodes, good):
717 717 displayer = cmdutil.show_changeset(ui, repo, {})
718 718 if len(nodes) == 1:
719 719 # narrowed it down to a single revision
720 720 if good:
721 721 ui.write(_("The first good revision is:\n"))
722 722 else:
723 723 ui.write(_("The first bad revision is:\n"))
724 724 displayer.show(repo[nodes[0]])
725 725 extendnode = extendbisectrange(nodes, good)
726 726 if extendnode is not None:
727 727 ui.write(_('Not all ancestors of this changeset have been'
728 728 ' checked.\nUse bisect --extend to continue the '
729 729 'bisection from\nthe common ancestor, %s.\n')
730 730 % extendnode)
731 731 else:
732 732 # multiple possible revisions
733 733 if good:
734 734 ui.write(_("Due to skipped revisions, the first "
735 735 "good revision could be any of:\n"))
736 736 else:
737 737 ui.write(_("Due to skipped revisions, the first "
738 738 "bad revision could be any of:\n"))
739 739 for n in nodes:
740 740 displayer.show(repo[n])
741 741 displayer.close()
742 742
743 743 def check_state(state, interactive=True):
744 744 if not state['good'] or not state['bad']:
745 745 if (good or bad or skip or reset) and interactive:
746 746 return
747 747 if not state['good']:
748 748 raise util.Abort(_('cannot bisect (no known good revisions)'))
749 749 else:
750 750 raise util.Abort(_('cannot bisect (no known bad revisions)'))
751 751 return True
752 752
753 753 # backward compatibility
754 754 if rev in "good bad reset init".split():
755 755 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
756 756 cmd, rev, extra = rev, extra, None
757 757 if cmd == "good":
758 758 good = True
759 759 elif cmd == "bad":
760 760 bad = True
761 761 else:
762 762 reset = True
763 763 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
764 764 raise util.Abort(_('incompatible arguments'))
765 765
766 766 cmdutil.checkunfinished(repo)
767 767
768 768 if reset:
769 769 p = repo.join("bisect.state")
770 770 if os.path.exists(p):
771 771 os.unlink(p)
772 772 return
773 773
774 774 state = hbisect.load_state(repo)
775 775
776 776 if command:
777 777 changesets = 1
778 778 if noupdate:
779 779 try:
780 780 node = state['current'][0]
781 781 except LookupError:
782 782 raise util.Abort(_('current bisect revision is unknown - '
783 783 'start a new bisect to fix'))
784 784 else:
785 785 node, p2 = repo.dirstate.parents()
786 786 if p2 != nullid:
787 787 raise util.Abort(_('current bisect revision is a merge'))
788 788 try:
789 789 while changesets:
790 790 # update state
791 791 state['current'] = [node]
792 792 hbisect.save_state(repo, state)
793 793 status = ui.system(command, environ={'HG_NODE': hex(node)})
794 794 if status == 125:
795 795 transition = "skip"
796 796 elif status == 0:
797 797 transition = "good"
798 798 # status < 0 means process was killed
799 799 elif status == 127:
800 800 raise util.Abort(_("failed to execute %s") % command)
801 801 elif status < 0:
802 802 raise util.Abort(_("%s killed") % command)
803 803 else:
804 804 transition = "bad"
805 805 ctx = scmutil.revsingle(repo, rev, node)
806 806 rev = None # clear for future iterations
807 807 state[transition].append(ctx.node())
808 808 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
809 809 check_state(state, interactive=False)
810 810 # bisect
811 811 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
812 812 # update to next check
813 813 node = nodes[0]
814 814 if not noupdate:
815 815 cmdutil.bailifchanged(repo)
816 816 hg.clean(repo, node, show_stats=False)
817 817 finally:
818 818 state['current'] = [node]
819 819 hbisect.save_state(repo, state)
820 820 print_result(nodes, bgood)
821 821 return
822 822
823 823 # update state
824 824
825 825 if rev:
826 826 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
827 827 else:
828 828 nodes = [repo.lookup('.')]
829 829
830 830 if good or bad or skip:
831 831 if good:
832 832 state['good'] += nodes
833 833 elif bad:
834 834 state['bad'] += nodes
835 835 elif skip:
836 836 state['skip'] += nodes
837 837 hbisect.save_state(repo, state)
838 838
839 839 if not check_state(state):
840 840 return
841 841
842 842 # actually bisect
843 843 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
844 844 if extend:
845 845 if not changesets:
846 846 extendnode = extendbisectrange(nodes, good)
847 847 if extendnode is not None:
848 848 ui.write(_("Extending search to changeset %d:%s\n")
849 849 % (extendnode.rev(), extendnode))
850 850 state['current'] = [extendnode.node()]
851 851 hbisect.save_state(repo, state)
852 852 if noupdate:
853 853 return
854 854 cmdutil.bailifchanged(repo)
855 855 return hg.clean(repo, extendnode.node())
856 856 raise util.Abort(_("nothing to extend"))
857 857
858 858 if changesets == 0:
859 859 print_result(nodes, good)
860 860 else:
861 861 assert len(nodes) == 1 # only a single node can be tested next
862 862 node = nodes[0]
863 863 # compute the approximate number of remaining tests
864 864 tests, size = 0, 2
865 865 while size <= changesets:
866 866 tests, size = tests + 1, size * 2
867 867 rev = repo.changelog.rev(node)
868 868 ui.write(_("Testing changeset %d:%s "
869 869 "(%d changesets remaining, ~%d tests)\n")
870 870 % (rev, short(node), changesets, tests))
871 871 state['current'] = [node]
872 872 hbisect.save_state(repo, state)
873 873 if not noupdate:
874 874 cmdutil.bailifchanged(repo)
875 875 return hg.clean(repo, node)
876 876
877 877 @command('bookmarks|bookmark',
878 878 [('f', 'force', False, _('force')),
879 879 ('r', 'rev', '', _('revision'), _('REV')),
880 880 ('d', 'delete', False, _('delete a given bookmark')),
881 881 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
882 882 ('i', 'inactive', False, _('mark a bookmark inactive')),
883 883 ] + formatteropts,
884 884 _('hg bookmarks [OPTIONS]... [NAME]...'))
885 885 def bookmark(ui, repo, *names, **opts):
886 886 '''create a new bookmark or list existing bookmarks
887 887
888 888 Bookmarks are labels on changesets to help track lines of development.
889 889 Bookmarks are unversioned and can be moved, renamed and deleted.
890 890 Deleting or moving a bookmark has no effect on the associated changesets.
891 891
892 892 Creating or updating to a bookmark causes it to be marked as 'active'.
893 893 The active bookmark is indicated with a '*'.
894 894 When a commit is made, the active bookmark will advance to the new commit.
895 895 A plain :hg:`update` will also advance an active bookmark, if possible.
896 896 Updating away from a bookmark will cause it to be deactivated.
897 897
898 898 Bookmarks can be pushed and pulled between repositories (see
899 899 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
900 900 diverged, a new 'divergent bookmark' of the form 'name@path' will
901 901 be created. Using :hg:`merge` will resolve the divergence.
902 902
903 903 A bookmark named '@' has the special property that :hg:`clone` will
904 904 check it out by default if it exists.
905 905
906 906 .. container:: verbose
907 907
908 908 Examples:
909 909
910 910 - create an active bookmark for a new line of development::
911 911
912 912 hg book new-feature
913 913
914 914 - create an inactive bookmark as a place marker::
915 915
916 916 hg book -i reviewed
917 917
918 918 - create an inactive bookmark on another changeset::
919 919
920 920 hg book -r .^ tested
921 921
922 922 - rename bookmark turkey to dinner::
923 923
924 924 hg book -m turkey dinner
925 925
926 926 - move the '@' bookmark from another branch::
927 927
928 928 hg book -f @
929 929 '''
930 930 force = opts.get('force')
931 931 rev = opts.get('rev')
932 932 delete = opts.get('delete')
933 933 rename = opts.get('rename')
934 934 inactive = opts.get('inactive')
935 935
936 936 def checkformat(mark):
937 937 mark = mark.strip()
938 938 if not mark:
939 939 raise util.Abort(_("bookmark names cannot consist entirely of "
940 940 "whitespace"))
941 941 scmutil.checknewlabel(repo, mark, 'bookmark')
942 942 return mark
943 943
944 944 def checkconflict(repo, mark, cur, force=False, target=None):
945 945 if mark in marks and not force:
946 946 if target:
947 947 if marks[mark] == target and target == cur:
948 948 # re-activating a bookmark
949 949 return
950 950 anc = repo.changelog.ancestors([repo[target].rev()])
951 951 bmctx = repo[marks[mark]]
952 952 divs = [repo[b].node() for b in marks
953 953 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
954 954
955 955 # allow resolving a single divergent bookmark even if moving
956 956 # the bookmark across branches when a revision is specified
957 957 # that contains a divergent bookmark
958 958 if bmctx.rev() not in anc and target in divs:
959 959 bookmarks.deletedivergent(repo, [target], mark)
960 960 return
961 961
962 962 deletefrom = [b for b in divs
963 963 if repo[b].rev() in anc or b == target]
964 964 bookmarks.deletedivergent(repo, deletefrom, mark)
965 965 if bookmarks.validdest(repo, bmctx, repo[target]):
966 966 ui.status(_("moving bookmark '%s' forward from %s\n") %
967 967 (mark, short(bmctx.node())))
968 968 return
969 969 raise util.Abort(_("bookmark '%s' already exists "
970 970 "(use -f to force)") % mark)
971 971 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
972 972 and not force):
973 973 raise util.Abort(
974 974 _("a bookmark cannot have the name of an existing branch"))
975 975
976 976 if delete and rename:
977 977 raise util.Abort(_("--delete and --rename are incompatible"))
978 978 if delete and rev:
979 979 raise util.Abort(_("--rev is incompatible with --delete"))
980 980 if rename and rev:
981 981 raise util.Abort(_("--rev is incompatible with --rename"))
982 982 if not names and (delete or rev):
983 983 raise util.Abort(_("bookmark name required"))
984 984
985 985 if delete or rename or names or inactive:
986 986 wlock = lock = tr = None
987 987 try:
988 988 wlock = repo.wlock()
989 989 lock = repo.lock()
990 990 cur = repo.changectx('.').node()
991 991 marks = repo._bookmarks
992 992 if delete:
993 993 tr = repo.transaction('bookmark')
994 994 for mark in names:
995 995 if mark not in marks:
996 996 raise util.Abort(_("bookmark '%s' does not exist") %
997 997 mark)
998 998 if mark == repo._activebookmark:
999 999 bookmarks.deactivate(repo)
1000 1000 del marks[mark]
1001 1001
1002 1002 elif rename:
1003 1003 tr = repo.transaction('bookmark')
1004 1004 if not names:
1005 1005 raise util.Abort(_("new bookmark name required"))
1006 1006 elif len(names) > 1:
1007 1007 raise util.Abort(_("only one new bookmark name allowed"))
1008 1008 mark = checkformat(names[0])
1009 1009 if rename not in marks:
1010 1010 raise util.Abort(_("bookmark '%s' does not exist") % rename)
1011 1011 checkconflict(repo, mark, cur, force)
1012 1012 marks[mark] = marks[rename]
1013 1013 if repo._activebookmark == rename and not inactive:
1014 1014 bookmarks.activate(repo, mark)
1015 1015 del marks[rename]
1016 1016 elif names:
1017 1017 tr = repo.transaction('bookmark')
1018 1018 newact = None
1019 1019 for mark in names:
1020 1020 mark = checkformat(mark)
1021 1021 if newact is None:
1022 1022 newact = mark
1023 1023 if inactive and mark == repo._activebookmark:
1024 1024 bookmarks.deactivate(repo)
1025 1025 return
1026 1026 tgt = cur
1027 1027 if rev:
1028 1028 tgt = scmutil.revsingle(repo, rev).node()
1029 1029 checkconflict(repo, mark, cur, force, tgt)
1030 1030 marks[mark] = tgt
1031 1031 if not inactive and cur == marks[newact] and not rev:
1032 1032 bookmarks.activate(repo, newact)
1033 1033 elif cur != tgt and newact == repo._activebookmark:
1034 1034 bookmarks.deactivate(repo)
1035 1035 elif inactive:
1036 1036 if len(marks) == 0:
1037 1037 ui.status(_("no bookmarks set\n"))
1038 1038 elif not repo._activebookmark:
1039 1039 ui.status(_("no active bookmark\n"))
1040 1040 else:
1041 1041 bookmarks.deactivate(repo)
1042 1042 if tr is not None:
1043 1043 marks.recordchange(tr)
1044 1044 tr.close()
1045 1045 finally:
1046 1046 lockmod.release(tr, lock, wlock)
1047 1047 else: # show bookmarks
1048 1048 fm = ui.formatter('bookmarks', opts)
1049 1049 hexfn = fm.hexfunc
1050 1050 marks = repo._bookmarks
1051 1051 if len(marks) == 0 and not fm:
1052 1052 ui.status(_("no bookmarks set\n"))
1053 1053 for bmark, n in sorted(marks.iteritems()):
1054 1054 active = repo._activebookmark
1055 1055 if bmark == active:
1056 1056 prefix, label = '*', activebookmarklabel
1057 1057 else:
1058 1058 prefix, label = ' ', ''
1059 1059
1060 1060 fm.startitem()
1061 1061 if not ui.quiet:
1062 1062 fm.plain(' %s ' % prefix, label=label)
1063 1063 fm.write('bookmark', '%s', bmark, label=label)
1064 1064 pad = " " * (25 - encoding.colwidth(bmark))
1065 1065 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1066 1066 repo.changelog.rev(n), hexfn(n), label=label)
1067 1067 fm.data(active=(bmark == active))
1068 1068 fm.plain('\n')
1069 1069 fm.end()
1070 1070
1071 1071 @command('branch',
1072 1072 [('f', 'force', None,
1073 1073 _('set branch name even if it shadows an existing branch')),
1074 1074 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1075 1075 _('[-fC] [NAME]'))
1076 1076 def branch(ui, repo, label=None, **opts):
1077 1077 """set or show the current branch name
1078 1078
1079 1079 .. note::
1080 1080
1081 1081 Branch names are permanent and global. Use :hg:`bookmark` to create a
1082 1082 light-weight bookmark instead. See :hg:`help glossary` for more
1083 1083 information about named branches and bookmarks.
1084 1084
1085 1085 With no argument, show the current branch name. With one argument,
1086 1086 set the working directory branch name (the branch will not exist
1087 1087 in the repository until the next commit). Standard practice
1088 1088 recommends that primary development take place on the 'default'
1089 1089 branch.
1090 1090
1091 1091 Unless -f/--force is specified, branch will not let you set a
1092 1092 branch name that already exists.
1093 1093
1094 1094 Use -C/--clean to reset the working directory branch to that of
1095 1095 the parent of the working directory, negating a previous branch
1096 1096 change.
1097 1097
1098 1098 Use the command :hg:`update` to switch to an existing branch. Use
1099 1099 :hg:`commit --close-branch` to mark this branch head as closed.
1100 1100 When all heads of the branch are closed, the branch will be
1101 1101 considered closed.
1102 1102
1103 1103 Returns 0 on success.
1104 1104 """
1105 1105 if label:
1106 1106 label = label.strip()
1107 1107
1108 1108 if not opts.get('clean') and not label:
1109 1109 ui.write("%s\n" % repo.dirstate.branch())
1110 1110 return
1111 1111
1112 1112 wlock = repo.wlock()
1113 1113 try:
1114 1114 if opts.get('clean'):
1115 1115 label = repo[None].p1().branch()
1116 1116 repo.dirstate.setbranch(label)
1117 1117 ui.status(_('reset working directory to branch %s\n') % label)
1118 1118 elif label:
1119 1119 if not opts.get('force') and label in repo.branchmap():
1120 1120 if label not in [p.branch() for p in repo.parents()]:
1121 1121 raise util.Abort(_('a branch of the same name already'
1122 1122 ' exists'),
1123 1123 # i18n: "it" refers to an existing branch
1124 1124 hint=_("use 'hg update' to switch to it"))
1125 1125 scmutil.checknewlabel(repo, label, 'branch')
1126 1126 repo.dirstate.setbranch(label)
1127 1127 ui.status(_('marked working directory as branch %s\n') % label)
1128 1128
1129 1129 # find any open named branches aside from default
1130 1130 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1131 1131 if n != "default" and not c]
1132 1132 if not others:
1133 1133 ui.status(_('(branches are permanent and global, '
1134 1134 'did you want a bookmark?)\n'))
1135 1135 finally:
1136 1136 wlock.release()
1137 1137
1138 1138 @command('branches',
1139 1139 [('a', 'active', False,
1140 1140 _('show only branches that have unmerged heads (DEPRECATED)')),
1141 1141 ('c', 'closed', False, _('show normal and closed branches')),
1142 1142 ] + formatteropts,
1143 1143 _('[-ac]'))
1144 1144 def branches(ui, repo, active=False, closed=False, **opts):
1145 1145 """list repository named branches
1146 1146
1147 1147 List the repository's named branches, indicating which ones are
1148 1148 inactive. If -c/--closed is specified, also list branches which have
1149 1149 been marked closed (see :hg:`commit --close-branch`).
1150 1150
1151 1151 Use the command :hg:`update` to switch to an existing branch.
1152 1152
1153 1153 Returns 0.
1154 1154 """
1155 1155
1156 1156 fm = ui.formatter('branches', opts)
1157 1157 hexfunc = fm.hexfunc
1158 1158
1159 1159 allheads = set(repo.heads())
1160 1160 branches = []
1161 1161 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1162 1162 isactive = not isclosed and bool(set(heads) & allheads)
1163 1163 branches.append((tag, repo[tip], isactive, not isclosed))
1164 1164 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1165 1165 reverse=True)
1166 1166
1167 1167 for tag, ctx, isactive, isopen in branches:
1168 1168 if active and not isactive:
1169 1169 continue
1170 1170 if isactive:
1171 1171 label = 'branches.active'
1172 1172 notice = ''
1173 1173 elif not isopen:
1174 1174 if not closed:
1175 1175 continue
1176 1176 label = 'branches.closed'
1177 1177 notice = _(' (closed)')
1178 1178 else:
1179 1179 label = 'branches.inactive'
1180 1180 notice = _(' (inactive)')
1181 1181 current = (tag == repo.dirstate.branch())
1182 1182 if current:
1183 1183 label = 'branches.current'
1184 1184
1185 1185 fm.startitem()
1186 1186 fm.write('branch', '%s', tag, label=label)
1187 1187 rev = ctx.rev()
1188 1188 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1189 1189 fmt = ' ' * padsize + ' %d:%s'
1190 1190 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1191 1191 label='log.changeset changeset.%s' % ctx.phasestr())
1192 1192 fm.data(active=isactive, closed=not isopen, current=current)
1193 1193 if not ui.quiet:
1194 1194 fm.plain(notice)
1195 1195 fm.plain('\n')
1196 1196 fm.end()
1197 1197
1198 1198 @command('bundle',
1199 1199 [('f', 'force', None, _('run even when the destination is unrelated')),
1200 1200 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1201 1201 _('REV')),
1202 1202 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1203 1203 _('BRANCH')),
1204 1204 ('', 'base', [],
1205 1205 _('a base changeset assumed to be available at the destination'),
1206 1206 _('REV')),
1207 1207 ('a', 'all', None, _('bundle all changesets in the repository')),
1208 1208 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1209 1209 ] + remoteopts,
1210 1210 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1211 1211 def bundle(ui, repo, fname, dest=None, **opts):
1212 1212 """create a changegroup file
1213 1213
1214 1214 Generate a compressed changegroup file collecting changesets not
1215 1215 known to be in another repository.
1216 1216
1217 1217 If you omit the destination repository, then hg assumes the
1218 1218 destination will have all the nodes you specify with --base
1219 1219 parameters. To create a bundle containing all changesets, use
1220 1220 -a/--all (or --base null).
1221 1221
1222 1222 You can change compression method with the -t/--type option.
1223 1223 The available compression methods are: none, bzip2, and
1224 1224 gzip (by default, bundles are compressed using bzip2).
1225 1225
1226 1226 The bundle file can then be transferred using conventional means
1227 1227 and applied to another repository with the unbundle or pull
1228 1228 command. This is useful when direct push and pull are not
1229 1229 available or when exporting an entire repository is undesirable.
1230 1230
1231 1231 Applying bundles preserves all changeset contents including
1232 1232 permissions, copy/rename information, and revision history.
1233 1233
1234 1234 Returns 0 on success, 1 if no changes found.
1235 1235 """
1236 1236 revs = None
1237 1237 if 'rev' in opts:
1238 1238 revs = scmutil.revrange(repo, opts['rev'])
1239 1239
1240 1240 bundletype = opts.get('type', 'bzip2').lower()
1241 1241 btypes = {'none': 'HG10UN',
1242 1242 'bzip2': 'HG10BZ',
1243 1243 'gzip': 'HG10GZ',
1244 1244 'bundle2': 'HG20'}
1245 1245 bundletype = btypes.get(bundletype)
1246 1246 if bundletype not in changegroup.bundletypes:
1247 1247 raise util.Abort(_('unknown bundle type specified with --type'))
1248 1248
1249 1249 if opts.get('all'):
1250 1250 base = ['null']
1251 1251 else:
1252 1252 base = scmutil.revrange(repo, opts.get('base'))
1253 1253 # TODO: get desired bundlecaps from command line.
1254 1254 bundlecaps = None
1255 1255 if base:
1256 1256 if dest:
1257 1257 raise util.Abort(_("--base is incompatible with specifying "
1258 1258 "a destination"))
1259 1259 common = [repo.lookup(rev) for rev in base]
1260 1260 heads = revs and map(repo.lookup, revs) or revs
1261 1261 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1262 1262 common=common, bundlecaps=bundlecaps)
1263 1263 outgoing = None
1264 1264 else:
1265 1265 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1266 1266 dest, branches = hg.parseurl(dest, opts.get('branch'))
1267 1267 other = hg.peer(repo, opts, dest)
1268 1268 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1269 1269 heads = revs and map(repo.lookup, revs) or revs
1270 1270 outgoing = discovery.findcommonoutgoing(repo, other,
1271 1271 onlyheads=heads,
1272 1272 force=opts.get('force'),
1273 1273 portable=True)
1274 1274 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1275 1275 bundlecaps)
1276 1276 if not cg:
1277 1277 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1278 1278 return 1
1279 1279
1280 1280 changegroup.writebundle(ui, cg, fname, bundletype)
1281 1281
1282 1282 @command('cat',
1283 1283 [('o', 'output', '',
1284 1284 _('print output to file with formatted name'), _('FORMAT')),
1285 1285 ('r', 'rev', '', _('print the given revision'), _('REV')),
1286 1286 ('', 'decode', None, _('apply any matching decode filter')),
1287 1287 ] + walkopts,
1288 1288 _('[OPTION]... FILE...'),
1289 1289 inferrepo=True)
1290 1290 def cat(ui, repo, file1, *pats, **opts):
1291 1291 """output the current or given revision of files
1292 1292
1293 1293 Print the specified files as they were at the given revision. If
1294 1294 no revision is given, the parent of the working directory is used.
1295 1295
1296 1296 Output may be to a file, in which case the name of the file is
1297 1297 given using a format string. The formatting rules as follows:
1298 1298
1299 1299 :``%%``: literal "%" character
1300 1300 :``%s``: basename of file being printed
1301 1301 :``%d``: dirname of file being printed, or '.' if in repository root
1302 1302 :``%p``: root-relative path name of file being printed
1303 1303 :``%H``: changeset hash (40 hexadecimal digits)
1304 1304 :``%R``: changeset revision number
1305 1305 :``%h``: short-form changeset hash (12 hexadecimal digits)
1306 1306 :``%r``: zero-padded changeset revision number
1307 1307 :``%b``: basename of the exporting repository
1308 1308
1309 1309 Returns 0 on success.
1310 1310 """
1311 1311 ctx = scmutil.revsingle(repo, opts.get('rev'))
1312 1312 m = scmutil.match(ctx, (file1,) + pats, opts)
1313 1313
1314 1314 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1315 1315
1316 1316 @command('^clone',
1317 1317 [('U', 'noupdate', None, _('the clone will include an empty working '
1318 1318 'directory (only a repository)')),
1319 1319 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1320 1320 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1321 1321 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1322 1322 ('', 'pull', None, _('use pull protocol to copy metadata')),
1323 1323 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1324 1324 ] + remoteopts,
1325 1325 _('[OPTION]... SOURCE [DEST]'),
1326 1326 norepo=True)
1327 1327 def clone(ui, source, dest=None, **opts):
1328 1328 """make a copy of an existing repository
1329 1329
1330 1330 Create a copy of an existing repository in a new directory.
1331 1331
1332 1332 If no destination directory name is specified, it defaults to the
1333 1333 basename of the source.
1334 1334
1335 1335 The location of the source is added to the new repository's
1336 1336 ``.hg/hgrc`` file, as the default to be used for future pulls.
1337 1337
1338 1338 Only local paths and ``ssh://`` URLs are supported as
1339 1339 destinations. For ``ssh://`` destinations, no working directory or
1340 1340 ``.hg/hgrc`` will be created on the remote side.
1341 1341
1342 1342 To pull only a subset of changesets, specify one or more revisions
1343 1343 identifiers with -r/--rev or branches with -b/--branch. The
1344 1344 resulting clone will contain only the specified changesets and
1345 1345 their ancestors. These options (or 'clone src#rev dest') imply
1346 1346 --pull, even for local source repositories. Note that specifying a
1347 1347 tag will include the tagged changeset but not the changeset
1348 1348 containing the tag.
1349 1349
1350 1350 If the source repository has a bookmark called '@' set, that
1351 1351 revision will be checked out in the new repository by default.
1352 1352
1353 1353 To check out a particular version, use -u/--update, or
1354 1354 -U/--noupdate to create a clone with no working directory.
1355 1355
1356 1356 .. container:: verbose
1357 1357
1358 1358 For efficiency, hardlinks are used for cloning whenever the
1359 1359 source and destination are on the same filesystem (note this
1360 1360 applies only to the repository data, not to the working
1361 1361 directory). Some filesystems, such as AFS, implement hardlinking
1362 1362 incorrectly, but do not report errors. In these cases, use the
1363 1363 --pull option to avoid hardlinking.
1364 1364
1365 1365 In some cases, you can clone repositories and the working
1366 1366 directory using full hardlinks with ::
1367 1367
1368 1368 $ cp -al REPO REPOCLONE
1369 1369
1370 1370 This is the fastest way to clone, but it is not always safe. The
1371 1371 operation is not atomic (making sure REPO is not modified during
1372 1372 the operation is up to you) and you have to make sure your
1373 1373 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1374 1374 so). Also, this is not compatible with certain extensions that
1375 1375 place their metadata under the .hg directory, such as mq.
1376 1376
1377 1377 Mercurial will update the working directory to the first applicable
1378 1378 revision from this list:
1379 1379
1380 1380 a) null if -U or the source repository has no changesets
1381 1381 b) if -u . and the source repository is local, the first parent of
1382 1382 the source repository's working directory
1383 1383 c) the changeset specified with -u (if a branch name, this means the
1384 1384 latest head of that branch)
1385 1385 d) the changeset specified with -r
1386 1386 e) the tipmost head specified with -b
1387 1387 f) the tipmost head specified with the url#branch source syntax
1388 1388 g) the revision marked with the '@' bookmark, if present
1389 1389 h) the tipmost head of the default branch
1390 1390 i) tip
1391 1391
1392 1392 Examples:
1393 1393
1394 1394 - clone a remote repository to a new directory named hg/::
1395 1395
1396 1396 hg clone http://selenic.com/hg
1397 1397
1398 1398 - create a lightweight local clone::
1399 1399
1400 1400 hg clone project/ project-feature/
1401 1401
1402 1402 - clone from an absolute path on an ssh server (note double-slash)::
1403 1403
1404 1404 hg clone ssh://user@server//home/projects/alpha/
1405 1405
1406 1406 - do a high-speed clone over a LAN while checking out a
1407 1407 specified version::
1408 1408
1409 1409 hg clone --uncompressed http://server/repo -u 1.5
1410 1410
1411 1411 - create a repository without changesets after a particular revision::
1412 1412
1413 1413 hg clone -r 04e544 experimental/ good/
1414 1414
1415 1415 - clone (and track) a particular named branch::
1416 1416
1417 1417 hg clone http://selenic.com/hg#stable
1418 1418
1419 1419 See :hg:`help urls` for details on specifying URLs.
1420 1420
1421 1421 Returns 0 on success.
1422 1422 """
1423 1423 if opts.get('noupdate') and opts.get('updaterev'):
1424 1424 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1425 1425
1426 1426 r = hg.clone(ui, opts, source, dest,
1427 1427 pull=opts.get('pull'),
1428 1428 stream=opts.get('uncompressed'),
1429 1429 rev=opts.get('rev'),
1430 1430 update=opts.get('updaterev') or not opts.get('noupdate'),
1431 1431 branch=opts.get('branch'),
1432 1432 shareopts=opts.get('shareopts'))
1433 1433
1434 1434 return r is None
1435 1435
1436 1436 @command('^commit|ci',
1437 1437 [('A', 'addremove', None,
1438 1438 _('mark new/missing files as added/removed before committing')),
1439 1439 ('', 'close-branch', None,
1440 1440 _('mark a branch head as closed')),
1441 1441 ('', 'amend', None, _('amend the parent of the working directory')),
1442 1442 ('s', 'secret', None, _('use the secret phase for committing')),
1443 1443 ('e', 'edit', None, _('invoke editor on commit messages')),
1444 1444 ('i', 'interactive', None, _('use interactive mode')),
1445 1445 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1446 1446 _('[OPTION]... [FILE]...'),
1447 1447 inferrepo=True)
1448 1448 def commit(ui, repo, *pats, **opts):
1449 1449 """commit the specified files or all outstanding changes
1450 1450
1451 1451 Commit changes to the given files into the repository. Unlike a
1452 1452 centralized SCM, this operation is a local operation. See
1453 1453 :hg:`push` for a way to actively distribute your changes.
1454 1454
1455 1455 If a list of files is omitted, all changes reported by :hg:`status`
1456 1456 will be committed.
1457 1457
1458 1458 If you are committing the result of a merge, do not provide any
1459 1459 filenames or -I/-X filters.
1460 1460
1461 1461 If no commit message is specified, Mercurial starts your
1462 1462 configured editor where you can enter a message. In case your
1463 1463 commit fails, you will find a backup of your message in
1464 1464 ``.hg/last-message.txt``.
1465 1465
1466 1466 The --close-branch flag can be used to mark the current branch
1467 1467 head closed. When all heads of a branch are closed, the branch
1468 1468 will be considered closed and no longer listed.
1469 1469
1470 1470 The --amend flag can be used to amend the parent of the
1471 1471 working directory with a new commit that contains the changes
1472 1472 in the parent in addition to those currently reported by :hg:`status`,
1473 1473 if there are any. The old commit is stored in a backup bundle in
1474 1474 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1475 1475 on how to restore it).
1476 1476
1477 1477 Message, user and date are taken from the amended commit unless
1478 1478 specified. When a message isn't specified on the command line,
1479 1479 the editor will open with the message of the amended commit.
1480 1480
1481 1481 It is not possible to amend public changesets (see :hg:`help phases`)
1482 1482 or changesets that have children.
1483 1483
1484 1484 See :hg:`help dates` for a list of formats valid for -d/--date.
1485 1485
1486 1486 Returns 0 on success, 1 if nothing changed.
1487 1487 """
1488 1488 if opts.get('interactive'):
1489 1489 opts.pop('interactive')
1490 1490 cmdutil.dorecord(ui, repo, commit, None, False,
1491 1491 cmdutil.recordfilter, *pats, **opts)
1492 1492 return
1493 1493
1494 1494 if opts.get('subrepos'):
1495 1495 if opts.get('amend'):
1496 1496 raise util.Abort(_('cannot amend with --subrepos'))
1497 1497 # Let --subrepos on the command line override config setting.
1498 1498 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1499 1499
1500 1500 cmdutil.checkunfinished(repo, commit=True)
1501 1501
1502 1502 branch = repo[None].branch()
1503 1503 bheads = repo.branchheads(branch)
1504 1504
1505 1505 extra = {}
1506 1506 if opts.get('close_branch'):
1507 1507 extra['close'] = 1
1508 1508
1509 1509 if not bheads:
1510 1510 raise util.Abort(_('can only close branch heads'))
1511 1511 elif opts.get('amend'):
1512 1512 if repo.parents()[0].p1().branch() != branch and \
1513 1513 repo.parents()[0].p2().branch() != branch:
1514 1514 raise util.Abort(_('can only close branch heads'))
1515 1515
1516 1516 if opts.get('amend'):
1517 1517 if ui.configbool('ui', 'commitsubrepos'):
1518 1518 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1519 1519
1520 1520 old = repo['.']
1521 1521 if not old.mutable():
1522 1522 raise util.Abort(_('cannot amend public changesets'))
1523 1523 if len(repo[None].parents()) > 1:
1524 1524 raise util.Abort(_('cannot amend while merging'))
1525 1525 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1526 1526 if not allowunstable and old.children():
1527 1527 raise util.Abort(_('cannot amend changeset with children'))
1528 1528
1529 1529 # commitfunc is used only for temporary amend commit by cmdutil.amend
1530 1530 def commitfunc(ui, repo, message, match, opts):
1531 1531 return repo.commit(message,
1532 1532 opts.get('user') or old.user(),
1533 1533 opts.get('date') or old.date(),
1534 1534 match,
1535 1535 extra=extra)
1536 1536
1537 1537 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1538 1538 if node == old.node():
1539 1539 ui.status(_("nothing changed\n"))
1540 1540 return 1
1541 1541 else:
1542 1542 def commitfunc(ui, repo, message, match, opts):
1543 1543 backup = ui.backupconfig('phases', 'new-commit')
1544 1544 baseui = repo.baseui
1545 1545 basebackup = baseui.backupconfig('phases', 'new-commit')
1546 1546 try:
1547 1547 if opts.get('secret'):
1548 1548 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1549 1549 # Propagate to subrepos
1550 1550 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1551 1551
1552 1552 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1553 1553 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1554 1554 return repo.commit(message, opts.get('user'), opts.get('date'),
1555 1555 match,
1556 1556 editor=editor,
1557 1557 extra=extra)
1558 1558 finally:
1559 1559 ui.restoreconfig(backup)
1560 1560 repo.baseui.restoreconfig(basebackup)
1561 1561
1562 1562
1563 1563 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1564 1564
1565 1565 if not node:
1566 1566 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1567 1567 if stat[3]:
1568 1568 ui.status(_("nothing changed (%d missing files, see "
1569 1569 "'hg status')\n") % len(stat[3]))
1570 1570 else:
1571 1571 ui.status(_("nothing changed\n"))
1572 1572 return 1
1573 1573
1574 1574 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1575 1575
1576 1576 @command('config|showconfig|debugconfig',
1577 1577 [('u', 'untrusted', None, _('show untrusted configuration options')),
1578 1578 ('e', 'edit', None, _('edit user config')),
1579 1579 ('l', 'local', None, _('edit repository config')),
1580 1580 ('g', 'global', None, _('edit global config'))],
1581 1581 _('[-u] [NAME]...'),
1582 1582 optionalrepo=True)
1583 1583 def config(ui, repo, *values, **opts):
1584 1584 """show combined config settings from all hgrc files
1585 1585
1586 1586 With no arguments, print names and values of all config items.
1587 1587
1588 1588 With one argument of the form section.name, print just the value
1589 1589 of that config item.
1590 1590
1591 1591 With multiple arguments, print names and values of all config
1592 1592 items with matching section names.
1593 1593
1594 1594 With --edit, start an editor on the user-level config file. With
1595 1595 --global, edit the system-wide config file. With --local, edit the
1596 1596 repository-level config file.
1597 1597
1598 1598 With --debug, the source (filename and line number) is printed
1599 1599 for each config item.
1600 1600
1601 1601 See :hg:`help config` for more information about config files.
1602 1602
1603 1603 Returns 0 on success, 1 if NAME does not exist.
1604 1604
1605 1605 """
1606 1606
1607 1607 if opts.get('edit') or opts.get('local') or opts.get('global'):
1608 1608 if opts.get('local') and opts.get('global'):
1609 1609 raise util.Abort(_("can't use --local and --global together"))
1610 1610
1611 1611 if opts.get('local'):
1612 1612 if not repo:
1613 1613 raise util.Abort(_("can't use --local outside a repository"))
1614 1614 paths = [repo.join('hgrc')]
1615 1615 elif opts.get('global'):
1616 1616 paths = scmutil.systemrcpath()
1617 1617 else:
1618 1618 paths = scmutil.userrcpath()
1619 1619
1620 1620 for f in paths:
1621 1621 if os.path.exists(f):
1622 1622 break
1623 1623 else:
1624 1624 if opts.get('global'):
1625 1625 samplehgrc = uimod.samplehgrcs['global']
1626 1626 elif opts.get('local'):
1627 1627 samplehgrc = uimod.samplehgrcs['local']
1628 1628 else:
1629 1629 samplehgrc = uimod.samplehgrcs['user']
1630 1630
1631 1631 f = paths[0]
1632 1632 fp = open(f, "w")
1633 1633 fp.write(samplehgrc)
1634 1634 fp.close()
1635 1635
1636 1636 editor = ui.geteditor()
1637 1637 ui.system("%s \"%s\"" % (editor, f),
1638 1638 onerr=util.Abort, errprefix=_("edit failed"))
1639 1639 return
1640 1640
1641 1641 for f in scmutil.rcpath():
1642 1642 ui.debug('read config from: %s\n' % f)
1643 1643 untrusted = bool(opts.get('untrusted'))
1644 1644 if values:
1645 1645 sections = [v for v in values if '.' not in v]
1646 1646 items = [v for v in values if '.' in v]
1647 1647 if len(items) > 1 or items and sections:
1648 1648 raise util.Abort(_('only one config item permitted'))
1649 1649 matched = False
1650 1650 for section, name, value in ui.walkconfig(untrusted=untrusted):
1651 1651 value = str(value).replace('\n', '\\n')
1652 1652 sectname = section + '.' + name
1653 1653 if values:
1654 1654 for v in values:
1655 1655 if v == section:
1656 1656 ui.debug('%s: ' %
1657 1657 ui.configsource(section, name, untrusted))
1658 1658 ui.write('%s=%s\n' % (sectname, value))
1659 1659 matched = True
1660 1660 elif v == sectname:
1661 1661 ui.debug('%s: ' %
1662 1662 ui.configsource(section, name, untrusted))
1663 1663 ui.write(value, '\n')
1664 1664 matched = True
1665 1665 else:
1666 1666 ui.debug('%s: ' %
1667 1667 ui.configsource(section, name, untrusted))
1668 1668 ui.write('%s=%s\n' % (sectname, value))
1669 1669 matched = True
1670 1670 if matched:
1671 1671 return 0
1672 1672 return 1
1673 1673
1674 1674 @command('copy|cp',
1675 1675 [('A', 'after', None, _('record a copy that has already occurred')),
1676 1676 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1677 1677 ] + walkopts + dryrunopts,
1678 1678 _('[OPTION]... [SOURCE]... DEST'))
1679 1679 def copy(ui, repo, *pats, **opts):
1680 1680 """mark files as copied for the next commit
1681 1681
1682 1682 Mark dest as having copies of source files. If dest is a
1683 1683 directory, copies are put in that directory. If dest is a file,
1684 1684 the source must be a single file.
1685 1685
1686 1686 By default, this command copies the contents of files as they
1687 1687 exist in the working directory. If invoked with -A/--after, the
1688 1688 operation is recorded, but no copying is performed.
1689 1689
1690 1690 This command takes effect with the next commit. To undo a copy
1691 1691 before that, see :hg:`revert`.
1692 1692
1693 1693 Returns 0 on success, 1 if errors are encountered.
1694 1694 """
1695 1695 wlock = repo.wlock(False)
1696 1696 try:
1697 1697 return cmdutil.copy(ui, repo, pats, opts)
1698 1698 finally:
1699 1699 wlock.release()
1700 1700
1701 1701 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1702 1702 def debugancestor(ui, repo, *args):
1703 1703 """find the ancestor revision of two revisions in a given index"""
1704 1704 if len(args) == 3:
1705 1705 index, rev1, rev2 = args
1706 1706 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1707 1707 lookup = r.lookup
1708 1708 elif len(args) == 2:
1709 1709 if not repo:
1710 1710 raise util.Abort(_("there is no Mercurial repository here "
1711 1711 "(.hg not found)"))
1712 1712 rev1, rev2 = args
1713 1713 r = repo.changelog
1714 1714 lookup = repo.lookup
1715 1715 else:
1716 1716 raise util.Abort(_('either two or three arguments required'))
1717 1717 a = r.ancestor(lookup(rev1), lookup(rev2))
1718 1718 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1719 1719
1720 1720 @command('debugbuilddag',
1721 1721 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1722 1722 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1723 1723 ('n', 'new-file', None, _('add new file at each rev'))],
1724 1724 _('[OPTION]... [TEXT]'))
1725 1725 def debugbuilddag(ui, repo, text=None,
1726 1726 mergeable_file=False,
1727 1727 overwritten_file=False,
1728 1728 new_file=False):
1729 1729 """builds a repo with a given DAG from scratch in the current empty repo
1730 1730
1731 1731 The description of the DAG is read from stdin if not given on the
1732 1732 command line.
1733 1733
1734 1734 Elements:
1735 1735
1736 1736 - "+n" is a linear run of n nodes based on the current default parent
1737 1737 - "." is a single node based on the current default parent
1738 1738 - "$" resets the default parent to null (implied at the start);
1739 1739 otherwise the default parent is always the last node created
1740 1740 - "<p" sets the default parent to the backref p
1741 1741 - "*p" is a fork at parent p, which is a backref
1742 1742 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1743 1743 - "/p2" is a merge of the preceding node and p2
1744 1744 - ":tag" defines a local tag for the preceding node
1745 1745 - "@branch" sets the named branch for subsequent nodes
1746 1746 - "#...\\n" is a comment up to the end of the line
1747 1747
1748 1748 Whitespace between the above elements is ignored.
1749 1749
1750 1750 A backref is either
1751 1751
1752 1752 - a number n, which references the node curr-n, where curr is the current
1753 1753 node, or
1754 1754 - the name of a local tag you placed earlier using ":tag", or
1755 1755 - empty to denote the default parent.
1756 1756
1757 1757 All string valued-elements are either strictly alphanumeric, or must
1758 1758 be enclosed in double quotes ("..."), with "\\" as escape character.
1759 1759 """
1760 1760
1761 1761 if text is None:
1762 1762 ui.status(_("reading DAG from stdin\n"))
1763 1763 text = ui.fin.read()
1764 1764
1765 1765 cl = repo.changelog
1766 1766 if len(cl) > 0:
1767 1767 raise util.Abort(_('repository is not empty'))
1768 1768
1769 1769 # determine number of revs in DAG
1770 1770 total = 0
1771 1771 for type, data in dagparser.parsedag(text):
1772 1772 if type == 'n':
1773 1773 total += 1
1774 1774
1775 1775 if mergeable_file:
1776 1776 linesperrev = 2
1777 1777 # make a file with k lines per rev
1778 1778 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1779 1779 initialmergedlines.append("")
1780 1780
1781 1781 tags = []
1782 1782
1783 1783 lock = tr = None
1784 1784 try:
1785 1785 lock = repo.lock()
1786 1786 tr = repo.transaction("builddag")
1787 1787
1788 1788 at = -1
1789 1789 atbranch = 'default'
1790 1790 nodeids = []
1791 1791 id = 0
1792 1792 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1793 1793 for type, data in dagparser.parsedag(text):
1794 1794 if type == 'n':
1795 1795 ui.note(('node %s\n' % str(data)))
1796 1796 id, ps = data
1797 1797
1798 1798 files = []
1799 1799 fctxs = {}
1800 1800
1801 1801 p2 = None
1802 1802 if mergeable_file:
1803 1803 fn = "mf"
1804 1804 p1 = repo[ps[0]]
1805 1805 if len(ps) > 1:
1806 1806 p2 = repo[ps[1]]
1807 1807 pa = p1.ancestor(p2)
1808 1808 base, local, other = [x[fn].data() for x in (pa, p1,
1809 1809 p2)]
1810 1810 m3 = simplemerge.Merge3Text(base, local, other)
1811 1811 ml = [l.strip() for l in m3.merge_lines()]
1812 1812 ml.append("")
1813 1813 elif at > 0:
1814 1814 ml = p1[fn].data().split("\n")
1815 1815 else:
1816 1816 ml = initialmergedlines
1817 1817 ml[id * linesperrev] += " r%i" % id
1818 1818 mergedtext = "\n".join(ml)
1819 1819 files.append(fn)
1820 1820 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1821 1821
1822 1822 if overwritten_file:
1823 1823 fn = "of"
1824 1824 files.append(fn)
1825 1825 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1826 1826
1827 1827 if new_file:
1828 1828 fn = "nf%i" % id
1829 1829 files.append(fn)
1830 1830 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1831 1831 if len(ps) > 1:
1832 1832 if not p2:
1833 1833 p2 = repo[ps[1]]
1834 1834 for fn in p2:
1835 1835 if fn.startswith("nf"):
1836 1836 files.append(fn)
1837 1837 fctxs[fn] = p2[fn]
1838 1838
1839 1839 def fctxfn(repo, cx, path):
1840 1840 return fctxs.get(path)
1841 1841
1842 1842 if len(ps) == 0 or ps[0] < 0:
1843 1843 pars = [None, None]
1844 1844 elif len(ps) == 1:
1845 1845 pars = [nodeids[ps[0]], None]
1846 1846 else:
1847 1847 pars = [nodeids[p] for p in ps]
1848 1848 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1849 1849 date=(id, 0),
1850 1850 user="debugbuilddag",
1851 1851 extra={'branch': atbranch})
1852 1852 nodeid = repo.commitctx(cx)
1853 1853 nodeids.append(nodeid)
1854 1854 at = id
1855 1855 elif type == 'l':
1856 1856 id, name = data
1857 1857 ui.note(('tag %s\n' % name))
1858 1858 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1859 1859 elif type == 'a':
1860 1860 ui.note(('branch %s\n' % data))
1861 1861 atbranch = data
1862 1862 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1863 1863 tr.close()
1864 1864
1865 1865 if tags:
1866 1866 repo.vfs.write("localtags", "".join(tags))
1867 1867 finally:
1868 1868 ui.progress(_('building'), None)
1869 1869 release(tr, lock)
1870 1870
1871 1871 @command('debugbundle',
1872 1872 [('a', 'all', None, _('show all details'))],
1873 1873 _('FILE'),
1874 1874 norepo=True)
1875 1875 def debugbundle(ui, bundlepath, all=None, **opts):
1876 1876 """lists the contents of a bundle"""
1877 1877 f = hg.openpath(ui, bundlepath)
1878 1878 try:
1879 1879 gen = exchange.readbundle(ui, f, bundlepath)
1880 1880 if isinstance(gen, bundle2.unbundle20):
1881 1881 return _debugbundle2(ui, gen, all=all, **opts)
1882 1882 if all:
1883 1883 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1884 1884
1885 1885 def showchunks(named):
1886 1886 ui.write("\n%s\n" % named)
1887 1887 chain = None
1888 1888 while True:
1889 1889 chunkdata = gen.deltachunk(chain)
1890 1890 if not chunkdata:
1891 1891 break
1892 1892 node = chunkdata['node']
1893 1893 p1 = chunkdata['p1']
1894 1894 p2 = chunkdata['p2']
1895 1895 cs = chunkdata['cs']
1896 1896 deltabase = chunkdata['deltabase']
1897 1897 delta = chunkdata['delta']
1898 1898 ui.write("%s %s %s %s %s %s\n" %
1899 1899 (hex(node), hex(p1), hex(p2),
1900 1900 hex(cs), hex(deltabase), len(delta)))
1901 1901 chain = node
1902 1902
1903 1903 chunkdata = gen.changelogheader()
1904 1904 showchunks("changelog")
1905 1905 chunkdata = gen.manifestheader()
1906 1906 showchunks("manifest")
1907 1907 while True:
1908 1908 chunkdata = gen.filelogheader()
1909 1909 if not chunkdata:
1910 1910 break
1911 1911 fname = chunkdata['filename']
1912 1912 showchunks(fname)
1913 1913 else:
1914 1914 if isinstance(gen, bundle2.unbundle20):
1915 1915 raise util.Abort(_('use debugbundle2 for this file'))
1916 1916 chunkdata = gen.changelogheader()
1917 1917 chain = None
1918 1918 while True:
1919 1919 chunkdata = gen.deltachunk(chain)
1920 1920 if not chunkdata:
1921 1921 break
1922 1922 node = chunkdata['node']
1923 1923 ui.write("%s\n" % hex(node))
1924 1924 chain = node
1925 1925 finally:
1926 1926 f.close()
1927 1927
1928 1928 def _debugbundle2(ui, gen, **opts):
1929 1929 """lists the contents of a bundle2"""
1930 1930 if not isinstance(gen, bundle2.unbundle20):
1931 1931 raise util.Abort(_('not a bundle2 file'))
1932 1932 ui.write(('Stream params: %s\n' % repr(gen.params)))
1933 1933 for part in gen.iterparts():
1934 1934 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1935 1935 if part.type == 'changegroup':
1936 1936 version = part.params.get('version', '01')
1937 1937 cg = changegroup.packermap[version][1](part, 'UN')
1938 1938 chunkdata = cg.changelogheader()
1939 1939 chain = None
1940 1940 while True:
1941 1941 chunkdata = cg.deltachunk(chain)
1942 1942 if not chunkdata:
1943 1943 break
1944 1944 node = chunkdata['node']
1945 1945 ui.write(" %s\n" % hex(node))
1946 1946 chain = node
1947 1947
1948 1948 @command('debugcheckstate', [], '')
1949 1949 def debugcheckstate(ui, repo):
1950 1950 """validate the correctness of the current dirstate"""
1951 1951 parent1, parent2 = repo.dirstate.parents()
1952 1952 m1 = repo[parent1].manifest()
1953 1953 m2 = repo[parent2].manifest()
1954 1954 errors = 0
1955 1955 for f in repo.dirstate:
1956 1956 state = repo.dirstate[f]
1957 1957 if state in "nr" and f not in m1:
1958 1958 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1959 1959 errors += 1
1960 1960 if state in "a" and f in m1:
1961 1961 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1962 1962 errors += 1
1963 1963 if state in "m" and f not in m1 and f not in m2:
1964 1964 ui.warn(_("%s in state %s, but not in either manifest\n") %
1965 1965 (f, state))
1966 1966 errors += 1
1967 1967 for f in m1:
1968 1968 state = repo.dirstate[f]
1969 1969 if state not in "nrm":
1970 1970 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1971 1971 errors += 1
1972 1972 if errors:
1973 1973 error = _(".hg/dirstate inconsistent with current parent's manifest")
1974 1974 raise util.Abort(error)
1975 1975
1976 1976 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
1977 1977 def debugcommands(ui, cmd='', *args):
1978 1978 """list all available commands and options"""
1979 1979 for cmd, vals in sorted(table.iteritems()):
1980 1980 cmd = cmd.split('|')[0].strip('^')
1981 1981 opts = ', '.join([i[1] for i in vals[1]])
1982 1982 ui.write('%s: %s\n' % (cmd, opts))
1983 1983
1984 1984 @command('debugcomplete',
1985 1985 [('o', 'options', None, _('show the command options'))],
1986 1986 _('[-o] CMD'),
1987 1987 norepo=True)
1988 1988 def debugcomplete(ui, cmd='', **opts):
1989 1989 """returns the completion list associated with the given command"""
1990 1990
1991 1991 if opts.get('options'):
1992 1992 options = []
1993 1993 otables = [globalopts]
1994 1994 if cmd:
1995 1995 aliases, entry = cmdutil.findcmd(cmd, table, False)
1996 1996 otables.append(entry[1])
1997 1997 for t in otables:
1998 1998 for o in t:
1999 1999 if "(DEPRECATED)" in o[3]:
2000 2000 continue
2001 2001 if o[0]:
2002 2002 options.append('-%s' % o[0])
2003 2003 options.append('--%s' % o[1])
2004 2004 ui.write("%s\n" % "\n".join(options))
2005 2005 return
2006 2006
2007 2007 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2008 2008 if ui.verbose:
2009 2009 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2010 2010 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2011 2011
2012 2012 @command('debugdag',
2013 2013 [('t', 'tags', None, _('use tags as labels')),
2014 2014 ('b', 'branches', None, _('annotate with branch names')),
2015 2015 ('', 'dots', None, _('use dots for runs')),
2016 2016 ('s', 'spaces', None, _('separate elements by spaces'))],
2017 2017 _('[OPTION]... [FILE [REV]...]'),
2018 2018 optionalrepo=True)
2019 2019 def debugdag(ui, repo, file_=None, *revs, **opts):
2020 2020 """format the changelog or an index DAG as a concise textual description
2021 2021
2022 2022 If you pass a revlog index, the revlog's DAG is emitted. If you list
2023 2023 revision numbers, they get labeled in the output as rN.
2024 2024
2025 2025 Otherwise, the changelog DAG of the current repo is emitted.
2026 2026 """
2027 2027 spaces = opts.get('spaces')
2028 2028 dots = opts.get('dots')
2029 2029 if file_:
2030 2030 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2031 2031 revs = set((int(r) for r in revs))
2032 2032 def events():
2033 2033 for r in rlog:
2034 2034 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2035 2035 if p != -1))
2036 2036 if r in revs:
2037 2037 yield 'l', (r, "r%i" % r)
2038 2038 elif repo:
2039 2039 cl = repo.changelog
2040 2040 tags = opts.get('tags')
2041 2041 branches = opts.get('branches')
2042 2042 if tags:
2043 2043 labels = {}
2044 2044 for l, n in repo.tags().items():
2045 2045 labels.setdefault(cl.rev(n), []).append(l)
2046 2046 def events():
2047 2047 b = "default"
2048 2048 for r in cl:
2049 2049 if branches:
2050 2050 newb = cl.read(cl.node(r))[5]['branch']
2051 2051 if newb != b:
2052 2052 yield 'a', newb
2053 2053 b = newb
2054 2054 yield 'n', (r, list(p for p in cl.parentrevs(r)
2055 2055 if p != -1))
2056 2056 if tags:
2057 2057 ls = labels.get(r)
2058 2058 if ls:
2059 2059 for l in ls:
2060 2060 yield 'l', (r, l)
2061 2061 else:
2062 2062 raise util.Abort(_('need repo for changelog dag'))
2063 2063
2064 2064 for line in dagparser.dagtextlines(events(),
2065 2065 addspaces=spaces,
2066 2066 wraplabels=True,
2067 2067 wrapannotations=True,
2068 2068 wrapnonlinear=dots,
2069 2069 usedots=dots,
2070 2070 maxlinewidth=70):
2071 2071 ui.write(line)
2072 2072 ui.write("\n")
2073 2073
2074 2074 @command('debugdata',
2075 2075 [('c', 'changelog', False, _('open changelog')),
2076 2076 ('m', 'manifest', False, _('open manifest')),
2077 2077 ('', 'dir', False, _('open directory manifest'))],
2078 2078 _('-c|-m|FILE REV'))
2079 2079 def debugdata(ui, repo, file_, rev=None, **opts):
2080 2080 """dump the contents of a data file revision"""
2081 2081 if opts.get('changelog') or opts.get('manifest'):
2082 2082 file_, rev = None, file_
2083 2083 elif rev is None:
2084 2084 raise error.CommandError('debugdata', _('invalid arguments'))
2085 2085 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2086 2086 try:
2087 2087 ui.write(r.revision(r.lookup(rev)))
2088 2088 except KeyError:
2089 2089 raise util.Abort(_('invalid revision identifier %s') % rev)
2090 2090
2091 2091 @command('debugdate',
2092 2092 [('e', 'extended', None, _('try extended date formats'))],
2093 2093 _('[-e] DATE [RANGE]'),
2094 2094 norepo=True, optionalrepo=True)
2095 2095 def debugdate(ui, date, range=None, **opts):
2096 2096 """parse and display a date"""
2097 2097 if opts["extended"]:
2098 2098 d = util.parsedate(date, util.extendeddateformats)
2099 2099 else:
2100 2100 d = util.parsedate(date)
2101 2101 ui.write(("internal: %s %s\n") % d)
2102 2102 ui.write(("standard: %s\n") % util.datestr(d))
2103 2103 if range:
2104 2104 m = util.matchdate(range)
2105 2105 ui.write(("match: %s\n") % m(d[0]))
2106 2106
2107 2107 @command('debugdiscovery',
2108 2108 [('', 'old', None, _('use old-style discovery')),
2109 2109 ('', 'nonheads', None,
2110 2110 _('use old-style discovery with non-heads included')),
2111 2111 ] + remoteopts,
2112 2112 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2113 2113 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2114 2114 """runs the changeset discovery protocol in isolation"""
2115 2115 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2116 2116 opts.get('branch'))
2117 2117 remote = hg.peer(repo, opts, remoteurl)
2118 2118 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2119 2119
2120 2120 # make sure tests are repeatable
2121 2121 random.seed(12323)
2122 2122
2123 2123 def doit(localheads, remoteheads, remote=remote):
2124 2124 if opts.get('old'):
2125 2125 if localheads:
2126 2126 raise util.Abort('cannot use localheads with old style '
2127 2127 'discovery')
2128 2128 if not util.safehasattr(remote, 'branches'):
2129 2129 # enable in-client legacy support
2130 2130 remote = localrepo.locallegacypeer(remote.local())
2131 2131 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2132 2132 force=True)
2133 2133 common = set(common)
2134 2134 if not opts.get('nonheads'):
2135 2135 ui.write(("unpruned common: %s\n") %
2136 2136 " ".join(sorted(short(n) for n in common)))
2137 2137 dag = dagutil.revlogdag(repo.changelog)
2138 2138 all = dag.ancestorset(dag.internalizeall(common))
2139 2139 common = dag.externalizeall(dag.headsetofconnecteds(all))
2140 2140 else:
2141 2141 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2142 2142 common = set(common)
2143 2143 rheads = set(hds)
2144 2144 lheads = set(repo.heads())
2145 2145 ui.write(("common heads: %s\n") %
2146 2146 " ".join(sorted(short(n) for n in common)))
2147 2147 if lheads <= common:
2148 2148 ui.write(("local is subset\n"))
2149 2149 elif rheads <= common:
2150 2150 ui.write(("remote is subset\n"))
2151 2151
2152 2152 serverlogs = opts.get('serverlog')
2153 2153 if serverlogs:
2154 2154 for filename in serverlogs:
2155 2155 logfile = open(filename, 'r')
2156 2156 try:
2157 2157 line = logfile.readline()
2158 2158 while line:
2159 2159 parts = line.strip().split(';')
2160 2160 op = parts[1]
2161 2161 if op == 'cg':
2162 2162 pass
2163 2163 elif op == 'cgss':
2164 2164 doit(parts[2].split(' '), parts[3].split(' '))
2165 2165 elif op == 'unb':
2166 2166 doit(parts[3].split(' '), parts[2].split(' '))
2167 2167 line = logfile.readline()
2168 2168 finally:
2169 2169 logfile.close()
2170 2170
2171 2171 else:
2172 2172 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2173 2173 opts.get('remote_head'))
2174 2174 localrevs = opts.get('local_head')
2175 2175 doit(localrevs, remoterevs)
2176 2176
2177 2177 @command('debugextensions', formatteropts, [], norepo=True)
2178 2178 def debugextensions(ui, **opts):
2179 2179 '''show information about active extensions'''
2180 2180 exts = extensions.extensions(ui)
2181 2181 fm = ui.formatter('debugextensions', opts)
2182 2182 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
2183 2183 extsource = extmod.__file__
2184 2184 exttestedwith = getattr(extmod, 'testedwith', None)
2185 2185 if exttestedwith is not None:
2186 2186 exttestedwith = exttestedwith.split()
2187 2187 extbuglink = getattr(extmod, 'buglink', None)
2188 2188
2189 2189 fm.startitem()
2190 2190
2191 2191 if ui.quiet or ui.verbose:
2192 2192 fm.write('name', '%s\n', extname)
2193 2193 else:
2194 2194 fm.write('name', '%s', extname)
2195 2195 if not exttestedwith:
2196 2196 fm.plain(_(' (untested!)\n'))
2197 2197 else:
2198 2198 if exttestedwith == ['internal'] or \
2199 2199 util.version() in exttestedwith:
2200 2200 fm.plain('\n')
2201 2201 else:
2202 2202 lasttestedversion = exttestedwith[-1]
2203 2203 fm.plain(' (%s!)\n' % lasttestedversion)
2204 2204
2205 2205 fm.condwrite(ui.verbose and extsource, 'source',
2206 2206 _(' location: %s\n'), extsource or "")
2207 2207
2208 2208 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
2209 2209 _(' tested with: %s\n'), ' '.join(exttestedwith or []))
2210 2210
2211 2211 fm.condwrite(ui.verbose and extbuglink, 'buglink',
2212 2212 _(' bug reporting: %s\n'), extbuglink or "")
2213 2213
2214 2214 fm.end()
2215 2215
2216 2216 @command('debugfileset',
2217 2217 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2218 2218 _('[-r REV] FILESPEC'))
2219 2219 def debugfileset(ui, repo, expr, **opts):
2220 2220 '''parse and apply a fileset specification'''
2221 2221 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2222 2222 if ui.verbose:
2223 2223 tree = fileset.parse(expr)
2224 2224 ui.note(fileset.prettyformat(tree), "\n")
2225 2225
2226 2226 for f in ctx.getfileset(expr):
2227 2227 ui.write("%s\n" % f)
2228 2228
2229 2229 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2230 2230 def debugfsinfo(ui, path="."):
2231 2231 """show information detected about current filesystem"""
2232 2232 util.writefile('.debugfsinfo', '')
2233 2233 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2234 2234 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2235 2235 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2236 2236 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2237 2237 and 'yes' or 'no'))
2238 2238 os.unlink('.debugfsinfo')
2239 2239
2240 2240 @command('debuggetbundle',
2241 2241 [('H', 'head', [], _('id of head node'), _('ID')),
2242 2242 ('C', 'common', [], _('id of common node'), _('ID')),
2243 2243 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2244 2244 _('REPO FILE [-H|-C ID]...'),
2245 2245 norepo=True)
2246 2246 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2247 2247 """retrieves a bundle from a repo
2248 2248
2249 2249 Every ID must be a full-length hex node id string. Saves the bundle to the
2250 2250 given file.
2251 2251 """
2252 2252 repo = hg.peer(ui, opts, repopath)
2253 2253 if not repo.capable('getbundle'):
2254 2254 raise util.Abort("getbundle() not supported by target repository")
2255 2255 args = {}
2256 2256 if common:
2257 2257 args['common'] = [bin(s) for s in common]
2258 2258 if head:
2259 2259 args['heads'] = [bin(s) for s in head]
2260 2260 # TODO: get desired bundlecaps from command line.
2261 2261 args['bundlecaps'] = None
2262 2262 bundle = repo.getbundle('debug', **args)
2263 2263
2264 2264 bundletype = opts.get('type', 'bzip2').lower()
2265 2265 btypes = {'none': 'HG10UN',
2266 2266 'bzip2': 'HG10BZ',
2267 2267 'gzip': 'HG10GZ',
2268 2268 'bundle2': 'HG20'}
2269 2269 bundletype = btypes.get(bundletype)
2270 2270 if bundletype not in changegroup.bundletypes:
2271 2271 raise util.Abort(_('unknown bundle type specified with --type'))
2272 2272 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2273 2273
2274 2274 @command('debugignore', [], '')
2275 2275 def debugignore(ui, repo, *values, **opts):
2276 2276 """display the combined ignore pattern"""
2277 2277 ignore = repo.dirstate._ignore
2278 2278 includepat = getattr(ignore, 'includepat', None)
2279 2279 if includepat is not None:
2280 2280 ui.write("%s\n" % includepat)
2281 2281 else:
2282 2282 raise util.Abort(_("no ignore patterns found"))
2283 2283
2284 2284 @command('debugindex',
2285 2285 [('c', 'changelog', False, _('open changelog')),
2286 2286 ('m', 'manifest', False, _('open manifest')),
2287 2287 ('', 'dir', False, _('open directory manifest')),
2288 2288 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2289 2289 _('[-f FORMAT] -c|-m|FILE'),
2290 2290 optionalrepo=True)
2291 2291 def debugindex(ui, repo, file_=None, **opts):
2292 2292 """dump the contents of an index file"""
2293 2293 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2294 2294 format = opts.get('format', 0)
2295 2295 if format not in (0, 1):
2296 2296 raise util.Abort(_("unknown format %d") % format)
2297 2297
2298 2298 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2299 2299 if generaldelta:
2300 2300 basehdr = ' delta'
2301 2301 else:
2302 2302 basehdr = ' base'
2303 2303
2304 2304 if ui.debugflag:
2305 2305 shortfn = hex
2306 2306 else:
2307 2307 shortfn = short
2308 2308
2309 2309 # There might not be anything in r, so have a sane default
2310 2310 idlen = 12
2311 2311 for i in r:
2312 2312 idlen = len(shortfn(r.node(i)))
2313 2313 break
2314 2314
2315 2315 if format == 0:
2316 2316 ui.write(" rev offset length " + basehdr + " linkrev"
2317 2317 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2318 2318 elif format == 1:
2319 2319 ui.write(" rev flag offset length"
2320 2320 " size " + basehdr + " link p1 p2"
2321 2321 " %s\n" % "nodeid".rjust(idlen))
2322 2322
2323 2323 for i in r:
2324 2324 node = r.node(i)
2325 2325 if generaldelta:
2326 2326 base = r.deltaparent(i)
2327 2327 else:
2328 2328 base = r.chainbase(i)
2329 2329 if format == 0:
2330 2330 try:
2331 2331 pp = r.parents(node)
2332 2332 except Exception:
2333 2333 pp = [nullid, nullid]
2334 2334 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2335 2335 i, r.start(i), r.length(i), base, r.linkrev(i),
2336 2336 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2337 2337 elif format == 1:
2338 2338 pr = r.parentrevs(i)
2339 2339 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2340 2340 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2341 2341 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2342 2342
2343 2343 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2344 2344 def debugindexdot(ui, repo, file_):
2345 2345 """dump an index DAG as a graphviz dot file"""
2346 2346 r = None
2347 2347 if repo:
2348 2348 filelog = repo.file(file_)
2349 2349 if len(filelog):
2350 2350 r = filelog
2351 2351 if not r:
2352 2352 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2353 2353 ui.write(("digraph G {\n"))
2354 2354 for i in r:
2355 2355 node = r.node(i)
2356 2356 pp = r.parents(node)
2357 2357 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2358 2358 if pp[1] != nullid:
2359 2359 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2360 2360 ui.write("}\n")
2361 2361
2362 2362 @command('debuginstall', [], '', norepo=True)
2363 2363 def debuginstall(ui):
2364 2364 '''test Mercurial installation
2365 2365
2366 2366 Returns 0 on success.
2367 2367 '''
2368 2368
2369 2369 def writetemp(contents):
2370 2370 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2371 2371 f = os.fdopen(fd, "wb")
2372 2372 f.write(contents)
2373 2373 f.close()
2374 2374 return name
2375 2375
2376 2376 problems = 0
2377 2377
2378 2378 # encoding
2379 2379 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2380 2380 try:
2381 2381 encoding.fromlocal("test")
2382 2382 except util.Abort as inst:
2383 2383 ui.write(" %s\n" % inst)
2384 2384 ui.write(_(" (check that your locale is properly set)\n"))
2385 2385 problems += 1
2386 2386
2387 2387 # Python
2388 2388 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2389 2389 ui.status(_("checking Python version (%s)\n")
2390 2390 % ("%s.%s.%s" % sys.version_info[:3]))
2391 2391 ui.status(_("checking Python lib (%s)...\n")
2392 2392 % os.path.dirname(os.__file__))
2393 2393
2394 2394 # compiled modules
2395 2395 ui.status(_("checking installed modules (%s)...\n")
2396 2396 % os.path.dirname(__file__))
2397 2397 try:
2398 2398 import bdiff, mpatch, base85, osutil
2399 2399 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2400 2400 except Exception as inst:
2401 2401 ui.write(" %s\n" % inst)
2402 2402 ui.write(_(" One or more extensions could not be found"))
2403 2403 ui.write(_(" (check that you compiled the extensions)\n"))
2404 2404 problems += 1
2405 2405
2406 2406 # templates
2407 2407 import templater
2408 2408 p = templater.templatepaths()
2409 2409 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2410 2410 if p:
2411 2411 m = templater.templatepath("map-cmdline.default")
2412 2412 if m:
2413 2413 # template found, check if it is working
2414 2414 try:
2415 2415 templater.templater(m)
2416 2416 except Exception as inst:
2417 2417 ui.write(" %s\n" % inst)
2418 2418 p = None
2419 2419 else:
2420 2420 ui.write(_(" template 'default' not found\n"))
2421 2421 p = None
2422 2422 else:
2423 2423 ui.write(_(" no template directories found\n"))
2424 2424 if not p:
2425 2425 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2426 2426 problems += 1
2427 2427
2428 2428 # editor
2429 2429 ui.status(_("checking commit editor...\n"))
2430 2430 editor = ui.geteditor()
2431 2431 editor = util.expandpath(editor)
2432 2432 cmdpath = util.findexe(shlex.split(editor)[0])
2433 2433 if not cmdpath:
2434 2434 if editor == 'vi':
2435 2435 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2436 2436 ui.write(_(" (specify a commit editor in your configuration"
2437 2437 " file)\n"))
2438 2438 else:
2439 2439 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2440 2440 ui.write(_(" (specify a commit editor in your configuration"
2441 2441 " file)\n"))
2442 2442 problems += 1
2443 2443
2444 2444 # check username
2445 2445 ui.status(_("checking username...\n"))
2446 2446 try:
2447 2447 ui.username()
2448 2448 except util.Abort as e:
2449 2449 ui.write(" %s\n" % e)
2450 2450 ui.write(_(" (specify a username in your configuration file)\n"))
2451 2451 problems += 1
2452 2452
2453 2453 if not problems:
2454 2454 ui.status(_("no problems detected\n"))
2455 2455 else:
2456 2456 ui.write(_("%s problems detected,"
2457 2457 " please check your install!\n") % problems)
2458 2458
2459 2459 return problems
2460 2460
2461 2461 @command('debugknown', [], _('REPO ID...'), norepo=True)
2462 2462 def debugknown(ui, repopath, *ids, **opts):
2463 2463 """test whether node ids are known to a repo
2464 2464
2465 2465 Every ID must be a full-length hex node id string. Returns a list of 0s
2466 2466 and 1s indicating unknown/known.
2467 2467 """
2468 2468 repo = hg.peer(ui, opts, repopath)
2469 2469 if not repo.capable('known'):
2470 2470 raise util.Abort("known() not supported by target repository")
2471 2471 flags = repo.known([bin(s) for s in ids])
2472 2472 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2473 2473
2474 2474 @command('debuglabelcomplete', [], _('LABEL...'))
2475 2475 def debuglabelcomplete(ui, repo, *args):
2476 2476 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2477 2477 debugnamecomplete(ui, repo, *args)
2478 2478
2479 @command('debugmergestate', [], '')
2480 def debugmergestate(ui, repo, *args):
2481 """print merge state
2482
2483 Use --verbose to print out information about whether v1 or v2 merge state
2484 was chosen."""
2485 def printrecords(version):
2486 ui.write(('* version %s records\n') % version)
2487 if version == 1:
2488 records = v1records
2489 else:
2490 records = v2records
2491
2492 for rtype, record in records:
2493 # pretty print some record types
2494 if rtype == 'L':
2495 ui.write(('local: %s\n') % record)
2496 elif rtype == 'O':
2497 ui.write(('other: %s\n') % record)
2498 elif rtype == 'F':
2499 r = record.split('\0')
2500 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2501 if version == 1:
2502 onode = 'not stored in v1 format'
2503 flags = r[7]
2504 else:
2505 onode, flags = r[7:9]
2506 ui.write(('file: %s (state "%s", hash %s)\n')
2507 % (f, state, hash))
2508 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2509 ui.write((' ancestor path: %s (node %s)\n') % (afile, anode))
2510 ui.write((' other path: %s (node %s)\n') % (ofile, onode))
2511 else:
2512 ui.write(('unrecognized entry: %s\t%s\n')
2513 % (rtype, record.replace('\0', '\t')))
2514
2515 ms = mergemod.mergestate(repo)
2516
2517 # sort so that reasonable information is on top
2518 v1records = ms._readrecordsv1()
2519 v2records = ms._readrecordsv2()
2520 order = 'LO'
2521 def key(r):
2522 idx = order.find(r[0])
2523 if idx == -1:
2524 return (1, r[1])
2525 else:
2526 return (0, idx)
2527 v1records.sort(key=key)
2528 v2records.sort(key=key)
2529
2530 if not v1records and not v2records:
2531 ui.write(('no merge state found\n'))
2532 elif not v2records:
2533 ui.note(('no version 2 merge state\n'))
2534 printrecords(1)
2535 elif ms._v1v2match(v1records, v2records):
2536 ui.note(('v1 and v2 states match: using v2\n'))
2537 printrecords(2)
2538 else:
2539 ui.note(('v1 and v2 states mismatch: using v1\n'))
2540 printrecords(1)
2541 if ui.verbose:
2542 printrecords(2)
2543
2479 2544 @command('debugnamecomplete', [], _('NAME...'))
2480 2545 def debugnamecomplete(ui, repo, *args):
2481 2546 '''complete "names" - tags, open branch names, bookmark names'''
2482 2547
2483 2548 names = set()
2484 2549 # since we previously only listed open branches, we will handle that
2485 2550 # specially (after this for loop)
2486 2551 for name, ns in repo.names.iteritems():
2487 2552 if name != 'branches':
2488 2553 names.update(ns.listnames(repo))
2489 2554 names.update(tag for (tag, heads, tip, closed)
2490 2555 in repo.branchmap().iterbranches() if not closed)
2491 2556 completions = set()
2492 2557 if not args:
2493 2558 args = ['']
2494 2559 for a in args:
2495 2560 completions.update(n for n in names if n.startswith(a))
2496 2561 ui.write('\n'.join(sorted(completions)))
2497 2562 ui.write('\n')
2498 2563
2499 2564 @command('debuglocks',
2500 2565 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2501 2566 ('W', 'force-wlock', None,
2502 2567 _('free the working state lock (DANGEROUS)'))],
2503 2568 _('[OPTION]...'))
2504 2569 def debuglocks(ui, repo, **opts):
2505 2570 """show or modify state of locks
2506 2571
2507 2572 By default, this command will show which locks are held. This
2508 2573 includes the user and process holding the lock, the amount of time
2509 2574 the lock has been held, and the machine name where the process is
2510 2575 running if it's not local.
2511 2576
2512 2577 Locks protect the integrity of Mercurial's data, so should be
2513 2578 treated with care. System crashes or other interruptions may cause
2514 2579 locks to not be properly released, though Mercurial will usually
2515 2580 detect and remove such stale locks automatically.
2516 2581
2517 2582 However, detecting stale locks may not always be possible (for
2518 2583 instance, on a shared filesystem). Removing locks may also be
2519 2584 blocked by filesystem permissions.
2520 2585
2521 2586 Returns 0 if no locks are held.
2522 2587
2523 2588 """
2524 2589
2525 2590 if opts.get('force_lock'):
2526 2591 repo.svfs.unlink('lock')
2527 2592 if opts.get('force_wlock'):
2528 2593 repo.vfs.unlink('wlock')
2529 2594 if opts.get('force_lock') or opts.get('force_lock'):
2530 2595 return 0
2531 2596
2532 2597 now = time.time()
2533 2598 held = 0
2534 2599
2535 2600 def report(vfs, name, method):
2536 2601 # this causes stale locks to get reaped for more accurate reporting
2537 2602 try:
2538 2603 l = method(False)
2539 2604 except error.LockHeld:
2540 2605 l = None
2541 2606
2542 2607 if l:
2543 2608 l.release()
2544 2609 else:
2545 2610 try:
2546 2611 stat = vfs.lstat(name)
2547 2612 age = now - stat.st_mtime
2548 2613 user = util.username(stat.st_uid)
2549 2614 locker = vfs.readlock(name)
2550 2615 if ":" in locker:
2551 2616 host, pid = locker.split(':')
2552 2617 if host == socket.gethostname():
2553 2618 locker = 'user %s, process %s' % (user, pid)
2554 2619 else:
2555 2620 locker = 'user %s, process %s, host %s' \
2556 2621 % (user, pid, host)
2557 2622 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2558 2623 return 1
2559 2624 except OSError as e:
2560 2625 if e.errno != errno.ENOENT:
2561 2626 raise
2562 2627
2563 2628 ui.write("%-6s free\n" % (name + ":"))
2564 2629 return 0
2565 2630
2566 2631 held += report(repo.svfs, "lock", repo.lock)
2567 2632 held += report(repo.vfs, "wlock", repo.wlock)
2568 2633
2569 2634 return held
2570 2635
2571 2636 @command('debugobsolete',
2572 2637 [('', 'flags', 0, _('markers flag')),
2573 2638 ('', 'record-parents', False,
2574 2639 _('record parent information for the precursor')),
2575 2640 ('r', 'rev', [], _('display markers relevant to REV')),
2576 2641 ] + commitopts2,
2577 2642 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2578 2643 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2579 2644 """create arbitrary obsolete marker
2580 2645
2581 2646 With no arguments, displays the list of obsolescence markers."""
2582 2647
2583 2648 def parsenodeid(s):
2584 2649 try:
2585 2650 # We do not use revsingle/revrange functions here to accept
2586 2651 # arbitrary node identifiers, possibly not present in the
2587 2652 # local repository.
2588 2653 n = bin(s)
2589 2654 if len(n) != len(nullid):
2590 2655 raise TypeError()
2591 2656 return n
2592 2657 except TypeError:
2593 2658 raise util.Abort('changeset references must be full hexadecimal '
2594 2659 'node identifiers')
2595 2660
2596 2661 if precursor is not None:
2597 2662 if opts['rev']:
2598 2663 raise util.Abort('cannot select revision when creating marker')
2599 2664 metadata = {}
2600 2665 metadata['user'] = opts['user'] or ui.username()
2601 2666 succs = tuple(parsenodeid(succ) for succ in successors)
2602 2667 l = repo.lock()
2603 2668 try:
2604 2669 tr = repo.transaction('debugobsolete')
2605 2670 try:
2606 2671 date = opts.get('date')
2607 2672 if date:
2608 2673 date = util.parsedate(date)
2609 2674 else:
2610 2675 date = None
2611 2676 prec = parsenodeid(precursor)
2612 2677 parents = None
2613 2678 if opts['record_parents']:
2614 2679 if prec not in repo.unfiltered():
2615 2680 raise util.Abort('cannot used --record-parents on '
2616 2681 'unknown changesets')
2617 2682 parents = repo.unfiltered()[prec].parents()
2618 2683 parents = tuple(p.node() for p in parents)
2619 2684 repo.obsstore.create(tr, prec, succs, opts['flags'],
2620 2685 parents=parents, date=date,
2621 2686 metadata=metadata)
2622 2687 tr.close()
2623 2688 except ValueError as exc:
2624 2689 raise util.Abort(_('bad obsmarker input: %s') % exc)
2625 2690 finally:
2626 2691 tr.release()
2627 2692 finally:
2628 2693 l.release()
2629 2694 else:
2630 2695 if opts['rev']:
2631 2696 revs = scmutil.revrange(repo, opts['rev'])
2632 2697 nodes = [repo[r].node() for r in revs]
2633 2698 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2634 2699 markers.sort(key=lambda x: x._data)
2635 2700 else:
2636 2701 markers = obsolete.getmarkers(repo)
2637 2702
2638 2703 for m in markers:
2639 2704 cmdutil.showmarker(ui, m)
2640 2705
2641 2706 @command('debugpathcomplete',
2642 2707 [('f', 'full', None, _('complete an entire path')),
2643 2708 ('n', 'normal', None, _('show only normal files')),
2644 2709 ('a', 'added', None, _('show only added files')),
2645 2710 ('r', 'removed', None, _('show only removed files'))],
2646 2711 _('FILESPEC...'))
2647 2712 def debugpathcomplete(ui, repo, *specs, **opts):
2648 2713 '''complete part or all of a tracked path
2649 2714
2650 2715 This command supports shells that offer path name completion. It
2651 2716 currently completes only files already known to the dirstate.
2652 2717
2653 2718 Completion extends only to the next path segment unless
2654 2719 --full is specified, in which case entire paths are used.'''
2655 2720
2656 2721 def complete(path, acceptable):
2657 2722 dirstate = repo.dirstate
2658 2723 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2659 2724 rootdir = repo.root + os.sep
2660 2725 if spec != repo.root and not spec.startswith(rootdir):
2661 2726 return [], []
2662 2727 if os.path.isdir(spec):
2663 2728 spec += '/'
2664 2729 spec = spec[len(rootdir):]
2665 2730 fixpaths = os.sep != '/'
2666 2731 if fixpaths:
2667 2732 spec = spec.replace(os.sep, '/')
2668 2733 speclen = len(spec)
2669 2734 fullpaths = opts['full']
2670 2735 files, dirs = set(), set()
2671 2736 adddir, addfile = dirs.add, files.add
2672 2737 for f, st in dirstate.iteritems():
2673 2738 if f.startswith(spec) and st[0] in acceptable:
2674 2739 if fixpaths:
2675 2740 f = f.replace('/', os.sep)
2676 2741 if fullpaths:
2677 2742 addfile(f)
2678 2743 continue
2679 2744 s = f.find(os.sep, speclen)
2680 2745 if s >= 0:
2681 2746 adddir(f[:s])
2682 2747 else:
2683 2748 addfile(f)
2684 2749 return files, dirs
2685 2750
2686 2751 acceptable = ''
2687 2752 if opts['normal']:
2688 2753 acceptable += 'nm'
2689 2754 if opts['added']:
2690 2755 acceptable += 'a'
2691 2756 if opts['removed']:
2692 2757 acceptable += 'r'
2693 2758 cwd = repo.getcwd()
2694 2759 if not specs:
2695 2760 specs = ['.']
2696 2761
2697 2762 files, dirs = set(), set()
2698 2763 for spec in specs:
2699 2764 f, d = complete(spec, acceptable or 'nmar')
2700 2765 files.update(f)
2701 2766 dirs.update(d)
2702 2767 files.update(dirs)
2703 2768 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2704 2769 ui.write('\n')
2705 2770
2706 2771 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2707 2772 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2708 2773 '''access the pushkey key/value protocol
2709 2774
2710 2775 With two args, list the keys in the given namespace.
2711 2776
2712 2777 With five args, set a key to new if it currently is set to old.
2713 2778 Reports success or failure.
2714 2779 '''
2715 2780
2716 2781 target = hg.peer(ui, {}, repopath)
2717 2782 if keyinfo:
2718 2783 key, old, new = keyinfo
2719 2784 r = target.pushkey(namespace, key, old, new)
2720 2785 ui.status(str(r) + '\n')
2721 2786 return not r
2722 2787 else:
2723 2788 for k, v in sorted(target.listkeys(namespace).iteritems()):
2724 2789 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2725 2790 v.encode('string-escape')))
2726 2791
2727 2792 @command('debugpvec', [], _('A B'))
2728 2793 def debugpvec(ui, repo, a, b=None):
2729 2794 ca = scmutil.revsingle(repo, a)
2730 2795 cb = scmutil.revsingle(repo, b)
2731 2796 pa = pvec.ctxpvec(ca)
2732 2797 pb = pvec.ctxpvec(cb)
2733 2798 if pa == pb:
2734 2799 rel = "="
2735 2800 elif pa > pb:
2736 2801 rel = ">"
2737 2802 elif pa < pb:
2738 2803 rel = "<"
2739 2804 elif pa | pb:
2740 2805 rel = "|"
2741 2806 ui.write(_("a: %s\n") % pa)
2742 2807 ui.write(_("b: %s\n") % pb)
2743 2808 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2744 2809 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2745 2810 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2746 2811 pa.distance(pb), rel))
2747 2812
2748 2813 @command('debugrebuilddirstate|debugrebuildstate',
2749 2814 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
2750 2815 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
2751 2816 'the working copy parent')),
2752 2817 ],
2753 2818 _('[-r REV]'))
2754 2819 def debugrebuilddirstate(ui, repo, rev, **opts):
2755 2820 """rebuild the dirstate as it would look like for the given revision
2756 2821
2757 2822 If no revision is specified the first current parent will be used.
2758 2823
2759 2824 The dirstate will be set to the files of the given revision.
2760 2825 The actual working directory content or existing dirstate
2761 2826 information such as adds or removes is not considered.
2762 2827
2763 2828 ``minimal`` will only rebuild the dirstate status for files that claim to be
2764 2829 tracked but are not in the parent manifest, or that exist in the parent
2765 2830 manifest but are not in the dirstate. It will not change adds, removes, or
2766 2831 modified files that are in the working copy parent.
2767 2832
2768 2833 One use of this command is to make the next :hg:`status` invocation
2769 2834 check the actual file content.
2770 2835 """
2771 2836 ctx = scmutil.revsingle(repo, rev)
2772 2837 wlock = repo.wlock()
2773 2838 try:
2774 2839 dirstate = repo.dirstate
2775 2840
2776 2841 # See command doc for what minimal does.
2777 2842 if opts.get('minimal'):
2778 2843 dirstatefiles = set(dirstate)
2779 2844 ctxfiles = set(ctx.manifest().keys())
2780 2845 for file in (dirstatefiles | ctxfiles):
2781 2846 indirstate = file in dirstatefiles
2782 2847 inctx = file in ctxfiles
2783 2848
2784 2849 if indirstate and not inctx and dirstate[file] != 'a':
2785 2850 dirstate.drop(file)
2786 2851 elif inctx and not indirstate:
2787 2852 dirstate.normallookup(file)
2788 2853 else:
2789 2854 dirstate.rebuild(ctx.node(), ctx.manifest())
2790 2855 finally:
2791 2856 wlock.release()
2792 2857
2793 2858 @command('debugrebuildfncache', [], '')
2794 2859 def debugrebuildfncache(ui, repo):
2795 2860 """rebuild the fncache file"""
2796 2861 repair.rebuildfncache(ui, repo)
2797 2862
2798 2863 @command('debugrename',
2799 2864 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2800 2865 _('[-r REV] FILE'))
2801 2866 def debugrename(ui, repo, file1, *pats, **opts):
2802 2867 """dump rename information"""
2803 2868
2804 2869 ctx = scmutil.revsingle(repo, opts.get('rev'))
2805 2870 m = scmutil.match(ctx, (file1,) + pats, opts)
2806 2871 for abs in ctx.walk(m):
2807 2872 fctx = ctx[abs]
2808 2873 o = fctx.filelog().renamed(fctx.filenode())
2809 2874 rel = m.rel(abs)
2810 2875 if o:
2811 2876 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2812 2877 else:
2813 2878 ui.write(_("%s not renamed\n") % rel)
2814 2879
2815 2880 @command('debugrevlog',
2816 2881 [('c', 'changelog', False, _('open changelog')),
2817 2882 ('m', 'manifest', False, _('open manifest')),
2818 2883 ('', 'dir', False, _('open directory manifest')),
2819 2884 ('d', 'dump', False, _('dump index data'))],
2820 2885 _('-c|-m|FILE'),
2821 2886 optionalrepo=True)
2822 2887 def debugrevlog(ui, repo, file_=None, **opts):
2823 2888 """show data and statistics about a revlog"""
2824 2889 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2825 2890
2826 2891 if opts.get("dump"):
2827 2892 numrevs = len(r)
2828 2893 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2829 2894 " rawsize totalsize compression heads chainlen\n")
2830 2895 ts = 0
2831 2896 heads = set()
2832 2897
2833 2898 for rev in xrange(numrevs):
2834 2899 dbase = r.deltaparent(rev)
2835 2900 if dbase == -1:
2836 2901 dbase = rev
2837 2902 cbase = r.chainbase(rev)
2838 2903 clen = r.chainlen(rev)
2839 2904 p1, p2 = r.parentrevs(rev)
2840 2905 rs = r.rawsize(rev)
2841 2906 ts = ts + rs
2842 2907 heads -= set(r.parentrevs(rev))
2843 2908 heads.add(rev)
2844 2909 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2845 2910 "%11d %5d %8d\n" %
2846 2911 (rev, p1, p2, r.start(rev), r.end(rev),
2847 2912 r.start(dbase), r.start(cbase),
2848 2913 r.start(p1), r.start(p2),
2849 2914 rs, ts, ts / r.end(rev), len(heads), clen))
2850 2915 return 0
2851 2916
2852 2917 v = r.version
2853 2918 format = v & 0xFFFF
2854 2919 flags = []
2855 2920 gdelta = False
2856 2921 if v & revlog.REVLOGNGINLINEDATA:
2857 2922 flags.append('inline')
2858 2923 if v & revlog.REVLOGGENERALDELTA:
2859 2924 gdelta = True
2860 2925 flags.append('generaldelta')
2861 2926 if not flags:
2862 2927 flags = ['(none)']
2863 2928
2864 2929 nummerges = 0
2865 2930 numfull = 0
2866 2931 numprev = 0
2867 2932 nump1 = 0
2868 2933 nump2 = 0
2869 2934 numother = 0
2870 2935 nump1prev = 0
2871 2936 nump2prev = 0
2872 2937 chainlengths = []
2873 2938
2874 2939 datasize = [None, 0, 0L]
2875 2940 fullsize = [None, 0, 0L]
2876 2941 deltasize = [None, 0, 0L]
2877 2942
2878 2943 def addsize(size, l):
2879 2944 if l[0] is None or size < l[0]:
2880 2945 l[0] = size
2881 2946 if size > l[1]:
2882 2947 l[1] = size
2883 2948 l[2] += size
2884 2949
2885 2950 numrevs = len(r)
2886 2951 for rev in xrange(numrevs):
2887 2952 p1, p2 = r.parentrevs(rev)
2888 2953 delta = r.deltaparent(rev)
2889 2954 if format > 0:
2890 2955 addsize(r.rawsize(rev), datasize)
2891 2956 if p2 != nullrev:
2892 2957 nummerges += 1
2893 2958 size = r.length(rev)
2894 2959 if delta == nullrev:
2895 2960 chainlengths.append(0)
2896 2961 numfull += 1
2897 2962 addsize(size, fullsize)
2898 2963 else:
2899 2964 chainlengths.append(chainlengths[delta] + 1)
2900 2965 addsize(size, deltasize)
2901 2966 if delta == rev - 1:
2902 2967 numprev += 1
2903 2968 if delta == p1:
2904 2969 nump1prev += 1
2905 2970 elif delta == p2:
2906 2971 nump2prev += 1
2907 2972 elif delta == p1:
2908 2973 nump1 += 1
2909 2974 elif delta == p2:
2910 2975 nump2 += 1
2911 2976 elif delta != nullrev:
2912 2977 numother += 1
2913 2978
2914 2979 # Adjust size min value for empty cases
2915 2980 for size in (datasize, fullsize, deltasize):
2916 2981 if size[0] is None:
2917 2982 size[0] = 0
2918 2983
2919 2984 numdeltas = numrevs - numfull
2920 2985 numoprev = numprev - nump1prev - nump2prev
2921 2986 totalrawsize = datasize[2]
2922 2987 datasize[2] /= numrevs
2923 2988 fulltotal = fullsize[2]
2924 2989 fullsize[2] /= numfull
2925 2990 deltatotal = deltasize[2]
2926 2991 if numrevs - numfull > 0:
2927 2992 deltasize[2] /= numrevs - numfull
2928 2993 totalsize = fulltotal + deltatotal
2929 2994 avgchainlen = sum(chainlengths) / numrevs
2930 2995 maxchainlen = max(chainlengths)
2931 2996 compratio = totalrawsize / totalsize
2932 2997
2933 2998 basedfmtstr = '%%%dd\n'
2934 2999 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2935 3000
2936 3001 def dfmtstr(max):
2937 3002 return basedfmtstr % len(str(max))
2938 3003 def pcfmtstr(max, padding=0):
2939 3004 return basepcfmtstr % (len(str(max)), ' ' * padding)
2940 3005
2941 3006 def pcfmt(value, total):
2942 3007 return (value, 100 * float(value) / total)
2943 3008
2944 3009 ui.write(('format : %d\n') % format)
2945 3010 ui.write(('flags : %s\n') % ', '.join(flags))
2946 3011
2947 3012 ui.write('\n')
2948 3013 fmt = pcfmtstr(totalsize)
2949 3014 fmt2 = dfmtstr(totalsize)
2950 3015 ui.write(('revisions : ') + fmt2 % numrevs)
2951 3016 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2952 3017 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2953 3018 ui.write(('revisions : ') + fmt2 % numrevs)
2954 3019 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2955 3020 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2956 3021 ui.write(('revision size : ') + fmt2 % totalsize)
2957 3022 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2958 3023 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2959 3024
2960 3025 ui.write('\n')
2961 3026 fmt = dfmtstr(max(avgchainlen, compratio))
2962 3027 ui.write(('avg chain length : ') + fmt % avgchainlen)
2963 3028 ui.write(('max chain length : ') + fmt % maxchainlen)
2964 3029 ui.write(('compression ratio : ') + fmt % compratio)
2965 3030
2966 3031 if format > 0:
2967 3032 ui.write('\n')
2968 3033 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2969 3034 % tuple(datasize))
2970 3035 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2971 3036 % tuple(fullsize))
2972 3037 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2973 3038 % tuple(deltasize))
2974 3039
2975 3040 if numdeltas > 0:
2976 3041 ui.write('\n')
2977 3042 fmt = pcfmtstr(numdeltas)
2978 3043 fmt2 = pcfmtstr(numdeltas, 4)
2979 3044 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2980 3045 if numprev > 0:
2981 3046 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2982 3047 numprev))
2983 3048 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2984 3049 numprev))
2985 3050 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2986 3051 numprev))
2987 3052 if gdelta:
2988 3053 ui.write(('deltas against p1 : ')
2989 3054 + fmt % pcfmt(nump1, numdeltas))
2990 3055 ui.write(('deltas against p2 : ')
2991 3056 + fmt % pcfmt(nump2, numdeltas))
2992 3057 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2993 3058 numdeltas))
2994 3059
2995 3060 @command('debugrevspec',
2996 3061 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2997 3062 ('REVSPEC'))
2998 3063 def debugrevspec(ui, repo, expr, **opts):
2999 3064 """parse and apply a revision specification
3000 3065
3001 3066 Use --verbose to print the parsed tree before and after aliases
3002 3067 expansion.
3003 3068 """
3004 3069 if ui.verbose:
3005 3070 tree = revset.parse(expr, lookup=repo.__contains__)
3006 3071 ui.note(revset.prettyformat(tree), "\n")
3007 3072 newtree = revset.findaliases(ui, tree)
3008 3073 if newtree != tree:
3009 3074 ui.note(revset.prettyformat(newtree), "\n")
3010 3075 tree = newtree
3011 3076 newtree = revset.foldconcat(tree)
3012 3077 if newtree != tree:
3013 3078 ui.note(revset.prettyformat(newtree), "\n")
3014 3079 if opts["optimize"]:
3015 3080 weight, optimizedtree = revset.optimize(newtree, True)
3016 3081 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
3017 3082 func = revset.match(ui, expr, repo)
3018 3083 revs = func(repo)
3019 3084 if ui.verbose:
3020 3085 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
3021 3086 for c in revs:
3022 3087 ui.write("%s\n" % c)
3023 3088
3024 3089 @command('debugsetparents', [], _('REV1 [REV2]'))
3025 3090 def debugsetparents(ui, repo, rev1, rev2=None):
3026 3091 """manually set the parents of the current working directory
3027 3092
3028 3093 This is useful for writing repository conversion tools, but should
3029 3094 be used with care. For example, neither the working directory nor the
3030 3095 dirstate is updated, so file status may be incorrect after running this
3031 3096 command.
3032 3097
3033 3098 Returns 0 on success.
3034 3099 """
3035 3100
3036 3101 r1 = scmutil.revsingle(repo, rev1).node()
3037 3102 r2 = scmutil.revsingle(repo, rev2, 'null').node()
3038 3103
3039 3104 wlock = repo.wlock()
3040 3105 try:
3041 3106 repo.dirstate.beginparentchange()
3042 3107 repo.setparents(r1, r2)
3043 3108 repo.dirstate.endparentchange()
3044 3109 finally:
3045 3110 wlock.release()
3046 3111
3047 3112 @command('debugdirstate|debugstate',
3048 3113 [('', 'nodates', None, _('do not display the saved mtime')),
3049 3114 ('', 'datesort', None, _('sort by saved mtime'))],
3050 3115 _('[OPTION]...'))
3051 3116 def debugstate(ui, repo, nodates=None, datesort=None):
3052 3117 """show the contents of the current dirstate"""
3053 3118 timestr = ""
3054 3119 if datesort:
3055 3120 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
3056 3121 else:
3057 3122 keyfunc = None # sort by filename
3058 3123 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
3059 3124 if ent[3] == -1:
3060 3125 timestr = 'unset '
3061 3126 elif nodates:
3062 3127 timestr = 'set '
3063 3128 else:
3064 3129 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
3065 3130 time.localtime(ent[3]))
3066 3131 if ent[1] & 0o20000:
3067 3132 mode = 'lnk'
3068 3133 else:
3069 3134 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3070 3135 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3071 3136 for f in repo.dirstate.copies():
3072 3137 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3073 3138
3074 3139 @command('debugsub',
3075 3140 [('r', 'rev', '',
3076 3141 _('revision to check'), _('REV'))],
3077 3142 _('[-r REV] [REV]'))
3078 3143 def debugsub(ui, repo, rev=None):
3079 3144 ctx = scmutil.revsingle(repo, rev, None)
3080 3145 for k, v in sorted(ctx.substate.items()):
3081 3146 ui.write(('path %s\n') % k)
3082 3147 ui.write((' source %s\n') % v[0])
3083 3148 ui.write((' revision %s\n') % v[1])
3084 3149
3085 3150 @command('debugsuccessorssets',
3086 3151 [],
3087 3152 _('[REV]'))
3088 3153 def debugsuccessorssets(ui, repo, *revs):
3089 3154 """show set of successors for revision
3090 3155
3091 3156 A successors set of changeset A is a consistent group of revisions that
3092 3157 succeed A. It contains non-obsolete changesets only.
3093 3158
3094 3159 In most cases a changeset A has a single successors set containing a single
3095 3160 successor (changeset A replaced by A').
3096 3161
3097 3162 A changeset that is made obsolete with no successors are called "pruned".
3098 3163 Such changesets have no successors sets at all.
3099 3164
3100 3165 A changeset that has been "split" will have a successors set containing
3101 3166 more than one successor.
3102 3167
3103 3168 A changeset that has been rewritten in multiple different ways is called
3104 3169 "divergent". Such changesets have multiple successor sets (each of which
3105 3170 may also be split, i.e. have multiple successors).
3106 3171
3107 3172 Results are displayed as follows::
3108 3173
3109 3174 <rev1>
3110 3175 <successors-1A>
3111 3176 <rev2>
3112 3177 <successors-2A>
3113 3178 <successors-2B1> <successors-2B2> <successors-2B3>
3114 3179
3115 3180 Here rev2 has two possible (i.e. divergent) successors sets. The first
3116 3181 holds one element, whereas the second holds three (i.e. the changeset has
3117 3182 been split).
3118 3183 """
3119 3184 # passed to successorssets caching computation from one call to another
3120 3185 cache = {}
3121 3186 ctx2str = str
3122 3187 node2str = short
3123 3188 if ui.debug():
3124 3189 def ctx2str(ctx):
3125 3190 return ctx.hex()
3126 3191 node2str = hex
3127 3192 for rev in scmutil.revrange(repo, revs):
3128 3193 ctx = repo[rev]
3129 3194 ui.write('%s\n'% ctx2str(ctx))
3130 3195 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3131 3196 if succsset:
3132 3197 ui.write(' ')
3133 3198 ui.write(node2str(succsset[0]))
3134 3199 for node in succsset[1:]:
3135 3200 ui.write(' ')
3136 3201 ui.write(node2str(node))
3137 3202 ui.write('\n')
3138 3203
3139 3204 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3140 3205 def debugwalk(ui, repo, *pats, **opts):
3141 3206 """show how files match on given patterns"""
3142 3207 m = scmutil.match(repo[None], pats, opts)
3143 3208 items = list(repo.walk(m))
3144 3209 if not items:
3145 3210 return
3146 3211 f = lambda fn: fn
3147 3212 if ui.configbool('ui', 'slash') and os.sep != '/':
3148 3213 f = lambda fn: util.normpath(fn)
3149 3214 fmt = 'f %%-%ds %%-%ds %%s' % (
3150 3215 max([len(abs) for abs in items]),
3151 3216 max([len(m.rel(abs)) for abs in items]))
3152 3217 for abs in items:
3153 3218 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3154 3219 ui.write("%s\n" % line.rstrip())
3155 3220
3156 3221 @command('debugwireargs',
3157 3222 [('', 'three', '', 'three'),
3158 3223 ('', 'four', '', 'four'),
3159 3224 ('', 'five', '', 'five'),
3160 3225 ] + remoteopts,
3161 3226 _('REPO [OPTIONS]... [ONE [TWO]]'),
3162 3227 norepo=True)
3163 3228 def debugwireargs(ui, repopath, *vals, **opts):
3164 3229 repo = hg.peer(ui, opts, repopath)
3165 3230 for opt in remoteopts:
3166 3231 del opts[opt[1]]
3167 3232 args = {}
3168 3233 for k, v in opts.iteritems():
3169 3234 if v:
3170 3235 args[k] = v
3171 3236 # run twice to check that we don't mess up the stream for the next command
3172 3237 res1 = repo.debugwireargs(*vals, **args)
3173 3238 res2 = repo.debugwireargs(*vals, **args)
3174 3239 ui.write("%s\n" % res1)
3175 3240 if res1 != res2:
3176 3241 ui.warn("%s\n" % res2)
3177 3242
3178 3243 @command('^diff',
3179 3244 [('r', 'rev', [], _('revision'), _('REV')),
3180 3245 ('c', 'change', '', _('change made by revision'), _('REV'))
3181 3246 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3182 3247 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3183 3248 inferrepo=True)
3184 3249 def diff(ui, repo, *pats, **opts):
3185 3250 """diff repository (or selected files)
3186 3251
3187 3252 Show differences between revisions for the specified files.
3188 3253
3189 3254 Differences between files are shown using the unified diff format.
3190 3255
3191 3256 .. note::
3192 3257
3193 3258 diff may generate unexpected results for merges, as it will
3194 3259 default to comparing against the working directory's first
3195 3260 parent changeset if no revisions are specified.
3196 3261
3197 3262 When two revision arguments are given, then changes are shown
3198 3263 between those revisions. If only one revision is specified then
3199 3264 that revision is compared to the working directory, and, when no
3200 3265 revisions are specified, the working directory files are compared
3201 3266 to its parent.
3202 3267
3203 3268 Alternatively you can specify -c/--change with a revision to see
3204 3269 the changes in that changeset relative to its first parent.
3205 3270
3206 3271 Without the -a/--text option, diff will avoid generating diffs of
3207 3272 files it detects as binary. With -a, diff will generate a diff
3208 3273 anyway, probably with undesirable results.
3209 3274
3210 3275 Use the -g/--git option to generate diffs in the git extended diff
3211 3276 format. For more information, read :hg:`help diffs`.
3212 3277
3213 3278 .. container:: verbose
3214 3279
3215 3280 Examples:
3216 3281
3217 3282 - compare a file in the current working directory to its parent::
3218 3283
3219 3284 hg diff foo.c
3220 3285
3221 3286 - compare two historical versions of a directory, with rename info::
3222 3287
3223 3288 hg diff --git -r 1.0:1.2 lib/
3224 3289
3225 3290 - get change stats relative to the last change on some date::
3226 3291
3227 3292 hg diff --stat -r "date('may 2')"
3228 3293
3229 3294 - diff all newly-added files that contain a keyword::
3230 3295
3231 3296 hg diff "set:added() and grep(GNU)"
3232 3297
3233 3298 - compare a revision and its parents::
3234 3299
3235 3300 hg diff -c 9353 # compare against first parent
3236 3301 hg diff -r 9353^:9353 # same using revset syntax
3237 3302 hg diff -r 9353^2:9353 # compare against the second parent
3238 3303
3239 3304 Returns 0 on success.
3240 3305 """
3241 3306
3242 3307 revs = opts.get('rev')
3243 3308 change = opts.get('change')
3244 3309 stat = opts.get('stat')
3245 3310 reverse = opts.get('reverse')
3246 3311
3247 3312 if revs and change:
3248 3313 msg = _('cannot specify --rev and --change at the same time')
3249 3314 raise util.Abort(msg)
3250 3315 elif change:
3251 3316 node2 = scmutil.revsingle(repo, change, None).node()
3252 3317 node1 = repo[node2].p1().node()
3253 3318 else:
3254 3319 node1, node2 = scmutil.revpair(repo, revs)
3255 3320
3256 3321 if reverse:
3257 3322 node1, node2 = node2, node1
3258 3323
3259 3324 diffopts = patch.diffallopts(ui, opts)
3260 3325 m = scmutil.match(repo[node2], pats, opts)
3261 3326 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3262 3327 listsubrepos=opts.get('subrepos'),
3263 3328 root=opts.get('root'))
3264 3329
3265 3330 @command('^export',
3266 3331 [('o', 'output', '',
3267 3332 _('print output to file with formatted name'), _('FORMAT')),
3268 3333 ('', 'switch-parent', None, _('diff against the second parent')),
3269 3334 ('r', 'rev', [], _('revisions to export'), _('REV')),
3270 3335 ] + diffopts,
3271 3336 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3272 3337 def export(ui, repo, *changesets, **opts):
3273 3338 """dump the header and diffs for one or more changesets
3274 3339
3275 3340 Print the changeset header and diffs for one or more revisions.
3276 3341 If no revision is given, the parent of the working directory is used.
3277 3342
3278 3343 The information shown in the changeset header is: author, date,
3279 3344 branch name (if non-default), changeset hash, parent(s) and commit
3280 3345 comment.
3281 3346
3282 3347 .. note::
3283 3348
3284 3349 export may generate unexpected diff output for merge
3285 3350 changesets, as it will compare the merge changeset against its
3286 3351 first parent only.
3287 3352
3288 3353 Output may be to a file, in which case the name of the file is
3289 3354 given using a format string. The formatting rules are as follows:
3290 3355
3291 3356 :``%%``: literal "%" character
3292 3357 :``%H``: changeset hash (40 hexadecimal digits)
3293 3358 :``%N``: number of patches being generated
3294 3359 :``%R``: changeset revision number
3295 3360 :``%b``: basename of the exporting repository
3296 3361 :``%h``: short-form changeset hash (12 hexadecimal digits)
3297 3362 :``%m``: first line of the commit message (only alphanumeric characters)
3298 3363 :``%n``: zero-padded sequence number, starting at 1
3299 3364 :``%r``: zero-padded changeset revision number
3300 3365
3301 3366 Without the -a/--text option, export will avoid generating diffs
3302 3367 of files it detects as binary. With -a, export will generate a
3303 3368 diff anyway, probably with undesirable results.
3304 3369
3305 3370 Use the -g/--git option to generate diffs in the git extended diff
3306 3371 format. See :hg:`help diffs` for more information.
3307 3372
3308 3373 With the --switch-parent option, the diff will be against the
3309 3374 second parent. It can be useful to review a merge.
3310 3375
3311 3376 .. container:: verbose
3312 3377
3313 3378 Examples:
3314 3379
3315 3380 - use export and import to transplant a bugfix to the current
3316 3381 branch::
3317 3382
3318 3383 hg export -r 9353 | hg import -
3319 3384
3320 3385 - export all the changesets between two revisions to a file with
3321 3386 rename information::
3322 3387
3323 3388 hg export --git -r 123:150 > changes.txt
3324 3389
3325 3390 - split outgoing changes into a series of patches with
3326 3391 descriptive names::
3327 3392
3328 3393 hg export -r "outgoing()" -o "%n-%m.patch"
3329 3394
3330 3395 Returns 0 on success.
3331 3396 """
3332 3397 changesets += tuple(opts.get('rev', []))
3333 3398 if not changesets:
3334 3399 changesets = ['.']
3335 3400 revs = scmutil.revrange(repo, changesets)
3336 3401 if not revs:
3337 3402 raise util.Abort(_("export requires at least one changeset"))
3338 3403 if len(revs) > 1:
3339 3404 ui.note(_('exporting patches:\n'))
3340 3405 else:
3341 3406 ui.note(_('exporting patch:\n'))
3342 3407 cmdutil.export(repo, revs, template=opts.get('output'),
3343 3408 switch_parent=opts.get('switch_parent'),
3344 3409 opts=patch.diffallopts(ui, opts))
3345 3410
3346 3411 @command('files',
3347 3412 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3348 3413 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3349 3414 ] + walkopts + formatteropts + subrepoopts,
3350 3415 _('[OPTION]... [PATTERN]...'))
3351 3416 def files(ui, repo, *pats, **opts):
3352 3417 """list tracked files
3353 3418
3354 3419 Print files under Mercurial control in the working directory or
3355 3420 specified revision whose names match the given patterns (excluding
3356 3421 removed files).
3357 3422
3358 3423 If no patterns are given to match, this command prints the names
3359 3424 of all files under Mercurial control in the working directory.
3360 3425
3361 3426 .. container:: verbose
3362 3427
3363 3428 Examples:
3364 3429
3365 3430 - list all files under the current directory::
3366 3431
3367 3432 hg files .
3368 3433
3369 3434 - shows sizes and flags for current revision::
3370 3435
3371 3436 hg files -vr .
3372 3437
3373 3438 - list all files named README::
3374 3439
3375 3440 hg files -I "**/README"
3376 3441
3377 3442 - list all binary files::
3378 3443
3379 3444 hg files "set:binary()"
3380 3445
3381 3446 - find files containing a regular expression::
3382 3447
3383 3448 hg files "set:grep('bob')"
3384 3449
3385 3450 - search tracked file contents with xargs and grep::
3386 3451
3387 3452 hg files -0 | xargs -0 grep foo
3388 3453
3389 3454 See :hg:`help patterns` and :hg:`help filesets` for more information
3390 3455 on specifying file patterns.
3391 3456
3392 3457 Returns 0 if a match is found, 1 otherwise.
3393 3458
3394 3459 """
3395 3460 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3396 3461
3397 3462 end = '\n'
3398 3463 if opts.get('print0'):
3399 3464 end = '\0'
3400 3465 fm = ui.formatter('files', opts)
3401 3466 fmt = '%s' + end
3402 3467
3403 3468 m = scmutil.match(ctx, pats, opts)
3404 3469 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3405 3470
3406 3471 fm.end()
3407 3472
3408 3473 return ret
3409 3474
3410 3475 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3411 3476 def forget(ui, repo, *pats, **opts):
3412 3477 """forget the specified files on the next commit
3413 3478
3414 3479 Mark the specified files so they will no longer be tracked
3415 3480 after the next commit.
3416 3481
3417 3482 This only removes files from the current branch, not from the
3418 3483 entire project history, and it does not delete them from the
3419 3484 working directory.
3420 3485
3421 3486 To delete the file from the working directory, see :hg:`remove`.
3422 3487
3423 3488 To undo a forget before the next commit, see :hg:`add`.
3424 3489
3425 3490 .. container:: verbose
3426 3491
3427 3492 Examples:
3428 3493
3429 3494 - forget newly-added binary files::
3430 3495
3431 3496 hg forget "set:added() and binary()"
3432 3497
3433 3498 - forget files that would be excluded by .hgignore::
3434 3499
3435 3500 hg forget "set:hgignore()"
3436 3501
3437 3502 Returns 0 on success.
3438 3503 """
3439 3504
3440 3505 if not pats:
3441 3506 raise util.Abort(_('no files specified'))
3442 3507
3443 3508 m = scmutil.match(repo[None], pats, opts)
3444 3509 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3445 3510 return rejected and 1 or 0
3446 3511
3447 3512 @command(
3448 3513 'graft',
3449 3514 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3450 3515 ('c', 'continue', False, _('resume interrupted graft')),
3451 3516 ('e', 'edit', False, _('invoke editor on commit messages')),
3452 3517 ('', 'log', None, _('append graft info to log message')),
3453 3518 ('f', 'force', False, _('force graft')),
3454 3519 ('D', 'currentdate', False,
3455 3520 _('record the current date as commit date')),
3456 3521 ('U', 'currentuser', False,
3457 3522 _('record the current user as committer'), _('DATE'))]
3458 3523 + commitopts2 + mergetoolopts + dryrunopts,
3459 3524 _('[OPTION]... [-r] REV...'))
3460 3525 def graft(ui, repo, *revs, **opts):
3461 3526 '''copy changes from other branches onto the current branch
3462 3527
3463 3528 This command uses Mercurial's merge logic to copy individual
3464 3529 changes from other branches without merging branches in the
3465 3530 history graph. This is sometimes known as 'backporting' or
3466 3531 'cherry-picking'. By default, graft will copy user, date, and
3467 3532 description from the source changesets.
3468 3533
3469 3534 Changesets that are ancestors of the current revision, that have
3470 3535 already been grafted, or that are merges will be skipped.
3471 3536
3472 3537 If --log is specified, log messages will have a comment appended
3473 3538 of the form::
3474 3539
3475 3540 (grafted from CHANGESETHASH)
3476 3541
3477 3542 If --force is specified, revisions will be grafted even if they
3478 3543 are already ancestors of or have been grafted to the destination.
3479 3544 This is useful when the revisions have since been backed out.
3480 3545
3481 3546 If a graft merge results in conflicts, the graft process is
3482 3547 interrupted so that the current merge can be manually resolved.
3483 3548 Once all conflicts are addressed, the graft process can be
3484 3549 continued with the -c/--continue option.
3485 3550
3486 3551 .. note::
3487 3552
3488 3553 The -c/--continue option does not reapply earlier options, except
3489 3554 for --force.
3490 3555
3491 3556 .. container:: verbose
3492 3557
3493 3558 Examples:
3494 3559
3495 3560 - copy a single change to the stable branch and edit its description::
3496 3561
3497 3562 hg update stable
3498 3563 hg graft --edit 9393
3499 3564
3500 3565 - graft a range of changesets with one exception, updating dates::
3501 3566
3502 3567 hg graft -D "2085::2093 and not 2091"
3503 3568
3504 3569 - continue a graft after resolving conflicts::
3505 3570
3506 3571 hg graft -c
3507 3572
3508 3573 - show the source of a grafted changeset::
3509 3574
3510 3575 hg log --debug -r .
3511 3576
3512 3577 See :hg:`help revisions` and :hg:`help revsets` for more about
3513 3578 specifying revisions.
3514 3579
3515 3580 Returns 0 on successful completion.
3516 3581 '''
3517 3582
3518 3583 revs = list(revs)
3519 3584 revs.extend(opts['rev'])
3520 3585
3521 3586 if not opts.get('user') and opts.get('currentuser'):
3522 3587 opts['user'] = ui.username()
3523 3588 if not opts.get('date') and opts.get('currentdate'):
3524 3589 opts['date'] = "%d %d" % util.makedate()
3525 3590
3526 3591 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3527 3592
3528 3593 cont = False
3529 3594 if opts['continue']:
3530 3595 cont = True
3531 3596 if revs:
3532 3597 raise util.Abort(_("can't specify --continue and revisions"))
3533 3598 # read in unfinished revisions
3534 3599 try:
3535 3600 nodes = repo.vfs.read('graftstate').splitlines()
3536 3601 revs = [repo[node].rev() for node in nodes]
3537 3602 except IOError as inst:
3538 3603 if inst.errno != errno.ENOENT:
3539 3604 raise
3540 3605 raise util.Abort(_("no graft state found, can't continue"))
3541 3606 else:
3542 3607 cmdutil.checkunfinished(repo)
3543 3608 cmdutil.bailifchanged(repo)
3544 3609 if not revs:
3545 3610 raise util.Abort(_('no revisions specified'))
3546 3611 revs = scmutil.revrange(repo, revs)
3547 3612
3548 3613 skipped = set()
3549 3614 # check for merges
3550 3615 for rev in repo.revs('%ld and merge()', revs):
3551 3616 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3552 3617 skipped.add(rev)
3553 3618 revs = [r for r in revs if r not in skipped]
3554 3619 if not revs:
3555 3620 return -1
3556 3621
3557 3622 # Don't check in the --continue case, in effect retaining --force across
3558 3623 # --continues. That's because without --force, any revisions we decided to
3559 3624 # skip would have been filtered out here, so they wouldn't have made their
3560 3625 # way to the graftstate. With --force, any revisions we would have otherwise
3561 3626 # skipped would not have been filtered out, and if they hadn't been applied
3562 3627 # already, they'd have been in the graftstate.
3563 3628 if not (cont or opts.get('force')):
3564 3629 # check for ancestors of dest branch
3565 3630 crev = repo['.'].rev()
3566 3631 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3567 3632 # Cannot use x.remove(y) on smart set, this has to be a list.
3568 3633 # XXX make this lazy in the future
3569 3634 revs = list(revs)
3570 3635 # don't mutate while iterating, create a copy
3571 3636 for rev in list(revs):
3572 3637 if rev in ancestors:
3573 3638 ui.warn(_('skipping ancestor revision %d:%s\n') %
3574 3639 (rev, repo[rev]))
3575 3640 # XXX remove on list is slow
3576 3641 revs.remove(rev)
3577 3642 if not revs:
3578 3643 return -1
3579 3644
3580 3645 # analyze revs for earlier grafts
3581 3646 ids = {}
3582 3647 for ctx in repo.set("%ld", revs):
3583 3648 ids[ctx.hex()] = ctx.rev()
3584 3649 n = ctx.extra().get('source')
3585 3650 if n:
3586 3651 ids[n] = ctx.rev()
3587 3652
3588 3653 # check ancestors for earlier grafts
3589 3654 ui.debug('scanning for duplicate grafts\n')
3590 3655
3591 3656 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3592 3657 ctx = repo[rev]
3593 3658 n = ctx.extra().get('source')
3594 3659 if n in ids:
3595 3660 try:
3596 3661 r = repo[n].rev()
3597 3662 except error.RepoLookupError:
3598 3663 r = None
3599 3664 if r in revs:
3600 3665 ui.warn(_('skipping revision %d:%s '
3601 3666 '(already grafted to %d:%s)\n')
3602 3667 % (r, repo[r], rev, ctx))
3603 3668 revs.remove(r)
3604 3669 elif ids[n] in revs:
3605 3670 if r is None:
3606 3671 ui.warn(_('skipping already grafted revision %d:%s '
3607 3672 '(%d:%s also has unknown origin %s)\n')
3608 3673 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3609 3674 else:
3610 3675 ui.warn(_('skipping already grafted revision %d:%s '
3611 3676 '(%d:%s also has origin %d:%s)\n')
3612 3677 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3613 3678 revs.remove(ids[n])
3614 3679 elif ctx.hex() in ids:
3615 3680 r = ids[ctx.hex()]
3616 3681 ui.warn(_('skipping already grafted revision %d:%s '
3617 3682 '(was grafted from %d:%s)\n') %
3618 3683 (r, repo[r], rev, ctx))
3619 3684 revs.remove(r)
3620 3685 if not revs:
3621 3686 return -1
3622 3687
3623 3688 wlock = repo.wlock()
3624 3689 try:
3625 3690 for pos, ctx in enumerate(repo.set("%ld", revs)):
3626 3691 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3627 3692 ctx.description().split('\n', 1)[0])
3628 3693 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3629 3694 if names:
3630 3695 desc += ' (%s)' % ' '.join(names)
3631 3696 ui.status(_('grafting %s\n') % desc)
3632 3697 if opts.get('dry_run'):
3633 3698 continue
3634 3699
3635 3700 source = ctx.extra().get('source')
3636 3701 extra = {}
3637 3702 if source:
3638 3703 extra['source'] = source
3639 3704 extra['intermediate-source'] = ctx.hex()
3640 3705 else:
3641 3706 extra['source'] = ctx.hex()
3642 3707 user = ctx.user()
3643 3708 if opts.get('user'):
3644 3709 user = opts['user']
3645 3710 date = ctx.date()
3646 3711 if opts.get('date'):
3647 3712 date = opts['date']
3648 3713 message = ctx.description()
3649 3714 if opts.get('log'):
3650 3715 message += '\n(grafted from %s)' % ctx.hex()
3651 3716
3652 3717 # we don't merge the first commit when continuing
3653 3718 if not cont:
3654 3719 # perform the graft merge with p1(rev) as 'ancestor'
3655 3720 try:
3656 3721 # ui.forcemerge is an internal variable, do not document
3657 3722 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3658 3723 'graft')
3659 3724 stats = mergemod.graft(repo, ctx, ctx.p1(),
3660 3725 ['local', 'graft'])
3661 3726 finally:
3662 3727 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3663 3728 # report any conflicts
3664 3729 if stats and stats[3] > 0:
3665 3730 # write out state for --continue
3666 3731 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3667 3732 repo.vfs.write('graftstate', ''.join(nodelines))
3668 3733 raise util.Abort(
3669 3734 _("unresolved conflicts, can't continue"),
3670 3735 hint=_('use hg resolve and hg graft --continue'))
3671 3736 else:
3672 3737 cont = False
3673 3738
3674 3739 # commit
3675 3740 node = repo.commit(text=message, user=user,
3676 3741 date=date, extra=extra, editor=editor)
3677 3742 if node is None:
3678 3743 ui.warn(
3679 3744 _('note: graft of %d:%s created no changes to commit\n') %
3680 3745 (ctx.rev(), ctx))
3681 3746 finally:
3682 3747 wlock.release()
3683 3748
3684 3749 # remove state when we complete successfully
3685 3750 if not opts.get('dry_run'):
3686 3751 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3687 3752
3688 3753 return 0
3689 3754
3690 3755 @command('grep',
3691 3756 [('0', 'print0', None, _('end fields with NUL')),
3692 3757 ('', 'all', None, _('print all revisions that match')),
3693 3758 ('a', 'text', None, _('treat all files as text')),
3694 3759 ('f', 'follow', None,
3695 3760 _('follow changeset history,'
3696 3761 ' or file history across copies and renames')),
3697 3762 ('i', 'ignore-case', None, _('ignore case when matching')),
3698 3763 ('l', 'files-with-matches', None,
3699 3764 _('print only filenames and revisions that match')),
3700 3765 ('n', 'line-number', None, _('print matching line numbers')),
3701 3766 ('r', 'rev', [],
3702 3767 _('only search files changed within revision range'), _('REV')),
3703 3768 ('u', 'user', None, _('list the author (long with -v)')),
3704 3769 ('d', 'date', None, _('list the date (short with -q)')),
3705 3770 ] + walkopts,
3706 3771 _('[OPTION]... PATTERN [FILE]...'),
3707 3772 inferrepo=True)
3708 3773 def grep(ui, repo, pattern, *pats, **opts):
3709 3774 """search for a pattern in specified files and revisions
3710 3775
3711 3776 Search revisions of files for a regular expression.
3712 3777
3713 3778 This command behaves differently than Unix grep. It only accepts
3714 3779 Python/Perl regexps. It searches repository history, not the
3715 3780 working directory. It always prints the revision number in which a
3716 3781 match appears.
3717 3782
3718 3783 By default, grep only prints output for the first revision of a
3719 3784 file in which it finds a match. To get it to print every revision
3720 3785 that contains a change in match status ("-" for a match that
3721 3786 becomes a non-match, or "+" for a non-match that becomes a match),
3722 3787 use the --all flag.
3723 3788
3724 3789 Returns 0 if a match is found, 1 otherwise.
3725 3790 """
3726 3791 reflags = re.M
3727 3792 if opts.get('ignore_case'):
3728 3793 reflags |= re.I
3729 3794 try:
3730 3795 regexp = util.re.compile(pattern, reflags)
3731 3796 except re.error as inst:
3732 3797 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3733 3798 return 1
3734 3799 sep, eol = ':', '\n'
3735 3800 if opts.get('print0'):
3736 3801 sep = eol = '\0'
3737 3802
3738 3803 getfile = util.lrucachefunc(repo.file)
3739 3804
3740 3805 def matchlines(body):
3741 3806 begin = 0
3742 3807 linenum = 0
3743 3808 while begin < len(body):
3744 3809 match = regexp.search(body, begin)
3745 3810 if not match:
3746 3811 break
3747 3812 mstart, mend = match.span()
3748 3813 linenum += body.count('\n', begin, mstart) + 1
3749 3814 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3750 3815 begin = body.find('\n', mend) + 1 or len(body) + 1
3751 3816 lend = begin - 1
3752 3817 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3753 3818
3754 3819 class linestate(object):
3755 3820 def __init__(self, line, linenum, colstart, colend):
3756 3821 self.line = line
3757 3822 self.linenum = linenum
3758 3823 self.colstart = colstart
3759 3824 self.colend = colend
3760 3825
3761 3826 def __hash__(self):
3762 3827 return hash((self.linenum, self.line))
3763 3828
3764 3829 def __eq__(self, other):
3765 3830 return self.line == other.line
3766 3831
3767 3832 def __iter__(self):
3768 3833 yield (self.line[:self.colstart], '')
3769 3834 yield (self.line[self.colstart:self.colend], 'grep.match')
3770 3835 rest = self.line[self.colend:]
3771 3836 while rest != '':
3772 3837 match = regexp.search(rest)
3773 3838 if not match:
3774 3839 yield (rest, '')
3775 3840 break
3776 3841 mstart, mend = match.span()
3777 3842 yield (rest[:mstart], '')
3778 3843 yield (rest[mstart:mend], 'grep.match')
3779 3844 rest = rest[mend:]
3780 3845
3781 3846 matches = {}
3782 3847 copies = {}
3783 3848 def grepbody(fn, rev, body):
3784 3849 matches[rev].setdefault(fn, [])
3785 3850 m = matches[rev][fn]
3786 3851 for lnum, cstart, cend, line in matchlines(body):
3787 3852 s = linestate(line, lnum, cstart, cend)
3788 3853 m.append(s)
3789 3854
3790 3855 def difflinestates(a, b):
3791 3856 sm = difflib.SequenceMatcher(None, a, b)
3792 3857 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3793 3858 if tag == 'insert':
3794 3859 for i in xrange(blo, bhi):
3795 3860 yield ('+', b[i])
3796 3861 elif tag == 'delete':
3797 3862 for i in xrange(alo, ahi):
3798 3863 yield ('-', a[i])
3799 3864 elif tag == 'replace':
3800 3865 for i in xrange(alo, ahi):
3801 3866 yield ('-', a[i])
3802 3867 for i in xrange(blo, bhi):
3803 3868 yield ('+', b[i])
3804 3869
3805 3870 def display(fn, ctx, pstates, states):
3806 3871 rev = ctx.rev()
3807 3872 if ui.quiet:
3808 3873 datefunc = util.shortdate
3809 3874 else:
3810 3875 datefunc = util.datestr
3811 3876 found = False
3812 3877 @util.cachefunc
3813 3878 def binary():
3814 3879 flog = getfile(fn)
3815 3880 return util.binary(flog.read(ctx.filenode(fn)))
3816 3881
3817 3882 if opts.get('all'):
3818 3883 iter = difflinestates(pstates, states)
3819 3884 else:
3820 3885 iter = [('', l) for l in states]
3821 3886 for change, l in iter:
3822 3887 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3823 3888
3824 3889 if opts.get('line_number'):
3825 3890 cols.append((str(l.linenum), 'grep.linenumber'))
3826 3891 if opts.get('all'):
3827 3892 cols.append((change, 'grep.change'))
3828 3893 if opts.get('user'):
3829 3894 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3830 3895 if opts.get('date'):
3831 3896 cols.append((datefunc(ctx.date()), 'grep.date'))
3832 3897 for col, label in cols[:-1]:
3833 3898 ui.write(col, label=label)
3834 3899 ui.write(sep, label='grep.sep')
3835 3900 ui.write(cols[-1][0], label=cols[-1][1])
3836 3901 if not opts.get('files_with_matches'):
3837 3902 ui.write(sep, label='grep.sep')
3838 3903 if not opts.get('text') and binary():
3839 3904 ui.write(" Binary file matches")
3840 3905 else:
3841 3906 for s, label in l:
3842 3907 ui.write(s, label=label)
3843 3908 ui.write(eol)
3844 3909 found = True
3845 3910 if opts.get('files_with_matches'):
3846 3911 break
3847 3912 return found
3848 3913
3849 3914 skip = {}
3850 3915 revfiles = {}
3851 3916 matchfn = scmutil.match(repo[None], pats, opts)
3852 3917 found = False
3853 3918 follow = opts.get('follow')
3854 3919
3855 3920 def prep(ctx, fns):
3856 3921 rev = ctx.rev()
3857 3922 pctx = ctx.p1()
3858 3923 parent = pctx.rev()
3859 3924 matches.setdefault(rev, {})
3860 3925 matches.setdefault(parent, {})
3861 3926 files = revfiles.setdefault(rev, [])
3862 3927 for fn in fns:
3863 3928 flog = getfile(fn)
3864 3929 try:
3865 3930 fnode = ctx.filenode(fn)
3866 3931 except error.LookupError:
3867 3932 continue
3868 3933
3869 3934 copied = flog.renamed(fnode)
3870 3935 copy = follow and copied and copied[0]
3871 3936 if copy:
3872 3937 copies.setdefault(rev, {})[fn] = copy
3873 3938 if fn in skip:
3874 3939 if copy:
3875 3940 skip[copy] = True
3876 3941 continue
3877 3942 files.append(fn)
3878 3943
3879 3944 if fn not in matches[rev]:
3880 3945 grepbody(fn, rev, flog.read(fnode))
3881 3946
3882 3947 pfn = copy or fn
3883 3948 if pfn not in matches[parent]:
3884 3949 try:
3885 3950 fnode = pctx.filenode(pfn)
3886 3951 grepbody(pfn, parent, flog.read(fnode))
3887 3952 except error.LookupError:
3888 3953 pass
3889 3954
3890 3955 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3891 3956 rev = ctx.rev()
3892 3957 parent = ctx.p1().rev()
3893 3958 for fn in sorted(revfiles.get(rev, [])):
3894 3959 states = matches[rev][fn]
3895 3960 copy = copies.get(rev, {}).get(fn)
3896 3961 if fn in skip:
3897 3962 if copy:
3898 3963 skip[copy] = True
3899 3964 continue
3900 3965 pstates = matches.get(parent, {}).get(copy or fn, [])
3901 3966 if pstates or states:
3902 3967 r = display(fn, ctx, pstates, states)
3903 3968 found = found or r
3904 3969 if r and not opts.get('all'):
3905 3970 skip[fn] = True
3906 3971 if copy:
3907 3972 skip[copy] = True
3908 3973 del matches[rev]
3909 3974 del revfiles[rev]
3910 3975
3911 3976 return not found
3912 3977
3913 3978 @command('heads',
3914 3979 [('r', 'rev', '',
3915 3980 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3916 3981 ('t', 'topo', False, _('show topological heads only')),
3917 3982 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3918 3983 ('c', 'closed', False, _('show normal and closed branch heads')),
3919 3984 ] + templateopts,
3920 3985 _('[-ct] [-r STARTREV] [REV]...'))
3921 3986 def heads(ui, repo, *branchrevs, **opts):
3922 3987 """show branch heads
3923 3988
3924 3989 With no arguments, show all open branch heads in the repository.
3925 3990 Branch heads are changesets that have no descendants on the
3926 3991 same branch. They are where development generally takes place and
3927 3992 are the usual targets for update and merge operations.
3928 3993
3929 3994 If one or more REVs are given, only open branch heads on the
3930 3995 branches associated with the specified changesets are shown. This
3931 3996 means that you can use :hg:`heads .` to see the heads on the
3932 3997 currently checked-out branch.
3933 3998
3934 3999 If -c/--closed is specified, also show branch heads marked closed
3935 4000 (see :hg:`commit --close-branch`).
3936 4001
3937 4002 If STARTREV is specified, only those heads that are descendants of
3938 4003 STARTREV will be displayed.
3939 4004
3940 4005 If -t/--topo is specified, named branch mechanics will be ignored and only
3941 4006 topological heads (changesets with no children) will be shown.
3942 4007
3943 4008 Returns 0 if matching heads are found, 1 if not.
3944 4009 """
3945 4010
3946 4011 start = None
3947 4012 if 'rev' in opts:
3948 4013 start = scmutil.revsingle(repo, opts['rev'], None).node()
3949 4014
3950 4015 if opts.get('topo'):
3951 4016 heads = [repo[h] for h in repo.heads(start)]
3952 4017 else:
3953 4018 heads = []
3954 4019 for branch in repo.branchmap():
3955 4020 heads += repo.branchheads(branch, start, opts.get('closed'))
3956 4021 heads = [repo[h] for h in heads]
3957 4022
3958 4023 if branchrevs:
3959 4024 branches = set(repo[br].branch() for br in branchrevs)
3960 4025 heads = [h for h in heads if h.branch() in branches]
3961 4026
3962 4027 if opts.get('active') and branchrevs:
3963 4028 dagheads = repo.heads(start)
3964 4029 heads = [h for h in heads if h.node() in dagheads]
3965 4030
3966 4031 if branchrevs:
3967 4032 haveheads = set(h.branch() for h in heads)
3968 4033 if branches - haveheads:
3969 4034 headless = ', '.join(b for b in branches - haveheads)
3970 4035 msg = _('no open branch heads found on branches %s')
3971 4036 if opts.get('rev'):
3972 4037 msg += _(' (started at %s)') % opts['rev']
3973 4038 ui.warn((msg + '\n') % headless)
3974 4039
3975 4040 if not heads:
3976 4041 return 1
3977 4042
3978 4043 heads = sorted(heads, key=lambda x: -x.rev())
3979 4044 displayer = cmdutil.show_changeset(ui, repo, opts)
3980 4045 for ctx in heads:
3981 4046 displayer.show(ctx)
3982 4047 displayer.close()
3983 4048
3984 4049 @command('help',
3985 4050 [('e', 'extension', None, _('show only help for extensions')),
3986 4051 ('c', 'command', None, _('show only help for commands')),
3987 4052 ('k', 'keyword', None, _('show topics matching keyword')),
3988 4053 ],
3989 4054 _('[-eck] [TOPIC]'),
3990 4055 norepo=True)
3991 4056 def help_(ui, name=None, **opts):
3992 4057 """show help for a given topic or a help overview
3993 4058
3994 4059 With no arguments, print a list of commands with short help messages.
3995 4060
3996 4061 Given a topic, extension, or command name, print help for that
3997 4062 topic.
3998 4063
3999 4064 Returns 0 if successful.
4000 4065 """
4001 4066
4002 4067 textwidth = min(ui.termwidth(), 80) - 2
4003 4068
4004 4069 keep = []
4005 4070 if ui.verbose:
4006 4071 keep.append('verbose')
4007 4072 if sys.platform.startswith('win'):
4008 4073 keep.append('windows')
4009 4074 elif sys.platform == 'OpenVMS':
4010 4075 keep.append('vms')
4011 4076 elif sys.platform == 'plan9':
4012 4077 keep.append('plan9')
4013 4078 else:
4014 4079 keep.append('unix')
4015 4080 keep.append(sys.platform.lower())
4016 4081
4017 4082 section = None
4018 4083 if name and '.' in name:
4019 4084 name, section = name.split('.', 1)
4020 4085 section = section.lower()
4021 4086
4022 4087 text = help.help_(ui, name, **opts)
4023 4088
4024 4089 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4025 4090 section=section)
4026 4091
4027 4092 # We could have been given a weird ".foo" section without a name
4028 4093 # to look for, or we could have simply failed to found "foo.bar"
4029 4094 # because bar isn't a section of foo
4030 4095 if section and not (formatted and name):
4031 4096 raise util.Abort(_("help section not found"))
4032 4097
4033 4098 if 'verbose' in pruned:
4034 4099 keep.append('omitted')
4035 4100 else:
4036 4101 keep.append('notomitted')
4037 4102 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4038 4103 section=section)
4039 4104 ui.write(formatted)
4040 4105
4041 4106
4042 4107 @command('identify|id',
4043 4108 [('r', 'rev', '',
4044 4109 _('identify the specified revision'), _('REV')),
4045 4110 ('n', 'num', None, _('show local revision number')),
4046 4111 ('i', 'id', None, _('show global revision id')),
4047 4112 ('b', 'branch', None, _('show branch')),
4048 4113 ('t', 'tags', None, _('show tags')),
4049 4114 ('B', 'bookmarks', None, _('show bookmarks')),
4050 4115 ] + remoteopts,
4051 4116 _('[-nibtB] [-r REV] [SOURCE]'),
4052 4117 optionalrepo=True)
4053 4118 def identify(ui, repo, source=None, rev=None,
4054 4119 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
4055 4120 """identify the working directory or specified revision
4056 4121
4057 4122 Print a summary identifying the repository state at REV using one or
4058 4123 two parent hash identifiers, followed by a "+" if the working
4059 4124 directory has uncommitted changes, the branch name (if not default),
4060 4125 a list of tags, and a list of bookmarks.
4061 4126
4062 4127 When REV is not given, print a summary of the current state of the
4063 4128 repository.
4064 4129
4065 4130 Specifying a path to a repository root or Mercurial bundle will
4066 4131 cause lookup to operate on that repository/bundle.
4067 4132
4068 4133 .. container:: verbose
4069 4134
4070 4135 Examples:
4071 4136
4072 4137 - generate a build identifier for the working directory::
4073 4138
4074 4139 hg id --id > build-id.dat
4075 4140
4076 4141 - find the revision corresponding to a tag::
4077 4142
4078 4143 hg id -n -r 1.3
4079 4144
4080 4145 - check the most recent revision of a remote repository::
4081 4146
4082 4147 hg id -r tip http://selenic.com/hg/
4083 4148
4084 4149 Returns 0 if successful.
4085 4150 """
4086 4151
4087 4152 if not repo and not source:
4088 4153 raise util.Abort(_("there is no Mercurial repository here "
4089 4154 "(.hg not found)"))
4090 4155
4091 4156 if ui.debugflag:
4092 4157 hexfunc = hex
4093 4158 else:
4094 4159 hexfunc = short
4095 4160 default = not (num or id or branch or tags or bookmarks)
4096 4161 output = []
4097 4162 revs = []
4098 4163
4099 4164 if source:
4100 4165 source, branches = hg.parseurl(ui.expandpath(source))
4101 4166 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4102 4167 repo = peer.local()
4103 4168 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4104 4169
4105 4170 if not repo:
4106 4171 if num or branch or tags:
4107 4172 raise util.Abort(
4108 4173 _("can't query remote revision number, branch, or tags"))
4109 4174 if not rev and revs:
4110 4175 rev = revs[0]
4111 4176 if not rev:
4112 4177 rev = "tip"
4113 4178
4114 4179 remoterev = peer.lookup(rev)
4115 4180 if default or id:
4116 4181 output = [hexfunc(remoterev)]
4117 4182
4118 4183 def getbms():
4119 4184 bms = []
4120 4185
4121 4186 if 'bookmarks' in peer.listkeys('namespaces'):
4122 4187 hexremoterev = hex(remoterev)
4123 4188 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4124 4189 if bmr == hexremoterev]
4125 4190
4126 4191 return sorted(bms)
4127 4192
4128 4193 if bookmarks:
4129 4194 output.extend(getbms())
4130 4195 elif default and not ui.quiet:
4131 4196 # multiple bookmarks for a single parent separated by '/'
4132 4197 bm = '/'.join(getbms())
4133 4198 if bm:
4134 4199 output.append(bm)
4135 4200 else:
4136 4201 ctx = scmutil.revsingle(repo, rev, None)
4137 4202
4138 4203 if ctx.rev() is None:
4139 4204 ctx = repo[None]
4140 4205 parents = ctx.parents()
4141 4206 taglist = []
4142 4207 for p in parents:
4143 4208 taglist.extend(p.tags())
4144 4209
4145 4210 changed = ""
4146 4211 if default or id or num:
4147 4212 if (any(repo.status())
4148 4213 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4149 4214 changed = '+'
4150 4215 if default or id:
4151 4216 output = ["%s%s" %
4152 4217 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4153 4218 if num:
4154 4219 output.append("%s%s" %
4155 4220 ('+'.join([str(p.rev()) for p in parents]), changed))
4156 4221 else:
4157 4222 if default or id:
4158 4223 output = [hexfunc(ctx.node())]
4159 4224 if num:
4160 4225 output.append(str(ctx.rev()))
4161 4226 taglist = ctx.tags()
4162 4227
4163 4228 if default and not ui.quiet:
4164 4229 b = ctx.branch()
4165 4230 if b != 'default':
4166 4231 output.append("(%s)" % b)
4167 4232
4168 4233 # multiple tags for a single parent separated by '/'
4169 4234 t = '/'.join(taglist)
4170 4235 if t:
4171 4236 output.append(t)
4172 4237
4173 4238 # multiple bookmarks for a single parent separated by '/'
4174 4239 bm = '/'.join(ctx.bookmarks())
4175 4240 if bm:
4176 4241 output.append(bm)
4177 4242 else:
4178 4243 if branch:
4179 4244 output.append(ctx.branch())
4180 4245
4181 4246 if tags:
4182 4247 output.extend(taglist)
4183 4248
4184 4249 if bookmarks:
4185 4250 output.extend(ctx.bookmarks())
4186 4251
4187 4252 ui.write("%s\n" % ' '.join(output))
4188 4253
4189 4254 @command('import|patch',
4190 4255 [('p', 'strip', 1,
4191 4256 _('directory strip option for patch. This has the same '
4192 4257 'meaning as the corresponding patch option'), _('NUM')),
4193 4258 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4194 4259 ('e', 'edit', False, _('invoke editor on commit messages')),
4195 4260 ('f', 'force', None,
4196 4261 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4197 4262 ('', 'no-commit', None,
4198 4263 _("don't commit, just update the working directory")),
4199 4264 ('', 'bypass', None,
4200 4265 _("apply patch without touching the working directory")),
4201 4266 ('', 'partial', None,
4202 4267 _('commit even if some hunks fail')),
4203 4268 ('', 'exact', None,
4204 4269 _('apply patch to the nodes from which it was generated')),
4205 4270 ('', 'prefix', '',
4206 4271 _('apply patch to subdirectory'), _('DIR')),
4207 4272 ('', 'import-branch', None,
4208 4273 _('use any branch information in patch (implied by --exact)'))] +
4209 4274 commitopts + commitopts2 + similarityopts,
4210 4275 _('[OPTION]... PATCH...'))
4211 4276 def import_(ui, repo, patch1=None, *patches, **opts):
4212 4277 """import an ordered set of patches
4213 4278
4214 4279 Import a list of patches and commit them individually (unless
4215 4280 --no-commit is specified).
4216 4281
4217 4282 Because import first applies changes to the working directory,
4218 4283 import will abort if there are outstanding changes.
4219 4284
4220 4285 You can import a patch straight from a mail message. Even patches
4221 4286 as attachments work (to use the body part, it must have type
4222 4287 text/plain or text/x-patch). From and Subject headers of email
4223 4288 message are used as default committer and commit message. All
4224 4289 text/plain body parts before first diff are added to commit
4225 4290 message.
4226 4291
4227 4292 If the imported patch was generated by :hg:`export`, user and
4228 4293 description from patch override values from message headers and
4229 4294 body. Values given on command line with -m/--message and -u/--user
4230 4295 override these.
4231 4296
4232 4297 If --exact is specified, import will set the working directory to
4233 4298 the parent of each patch before applying it, and will abort if the
4234 4299 resulting changeset has a different ID than the one recorded in
4235 4300 the patch. This may happen due to character set problems or other
4236 4301 deficiencies in the text patch format.
4237 4302
4238 4303 Use --bypass to apply and commit patches directly to the
4239 4304 repository, not touching the working directory. Without --exact,
4240 4305 patches will be applied on top of the working directory parent
4241 4306 revision.
4242 4307
4243 4308 With -s/--similarity, hg will attempt to discover renames and
4244 4309 copies in the patch in the same way as :hg:`addremove`.
4245 4310
4246 4311 Use --partial to ensure a changeset will be created from the patch
4247 4312 even if some hunks fail to apply. Hunks that fail to apply will be
4248 4313 written to a <target-file>.rej file. Conflicts can then be resolved
4249 4314 by hand before :hg:`commit --amend` is run to update the created
4250 4315 changeset. This flag exists to let people import patches that
4251 4316 partially apply without losing the associated metadata (author,
4252 4317 date, description, ...). Note that when none of the hunk applies
4253 4318 cleanly, :hg:`import --partial` will create an empty changeset,
4254 4319 importing only the patch metadata.
4255 4320
4256 4321 It is possible to use external patch programs to perform the patch
4257 4322 by setting the ``ui.patch`` configuration option. For the default
4258 4323 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4259 4324 See :hg:`help config` for more information about configuration
4260 4325 files and how to use these options.
4261 4326
4262 4327 To read a patch from standard input, use "-" as the patch name. If
4263 4328 a URL is specified, the patch will be downloaded from it.
4264 4329 See :hg:`help dates` for a list of formats valid for -d/--date.
4265 4330
4266 4331 .. container:: verbose
4267 4332
4268 4333 Examples:
4269 4334
4270 4335 - import a traditional patch from a website and detect renames::
4271 4336
4272 4337 hg import -s 80 http://example.com/bugfix.patch
4273 4338
4274 4339 - import a changeset from an hgweb server::
4275 4340
4276 4341 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4277 4342
4278 4343 - import all the patches in an Unix-style mbox::
4279 4344
4280 4345 hg import incoming-patches.mbox
4281 4346
4282 4347 - attempt to exactly restore an exported changeset (not always
4283 4348 possible)::
4284 4349
4285 4350 hg import --exact proposed-fix.patch
4286 4351
4287 4352 - use an external tool to apply a patch which is too fuzzy for
4288 4353 the default internal tool.
4289 4354
4290 4355 hg import --config ui.patch="patch --merge" fuzzy.patch
4291 4356
4292 4357 - change the default fuzzing from 2 to a less strict 7
4293 4358
4294 4359 hg import --config ui.fuzz=7 fuzz.patch
4295 4360
4296 4361 Returns 0 on success, 1 on partial success (see --partial).
4297 4362 """
4298 4363
4299 4364 if not patch1:
4300 4365 raise util.Abort(_('need at least one patch to import'))
4301 4366
4302 4367 patches = (patch1,) + patches
4303 4368
4304 4369 date = opts.get('date')
4305 4370 if date:
4306 4371 opts['date'] = util.parsedate(date)
4307 4372
4308 4373 update = not opts.get('bypass')
4309 4374 if not update and opts.get('no_commit'):
4310 4375 raise util.Abort(_('cannot use --no-commit with --bypass'))
4311 4376 try:
4312 4377 sim = float(opts.get('similarity') or 0)
4313 4378 except ValueError:
4314 4379 raise util.Abort(_('similarity must be a number'))
4315 4380 if sim < 0 or sim > 100:
4316 4381 raise util.Abort(_('similarity must be between 0 and 100'))
4317 4382 if sim and not update:
4318 4383 raise util.Abort(_('cannot use --similarity with --bypass'))
4319 4384 if opts.get('exact') and opts.get('edit'):
4320 4385 raise util.Abort(_('cannot use --exact with --edit'))
4321 4386 if opts.get('exact') and opts.get('prefix'):
4322 4387 raise util.Abort(_('cannot use --exact with --prefix'))
4323 4388
4324 4389 if update:
4325 4390 cmdutil.checkunfinished(repo)
4326 4391 if (opts.get('exact') or not opts.get('force')) and update:
4327 4392 cmdutil.bailifchanged(repo)
4328 4393
4329 4394 base = opts["base"]
4330 4395 wlock = dsguard = lock = tr = None
4331 4396 msgs = []
4332 4397 ret = 0
4333 4398
4334 4399
4335 4400 try:
4336 4401 try:
4337 4402 wlock = repo.wlock()
4338 4403 dsguard = cmdutil.dirstateguard(repo, 'import')
4339 4404 if not opts.get('no_commit'):
4340 4405 lock = repo.lock()
4341 4406 tr = repo.transaction('import')
4342 4407 parents = repo.parents()
4343 4408 for patchurl in patches:
4344 4409 if patchurl == '-':
4345 4410 ui.status(_('applying patch from stdin\n'))
4346 4411 patchfile = ui.fin
4347 4412 patchurl = 'stdin' # for error message
4348 4413 else:
4349 4414 patchurl = os.path.join(base, patchurl)
4350 4415 ui.status(_('applying %s\n') % patchurl)
4351 4416 patchfile = hg.openpath(ui, patchurl)
4352 4417
4353 4418 haspatch = False
4354 4419 for hunk in patch.split(patchfile):
4355 4420 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4356 4421 parents, opts,
4357 4422 msgs, hg.clean)
4358 4423 if msg:
4359 4424 haspatch = True
4360 4425 ui.note(msg + '\n')
4361 4426 if update or opts.get('exact'):
4362 4427 parents = repo.parents()
4363 4428 else:
4364 4429 parents = [repo[node]]
4365 4430 if rej:
4366 4431 ui.write_err(_("patch applied partially\n"))
4367 4432 ui.write_err(_("(fix the .rej files and run "
4368 4433 "`hg commit --amend`)\n"))
4369 4434 ret = 1
4370 4435 break
4371 4436
4372 4437 if not haspatch:
4373 4438 raise util.Abort(_('%s: no diffs found') % patchurl)
4374 4439
4375 4440 if tr:
4376 4441 tr.close()
4377 4442 if msgs:
4378 4443 repo.savecommitmessage('\n* * *\n'.join(msgs))
4379 4444 dsguard.close()
4380 4445 return ret
4381 4446 finally:
4382 4447 # TODO: get rid of this meaningless try/finally enclosing.
4383 4448 # this is kept only to reduce changes in a patch.
4384 4449 pass
4385 4450 finally:
4386 4451 if tr:
4387 4452 tr.release()
4388 4453 release(lock, dsguard, wlock)
4389 4454
4390 4455 @command('incoming|in',
4391 4456 [('f', 'force', None,
4392 4457 _('run even if remote repository is unrelated')),
4393 4458 ('n', 'newest-first', None, _('show newest record first')),
4394 4459 ('', 'bundle', '',
4395 4460 _('file to store the bundles into'), _('FILE')),
4396 4461 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4397 4462 ('B', 'bookmarks', False, _("compare bookmarks")),
4398 4463 ('b', 'branch', [],
4399 4464 _('a specific branch you would like to pull'), _('BRANCH')),
4400 4465 ] + logopts + remoteopts + subrepoopts,
4401 4466 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4402 4467 def incoming(ui, repo, source="default", **opts):
4403 4468 """show new changesets found in source
4404 4469
4405 4470 Show new changesets found in the specified path/URL or the default
4406 4471 pull location. These are the changesets that would have been pulled
4407 4472 if a pull at the time you issued this command.
4408 4473
4409 4474 See pull for valid source format details.
4410 4475
4411 4476 .. container:: verbose
4412 4477
4413 4478 With -B/--bookmarks, the result of bookmark comparison between
4414 4479 local and remote repositories is displayed. With -v/--verbose,
4415 4480 status is also displayed for each bookmark like below::
4416 4481
4417 4482 BM1 01234567890a added
4418 4483 BM2 1234567890ab advanced
4419 4484 BM3 234567890abc diverged
4420 4485 BM4 34567890abcd changed
4421 4486
4422 4487 The action taken locally when pulling depends on the
4423 4488 status of each bookmark:
4424 4489
4425 4490 :``added``: pull will create it
4426 4491 :``advanced``: pull will update it
4427 4492 :``diverged``: pull will create a divergent bookmark
4428 4493 :``changed``: result depends on remote changesets
4429 4494
4430 4495 From the point of view of pulling behavior, bookmark
4431 4496 existing only in the remote repository are treated as ``added``,
4432 4497 even if it is in fact locally deleted.
4433 4498
4434 4499 .. container:: verbose
4435 4500
4436 4501 For remote repository, using --bundle avoids downloading the
4437 4502 changesets twice if the incoming is followed by a pull.
4438 4503
4439 4504 Examples:
4440 4505
4441 4506 - show incoming changes with patches and full description::
4442 4507
4443 4508 hg incoming -vp
4444 4509
4445 4510 - show incoming changes excluding merges, store a bundle::
4446 4511
4447 4512 hg in -vpM --bundle incoming.hg
4448 4513 hg pull incoming.hg
4449 4514
4450 4515 - briefly list changes inside a bundle::
4451 4516
4452 4517 hg in changes.hg -T "{desc|firstline}\\n"
4453 4518
4454 4519 Returns 0 if there are incoming changes, 1 otherwise.
4455 4520 """
4456 4521 if opts.get('graph'):
4457 4522 cmdutil.checkunsupportedgraphflags([], opts)
4458 4523 def display(other, chlist, displayer):
4459 4524 revdag = cmdutil.graphrevs(other, chlist, opts)
4460 4525 showparents = [ctx.node() for ctx in repo[None].parents()]
4461 4526 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4462 4527 graphmod.asciiedges)
4463 4528
4464 4529 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4465 4530 return 0
4466 4531
4467 4532 if opts.get('bundle') and opts.get('subrepos'):
4468 4533 raise util.Abort(_('cannot combine --bundle and --subrepos'))
4469 4534
4470 4535 if opts.get('bookmarks'):
4471 4536 source, branches = hg.parseurl(ui.expandpath(source),
4472 4537 opts.get('branch'))
4473 4538 other = hg.peer(repo, opts, source)
4474 4539 if 'bookmarks' not in other.listkeys('namespaces'):
4475 4540 ui.warn(_("remote doesn't support bookmarks\n"))
4476 4541 return 0
4477 4542 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4478 4543 return bookmarks.incoming(ui, repo, other)
4479 4544
4480 4545 repo._subtoppath = ui.expandpath(source)
4481 4546 try:
4482 4547 return hg.incoming(ui, repo, source, opts)
4483 4548 finally:
4484 4549 del repo._subtoppath
4485 4550
4486 4551
4487 4552 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4488 4553 norepo=True)
4489 4554 def init(ui, dest=".", **opts):
4490 4555 """create a new repository in the given directory
4491 4556
4492 4557 Initialize a new repository in the given directory. If the given
4493 4558 directory does not exist, it will be created.
4494 4559
4495 4560 If no directory is given, the current directory is used.
4496 4561
4497 4562 It is possible to specify an ``ssh://`` URL as the destination.
4498 4563 See :hg:`help urls` for more information.
4499 4564
4500 4565 Returns 0 on success.
4501 4566 """
4502 4567 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4503 4568
4504 4569 @command('locate',
4505 4570 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4506 4571 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4507 4572 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4508 4573 ] + walkopts,
4509 4574 _('[OPTION]... [PATTERN]...'))
4510 4575 def locate(ui, repo, *pats, **opts):
4511 4576 """locate files matching specific patterns (DEPRECATED)
4512 4577
4513 4578 Print files under Mercurial control in the working directory whose
4514 4579 names match the given patterns.
4515 4580
4516 4581 By default, this command searches all directories in the working
4517 4582 directory. To search just the current directory and its
4518 4583 subdirectories, use "--include .".
4519 4584
4520 4585 If no patterns are given to match, this command prints the names
4521 4586 of all files under Mercurial control in the working directory.
4522 4587
4523 4588 If you want to feed the output of this command into the "xargs"
4524 4589 command, use the -0 option to both this command and "xargs". This
4525 4590 will avoid the problem of "xargs" treating single filenames that
4526 4591 contain whitespace as multiple filenames.
4527 4592
4528 4593 See :hg:`help files` for a more versatile command.
4529 4594
4530 4595 Returns 0 if a match is found, 1 otherwise.
4531 4596 """
4532 4597 if opts.get('print0'):
4533 4598 end = '\0'
4534 4599 else:
4535 4600 end = '\n'
4536 4601 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4537 4602
4538 4603 ret = 1
4539 4604 ctx = repo[rev]
4540 4605 m = scmutil.match(ctx, pats, opts, default='relglob',
4541 4606 badfn=lambda x, y: False)
4542 4607
4543 4608 for abs in ctx.matches(m):
4544 4609 if opts.get('fullpath'):
4545 4610 ui.write(repo.wjoin(abs), end)
4546 4611 else:
4547 4612 ui.write(((pats and m.rel(abs)) or abs), end)
4548 4613 ret = 0
4549 4614
4550 4615 return ret
4551 4616
4552 4617 @command('^log|history',
4553 4618 [('f', 'follow', None,
4554 4619 _('follow changeset history, or file history across copies and renames')),
4555 4620 ('', 'follow-first', None,
4556 4621 _('only follow the first parent of merge changesets (DEPRECATED)')),
4557 4622 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4558 4623 ('C', 'copies', None, _('show copied files')),
4559 4624 ('k', 'keyword', [],
4560 4625 _('do case-insensitive search for a given text'), _('TEXT')),
4561 4626 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4562 4627 ('', 'removed', None, _('include revisions where files were removed')),
4563 4628 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4564 4629 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4565 4630 ('', 'only-branch', [],
4566 4631 _('show only changesets within the given named branch (DEPRECATED)'),
4567 4632 _('BRANCH')),
4568 4633 ('b', 'branch', [],
4569 4634 _('show changesets within the given named branch'), _('BRANCH')),
4570 4635 ('P', 'prune', [],
4571 4636 _('do not display revision or any of its ancestors'), _('REV')),
4572 4637 ] + logopts + walkopts,
4573 4638 _('[OPTION]... [FILE]'),
4574 4639 inferrepo=True)
4575 4640 def log(ui, repo, *pats, **opts):
4576 4641 """show revision history of entire repository or files
4577 4642
4578 4643 Print the revision history of the specified files or the entire
4579 4644 project.
4580 4645
4581 4646 If no revision range is specified, the default is ``tip:0`` unless
4582 4647 --follow is set, in which case the working directory parent is
4583 4648 used as the starting revision.
4584 4649
4585 4650 File history is shown without following rename or copy history of
4586 4651 files. Use -f/--follow with a filename to follow history across
4587 4652 renames and copies. --follow without a filename will only show
4588 4653 ancestors or descendants of the starting revision.
4589 4654
4590 4655 By default this command prints revision number and changeset id,
4591 4656 tags, non-trivial parents, user, date and time, and a summary for
4592 4657 each commit. When the -v/--verbose switch is used, the list of
4593 4658 changed files and full commit message are shown.
4594 4659
4595 4660 With --graph the revisions are shown as an ASCII art DAG with the most
4596 4661 recent changeset at the top.
4597 4662 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4598 4663 and '+' represents a fork where the changeset from the lines below is a
4599 4664 parent of the 'o' merge on the same line.
4600 4665
4601 4666 .. note::
4602 4667
4603 4668 log -p/--patch may generate unexpected diff output for merge
4604 4669 changesets, as it will only compare the merge changeset against
4605 4670 its first parent. Also, only files different from BOTH parents
4606 4671 will appear in files:.
4607 4672
4608 4673 .. note::
4609 4674
4610 4675 for performance reasons, log FILE may omit duplicate changes
4611 4676 made on branches and will not show removals or mode changes. To
4612 4677 see all such changes, use the --removed switch.
4613 4678
4614 4679 .. container:: verbose
4615 4680
4616 4681 Some examples:
4617 4682
4618 4683 - changesets with full descriptions and file lists::
4619 4684
4620 4685 hg log -v
4621 4686
4622 4687 - changesets ancestral to the working directory::
4623 4688
4624 4689 hg log -f
4625 4690
4626 4691 - last 10 commits on the current branch::
4627 4692
4628 4693 hg log -l 10 -b .
4629 4694
4630 4695 - changesets showing all modifications of a file, including removals::
4631 4696
4632 4697 hg log --removed file.c
4633 4698
4634 4699 - all changesets that touch a directory, with diffs, excluding merges::
4635 4700
4636 4701 hg log -Mp lib/
4637 4702
4638 4703 - all revision numbers that match a keyword::
4639 4704
4640 4705 hg log -k bug --template "{rev}\\n"
4641 4706
4642 4707 - list available log templates::
4643 4708
4644 4709 hg log -T list
4645 4710
4646 4711 - check if a given changeset is included in a tagged release::
4647 4712
4648 4713 hg log -r "a21ccf and ancestor(1.9)"
4649 4714
4650 4715 - find all changesets by some user in a date range::
4651 4716
4652 4717 hg log -k alice -d "may 2008 to jul 2008"
4653 4718
4654 4719 - summary of all changesets after the last tag::
4655 4720
4656 4721 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4657 4722
4658 4723 See :hg:`help dates` for a list of formats valid for -d/--date.
4659 4724
4660 4725 See :hg:`help revisions` and :hg:`help revsets` for more about
4661 4726 specifying revisions.
4662 4727
4663 4728 See :hg:`help templates` for more about pre-packaged styles and
4664 4729 specifying custom templates.
4665 4730
4666 4731 Returns 0 on success.
4667 4732
4668 4733 """
4669 4734 if opts.get('follow') and opts.get('rev'):
4670 4735 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4671 4736 del opts['follow']
4672 4737
4673 4738 if opts.get('graph'):
4674 4739 return cmdutil.graphlog(ui, repo, *pats, **opts)
4675 4740
4676 4741 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4677 4742 limit = cmdutil.loglimit(opts)
4678 4743 count = 0
4679 4744
4680 4745 getrenamed = None
4681 4746 if opts.get('copies'):
4682 4747 endrev = None
4683 4748 if opts.get('rev'):
4684 4749 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4685 4750 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4686 4751
4687 4752 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4688 4753 for rev in revs:
4689 4754 if count == limit:
4690 4755 break
4691 4756 ctx = repo[rev]
4692 4757 copies = None
4693 4758 if getrenamed is not None and rev:
4694 4759 copies = []
4695 4760 for fn in ctx.files():
4696 4761 rename = getrenamed(fn, rev)
4697 4762 if rename:
4698 4763 copies.append((fn, rename[0]))
4699 4764 if filematcher:
4700 4765 revmatchfn = filematcher(ctx.rev())
4701 4766 else:
4702 4767 revmatchfn = None
4703 4768 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4704 4769 if displayer.flush(ctx):
4705 4770 count += 1
4706 4771
4707 4772 displayer.close()
4708 4773
4709 4774 @command('manifest',
4710 4775 [('r', 'rev', '', _('revision to display'), _('REV')),
4711 4776 ('', 'all', False, _("list files from all revisions"))]
4712 4777 + formatteropts,
4713 4778 _('[-r REV]'))
4714 4779 def manifest(ui, repo, node=None, rev=None, **opts):
4715 4780 """output the current or given revision of the project manifest
4716 4781
4717 4782 Print a list of version controlled files for the given revision.
4718 4783 If no revision is given, the first parent of the working directory
4719 4784 is used, or the null revision if no revision is checked out.
4720 4785
4721 4786 With -v, print file permissions, symlink and executable bits.
4722 4787 With --debug, print file revision hashes.
4723 4788
4724 4789 If option --all is specified, the list of all files from all revisions
4725 4790 is printed. This includes deleted and renamed files.
4726 4791
4727 4792 Returns 0 on success.
4728 4793 """
4729 4794
4730 4795 fm = ui.formatter('manifest', opts)
4731 4796
4732 4797 if opts.get('all'):
4733 4798 if rev or node:
4734 4799 raise util.Abort(_("can't specify a revision with --all"))
4735 4800
4736 4801 res = []
4737 4802 prefix = "data/"
4738 4803 suffix = ".i"
4739 4804 plen = len(prefix)
4740 4805 slen = len(suffix)
4741 4806 lock = repo.lock()
4742 4807 try:
4743 4808 for fn, b, size in repo.store.datafiles():
4744 4809 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4745 4810 res.append(fn[plen:-slen])
4746 4811 finally:
4747 4812 lock.release()
4748 4813 for f in res:
4749 4814 fm.startitem()
4750 4815 fm.write("path", '%s\n', f)
4751 4816 fm.end()
4752 4817 return
4753 4818
4754 4819 if rev and node:
4755 4820 raise util.Abort(_("please specify just one revision"))
4756 4821
4757 4822 if not node:
4758 4823 node = rev
4759 4824
4760 4825 char = {'l': '@', 'x': '*', '': ''}
4761 4826 mode = {'l': '644', 'x': '755', '': '644'}
4762 4827 ctx = scmutil.revsingle(repo, node)
4763 4828 mf = ctx.manifest()
4764 4829 for f in ctx:
4765 4830 fm.startitem()
4766 4831 fl = ctx[f].flags()
4767 4832 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4768 4833 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4769 4834 fm.write('path', '%s\n', f)
4770 4835 fm.end()
4771 4836
4772 4837 @command('^merge',
4773 4838 [('f', 'force', None,
4774 4839 _('force a merge including outstanding changes (DEPRECATED)')),
4775 4840 ('r', 'rev', '', _('revision to merge'), _('REV')),
4776 4841 ('P', 'preview', None,
4777 4842 _('review revisions to merge (no merge is performed)'))
4778 4843 ] + mergetoolopts,
4779 4844 _('[-P] [-f] [[-r] REV]'))
4780 4845 def merge(ui, repo, node=None, **opts):
4781 4846 """merge another revision into working directory
4782 4847
4783 4848 The current working directory is updated with all changes made in
4784 4849 the requested revision since the last common predecessor revision.
4785 4850
4786 4851 Files that changed between either parent are marked as changed for
4787 4852 the next commit and a commit must be performed before any further
4788 4853 updates to the repository are allowed. The next commit will have
4789 4854 two parents.
4790 4855
4791 4856 ``--tool`` can be used to specify the merge tool used for file
4792 4857 merges. It overrides the HGMERGE environment variable and your
4793 4858 configuration files. See :hg:`help merge-tools` for options.
4794 4859
4795 4860 If no revision is specified, the working directory's parent is a
4796 4861 head revision, and the current branch contains exactly one other
4797 4862 head, the other head is merged with by default. Otherwise, an
4798 4863 explicit revision with which to merge with must be provided.
4799 4864
4800 4865 :hg:`resolve` must be used to resolve unresolved files.
4801 4866
4802 4867 To undo an uncommitted merge, use :hg:`update --clean .` which
4803 4868 will check out a clean copy of the original merge parent, losing
4804 4869 all changes.
4805 4870
4806 4871 Returns 0 on success, 1 if there are unresolved files.
4807 4872 """
4808 4873
4809 4874 if opts.get('rev') and node:
4810 4875 raise util.Abort(_("please specify just one revision"))
4811 4876 if not node:
4812 4877 node = opts.get('rev')
4813 4878
4814 4879 if node:
4815 4880 node = scmutil.revsingle(repo, node).node()
4816 4881
4817 4882 if not node:
4818 4883 node = scmutil.revsingle(repo, '_mergedefaultdest()').node()
4819 4884
4820 4885 if opts.get('preview'):
4821 4886 # find nodes that are ancestors of p2 but not of p1
4822 4887 p1 = repo.lookup('.')
4823 4888 p2 = repo.lookup(node)
4824 4889 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4825 4890
4826 4891 displayer = cmdutil.show_changeset(ui, repo, opts)
4827 4892 for node in nodes:
4828 4893 displayer.show(repo[node])
4829 4894 displayer.close()
4830 4895 return 0
4831 4896
4832 4897 try:
4833 4898 # ui.forcemerge is an internal variable, do not document
4834 4899 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4835 4900 return hg.merge(repo, node, force=opts.get('force'))
4836 4901 finally:
4837 4902 ui.setconfig('ui', 'forcemerge', '', 'merge')
4838 4903
4839 4904 @command('outgoing|out',
4840 4905 [('f', 'force', None, _('run even when the destination is unrelated')),
4841 4906 ('r', 'rev', [],
4842 4907 _('a changeset intended to be included in the destination'), _('REV')),
4843 4908 ('n', 'newest-first', None, _('show newest record first')),
4844 4909 ('B', 'bookmarks', False, _('compare bookmarks')),
4845 4910 ('b', 'branch', [], _('a specific branch you would like to push'),
4846 4911 _('BRANCH')),
4847 4912 ] + logopts + remoteopts + subrepoopts,
4848 4913 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4849 4914 def outgoing(ui, repo, dest=None, **opts):
4850 4915 """show changesets not found in the destination
4851 4916
4852 4917 Show changesets not found in the specified destination repository
4853 4918 or the default push location. These are the changesets that would
4854 4919 be pushed if a push was requested.
4855 4920
4856 4921 See pull for details of valid destination formats.
4857 4922
4858 4923 .. container:: verbose
4859 4924
4860 4925 With -B/--bookmarks, the result of bookmark comparison between
4861 4926 local and remote repositories is displayed. With -v/--verbose,
4862 4927 status is also displayed for each bookmark like below::
4863 4928
4864 4929 BM1 01234567890a added
4865 4930 BM2 deleted
4866 4931 BM3 234567890abc advanced
4867 4932 BM4 34567890abcd diverged
4868 4933 BM5 4567890abcde changed
4869 4934
4870 4935 The action taken when pushing depends on the
4871 4936 status of each bookmark:
4872 4937
4873 4938 :``added``: push with ``-B`` will create it
4874 4939 :``deleted``: push with ``-B`` will delete it
4875 4940 :``advanced``: push will update it
4876 4941 :``diverged``: push with ``-B`` will update it
4877 4942 :``changed``: push with ``-B`` will update it
4878 4943
4879 4944 From the point of view of pushing behavior, bookmarks
4880 4945 existing only in the remote repository are treated as
4881 4946 ``deleted``, even if it is in fact added remotely.
4882 4947
4883 4948 Returns 0 if there are outgoing changes, 1 otherwise.
4884 4949 """
4885 4950 if opts.get('graph'):
4886 4951 cmdutil.checkunsupportedgraphflags([], opts)
4887 4952 o, other = hg._outgoing(ui, repo, dest, opts)
4888 4953 if not o:
4889 4954 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4890 4955 return
4891 4956
4892 4957 revdag = cmdutil.graphrevs(repo, o, opts)
4893 4958 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4894 4959 showparents = [ctx.node() for ctx in repo[None].parents()]
4895 4960 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4896 4961 graphmod.asciiedges)
4897 4962 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4898 4963 return 0
4899 4964
4900 4965 if opts.get('bookmarks'):
4901 4966 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4902 4967 dest, branches = hg.parseurl(dest, opts.get('branch'))
4903 4968 other = hg.peer(repo, opts, dest)
4904 4969 if 'bookmarks' not in other.listkeys('namespaces'):
4905 4970 ui.warn(_("remote doesn't support bookmarks\n"))
4906 4971 return 0
4907 4972 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4908 4973 return bookmarks.outgoing(ui, repo, other)
4909 4974
4910 4975 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4911 4976 try:
4912 4977 return hg.outgoing(ui, repo, dest, opts)
4913 4978 finally:
4914 4979 del repo._subtoppath
4915 4980
4916 4981 @command('parents',
4917 4982 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4918 4983 ] + templateopts,
4919 4984 _('[-r REV] [FILE]'),
4920 4985 inferrepo=True)
4921 4986 def parents(ui, repo, file_=None, **opts):
4922 4987 """show the parents of the working directory or revision (DEPRECATED)
4923 4988
4924 4989 Print the working directory's parent revisions. If a revision is
4925 4990 given via -r/--rev, the parent of that revision will be printed.
4926 4991 If a file argument is given, the revision in which the file was
4927 4992 last changed (before the working directory revision or the
4928 4993 argument to --rev if given) is printed.
4929 4994
4930 4995 See :hg:`summary` and :hg:`help revsets` for related information.
4931 4996
4932 4997 Returns 0 on success.
4933 4998 """
4934 4999
4935 5000 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4936 5001
4937 5002 if file_:
4938 5003 m = scmutil.match(ctx, (file_,), opts)
4939 5004 if m.anypats() or len(m.files()) != 1:
4940 5005 raise util.Abort(_('can only specify an explicit filename'))
4941 5006 file_ = m.files()[0]
4942 5007 filenodes = []
4943 5008 for cp in ctx.parents():
4944 5009 if not cp:
4945 5010 continue
4946 5011 try:
4947 5012 filenodes.append(cp.filenode(file_))
4948 5013 except error.LookupError:
4949 5014 pass
4950 5015 if not filenodes:
4951 5016 raise util.Abort(_("'%s' not found in manifest!") % file_)
4952 5017 p = []
4953 5018 for fn in filenodes:
4954 5019 fctx = repo.filectx(file_, fileid=fn)
4955 5020 p.append(fctx.node())
4956 5021 else:
4957 5022 p = [cp.node() for cp in ctx.parents()]
4958 5023
4959 5024 displayer = cmdutil.show_changeset(ui, repo, opts)
4960 5025 for n in p:
4961 5026 if n != nullid:
4962 5027 displayer.show(repo[n])
4963 5028 displayer.close()
4964 5029
4965 5030 @command('paths', [], _('[NAME]'), optionalrepo=True)
4966 5031 def paths(ui, repo, search=None):
4967 5032 """show aliases for remote repositories
4968 5033
4969 5034 Show definition of symbolic path name NAME. If no name is given,
4970 5035 show definition of all available names.
4971 5036
4972 5037 Option -q/--quiet suppresses all output when searching for NAME
4973 5038 and shows only the path names when listing all definitions.
4974 5039
4975 5040 Path names are defined in the [paths] section of your
4976 5041 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4977 5042 repository, ``.hg/hgrc`` is used, too.
4978 5043
4979 5044 The path names ``default`` and ``default-push`` have a special
4980 5045 meaning. When performing a push or pull operation, they are used
4981 5046 as fallbacks if no location is specified on the command-line.
4982 5047 When ``default-push`` is set, it will be used for push and
4983 5048 ``default`` will be used for pull; otherwise ``default`` is used
4984 5049 as the fallback for both. When cloning a repository, the clone
4985 5050 source is written as ``default`` in ``.hg/hgrc``. Note that
4986 5051 ``default`` and ``default-push`` apply to all inbound (e.g.
4987 5052 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4988 5053 :hg:`bundle`) operations.
4989 5054
4990 5055 See :hg:`help urls` for more information.
4991 5056
4992 5057 Returns 0 on success.
4993 5058 """
4994 5059 if search:
4995 5060 for name, path in sorted(ui.paths.iteritems()):
4996 5061 if name == search:
4997 5062 ui.status("%s\n" % util.hidepassword(path.loc))
4998 5063 return
4999 5064 if not ui.quiet:
5000 5065 ui.warn(_("not found!\n"))
5001 5066 return 1
5002 5067 else:
5003 5068 for name, path in sorted(ui.paths.iteritems()):
5004 5069 if ui.quiet:
5005 5070 ui.write("%s\n" % name)
5006 5071 else:
5007 5072 ui.write("%s = %s\n" % (name,
5008 5073 util.hidepassword(path.loc)))
5009 5074
5010 5075 @command('phase',
5011 5076 [('p', 'public', False, _('set changeset phase to public')),
5012 5077 ('d', 'draft', False, _('set changeset phase to draft')),
5013 5078 ('s', 'secret', False, _('set changeset phase to secret')),
5014 5079 ('f', 'force', False, _('allow to move boundary backward')),
5015 5080 ('r', 'rev', [], _('target revision'), _('REV')),
5016 5081 ],
5017 5082 _('[-p|-d|-s] [-f] [-r] [REV...]'))
5018 5083 def phase(ui, repo, *revs, **opts):
5019 5084 """set or show the current phase name
5020 5085
5021 5086 With no argument, show the phase name of the current revision(s).
5022 5087
5023 5088 With one of -p/--public, -d/--draft or -s/--secret, change the
5024 5089 phase value of the specified revisions.
5025 5090
5026 5091 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5027 5092 lower phase to an higher phase. Phases are ordered as follows::
5028 5093
5029 5094 public < draft < secret
5030 5095
5031 5096 Returns 0 on success, 1 if some phases could not be changed.
5032 5097
5033 5098 (For more information about the phases concept, see :hg:`help phases`.)
5034 5099 """
5035 5100 # search for a unique phase argument
5036 5101 targetphase = None
5037 5102 for idx, name in enumerate(phases.phasenames):
5038 5103 if opts[name]:
5039 5104 if targetphase is not None:
5040 5105 raise util.Abort(_('only one phase can be specified'))
5041 5106 targetphase = idx
5042 5107
5043 5108 # look for specified revision
5044 5109 revs = list(revs)
5045 5110 revs.extend(opts['rev'])
5046 5111 if not revs:
5047 5112 # display both parents as the second parent phase can influence
5048 5113 # the phase of a merge commit
5049 5114 revs = [c.rev() for c in repo[None].parents()]
5050 5115
5051 5116 revs = scmutil.revrange(repo, revs)
5052 5117
5053 5118 lock = None
5054 5119 ret = 0
5055 5120 if targetphase is None:
5056 5121 # display
5057 5122 for r in revs:
5058 5123 ctx = repo[r]
5059 5124 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5060 5125 else:
5061 5126 tr = None
5062 5127 lock = repo.lock()
5063 5128 try:
5064 5129 tr = repo.transaction("phase")
5065 5130 # set phase
5066 5131 if not revs:
5067 5132 raise util.Abort(_('empty revision set'))
5068 5133 nodes = [repo[r].node() for r in revs]
5069 5134 # moving revision from public to draft may hide them
5070 5135 # We have to check result on an unfiltered repository
5071 5136 unfi = repo.unfiltered()
5072 5137 getphase = unfi._phasecache.phase
5073 5138 olddata = [getphase(unfi, r) for r in unfi]
5074 5139 phases.advanceboundary(repo, tr, targetphase, nodes)
5075 5140 if opts['force']:
5076 5141 phases.retractboundary(repo, tr, targetphase, nodes)
5077 5142 tr.close()
5078 5143 finally:
5079 5144 if tr is not None:
5080 5145 tr.release()
5081 5146 lock.release()
5082 5147 getphase = unfi._phasecache.phase
5083 5148 newdata = [getphase(unfi, r) for r in unfi]
5084 5149 changes = sum(newdata[r] != olddata[r] for r in unfi)
5085 5150 cl = unfi.changelog
5086 5151 rejected = [n for n in nodes
5087 5152 if newdata[cl.rev(n)] < targetphase]
5088 5153 if rejected:
5089 5154 ui.warn(_('cannot move %i changesets to a higher '
5090 5155 'phase, use --force\n') % len(rejected))
5091 5156 ret = 1
5092 5157 if changes:
5093 5158 msg = _('phase changed for %i changesets\n') % changes
5094 5159 if ret:
5095 5160 ui.status(msg)
5096 5161 else:
5097 5162 ui.note(msg)
5098 5163 else:
5099 5164 ui.warn(_('no phases changed\n'))
5100 5165 return ret
5101 5166
5102 5167 def postincoming(ui, repo, modheads, optupdate, checkout):
5103 5168 if modheads == 0:
5104 5169 return
5105 5170 if optupdate:
5106 5171 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
5107 5172 try:
5108 5173 ret = hg.update(repo, checkout)
5109 5174 except util.Abort as inst:
5110 5175 ui.warn(_("not updating: %s\n") % str(inst))
5111 5176 if inst.hint:
5112 5177 ui.warn(_("(%s)\n") % inst.hint)
5113 5178 return 0
5114 5179 if not ret and not checkout:
5115 5180 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5116 5181 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5117 5182 return ret
5118 5183 if modheads > 1:
5119 5184 currentbranchheads = len(repo.branchheads())
5120 5185 if currentbranchheads == modheads:
5121 5186 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5122 5187 elif currentbranchheads > 1:
5123 5188 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5124 5189 "merge)\n"))
5125 5190 else:
5126 5191 ui.status(_("(run 'hg heads' to see heads)\n"))
5127 5192 else:
5128 5193 ui.status(_("(run 'hg update' to get a working copy)\n"))
5129 5194
5130 5195 @command('^pull',
5131 5196 [('u', 'update', None,
5132 5197 _('update to new branch head if changesets were pulled')),
5133 5198 ('f', 'force', None, _('run even when remote repository is unrelated')),
5134 5199 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5135 5200 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5136 5201 ('b', 'branch', [], _('a specific branch you would like to pull'),
5137 5202 _('BRANCH')),
5138 5203 ] + remoteopts,
5139 5204 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5140 5205 def pull(ui, repo, source="default", **opts):
5141 5206 """pull changes from the specified source
5142 5207
5143 5208 Pull changes from a remote repository to a local one.
5144 5209
5145 5210 This finds all changes from the repository at the specified path
5146 5211 or URL and adds them to a local repository (the current one unless
5147 5212 -R is specified). By default, this does not update the copy of the
5148 5213 project in the working directory.
5149 5214
5150 5215 Use :hg:`incoming` if you want to see what would have been added
5151 5216 by a pull at the time you issued this command. If you then decide
5152 5217 to add those changes to the repository, you should use :hg:`pull
5153 5218 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5154 5219
5155 5220 If SOURCE is omitted, the 'default' path will be used.
5156 5221 See :hg:`help urls` for more information.
5157 5222
5158 5223 Returns 0 on success, 1 if an update had unresolved files.
5159 5224 """
5160 5225 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5161 5226 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5162 5227 other = hg.peer(repo, opts, source)
5163 5228 try:
5164 5229 revs, checkout = hg.addbranchrevs(repo, other, branches,
5165 5230 opts.get('rev'))
5166 5231
5167 5232
5168 5233 pullopargs = {}
5169 5234 if opts.get('bookmark'):
5170 5235 if not revs:
5171 5236 revs = []
5172 5237 # The list of bookmark used here is not the one used to actually
5173 5238 # update the bookmark name. This can result in the revision pulled
5174 5239 # not ending up with the name of the bookmark because of a race
5175 5240 # condition on the server. (See issue 4689 for details)
5176 5241 remotebookmarks = other.listkeys('bookmarks')
5177 5242 pullopargs['remotebookmarks'] = remotebookmarks
5178 5243 for b in opts['bookmark']:
5179 5244 if b not in remotebookmarks:
5180 5245 raise util.Abort(_('remote bookmark %s not found!') % b)
5181 5246 revs.append(remotebookmarks[b])
5182 5247
5183 5248 if revs:
5184 5249 try:
5185 5250 # When 'rev' is a bookmark name, we cannot guarantee that it
5186 5251 # will be updated with that name because of a race condition
5187 5252 # server side. (See issue 4689 for details)
5188 5253 oldrevs = revs
5189 5254 revs = [] # actually, nodes
5190 5255 for r in oldrevs:
5191 5256 node = other.lookup(r)
5192 5257 revs.append(node)
5193 5258 if r == checkout:
5194 5259 checkout = node
5195 5260 except error.CapabilityError:
5196 5261 err = _("other repository doesn't support revision lookup, "
5197 5262 "so a rev cannot be specified.")
5198 5263 raise util.Abort(err)
5199 5264
5200 5265 modheads = exchange.pull(repo, other, heads=revs,
5201 5266 force=opts.get('force'),
5202 5267 bookmarks=opts.get('bookmark', ()),
5203 5268 opargs=pullopargs).cgresult
5204 5269 if checkout:
5205 5270 checkout = str(repo.changelog.rev(checkout))
5206 5271 repo._subtoppath = source
5207 5272 try:
5208 5273 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5209 5274
5210 5275 finally:
5211 5276 del repo._subtoppath
5212 5277
5213 5278 finally:
5214 5279 other.close()
5215 5280 return ret
5216 5281
5217 5282 @command('^push',
5218 5283 [('f', 'force', None, _('force push')),
5219 5284 ('r', 'rev', [],
5220 5285 _('a changeset intended to be included in the destination'),
5221 5286 _('REV')),
5222 5287 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5223 5288 ('b', 'branch', [],
5224 5289 _('a specific branch you would like to push'), _('BRANCH')),
5225 5290 ('', 'new-branch', False, _('allow pushing a new branch')),
5226 5291 ] + remoteopts,
5227 5292 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5228 5293 def push(ui, repo, dest=None, **opts):
5229 5294 """push changes to the specified destination
5230 5295
5231 5296 Push changesets from the local repository to the specified
5232 5297 destination.
5233 5298
5234 5299 This operation is symmetrical to pull: it is identical to a pull
5235 5300 in the destination repository from the current one.
5236 5301
5237 5302 By default, push will not allow creation of new heads at the
5238 5303 destination, since multiple heads would make it unclear which head
5239 5304 to use. In this situation, it is recommended to pull and merge
5240 5305 before pushing.
5241 5306
5242 5307 Use --new-branch if you want to allow push to create a new named
5243 5308 branch that is not present at the destination. This allows you to
5244 5309 only create a new branch without forcing other changes.
5245 5310
5246 5311 .. note::
5247 5312
5248 5313 Extra care should be taken with the -f/--force option,
5249 5314 which will push all new heads on all branches, an action which will
5250 5315 almost always cause confusion for collaborators.
5251 5316
5252 5317 If -r/--rev is used, the specified revision and all its ancestors
5253 5318 will be pushed to the remote repository.
5254 5319
5255 5320 If -B/--bookmark is used, the specified bookmarked revision, its
5256 5321 ancestors, and the bookmark will be pushed to the remote
5257 5322 repository.
5258 5323
5259 5324 Please see :hg:`help urls` for important details about ``ssh://``
5260 5325 URLs. If DESTINATION is omitted, a default path will be used.
5261 5326
5262 5327 Returns 0 if push was successful, 1 if nothing to push.
5263 5328 """
5264 5329
5265 5330 if opts.get('bookmark'):
5266 5331 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5267 5332 for b in opts['bookmark']:
5268 5333 # translate -B options to -r so changesets get pushed
5269 5334 if b in repo._bookmarks:
5270 5335 opts.setdefault('rev', []).append(b)
5271 5336 else:
5272 5337 # if we try to push a deleted bookmark, translate it to null
5273 5338 # this lets simultaneous -r, -b options continue working
5274 5339 opts.setdefault('rev', []).append("null")
5275 5340
5276 5341 path = ui.paths.getpath(dest, default='default')
5277 5342 if not path:
5278 5343 raise util.Abort(_('default repository not configured!'),
5279 5344 hint=_('see the "path" section in "hg help config"'))
5280 5345 dest, branches = path.pushloc, (path.branch, opts.get('branch') or [])
5281 5346 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5282 5347 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5283 5348 other = hg.peer(repo, opts, dest)
5284 5349
5285 5350 if revs:
5286 5351 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5287 5352 if not revs:
5288 5353 raise util.Abort(_("specified revisions evaluate to an empty set"),
5289 5354 hint=_("use different revision arguments"))
5290 5355
5291 5356 repo._subtoppath = dest
5292 5357 try:
5293 5358 # push subrepos depth-first for coherent ordering
5294 5359 c = repo['']
5295 5360 subs = c.substate # only repos that are committed
5296 5361 for s in sorted(subs):
5297 5362 result = c.sub(s).push(opts)
5298 5363 if result == 0:
5299 5364 return not result
5300 5365 finally:
5301 5366 del repo._subtoppath
5302 5367 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5303 5368 newbranch=opts.get('new_branch'),
5304 5369 bookmarks=opts.get('bookmark', ()))
5305 5370
5306 5371 result = not pushop.cgresult
5307 5372
5308 5373 if pushop.bkresult is not None:
5309 5374 if pushop.bkresult == 2:
5310 5375 result = 2
5311 5376 elif not result and pushop.bkresult:
5312 5377 result = 2
5313 5378
5314 5379 return result
5315 5380
5316 5381 @command('recover', [])
5317 5382 def recover(ui, repo):
5318 5383 """roll back an interrupted transaction
5319 5384
5320 5385 Recover from an interrupted commit or pull.
5321 5386
5322 5387 This command tries to fix the repository status after an
5323 5388 interrupted operation. It should only be necessary when Mercurial
5324 5389 suggests it.
5325 5390
5326 5391 Returns 0 if successful, 1 if nothing to recover or verify fails.
5327 5392 """
5328 5393 if repo.recover():
5329 5394 return hg.verify(repo)
5330 5395 return 1
5331 5396
5332 5397 @command('^remove|rm',
5333 5398 [('A', 'after', None, _('record delete for missing files')),
5334 5399 ('f', 'force', None,
5335 5400 _('remove (and delete) file even if added or modified')),
5336 5401 ] + subrepoopts + walkopts,
5337 5402 _('[OPTION]... FILE...'),
5338 5403 inferrepo=True)
5339 5404 def remove(ui, repo, *pats, **opts):
5340 5405 """remove the specified files on the next commit
5341 5406
5342 5407 Schedule the indicated files for removal from the current branch.
5343 5408
5344 5409 This command schedules the files to be removed at the next commit.
5345 5410 To undo a remove before that, see :hg:`revert`. To undo added
5346 5411 files, see :hg:`forget`.
5347 5412
5348 5413 .. container:: verbose
5349 5414
5350 5415 -A/--after can be used to remove only files that have already
5351 5416 been deleted, -f/--force can be used to force deletion, and -Af
5352 5417 can be used to remove files from the next revision without
5353 5418 deleting them from the working directory.
5354 5419
5355 5420 The following table details the behavior of remove for different
5356 5421 file states (columns) and option combinations (rows). The file
5357 5422 states are Added [A], Clean [C], Modified [M] and Missing [!]
5358 5423 (as reported by :hg:`status`). The actions are Warn, Remove
5359 5424 (from branch) and Delete (from disk):
5360 5425
5361 5426 ========= == == == ==
5362 5427 opt/state A C M !
5363 5428 ========= == == == ==
5364 5429 none W RD W R
5365 5430 -f R RD RD R
5366 5431 -A W W W R
5367 5432 -Af R R R R
5368 5433 ========= == == == ==
5369 5434
5370 5435 Note that remove never deletes files in Added [A] state from the
5371 5436 working directory, not even if option --force is specified.
5372 5437
5373 5438 Returns 0 on success, 1 if any warnings encountered.
5374 5439 """
5375 5440
5376 5441 after, force = opts.get('after'), opts.get('force')
5377 5442 if not pats and not after:
5378 5443 raise util.Abort(_('no files specified'))
5379 5444
5380 5445 m = scmutil.match(repo[None], pats, opts)
5381 5446 subrepos = opts.get('subrepos')
5382 5447 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5383 5448
5384 5449 @command('rename|move|mv',
5385 5450 [('A', 'after', None, _('record a rename that has already occurred')),
5386 5451 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5387 5452 ] + walkopts + dryrunopts,
5388 5453 _('[OPTION]... SOURCE... DEST'))
5389 5454 def rename(ui, repo, *pats, **opts):
5390 5455 """rename files; equivalent of copy + remove
5391 5456
5392 5457 Mark dest as copies of sources; mark sources for deletion. If dest
5393 5458 is a directory, copies are put in that directory. If dest is a
5394 5459 file, there can only be one source.
5395 5460
5396 5461 By default, this command copies the contents of files as they
5397 5462 exist in the working directory. If invoked with -A/--after, the
5398 5463 operation is recorded, but no copying is performed.
5399 5464
5400 5465 This command takes effect at the next commit. To undo a rename
5401 5466 before that, see :hg:`revert`.
5402 5467
5403 5468 Returns 0 on success, 1 if errors are encountered.
5404 5469 """
5405 5470 wlock = repo.wlock(False)
5406 5471 try:
5407 5472 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5408 5473 finally:
5409 5474 wlock.release()
5410 5475
5411 5476 @command('resolve',
5412 5477 [('a', 'all', None, _('select all unresolved files')),
5413 5478 ('l', 'list', None, _('list state of files needing merge')),
5414 5479 ('m', 'mark', None, _('mark files as resolved')),
5415 5480 ('u', 'unmark', None, _('mark files as unresolved')),
5416 5481 ('n', 'no-status', None, _('hide status prefix'))]
5417 5482 + mergetoolopts + walkopts + formatteropts,
5418 5483 _('[OPTION]... [FILE]...'),
5419 5484 inferrepo=True)
5420 5485 def resolve(ui, repo, *pats, **opts):
5421 5486 """redo merges or set/view the merge status of files
5422 5487
5423 5488 Merges with unresolved conflicts are often the result of
5424 5489 non-interactive merging using the ``internal:merge`` configuration
5425 5490 setting, or a command-line merge tool like ``diff3``. The resolve
5426 5491 command is used to manage the files involved in a merge, after
5427 5492 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5428 5493 working directory must have two parents). See :hg:`help
5429 5494 merge-tools` for information on configuring merge tools.
5430 5495
5431 5496 The resolve command can be used in the following ways:
5432 5497
5433 5498 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5434 5499 files, discarding any previous merge attempts. Re-merging is not
5435 5500 performed for files already marked as resolved. Use ``--all/-a``
5436 5501 to select all unresolved files. ``--tool`` can be used to specify
5437 5502 the merge tool used for the given files. It overrides the HGMERGE
5438 5503 environment variable and your configuration files. Previous file
5439 5504 contents are saved with a ``.orig`` suffix.
5440 5505
5441 5506 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5442 5507 (e.g. after having manually fixed-up the files). The default is
5443 5508 to mark all unresolved files.
5444 5509
5445 5510 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5446 5511 default is to mark all resolved files.
5447 5512
5448 5513 - :hg:`resolve -l`: list files which had or still have conflicts.
5449 5514 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5450 5515
5451 5516 Note that Mercurial will not let you commit files with unresolved
5452 5517 merge conflicts. You must use :hg:`resolve -m ...` before you can
5453 5518 commit after a conflicting merge.
5454 5519
5455 5520 Returns 0 on success, 1 if any files fail a resolve attempt.
5456 5521 """
5457 5522
5458 5523 all, mark, unmark, show, nostatus = \
5459 5524 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5460 5525
5461 5526 if (show and (mark or unmark)) or (mark and unmark):
5462 5527 raise util.Abort(_("too many options specified"))
5463 5528 if pats and all:
5464 5529 raise util.Abort(_("can't specify --all and patterns"))
5465 5530 if not (all or pats or show or mark or unmark):
5466 5531 raise util.Abort(_('no files or directories specified'),
5467 5532 hint=('use --all to re-merge all unresolved files'))
5468 5533
5469 5534 if show:
5470 5535 fm = ui.formatter('resolve', opts)
5471 5536 ms = mergemod.mergestate(repo)
5472 5537 m = scmutil.match(repo[None], pats, opts)
5473 5538 for f in ms:
5474 5539 if not m(f):
5475 5540 continue
5476 5541 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved'}[ms[f]]
5477 5542 fm.startitem()
5478 5543 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5479 5544 fm.write('path', '%s\n', f, label=l)
5480 5545 fm.end()
5481 5546 return 0
5482 5547
5483 5548 wlock = repo.wlock()
5484 5549 try:
5485 5550 ms = mergemod.mergestate(repo)
5486 5551
5487 5552 if not (ms.active() or repo.dirstate.p2() != nullid):
5488 5553 raise util.Abort(
5489 5554 _('resolve command not applicable when not merging'))
5490 5555
5491 5556 m = scmutil.match(repo[None], pats, opts)
5492 5557 ret = 0
5493 5558 didwork = False
5494 5559
5495 5560 for f in ms:
5496 5561 if not m(f):
5497 5562 continue
5498 5563
5499 5564 didwork = True
5500 5565
5501 5566 if mark:
5502 5567 ms.mark(f, "r")
5503 5568 elif unmark:
5504 5569 ms.mark(f, "u")
5505 5570 else:
5506 5571 wctx = repo[None]
5507 5572
5508 5573 # backup pre-resolve (merge uses .orig for its own purposes)
5509 5574 a = repo.wjoin(f)
5510 5575 util.copyfile(a, a + ".resolve")
5511 5576
5512 5577 try:
5513 5578 # resolve file
5514 5579 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5515 5580 'resolve')
5516 5581 if ms.resolve(f, wctx):
5517 5582 ret = 1
5518 5583 finally:
5519 5584 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5520 5585 ms.commit()
5521 5586
5522 5587 # replace filemerge's .orig file with our resolve file
5523 5588 util.rename(a + ".resolve", a + ".orig")
5524 5589
5525 5590 ms.commit()
5526 5591
5527 5592 if not didwork and pats:
5528 5593 ui.warn(_("arguments do not match paths that need resolving\n"))
5529 5594
5530 5595 finally:
5531 5596 wlock.release()
5532 5597
5533 5598 # Nudge users into finishing an unfinished operation
5534 5599 if not list(ms.unresolved()):
5535 5600 ui.status(_('(no more unresolved files)\n'))
5536 5601
5537 5602 return ret
5538 5603
5539 5604 @command('revert',
5540 5605 [('a', 'all', None, _('revert all changes when no arguments given')),
5541 5606 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5542 5607 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5543 5608 ('C', 'no-backup', None, _('do not save backup copies of files')),
5544 5609 ('i', 'interactive', None,
5545 5610 _('interactively select the changes (EXPERIMENTAL)')),
5546 5611 ] + walkopts + dryrunopts,
5547 5612 _('[OPTION]... [-r REV] [NAME]...'))
5548 5613 def revert(ui, repo, *pats, **opts):
5549 5614 """restore files to their checkout state
5550 5615
5551 5616 .. note::
5552 5617
5553 5618 To check out earlier revisions, you should use :hg:`update REV`.
5554 5619 To cancel an uncommitted merge (and lose your changes),
5555 5620 use :hg:`update --clean .`.
5556 5621
5557 5622 With no revision specified, revert the specified files or directories
5558 5623 to the contents they had in the parent of the working directory.
5559 5624 This restores the contents of files to an unmodified
5560 5625 state and unschedules adds, removes, copies, and renames. If the
5561 5626 working directory has two parents, you must explicitly specify a
5562 5627 revision.
5563 5628
5564 5629 Using the -r/--rev or -d/--date options, revert the given files or
5565 5630 directories to their states as of a specific revision. Because
5566 5631 revert does not change the working directory parents, this will
5567 5632 cause these files to appear modified. This can be helpful to "back
5568 5633 out" some or all of an earlier change. See :hg:`backout` for a
5569 5634 related method.
5570 5635
5571 5636 Modified files are saved with a .orig suffix before reverting.
5572 5637 To disable these backups, use --no-backup.
5573 5638
5574 5639 See :hg:`help dates` for a list of formats valid for -d/--date.
5575 5640
5576 5641 See :hg:`help backout` for a way to reverse the effect of an
5577 5642 earlier changeset.
5578 5643
5579 5644 Returns 0 on success.
5580 5645 """
5581 5646
5582 5647 if opts.get("date"):
5583 5648 if opts.get("rev"):
5584 5649 raise util.Abort(_("you can't specify a revision and a date"))
5585 5650 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5586 5651
5587 5652 parent, p2 = repo.dirstate.parents()
5588 5653 if not opts.get('rev') and p2 != nullid:
5589 5654 # revert after merge is a trap for new users (issue2915)
5590 5655 raise util.Abort(_('uncommitted merge with no revision specified'),
5591 5656 hint=_('use "hg update" or see "hg help revert"'))
5592 5657
5593 5658 ctx = scmutil.revsingle(repo, opts.get('rev'))
5594 5659
5595 5660 if (not (pats or opts.get('include') or opts.get('exclude') or
5596 5661 opts.get('all') or opts.get('interactive'))):
5597 5662 msg = _("no files or directories specified")
5598 5663 if p2 != nullid:
5599 5664 hint = _("uncommitted merge, use --all to discard all changes,"
5600 5665 " or 'hg update -C .' to abort the merge")
5601 5666 raise util.Abort(msg, hint=hint)
5602 5667 dirty = any(repo.status())
5603 5668 node = ctx.node()
5604 5669 if node != parent:
5605 5670 if dirty:
5606 5671 hint = _("uncommitted changes, use --all to discard all"
5607 5672 " changes, or 'hg update %s' to update") % ctx.rev()
5608 5673 else:
5609 5674 hint = _("use --all to revert all files,"
5610 5675 " or 'hg update %s' to update") % ctx.rev()
5611 5676 elif dirty:
5612 5677 hint = _("uncommitted changes, use --all to discard all changes")
5613 5678 else:
5614 5679 hint = _("use --all to revert all files")
5615 5680 raise util.Abort(msg, hint=hint)
5616 5681
5617 5682 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5618 5683
5619 5684 @command('rollback', dryrunopts +
5620 5685 [('f', 'force', False, _('ignore safety measures'))])
5621 5686 def rollback(ui, repo, **opts):
5622 5687 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5623 5688
5624 5689 Please use :hg:`commit --amend` instead of rollback to correct
5625 5690 mistakes in the last commit.
5626 5691
5627 5692 This command should be used with care. There is only one level of
5628 5693 rollback, and there is no way to undo a rollback. It will also
5629 5694 restore the dirstate at the time of the last transaction, losing
5630 5695 any dirstate changes since that time. This command does not alter
5631 5696 the working directory.
5632 5697
5633 5698 Transactions are used to encapsulate the effects of all commands
5634 5699 that create new changesets or propagate existing changesets into a
5635 5700 repository.
5636 5701
5637 5702 .. container:: verbose
5638 5703
5639 5704 For example, the following commands are transactional, and their
5640 5705 effects can be rolled back:
5641 5706
5642 5707 - commit
5643 5708 - import
5644 5709 - pull
5645 5710 - push (with this repository as the destination)
5646 5711 - unbundle
5647 5712
5648 5713 To avoid permanent data loss, rollback will refuse to rollback a
5649 5714 commit transaction if it isn't checked out. Use --force to
5650 5715 override this protection.
5651 5716
5652 5717 This command is not intended for use on public repositories. Once
5653 5718 changes are visible for pull by other users, rolling a transaction
5654 5719 back locally is ineffective (someone else may already have pulled
5655 5720 the changes). Furthermore, a race is possible with readers of the
5656 5721 repository; for example an in-progress pull from the repository
5657 5722 may fail if a rollback is performed.
5658 5723
5659 5724 Returns 0 on success, 1 if no rollback data is available.
5660 5725 """
5661 5726 return repo.rollback(dryrun=opts.get('dry_run'),
5662 5727 force=opts.get('force'))
5663 5728
5664 5729 @command('root', [])
5665 5730 def root(ui, repo):
5666 5731 """print the root (top) of the current working directory
5667 5732
5668 5733 Print the root directory of the current repository.
5669 5734
5670 5735 Returns 0 on success.
5671 5736 """
5672 5737 ui.write(repo.root + "\n")
5673 5738
5674 5739 @command('^serve',
5675 5740 [('A', 'accesslog', '', _('name of access log file to write to'),
5676 5741 _('FILE')),
5677 5742 ('d', 'daemon', None, _('run server in background')),
5678 5743 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5679 5744 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5680 5745 # use string type, then we can check if something was passed
5681 5746 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5682 5747 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5683 5748 _('ADDR')),
5684 5749 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5685 5750 _('PREFIX')),
5686 5751 ('n', 'name', '',
5687 5752 _('name to show in web pages (default: working directory)'), _('NAME')),
5688 5753 ('', 'web-conf', '',
5689 5754 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5690 5755 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5691 5756 _('FILE')),
5692 5757 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5693 5758 ('', 'stdio', None, _('for remote clients')),
5694 5759 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5695 5760 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5696 5761 ('', 'style', '', _('template style to use'), _('STYLE')),
5697 5762 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5698 5763 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5699 5764 _('[OPTION]...'),
5700 5765 optionalrepo=True)
5701 5766 def serve(ui, repo, **opts):
5702 5767 """start stand-alone webserver
5703 5768
5704 5769 Start a local HTTP repository browser and pull server. You can use
5705 5770 this for ad-hoc sharing and browsing of repositories. It is
5706 5771 recommended to use a real web server to serve a repository for
5707 5772 longer periods of time.
5708 5773
5709 5774 Please note that the server does not implement access control.
5710 5775 This means that, by default, anybody can read from the server and
5711 5776 nobody can write to it by default. Set the ``web.allow_push``
5712 5777 option to ``*`` to allow everybody to push to the server. You
5713 5778 should use a real web server if you need to authenticate users.
5714 5779
5715 5780 By default, the server logs accesses to stdout and errors to
5716 5781 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5717 5782 files.
5718 5783
5719 5784 To have the server choose a free port number to listen on, specify
5720 5785 a port number of 0; in this case, the server will print the port
5721 5786 number it uses.
5722 5787
5723 5788 Returns 0 on success.
5724 5789 """
5725 5790
5726 5791 if opts["stdio"] and opts["cmdserver"]:
5727 5792 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5728 5793
5729 5794 if opts["stdio"]:
5730 5795 if repo is None:
5731 5796 raise error.RepoError(_("there is no Mercurial repository here"
5732 5797 " (.hg not found)"))
5733 5798 s = sshserver.sshserver(ui, repo)
5734 5799 s.serve_forever()
5735 5800
5736 5801 if opts["cmdserver"]:
5737 5802 import commandserver
5738 5803 service = commandserver.createservice(ui, repo, opts)
5739 5804 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5740 5805
5741 5806 # this way we can check if something was given in the command-line
5742 5807 if opts.get('port'):
5743 5808 opts['port'] = util.getport(opts.get('port'))
5744 5809
5745 5810 if repo:
5746 5811 baseui = repo.baseui
5747 5812 else:
5748 5813 baseui = ui
5749 5814 optlist = ("name templates style address port prefix ipv6"
5750 5815 " accesslog errorlog certificate encoding")
5751 5816 for o in optlist.split():
5752 5817 val = opts.get(o, '')
5753 5818 if val in (None, ''): # should check against default options instead
5754 5819 continue
5755 5820 baseui.setconfig("web", o, val, 'serve')
5756 5821 if repo and repo.ui != baseui:
5757 5822 repo.ui.setconfig("web", o, val, 'serve')
5758 5823
5759 5824 o = opts.get('web_conf') or opts.get('webdir_conf')
5760 5825 if not o:
5761 5826 if not repo:
5762 5827 raise error.RepoError(_("there is no Mercurial repository"
5763 5828 " here (.hg not found)"))
5764 5829 o = repo
5765 5830
5766 5831 app = hgweb.hgweb(o, baseui=baseui)
5767 5832 service = httpservice(ui, app, opts)
5768 5833 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5769 5834
5770 5835 class httpservice(object):
5771 5836 def __init__(self, ui, app, opts):
5772 5837 self.ui = ui
5773 5838 self.app = app
5774 5839 self.opts = opts
5775 5840
5776 5841 def init(self):
5777 5842 util.setsignalhandler()
5778 5843 self.httpd = hgweb_server.create_server(self.ui, self.app)
5779 5844
5780 5845 if self.opts['port'] and not self.ui.verbose:
5781 5846 return
5782 5847
5783 5848 if self.httpd.prefix:
5784 5849 prefix = self.httpd.prefix.strip('/') + '/'
5785 5850 else:
5786 5851 prefix = ''
5787 5852
5788 5853 port = ':%d' % self.httpd.port
5789 5854 if port == ':80':
5790 5855 port = ''
5791 5856
5792 5857 bindaddr = self.httpd.addr
5793 5858 if bindaddr == '0.0.0.0':
5794 5859 bindaddr = '*'
5795 5860 elif ':' in bindaddr: # IPv6
5796 5861 bindaddr = '[%s]' % bindaddr
5797 5862
5798 5863 fqaddr = self.httpd.fqaddr
5799 5864 if ':' in fqaddr:
5800 5865 fqaddr = '[%s]' % fqaddr
5801 5866 if self.opts['port']:
5802 5867 write = self.ui.status
5803 5868 else:
5804 5869 write = self.ui.write
5805 5870 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5806 5871 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5807 5872 self.ui.flush() # avoid buffering of status message
5808 5873
5809 5874 def run(self):
5810 5875 self.httpd.serve_forever()
5811 5876
5812 5877
5813 5878 @command('^status|st',
5814 5879 [('A', 'all', None, _('show status of all files')),
5815 5880 ('m', 'modified', None, _('show only modified files')),
5816 5881 ('a', 'added', None, _('show only added files')),
5817 5882 ('r', 'removed', None, _('show only removed files')),
5818 5883 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5819 5884 ('c', 'clean', None, _('show only files without changes')),
5820 5885 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5821 5886 ('i', 'ignored', None, _('show only ignored files')),
5822 5887 ('n', 'no-status', None, _('hide status prefix')),
5823 5888 ('C', 'copies', None, _('show source of copied files')),
5824 5889 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5825 5890 ('', 'rev', [], _('show difference from revision'), _('REV')),
5826 5891 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5827 5892 ] + walkopts + subrepoopts + formatteropts,
5828 5893 _('[OPTION]... [FILE]...'),
5829 5894 inferrepo=True)
5830 5895 def status(ui, repo, *pats, **opts):
5831 5896 """show changed files in the working directory
5832 5897
5833 5898 Show status of files in the repository. If names are given, only
5834 5899 files that match are shown. Files that are clean or ignored or
5835 5900 the source of a copy/move operation, are not listed unless
5836 5901 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5837 5902 Unless options described with "show only ..." are given, the
5838 5903 options -mardu are used.
5839 5904
5840 5905 Option -q/--quiet hides untracked (unknown and ignored) files
5841 5906 unless explicitly requested with -u/--unknown or -i/--ignored.
5842 5907
5843 5908 .. note::
5844 5909
5845 5910 status may appear to disagree with diff if permissions have
5846 5911 changed or a merge has occurred. The standard diff format does
5847 5912 not report permission changes and diff only reports changes
5848 5913 relative to one merge parent.
5849 5914
5850 5915 If one revision is given, it is used as the base revision.
5851 5916 If two revisions are given, the differences between them are
5852 5917 shown. The --change option can also be used as a shortcut to list
5853 5918 the changed files of a revision from its first parent.
5854 5919
5855 5920 The codes used to show the status of files are::
5856 5921
5857 5922 M = modified
5858 5923 A = added
5859 5924 R = removed
5860 5925 C = clean
5861 5926 ! = missing (deleted by non-hg command, but still tracked)
5862 5927 ? = not tracked
5863 5928 I = ignored
5864 5929 = origin of the previous file (with --copies)
5865 5930
5866 5931 .. container:: verbose
5867 5932
5868 5933 Examples:
5869 5934
5870 5935 - show changes in the working directory relative to a
5871 5936 changeset::
5872 5937
5873 5938 hg status --rev 9353
5874 5939
5875 5940 - show changes in the working directory relative to the
5876 5941 current directory (see :hg:`help patterns` for more information)::
5877 5942
5878 5943 hg status re:
5879 5944
5880 5945 - show all changes including copies in an existing changeset::
5881 5946
5882 5947 hg status --copies --change 9353
5883 5948
5884 5949 - get a NUL separated list of added files, suitable for xargs::
5885 5950
5886 5951 hg status -an0
5887 5952
5888 5953 Returns 0 on success.
5889 5954 """
5890 5955
5891 5956 revs = opts.get('rev')
5892 5957 change = opts.get('change')
5893 5958
5894 5959 if revs and change:
5895 5960 msg = _('cannot specify --rev and --change at the same time')
5896 5961 raise util.Abort(msg)
5897 5962 elif change:
5898 5963 node2 = scmutil.revsingle(repo, change, None).node()
5899 5964 node1 = repo[node2].p1().node()
5900 5965 else:
5901 5966 node1, node2 = scmutil.revpair(repo, revs)
5902 5967
5903 5968 if pats:
5904 5969 cwd = repo.getcwd()
5905 5970 else:
5906 5971 cwd = ''
5907 5972
5908 5973 if opts.get('print0'):
5909 5974 end = '\0'
5910 5975 else:
5911 5976 end = '\n'
5912 5977 copy = {}
5913 5978 states = 'modified added removed deleted unknown ignored clean'.split()
5914 5979 show = [k for k in states if opts.get(k)]
5915 5980 if opts.get('all'):
5916 5981 show += ui.quiet and (states[:4] + ['clean']) or states
5917 5982 if not show:
5918 5983 if ui.quiet:
5919 5984 show = states[:4]
5920 5985 else:
5921 5986 show = states[:5]
5922 5987
5923 5988 m = scmutil.match(repo[node2], pats, opts)
5924 5989 stat = repo.status(node1, node2, m,
5925 5990 'ignored' in show, 'clean' in show, 'unknown' in show,
5926 5991 opts.get('subrepos'))
5927 5992 changestates = zip(states, 'MAR!?IC', stat)
5928 5993
5929 5994 if (opts.get('all') or opts.get('copies')
5930 5995 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5931 5996 copy = copies.pathcopies(repo[node1], repo[node2], m)
5932 5997
5933 5998 fm = ui.formatter('status', opts)
5934 5999 fmt = '%s' + end
5935 6000 showchar = not opts.get('no_status')
5936 6001
5937 6002 for state, char, files in changestates:
5938 6003 if state in show:
5939 6004 label = 'status.' + state
5940 6005 for f in files:
5941 6006 fm.startitem()
5942 6007 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5943 6008 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5944 6009 if f in copy:
5945 6010 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5946 6011 label='status.copied')
5947 6012 fm.end()
5948 6013
5949 6014 @command('^summary|sum',
5950 6015 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5951 6016 def summary(ui, repo, **opts):
5952 6017 """summarize working directory state
5953 6018
5954 6019 This generates a brief summary of the working directory state,
5955 6020 including parents, branch, commit status, phase and available updates.
5956 6021
5957 6022 With the --remote option, this will check the default paths for
5958 6023 incoming and outgoing changes. This can be time-consuming.
5959 6024
5960 6025 Returns 0 on success.
5961 6026 """
5962 6027
5963 6028 ctx = repo[None]
5964 6029 parents = ctx.parents()
5965 6030 pnode = parents[0].node()
5966 6031 marks = []
5967 6032
5968 6033 for p in parents:
5969 6034 # label with log.changeset (instead of log.parent) since this
5970 6035 # shows a working directory parent *changeset*:
5971 6036 # i18n: column positioning for "hg summary"
5972 6037 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5973 6038 label='log.changeset changeset.%s' % p.phasestr())
5974 6039 ui.write(' '.join(p.tags()), label='log.tag')
5975 6040 if p.bookmarks():
5976 6041 marks.extend(p.bookmarks())
5977 6042 if p.rev() == -1:
5978 6043 if not len(repo):
5979 6044 ui.write(_(' (empty repository)'))
5980 6045 else:
5981 6046 ui.write(_(' (no revision checked out)'))
5982 6047 ui.write('\n')
5983 6048 if p.description():
5984 6049 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5985 6050 label='log.summary')
5986 6051
5987 6052 branch = ctx.branch()
5988 6053 bheads = repo.branchheads(branch)
5989 6054 # i18n: column positioning for "hg summary"
5990 6055 m = _('branch: %s\n') % branch
5991 6056 if branch != 'default':
5992 6057 ui.write(m, label='log.branch')
5993 6058 else:
5994 6059 ui.status(m, label='log.branch')
5995 6060
5996 6061 if marks:
5997 6062 active = repo._activebookmark
5998 6063 # i18n: column positioning for "hg summary"
5999 6064 ui.write(_('bookmarks:'), label='log.bookmark')
6000 6065 if active is not None:
6001 6066 if active in marks:
6002 6067 ui.write(' *' + active, label=activebookmarklabel)
6003 6068 marks.remove(active)
6004 6069 else:
6005 6070 ui.write(' [%s]' % active, label=activebookmarklabel)
6006 6071 for m in marks:
6007 6072 ui.write(' ' + m, label='log.bookmark')
6008 6073 ui.write('\n', label='log.bookmark')
6009 6074
6010 6075 status = repo.status(unknown=True)
6011 6076
6012 6077 c = repo.dirstate.copies()
6013 6078 copied, renamed = [], []
6014 6079 for d, s in c.iteritems():
6015 6080 if s in status.removed:
6016 6081 status.removed.remove(s)
6017 6082 renamed.append(d)
6018 6083 else:
6019 6084 copied.append(d)
6020 6085 if d in status.added:
6021 6086 status.added.remove(d)
6022 6087
6023 6088 ms = mergemod.mergestate(repo)
6024 6089 unresolved = [f for f in ms if ms[f] == 'u']
6025 6090
6026 6091 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6027 6092
6028 6093 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6029 6094 (ui.label(_('%d added'), 'status.added'), status.added),
6030 6095 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6031 6096 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6032 6097 (ui.label(_('%d copied'), 'status.copied'), copied),
6033 6098 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6034 6099 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6035 6100 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6036 6101 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6037 6102 t = []
6038 6103 for l, s in labels:
6039 6104 if s:
6040 6105 t.append(l % len(s))
6041 6106
6042 6107 t = ', '.join(t)
6043 6108 cleanworkdir = False
6044 6109
6045 6110 if repo.vfs.exists('updatestate'):
6046 6111 t += _(' (interrupted update)')
6047 6112 elif len(parents) > 1:
6048 6113 t += _(' (merge)')
6049 6114 elif branch != parents[0].branch():
6050 6115 t += _(' (new branch)')
6051 6116 elif (parents[0].closesbranch() and
6052 6117 pnode in repo.branchheads(branch, closed=True)):
6053 6118 t += _(' (head closed)')
6054 6119 elif not (status.modified or status.added or status.removed or renamed or
6055 6120 copied or subs):
6056 6121 t += _(' (clean)')
6057 6122 cleanworkdir = True
6058 6123 elif pnode not in bheads:
6059 6124 t += _(' (new branch head)')
6060 6125
6061 6126 if parents:
6062 6127 pendingphase = max(p.phase() for p in parents)
6063 6128 else:
6064 6129 pendingphase = phases.public
6065 6130
6066 6131 if pendingphase > phases.newcommitphase(ui):
6067 6132 t += ' (%s)' % phases.phasenames[pendingphase]
6068 6133
6069 6134 if cleanworkdir:
6070 6135 # i18n: column positioning for "hg summary"
6071 6136 ui.status(_('commit: %s\n') % t.strip())
6072 6137 else:
6073 6138 # i18n: column positioning for "hg summary"
6074 6139 ui.write(_('commit: %s\n') % t.strip())
6075 6140
6076 6141 # all ancestors of branch heads - all ancestors of parent = new csets
6077 6142 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6078 6143 bheads))
6079 6144
6080 6145 if new == 0:
6081 6146 # i18n: column positioning for "hg summary"
6082 6147 ui.status(_('update: (current)\n'))
6083 6148 elif pnode not in bheads:
6084 6149 # i18n: column positioning for "hg summary"
6085 6150 ui.write(_('update: %d new changesets (update)\n') % new)
6086 6151 else:
6087 6152 # i18n: column positioning for "hg summary"
6088 6153 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6089 6154 (new, len(bheads)))
6090 6155
6091 6156 t = []
6092 6157 draft = len(repo.revs('draft()'))
6093 6158 if draft:
6094 6159 t.append(_('%d draft') % draft)
6095 6160 secret = len(repo.revs('secret()'))
6096 6161 if secret:
6097 6162 t.append(_('%d secret') % secret)
6098 6163
6099 6164 if draft or secret:
6100 6165 ui.status(_('phases: %s\n') % ', '.join(t))
6101 6166
6102 6167 cmdutil.summaryhooks(ui, repo)
6103 6168
6104 6169 if opts.get('remote'):
6105 6170 needsincoming, needsoutgoing = True, True
6106 6171 else:
6107 6172 needsincoming, needsoutgoing = False, False
6108 6173 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6109 6174 if i:
6110 6175 needsincoming = True
6111 6176 if o:
6112 6177 needsoutgoing = True
6113 6178 if not needsincoming and not needsoutgoing:
6114 6179 return
6115 6180
6116 6181 def getincoming():
6117 6182 source, branches = hg.parseurl(ui.expandpath('default'))
6118 6183 sbranch = branches[0]
6119 6184 try:
6120 6185 other = hg.peer(repo, {}, source)
6121 6186 except error.RepoError:
6122 6187 if opts.get('remote'):
6123 6188 raise
6124 6189 return source, sbranch, None, None, None
6125 6190 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6126 6191 if revs:
6127 6192 revs = [other.lookup(rev) for rev in revs]
6128 6193 ui.debug('comparing with %s\n' % util.hidepassword(source))
6129 6194 repo.ui.pushbuffer()
6130 6195 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6131 6196 repo.ui.popbuffer()
6132 6197 return source, sbranch, other, commoninc, commoninc[1]
6133 6198
6134 6199 if needsincoming:
6135 6200 source, sbranch, sother, commoninc, incoming = getincoming()
6136 6201 else:
6137 6202 source = sbranch = sother = commoninc = incoming = None
6138 6203
6139 6204 def getoutgoing():
6140 6205 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6141 6206 dbranch = branches[0]
6142 6207 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6143 6208 if source != dest:
6144 6209 try:
6145 6210 dother = hg.peer(repo, {}, dest)
6146 6211 except error.RepoError:
6147 6212 if opts.get('remote'):
6148 6213 raise
6149 6214 return dest, dbranch, None, None
6150 6215 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6151 6216 elif sother is None:
6152 6217 # there is no explicit destination peer, but source one is invalid
6153 6218 return dest, dbranch, None, None
6154 6219 else:
6155 6220 dother = sother
6156 6221 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6157 6222 common = None
6158 6223 else:
6159 6224 common = commoninc
6160 6225 if revs:
6161 6226 revs = [repo.lookup(rev) for rev in revs]
6162 6227 repo.ui.pushbuffer()
6163 6228 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6164 6229 commoninc=common)
6165 6230 repo.ui.popbuffer()
6166 6231 return dest, dbranch, dother, outgoing
6167 6232
6168 6233 if needsoutgoing:
6169 6234 dest, dbranch, dother, outgoing = getoutgoing()
6170 6235 else:
6171 6236 dest = dbranch = dother = outgoing = None
6172 6237
6173 6238 if opts.get('remote'):
6174 6239 t = []
6175 6240 if incoming:
6176 6241 t.append(_('1 or more incoming'))
6177 6242 o = outgoing.missing
6178 6243 if o:
6179 6244 t.append(_('%d outgoing') % len(o))
6180 6245 other = dother or sother
6181 6246 if 'bookmarks' in other.listkeys('namespaces'):
6182 6247 counts = bookmarks.summary(repo, other)
6183 6248 if counts[0] > 0:
6184 6249 t.append(_('%d incoming bookmarks') % counts[0])
6185 6250 if counts[1] > 0:
6186 6251 t.append(_('%d outgoing bookmarks') % counts[1])
6187 6252
6188 6253 if t:
6189 6254 # i18n: column positioning for "hg summary"
6190 6255 ui.write(_('remote: %s\n') % (', '.join(t)))
6191 6256 else:
6192 6257 # i18n: column positioning for "hg summary"
6193 6258 ui.status(_('remote: (synced)\n'))
6194 6259
6195 6260 cmdutil.summaryremotehooks(ui, repo, opts,
6196 6261 ((source, sbranch, sother, commoninc),
6197 6262 (dest, dbranch, dother, outgoing)))
6198 6263
6199 6264 @command('tag',
6200 6265 [('f', 'force', None, _('force tag')),
6201 6266 ('l', 'local', None, _('make the tag local')),
6202 6267 ('r', 'rev', '', _('revision to tag'), _('REV')),
6203 6268 ('', 'remove', None, _('remove a tag')),
6204 6269 # -l/--local is already there, commitopts cannot be used
6205 6270 ('e', 'edit', None, _('invoke editor on commit messages')),
6206 6271 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6207 6272 ] + commitopts2,
6208 6273 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6209 6274 def tag(ui, repo, name1, *names, **opts):
6210 6275 """add one or more tags for the current or given revision
6211 6276
6212 6277 Name a particular revision using <name>.
6213 6278
6214 6279 Tags are used to name particular revisions of the repository and are
6215 6280 very useful to compare different revisions, to go back to significant
6216 6281 earlier versions or to mark branch points as releases, etc. Changing
6217 6282 an existing tag is normally disallowed; use -f/--force to override.
6218 6283
6219 6284 If no revision is given, the parent of the working directory is
6220 6285 used.
6221 6286
6222 6287 To facilitate version control, distribution, and merging of tags,
6223 6288 they are stored as a file named ".hgtags" which is managed similarly
6224 6289 to other project files and can be hand-edited if necessary. This
6225 6290 also means that tagging creates a new commit. The file
6226 6291 ".hg/localtags" is used for local tags (not shared among
6227 6292 repositories).
6228 6293
6229 6294 Tag commits are usually made at the head of a branch. If the parent
6230 6295 of the working directory is not a branch head, :hg:`tag` aborts; use
6231 6296 -f/--force to force the tag commit to be based on a non-head
6232 6297 changeset.
6233 6298
6234 6299 See :hg:`help dates` for a list of formats valid for -d/--date.
6235 6300
6236 6301 Since tag names have priority over branch names during revision
6237 6302 lookup, using an existing branch name as a tag name is discouraged.
6238 6303
6239 6304 Returns 0 on success.
6240 6305 """
6241 6306 wlock = lock = None
6242 6307 try:
6243 6308 wlock = repo.wlock()
6244 6309 lock = repo.lock()
6245 6310 rev_ = "."
6246 6311 names = [t.strip() for t in (name1,) + names]
6247 6312 if len(names) != len(set(names)):
6248 6313 raise util.Abort(_('tag names must be unique'))
6249 6314 for n in names:
6250 6315 scmutil.checknewlabel(repo, n, 'tag')
6251 6316 if not n:
6252 6317 raise util.Abort(_('tag names cannot consist entirely of '
6253 6318 'whitespace'))
6254 6319 if opts.get('rev') and opts.get('remove'):
6255 6320 raise util.Abort(_("--rev and --remove are incompatible"))
6256 6321 if opts.get('rev'):
6257 6322 rev_ = opts['rev']
6258 6323 message = opts.get('message')
6259 6324 if opts.get('remove'):
6260 6325 if opts.get('local'):
6261 6326 expectedtype = 'local'
6262 6327 else:
6263 6328 expectedtype = 'global'
6264 6329
6265 6330 for n in names:
6266 6331 if not repo.tagtype(n):
6267 6332 raise util.Abort(_("tag '%s' does not exist") % n)
6268 6333 if repo.tagtype(n) != expectedtype:
6269 6334 if expectedtype == 'global':
6270 6335 raise util.Abort(_("tag '%s' is not a global tag") % n)
6271 6336 else:
6272 6337 raise util.Abort(_("tag '%s' is not a local tag") % n)
6273 6338 rev_ = 'null'
6274 6339 if not message:
6275 6340 # we don't translate commit messages
6276 6341 message = 'Removed tag %s' % ', '.join(names)
6277 6342 elif not opts.get('force'):
6278 6343 for n in names:
6279 6344 if n in repo.tags():
6280 6345 raise util.Abort(_("tag '%s' already exists "
6281 6346 "(use -f to force)") % n)
6282 6347 if not opts.get('local'):
6283 6348 p1, p2 = repo.dirstate.parents()
6284 6349 if p2 != nullid:
6285 6350 raise util.Abort(_('uncommitted merge'))
6286 6351 bheads = repo.branchheads()
6287 6352 if not opts.get('force') and bheads and p1 not in bheads:
6288 6353 raise util.Abort(_('not at a branch head (use -f to force)'))
6289 6354 r = scmutil.revsingle(repo, rev_).node()
6290 6355
6291 6356 if not message:
6292 6357 # we don't translate commit messages
6293 6358 message = ('Added tag %s for changeset %s' %
6294 6359 (', '.join(names), short(r)))
6295 6360
6296 6361 date = opts.get('date')
6297 6362 if date:
6298 6363 date = util.parsedate(date)
6299 6364
6300 6365 if opts.get('remove'):
6301 6366 editform = 'tag.remove'
6302 6367 else:
6303 6368 editform = 'tag.add'
6304 6369 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6305 6370
6306 6371 # don't allow tagging the null rev
6307 6372 if (not opts.get('remove') and
6308 6373 scmutil.revsingle(repo, rev_).rev() == nullrev):
6309 6374 raise util.Abort(_("cannot tag null revision"))
6310 6375
6311 6376 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6312 6377 editor=editor)
6313 6378 finally:
6314 6379 release(lock, wlock)
6315 6380
6316 6381 @command('tags', formatteropts, '')
6317 6382 def tags(ui, repo, **opts):
6318 6383 """list repository tags
6319 6384
6320 6385 This lists both regular and local tags. When the -v/--verbose
6321 6386 switch is used, a third column "local" is printed for local tags.
6322 6387
6323 6388 Returns 0 on success.
6324 6389 """
6325 6390
6326 6391 fm = ui.formatter('tags', opts)
6327 6392 hexfunc = fm.hexfunc
6328 6393 tagtype = ""
6329 6394
6330 6395 for t, n in reversed(repo.tagslist()):
6331 6396 hn = hexfunc(n)
6332 6397 label = 'tags.normal'
6333 6398 tagtype = ''
6334 6399 if repo.tagtype(t) == 'local':
6335 6400 label = 'tags.local'
6336 6401 tagtype = 'local'
6337 6402
6338 6403 fm.startitem()
6339 6404 fm.write('tag', '%s', t, label=label)
6340 6405 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6341 6406 fm.condwrite(not ui.quiet, 'rev node', fmt,
6342 6407 repo.changelog.rev(n), hn, label=label)
6343 6408 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6344 6409 tagtype, label=label)
6345 6410 fm.plain('\n')
6346 6411 fm.end()
6347 6412
6348 6413 @command('tip',
6349 6414 [('p', 'patch', None, _('show patch')),
6350 6415 ('g', 'git', None, _('use git extended diff format')),
6351 6416 ] + templateopts,
6352 6417 _('[-p] [-g]'))
6353 6418 def tip(ui, repo, **opts):
6354 6419 """show the tip revision (DEPRECATED)
6355 6420
6356 6421 The tip revision (usually just called the tip) is the changeset
6357 6422 most recently added to the repository (and therefore the most
6358 6423 recently changed head).
6359 6424
6360 6425 If you have just made a commit, that commit will be the tip. If
6361 6426 you have just pulled changes from another repository, the tip of
6362 6427 that repository becomes the current tip. The "tip" tag is special
6363 6428 and cannot be renamed or assigned to a different changeset.
6364 6429
6365 6430 This command is deprecated, please use :hg:`heads` instead.
6366 6431
6367 6432 Returns 0 on success.
6368 6433 """
6369 6434 displayer = cmdutil.show_changeset(ui, repo, opts)
6370 6435 displayer.show(repo['tip'])
6371 6436 displayer.close()
6372 6437
6373 6438 @command('unbundle',
6374 6439 [('u', 'update', None,
6375 6440 _('update to new branch head if changesets were unbundled'))],
6376 6441 _('[-u] FILE...'))
6377 6442 def unbundle(ui, repo, fname1, *fnames, **opts):
6378 6443 """apply one or more changegroup files
6379 6444
6380 6445 Apply one or more compressed changegroup files generated by the
6381 6446 bundle command.
6382 6447
6383 6448 Returns 0 on success, 1 if an update has unresolved files.
6384 6449 """
6385 6450 fnames = (fname1,) + fnames
6386 6451
6387 6452 lock = repo.lock()
6388 6453 try:
6389 6454 for fname in fnames:
6390 6455 f = hg.openpath(ui, fname)
6391 6456 gen = exchange.readbundle(ui, f, fname)
6392 6457 if isinstance(gen, bundle2.unbundle20):
6393 6458 tr = repo.transaction('unbundle')
6394 6459 try:
6395 6460 op = bundle2.processbundle(repo, gen, lambda: tr)
6396 6461 tr.close()
6397 6462 except error.BundleUnknownFeatureError as exc:
6398 6463 raise util.Abort(_('%s: unknown bundle feature, %s')
6399 6464 % (fname, exc),
6400 6465 hint=_("see https://mercurial-scm.org/"
6401 6466 "wiki/BundleFeature for more "
6402 6467 "information"))
6403 6468 finally:
6404 6469 if tr:
6405 6470 tr.release()
6406 6471 changes = [r.get('result', 0)
6407 6472 for r in op.records['changegroup']]
6408 6473 modheads = changegroup.combineresults(changes)
6409 6474 else:
6410 6475 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
6411 6476 'bundle:' + fname)
6412 6477 finally:
6413 6478 lock.release()
6414 6479
6415 6480 return postincoming(ui, repo, modheads, opts.get('update'), None)
6416 6481
6417 6482 @command('^update|up|checkout|co',
6418 6483 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6419 6484 ('c', 'check', None,
6420 6485 _('update across branches if no uncommitted changes')),
6421 6486 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6422 6487 ('r', 'rev', '', _('revision'), _('REV'))
6423 6488 ] + mergetoolopts,
6424 6489 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6425 6490 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6426 6491 tool=None):
6427 6492 """update working directory (or switch revisions)
6428 6493
6429 6494 Update the repository's working directory to the specified
6430 6495 changeset. If no changeset is specified, update to the tip of the
6431 6496 current named branch and move the active bookmark (see :hg:`help
6432 6497 bookmarks`).
6433 6498
6434 6499 Update sets the working directory's parent revision to the specified
6435 6500 changeset (see :hg:`help parents`).
6436 6501
6437 6502 If the changeset is not a descendant or ancestor of the working
6438 6503 directory's parent, the update is aborted. With the -c/--check
6439 6504 option, the working directory is checked for uncommitted changes; if
6440 6505 none are found, the working directory is updated to the specified
6441 6506 changeset.
6442 6507
6443 6508 .. container:: verbose
6444 6509
6445 6510 The following rules apply when the working directory contains
6446 6511 uncommitted changes:
6447 6512
6448 6513 1. If neither -c/--check nor -C/--clean is specified, and if
6449 6514 the requested changeset is an ancestor or descendant of
6450 6515 the working directory's parent, the uncommitted changes
6451 6516 are merged into the requested changeset and the merged
6452 6517 result is left uncommitted. If the requested changeset is
6453 6518 not an ancestor or descendant (that is, it is on another
6454 6519 branch), the update is aborted and the uncommitted changes
6455 6520 are preserved.
6456 6521
6457 6522 2. With the -c/--check option, the update is aborted and the
6458 6523 uncommitted changes are preserved.
6459 6524
6460 6525 3. With the -C/--clean option, uncommitted changes are discarded and
6461 6526 the working directory is updated to the requested changeset.
6462 6527
6463 6528 To cancel an uncommitted merge (and lose your changes), use
6464 6529 :hg:`update --clean .`.
6465 6530
6466 6531 Use null as the changeset to remove the working directory (like
6467 6532 :hg:`clone -U`).
6468 6533
6469 6534 If you want to revert just one file to an older revision, use
6470 6535 :hg:`revert [-r REV] NAME`.
6471 6536
6472 6537 See :hg:`help dates` for a list of formats valid for -d/--date.
6473 6538
6474 6539 Returns 0 on success, 1 if there are unresolved files.
6475 6540 """
6476 6541 if rev and node:
6477 6542 raise util.Abort(_("please specify just one revision"))
6478 6543
6479 6544 if rev is None or rev == '':
6480 6545 rev = node
6481 6546
6482 6547 wlock = repo.wlock()
6483 6548 try:
6484 6549 cmdutil.clearunfinished(repo)
6485 6550
6486 6551 if date:
6487 6552 if rev is not None:
6488 6553 raise util.Abort(_("you can't specify a revision and a date"))
6489 6554 rev = cmdutil.finddate(ui, repo, date)
6490 6555
6491 6556 # with no argument, we also move the active bookmark, if any
6492 6557 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
6493 6558
6494 6559 # if we defined a bookmark, we have to remember the original name
6495 6560 brev = rev
6496 6561 rev = scmutil.revsingle(repo, rev, rev).rev()
6497 6562
6498 6563 if check and clean:
6499 6564 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
6500 6565
6501 6566 if check:
6502 6567 cmdutil.bailifchanged(repo, merge=False)
6503 6568 if rev is None:
6504 6569 rev = repo[repo[None].branch()].rev()
6505 6570
6506 6571 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6507 6572
6508 6573 if clean:
6509 6574 ret = hg.clean(repo, rev)
6510 6575 else:
6511 6576 ret = hg.update(repo, rev)
6512 6577
6513 6578 if not ret and movemarkfrom:
6514 6579 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6515 6580 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6516 6581 else:
6517 6582 # this can happen with a non-linear update
6518 6583 ui.status(_("(leaving bookmark %s)\n") %
6519 6584 repo._activebookmark)
6520 6585 bookmarks.deactivate(repo)
6521 6586 elif brev in repo._bookmarks:
6522 6587 bookmarks.activate(repo, brev)
6523 6588 ui.status(_("(activating bookmark %s)\n") % brev)
6524 6589 elif brev:
6525 6590 if repo._activebookmark:
6526 6591 ui.status(_("(leaving bookmark %s)\n") %
6527 6592 repo._activebookmark)
6528 6593 bookmarks.deactivate(repo)
6529 6594 finally:
6530 6595 wlock.release()
6531 6596
6532 6597 return ret
6533 6598
6534 6599 @command('verify', [])
6535 6600 def verify(ui, repo):
6536 6601 """verify the integrity of the repository
6537 6602
6538 6603 Verify the integrity of the current repository.
6539 6604
6540 6605 This will perform an extensive check of the repository's
6541 6606 integrity, validating the hashes and checksums of each entry in
6542 6607 the changelog, manifest, and tracked files, as well as the
6543 6608 integrity of their crosslinks and indices.
6544 6609
6545 6610 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6546 6611 for more information about recovery from corruption of the
6547 6612 repository.
6548 6613
6549 6614 Returns 0 on success, 1 if errors are encountered.
6550 6615 """
6551 6616 return hg.verify(repo)
6552 6617
6553 6618 @command('version', [], norepo=True)
6554 6619 def version_(ui):
6555 6620 """output version and copyright information"""
6556 6621 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6557 6622 % util.version())
6558 6623 ui.status(_(
6559 6624 "(see https://mercurial-scm.org for more information)\n"
6560 6625 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6561 6626 "This is free software; see the source for copying conditions. "
6562 6627 "There is NO\nwarranty; "
6563 6628 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6564 6629 ))
6565 6630
6566 6631 ui.note(_("\nEnabled extensions:\n\n"))
6567 6632 if ui.verbose:
6568 6633 # format names and versions into columns
6569 6634 names = []
6570 6635 vers = []
6571 6636 for name, module in extensions.extensions():
6572 6637 names.append(name)
6573 6638 vers.append(extensions.moduleversion(module))
6574 6639 if names:
6575 6640 maxnamelen = max(len(n) for n in names)
6576 6641 for i, name in enumerate(names):
6577 6642 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
@@ -1,635 +1,652 b''
1 1 $ hg init basic
2 2 $ cd basic
3 3
4 4 should complain
5 5
6 6 $ hg backout
7 7 abort: please specify a revision to backout
8 8 [255]
9 9 $ hg backout -r 0 0
10 10 abort: please specify just one revision
11 11 [255]
12 12
13 13 basic operation
14 14 (this also tests that editor is invoked if the commit message is not
15 15 specified explicitly)
16 16
17 17 $ echo a > a
18 18 $ hg commit -d '0 0' -A -m a
19 19 adding a
20 20 $ echo b >> a
21 21 $ hg commit -d '1 0' -m b
22 22
23 23 $ hg status --rev tip --rev "tip^1"
24 24 M a
25 25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
26 26 reverting a
27 27 Backed out changeset a820f4f40a57
28 28
29 29
30 30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
31 31 HG: Leave message empty to abort commit.
32 32 HG: --
33 33 HG: user: test
34 34 HG: branch 'default'
35 35 HG: changed a
36 36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
37 37 $ cat a
38 38 a
39 39 $ hg summary
40 40 parent: 2:2929462c3dff tip
41 41 Backed out changeset a820f4f40a57
42 42 branch: default
43 43 commit: (clean)
44 44 update: (current)
45 45 phases: 3 draft
46 46
47 47 commit option
48 48
49 49 $ cd ..
50 50 $ hg init commit
51 51 $ cd commit
52 52
53 53 $ echo tomatoes > a
54 54 $ hg add a
55 55 $ hg commit -d '0 0' -m tomatoes
56 56
57 57 $ echo chair > b
58 58 $ hg add b
59 59 $ hg commit -d '1 0' -m chair
60 60
61 61 $ echo grapes >> a
62 62 $ hg commit -d '2 0' -m grapes
63 63
64 64 $ hg backout --commit -d '4 0' 1 --tool=:fail
65 65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
67 67 $ hg summary
68 68 parent: 3:1c2161e97c0a tip
69 69 Backed out changeset 22cb4f70d813
70 70 branch: default
71 71 commit: (clean)
72 72 update: (current)
73 73 phases: 4 draft
74 74
75 75 $ echo ypples > a
76 76 $ hg commit -d '5 0' -m ypples
77 77
78 78 $ hg backout --commit -d '6 0' 2 --tool=:fail
79 79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
80 80 use 'hg resolve' to retry unresolved file merges
81 81 [1]
82 82 $ hg summary
83 83 parent: 4:ed99997b793d tip
84 84 ypples
85 85 branch: default
86 86 commit: 1 unresolved (clean)
87 87 update: (current)
88 88 phases: 5 draft
89 89
90 90 file that was removed is recreated
91 91 (this also tests that editor is not invoked if the commit message is
92 92 specified explicitly)
93 93
94 94 $ cd ..
95 95 $ hg init remove
96 96 $ cd remove
97 97
98 98 $ echo content > a
99 99 $ hg commit -d '0 0' -A -m a
100 100 adding a
101 101
102 102 $ hg rm a
103 103 $ hg commit -d '1 0' -m b
104 104
105 105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
106 106 adding a
107 107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
108 108 $ cat a
109 109 content
110 110 $ hg summary
111 111 parent: 2:de31bdc76c0d tip
112 112 Backed out changeset 76862dcce372
113 113 branch: default
114 114 commit: (clean)
115 115 update: (current)
116 116 phases: 3 draft
117 117
118 118 backout of backout is as if nothing happened
119 119
120 120 $ hg backout -d '3 0' --merge tip --tool=true
121 121 removing a
122 122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
123 123 $ test -f a
124 124 [1]
125 125 $ hg summary
126 126 parent: 3:7f6d0f120113 tip
127 127 Backed out changeset de31bdc76c0d
128 128 branch: default
129 129 commit: (clean)
130 130 update: (current)
131 131 phases: 4 draft
132 132
133 133 Test that 'hg rollback' restores dirstate just before opening
134 134 transaction: in-memory dirstate changes should be written into
135 135 '.hg/journal.dirstate' as expected.
136 136
137 137 $ echo 'removed soon' > b
138 138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
139 139 adding b
140 140 $ echo 'newly added' > c
141 141 $ hg add c
142 142 $ hg remove b
143 143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
144 144 $ touch -t 200001010000 c
145 145 $ hg status -A
146 146 C c
147 147 $ hg debugstate --nodates
148 148 n 644 12 set c
149 149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
150 150 adding b
151 151 removing c
152 152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
153 153 $ hg rollback -q
154 154 $ hg status -A
155 155 A b
156 156 R c
157 157 $ hg debugstate --nodates
158 158 a 0 -1 unset b
159 159 r 0 0 set c
160 160
161 161 across branch
162 162
163 163 $ cd ..
164 164 $ hg init branch
165 165 $ cd branch
166 166 $ echo a > a
167 167 $ hg ci -Am0
168 168 adding a
169 169 $ echo b > b
170 170 $ hg ci -Am1
171 171 adding b
172 172 $ hg co -C 0
173 173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
174 174 $ hg summary
175 175 parent: 0:f7b1eb17ad24
176 176 0
177 177 branch: default
178 178 commit: (clean)
179 179 update: 1 new changesets (update)
180 180 phases: 2 draft
181 181
182 182 should fail
183 183
184 184 $ hg backout 1
185 185 abort: cannot backout change that is not an ancestor
186 186 [255]
187 187 $ echo c > c
188 188 $ hg ci -Am2
189 189 adding c
190 190 created new head
191 191 $ hg summary
192 192 parent: 2:db815d6d32e6 tip
193 193 2
194 194 branch: default
195 195 commit: (clean)
196 196 update: 1 new changesets, 2 branch heads (merge)
197 197 phases: 3 draft
198 198
199 199 should fail
200 200
201 201 $ hg backout 1
202 202 abort: cannot backout change that is not an ancestor
203 203 [255]
204 204 $ hg summary
205 205 parent: 2:db815d6d32e6 tip
206 206 2
207 207 branch: default
208 208 commit: (clean)
209 209 update: 1 new changesets, 2 branch heads (merge)
210 210 phases: 3 draft
211 211
212 212 backout with merge
213 213
214 214 $ cd ..
215 215 $ hg init merge
216 216 $ cd merge
217 217
218 218 $ echo line 1 > a
219 219 $ echo line 2 >> a
220 220 $ hg commit -d '0 0' -A -m a
221 221 adding a
222 222 $ hg summary
223 223 parent: 0:59395513a13a tip
224 224 a
225 225 branch: default
226 226 commit: (clean)
227 227 update: (current)
228 228 phases: 1 draft
229 229
230 230 remove line 1
231 231
232 232 $ echo line 2 > a
233 233 $ hg commit -d '1 0' -m b
234 234
235 235 $ echo line 3 >> a
236 236 $ hg commit -d '2 0' -m c
237 237
238 238 $ hg backout --merge -d '3 0' 1 --tool=true
239 239 reverting a
240 240 created new head
241 241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
242 242 merging with changeset 3:26b8ccb9ad91
243 243 merging a
244 244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
245 245 (branch merge, don't forget to commit)
246 246 $ hg commit -d '4 0' -m d
247 247 $ hg summary
248 248 parent: 4:c7df5e0b9c09 tip
249 249 d
250 250 branch: default
251 251 commit: (clean)
252 252 update: (current)
253 253 phases: 5 draft
254 254
255 255 check line 1 is back
256 256
257 257 $ cat a
258 258 line 1
259 259 line 2
260 260 line 3
261 261
262 262 $ cd ..
263 263
264 264 backout should not back out subsequent changesets
265 265
266 266 $ hg init onecs
267 267 $ cd onecs
268 268 $ echo 1 > a
269 269 $ hg commit -d '0 0' -A -m a
270 270 adding a
271 271 $ echo 2 >> a
272 272 $ hg commit -d '1 0' -m b
273 273 $ echo 1 > b
274 274 $ hg commit -d '2 0' -A -m c
275 275 adding b
276 276 $ hg summary
277 277 parent: 2:882396649954 tip
278 278 c
279 279 branch: default
280 280 commit: (clean)
281 281 update: (current)
282 282 phases: 3 draft
283 283
284 284 without --merge
285 285 $ hg backout -d '3 0' 1 --tool=true
286 286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 287 changeset 22bca4c721e5 backed out, don't forget to commit.
288 288 $ hg locate b
289 289 b
290 290 $ hg update -C tip
291 291 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 292 $ hg locate b
293 293 b
294 294 $ hg summary
295 295 parent: 2:882396649954 tip
296 296 c
297 297 branch: default
298 298 commit: (clean)
299 299 update: (current)
300 300 phases: 3 draft
301 301
302 302 with --merge
303 303 $ hg backout --merge -d '3 0' 1 --tool=true
304 304 reverting a
305 305 created new head
306 306 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
307 307 merging with changeset 3:3202beb76721
308 308 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
309 309 (branch merge, don't forget to commit)
310 310 $ hg locate b
311 311 b
312 312 $ hg update -C tip
313 313 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
314 314 $ hg locate b
315 315 [1]
316 316
317 317 $ cd ..
318 318 $ hg init m
319 319 $ cd m
320 320 $ echo a > a
321 321 $ hg commit -d '0 0' -A -m a
322 322 adding a
323 323 $ echo b > b
324 324 $ hg commit -d '1 0' -A -m b
325 325 adding b
326 326 $ echo c > c
327 327 $ hg commit -d '2 0' -A -m b
328 328 adding c
329 329 $ hg update 1
330 330 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
331 331 $ echo d > d
332 332 $ hg commit -d '3 0' -A -m c
333 333 adding d
334 334 created new head
335 335 $ hg merge 2
336 336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 337 (branch merge, don't forget to commit)
338 338 $ hg commit -d '4 0' -A -m d
339 339 $ hg summary
340 340 parent: 4:b2f3bb92043e tip
341 341 d
342 342 branch: default
343 343 commit: (clean)
344 344 update: (current)
345 345 phases: 5 draft
346 346
347 347 backout of merge should fail
348 348
349 349 $ hg backout 4
350 350 abort: cannot backout a merge changeset
351 351 [255]
352 352
353 353 backout of merge with bad parent should fail
354 354
355 355 $ hg backout --parent 0 4
356 356 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
357 357 [255]
358 358
359 359 backout of non-merge with parent should fail
360 360
361 361 $ hg backout --parent 0 3
362 362 abort: cannot use --parent on non-merge changeset
363 363 [255]
364 364
365 365 backout with valid parent should be ok
366 366
367 367 $ hg backout -d '5 0' --parent 2 4 --tool=true
368 368 removing d
369 369 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
370 370 $ hg summary
371 371 parent: 5:10e5328c8435 tip
372 372 Backed out changeset b2f3bb92043e
373 373 branch: default
374 374 commit: (clean)
375 375 update: (current)
376 376 phases: 6 draft
377 377
378 378 $ hg rollback
379 379 repository tip rolled back to revision 4 (undo commit)
380 380 working directory now based on revision 4
381 381 $ hg update -C
382 382 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 383 $ hg summary
384 384 parent: 4:b2f3bb92043e tip
385 385 d
386 386 branch: default
387 387 commit: (clean)
388 388 update: (current)
389 389 phases: 5 draft
390 390
391 391 $ hg backout -d '6 0' --parent 3 4 --tool=true
392 392 removing c
393 393 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
394 394 $ hg summary
395 395 parent: 5:033590168430 tip
396 396 Backed out changeset b2f3bb92043e
397 397 branch: default
398 398 commit: (clean)
399 399 update: (current)
400 400 phases: 6 draft
401 401
402 402 $ cd ..
403 403
404 404 named branches
405 405
406 406 $ hg init named_branches
407 407 $ cd named_branches
408 408
409 409 $ echo default > default
410 410 $ hg ci -d '0 0' -Am default
411 411 adding default
412 412 $ hg branch branch1
413 413 marked working directory as branch branch1
414 414 (branches are permanent and global, did you want a bookmark?)
415 415 $ echo branch1 > file1
416 416 $ hg ci -d '1 0' -Am file1
417 417 adding file1
418 418 $ hg branch branch2
419 419 marked working directory as branch branch2
420 420 $ echo branch2 > file2
421 421 $ hg ci -d '2 0' -Am file2
422 422 adding file2
423 423
424 424 without --merge
425 425 $ hg backout -r 1 --tool=true
426 426 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
427 427 changeset bf1602f437f3 backed out, don't forget to commit.
428 428 $ hg branch
429 429 branch2
430 430 $ hg status -A
431 431 R file1
432 432 C default
433 433 C file2
434 434 $ hg summary
435 435 parent: 2:45bbcd363bf0 tip
436 436 file2
437 437 branch: branch2
438 438 commit: 1 removed
439 439 update: (current)
440 440 phases: 3 draft
441 441
442 442 with --merge
443 443 (this also tests that editor is invoked if '--edit' is specified
444 444 explicitly regardless of '--message')
445 445
446 446 $ hg update -qC
447 447 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
448 448 removing file1
449 449 backout on branch1
450 450
451 451
452 452 HG: Enter commit message. Lines beginning with 'HG:' are removed.
453 453 HG: Leave message empty to abort commit.
454 454 HG: --
455 455 HG: user: test
456 456 HG: branch 'branch2'
457 457 HG: removed file1
458 458 created new head
459 459 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
460 460 merging with changeset 3:d4e8f6db59fb
461 461 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
462 462 (branch merge, don't forget to commit)
463 463 $ hg summary
464 464 parent: 2:45bbcd363bf0
465 465 file2
466 466 parent: 3:d4e8f6db59fb tip
467 467 backout on branch1
468 468 branch: branch2
469 469 commit: 1 removed (merge)
470 470 update: (current)
471 471 phases: 4 draft
472 472 $ hg update -q -C 2
473 473
474 474 on branch2 with branch1 not merged, so file1 should still exist:
475 475
476 476 $ hg id
477 477 45bbcd363bf0 (branch2)
478 478 $ hg st -A
479 479 C default
480 480 C file1
481 481 C file2
482 482 $ hg summary
483 483 parent: 2:45bbcd363bf0
484 484 file2
485 485 branch: branch2
486 486 commit: (clean)
487 487 update: 1 new changesets, 2 branch heads (merge)
488 488 phases: 4 draft
489 489
490 490 on branch2 with branch1 merged, so file1 should be gone:
491 491
492 492 $ hg merge
493 493 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
494 494 (branch merge, don't forget to commit)
495 495 $ hg ci -d '4 0' -m 'merge backout of branch1'
496 496 $ hg id
497 497 22149cdde76d (branch2) tip
498 498 $ hg st -A
499 499 C default
500 500 C file2
501 501 $ hg summary
502 502 parent: 4:22149cdde76d tip
503 503 merge backout of branch1
504 504 branch: branch2
505 505 commit: (clean)
506 506 update: (current)
507 507 phases: 5 draft
508 508
509 509 on branch1, so no file1 and file2:
510 510
511 511 $ hg co -C branch1
512 512 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
513 513 $ hg id
514 514 bf1602f437f3 (branch1)
515 515 $ hg st -A
516 516 C default
517 517 C file1
518 518 $ hg summary
519 519 parent: 1:bf1602f437f3
520 520 file1
521 521 branch: branch1
522 522 commit: (clean)
523 523 update: (current)
524 524 phases: 5 draft
525 525
526 526 $ cd ..
527 527
528 528 backout of empty changeset (issue4190)
529 529
530 530 $ hg init emptycommit
531 531 $ cd emptycommit
532 532
533 533 $ touch file1
534 534 $ hg ci -Aqm file1
535 535 $ hg branch -q branch1
536 536 $ hg ci -qm branch1
537 537 $ hg backout -v 1
538 538 resolving manifests
539 539 nothing changed
540 540 [1]
541 541
542 542 $ cd ..
543 543
544 544
545 545 Test usage of `hg resolve` in case of conflict
546 546 (issue4163)
547 547
548 548 $ hg init issue4163
549 549 $ cd issue4163
550 550 $ touch foo
551 551 $ hg add foo
552 552 $ cat > foo << EOF
553 553 > one
554 554 > two
555 555 > three
556 556 > four
557 557 > five
558 558 > six
559 559 > seven
560 560 > height
561 561 > nine
562 562 > ten
563 563 > EOF
564 564 $ hg ci -m 'initial'
565 565 $ cat > foo << EOF
566 566 > one
567 567 > two
568 568 > THREE
569 569 > four
570 570 > five
571 571 > six
572 572 > seven
573 573 > height
574 574 > nine
575 575 > ten
576 576 > EOF
577 577 $ hg ci -m 'capital three'
578 578 $ cat > foo << EOF
579 579 > one
580 580 > two
581 581 > THREE
582 582 > four
583 583 > five
584 584 > six
585 585 > seven
586 586 > height
587 587 > nine
588 588 > TEN
589 589 > EOF
590 590 $ hg ci -m 'capital ten'
591 591 $ hg backout -r 'desc("capital three")' --tool internal:fail
592 592 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
593 593 use 'hg resolve' to retry unresolved file merges
594 594 [1]
595 595 $ hg status
596 $ hg debugmergestate
597 * version 2 records
598 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
599 other: a30dd8addae3ce71b8667868478542bc417439e6
600 file: foo (state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
601 local path: foo (flags "")
602 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
603 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
604 $ mv .hg/merge/state2 .hg/merge/state2-moved
605 $ hg debugmergestate
606 * version 1 records
607 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
608 file: foo (state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
609 local path: foo (flags "")
610 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
611 other path: foo (node not stored in v1 format)
612 $ mv .hg/merge/state2-moved .hg/merge/state2
596 613 $ hg resolve -l # still unresolved
597 614 U foo
598 615 $ hg summary
599 616 parent: 2:b71750c4b0fd tip
600 617 capital ten
601 618 branch: default
602 619 commit: 1 unresolved (clean)
603 620 update: (current)
604 621 phases: 3 draft
605 622 $ hg resolve --all --debug
606 623 picked tool 'internal:merge' for foo (binary False symlink False)
607 624 merging foo
608 625 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
609 626 premerge successful
610 627 (no more unresolved files)
611 628 $ hg status
612 629 M foo
613 630 ? foo.orig
614 631 $ hg resolve -l
615 632 R foo
616 633 $ hg summary
617 634 parent: 2:b71750c4b0fd tip
618 635 capital ten
619 636 branch: default
620 637 commit: 1 modified, 1 unknown
621 638 update: (current)
622 639 phases: 3 draft
623 640 $ cat foo
624 641 one
625 642 two
626 643 three
627 644 four
628 645 five
629 646 six
630 647 seven
631 648 height
632 649 nine
633 650 TEN
634 651
635 652
@@ -1,342 +1,344 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 72 debugbuilddag
73 73 debugbundle
74 74 debugcheckstate
75 75 debugcommands
76 76 debugcomplete
77 77 debugconfig
78 78 debugdag
79 79 debugdata
80 80 debugdate
81 81 debugdirstate
82 82 debugdiscovery
83 83 debugextensions
84 84 debugfileset
85 85 debugfsinfo
86 86 debuggetbundle
87 87 debugignore
88 88 debugindex
89 89 debugindexdot
90 90 debuginstall
91 91 debugknown
92 92 debuglabelcomplete
93 93 debuglocks
94 debugmergestate
94 95 debugnamecomplete
95 96 debugobsolete
96 97 debugpathcomplete
97 98 debugpushkey
98 99 debugpvec
99 100 debugrebuilddirstate
100 101 debugrebuildfncache
101 102 debugrename
102 103 debugrevlog
103 104 debugrevspec
104 105 debugsetparents
105 106 debugsub
106 107 debugsuccessorssets
107 108 debugwalk
108 109 debugwireargs
109 110
110 111 Do not show the alias of a debug command if there are other candidates
111 112 (this should hide rawcommit)
112 113 $ hg debugcomplete r
113 114 recover
114 115 remove
115 116 rename
116 117 resolve
117 118 revert
118 119 rollback
119 120 root
120 121 Show the alias of a debug command if there are no other candidates
121 122 $ hg debugcomplete rawc
122 123
123 124
124 125 Show the global options
125 126 $ hg debugcomplete --options | sort
126 127 --config
127 128 --cwd
128 129 --debug
129 130 --debugger
130 131 --encoding
131 132 --encodingmode
132 133 --help
133 134 --hidden
134 135 --noninteractive
135 136 --profile
136 137 --quiet
137 138 --repository
138 139 --time
139 140 --traceback
140 141 --verbose
141 142 --version
142 143 -R
143 144 -h
144 145 -q
145 146 -v
146 147 -y
147 148
148 149 Show the options for the "serve" command
149 150 $ hg debugcomplete --options serve | sort
150 151 --accesslog
151 152 --address
152 153 --certificate
153 154 --cmdserver
154 155 --config
155 156 --cwd
156 157 --daemon
157 158 --daemon-pipefds
158 159 --debug
159 160 --debugger
160 161 --encoding
161 162 --encodingmode
162 163 --errorlog
163 164 --help
164 165 --hidden
165 166 --ipv6
166 167 --name
167 168 --noninteractive
168 169 --pid-file
169 170 --port
170 171 --prefix
171 172 --profile
172 173 --quiet
173 174 --repository
174 175 --stdio
175 176 --style
176 177 --templates
177 178 --time
178 179 --traceback
179 180 --verbose
180 181 --version
181 182 --web-conf
182 183 -6
183 184 -A
184 185 -E
185 186 -R
186 187 -a
187 188 -d
188 189 -h
189 190 -n
190 191 -p
191 192 -q
192 193 -t
193 194 -v
194 195 -y
195 196
196 197 Show an error if we use --options with an ambiguous abbreviation
197 198 $ hg debugcomplete --options s
198 199 hg: command 's' is ambiguous:
199 200 serve showconfig status summary
200 201 [255]
201 202
202 203 Show all commands + options
203 204 $ hg debugcommands
204 205 add: include, exclude, subrepos, dry-run
205 206 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
206 207 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
207 208 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
208 209 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
209 210 export: output, switch-parent, rev, text, git, nodates
210 211 forget: include, exclude
211 212 init: ssh, remotecmd, insecure
212 213 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
213 214 merge: force, rev, preview, tool
214 215 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
215 216 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
216 217 remove: after, force, subrepos, include, exclude
217 218 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
218 219 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
219 220 summary: remote
220 221 update: clean, check, date, rev, tool
221 222 addremove: similarity, subrepos, include, exclude, dry-run
222 223 archive: no-decode, prefix, rev, type, subrepos, include, exclude
223 224 backout: merge, commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
224 225 bisect: reset, good, bad, skip, extend, command, noupdate
225 226 bookmarks: force, rev, delete, rename, inactive, template
226 227 branch: force, clean
227 228 branches: active, closed, template
228 229 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
229 230 cat: output, rev, decode, include, exclude
230 231 config: untrusted, edit, local, global
231 232 copy: after, force, include, exclude, dry-run
232 233 debugancestor:
233 234 debugbuilddag: mergeable-file, overwritten-file, new-file
234 235 debugbundle: all
235 236 debugcheckstate:
236 237 debugcommands:
237 238 debugcomplete: options
238 239 debugdag: tags, branches, dots, spaces
239 240 debugdata: changelog, manifest, dir
240 241 debugdate: extended
241 242 debugdirstate: nodates, datesort
242 243 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
243 244 debugextensions: template
244 245 debugfileset: rev
245 246 debugfsinfo:
246 247 debuggetbundle: head, common, type
247 248 debugignore:
248 249 debugindex: changelog, manifest, dir, format
249 250 debugindexdot:
250 251 debuginstall:
251 252 debugknown:
252 253 debuglabelcomplete:
253 254 debuglocks: force-lock, force-wlock
255 debugmergestate:
254 256 debugnamecomplete:
255 257 debugobsolete: flags, record-parents, rev, date, user
256 258 debugpathcomplete: full, normal, added, removed
257 259 debugpushkey:
258 260 debugpvec:
259 261 debugrebuilddirstate: rev, minimal
260 262 debugrebuildfncache:
261 263 debugrename: rev
262 264 debugrevlog: changelog, manifest, dir, dump
263 265 debugrevspec: optimize
264 266 debugsetparents:
265 267 debugsub: rev
266 268 debugsuccessorssets:
267 269 debugwalk: include, exclude
268 270 debugwireargs: three, four, five, ssh, remotecmd, insecure
269 271 files: rev, print0, include, exclude, template, subrepos
270 272 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
271 273 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
272 274 heads: rev, topo, active, closed, style, template
273 275 help: extension, command, keyword
274 276 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
275 277 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
276 278 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
277 279 locate: rev, print0, fullpath, include, exclude
278 280 manifest: rev, all, template
279 281 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
280 282 parents: rev, style, template
281 283 paths:
282 284 phase: public, draft, secret, force, rev
283 285 recover:
284 286 rename: after, force, include, exclude, dry-run
285 287 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
286 288 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
287 289 rollback: dry-run, force
288 290 root:
289 291 tag: force, local, rev, remove, edit, message, date, user
290 292 tags: template
291 293 tip: patch, git, style, template
292 294 unbundle: update
293 295 verify:
294 296 version:
295 297
296 298 $ hg init a
297 299 $ cd a
298 300 $ echo fee > fee
299 301 $ hg ci -q -Amfee
300 302 $ hg tag fee
301 303 $ mkdir fie
302 304 $ echo dead > fie/dead
303 305 $ echo live > fie/live
304 306 $ hg bookmark fo
305 307 $ hg branch -q fie
306 308 $ hg ci -q -Amfie
307 309 $ echo fo > fo
308 310 $ hg branch -qf default
309 311 $ hg ci -q -Amfo
310 312 $ echo Fum > Fum
311 313 $ hg ci -q -AmFum
312 314 $ hg bookmark Fum
313 315
314 316 Test debugpathcomplete
315 317
316 318 $ hg debugpathcomplete f
317 319 fee
318 320 fie
319 321 fo
320 322 $ hg debugpathcomplete -f f
321 323 fee
322 324 fie/dead
323 325 fie/live
324 326 fo
325 327
326 328 $ hg rm Fum
327 329 $ hg debugpathcomplete -r F
328 330 Fum
329 331
330 332 Test debugnamecomplete
331 333
332 334 $ hg debugnamecomplete
333 335 Fum
334 336 default
335 337 fee
336 338 fie
337 339 fo
338 340 tip
339 341 $ hg debugnamecomplete f
340 342 fee
341 343 fie
342 344 fo
@@ -1,2375 +1,2377 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 color colorize output from some commands
253 253 convert import revisions from foreign VCS repositories into
254 254 Mercurial
255 255 eol automatically manage newlines in repository files
256 256 extdiff command to allow external programs to compare revisions
257 257 factotum http authentication with factotum
258 258 gpg commands to sign and verify changesets
259 259 hgcia hooks for integrating with the CIA.vc notification service
260 260 hgk browse the repository in a graphical way
261 261 highlight syntax highlighting for hgweb (requires Pygments)
262 262 histedit interactive history editing
263 263 keyword expand keywords in tracked files
264 264 largefiles track large binary files
265 265 mq manage a stack of patches
266 266 notify hooks for sending email push notifications
267 267 pager browse command output with an external pager
268 268 patchbomb command to send changesets as (a series of) patch emails
269 269 purge command to delete untracked files from the working
270 270 directory
271 271 record commands to interactively select changes for
272 272 commit/qrefresh
273 273 relink recreates hardlinks between repository clones
274 274 schemes extend schemes with shortcuts to repository swarms
275 275 share share a common history between several working directories
276 276 shelve save and restore changes to the working directory
277 277 strip strip changesets and their descendants from history
278 278 transplant command to transplant changesets from another branch
279 279 win32mbcs allow the use of MBCS paths with problematic encodings
280 280 zeroconf discover and advertise repositories on the local network
281 281
282 282 Verify that extension keywords appear in help templates
283 283
284 284 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
285 285
286 286 Test short command list with verbose option
287 287
288 288 $ hg -v help shortlist
289 289 Mercurial Distributed SCM
290 290
291 291 basic commands:
292 292
293 293 add add the specified files on the next commit
294 294 annotate, blame
295 295 show changeset information by line for each file
296 296 clone make a copy of an existing repository
297 297 commit, ci commit the specified files or all outstanding changes
298 298 diff diff repository (or selected files)
299 299 export dump the header and diffs for one or more changesets
300 300 forget forget the specified files on the next commit
301 301 init create a new repository in the given directory
302 302 log, history show revision history of entire repository or files
303 303 merge merge another revision into working directory
304 304 pull pull changes from the specified source
305 305 push push changes to the specified destination
306 306 remove, rm remove the specified files on the next commit
307 307 serve start stand-alone webserver
308 308 status, st show changed files in the working directory
309 309 summary, sum summarize working directory state
310 310 update, up, checkout, co
311 311 update working directory (or switch revisions)
312 312
313 313 global options ([+] can be repeated):
314 314
315 315 -R --repository REPO repository root directory or name of overlay bundle
316 316 file
317 317 --cwd DIR change working directory
318 318 -y --noninteractive do not prompt, automatically pick the first choice for
319 319 all prompts
320 320 -q --quiet suppress output
321 321 -v --verbose enable additional output
322 322 --config CONFIG [+] set/override config option (use 'section.name=value')
323 323 --debug enable debugging output
324 324 --debugger start debugger
325 325 --encoding ENCODE set the charset encoding (default: ascii)
326 326 --encodingmode MODE set the charset encoding mode (default: strict)
327 327 --traceback always print a traceback on exception
328 328 --time time how long the command takes
329 329 --profile print command execution profile
330 330 --version output version information and exit
331 331 -h --help display help and exit
332 332 --hidden consider hidden changesets
333 333
334 334 (use "hg help" for the full list of commands)
335 335
336 336 $ hg add -h
337 337 hg add [OPTION]... [FILE]...
338 338
339 339 add the specified files on the next commit
340 340
341 341 Schedule files to be version controlled and added to the repository.
342 342
343 343 The files will be added to the repository at the next commit. To undo an
344 344 add before that, see "hg forget".
345 345
346 346 If no names are given, add all files to the repository.
347 347
348 348 Returns 0 if all files are successfully added.
349 349
350 350 options ([+] can be repeated):
351 351
352 352 -I --include PATTERN [+] include names matching the given patterns
353 353 -X --exclude PATTERN [+] exclude names matching the given patterns
354 354 -S --subrepos recurse into subrepositories
355 355 -n --dry-run do not perform actions, just print output
356 356
357 357 (some details hidden, use --verbose to show complete help)
358 358
359 359 Verbose help for add
360 360
361 361 $ hg add -hv
362 362 hg add [OPTION]... [FILE]...
363 363
364 364 add the specified files on the next commit
365 365
366 366 Schedule files to be version controlled and added to the repository.
367 367
368 368 The files will be added to the repository at the next commit. To undo an
369 369 add before that, see "hg forget".
370 370
371 371 If no names are given, add all files to the repository.
372 372
373 373 An example showing how new (unknown) files are added automatically by "hg
374 374 add":
375 375
376 376 $ ls
377 377 foo.c
378 378 $ hg status
379 379 ? foo.c
380 380 $ hg add
381 381 adding foo.c
382 382 $ hg status
383 383 A foo.c
384 384
385 385 Returns 0 if all files are successfully added.
386 386
387 387 options ([+] can be repeated):
388 388
389 389 -I --include PATTERN [+] include names matching the given patterns
390 390 -X --exclude PATTERN [+] exclude names matching the given patterns
391 391 -S --subrepos recurse into subrepositories
392 392 -n --dry-run do not perform actions, just print output
393 393
394 394 global options ([+] can be repeated):
395 395
396 396 -R --repository REPO repository root directory or name of overlay bundle
397 397 file
398 398 --cwd DIR change working directory
399 399 -y --noninteractive do not prompt, automatically pick the first choice for
400 400 all prompts
401 401 -q --quiet suppress output
402 402 -v --verbose enable additional output
403 403 --config CONFIG [+] set/override config option (use 'section.name=value')
404 404 --debug enable debugging output
405 405 --debugger start debugger
406 406 --encoding ENCODE set the charset encoding (default: ascii)
407 407 --encodingmode MODE set the charset encoding mode (default: strict)
408 408 --traceback always print a traceback on exception
409 409 --time time how long the command takes
410 410 --profile print command execution profile
411 411 --version output version information and exit
412 412 -h --help display help and exit
413 413 --hidden consider hidden changesets
414 414
415 415 Test help option with version option
416 416
417 417 $ hg add -h --version
418 418 Mercurial Distributed SCM (version *) (glob)
419 419 (see https://mercurial-scm.org for more information)
420 420
421 421 Copyright (C) 2005-2015 Matt Mackall and others
422 422 This is free software; see the source for copying conditions. There is NO
423 423 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
424 424
425 425 $ hg add --skjdfks
426 426 hg add: option --skjdfks not recognized
427 427 hg add [OPTION]... [FILE]...
428 428
429 429 add the specified files on the next commit
430 430
431 431 options ([+] can be repeated):
432 432
433 433 -I --include PATTERN [+] include names matching the given patterns
434 434 -X --exclude PATTERN [+] exclude names matching the given patterns
435 435 -S --subrepos recurse into subrepositories
436 436 -n --dry-run do not perform actions, just print output
437 437
438 438 (use "hg add -h" to show more help)
439 439 [255]
440 440
441 441 Test ambiguous command help
442 442
443 443 $ hg help ad
444 444 list of commands:
445 445
446 446 add add the specified files on the next commit
447 447 addremove add all new files, delete all missing files
448 448
449 449 (use "hg help -v ad" to show built-in aliases and global options)
450 450
451 451 Test command without options
452 452
453 453 $ hg help verify
454 454 hg verify
455 455
456 456 verify the integrity of the repository
457 457
458 458 Verify the integrity of the current repository.
459 459
460 460 This will perform an extensive check of the repository's integrity,
461 461 validating the hashes and checksums of each entry in the changelog,
462 462 manifest, and tracked files, as well as the integrity of their crosslinks
463 463 and indices.
464 464
465 465 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
466 466 information about recovery from corruption of the repository.
467 467
468 468 Returns 0 on success, 1 if errors are encountered.
469 469
470 470 (some details hidden, use --verbose to show complete help)
471 471
472 472 $ hg help diff
473 473 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
474 474
475 475 diff repository (or selected files)
476 476
477 477 Show differences between revisions for the specified files.
478 478
479 479 Differences between files are shown using the unified diff format.
480 480
481 481 Note:
482 482 diff may generate unexpected results for merges, as it will default to
483 483 comparing against the working directory's first parent changeset if no
484 484 revisions are specified.
485 485
486 486 When two revision arguments are given, then changes are shown between
487 487 those revisions. If only one revision is specified then that revision is
488 488 compared to the working directory, and, when no revisions are specified,
489 489 the working directory files are compared to its parent.
490 490
491 491 Alternatively you can specify -c/--change with a revision to see the
492 492 changes in that changeset relative to its first parent.
493 493
494 494 Without the -a/--text option, diff will avoid generating diffs of files it
495 495 detects as binary. With -a, diff will generate a diff anyway, probably
496 496 with undesirable results.
497 497
498 498 Use the -g/--git option to generate diffs in the git extended diff format.
499 499 For more information, read "hg help diffs".
500 500
501 501 Returns 0 on success.
502 502
503 503 options ([+] can be repeated):
504 504
505 505 -r --rev REV [+] revision
506 506 -c --change REV change made by revision
507 507 -a --text treat all files as text
508 508 -g --git use git extended diff format
509 509 --nodates omit dates from diff headers
510 510 --noprefix omit a/ and b/ prefixes from filenames
511 511 -p --show-function show which function each change is in
512 512 --reverse produce a diff that undoes the changes
513 513 -w --ignore-all-space ignore white space when comparing lines
514 514 -b --ignore-space-change ignore changes in the amount of white space
515 515 -B --ignore-blank-lines ignore changes whose lines are all blank
516 516 -U --unified NUM number of lines of context to show
517 517 --stat output diffstat-style summary of changes
518 518 --root DIR produce diffs relative to subdirectory
519 519 -I --include PATTERN [+] include names matching the given patterns
520 520 -X --exclude PATTERN [+] exclude names matching the given patterns
521 521 -S --subrepos recurse into subrepositories
522 522
523 523 (some details hidden, use --verbose to show complete help)
524 524
525 525 $ hg help status
526 526 hg status [OPTION]... [FILE]...
527 527
528 528 aliases: st
529 529
530 530 show changed files in the working directory
531 531
532 532 Show status of files in the repository. If names are given, only files
533 533 that match are shown. Files that are clean or ignored or the source of a
534 534 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
535 535 -C/--copies or -A/--all are given. Unless options described with "show
536 536 only ..." are given, the options -mardu are used.
537 537
538 538 Option -q/--quiet hides untracked (unknown and ignored) files unless
539 539 explicitly requested with -u/--unknown or -i/--ignored.
540 540
541 541 Note:
542 542 status may appear to disagree with diff if permissions have changed or
543 543 a merge has occurred. The standard diff format does not report
544 544 permission changes and diff only reports changes relative to one merge
545 545 parent.
546 546
547 547 If one revision is given, it is used as the base revision. If two
548 548 revisions are given, the differences between them are shown. The --change
549 549 option can also be used as a shortcut to list the changed files of a
550 550 revision from its first parent.
551 551
552 552 The codes used to show the status of files are:
553 553
554 554 M = modified
555 555 A = added
556 556 R = removed
557 557 C = clean
558 558 ! = missing (deleted by non-hg command, but still tracked)
559 559 ? = not tracked
560 560 I = ignored
561 561 = origin of the previous file (with --copies)
562 562
563 563 Returns 0 on success.
564 564
565 565 options ([+] can be repeated):
566 566
567 567 -A --all show status of all files
568 568 -m --modified show only modified files
569 569 -a --added show only added files
570 570 -r --removed show only removed files
571 571 -d --deleted show only deleted (but tracked) files
572 572 -c --clean show only files without changes
573 573 -u --unknown show only unknown (not tracked) files
574 574 -i --ignored show only ignored files
575 575 -n --no-status hide status prefix
576 576 -C --copies show source of copied files
577 577 -0 --print0 end filenames with NUL, for use with xargs
578 578 --rev REV [+] show difference from revision
579 579 --change REV list the changed files of a revision
580 580 -I --include PATTERN [+] include names matching the given patterns
581 581 -X --exclude PATTERN [+] exclude names matching the given patterns
582 582 -S --subrepos recurse into subrepositories
583 583
584 584 (some details hidden, use --verbose to show complete help)
585 585
586 586 $ hg -q help status
587 587 hg status [OPTION]... [FILE]...
588 588
589 589 show changed files in the working directory
590 590
591 591 $ hg help foo
592 592 abort: no such help topic: foo
593 593 (try "hg help --keyword foo")
594 594 [255]
595 595
596 596 $ hg skjdfks
597 597 hg: unknown command 'skjdfks'
598 598 Mercurial Distributed SCM
599 599
600 600 basic commands:
601 601
602 602 add add the specified files on the next commit
603 603 annotate show changeset information by line for each file
604 604 clone make a copy of an existing repository
605 605 commit commit the specified files or all outstanding changes
606 606 diff diff repository (or selected files)
607 607 export dump the header and diffs for one or more changesets
608 608 forget forget the specified files on the next commit
609 609 init create a new repository in the given directory
610 610 log show revision history of entire repository or files
611 611 merge merge another revision into working directory
612 612 pull pull changes from the specified source
613 613 push push changes to the specified destination
614 614 remove remove the specified files on the next commit
615 615 serve start stand-alone webserver
616 616 status show changed files in the working directory
617 617 summary summarize working directory state
618 618 update update working directory (or switch revisions)
619 619
620 620 (use "hg help" for the full list of commands or "hg -v" for details)
621 621 [255]
622 622
623 623
624 624 Make sure that we don't run afoul of the help system thinking that
625 625 this is a section and erroring out weirdly.
626 626
627 627 $ hg .log
628 628 hg: unknown command '.log'
629 629 (did you mean one of log?)
630 630 [255]
631 631
632 632 $ hg log.
633 633 hg: unknown command 'log.'
634 634 (did you mean one of log?)
635 635 [255]
636 636 $ hg pu.lh
637 637 hg: unknown command 'pu.lh'
638 638 (did you mean one of pull, push?)
639 639 [255]
640 640
641 641 $ cat > helpext.py <<EOF
642 642 > import os
643 643 > from mercurial import cmdutil, commands
644 644 >
645 645 > cmdtable = {}
646 646 > command = cmdutil.command(cmdtable)
647 647 >
648 648 > @command('nohelp',
649 649 > [('', 'longdesc', 3, 'x'*90),
650 650 > ('n', '', None, 'normal desc'),
651 651 > ('', 'newline', '', 'line1\nline2')],
652 652 > 'hg nohelp',
653 653 > norepo=True)
654 654 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
655 655 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
656 656 > def nohelp(ui, *args, **kwargs):
657 657 > pass
658 658 >
659 659 > EOF
660 660 $ echo '[extensions]' >> $HGRCPATH
661 661 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
662 662
663 663 Test command with no help text
664 664
665 665 $ hg help nohelp
666 666 hg nohelp
667 667
668 668 (no help text available)
669 669
670 670 options:
671 671
672 672 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
673 673 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
674 674 -n -- normal desc
675 675 --newline VALUE line1 line2
676 676
677 677 (some details hidden, use --verbose to show complete help)
678 678
679 679 $ hg help -k nohelp
680 680 Commands:
681 681
682 682 nohelp hg nohelp
683 683
684 684 Extension Commands:
685 685
686 686 nohelp (no help text available)
687 687
688 688 Test that default list of commands omits extension commands
689 689
690 690 $ hg help
691 691 Mercurial Distributed SCM
692 692
693 693 list of commands:
694 694
695 695 add add the specified files on the next commit
696 696 addremove add all new files, delete all missing files
697 697 annotate show changeset information by line for each file
698 698 archive create an unversioned archive of a repository revision
699 699 backout reverse effect of earlier changeset
700 700 bisect subdivision search of changesets
701 701 bookmarks create a new bookmark or list existing bookmarks
702 702 branch set or show the current branch name
703 703 branches list repository named branches
704 704 bundle create a changegroup file
705 705 cat output the current or given revision of files
706 706 clone make a copy of an existing repository
707 707 commit commit the specified files or all outstanding changes
708 708 config show combined config settings from all hgrc files
709 709 copy mark files as copied for the next commit
710 710 diff diff repository (or selected files)
711 711 export dump the header and diffs for one or more changesets
712 712 files list tracked files
713 713 forget forget the specified files on the next commit
714 714 graft copy changes from other branches onto the current branch
715 715 grep search for a pattern in specified files and revisions
716 716 heads show branch heads
717 717 help show help for a given topic or a help overview
718 718 identify identify the working directory or specified revision
719 719 import import an ordered set of patches
720 720 incoming show new changesets found in source
721 721 init create a new repository in the given directory
722 722 log show revision history of entire repository or files
723 723 manifest output the current or given revision of the project manifest
724 724 merge merge another revision into working directory
725 725 outgoing show changesets not found in the destination
726 726 paths show aliases for remote repositories
727 727 phase set or show the current phase name
728 728 pull pull changes from the specified source
729 729 push push changes to the specified destination
730 730 recover roll back an interrupted transaction
731 731 remove remove the specified files on the next commit
732 732 rename rename files; equivalent of copy + remove
733 733 resolve redo merges or set/view the merge status of files
734 734 revert restore files to their checkout state
735 735 root print the root (top) of the current working directory
736 736 serve start stand-alone webserver
737 737 status show changed files in the working directory
738 738 summary summarize working directory state
739 739 tag add one or more tags for the current or given revision
740 740 tags list repository tags
741 741 unbundle apply one or more changegroup files
742 742 update update working directory (or switch revisions)
743 743 verify verify the integrity of the repository
744 744 version output version and copyright information
745 745
746 746 enabled extensions:
747 747
748 748 helpext (no help text available)
749 749
750 750 additional help topics:
751 751
752 752 config Configuration Files
753 753 dates Date Formats
754 754 diffs Diff Formats
755 755 environment Environment Variables
756 756 extensions Using Additional Features
757 757 filesets Specifying File Sets
758 758 glossary Glossary
759 759 hgignore Syntax for Mercurial Ignore Files
760 760 hgweb Configuring hgweb
761 761 merge-tools Merge Tools
762 762 multirevs Specifying Multiple Revisions
763 763 patterns File Name Patterns
764 764 phases Working with Phases
765 765 revisions Specifying Single Revisions
766 766 revsets Specifying Revision Sets
767 767 scripting Using Mercurial from scripts and automation
768 768 subrepos Subrepositories
769 769 templating Template Usage
770 770 urls URL Paths
771 771
772 772 (use "hg help -v" to show built-in aliases and global options)
773 773
774 774
775 775 Test list of internal help commands
776 776
777 777 $ hg help debug
778 778 debug commands (internal and unsupported):
779 779
780 780 debugancestor
781 781 find the ancestor revision of two revisions in a given index
782 782 debugbuilddag
783 783 builds a repo with a given DAG from scratch in the current
784 784 empty repo
785 785 debugbundle lists the contents of a bundle
786 786 debugcheckstate
787 787 validate the correctness of the current dirstate
788 788 debugcommands
789 789 list all available commands and options
790 790 debugcomplete
791 791 returns the completion list associated with the given command
792 792 debugdag format the changelog or an index DAG as a concise textual
793 793 description
794 794 debugdata dump the contents of a data file revision
795 795 debugdate parse and display a date
796 796 debugdirstate
797 797 show the contents of the current dirstate
798 798 debugdiscovery
799 799 runs the changeset discovery protocol in isolation
800 800 debugextensions
801 801 show information about active extensions
802 802 debugfileset parse and apply a fileset specification
803 803 debugfsinfo show information detected about current filesystem
804 804 debuggetbundle
805 805 retrieves a bundle from a repo
806 806 debugignore display the combined ignore pattern
807 807 debugindex dump the contents of an index file
808 808 debugindexdot
809 809 dump an index DAG as a graphviz dot file
810 810 debuginstall test Mercurial installation
811 811 debugknown test whether node ids are known to a repo
812 812 debuglocks show or modify state of locks
813 debugmergestate
814 print merge state
813 815 debugnamecomplete
814 816 complete "names" - tags, open branch names, bookmark names
815 817 debugobsolete
816 818 create arbitrary obsolete marker
817 819 debugoptDEP (no help text available)
818 820 debugoptEXP (no help text available)
819 821 debugpathcomplete
820 822 complete part or all of a tracked path
821 823 debugpushkey access the pushkey key/value protocol
822 824 debugpvec (no help text available)
823 825 debugrebuilddirstate
824 826 rebuild the dirstate as it would look like for the given
825 827 revision
826 828 debugrebuildfncache
827 829 rebuild the fncache file
828 830 debugrename dump rename information
829 831 debugrevlog show data and statistics about a revlog
830 832 debugrevspec parse and apply a revision specification
831 833 debugsetparents
832 834 manually set the parents of the current working directory
833 835 debugsub (no help text available)
834 836 debugsuccessorssets
835 837 show set of successors for revision
836 838 debugwalk show how files match on given patterns
837 839 debugwireargs
838 840 (no help text available)
839 841
840 842 (use "hg help -v debug" to show built-in aliases and global options)
841 843
842 844
843 845 Test list of commands with command with no help text
844 846
845 847 $ hg help helpext
846 848 helpext extension - no help text available
847 849
848 850 list of commands:
849 851
850 852 nohelp (no help text available)
851 853
852 854 (use "hg help -v helpext" to show built-in aliases and global options)
853 855
854 856
855 857 test deprecated and experimental options are hidden in command help
856 858 $ hg help debugoptDEP
857 859 hg debugoptDEP
858 860
859 861 (no help text available)
860 862
861 863 options:
862 864
863 865 (some details hidden, use --verbose to show complete help)
864 866
865 867 $ hg help debugoptEXP
866 868 hg debugoptEXP
867 869
868 870 (no help text available)
869 871
870 872 options:
871 873
872 874 (some details hidden, use --verbose to show complete help)
873 875
874 876 test deprecated and experimental options is shown with -v
875 877 $ hg help -v debugoptDEP | grep dopt
876 878 --dopt option is (DEPRECATED)
877 879 $ hg help -v debugoptEXP | grep eopt
878 880 --eopt option is (EXPERIMENTAL)
879 881
880 882 #if gettext
881 883 test deprecated option is hidden with translation with untranslated description
882 884 (use many globy for not failing on changed transaction)
883 885 $ LANGUAGE=sv hg help debugoptDEP
884 886 hg debugoptDEP
885 887
886 888 (*) (glob)
887 889
888 890 options:
889 891
890 892 (some details hidden, use --verbose to show complete help)
891 893 #endif
892 894
893 895 Test commands that collide with topics (issue4240)
894 896
895 897 $ hg config -hq
896 898 hg config [-u] [NAME]...
897 899
898 900 show combined config settings from all hgrc files
899 901 $ hg showconfig -hq
900 902 hg config [-u] [NAME]...
901 903
902 904 show combined config settings from all hgrc files
903 905
904 906 Test a help topic
905 907
906 908 $ hg help revs
907 909 Specifying Single Revisions
908 910 """""""""""""""""""""""""""
909 911
910 912 Mercurial supports several ways to specify individual revisions.
911 913
912 914 A plain integer is treated as a revision number. Negative integers are
913 915 treated as sequential offsets from the tip, with -1 denoting the tip, -2
914 916 denoting the revision prior to the tip, and so forth.
915 917
916 918 A 40-digit hexadecimal string is treated as a unique revision identifier.
917 919
918 920 A hexadecimal string less than 40 characters long is treated as a unique
919 921 revision identifier and is referred to as a short-form identifier. A
920 922 short-form identifier is only valid if it is the prefix of exactly one
921 923 full-length identifier.
922 924
923 925 Any other string is treated as a bookmark, tag, or branch name. A bookmark
924 926 is a movable pointer to a revision. A tag is a permanent name associated
925 927 with a revision. A branch name denotes the tipmost open branch head of
926 928 that branch - or if they are all closed, the tipmost closed head of the
927 929 branch. Bookmark, tag, and branch names must not contain the ":"
928 930 character.
929 931
930 932 The reserved name "tip" always identifies the most recent revision.
931 933
932 934 The reserved name "null" indicates the null revision. This is the revision
933 935 of an empty repository, and the parent of revision 0.
934 936
935 937 The reserved name "." indicates the working directory parent. If no
936 938 working directory is checked out, it is equivalent to null. If an
937 939 uncommitted merge is in progress, "." is the revision of the first parent.
938 940
939 941 Test repeated config section name
940 942
941 943 $ hg help config.host
942 944 "http_proxy.host"
943 945 Host name and (optional) port of the proxy server, for example
944 946 "myproxy:8000".
945 947
946 948 "smtp.host"
947 949 Host name of mail server, e.g. "mail.example.com".
948 950
949 951 Unrelated trailing paragraphs shouldn't be included
950 952
951 953 $ hg help config.extramsg | grep '^$'
952 954
953 955
954 956 Test capitalized section name
955 957
956 958 $ hg help scripting.HGPLAIN > /dev/null
957 959
958 960 Help subsection:
959 961
960 962 $ hg help config.charsets |grep "Email example:" > /dev/null
961 963 [1]
962 964
963 965 Show nested definitions
964 966 ("profiling.type"[break]"ls"[break]"stat"[break])
965 967
966 968 $ hg help config.type | egrep '^$'|wc -l
967 969 \s*3 (re)
968 970
969 971 Last item in help config.*:
970 972
971 973 $ hg help config.`hg help config|grep '^ "'| \
972 974 > tail -1|sed 's![ "]*!!g'`| \
973 975 > grep "hg help -c config" > /dev/null
974 976 [1]
975 977
976 978 note to use help -c for general hg help config:
977 979
978 980 $ hg help config |grep "hg help -c config" > /dev/null
979 981
980 982 Test templating help
981 983
982 984 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
983 985 desc String. The text of the changeset description.
984 986 diffstat String. Statistics of changes with the following format:
985 987 firstline Any text. Returns the first line of text.
986 988 nonempty Any text. Returns '(none)' if the string is empty.
987 989
988 990 Test deprecated items
989 991
990 992 $ hg help -v templating | grep currentbookmark
991 993 currentbookmark
992 994 $ hg help templating | (grep currentbookmark || true)
993 995
994 996 Test help hooks
995 997
996 998 $ cat > helphook1.py <<EOF
997 999 > from mercurial import help
998 1000 >
999 1001 > def rewrite(ui, topic, doc):
1000 1002 > return doc + '\nhelphook1\n'
1001 1003 >
1002 1004 > def extsetup(ui):
1003 1005 > help.addtopichook('revsets', rewrite)
1004 1006 > EOF
1005 1007 $ cat > helphook2.py <<EOF
1006 1008 > from mercurial import help
1007 1009 >
1008 1010 > def rewrite(ui, topic, doc):
1009 1011 > return doc + '\nhelphook2\n'
1010 1012 >
1011 1013 > def extsetup(ui):
1012 1014 > help.addtopichook('revsets', rewrite)
1013 1015 > EOF
1014 1016 $ echo '[extensions]' >> $HGRCPATH
1015 1017 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1016 1018 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1017 1019 $ hg help revsets | grep helphook
1018 1020 helphook1
1019 1021 helphook2
1020 1022
1021 1023 Test -e / -c / -k combinations
1022 1024
1023 1025 $ hg help -c progress
1024 1026 abort: no such help topic: progress
1025 1027 (try "hg help --keyword progress")
1026 1028 [255]
1027 1029 $ hg help -e progress |head -1
1028 1030 progress extension - show progress bars for some actions (DEPRECATED)
1029 1031 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1030 1032 Commands:
1031 1033 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1032 1034 Extensions:
1033 1035 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1034 1036 Extensions:
1035 1037 Commands:
1036 1038 $ hg help -c commit > /dev/null
1037 1039 $ hg help -e -c commit > /dev/null
1038 1040 $ hg help -e commit > /dev/null
1039 1041 abort: no such help topic: commit
1040 1042 (try "hg help --keyword commit")
1041 1043 [255]
1042 1044
1043 1045 Test keyword search help
1044 1046
1045 1047 $ cat > prefixedname.py <<EOF
1046 1048 > '''matched against word "clone"
1047 1049 > '''
1048 1050 > EOF
1049 1051 $ echo '[extensions]' >> $HGRCPATH
1050 1052 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1051 1053 $ hg help -k clone
1052 1054 Topics:
1053 1055
1054 1056 config Configuration Files
1055 1057 extensions Using Additional Features
1056 1058 glossary Glossary
1057 1059 phases Working with Phases
1058 1060 subrepos Subrepositories
1059 1061 urls URL Paths
1060 1062
1061 1063 Commands:
1062 1064
1063 1065 bookmarks create a new bookmark or list existing bookmarks
1064 1066 clone make a copy of an existing repository
1065 1067 paths show aliases for remote repositories
1066 1068 update update working directory (or switch revisions)
1067 1069
1068 1070 Extensions:
1069 1071
1070 1072 prefixedname matched against word "clone"
1071 1073 relink recreates hardlinks between repository clones
1072 1074
1073 1075 Extension Commands:
1074 1076
1075 1077 qclone clone main and patch repository at same time
1076 1078
1077 1079 Test unfound topic
1078 1080
1079 1081 $ hg help nonexistingtopicthatwillneverexisteverever
1080 1082 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1081 1083 (try "hg help --keyword nonexistingtopicthatwillneverexisteverever")
1082 1084 [255]
1083 1085
1084 1086 Test unfound keyword
1085 1087
1086 1088 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1087 1089 abort: no matches
1088 1090 (try "hg help" for a list of topics)
1089 1091 [255]
1090 1092
1091 1093 Test omit indicating for help
1092 1094
1093 1095 $ cat > addverboseitems.py <<EOF
1094 1096 > '''extension to test omit indicating.
1095 1097 >
1096 1098 > This paragraph is never omitted (for extension)
1097 1099 >
1098 1100 > .. container:: verbose
1099 1101 >
1100 1102 > This paragraph is omitted,
1101 1103 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1102 1104 >
1103 1105 > This paragraph is never omitted, too (for extension)
1104 1106 > '''
1105 1107 >
1106 1108 > from mercurial import help, commands
1107 1109 > testtopic = """This paragraph is never omitted (for topic).
1108 1110 >
1109 1111 > .. container:: verbose
1110 1112 >
1111 1113 > This paragraph is omitted,
1112 1114 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1113 1115 >
1114 1116 > This paragraph is never omitted, too (for topic)
1115 1117 > """
1116 1118 > def extsetup(ui):
1117 1119 > help.helptable.append((["topic-containing-verbose"],
1118 1120 > "This is the topic to test omit indicating.",
1119 1121 > lambda ui: testtopic))
1120 1122 > EOF
1121 1123 $ echo '[extensions]' >> $HGRCPATH
1122 1124 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1123 1125 $ hg help addverboseitems
1124 1126 addverboseitems extension - extension to test omit indicating.
1125 1127
1126 1128 This paragraph is never omitted (for extension)
1127 1129
1128 1130 This paragraph is never omitted, too (for extension)
1129 1131
1130 1132 (some details hidden, use --verbose to show complete help)
1131 1133
1132 1134 no commands defined
1133 1135 $ hg help -v addverboseitems
1134 1136 addverboseitems extension - extension to test omit indicating.
1135 1137
1136 1138 This paragraph is never omitted (for extension)
1137 1139
1138 1140 This paragraph is omitted, if "hg help" is invoked without "-v" (for
1139 1141 extension)
1140 1142
1141 1143 This paragraph is never omitted, too (for extension)
1142 1144
1143 1145 no commands defined
1144 1146 $ hg help topic-containing-verbose
1145 1147 This is the topic to test omit indicating.
1146 1148 """"""""""""""""""""""""""""""""""""""""""
1147 1149
1148 1150 This paragraph is never omitted (for topic).
1149 1151
1150 1152 This paragraph is never omitted, too (for topic)
1151 1153
1152 1154 (some details hidden, use --verbose to show complete help)
1153 1155 $ hg help -v topic-containing-verbose
1154 1156 This is the topic to test omit indicating.
1155 1157 """"""""""""""""""""""""""""""""""""""""""
1156 1158
1157 1159 This paragraph is never omitted (for topic).
1158 1160
1159 1161 This paragraph is omitted, if "hg help" is invoked without "-v" (for
1160 1162 topic)
1161 1163
1162 1164 This paragraph is never omitted, too (for topic)
1163 1165
1164 1166 Test section lookup
1165 1167
1166 1168 $ hg help revset.merge
1167 1169 "merge()"
1168 1170 Changeset is a merge changeset.
1169 1171
1170 1172 $ hg help glossary.dag
1171 1173 DAG
1172 1174 The repository of changesets of a distributed version control system
1173 1175 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1174 1176 of nodes and edges, where nodes correspond to changesets and edges
1175 1177 imply a parent -> child relation. This graph can be visualized by
1176 1178 graphical tools such as "hg log --graph". In Mercurial, the DAG is
1177 1179 limited by the requirement for children to have at most two parents.
1178 1180
1179 1181
1180 1182 $ hg help hgrc.paths
1181 1183 "paths"
1182 1184 -------
1183 1185
1184 1186 Assigns symbolic names to repositories. The left side is the symbolic
1185 1187 name, and the right gives the directory or URL that is the location of the
1186 1188 repository. Default paths can be declared by setting the following
1187 1189 entries.
1188 1190
1189 1191 "default"
1190 1192 Directory or URL to use when pulling if no source is specified.
1191 1193 (default: repository from which the current repository was cloned)
1192 1194
1193 1195 "default-push"
1194 1196 Optional. Directory or URL to use when pushing if no destination is
1195 1197 specified.
1196 1198
1197 1199 Custom paths can be defined by assigning the path to a name that later can
1198 1200 be used from the command line. Example:
1199 1201
1200 1202 [paths]
1201 1203 my_path = http://example.com/path
1202 1204
1203 1205 To push to the path defined in "my_path" run the command:
1204 1206
1205 1207 hg push my_path
1206 1208
1207 1209 $ hg help glossary.mcguffin
1208 1210 abort: help section not found
1209 1211 [255]
1210 1212
1211 1213 $ hg help glossary.mc.guffin
1212 1214 abort: help section not found
1213 1215 [255]
1214 1216
1215 1217 $ hg help template.files
1216 1218 files List of strings. All files modified, added, or removed by
1217 1219 this changeset.
1218 1220
1219 1221 Test dynamic list of merge tools only shows up once
1220 1222 $ hg help merge-tools
1221 1223 Merge Tools
1222 1224 """""""""""
1223 1225
1224 1226 To merge files Mercurial uses merge tools.
1225 1227
1226 1228 A merge tool combines two different versions of a file into a merged file.
1227 1229 Merge tools are given the two files and the greatest common ancestor of
1228 1230 the two file versions, so they can determine the changes made on both
1229 1231 branches.
1230 1232
1231 1233 Merge tools are used both for "hg resolve", "hg merge", "hg update", "hg
1232 1234 backout" and in several extensions.
1233 1235
1234 1236 Usually, the merge tool tries to automatically reconcile the files by
1235 1237 combining all non-overlapping changes that occurred separately in the two
1236 1238 different evolutions of the same initial base file. Furthermore, some
1237 1239 interactive merge programs make it easier to manually resolve conflicting
1238 1240 merges, either in a graphical way, or by inserting some conflict markers.
1239 1241 Mercurial does not include any interactive merge programs but relies on
1240 1242 external tools for that.
1241 1243
1242 1244 Available merge tools
1243 1245 =====================
1244 1246
1245 1247 External merge tools and their properties are configured in the merge-
1246 1248 tools configuration section - see hgrc(5) - but they can often just be
1247 1249 named by their executable.
1248 1250
1249 1251 A merge tool is generally usable if its executable can be found on the
1250 1252 system and if it can handle the merge. The executable is found if it is an
1251 1253 absolute or relative executable path or the name of an application in the
1252 1254 executable search path. The tool is assumed to be able to handle the merge
1253 1255 if it can handle symlinks if the file is a symlink, if it can handle
1254 1256 binary files if the file is binary, and if a GUI is available if the tool
1255 1257 requires a GUI.
1256 1258
1257 1259 There are some internal merge tools which can be used. The internal merge
1258 1260 tools are:
1259 1261
1260 1262 ":dump"
1261 1263 Creates three versions of the files to merge, containing the contents of
1262 1264 local, other and base. These files can then be used to perform a merge
1263 1265 manually. If the file to be merged is named "a.txt", these files will
1264 1266 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1265 1267 they will be placed in the same directory as "a.txt".
1266 1268
1267 1269 ":fail"
1268 1270 Rather than attempting to merge files that were modified on both
1269 1271 branches, it marks them as unresolved. The resolve command must be used
1270 1272 to resolve these conflicts.
1271 1273
1272 1274 ":local"
1273 1275 Uses the local version of files as the merged version.
1274 1276
1275 1277 ":merge"
1276 1278 Uses the internal non-interactive simple merge algorithm for merging
1277 1279 files. It will fail if there are any conflicts and leave markers in the
1278 1280 partially merged file. Markers will have two sections, one for each side
1279 1281 of merge.
1280 1282
1281 1283 ":merge-local"
1282 1284 Like :merge, but resolve all conflicts non-interactively in favor of the
1283 1285 local changes.
1284 1286
1285 1287 ":merge-other"
1286 1288 Like :merge, but resolve all conflicts non-interactively in favor of the
1287 1289 other changes.
1288 1290
1289 1291 ":merge3"
1290 1292 Uses the internal non-interactive simple merge algorithm for merging
1291 1293 files. It will fail if there are any conflicts and leave markers in the
1292 1294 partially merged file. Marker will have three sections, one from each
1293 1295 side of the merge and one for the base content.
1294 1296
1295 1297 ":other"
1296 1298 Uses the other version of files as the merged version.
1297 1299
1298 1300 ":prompt"
1299 1301 Asks the user which of the local or the other version to keep as the
1300 1302 merged version.
1301 1303
1302 1304 ":tagmerge"
1303 1305 Uses the internal tag merge algorithm (experimental).
1304 1306
1305 1307 ":union"
1306 1308 Uses the internal non-interactive simple merge algorithm for merging
1307 1309 files. It will use both left and right sides for conflict regions. No
1308 1310 markers are inserted.
1309 1311
1310 1312 Internal tools are always available and do not require a GUI but will by
1311 1313 default not handle symlinks or binary files.
1312 1314
1313 1315 Choosing a merge tool
1314 1316 =====================
1315 1317
1316 1318 Mercurial uses these rules when deciding which merge tool to use:
1317 1319
1318 1320 1. If a tool has been specified with the --tool option to merge or
1319 1321 resolve, it is used. If it is the name of a tool in the merge-tools
1320 1322 configuration, its configuration is used. Otherwise the specified tool
1321 1323 must be executable by the shell.
1322 1324 2. If the "HGMERGE" environment variable is present, its value is used and
1323 1325 must be executable by the shell.
1324 1326 3. If the filename of the file to be merged matches any of the patterns in
1325 1327 the merge-patterns configuration section, the first usable merge tool
1326 1328 corresponding to a matching pattern is used. Here, binary capabilities
1327 1329 of the merge tool are not considered.
1328 1330 4. If ui.merge is set it will be considered next. If the value is not the
1329 1331 name of a configured tool, the specified value is used and must be
1330 1332 executable by the shell. Otherwise the named tool is used if it is
1331 1333 usable.
1332 1334 5. If any usable merge tools are present in the merge-tools configuration
1333 1335 section, the one with the highest priority is used.
1334 1336 6. If a program named "hgmerge" can be found on the system, it is used -
1335 1337 but it will by default not be used for symlinks and binary files.
1336 1338 7. If the file to be merged is not binary and is not a symlink, then
1337 1339 internal ":merge" is used.
1338 1340 8. The merge of the file fails and must be resolved before commit.
1339 1341
1340 1342 Note:
1341 1343 After selecting a merge program, Mercurial will by default attempt to
1342 1344 merge the files using a simple merge algorithm first. Only if it
1343 1345 doesn't succeed because of conflicting changes Mercurial will actually
1344 1346 execute the merge program. Whether to use the simple merge algorithm
1345 1347 first can be controlled by the premerge setting of the merge tool.
1346 1348 Premerge is enabled by default unless the file is binary or a symlink.
1347 1349
1348 1350 See the merge-tools and ui sections of hgrc(5) for details on the
1349 1351 configuration of merge tools.
1350 1352
1351 1353 Test usage of section marks in help documents
1352 1354
1353 1355 $ cd "$TESTDIR"/../doc
1354 1356 $ python check-seclevel.py
1355 1357 $ cd $TESTTMP
1356 1358
1357 1359 #if serve
1358 1360
1359 1361 Test the help pages in hgweb.
1360 1362
1361 1363 Dish up an empty repo; serve it cold.
1362 1364
1363 1365 $ hg init "$TESTTMP/test"
1364 1366 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1365 1367 $ cat hg.pid >> $DAEMON_PIDS
1366 1368
1367 1369 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1368 1370 200 Script output follows
1369 1371
1370 1372 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1371 1373 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1372 1374 <head>
1373 1375 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1374 1376 <meta name="robots" content="index, nofollow" />
1375 1377 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1376 1378 <script type="text/javascript" src="/static/mercurial.js"></script>
1377 1379
1378 1380 <title>Help: Index</title>
1379 1381 </head>
1380 1382 <body>
1381 1383
1382 1384 <div class="container">
1383 1385 <div class="menu">
1384 1386 <div class="logo">
1385 1387 <a href="https://mercurial-scm.org/">
1386 1388 <img src="/static/hglogo.png" alt="mercurial" /></a>
1387 1389 </div>
1388 1390 <ul>
1389 1391 <li><a href="/shortlog">log</a></li>
1390 1392 <li><a href="/graph">graph</a></li>
1391 1393 <li><a href="/tags">tags</a></li>
1392 1394 <li><a href="/bookmarks">bookmarks</a></li>
1393 1395 <li><a href="/branches">branches</a></li>
1394 1396 </ul>
1395 1397 <ul>
1396 1398 <li class="active">help</li>
1397 1399 </ul>
1398 1400 </div>
1399 1401
1400 1402 <div class="main">
1401 1403 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1402 1404 <form class="search" action="/log">
1403 1405
1404 1406 <p><input name="rev" id="search1" type="text" size="30" /></p>
1405 1407 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1406 1408 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1407 1409 </form>
1408 1410 <table class="bigtable">
1409 1411 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
1410 1412
1411 1413 <tr><td>
1412 1414 <a href="/help/config">
1413 1415 config
1414 1416 </a>
1415 1417 </td><td>
1416 1418 Configuration Files
1417 1419 </td></tr>
1418 1420 <tr><td>
1419 1421 <a href="/help/dates">
1420 1422 dates
1421 1423 </a>
1422 1424 </td><td>
1423 1425 Date Formats
1424 1426 </td></tr>
1425 1427 <tr><td>
1426 1428 <a href="/help/diffs">
1427 1429 diffs
1428 1430 </a>
1429 1431 </td><td>
1430 1432 Diff Formats
1431 1433 </td></tr>
1432 1434 <tr><td>
1433 1435 <a href="/help/environment">
1434 1436 environment
1435 1437 </a>
1436 1438 </td><td>
1437 1439 Environment Variables
1438 1440 </td></tr>
1439 1441 <tr><td>
1440 1442 <a href="/help/extensions">
1441 1443 extensions
1442 1444 </a>
1443 1445 </td><td>
1444 1446 Using Additional Features
1445 1447 </td></tr>
1446 1448 <tr><td>
1447 1449 <a href="/help/filesets">
1448 1450 filesets
1449 1451 </a>
1450 1452 </td><td>
1451 1453 Specifying File Sets
1452 1454 </td></tr>
1453 1455 <tr><td>
1454 1456 <a href="/help/glossary">
1455 1457 glossary
1456 1458 </a>
1457 1459 </td><td>
1458 1460 Glossary
1459 1461 </td></tr>
1460 1462 <tr><td>
1461 1463 <a href="/help/hgignore">
1462 1464 hgignore
1463 1465 </a>
1464 1466 </td><td>
1465 1467 Syntax for Mercurial Ignore Files
1466 1468 </td></tr>
1467 1469 <tr><td>
1468 1470 <a href="/help/hgweb">
1469 1471 hgweb
1470 1472 </a>
1471 1473 </td><td>
1472 1474 Configuring hgweb
1473 1475 </td></tr>
1474 1476 <tr><td>
1475 1477 <a href="/help/merge-tools">
1476 1478 merge-tools
1477 1479 </a>
1478 1480 </td><td>
1479 1481 Merge Tools
1480 1482 </td></tr>
1481 1483 <tr><td>
1482 1484 <a href="/help/multirevs">
1483 1485 multirevs
1484 1486 </a>
1485 1487 </td><td>
1486 1488 Specifying Multiple Revisions
1487 1489 </td></tr>
1488 1490 <tr><td>
1489 1491 <a href="/help/patterns">
1490 1492 patterns
1491 1493 </a>
1492 1494 </td><td>
1493 1495 File Name Patterns
1494 1496 </td></tr>
1495 1497 <tr><td>
1496 1498 <a href="/help/phases">
1497 1499 phases
1498 1500 </a>
1499 1501 </td><td>
1500 1502 Working with Phases
1501 1503 </td></tr>
1502 1504 <tr><td>
1503 1505 <a href="/help/revisions">
1504 1506 revisions
1505 1507 </a>
1506 1508 </td><td>
1507 1509 Specifying Single Revisions
1508 1510 </td></tr>
1509 1511 <tr><td>
1510 1512 <a href="/help/revsets">
1511 1513 revsets
1512 1514 </a>
1513 1515 </td><td>
1514 1516 Specifying Revision Sets
1515 1517 </td></tr>
1516 1518 <tr><td>
1517 1519 <a href="/help/scripting">
1518 1520 scripting
1519 1521 </a>
1520 1522 </td><td>
1521 1523 Using Mercurial from scripts and automation
1522 1524 </td></tr>
1523 1525 <tr><td>
1524 1526 <a href="/help/subrepos">
1525 1527 subrepos
1526 1528 </a>
1527 1529 </td><td>
1528 1530 Subrepositories
1529 1531 </td></tr>
1530 1532 <tr><td>
1531 1533 <a href="/help/templating">
1532 1534 templating
1533 1535 </a>
1534 1536 </td><td>
1535 1537 Template Usage
1536 1538 </td></tr>
1537 1539 <tr><td>
1538 1540 <a href="/help/urls">
1539 1541 urls
1540 1542 </a>
1541 1543 </td><td>
1542 1544 URL Paths
1543 1545 </td></tr>
1544 1546 <tr><td>
1545 1547 <a href="/help/topic-containing-verbose">
1546 1548 topic-containing-verbose
1547 1549 </a>
1548 1550 </td><td>
1549 1551 This is the topic to test omit indicating.
1550 1552 </td></tr>
1551 1553
1552 1554 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1553 1555
1554 1556 <tr><td>
1555 1557 <a href="/help/add">
1556 1558 add
1557 1559 </a>
1558 1560 </td><td>
1559 1561 add the specified files on the next commit
1560 1562 </td></tr>
1561 1563 <tr><td>
1562 1564 <a href="/help/annotate">
1563 1565 annotate
1564 1566 </a>
1565 1567 </td><td>
1566 1568 show changeset information by line for each file
1567 1569 </td></tr>
1568 1570 <tr><td>
1569 1571 <a href="/help/clone">
1570 1572 clone
1571 1573 </a>
1572 1574 </td><td>
1573 1575 make a copy of an existing repository
1574 1576 </td></tr>
1575 1577 <tr><td>
1576 1578 <a href="/help/commit">
1577 1579 commit
1578 1580 </a>
1579 1581 </td><td>
1580 1582 commit the specified files or all outstanding changes
1581 1583 </td></tr>
1582 1584 <tr><td>
1583 1585 <a href="/help/diff">
1584 1586 diff
1585 1587 </a>
1586 1588 </td><td>
1587 1589 diff repository (or selected files)
1588 1590 </td></tr>
1589 1591 <tr><td>
1590 1592 <a href="/help/export">
1591 1593 export
1592 1594 </a>
1593 1595 </td><td>
1594 1596 dump the header and diffs for one or more changesets
1595 1597 </td></tr>
1596 1598 <tr><td>
1597 1599 <a href="/help/forget">
1598 1600 forget
1599 1601 </a>
1600 1602 </td><td>
1601 1603 forget the specified files on the next commit
1602 1604 </td></tr>
1603 1605 <tr><td>
1604 1606 <a href="/help/init">
1605 1607 init
1606 1608 </a>
1607 1609 </td><td>
1608 1610 create a new repository in the given directory
1609 1611 </td></tr>
1610 1612 <tr><td>
1611 1613 <a href="/help/log">
1612 1614 log
1613 1615 </a>
1614 1616 </td><td>
1615 1617 show revision history of entire repository or files
1616 1618 </td></tr>
1617 1619 <tr><td>
1618 1620 <a href="/help/merge">
1619 1621 merge
1620 1622 </a>
1621 1623 </td><td>
1622 1624 merge another revision into working directory
1623 1625 </td></tr>
1624 1626 <tr><td>
1625 1627 <a href="/help/pull">
1626 1628 pull
1627 1629 </a>
1628 1630 </td><td>
1629 1631 pull changes from the specified source
1630 1632 </td></tr>
1631 1633 <tr><td>
1632 1634 <a href="/help/push">
1633 1635 push
1634 1636 </a>
1635 1637 </td><td>
1636 1638 push changes to the specified destination
1637 1639 </td></tr>
1638 1640 <tr><td>
1639 1641 <a href="/help/remove">
1640 1642 remove
1641 1643 </a>
1642 1644 </td><td>
1643 1645 remove the specified files on the next commit
1644 1646 </td></tr>
1645 1647 <tr><td>
1646 1648 <a href="/help/serve">
1647 1649 serve
1648 1650 </a>
1649 1651 </td><td>
1650 1652 start stand-alone webserver
1651 1653 </td></tr>
1652 1654 <tr><td>
1653 1655 <a href="/help/status">
1654 1656 status
1655 1657 </a>
1656 1658 </td><td>
1657 1659 show changed files in the working directory
1658 1660 </td></tr>
1659 1661 <tr><td>
1660 1662 <a href="/help/summary">
1661 1663 summary
1662 1664 </a>
1663 1665 </td><td>
1664 1666 summarize working directory state
1665 1667 </td></tr>
1666 1668 <tr><td>
1667 1669 <a href="/help/update">
1668 1670 update
1669 1671 </a>
1670 1672 </td><td>
1671 1673 update working directory (or switch revisions)
1672 1674 </td></tr>
1673 1675
1674 1676 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1675 1677
1676 1678 <tr><td>
1677 1679 <a href="/help/addremove">
1678 1680 addremove
1679 1681 </a>
1680 1682 </td><td>
1681 1683 add all new files, delete all missing files
1682 1684 </td></tr>
1683 1685 <tr><td>
1684 1686 <a href="/help/archive">
1685 1687 archive
1686 1688 </a>
1687 1689 </td><td>
1688 1690 create an unversioned archive of a repository revision
1689 1691 </td></tr>
1690 1692 <tr><td>
1691 1693 <a href="/help/backout">
1692 1694 backout
1693 1695 </a>
1694 1696 </td><td>
1695 1697 reverse effect of earlier changeset
1696 1698 </td></tr>
1697 1699 <tr><td>
1698 1700 <a href="/help/bisect">
1699 1701 bisect
1700 1702 </a>
1701 1703 </td><td>
1702 1704 subdivision search of changesets
1703 1705 </td></tr>
1704 1706 <tr><td>
1705 1707 <a href="/help/bookmarks">
1706 1708 bookmarks
1707 1709 </a>
1708 1710 </td><td>
1709 1711 create a new bookmark or list existing bookmarks
1710 1712 </td></tr>
1711 1713 <tr><td>
1712 1714 <a href="/help/branch">
1713 1715 branch
1714 1716 </a>
1715 1717 </td><td>
1716 1718 set or show the current branch name
1717 1719 </td></tr>
1718 1720 <tr><td>
1719 1721 <a href="/help/branches">
1720 1722 branches
1721 1723 </a>
1722 1724 </td><td>
1723 1725 list repository named branches
1724 1726 </td></tr>
1725 1727 <tr><td>
1726 1728 <a href="/help/bundle">
1727 1729 bundle
1728 1730 </a>
1729 1731 </td><td>
1730 1732 create a changegroup file
1731 1733 </td></tr>
1732 1734 <tr><td>
1733 1735 <a href="/help/cat">
1734 1736 cat
1735 1737 </a>
1736 1738 </td><td>
1737 1739 output the current or given revision of files
1738 1740 </td></tr>
1739 1741 <tr><td>
1740 1742 <a href="/help/config">
1741 1743 config
1742 1744 </a>
1743 1745 </td><td>
1744 1746 show combined config settings from all hgrc files
1745 1747 </td></tr>
1746 1748 <tr><td>
1747 1749 <a href="/help/copy">
1748 1750 copy
1749 1751 </a>
1750 1752 </td><td>
1751 1753 mark files as copied for the next commit
1752 1754 </td></tr>
1753 1755 <tr><td>
1754 1756 <a href="/help/files">
1755 1757 files
1756 1758 </a>
1757 1759 </td><td>
1758 1760 list tracked files
1759 1761 </td></tr>
1760 1762 <tr><td>
1761 1763 <a href="/help/graft">
1762 1764 graft
1763 1765 </a>
1764 1766 </td><td>
1765 1767 copy changes from other branches onto the current branch
1766 1768 </td></tr>
1767 1769 <tr><td>
1768 1770 <a href="/help/grep">
1769 1771 grep
1770 1772 </a>
1771 1773 </td><td>
1772 1774 search for a pattern in specified files and revisions
1773 1775 </td></tr>
1774 1776 <tr><td>
1775 1777 <a href="/help/heads">
1776 1778 heads
1777 1779 </a>
1778 1780 </td><td>
1779 1781 show branch heads
1780 1782 </td></tr>
1781 1783 <tr><td>
1782 1784 <a href="/help/help">
1783 1785 help
1784 1786 </a>
1785 1787 </td><td>
1786 1788 show help for a given topic or a help overview
1787 1789 </td></tr>
1788 1790 <tr><td>
1789 1791 <a href="/help/identify">
1790 1792 identify
1791 1793 </a>
1792 1794 </td><td>
1793 1795 identify the working directory or specified revision
1794 1796 </td></tr>
1795 1797 <tr><td>
1796 1798 <a href="/help/import">
1797 1799 import
1798 1800 </a>
1799 1801 </td><td>
1800 1802 import an ordered set of patches
1801 1803 </td></tr>
1802 1804 <tr><td>
1803 1805 <a href="/help/incoming">
1804 1806 incoming
1805 1807 </a>
1806 1808 </td><td>
1807 1809 show new changesets found in source
1808 1810 </td></tr>
1809 1811 <tr><td>
1810 1812 <a href="/help/manifest">
1811 1813 manifest
1812 1814 </a>
1813 1815 </td><td>
1814 1816 output the current or given revision of the project manifest
1815 1817 </td></tr>
1816 1818 <tr><td>
1817 1819 <a href="/help/nohelp">
1818 1820 nohelp
1819 1821 </a>
1820 1822 </td><td>
1821 1823 (no help text available)
1822 1824 </td></tr>
1823 1825 <tr><td>
1824 1826 <a href="/help/outgoing">
1825 1827 outgoing
1826 1828 </a>
1827 1829 </td><td>
1828 1830 show changesets not found in the destination
1829 1831 </td></tr>
1830 1832 <tr><td>
1831 1833 <a href="/help/paths">
1832 1834 paths
1833 1835 </a>
1834 1836 </td><td>
1835 1837 show aliases for remote repositories
1836 1838 </td></tr>
1837 1839 <tr><td>
1838 1840 <a href="/help/phase">
1839 1841 phase
1840 1842 </a>
1841 1843 </td><td>
1842 1844 set or show the current phase name
1843 1845 </td></tr>
1844 1846 <tr><td>
1845 1847 <a href="/help/recover">
1846 1848 recover
1847 1849 </a>
1848 1850 </td><td>
1849 1851 roll back an interrupted transaction
1850 1852 </td></tr>
1851 1853 <tr><td>
1852 1854 <a href="/help/rename">
1853 1855 rename
1854 1856 </a>
1855 1857 </td><td>
1856 1858 rename files; equivalent of copy + remove
1857 1859 </td></tr>
1858 1860 <tr><td>
1859 1861 <a href="/help/resolve">
1860 1862 resolve
1861 1863 </a>
1862 1864 </td><td>
1863 1865 redo merges or set/view the merge status of files
1864 1866 </td></tr>
1865 1867 <tr><td>
1866 1868 <a href="/help/revert">
1867 1869 revert
1868 1870 </a>
1869 1871 </td><td>
1870 1872 restore files to their checkout state
1871 1873 </td></tr>
1872 1874 <tr><td>
1873 1875 <a href="/help/root">
1874 1876 root
1875 1877 </a>
1876 1878 </td><td>
1877 1879 print the root (top) of the current working directory
1878 1880 </td></tr>
1879 1881 <tr><td>
1880 1882 <a href="/help/tag">
1881 1883 tag
1882 1884 </a>
1883 1885 </td><td>
1884 1886 add one or more tags for the current or given revision
1885 1887 </td></tr>
1886 1888 <tr><td>
1887 1889 <a href="/help/tags">
1888 1890 tags
1889 1891 </a>
1890 1892 </td><td>
1891 1893 list repository tags
1892 1894 </td></tr>
1893 1895 <tr><td>
1894 1896 <a href="/help/unbundle">
1895 1897 unbundle
1896 1898 </a>
1897 1899 </td><td>
1898 1900 apply one or more changegroup files
1899 1901 </td></tr>
1900 1902 <tr><td>
1901 1903 <a href="/help/verify">
1902 1904 verify
1903 1905 </a>
1904 1906 </td><td>
1905 1907 verify the integrity of the repository
1906 1908 </td></tr>
1907 1909 <tr><td>
1908 1910 <a href="/help/version">
1909 1911 version
1910 1912 </a>
1911 1913 </td><td>
1912 1914 output version and copyright information
1913 1915 </td></tr>
1914 1916 </table>
1915 1917 </div>
1916 1918 </div>
1917 1919
1918 1920 <script type="text/javascript">process_dates()</script>
1919 1921
1920 1922
1921 1923 </body>
1922 1924 </html>
1923 1925
1924 1926
1925 1927 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
1926 1928 200 Script output follows
1927 1929
1928 1930 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1929 1931 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1930 1932 <head>
1931 1933 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1932 1934 <meta name="robots" content="index, nofollow" />
1933 1935 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1934 1936 <script type="text/javascript" src="/static/mercurial.js"></script>
1935 1937
1936 1938 <title>Help: add</title>
1937 1939 </head>
1938 1940 <body>
1939 1941
1940 1942 <div class="container">
1941 1943 <div class="menu">
1942 1944 <div class="logo">
1943 1945 <a href="https://mercurial-scm.org/">
1944 1946 <img src="/static/hglogo.png" alt="mercurial" /></a>
1945 1947 </div>
1946 1948 <ul>
1947 1949 <li><a href="/shortlog">log</a></li>
1948 1950 <li><a href="/graph">graph</a></li>
1949 1951 <li><a href="/tags">tags</a></li>
1950 1952 <li><a href="/bookmarks">bookmarks</a></li>
1951 1953 <li><a href="/branches">branches</a></li>
1952 1954 </ul>
1953 1955 <ul>
1954 1956 <li class="active"><a href="/help">help</a></li>
1955 1957 </ul>
1956 1958 </div>
1957 1959
1958 1960 <div class="main">
1959 1961 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1960 1962 <h3>Help: add</h3>
1961 1963
1962 1964 <form class="search" action="/log">
1963 1965
1964 1966 <p><input name="rev" id="search1" type="text" size="30" /></p>
1965 1967 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1966 1968 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1967 1969 </form>
1968 1970 <div id="doc">
1969 1971 <p>
1970 1972 hg add [OPTION]... [FILE]...
1971 1973 </p>
1972 1974 <p>
1973 1975 add the specified files on the next commit
1974 1976 </p>
1975 1977 <p>
1976 1978 Schedule files to be version controlled and added to the
1977 1979 repository.
1978 1980 </p>
1979 1981 <p>
1980 1982 The files will be added to the repository at the next commit. To
1981 1983 undo an add before that, see &quot;hg forget&quot;.
1982 1984 </p>
1983 1985 <p>
1984 1986 If no names are given, add all files to the repository.
1985 1987 </p>
1986 1988 <p>
1987 1989 An example showing how new (unknown) files are added
1988 1990 automatically by &quot;hg add&quot;:
1989 1991 </p>
1990 1992 <pre>
1991 1993 \$ ls (re)
1992 1994 foo.c
1993 1995 \$ hg status (re)
1994 1996 ? foo.c
1995 1997 \$ hg add (re)
1996 1998 adding foo.c
1997 1999 \$ hg status (re)
1998 2000 A foo.c
1999 2001 </pre>
2000 2002 <p>
2001 2003 Returns 0 if all files are successfully added.
2002 2004 </p>
2003 2005 <p>
2004 2006 options ([+] can be repeated):
2005 2007 </p>
2006 2008 <table>
2007 2009 <tr><td>-I</td>
2008 2010 <td>--include PATTERN [+]</td>
2009 2011 <td>include names matching the given patterns</td></tr>
2010 2012 <tr><td>-X</td>
2011 2013 <td>--exclude PATTERN [+]</td>
2012 2014 <td>exclude names matching the given patterns</td></tr>
2013 2015 <tr><td>-S</td>
2014 2016 <td>--subrepos</td>
2015 2017 <td>recurse into subrepositories</td></tr>
2016 2018 <tr><td>-n</td>
2017 2019 <td>--dry-run</td>
2018 2020 <td>do not perform actions, just print output</td></tr>
2019 2021 </table>
2020 2022 <p>
2021 2023 global options ([+] can be repeated):
2022 2024 </p>
2023 2025 <table>
2024 2026 <tr><td>-R</td>
2025 2027 <td>--repository REPO</td>
2026 2028 <td>repository root directory or name of overlay bundle file</td></tr>
2027 2029 <tr><td></td>
2028 2030 <td>--cwd DIR</td>
2029 2031 <td>change working directory</td></tr>
2030 2032 <tr><td>-y</td>
2031 2033 <td>--noninteractive</td>
2032 2034 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2033 2035 <tr><td>-q</td>
2034 2036 <td>--quiet</td>
2035 2037 <td>suppress output</td></tr>
2036 2038 <tr><td>-v</td>
2037 2039 <td>--verbose</td>
2038 2040 <td>enable additional output</td></tr>
2039 2041 <tr><td></td>
2040 2042 <td>--config CONFIG [+]</td>
2041 2043 <td>set/override config option (use 'section.name=value')</td></tr>
2042 2044 <tr><td></td>
2043 2045 <td>--debug</td>
2044 2046 <td>enable debugging output</td></tr>
2045 2047 <tr><td></td>
2046 2048 <td>--debugger</td>
2047 2049 <td>start debugger</td></tr>
2048 2050 <tr><td></td>
2049 2051 <td>--encoding ENCODE</td>
2050 2052 <td>set the charset encoding (default: ascii)</td></tr>
2051 2053 <tr><td></td>
2052 2054 <td>--encodingmode MODE</td>
2053 2055 <td>set the charset encoding mode (default: strict)</td></tr>
2054 2056 <tr><td></td>
2055 2057 <td>--traceback</td>
2056 2058 <td>always print a traceback on exception</td></tr>
2057 2059 <tr><td></td>
2058 2060 <td>--time</td>
2059 2061 <td>time how long the command takes</td></tr>
2060 2062 <tr><td></td>
2061 2063 <td>--profile</td>
2062 2064 <td>print command execution profile</td></tr>
2063 2065 <tr><td></td>
2064 2066 <td>--version</td>
2065 2067 <td>output version information and exit</td></tr>
2066 2068 <tr><td>-h</td>
2067 2069 <td>--help</td>
2068 2070 <td>display help and exit</td></tr>
2069 2071 <tr><td></td>
2070 2072 <td>--hidden</td>
2071 2073 <td>consider hidden changesets</td></tr>
2072 2074 </table>
2073 2075
2074 2076 </div>
2075 2077 </div>
2076 2078 </div>
2077 2079
2078 2080 <script type="text/javascript">process_dates()</script>
2079 2081
2080 2082
2081 2083 </body>
2082 2084 </html>
2083 2085
2084 2086
2085 2087 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2086 2088 200 Script output follows
2087 2089
2088 2090 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2089 2091 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2090 2092 <head>
2091 2093 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2092 2094 <meta name="robots" content="index, nofollow" />
2093 2095 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2094 2096 <script type="text/javascript" src="/static/mercurial.js"></script>
2095 2097
2096 2098 <title>Help: remove</title>
2097 2099 </head>
2098 2100 <body>
2099 2101
2100 2102 <div class="container">
2101 2103 <div class="menu">
2102 2104 <div class="logo">
2103 2105 <a href="https://mercurial-scm.org/">
2104 2106 <img src="/static/hglogo.png" alt="mercurial" /></a>
2105 2107 </div>
2106 2108 <ul>
2107 2109 <li><a href="/shortlog">log</a></li>
2108 2110 <li><a href="/graph">graph</a></li>
2109 2111 <li><a href="/tags">tags</a></li>
2110 2112 <li><a href="/bookmarks">bookmarks</a></li>
2111 2113 <li><a href="/branches">branches</a></li>
2112 2114 </ul>
2113 2115 <ul>
2114 2116 <li class="active"><a href="/help">help</a></li>
2115 2117 </ul>
2116 2118 </div>
2117 2119
2118 2120 <div class="main">
2119 2121 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2120 2122 <h3>Help: remove</h3>
2121 2123
2122 2124 <form class="search" action="/log">
2123 2125
2124 2126 <p><input name="rev" id="search1" type="text" size="30" /></p>
2125 2127 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2126 2128 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2127 2129 </form>
2128 2130 <div id="doc">
2129 2131 <p>
2130 2132 hg remove [OPTION]... FILE...
2131 2133 </p>
2132 2134 <p>
2133 2135 aliases: rm
2134 2136 </p>
2135 2137 <p>
2136 2138 remove the specified files on the next commit
2137 2139 </p>
2138 2140 <p>
2139 2141 Schedule the indicated files for removal from the current branch.
2140 2142 </p>
2141 2143 <p>
2142 2144 This command schedules the files to be removed at the next commit.
2143 2145 To undo a remove before that, see &quot;hg revert&quot;. To undo added
2144 2146 files, see &quot;hg forget&quot;.
2145 2147 </p>
2146 2148 <p>
2147 2149 -A/--after can be used to remove only files that have already
2148 2150 been deleted, -f/--force can be used to force deletion, and -Af
2149 2151 can be used to remove files from the next revision without
2150 2152 deleting them from the working directory.
2151 2153 </p>
2152 2154 <p>
2153 2155 The following table details the behavior of remove for different
2154 2156 file states (columns) and option combinations (rows). The file
2155 2157 states are Added [A], Clean [C], Modified [M] and Missing [!]
2156 2158 (as reported by &quot;hg status&quot;). The actions are Warn, Remove
2157 2159 (from branch) and Delete (from disk):
2158 2160 </p>
2159 2161 <table>
2160 2162 <tr><td>opt/state</td>
2161 2163 <td>A</td>
2162 2164 <td>C</td>
2163 2165 <td>M</td>
2164 2166 <td>!</td></tr>
2165 2167 <tr><td>none</td>
2166 2168 <td>W</td>
2167 2169 <td>RD</td>
2168 2170 <td>W</td>
2169 2171 <td>R</td></tr>
2170 2172 <tr><td>-f</td>
2171 2173 <td>R</td>
2172 2174 <td>RD</td>
2173 2175 <td>RD</td>
2174 2176 <td>R</td></tr>
2175 2177 <tr><td>-A</td>
2176 2178 <td>W</td>
2177 2179 <td>W</td>
2178 2180 <td>W</td>
2179 2181 <td>R</td></tr>
2180 2182 <tr><td>-Af</td>
2181 2183 <td>R</td>
2182 2184 <td>R</td>
2183 2185 <td>R</td>
2184 2186 <td>R</td></tr>
2185 2187 </table>
2186 2188 <p>
2187 2189 Note that remove never deletes files in Added [A] state from the
2188 2190 working directory, not even if option --force is specified.
2189 2191 </p>
2190 2192 <p>
2191 2193 Returns 0 on success, 1 if any warnings encountered.
2192 2194 </p>
2193 2195 <p>
2194 2196 options ([+] can be repeated):
2195 2197 </p>
2196 2198 <table>
2197 2199 <tr><td>-A</td>
2198 2200 <td>--after</td>
2199 2201 <td>record delete for missing files</td></tr>
2200 2202 <tr><td>-f</td>
2201 2203 <td>--force</td>
2202 2204 <td>remove (and delete) file even if added or modified</td></tr>
2203 2205 <tr><td>-S</td>
2204 2206 <td>--subrepos</td>
2205 2207 <td>recurse into subrepositories</td></tr>
2206 2208 <tr><td>-I</td>
2207 2209 <td>--include PATTERN [+]</td>
2208 2210 <td>include names matching the given patterns</td></tr>
2209 2211 <tr><td>-X</td>
2210 2212 <td>--exclude PATTERN [+]</td>
2211 2213 <td>exclude names matching the given patterns</td></tr>
2212 2214 </table>
2213 2215 <p>
2214 2216 global options ([+] can be repeated):
2215 2217 </p>
2216 2218 <table>
2217 2219 <tr><td>-R</td>
2218 2220 <td>--repository REPO</td>
2219 2221 <td>repository root directory or name of overlay bundle file</td></tr>
2220 2222 <tr><td></td>
2221 2223 <td>--cwd DIR</td>
2222 2224 <td>change working directory</td></tr>
2223 2225 <tr><td>-y</td>
2224 2226 <td>--noninteractive</td>
2225 2227 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2226 2228 <tr><td>-q</td>
2227 2229 <td>--quiet</td>
2228 2230 <td>suppress output</td></tr>
2229 2231 <tr><td>-v</td>
2230 2232 <td>--verbose</td>
2231 2233 <td>enable additional output</td></tr>
2232 2234 <tr><td></td>
2233 2235 <td>--config CONFIG [+]</td>
2234 2236 <td>set/override config option (use 'section.name=value')</td></tr>
2235 2237 <tr><td></td>
2236 2238 <td>--debug</td>
2237 2239 <td>enable debugging output</td></tr>
2238 2240 <tr><td></td>
2239 2241 <td>--debugger</td>
2240 2242 <td>start debugger</td></tr>
2241 2243 <tr><td></td>
2242 2244 <td>--encoding ENCODE</td>
2243 2245 <td>set the charset encoding (default: ascii)</td></tr>
2244 2246 <tr><td></td>
2245 2247 <td>--encodingmode MODE</td>
2246 2248 <td>set the charset encoding mode (default: strict)</td></tr>
2247 2249 <tr><td></td>
2248 2250 <td>--traceback</td>
2249 2251 <td>always print a traceback on exception</td></tr>
2250 2252 <tr><td></td>
2251 2253 <td>--time</td>
2252 2254 <td>time how long the command takes</td></tr>
2253 2255 <tr><td></td>
2254 2256 <td>--profile</td>
2255 2257 <td>print command execution profile</td></tr>
2256 2258 <tr><td></td>
2257 2259 <td>--version</td>
2258 2260 <td>output version information and exit</td></tr>
2259 2261 <tr><td>-h</td>
2260 2262 <td>--help</td>
2261 2263 <td>display help and exit</td></tr>
2262 2264 <tr><td></td>
2263 2265 <td>--hidden</td>
2264 2266 <td>consider hidden changesets</td></tr>
2265 2267 </table>
2266 2268
2267 2269 </div>
2268 2270 </div>
2269 2271 </div>
2270 2272
2271 2273 <script type="text/javascript">process_dates()</script>
2272 2274
2273 2275
2274 2276 </body>
2275 2277 </html>
2276 2278
2277 2279
2278 2280 $ get-with-headers.py 127.0.0.1:$HGPORT "help/revisions"
2279 2281 200 Script output follows
2280 2282
2281 2283 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2282 2284 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2283 2285 <head>
2284 2286 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2285 2287 <meta name="robots" content="index, nofollow" />
2286 2288 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2287 2289 <script type="text/javascript" src="/static/mercurial.js"></script>
2288 2290
2289 2291 <title>Help: revisions</title>
2290 2292 </head>
2291 2293 <body>
2292 2294
2293 2295 <div class="container">
2294 2296 <div class="menu">
2295 2297 <div class="logo">
2296 2298 <a href="https://mercurial-scm.org/">
2297 2299 <img src="/static/hglogo.png" alt="mercurial" /></a>
2298 2300 </div>
2299 2301 <ul>
2300 2302 <li><a href="/shortlog">log</a></li>
2301 2303 <li><a href="/graph">graph</a></li>
2302 2304 <li><a href="/tags">tags</a></li>
2303 2305 <li><a href="/bookmarks">bookmarks</a></li>
2304 2306 <li><a href="/branches">branches</a></li>
2305 2307 </ul>
2306 2308 <ul>
2307 2309 <li class="active"><a href="/help">help</a></li>
2308 2310 </ul>
2309 2311 </div>
2310 2312
2311 2313 <div class="main">
2312 2314 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2313 2315 <h3>Help: revisions</h3>
2314 2316
2315 2317 <form class="search" action="/log">
2316 2318
2317 2319 <p><input name="rev" id="search1" type="text" size="30" /></p>
2318 2320 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2319 2321 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2320 2322 </form>
2321 2323 <div id="doc">
2322 2324 <h1>Specifying Single Revisions</h1>
2323 2325 <p>
2324 2326 Mercurial supports several ways to specify individual revisions.
2325 2327 </p>
2326 2328 <p>
2327 2329 A plain integer is treated as a revision number. Negative integers are
2328 2330 treated as sequential offsets from the tip, with -1 denoting the tip,
2329 2331 -2 denoting the revision prior to the tip, and so forth.
2330 2332 </p>
2331 2333 <p>
2332 2334 A 40-digit hexadecimal string is treated as a unique revision
2333 2335 identifier.
2334 2336 </p>
2335 2337 <p>
2336 2338 A hexadecimal string less than 40 characters long is treated as a
2337 2339 unique revision identifier and is referred to as a short-form
2338 2340 identifier. A short-form identifier is only valid if it is the prefix
2339 2341 of exactly one full-length identifier.
2340 2342 </p>
2341 2343 <p>
2342 2344 Any other string is treated as a bookmark, tag, or branch name. A
2343 2345 bookmark is a movable pointer to a revision. A tag is a permanent name
2344 2346 associated with a revision. A branch name denotes the tipmost open branch head
2345 2347 of that branch - or if they are all closed, the tipmost closed head of the
2346 2348 branch. Bookmark, tag, and branch names must not contain the &quot;:&quot; character.
2347 2349 </p>
2348 2350 <p>
2349 2351 The reserved name &quot;tip&quot; always identifies the most recent revision.
2350 2352 </p>
2351 2353 <p>
2352 2354 The reserved name &quot;null&quot; indicates the null revision. This is the
2353 2355 revision of an empty repository, and the parent of revision 0.
2354 2356 </p>
2355 2357 <p>
2356 2358 The reserved name &quot;.&quot; indicates the working directory parent. If no
2357 2359 working directory is checked out, it is equivalent to null. If an
2358 2360 uncommitted merge is in progress, &quot;.&quot; is the revision of the first
2359 2361 parent.
2360 2362 </p>
2361 2363
2362 2364 </div>
2363 2365 </div>
2364 2366 </div>
2365 2367
2366 2368 <script type="text/javascript">process_dates()</script>
2367 2369
2368 2370
2369 2371 </body>
2370 2372 </html>
2371 2373
2372 2374
2373 2375 $ killdaemons.py
2374 2376
2375 2377 #endif
General Comments 0
You need to be logged in to leave comments. Login now