##// END OF EJS Templates
commands: add example for 'hg add'
Mathias De Maré -
r27143:fab21bac default
parent child Browse files
Show More
@@ -1,6757 +1,6771 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, nullhex, 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 import merge as mergemod
19 19 import minirst, revset, fileset
20 20 import dagparser, context, simplemerge, graphmod, copies
21 21 import random, operator
22 22 import setdiscovery, treediscovery, dagutil, pvec, localrepo, destutil
23 23 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
24 24 import ui as uimod
25 25 import streamclone
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 An example showing how new (unknown) files are added
194 automatically by :hg:`add`::
195
196 $ ls
197 foo.c
198 $ hg status
199 ? foo.c
200 $ hg add
201 adding foo.c
202 $ hg status
203 A foo.c
193 Examples:
194
195 - New (unknown) files are added
196 automatically by :hg:`add`::
197
198 $ ls
199 foo.c
200 $ hg status
201 ? foo.c
202 $ hg add
203 adding foo.c
204 $ hg status
205 A foo.c
206
207 - Specific files to be added can be specified::
208
209 $ ls
210 bar.c foo.c
211 $ hg status
212 ? bar.c
213 ? foo.c
214 $ hg add bar.c
215 $ hg status
216 A bar.c
217 ? foo.c
204 218
205 219 Returns 0 if all files are successfully added.
206 220 """
207 221
208 222 m = scmutil.match(repo[None], pats, opts)
209 223 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
210 224 return rejected and 1 or 0
211 225
212 226 @command('addremove',
213 227 similarityopts + subrepoopts + walkopts + dryrunopts,
214 228 _('[OPTION]... [FILE]...'),
215 229 inferrepo=True)
216 230 def addremove(ui, repo, *pats, **opts):
217 231 """add all new files, delete all missing files
218 232
219 233 Add all new files and remove all missing files from the
220 234 repository.
221 235
222 236 New files are ignored if they match any of the patterns in
223 237 ``.hgignore``. As with add, these changes take effect at the next
224 238 commit.
225 239
226 240 Use the -s/--similarity option to detect renamed files. This
227 241 option takes a percentage between 0 (disabled) and 100 (files must
228 242 be identical) as its parameter. With a parameter greater than 0,
229 243 this compares every removed file with every added file and records
230 244 those similar enough as renames. Detecting renamed files this way
231 245 can be expensive. After using this option, :hg:`status -C` can be
232 246 used to check which files were identified as moved or renamed. If
233 247 not specified, -s/--similarity defaults to 100 and only renames of
234 248 identical files are detected.
235 249
236 250 Returns 0 if all files are successfully added.
237 251 """
238 252 try:
239 253 sim = float(opts.get('similarity') or 100)
240 254 except ValueError:
241 255 raise error.Abort(_('similarity must be a number'))
242 256 if sim < 0 or sim > 100:
243 257 raise error.Abort(_('similarity must be between 0 and 100'))
244 258 matcher = scmutil.match(repo[None], pats, opts)
245 259 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
246 260
247 261 @command('^annotate|blame',
248 262 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
249 263 ('', 'follow', None,
250 264 _('follow copies/renames and list the filename (DEPRECATED)')),
251 265 ('', 'no-follow', None, _("don't follow copies and renames")),
252 266 ('a', 'text', None, _('treat all files as text')),
253 267 ('u', 'user', None, _('list the author (long with -v)')),
254 268 ('f', 'file', None, _('list the filename')),
255 269 ('d', 'date', None, _('list the date (short with -q)')),
256 270 ('n', 'number', None, _('list the revision number (default)')),
257 271 ('c', 'changeset', None, _('list the changeset')),
258 272 ('l', 'line-number', None, _('show line number at the first appearance'))
259 273 ] + diffwsopts + walkopts + formatteropts,
260 274 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
261 275 inferrepo=True)
262 276 def annotate(ui, repo, *pats, **opts):
263 277 """show changeset information by line for each file
264 278
265 279 List changes in files, showing the revision id responsible for
266 280 each line
267 281
268 282 This command is useful for discovering when a change was made and
269 283 by whom.
270 284
271 285 Without the -a/--text option, annotate will avoid processing files
272 286 it detects as binary. With -a, annotate will annotate the file
273 287 anyway, although the results will probably be neither useful
274 288 nor desirable.
275 289
276 290 Returns 0 on success.
277 291 """
278 292 if not pats:
279 293 raise error.Abort(_('at least one filename or pattern is required'))
280 294
281 295 if opts.get('follow'):
282 296 # --follow is deprecated and now just an alias for -f/--file
283 297 # to mimic the behavior of Mercurial before version 1.5
284 298 opts['file'] = True
285 299
286 300 ctx = scmutil.revsingle(repo, opts.get('rev'))
287 301
288 302 fm = ui.formatter('annotate', opts)
289 303 if ui.quiet:
290 304 datefunc = util.shortdate
291 305 else:
292 306 datefunc = util.datestr
293 307 if ctx.rev() is None:
294 308 def hexfn(node):
295 309 if node is None:
296 310 return None
297 311 else:
298 312 return fm.hexfunc(node)
299 313 if opts.get('changeset'):
300 314 # omit "+" suffix which is appended to node hex
301 315 def formatrev(rev):
302 316 if rev is None:
303 317 return '%d' % ctx.p1().rev()
304 318 else:
305 319 return '%d' % rev
306 320 else:
307 321 def formatrev(rev):
308 322 if rev is None:
309 323 return '%d+' % ctx.p1().rev()
310 324 else:
311 325 return '%d ' % rev
312 326 def formathex(hex):
313 327 if hex is None:
314 328 return '%s+' % fm.hexfunc(ctx.p1().node())
315 329 else:
316 330 return '%s ' % hex
317 331 else:
318 332 hexfn = fm.hexfunc
319 333 formatrev = formathex = str
320 334
321 335 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
322 336 ('number', ' ', lambda x: x[0].rev(), formatrev),
323 337 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
324 338 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
325 339 ('file', ' ', lambda x: x[0].path(), str),
326 340 ('line_number', ':', lambda x: x[1], str),
327 341 ]
328 342 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
329 343
330 344 if (not opts.get('user') and not opts.get('changeset')
331 345 and not opts.get('date') and not opts.get('file')):
332 346 opts['number'] = True
333 347
334 348 linenumber = opts.get('line_number') is not None
335 349 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
336 350 raise error.Abort(_('at least one of -n/-c is required for -l'))
337 351
338 352 if fm:
339 353 def makefunc(get, fmt):
340 354 return get
341 355 else:
342 356 def makefunc(get, fmt):
343 357 return lambda x: fmt(get(x))
344 358 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
345 359 if opts.get(op)]
346 360 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
347 361 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
348 362 if opts.get(op))
349 363
350 364 def bad(x, y):
351 365 raise error.Abort("%s: %s" % (x, y))
352 366
353 367 m = scmutil.match(ctx, pats, opts, badfn=bad)
354 368
355 369 follow = not opts.get('no_follow')
356 370 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
357 371 whitespace=True)
358 372 for abs in ctx.walk(m):
359 373 fctx = ctx[abs]
360 374 if not opts.get('text') and util.binary(fctx.data()):
361 375 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
362 376 continue
363 377
364 378 lines = fctx.annotate(follow=follow, linenumber=linenumber,
365 379 diffopts=diffopts)
366 380 formats = []
367 381 pieces = []
368 382
369 383 for f, sep in funcmap:
370 384 l = [f(n) for n, dummy in lines]
371 385 if l:
372 386 if fm:
373 387 formats.append(['%s' for x in l])
374 388 else:
375 389 sizes = [encoding.colwidth(x) for x in l]
376 390 ml = max(sizes)
377 391 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
378 392 pieces.append(l)
379 393
380 394 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
381 395 fm.startitem()
382 396 fm.write(fields, "".join(f), *p)
383 397 fm.write('line', ": %s", l[1])
384 398
385 399 if lines and not lines[-1][1].endswith('\n'):
386 400 fm.plain('\n')
387 401
388 402 fm.end()
389 403
390 404 @command('archive',
391 405 [('', 'no-decode', None, _('do not pass files through decoders')),
392 406 ('p', 'prefix', '', _('directory prefix for files in archive'),
393 407 _('PREFIX')),
394 408 ('r', 'rev', '', _('revision to distribute'), _('REV')),
395 409 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
396 410 ] + subrepoopts + walkopts,
397 411 _('[OPTION]... DEST'))
398 412 def archive(ui, repo, dest, **opts):
399 413 '''create an unversioned archive of a repository revision
400 414
401 415 By default, the revision used is the parent of the working
402 416 directory; use -r/--rev to specify a different revision.
403 417
404 418 The archive type is automatically detected based on file
405 419 extension (or override using -t/--type).
406 420
407 421 .. container:: verbose
408 422
409 423 Examples:
410 424
411 425 - create a zip file containing the 1.0 release::
412 426
413 427 hg archive -r 1.0 project-1.0.zip
414 428
415 429 - create a tarball excluding .hg files::
416 430
417 431 hg archive project.tar.gz -X ".hg*"
418 432
419 433 Valid types are:
420 434
421 435 :``files``: a directory full of files (default)
422 436 :``tar``: tar archive, uncompressed
423 437 :``tbz2``: tar archive, compressed using bzip2
424 438 :``tgz``: tar archive, compressed using gzip
425 439 :``uzip``: zip archive, uncompressed
426 440 :``zip``: zip archive, compressed using deflate
427 441
428 442 The exact name of the destination archive or directory is given
429 443 using a format string; see :hg:`help export` for details.
430 444
431 445 Each member added to an archive file has a directory prefix
432 446 prepended. Use -p/--prefix to specify a format string for the
433 447 prefix. The default is the basename of the archive, with suffixes
434 448 removed.
435 449
436 450 Returns 0 on success.
437 451 '''
438 452
439 453 ctx = scmutil.revsingle(repo, opts.get('rev'))
440 454 if not ctx:
441 455 raise error.Abort(_('no working directory: please specify a revision'))
442 456 node = ctx.node()
443 457 dest = cmdutil.makefilename(repo, dest, node)
444 458 if os.path.realpath(dest) == repo.root:
445 459 raise error.Abort(_('repository root cannot be destination'))
446 460
447 461 kind = opts.get('type') or archival.guesskind(dest) or 'files'
448 462 prefix = opts.get('prefix')
449 463
450 464 if dest == '-':
451 465 if kind == 'files':
452 466 raise error.Abort(_('cannot archive plain files to stdout'))
453 467 dest = cmdutil.makefileobj(repo, dest)
454 468 if not prefix:
455 469 prefix = os.path.basename(repo.root) + '-%h'
456 470
457 471 prefix = cmdutil.makefilename(repo, prefix, node)
458 472 matchfn = scmutil.match(ctx, [], opts)
459 473 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
460 474 matchfn, prefix, subrepos=opts.get('subrepos'))
461 475
462 476 @command('backout',
463 477 [('', 'merge', None, _('merge with old dirstate parent after backout')),
464 478 ('', 'commit', None, _('commit if no conflicts were encountered')),
465 479 ('', 'parent', '',
466 480 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
467 481 ('r', 'rev', '', _('revision to backout'), _('REV')),
468 482 ('e', 'edit', False, _('invoke editor on commit messages')),
469 483 ] + mergetoolopts + walkopts + commitopts + commitopts2,
470 484 _('[OPTION]... [-r] REV'))
471 485 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
472 486 '''reverse effect of earlier changeset
473 487
474 488 Prepare a new changeset with the effect of REV undone in the
475 489 current working directory.
476 490
477 491 If REV is the parent of the working directory, then this new changeset
478 492 is committed automatically. Otherwise, hg needs to merge the
479 493 changes and the merged result is left uncommitted.
480 494
481 495 .. note::
482 496
483 497 backout cannot be used to fix either an unwanted or
484 498 incorrect merge.
485 499
486 500 .. container:: verbose
487 501
488 502 Examples:
489 503
490 504 - Reverse the effect of the parent of the working directory.
491 505 This backout will be committed immediately::
492 506
493 507 hg backout -r .
494 508
495 509 - Reverse the effect of previous bad revision 23::
496 510
497 511 hg backout -r 23
498 512 hg commit -m "Backout revision 23"
499 513
500 514 - Reverse the effect of previous bad revision 23 and
501 515 commit the backout immediately::
502 516
503 517 hg backout -r 23 --commit
504 518
505 519 By default, the pending changeset will have one parent,
506 520 maintaining a linear history. With --merge, the pending
507 521 changeset will instead have two parents: the old parent of the
508 522 working directory and a new child of REV that simply undoes REV.
509 523
510 524 Before version 1.7, the behavior without --merge was equivalent
511 525 to specifying --merge followed by :hg:`update --clean .` to
512 526 cancel the merge and leave the child of REV as a head to be
513 527 merged separately.
514 528
515 529 See :hg:`help dates` for a list of formats valid for -d/--date.
516 530
517 531 See :hg:`help revert` for a way to restore files to the state
518 532 of another revision.
519 533
520 534 Returns 0 on success, 1 if nothing to backout or there are unresolved
521 535 files.
522 536 '''
523 537 if rev and node:
524 538 raise error.Abort(_("please specify just one revision"))
525 539
526 540 if not rev:
527 541 rev = node
528 542
529 543 if not rev:
530 544 raise error.Abort(_("please specify a revision to backout"))
531 545
532 546 date = opts.get('date')
533 547 if date:
534 548 opts['date'] = util.parsedate(date)
535 549
536 550 cmdutil.checkunfinished(repo)
537 551 cmdutil.bailifchanged(repo)
538 552 node = scmutil.revsingle(repo, rev).node()
539 553
540 554 op1, op2 = repo.dirstate.parents()
541 555 if not repo.changelog.isancestor(node, op1):
542 556 raise error.Abort(_('cannot backout change that is not an ancestor'))
543 557
544 558 p1, p2 = repo.changelog.parents(node)
545 559 if p1 == nullid:
546 560 raise error.Abort(_('cannot backout a change with no parents'))
547 561 if p2 != nullid:
548 562 if not opts.get('parent'):
549 563 raise error.Abort(_('cannot backout a merge changeset'))
550 564 p = repo.lookup(opts['parent'])
551 565 if p not in (p1, p2):
552 566 raise error.Abort(_('%s is not a parent of %s') %
553 567 (short(p), short(node)))
554 568 parent = p
555 569 else:
556 570 if opts.get('parent'):
557 571 raise error.Abort(_('cannot use --parent on non-merge changeset'))
558 572 parent = p1
559 573
560 574 # the backout should appear on the same branch
561 575 wlock = repo.wlock()
562 576 try:
563 577 branch = repo.dirstate.branch()
564 578 bheads = repo.branchheads(branch)
565 579 rctx = scmutil.revsingle(repo, hex(parent))
566 580 if not opts.get('merge') and op1 != node:
567 581 dsguard = cmdutil.dirstateguard(repo, 'backout')
568 582 try:
569 583 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
570 584 'backout')
571 585 stats = mergemod.update(repo, parent, True, True, False,
572 586 node, False)
573 587 repo.setparents(op1, op2)
574 588 dsguard.close()
575 589 hg._showstats(repo, stats)
576 590 if stats[3]:
577 591 repo.ui.status(_("use 'hg resolve' to retry unresolved "
578 592 "file merges\n"))
579 593 return 1
580 594 elif not commit:
581 595 msg = _("changeset %s backed out, "
582 596 "don't forget to commit.\n")
583 597 ui.status(msg % short(node))
584 598 return 0
585 599 finally:
586 600 ui.setconfig('ui', 'forcemerge', '', '')
587 601 lockmod.release(dsguard)
588 602 else:
589 603 hg.clean(repo, node, show_stats=False)
590 604 repo.dirstate.setbranch(branch)
591 605 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
592 606
593 607
594 608 def commitfunc(ui, repo, message, match, opts):
595 609 editform = 'backout'
596 610 e = cmdutil.getcommiteditor(editform=editform, **opts)
597 611 if not message:
598 612 # we don't translate commit messages
599 613 message = "Backed out changeset %s" % short(node)
600 614 e = cmdutil.getcommiteditor(edit=True, editform=editform)
601 615 return repo.commit(message, opts.get('user'), opts.get('date'),
602 616 match, editor=e)
603 617 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
604 618 if not newnode:
605 619 ui.status(_("nothing changed\n"))
606 620 return 1
607 621 cmdutil.commitstatus(repo, newnode, branch, bheads)
608 622
609 623 def nice(node):
610 624 return '%d:%s' % (repo.changelog.rev(node), short(node))
611 625 ui.status(_('changeset %s backs out changeset %s\n') %
612 626 (nice(repo.changelog.tip()), nice(node)))
613 627 if opts.get('merge') and op1 != node:
614 628 hg.clean(repo, op1, show_stats=False)
615 629 ui.status(_('merging with changeset %s\n')
616 630 % nice(repo.changelog.tip()))
617 631 try:
618 632 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
619 633 'backout')
620 634 return hg.merge(repo, hex(repo.changelog.tip()))
621 635 finally:
622 636 ui.setconfig('ui', 'forcemerge', '', '')
623 637 finally:
624 638 wlock.release()
625 639 return 0
626 640
627 641 @command('bisect',
628 642 [('r', 'reset', False, _('reset bisect state')),
629 643 ('g', 'good', False, _('mark changeset good')),
630 644 ('b', 'bad', False, _('mark changeset bad')),
631 645 ('s', 'skip', False, _('skip testing changeset')),
632 646 ('e', 'extend', False, _('extend the bisect range')),
633 647 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
634 648 ('U', 'noupdate', False, _('do not update to target'))],
635 649 _("[-gbsr] [-U] [-c CMD] [REV]"))
636 650 def bisect(ui, repo, rev=None, extra=None, command=None,
637 651 reset=None, good=None, bad=None, skip=None, extend=None,
638 652 noupdate=None):
639 653 """subdivision search of changesets
640 654
641 655 This command helps to find changesets which introduce problems. To
642 656 use, mark the earliest changeset you know exhibits the problem as
643 657 bad, then mark the latest changeset which is free from the problem
644 658 as good. Bisect will update your working directory to a revision
645 659 for testing (unless the -U/--noupdate option is specified). Once
646 660 you have performed tests, mark the working directory as good or
647 661 bad, and bisect will either update to another candidate changeset
648 662 or announce that it has found the bad revision.
649 663
650 664 As a shortcut, you can also use the revision argument to mark a
651 665 revision as good or bad without checking it out first.
652 666
653 667 If you supply a command, it will be used for automatic bisection.
654 668 The environment variable HG_NODE will contain the ID of the
655 669 changeset being tested. The exit status of the command will be
656 670 used to mark revisions as good or bad: status 0 means good, 125
657 671 means to skip the revision, 127 (command not found) will abort the
658 672 bisection, and any other non-zero exit status means the revision
659 673 is bad.
660 674
661 675 .. container:: verbose
662 676
663 677 Some examples:
664 678
665 679 - start a bisection with known bad revision 34, and good revision 12::
666 680
667 681 hg bisect --bad 34
668 682 hg bisect --good 12
669 683
670 684 - advance the current bisection by marking current revision as good or
671 685 bad::
672 686
673 687 hg bisect --good
674 688 hg bisect --bad
675 689
676 690 - mark the current revision, or a known revision, to be skipped (e.g. if
677 691 that revision is not usable because of another issue)::
678 692
679 693 hg bisect --skip
680 694 hg bisect --skip 23
681 695
682 696 - skip all revisions that do not touch directories ``foo`` or ``bar``::
683 697
684 698 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
685 699
686 700 - forget the current bisection::
687 701
688 702 hg bisect --reset
689 703
690 704 - use 'make && make tests' to automatically find the first broken
691 705 revision::
692 706
693 707 hg bisect --reset
694 708 hg bisect --bad 34
695 709 hg bisect --good 12
696 710 hg bisect --command "make && make tests"
697 711
698 712 - see all changesets whose states are already known in the current
699 713 bisection::
700 714
701 715 hg log -r "bisect(pruned)"
702 716
703 717 - see the changeset currently being bisected (especially useful
704 718 if running with -U/--noupdate)::
705 719
706 720 hg log -r "bisect(current)"
707 721
708 722 - see all changesets that took part in the current bisection::
709 723
710 724 hg log -r "bisect(range)"
711 725
712 726 - you can even get a nice graph::
713 727
714 728 hg log --graph -r "bisect(range)"
715 729
716 730 See :hg:`help revsets` for more about the `bisect()` keyword.
717 731
718 732 Returns 0 on success.
719 733 """
720 734 def extendbisectrange(nodes, good):
721 735 # bisect is incomplete when it ends on a merge node and
722 736 # one of the parent was not checked.
723 737 parents = repo[nodes[0]].parents()
724 738 if len(parents) > 1:
725 739 if good:
726 740 side = state['bad']
727 741 else:
728 742 side = state['good']
729 743 num = len(set(i.node() for i in parents) & set(side))
730 744 if num == 1:
731 745 return parents[0].ancestor(parents[1])
732 746 return None
733 747
734 748 def print_result(nodes, good):
735 749 displayer = cmdutil.show_changeset(ui, repo, {})
736 750 if len(nodes) == 1:
737 751 # narrowed it down to a single revision
738 752 if good:
739 753 ui.write(_("The first good revision is:\n"))
740 754 else:
741 755 ui.write(_("The first bad revision is:\n"))
742 756 displayer.show(repo[nodes[0]])
743 757 extendnode = extendbisectrange(nodes, good)
744 758 if extendnode is not None:
745 759 ui.write(_('Not all ancestors of this changeset have been'
746 760 ' checked.\nUse bisect --extend to continue the '
747 761 'bisection from\nthe common ancestor, %s.\n')
748 762 % extendnode)
749 763 else:
750 764 # multiple possible revisions
751 765 if good:
752 766 ui.write(_("Due to skipped revisions, the first "
753 767 "good revision could be any of:\n"))
754 768 else:
755 769 ui.write(_("Due to skipped revisions, the first "
756 770 "bad revision could be any of:\n"))
757 771 for n in nodes:
758 772 displayer.show(repo[n])
759 773 displayer.close()
760 774
761 775 def check_state(state, interactive=True):
762 776 if not state['good'] or not state['bad']:
763 777 if (good or bad or skip or reset) and interactive:
764 778 return
765 779 if not state['good']:
766 780 raise error.Abort(_('cannot bisect (no known good revisions)'))
767 781 else:
768 782 raise error.Abort(_('cannot bisect (no known bad revisions)'))
769 783 return True
770 784
771 785 # backward compatibility
772 786 if rev in "good bad reset init".split():
773 787 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
774 788 cmd, rev, extra = rev, extra, None
775 789 if cmd == "good":
776 790 good = True
777 791 elif cmd == "bad":
778 792 bad = True
779 793 else:
780 794 reset = True
781 795 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
782 796 raise error.Abort(_('incompatible arguments'))
783 797
784 798 cmdutil.checkunfinished(repo)
785 799
786 800 if reset:
787 801 p = repo.join("bisect.state")
788 802 if os.path.exists(p):
789 803 os.unlink(p)
790 804 return
791 805
792 806 state = hbisect.load_state(repo)
793 807
794 808 if command:
795 809 changesets = 1
796 810 if noupdate:
797 811 try:
798 812 node = state['current'][0]
799 813 except LookupError:
800 814 raise error.Abort(_('current bisect revision is unknown - '
801 815 'start a new bisect to fix'))
802 816 else:
803 817 node, p2 = repo.dirstate.parents()
804 818 if p2 != nullid:
805 819 raise error.Abort(_('current bisect revision is a merge'))
806 820 try:
807 821 while changesets:
808 822 # update state
809 823 state['current'] = [node]
810 824 hbisect.save_state(repo, state)
811 825 status = ui.system(command, environ={'HG_NODE': hex(node)})
812 826 if status == 125:
813 827 transition = "skip"
814 828 elif status == 0:
815 829 transition = "good"
816 830 # status < 0 means process was killed
817 831 elif status == 127:
818 832 raise error.Abort(_("failed to execute %s") % command)
819 833 elif status < 0:
820 834 raise error.Abort(_("%s killed") % command)
821 835 else:
822 836 transition = "bad"
823 837 ctx = scmutil.revsingle(repo, rev, node)
824 838 rev = None # clear for future iterations
825 839 state[transition].append(ctx.node())
826 840 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
827 841 check_state(state, interactive=False)
828 842 # bisect
829 843 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
830 844 # update to next check
831 845 node = nodes[0]
832 846 if not noupdate:
833 847 cmdutil.bailifchanged(repo)
834 848 hg.clean(repo, node, show_stats=False)
835 849 finally:
836 850 state['current'] = [node]
837 851 hbisect.save_state(repo, state)
838 852 print_result(nodes, bgood)
839 853 return
840 854
841 855 # update state
842 856
843 857 if rev:
844 858 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
845 859 else:
846 860 nodes = [repo.lookup('.')]
847 861
848 862 if good or bad or skip:
849 863 if good:
850 864 state['good'] += nodes
851 865 elif bad:
852 866 state['bad'] += nodes
853 867 elif skip:
854 868 state['skip'] += nodes
855 869 hbisect.save_state(repo, state)
856 870
857 871 if not check_state(state):
858 872 return
859 873
860 874 # actually bisect
861 875 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
862 876 if extend:
863 877 if not changesets:
864 878 extendnode = extendbisectrange(nodes, good)
865 879 if extendnode is not None:
866 880 ui.write(_("Extending search to changeset %d:%s\n")
867 881 % (extendnode.rev(), extendnode))
868 882 state['current'] = [extendnode.node()]
869 883 hbisect.save_state(repo, state)
870 884 if noupdate:
871 885 return
872 886 cmdutil.bailifchanged(repo)
873 887 return hg.clean(repo, extendnode.node())
874 888 raise error.Abort(_("nothing to extend"))
875 889
876 890 if changesets == 0:
877 891 print_result(nodes, good)
878 892 else:
879 893 assert len(nodes) == 1 # only a single node can be tested next
880 894 node = nodes[0]
881 895 # compute the approximate number of remaining tests
882 896 tests, size = 0, 2
883 897 while size <= changesets:
884 898 tests, size = tests + 1, size * 2
885 899 rev = repo.changelog.rev(node)
886 900 ui.write(_("Testing changeset %d:%s "
887 901 "(%d changesets remaining, ~%d tests)\n")
888 902 % (rev, short(node), changesets, tests))
889 903 state['current'] = [node]
890 904 hbisect.save_state(repo, state)
891 905 if not noupdate:
892 906 cmdutil.bailifchanged(repo)
893 907 return hg.clean(repo, node)
894 908
895 909 @command('bookmarks|bookmark',
896 910 [('f', 'force', False, _('force')),
897 911 ('r', 'rev', '', _('revision'), _('REV')),
898 912 ('d', 'delete', False, _('delete a given bookmark')),
899 913 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
900 914 ('i', 'inactive', False, _('mark a bookmark inactive')),
901 915 ] + formatteropts,
902 916 _('hg bookmarks [OPTIONS]... [NAME]...'))
903 917 def bookmark(ui, repo, *names, **opts):
904 918 '''create a new bookmark or list existing bookmarks
905 919
906 920 Bookmarks are labels on changesets to help track lines of development.
907 921 Bookmarks are unversioned and can be moved, renamed and deleted.
908 922 Deleting or moving a bookmark has no effect on the associated changesets.
909 923
910 924 Creating or updating to a bookmark causes it to be marked as 'active'.
911 925 The active bookmark is indicated with a '*'.
912 926 When a commit is made, the active bookmark will advance to the new commit.
913 927 A plain :hg:`update` will also advance an active bookmark, if possible.
914 928 Updating away from a bookmark will cause it to be deactivated.
915 929
916 930 Bookmarks can be pushed and pulled between repositories (see
917 931 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
918 932 diverged, a new 'divergent bookmark' of the form 'name@path' will
919 933 be created. Using :hg:`merge` will resolve the divergence.
920 934
921 935 A bookmark named '@' has the special property that :hg:`clone` will
922 936 check it out by default if it exists.
923 937
924 938 .. container:: verbose
925 939
926 940 Examples:
927 941
928 942 - create an active bookmark for a new line of development::
929 943
930 944 hg book new-feature
931 945
932 946 - create an inactive bookmark as a place marker::
933 947
934 948 hg book -i reviewed
935 949
936 950 - create an inactive bookmark on another changeset::
937 951
938 952 hg book -r .^ tested
939 953
940 954 - rename bookmark turkey to dinner::
941 955
942 956 hg book -m turkey dinner
943 957
944 958 - move the '@' bookmark from another branch::
945 959
946 960 hg book -f @
947 961 '''
948 962 force = opts.get('force')
949 963 rev = opts.get('rev')
950 964 delete = opts.get('delete')
951 965 rename = opts.get('rename')
952 966 inactive = opts.get('inactive')
953 967
954 968 def checkformat(mark):
955 969 mark = mark.strip()
956 970 if not mark:
957 971 raise error.Abort(_("bookmark names cannot consist entirely of "
958 972 "whitespace"))
959 973 scmutil.checknewlabel(repo, mark, 'bookmark')
960 974 return mark
961 975
962 976 def checkconflict(repo, mark, cur, force=False, target=None):
963 977 if mark in marks and not force:
964 978 if target:
965 979 if marks[mark] == target and target == cur:
966 980 # re-activating a bookmark
967 981 return
968 982 anc = repo.changelog.ancestors([repo[target].rev()])
969 983 bmctx = repo[marks[mark]]
970 984 divs = [repo[b].node() for b in marks
971 985 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
972 986
973 987 # allow resolving a single divergent bookmark even if moving
974 988 # the bookmark across branches when a revision is specified
975 989 # that contains a divergent bookmark
976 990 if bmctx.rev() not in anc and target in divs:
977 991 bookmarks.deletedivergent(repo, [target], mark)
978 992 return
979 993
980 994 deletefrom = [b for b in divs
981 995 if repo[b].rev() in anc or b == target]
982 996 bookmarks.deletedivergent(repo, deletefrom, mark)
983 997 if bookmarks.validdest(repo, bmctx, repo[target]):
984 998 ui.status(_("moving bookmark '%s' forward from %s\n") %
985 999 (mark, short(bmctx.node())))
986 1000 return
987 1001 raise error.Abort(_("bookmark '%s' already exists "
988 1002 "(use -f to force)") % mark)
989 1003 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
990 1004 and not force):
991 1005 raise error.Abort(
992 1006 _("a bookmark cannot have the name of an existing branch"))
993 1007
994 1008 if delete and rename:
995 1009 raise error.Abort(_("--delete and --rename are incompatible"))
996 1010 if delete and rev:
997 1011 raise error.Abort(_("--rev is incompatible with --delete"))
998 1012 if rename and rev:
999 1013 raise error.Abort(_("--rev is incompatible with --rename"))
1000 1014 if not names and (delete or rev):
1001 1015 raise error.Abort(_("bookmark name required"))
1002 1016
1003 1017 if delete or rename or names or inactive:
1004 1018 wlock = lock = tr = None
1005 1019 try:
1006 1020 wlock = repo.wlock()
1007 1021 lock = repo.lock()
1008 1022 cur = repo.changectx('.').node()
1009 1023 marks = repo._bookmarks
1010 1024 if delete:
1011 1025 tr = repo.transaction('bookmark')
1012 1026 for mark in names:
1013 1027 if mark not in marks:
1014 1028 raise error.Abort(_("bookmark '%s' does not exist") %
1015 1029 mark)
1016 1030 if mark == repo._activebookmark:
1017 1031 bookmarks.deactivate(repo)
1018 1032 del marks[mark]
1019 1033
1020 1034 elif rename:
1021 1035 tr = repo.transaction('bookmark')
1022 1036 if not names:
1023 1037 raise error.Abort(_("new bookmark name required"))
1024 1038 elif len(names) > 1:
1025 1039 raise error.Abort(_("only one new bookmark name allowed"))
1026 1040 mark = checkformat(names[0])
1027 1041 if rename not in marks:
1028 1042 raise error.Abort(_("bookmark '%s' does not exist")
1029 1043 % rename)
1030 1044 checkconflict(repo, mark, cur, force)
1031 1045 marks[mark] = marks[rename]
1032 1046 if repo._activebookmark == rename and not inactive:
1033 1047 bookmarks.activate(repo, mark)
1034 1048 del marks[rename]
1035 1049 elif names:
1036 1050 tr = repo.transaction('bookmark')
1037 1051 newact = None
1038 1052 for mark in names:
1039 1053 mark = checkformat(mark)
1040 1054 if newact is None:
1041 1055 newact = mark
1042 1056 if inactive and mark == repo._activebookmark:
1043 1057 bookmarks.deactivate(repo)
1044 1058 return
1045 1059 tgt = cur
1046 1060 if rev:
1047 1061 tgt = scmutil.revsingle(repo, rev).node()
1048 1062 checkconflict(repo, mark, cur, force, tgt)
1049 1063 marks[mark] = tgt
1050 1064 if not inactive and cur == marks[newact] and not rev:
1051 1065 bookmarks.activate(repo, newact)
1052 1066 elif cur != tgt and newact == repo._activebookmark:
1053 1067 bookmarks.deactivate(repo)
1054 1068 elif inactive:
1055 1069 if len(marks) == 0:
1056 1070 ui.status(_("no bookmarks set\n"))
1057 1071 elif not repo._activebookmark:
1058 1072 ui.status(_("no active bookmark\n"))
1059 1073 else:
1060 1074 bookmarks.deactivate(repo)
1061 1075 if tr is not None:
1062 1076 marks.recordchange(tr)
1063 1077 tr.close()
1064 1078 finally:
1065 1079 lockmod.release(tr, lock, wlock)
1066 1080 else: # show bookmarks
1067 1081 fm = ui.formatter('bookmarks', opts)
1068 1082 hexfn = fm.hexfunc
1069 1083 marks = repo._bookmarks
1070 1084 if len(marks) == 0 and not fm:
1071 1085 ui.status(_("no bookmarks set\n"))
1072 1086 for bmark, n in sorted(marks.iteritems()):
1073 1087 active = repo._activebookmark
1074 1088 if bmark == active:
1075 1089 prefix, label = '*', activebookmarklabel
1076 1090 else:
1077 1091 prefix, label = ' ', ''
1078 1092
1079 1093 fm.startitem()
1080 1094 if not ui.quiet:
1081 1095 fm.plain(' %s ' % prefix, label=label)
1082 1096 fm.write('bookmark', '%s', bmark, label=label)
1083 1097 pad = " " * (25 - encoding.colwidth(bmark))
1084 1098 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1085 1099 repo.changelog.rev(n), hexfn(n), label=label)
1086 1100 fm.data(active=(bmark == active))
1087 1101 fm.plain('\n')
1088 1102 fm.end()
1089 1103
1090 1104 @command('branch',
1091 1105 [('f', 'force', None,
1092 1106 _('set branch name even if it shadows an existing branch')),
1093 1107 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1094 1108 _('[-fC] [NAME]'))
1095 1109 def branch(ui, repo, label=None, **opts):
1096 1110 """set or show the current branch name
1097 1111
1098 1112 .. note::
1099 1113
1100 1114 Branch names are permanent and global. Use :hg:`bookmark` to create a
1101 1115 light-weight bookmark instead. See :hg:`help glossary` for more
1102 1116 information about named branches and bookmarks.
1103 1117
1104 1118 With no argument, show the current branch name. With one argument,
1105 1119 set the working directory branch name (the branch will not exist
1106 1120 in the repository until the next commit). Standard practice
1107 1121 recommends that primary development take place on the 'default'
1108 1122 branch.
1109 1123
1110 1124 Unless -f/--force is specified, branch will not let you set a
1111 1125 branch name that already exists.
1112 1126
1113 1127 Use -C/--clean to reset the working directory branch to that of
1114 1128 the parent of the working directory, negating a previous branch
1115 1129 change.
1116 1130
1117 1131 Use the command :hg:`update` to switch to an existing branch. Use
1118 1132 :hg:`commit --close-branch` to mark this branch head as closed.
1119 1133 When all heads of the branch are closed, the branch will be
1120 1134 considered closed.
1121 1135
1122 1136 Returns 0 on success.
1123 1137 """
1124 1138 if label:
1125 1139 label = label.strip()
1126 1140
1127 1141 if not opts.get('clean') and not label:
1128 1142 ui.write("%s\n" % repo.dirstate.branch())
1129 1143 return
1130 1144
1131 1145 wlock = repo.wlock()
1132 1146 try:
1133 1147 if opts.get('clean'):
1134 1148 label = repo[None].p1().branch()
1135 1149 repo.dirstate.setbranch(label)
1136 1150 ui.status(_('reset working directory to branch %s\n') % label)
1137 1151 elif label:
1138 1152 if not opts.get('force') and label in repo.branchmap():
1139 1153 if label not in [p.branch() for p in repo.parents()]:
1140 1154 raise error.Abort(_('a branch of the same name already'
1141 1155 ' exists'),
1142 1156 # i18n: "it" refers to an existing branch
1143 1157 hint=_("use 'hg update' to switch to it"))
1144 1158 scmutil.checknewlabel(repo, label, 'branch')
1145 1159 repo.dirstate.setbranch(label)
1146 1160 ui.status(_('marked working directory as branch %s\n') % label)
1147 1161
1148 1162 # find any open named branches aside from default
1149 1163 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1150 1164 if n != "default" and not c]
1151 1165 if not others:
1152 1166 ui.status(_('(branches are permanent and global, '
1153 1167 'did you want a bookmark?)\n'))
1154 1168 finally:
1155 1169 wlock.release()
1156 1170
1157 1171 @command('branches',
1158 1172 [('a', 'active', False,
1159 1173 _('show only branches that have unmerged heads (DEPRECATED)')),
1160 1174 ('c', 'closed', False, _('show normal and closed branches')),
1161 1175 ] + formatteropts,
1162 1176 _('[-ac]'))
1163 1177 def branches(ui, repo, active=False, closed=False, **opts):
1164 1178 """list repository named branches
1165 1179
1166 1180 List the repository's named branches, indicating which ones are
1167 1181 inactive. If -c/--closed is specified, also list branches which have
1168 1182 been marked closed (see :hg:`commit --close-branch`).
1169 1183
1170 1184 Use the command :hg:`update` to switch to an existing branch.
1171 1185
1172 1186 Returns 0.
1173 1187 """
1174 1188
1175 1189 fm = ui.formatter('branches', opts)
1176 1190 hexfunc = fm.hexfunc
1177 1191
1178 1192 allheads = set(repo.heads())
1179 1193 branches = []
1180 1194 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1181 1195 isactive = not isclosed and bool(set(heads) & allheads)
1182 1196 branches.append((tag, repo[tip], isactive, not isclosed))
1183 1197 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1184 1198 reverse=True)
1185 1199
1186 1200 for tag, ctx, isactive, isopen in branches:
1187 1201 if active and not isactive:
1188 1202 continue
1189 1203 if isactive:
1190 1204 label = 'branches.active'
1191 1205 notice = ''
1192 1206 elif not isopen:
1193 1207 if not closed:
1194 1208 continue
1195 1209 label = 'branches.closed'
1196 1210 notice = _(' (closed)')
1197 1211 else:
1198 1212 label = 'branches.inactive'
1199 1213 notice = _(' (inactive)')
1200 1214 current = (tag == repo.dirstate.branch())
1201 1215 if current:
1202 1216 label = 'branches.current'
1203 1217
1204 1218 fm.startitem()
1205 1219 fm.write('branch', '%s', tag, label=label)
1206 1220 rev = ctx.rev()
1207 1221 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1208 1222 fmt = ' ' * padsize + ' %d:%s'
1209 1223 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1210 1224 label='log.changeset changeset.%s' % ctx.phasestr())
1211 1225 fm.data(active=isactive, closed=not isopen, current=current)
1212 1226 if not ui.quiet:
1213 1227 fm.plain(notice)
1214 1228 fm.plain('\n')
1215 1229 fm.end()
1216 1230
1217 1231 @command('bundle',
1218 1232 [('f', 'force', None, _('run even when the destination is unrelated')),
1219 1233 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1220 1234 _('REV')),
1221 1235 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1222 1236 _('BRANCH')),
1223 1237 ('', 'base', [],
1224 1238 _('a base changeset assumed to be available at the destination'),
1225 1239 _('REV')),
1226 1240 ('a', 'all', None, _('bundle all changesets in the repository')),
1227 1241 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1228 1242 ] + remoteopts,
1229 1243 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1230 1244 def bundle(ui, repo, fname, dest=None, **opts):
1231 1245 """create a changegroup file
1232 1246
1233 1247 Generate a compressed changegroup file collecting changesets not
1234 1248 known to be in another repository.
1235 1249
1236 1250 If you omit the destination repository, then hg assumes the
1237 1251 destination will have all the nodes you specify with --base
1238 1252 parameters. To create a bundle containing all changesets, use
1239 1253 -a/--all (or --base null).
1240 1254
1241 1255 You can change bundle format with the -t/--type option. You can
1242 1256 specify a compression, a bundle version or both using a dash
1243 1257 (comp-version). The available compression methods are: none, bzip2,
1244 1258 and gzip (by default, bundles are compressed using bzip2). The
1245 1259 available format are: v1, v2 (default to most suitable).
1246 1260
1247 1261 The bundle file can then be transferred using conventional means
1248 1262 and applied to another repository with the unbundle or pull
1249 1263 command. This is useful when direct push and pull are not
1250 1264 available or when exporting an entire repository is undesirable.
1251 1265
1252 1266 Applying bundles preserves all changeset contents including
1253 1267 permissions, copy/rename information, and revision history.
1254 1268
1255 1269 Returns 0 on success, 1 if no changes found.
1256 1270 """
1257 1271 revs = None
1258 1272 if 'rev' in opts:
1259 1273 revs = scmutil.revrange(repo, opts['rev'])
1260 1274
1261 1275 bundletype = opts.get('type', 'bzip2').lower()
1262 1276 try:
1263 1277 bcompression, cgversion, params = exchange.parsebundlespec(
1264 1278 repo, bundletype, strict=False)
1265 1279 except error.UnsupportedBundleSpecification as e:
1266 1280 raise error.Abort(str(e),
1267 1281 hint=_('see "hg help bundle" for supported '
1268 1282 'values for --type'))
1269 1283
1270 1284 # Packed bundles are a pseudo bundle format for now.
1271 1285 if cgversion == 's1':
1272 1286 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1273 1287 hint=_('use "hg debugcreatestreamclonebundle"'))
1274 1288
1275 1289 if opts.get('all'):
1276 1290 base = ['null']
1277 1291 else:
1278 1292 base = scmutil.revrange(repo, opts.get('base'))
1279 1293 # TODO: get desired bundlecaps from command line.
1280 1294 bundlecaps = None
1281 1295 if base:
1282 1296 if dest:
1283 1297 raise error.Abort(_("--base is incompatible with specifying "
1284 1298 "a destination"))
1285 1299 common = [repo.lookup(rev) for rev in base]
1286 1300 heads = revs and map(repo.lookup, revs) or revs
1287 1301 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1288 1302 common=common, bundlecaps=bundlecaps,
1289 1303 version=cgversion)
1290 1304 outgoing = None
1291 1305 else:
1292 1306 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1293 1307 dest, branches = hg.parseurl(dest, opts.get('branch'))
1294 1308 other = hg.peer(repo, opts, dest)
1295 1309 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1296 1310 heads = revs and map(repo.lookup, revs) or revs
1297 1311 outgoing = discovery.findcommonoutgoing(repo, other,
1298 1312 onlyheads=heads,
1299 1313 force=opts.get('force'),
1300 1314 portable=True)
1301 1315 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1302 1316 bundlecaps, version=cgversion)
1303 1317 if not cg:
1304 1318 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1305 1319 return 1
1306 1320
1307 1321 if cgversion == '01': #bundle1
1308 1322 if bcompression is None:
1309 1323 bcompression = 'UN'
1310 1324 bversion = 'HG10' + bcompression
1311 1325 bcompression = None
1312 1326 else:
1313 1327 assert cgversion == '02'
1314 1328 bversion = 'HG20'
1315 1329
1316 1330
1317 1331 changegroup.writebundle(ui, cg, fname, bversion, compression=bcompression)
1318 1332
1319 1333 @command('cat',
1320 1334 [('o', 'output', '',
1321 1335 _('print output to file with formatted name'), _('FORMAT')),
1322 1336 ('r', 'rev', '', _('print the given revision'), _('REV')),
1323 1337 ('', 'decode', None, _('apply any matching decode filter')),
1324 1338 ] + walkopts,
1325 1339 _('[OPTION]... FILE...'),
1326 1340 inferrepo=True)
1327 1341 def cat(ui, repo, file1, *pats, **opts):
1328 1342 """output the current or given revision of files
1329 1343
1330 1344 Print the specified files as they were at the given revision. If
1331 1345 no revision is given, the parent of the working directory is used.
1332 1346
1333 1347 Output may be to a file, in which case the name of the file is
1334 1348 given using a format string. The formatting rules as follows:
1335 1349
1336 1350 :``%%``: literal "%" character
1337 1351 :``%s``: basename of file being printed
1338 1352 :``%d``: dirname of file being printed, or '.' if in repository root
1339 1353 :``%p``: root-relative path name of file being printed
1340 1354 :``%H``: changeset hash (40 hexadecimal digits)
1341 1355 :``%R``: changeset revision number
1342 1356 :``%h``: short-form changeset hash (12 hexadecimal digits)
1343 1357 :``%r``: zero-padded changeset revision number
1344 1358 :``%b``: basename of the exporting repository
1345 1359
1346 1360 Returns 0 on success.
1347 1361 """
1348 1362 ctx = scmutil.revsingle(repo, opts.get('rev'))
1349 1363 m = scmutil.match(ctx, (file1,) + pats, opts)
1350 1364
1351 1365 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1352 1366
1353 1367 @command('^clone',
1354 1368 [('U', 'noupdate', None, _('the clone will include an empty working '
1355 1369 'directory (only a repository)')),
1356 1370 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1357 1371 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1358 1372 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1359 1373 ('', 'pull', None, _('use pull protocol to copy metadata')),
1360 1374 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1361 1375 ] + remoteopts,
1362 1376 _('[OPTION]... SOURCE [DEST]'),
1363 1377 norepo=True)
1364 1378 def clone(ui, source, dest=None, **opts):
1365 1379 """make a copy of an existing repository
1366 1380
1367 1381 Create a copy of an existing repository in a new directory.
1368 1382
1369 1383 If no destination directory name is specified, it defaults to the
1370 1384 basename of the source.
1371 1385
1372 1386 The location of the source is added to the new repository's
1373 1387 ``.hg/hgrc`` file, as the default to be used for future pulls.
1374 1388
1375 1389 Only local paths and ``ssh://`` URLs are supported as
1376 1390 destinations. For ``ssh://`` destinations, no working directory or
1377 1391 ``.hg/hgrc`` will be created on the remote side.
1378 1392
1379 1393 To pull only a subset of changesets, specify one or more revisions
1380 1394 identifiers with -r/--rev or branches with -b/--branch. The
1381 1395 resulting clone will contain only the specified changesets and
1382 1396 their ancestors. These options (or 'clone src#rev dest') imply
1383 1397 --pull, even for local source repositories. Note that specifying a
1384 1398 tag will include the tagged changeset but not the changeset
1385 1399 containing the tag.
1386 1400
1387 1401 If the source repository has a bookmark called '@' set, that
1388 1402 revision will be checked out in the new repository by default.
1389 1403
1390 1404 To check out a particular version, use -u/--update, or
1391 1405 -U/--noupdate to create a clone with no working directory.
1392 1406
1393 1407 .. container:: verbose
1394 1408
1395 1409 For efficiency, hardlinks are used for cloning whenever the
1396 1410 source and destination are on the same filesystem (note this
1397 1411 applies only to the repository data, not to the working
1398 1412 directory). Some filesystems, such as AFS, implement hardlinking
1399 1413 incorrectly, but do not report errors. In these cases, use the
1400 1414 --pull option to avoid hardlinking.
1401 1415
1402 1416 In some cases, you can clone repositories and the working
1403 1417 directory using full hardlinks with ::
1404 1418
1405 1419 $ cp -al REPO REPOCLONE
1406 1420
1407 1421 This is the fastest way to clone, but it is not always safe. The
1408 1422 operation is not atomic (making sure REPO is not modified during
1409 1423 the operation is up to you) and you have to make sure your
1410 1424 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1411 1425 so). Also, this is not compatible with certain extensions that
1412 1426 place their metadata under the .hg directory, such as mq.
1413 1427
1414 1428 Mercurial will update the working directory to the first applicable
1415 1429 revision from this list:
1416 1430
1417 1431 a) null if -U or the source repository has no changesets
1418 1432 b) if -u . and the source repository is local, the first parent of
1419 1433 the source repository's working directory
1420 1434 c) the changeset specified with -u (if a branch name, this means the
1421 1435 latest head of that branch)
1422 1436 d) the changeset specified with -r
1423 1437 e) the tipmost head specified with -b
1424 1438 f) the tipmost head specified with the url#branch source syntax
1425 1439 g) the revision marked with the '@' bookmark, if present
1426 1440 h) the tipmost head of the default branch
1427 1441 i) tip
1428 1442
1429 1443 Examples:
1430 1444
1431 1445 - clone a remote repository to a new directory named hg/::
1432 1446
1433 1447 hg clone http://selenic.com/hg
1434 1448
1435 1449 - create a lightweight local clone::
1436 1450
1437 1451 hg clone project/ project-feature/
1438 1452
1439 1453 - clone from an absolute path on an ssh server (note double-slash)::
1440 1454
1441 1455 hg clone ssh://user@server//home/projects/alpha/
1442 1456
1443 1457 - do a high-speed clone over a LAN while checking out a
1444 1458 specified version::
1445 1459
1446 1460 hg clone --uncompressed http://server/repo -u 1.5
1447 1461
1448 1462 - create a repository without changesets after a particular revision::
1449 1463
1450 1464 hg clone -r 04e544 experimental/ good/
1451 1465
1452 1466 - clone (and track) a particular named branch::
1453 1467
1454 1468 hg clone http://selenic.com/hg#stable
1455 1469
1456 1470 See :hg:`help urls` for details on specifying URLs.
1457 1471
1458 1472 Returns 0 on success.
1459 1473 """
1460 1474 if opts.get('noupdate') and opts.get('updaterev'):
1461 1475 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1462 1476
1463 1477 r = hg.clone(ui, opts, source, dest,
1464 1478 pull=opts.get('pull'),
1465 1479 stream=opts.get('uncompressed'),
1466 1480 rev=opts.get('rev'),
1467 1481 update=opts.get('updaterev') or not opts.get('noupdate'),
1468 1482 branch=opts.get('branch'),
1469 1483 shareopts=opts.get('shareopts'))
1470 1484
1471 1485 return r is None
1472 1486
1473 1487 @command('^commit|ci',
1474 1488 [('A', 'addremove', None,
1475 1489 _('mark new/missing files as added/removed before committing')),
1476 1490 ('', 'close-branch', None,
1477 1491 _('mark a branch head as closed')),
1478 1492 ('', 'amend', None, _('amend the parent of the working directory')),
1479 1493 ('s', 'secret', None, _('use the secret phase for committing')),
1480 1494 ('e', 'edit', None, _('invoke editor on commit messages')),
1481 1495 ('i', 'interactive', None, _('use interactive mode')),
1482 1496 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1483 1497 _('[OPTION]... [FILE]...'),
1484 1498 inferrepo=True)
1485 1499 def commit(ui, repo, *pats, **opts):
1486 1500 """commit the specified files or all outstanding changes
1487 1501
1488 1502 Commit changes to the given files into the repository. Unlike a
1489 1503 centralized SCM, this operation is a local operation. See
1490 1504 :hg:`push` for a way to actively distribute your changes.
1491 1505
1492 1506 If a list of files is omitted, all changes reported by :hg:`status`
1493 1507 will be committed.
1494 1508
1495 1509 If you are committing the result of a merge, do not provide any
1496 1510 filenames or -I/-X filters.
1497 1511
1498 1512 If no commit message is specified, Mercurial starts your
1499 1513 configured editor where you can enter a message. In case your
1500 1514 commit fails, you will find a backup of your message in
1501 1515 ``.hg/last-message.txt``.
1502 1516
1503 1517 The --close-branch flag can be used to mark the current branch
1504 1518 head closed. When all heads of a branch are closed, the branch
1505 1519 will be considered closed and no longer listed.
1506 1520
1507 1521 The --amend flag can be used to amend the parent of the
1508 1522 working directory with a new commit that contains the changes
1509 1523 in the parent in addition to those currently reported by :hg:`status`,
1510 1524 if there are any. The old commit is stored in a backup bundle in
1511 1525 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1512 1526 on how to restore it).
1513 1527
1514 1528 Message, user and date are taken from the amended commit unless
1515 1529 specified. When a message isn't specified on the command line,
1516 1530 the editor will open with the message of the amended commit.
1517 1531
1518 1532 It is not possible to amend public changesets (see :hg:`help phases`)
1519 1533 or changesets that have children.
1520 1534
1521 1535 See :hg:`help dates` for a list of formats valid for -d/--date.
1522 1536
1523 1537 Returns 0 on success, 1 if nothing changed.
1524 1538 """
1525 1539 if opts.get('interactive'):
1526 1540 opts.pop('interactive')
1527 1541 cmdutil.dorecord(ui, repo, commit, None, False,
1528 1542 cmdutil.recordfilter, *pats, **opts)
1529 1543 return
1530 1544
1531 1545 if opts.get('subrepos'):
1532 1546 if opts.get('amend'):
1533 1547 raise error.Abort(_('cannot amend with --subrepos'))
1534 1548 # Let --subrepos on the command line override config setting.
1535 1549 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1536 1550
1537 1551 cmdutil.checkunfinished(repo, commit=True)
1538 1552
1539 1553 branch = repo[None].branch()
1540 1554 bheads = repo.branchheads(branch)
1541 1555
1542 1556 extra = {}
1543 1557 if opts.get('close_branch'):
1544 1558 extra['close'] = 1
1545 1559
1546 1560 if not bheads:
1547 1561 raise error.Abort(_('can only close branch heads'))
1548 1562 elif opts.get('amend'):
1549 1563 if repo.parents()[0].p1().branch() != branch and \
1550 1564 repo.parents()[0].p2().branch() != branch:
1551 1565 raise error.Abort(_('can only close branch heads'))
1552 1566
1553 1567 if opts.get('amend'):
1554 1568 if ui.configbool('ui', 'commitsubrepos'):
1555 1569 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1556 1570
1557 1571 old = repo['.']
1558 1572 if not old.mutable():
1559 1573 raise error.Abort(_('cannot amend public changesets'))
1560 1574 if len(repo[None].parents()) > 1:
1561 1575 raise error.Abort(_('cannot amend while merging'))
1562 1576 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1563 1577 if not allowunstable and old.children():
1564 1578 raise error.Abort(_('cannot amend changeset with children'))
1565 1579
1566 1580 # commitfunc is used only for temporary amend commit by cmdutil.amend
1567 1581 def commitfunc(ui, repo, message, match, opts):
1568 1582 return repo.commit(message,
1569 1583 opts.get('user') or old.user(),
1570 1584 opts.get('date') or old.date(),
1571 1585 match,
1572 1586 extra=extra)
1573 1587
1574 1588 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1575 1589 if node == old.node():
1576 1590 ui.status(_("nothing changed\n"))
1577 1591 return 1
1578 1592 else:
1579 1593 def commitfunc(ui, repo, message, match, opts):
1580 1594 backup = ui.backupconfig('phases', 'new-commit')
1581 1595 baseui = repo.baseui
1582 1596 basebackup = baseui.backupconfig('phases', 'new-commit')
1583 1597 try:
1584 1598 if opts.get('secret'):
1585 1599 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1586 1600 # Propagate to subrepos
1587 1601 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1588 1602
1589 1603 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1590 1604 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1591 1605 return repo.commit(message, opts.get('user'), opts.get('date'),
1592 1606 match,
1593 1607 editor=editor,
1594 1608 extra=extra)
1595 1609 finally:
1596 1610 ui.restoreconfig(backup)
1597 1611 repo.baseui.restoreconfig(basebackup)
1598 1612
1599 1613
1600 1614 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1601 1615
1602 1616 if not node:
1603 1617 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1604 1618 if stat[3]:
1605 1619 ui.status(_("nothing changed (%d missing files, see "
1606 1620 "'hg status')\n") % len(stat[3]))
1607 1621 else:
1608 1622 ui.status(_("nothing changed\n"))
1609 1623 return 1
1610 1624
1611 1625 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1612 1626
1613 1627 @command('config|showconfig|debugconfig',
1614 1628 [('u', 'untrusted', None, _('show untrusted configuration options')),
1615 1629 ('e', 'edit', None, _('edit user config')),
1616 1630 ('l', 'local', None, _('edit repository config')),
1617 1631 ('g', 'global', None, _('edit global config'))],
1618 1632 _('[-u] [NAME]...'),
1619 1633 optionalrepo=True)
1620 1634 def config(ui, repo, *values, **opts):
1621 1635 """show combined config settings from all hgrc files
1622 1636
1623 1637 With no arguments, print names and values of all config items.
1624 1638
1625 1639 With one argument of the form section.name, print just the value
1626 1640 of that config item.
1627 1641
1628 1642 With multiple arguments, print names and values of all config
1629 1643 items with matching section names.
1630 1644
1631 1645 With --edit, start an editor on the user-level config file. With
1632 1646 --global, edit the system-wide config file. With --local, edit the
1633 1647 repository-level config file.
1634 1648
1635 1649 With --debug, the source (filename and line number) is printed
1636 1650 for each config item.
1637 1651
1638 1652 See :hg:`help config` for more information about config files.
1639 1653
1640 1654 Returns 0 on success, 1 if NAME does not exist.
1641 1655
1642 1656 """
1643 1657
1644 1658 if opts.get('edit') or opts.get('local') or opts.get('global'):
1645 1659 if opts.get('local') and opts.get('global'):
1646 1660 raise error.Abort(_("can't use --local and --global together"))
1647 1661
1648 1662 if opts.get('local'):
1649 1663 if not repo:
1650 1664 raise error.Abort(_("can't use --local outside a repository"))
1651 1665 paths = [repo.join('hgrc')]
1652 1666 elif opts.get('global'):
1653 1667 paths = scmutil.systemrcpath()
1654 1668 else:
1655 1669 paths = scmutil.userrcpath()
1656 1670
1657 1671 for f in paths:
1658 1672 if os.path.exists(f):
1659 1673 break
1660 1674 else:
1661 1675 if opts.get('global'):
1662 1676 samplehgrc = uimod.samplehgrcs['global']
1663 1677 elif opts.get('local'):
1664 1678 samplehgrc = uimod.samplehgrcs['local']
1665 1679 else:
1666 1680 samplehgrc = uimod.samplehgrcs['user']
1667 1681
1668 1682 f = paths[0]
1669 1683 fp = open(f, "w")
1670 1684 fp.write(samplehgrc)
1671 1685 fp.close()
1672 1686
1673 1687 editor = ui.geteditor()
1674 1688 ui.system("%s \"%s\"" % (editor, f),
1675 1689 onerr=error.Abort, errprefix=_("edit failed"))
1676 1690 return
1677 1691
1678 1692 for f in scmutil.rcpath():
1679 1693 ui.debug('read config from: %s\n' % f)
1680 1694 untrusted = bool(opts.get('untrusted'))
1681 1695 if values:
1682 1696 sections = [v for v in values if '.' not in v]
1683 1697 items = [v for v in values if '.' in v]
1684 1698 if len(items) > 1 or items and sections:
1685 1699 raise error.Abort(_('only one config item permitted'))
1686 1700 matched = False
1687 1701 for section, name, value in ui.walkconfig(untrusted=untrusted):
1688 1702 value = str(value).replace('\n', '\\n')
1689 1703 sectname = section + '.' + name
1690 1704 if values:
1691 1705 for v in values:
1692 1706 if v == section:
1693 1707 ui.debug('%s: ' %
1694 1708 ui.configsource(section, name, untrusted))
1695 1709 ui.write('%s=%s\n' % (sectname, value))
1696 1710 matched = True
1697 1711 elif v == sectname:
1698 1712 ui.debug('%s: ' %
1699 1713 ui.configsource(section, name, untrusted))
1700 1714 ui.write(value, '\n')
1701 1715 matched = True
1702 1716 else:
1703 1717 ui.debug('%s: ' %
1704 1718 ui.configsource(section, name, untrusted))
1705 1719 ui.write('%s=%s\n' % (sectname, value))
1706 1720 matched = True
1707 1721 if matched:
1708 1722 return 0
1709 1723 return 1
1710 1724
1711 1725 @command('copy|cp',
1712 1726 [('A', 'after', None, _('record a copy that has already occurred')),
1713 1727 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1714 1728 ] + walkopts + dryrunopts,
1715 1729 _('[OPTION]... [SOURCE]... DEST'))
1716 1730 def copy(ui, repo, *pats, **opts):
1717 1731 """mark files as copied for the next commit
1718 1732
1719 1733 Mark dest as having copies of source files. If dest is a
1720 1734 directory, copies are put in that directory. If dest is a file,
1721 1735 the source must be a single file.
1722 1736
1723 1737 By default, this command copies the contents of files as they
1724 1738 exist in the working directory. If invoked with -A/--after, the
1725 1739 operation is recorded, but no copying is performed.
1726 1740
1727 1741 This command takes effect with the next commit. To undo a copy
1728 1742 before that, see :hg:`revert`.
1729 1743
1730 1744 Returns 0 on success, 1 if errors are encountered.
1731 1745 """
1732 1746 wlock = repo.wlock(False)
1733 1747 try:
1734 1748 return cmdutil.copy(ui, repo, pats, opts)
1735 1749 finally:
1736 1750 wlock.release()
1737 1751
1738 1752 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1739 1753 def debugancestor(ui, repo, *args):
1740 1754 """find the ancestor revision of two revisions in a given index"""
1741 1755 if len(args) == 3:
1742 1756 index, rev1, rev2 = args
1743 1757 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1744 1758 lookup = r.lookup
1745 1759 elif len(args) == 2:
1746 1760 if not repo:
1747 1761 raise error.Abort(_("there is no Mercurial repository here "
1748 1762 "(.hg not found)"))
1749 1763 rev1, rev2 = args
1750 1764 r = repo.changelog
1751 1765 lookup = repo.lookup
1752 1766 else:
1753 1767 raise error.Abort(_('either two or three arguments required'))
1754 1768 a = r.ancestor(lookup(rev1), lookup(rev2))
1755 1769 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1756 1770
1757 1771 @command('debugbuilddag',
1758 1772 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1759 1773 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1760 1774 ('n', 'new-file', None, _('add new file at each rev'))],
1761 1775 _('[OPTION]... [TEXT]'))
1762 1776 def debugbuilddag(ui, repo, text=None,
1763 1777 mergeable_file=False,
1764 1778 overwritten_file=False,
1765 1779 new_file=False):
1766 1780 """builds a repo with a given DAG from scratch in the current empty repo
1767 1781
1768 1782 The description of the DAG is read from stdin if not given on the
1769 1783 command line.
1770 1784
1771 1785 Elements:
1772 1786
1773 1787 - "+n" is a linear run of n nodes based on the current default parent
1774 1788 - "." is a single node based on the current default parent
1775 1789 - "$" resets the default parent to null (implied at the start);
1776 1790 otherwise the default parent is always the last node created
1777 1791 - "<p" sets the default parent to the backref p
1778 1792 - "*p" is a fork at parent p, which is a backref
1779 1793 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1780 1794 - "/p2" is a merge of the preceding node and p2
1781 1795 - ":tag" defines a local tag for the preceding node
1782 1796 - "@branch" sets the named branch for subsequent nodes
1783 1797 - "#...\\n" is a comment up to the end of the line
1784 1798
1785 1799 Whitespace between the above elements is ignored.
1786 1800
1787 1801 A backref is either
1788 1802
1789 1803 - a number n, which references the node curr-n, where curr is the current
1790 1804 node, or
1791 1805 - the name of a local tag you placed earlier using ":tag", or
1792 1806 - empty to denote the default parent.
1793 1807
1794 1808 All string valued-elements are either strictly alphanumeric, or must
1795 1809 be enclosed in double quotes ("..."), with "\\" as escape character.
1796 1810 """
1797 1811
1798 1812 if text is None:
1799 1813 ui.status(_("reading DAG from stdin\n"))
1800 1814 text = ui.fin.read()
1801 1815
1802 1816 cl = repo.changelog
1803 1817 if len(cl) > 0:
1804 1818 raise error.Abort(_('repository is not empty'))
1805 1819
1806 1820 # determine number of revs in DAG
1807 1821 total = 0
1808 1822 for type, data in dagparser.parsedag(text):
1809 1823 if type == 'n':
1810 1824 total += 1
1811 1825
1812 1826 if mergeable_file:
1813 1827 linesperrev = 2
1814 1828 # make a file with k lines per rev
1815 1829 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1816 1830 initialmergedlines.append("")
1817 1831
1818 1832 tags = []
1819 1833
1820 1834 lock = tr = None
1821 1835 try:
1822 1836 lock = repo.lock()
1823 1837 tr = repo.transaction("builddag")
1824 1838
1825 1839 at = -1
1826 1840 atbranch = 'default'
1827 1841 nodeids = []
1828 1842 id = 0
1829 1843 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1830 1844 for type, data in dagparser.parsedag(text):
1831 1845 if type == 'n':
1832 1846 ui.note(('node %s\n' % str(data)))
1833 1847 id, ps = data
1834 1848
1835 1849 files = []
1836 1850 fctxs = {}
1837 1851
1838 1852 p2 = None
1839 1853 if mergeable_file:
1840 1854 fn = "mf"
1841 1855 p1 = repo[ps[0]]
1842 1856 if len(ps) > 1:
1843 1857 p2 = repo[ps[1]]
1844 1858 pa = p1.ancestor(p2)
1845 1859 base, local, other = [x[fn].data() for x in (pa, p1,
1846 1860 p2)]
1847 1861 m3 = simplemerge.Merge3Text(base, local, other)
1848 1862 ml = [l.strip() for l in m3.merge_lines()]
1849 1863 ml.append("")
1850 1864 elif at > 0:
1851 1865 ml = p1[fn].data().split("\n")
1852 1866 else:
1853 1867 ml = initialmergedlines
1854 1868 ml[id * linesperrev] += " r%i" % id
1855 1869 mergedtext = "\n".join(ml)
1856 1870 files.append(fn)
1857 1871 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1858 1872
1859 1873 if overwritten_file:
1860 1874 fn = "of"
1861 1875 files.append(fn)
1862 1876 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1863 1877
1864 1878 if new_file:
1865 1879 fn = "nf%i" % id
1866 1880 files.append(fn)
1867 1881 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1868 1882 if len(ps) > 1:
1869 1883 if not p2:
1870 1884 p2 = repo[ps[1]]
1871 1885 for fn in p2:
1872 1886 if fn.startswith("nf"):
1873 1887 files.append(fn)
1874 1888 fctxs[fn] = p2[fn]
1875 1889
1876 1890 def fctxfn(repo, cx, path):
1877 1891 return fctxs.get(path)
1878 1892
1879 1893 if len(ps) == 0 or ps[0] < 0:
1880 1894 pars = [None, None]
1881 1895 elif len(ps) == 1:
1882 1896 pars = [nodeids[ps[0]], None]
1883 1897 else:
1884 1898 pars = [nodeids[p] for p in ps]
1885 1899 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1886 1900 date=(id, 0),
1887 1901 user="debugbuilddag",
1888 1902 extra={'branch': atbranch})
1889 1903 nodeid = repo.commitctx(cx)
1890 1904 nodeids.append(nodeid)
1891 1905 at = id
1892 1906 elif type == 'l':
1893 1907 id, name = data
1894 1908 ui.note(('tag %s\n' % name))
1895 1909 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1896 1910 elif type == 'a':
1897 1911 ui.note(('branch %s\n' % data))
1898 1912 atbranch = data
1899 1913 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1900 1914 tr.close()
1901 1915
1902 1916 if tags:
1903 1917 repo.vfs.write("localtags", "".join(tags))
1904 1918 finally:
1905 1919 ui.progress(_('building'), None)
1906 1920 release(tr, lock)
1907 1921
1908 1922 @command('debugbundle',
1909 1923 [('a', 'all', None, _('show all details'))],
1910 1924 _('FILE'),
1911 1925 norepo=True)
1912 1926 def debugbundle(ui, bundlepath, all=None, **opts):
1913 1927 """lists the contents of a bundle"""
1914 1928 f = hg.openpath(ui, bundlepath)
1915 1929 try:
1916 1930 gen = exchange.readbundle(ui, f, bundlepath)
1917 1931 if isinstance(gen, bundle2.unbundle20):
1918 1932 return _debugbundle2(ui, gen, all=all, **opts)
1919 1933 if all:
1920 1934 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1921 1935
1922 1936 def showchunks(named):
1923 1937 ui.write("\n%s\n" % named)
1924 1938 chain = None
1925 1939 while True:
1926 1940 chunkdata = gen.deltachunk(chain)
1927 1941 if not chunkdata:
1928 1942 break
1929 1943 node = chunkdata['node']
1930 1944 p1 = chunkdata['p1']
1931 1945 p2 = chunkdata['p2']
1932 1946 cs = chunkdata['cs']
1933 1947 deltabase = chunkdata['deltabase']
1934 1948 delta = chunkdata['delta']
1935 1949 ui.write("%s %s %s %s %s %s\n" %
1936 1950 (hex(node), hex(p1), hex(p2),
1937 1951 hex(cs), hex(deltabase), len(delta)))
1938 1952 chain = node
1939 1953
1940 1954 chunkdata = gen.changelogheader()
1941 1955 showchunks("changelog")
1942 1956 chunkdata = gen.manifestheader()
1943 1957 showchunks("manifest")
1944 1958 while True:
1945 1959 chunkdata = gen.filelogheader()
1946 1960 if not chunkdata:
1947 1961 break
1948 1962 fname = chunkdata['filename']
1949 1963 showchunks(fname)
1950 1964 else:
1951 1965 if isinstance(gen, bundle2.unbundle20):
1952 1966 raise error.Abort(_('use debugbundle2 for this file'))
1953 1967 chunkdata = gen.changelogheader()
1954 1968 chain = None
1955 1969 while True:
1956 1970 chunkdata = gen.deltachunk(chain)
1957 1971 if not chunkdata:
1958 1972 break
1959 1973 node = chunkdata['node']
1960 1974 ui.write("%s\n" % hex(node))
1961 1975 chain = node
1962 1976 finally:
1963 1977 f.close()
1964 1978
1965 1979 def _debugbundle2(ui, gen, **opts):
1966 1980 """lists the contents of a bundle2"""
1967 1981 if not isinstance(gen, bundle2.unbundle20):
1968 1982 raise error.Abort(_('not a bundle2 file'))
1969 1983 ui.write(('Stream params: %s\n' % repr(gen.params)))
1970 1984 for part in gen.iterparts():
1971 1985 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1972 1986 if part.type == 'changegroup':
1973 1987 version = part.params.get('version', '01')
1974 1988 cg = changegroup.packermap[version][1](part, 'UN')
1975 1989 chunkdata = cg.changelogheader()
1976 1990 chain = None
1977 1991 while True:
1978 1992 chunkdata = cg.deltachunk(chain)
1979 1993 if not chunkdata:
1980 1994 break
1981 1995 node = chunkdata['node']
1982 1996 ui.write(" %s\n" % hex(node))
1983 1997 chain = node
1984 1998
1985 1999 @command('debugcreatestreamclonebundle', [], 'FILE')
1986 2000 def debugcreatestreamclonebundle(ui, repo, fname):
1987 2001 """create a stream clone bundle file
1988 2002
1989 2003 Stream bundles are special bundles that are essentially archives of
1990 2004 revlog files. They are commonly used for cloning very quickly.
1991 2005 """
1992 2006 requirements, gen = streamclone.generatebundlev1(repo)
1993 2007 changegroup.writechunks(ui, gen, fname)
1994 2008
1995 2009 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
1996 2010
1997 2011 @command('debugapplystreamclonebundle', [], 'FILE')
1998 2012 def debugapplystreamclonebundle(ui, repo, fname):
1999 2013 """apply a stream clone bundle file"""
2000 2014 f = hg.openpath(ui, fname)
2001 2015 gen = exchange.readbundle(ui, f, fname)
2002 2016 gen.apply(repo)
2003 2017
2004 2018 @command('debugcheckstate', [], '')
2005 2019 def debugcheckstate(ui, repo):
2006 2020 """validate the correctness of the current dirstate"""
2007 2021 parent1, parent2 = repo.dirstate.parents()
2008 2022 m1 = repo[parent1].manifest()
2009 2023 m2 = repo[parent2].manifest()
2010 2024 errors = 0
2011 2025 for f in repo.dirstate:
2012 2026 state = repo.dirstate[f]
2013 2027 if state in "nr" and f not in m1:
2014 2028 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
2015 2029 errors += 1
2016 2030 if state in "a" and f in m1:
2017 2031 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
2018 2032 errors += 1
2019 2033 if state in "m" and f not in m1 and f not in m2:
2020 2034 ui.warn(_("%s in state %s, but not in either manifest\n") %
2021 2035 (f, state))
2022 2036 errors += 1
2023 2037 for f in m1:
2024 2038 state = repo.dirstate[f]
2025 2039 if state not in "nrm":
2026 2040 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
2027 2041 errors += 1
2028 2042 if errors:
2029 2043 error = _(".hg/dirstate inconsistent with current parent's manifest")
2030 2044 raise error.Abort(error)
2031 2045
2032 2046 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
2033 2047 def debugcommands(ui, cmd='', *args):
2034 2048 """list all available commands and options"""
2035 2049 for cmd, vals in sorted(table.iteritems()):
2036 2050 cmd = cmd.split('|')[0].strip('^')
2037 2051 opts = ', '.join([i[1] for i in vals[1]])
2038 2052 ui.write('%s: %s\n' % (cmd, opts))
2039 2053
2040 2054 @command('debugcomplete',
2041 2055 [('o', 'options', None, _('show the command options'))],
2042 2056 _('[-o] CMD'),
2043 2057 norepo=True)
2044 2058 def debugcomplete(ui, cmd='', **opts):
2045 2059 """returns the completion list associated with the given command"""
2046 2060
2047 2061 if opts.get('options'):
2048 2062 options = []
2049 2063 otables = [globalopts]
2050 2064 if cmd:
2051 2065 aliases, entry = cmdutil.findcmd(cmd, table, False)
2052 2066 otables.append(entry[1])
2053 2067 for t in otables:
2054 2068 for o in t:
2055 2069 if "(DEPRECATED)" in o[3]:
2056 2070 continue
2057 2071 if o[0]:
2058 2072 options.append('-%s' % o[0])
2059 2073 options.append('--%s' % o[1])
2060 2074 ui.write("%s\n" % "\n".join(options))
2061 2075 return
2062 2076
2063 2077 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2064 2078 if ui.verbose:
2065 2079 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2066 2080 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2067 2081
2068 2082 @command('debugdag',
2069 2083 [('t', 'tags', None, _('use tags as labels')),
2070 2084 ('b', 'branches', None, _('annotate with branch names')),
2071 2085 ('', 'dots', None, _('use dots for runs')),
2072 2086 ('s', 'spaces', None, _('separate elements by spaces'))],
2073 2087 _('[OPTION]... [FILE [REV]...]'),
2074 2088 optionalrepo=True)
2075 2089 def debugdag(ui, repo, file_=None, *revs, **opts):
2076 2090 """format the changelog or an index DAG as a concise textual description
2077 2091
2078 2092 If you pass a revlog index, the revlog's DAG is emitted. If you list
2079 2093 revision numbers, they get labeled in the output as rN.
2080 2094
2081 2095 Otherwise, the changelog DAG of the current repo is emitted.
2082 2096 """
2083 2097 spaces = opts.get('spaces')
2084 2098 dots = opts.get('dots')
2085 2099 if file_:
2086 2100 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2087 2101 revs = set((int(r) for r in revs))
2088 2102 def events():
2089 2103 for r in rlog:
2090 2104 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2091 2105 if p != -1))
2092 2106 if r in revs:
2093 2107 yield 'l', (r, "r%i" % r)
2094 2108 elif repo:
2095 2109 cl = repo.changelog
2096 2110 tags = opts.get('tags')
2097 2111 branches = opts.get('branches')
2098 2112 if tags:
2099 2113 labels = {}
2100 2114 for l, n in repo.tags().items():
2101 2115 labels.setdefault(cl.rev(n), []).append(l)
2102 2116 def events():
2103 2117 b = "default"
2104 2118 for r in cl:
2105 2119 if branches:
2106 2120 newb = cl.read(cl.node(r))[5]['branch']
2107 2121 if newb != b:
2108 2122 yield 'a', newb
2109 2123 b = newb
2110 2124 yield 'n', (r, list(p for p in cl.parentrevs(r)
2111 2125 if p != -1))
2112 2126 if tags:
2113 2127 ls = labels.get(r)
2114 2128 if ls:
2115 2129 for l in ls:
2116 2130 yield 'l', (r, l)
2117 2131 else:
2118 2132 raise error.Abort(_('need repo for changelog dag'))
2119 2133
2120 2134 for line in dagparser.dagtextlines(events(),
2121 2135 addspaces=spaces,
2122 2136 wraplabels=True,
2123 2137 wrapannotations=True,
2124 2138 wrapnonlinear=dots,
2125 2139 usedots=dots,
2126 2140 maxlinewidth=70):
2127 2141 ui.write(line)
2128 2142 ui.write("\n")
2129 2143
2130 2144 @command('debugdata',
2131 2145 [('c', 'changelog', False, _('open changelog')),
2132 2146 ('m', 'manifest', False, _('open manifest')),
2133 2147 ('', 'dir', False, _('open directory manifest'))],
2134 2148 _('-c|-m|FILE REV'))
2135 2149 def debugdata(ui, repo, file_, rev=None, **opts):
2136 2150 """dump the contents of a data file revision"""
2137 2151 if opts.get('changelog') or opts.get('manifest'):
2138 2152 file_, rev = None, file_
2139 2153 elif rev is None:
2140 2154 raise error.CommandError('debugdata', _('invalid arguments'))
2141 2155 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2142 2156 try:
2143 2157 ui.write(r.revision(r.lookup(rev)))
2144 2158 except KeyError:
2145 2159 raise error.Abort(_('invalid revision identifier %s') % rev)
2146 2160
2147 2161 @command('debugdate',
2148 2162 [('e', 'extended', None, _('try extended date formats'))],
2149 2163 _('[-e] DATE [RANGE]'),
2150 2164 norepo=True, optionalrepo=True)
2151 2165 def debugdate(ui, date, range=None, **opts):
2152 2166 """parse and display a date"""
2153 2167 if opts["extended"]:
2154 2168 d = util.parsedate(date, util.extendeddateformats)
2155 2169 else:
2156 2170 d = util.parsedate(date)
2157 2171 ui.write(("internal: %s %s\n") % d)
2158 2172 ui.write(("standard: %s\n") % util.datestr(d))
2159 2173 if range:
2160 2174 m = util.matchdate(range)
2161 2175 ui.write(("match: %s\n") % m(d[0]))
2162 2176
2163 2177 @command('debugdiscovery',
2164 2178 [('', 'old', None, _('use old-style discovery')),
2165 2179 ('', 'nonheads', None,
2166 2180 _('use old-style discovery with non-heads included')),
2167 2181 ] + remoteopts,
2168 2182 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2169 2183 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2170 2184 """runs the changeset discovery protocol in isolation"""
2171 2185 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2172 2186 opts.get('branch'))
2173 2187 remote = hg.peer(repo, opts, remoteurl)
2174 2188 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2175 2189
2176 2190 # make sure tests are repeatable
2177 2191 random.seed(12323)
2178 2192
2179 2193 def doit(localheads, remoteheads, remote=remote):
2180 2194 if opts.get('old'):
2181 2195 if localheads:
2182 2196 raise error.Abort('cannot use localheads with old style '
2183 2197 'discovery')
2184 2198 if not util.safehasattr(remote, 'branches'):
2185 2199 # enable in-client legacy support
2186 2200 remote = localrepo.locallegacypeer(remote.local())
2187 2201 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2188 2202 force=True)
2189 2203 common = set(common)
2190 2204 if not opts.get('nonheads'):
2191 2205 ui.write(("unpruned common: %s\n") %
2192 2206 " ".join(sorted(short(n) for n in common)))
2193 2207 dag = dagutil.revlogdag(repo.changelog)
2194 2208 all = dag.ancestorset(dag.internalizeall(common))
2195 2209 common = dag.externalizeall(dag.headsetofconnecteds(all))
2196 2210 else:
2197 2211 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2198 2212 common = set(common)
2199 2213 rheads = set(hds)
2200 2214 lheads = set(repo.heads())
2201 2215 ui.write(("common heads: %s\n") %
2202 2216 " ".join(sorted(short(n) for n in common)))
2203 2217 if lheads <= common:
2204 2218 ui.write(("local is subset\n"))
2205 2219 elif rheads <= common:
2206 2220 ui.write(("remote is subset\n"))
2207 2221
2208 2222 serverlogs = opts.get('serverlog')
2209 2223 if serverlogs:
2210 2224 for filename in serverlogs:
2211 2225 logfile = open(filename, 'r')
2212 2226 try:
2213 2227 line = logfile.readline()
2214 2228 while line:
2215 2229 parts = line.strip().split(';')
2216 2230 op = parts[1]
2217 2231 if op == 'cg':
2218 2232 pass
2219 2233 elif op == 'cgss':
2220 2234 doit(parts[2].split(' '), parts[3].split(' '))
2221 2235 elif op == 'unb':
2222 2236 doit(parts[3].split(' '), parts[2].split(' '))
2223 2237 line = logfile.readline()
2224 2238 finally:
2225 2239 logfile.close()
2226 2240
2227 2241 else:
2228 2242 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2229 2243 opts.get('remote_head'))
2230 2244 localrevs = opts.get('local_head')
2231 2245 doit(localrevs, remoterevs)
2232 2246
2233 2247 @command('debugextensions', formatteropts, [], norepo=True)
2234 2248 def debugextensions(ui, **opts):
2235 2249 '''show information about active extensions'''
2236 2250 exts = extensions.extensions(ui)
2237 2251 fm = ui.formatter('debugextensions', opts)
2238 2252 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
2239 2253 extsource = extmod.__file__
2240 2254 exttestedwith = getattr(extmod, 'testedwith', None)
2241 2255 if exttestedwith is not None:
2242 2256 exttestedwith = exttestedwith.split()
2243 2257 extbuglink = getattr(extmod, 'buglink', None)
2244 2258
2245 2259 fm.startitem()
2246 2260
2247 2261 if ui.quiet or ui.verbose:
2248 2262 fm.write('name', '%s\n', extname)
2249 2263 else:
2250 2264 fm.write('name', '%s', extname)
2251 2265 if not exttestedwith:
2252 2266 fm.plain(_(' (untested!)\n'))
2253 2267 else:
2254 2268 if exttestedwith == ['internal'] or \
2255 2269 util.version() in exttestedwith:
2256 2270 fm.plain('\n')
2257 2271 else:
2258 2272 lasttestedversion = exttestedwith[-1]
2259 2273 fm.plain(' (%s!)\n' % lasttestedversion)
2260 2274
2261 2275 fm.condwrite(ui.verbose and extsource, 'source',
2262 2276 _(' location: %s\n'), extsource or "")
2263 2277
2264 2278 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
2265 2279 _(' tested with: %s\n'), ' '.join(exttestedwith or []))
2266 2280
2267 2281 fm.condwrite(ui.verbose and extbuglink, 'buglink',
2268 2282 _(' bug reporting: %s\n'), extbuglink or "")
2269 2283
2270 2284 fm.end()
2271 2285
2272 2286 @command('debugfileset',
2273 2287 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2274 2288 _('[-r REV] FILESPEC'))
2275 2289 def debugfileset(ui, repo, expr, **opts):
2276 2290 '''parse and apply a fileset specification'''
2277 2291 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2278 2292 if ui.verbose:
2279 2293 tree = fileset.parse(expr)
2280 2294 ui.note(fileset.prettyformat(tree), "\n")
2281 2295
2282 2296 for f in ctx.getfileset(expr):
2283 2297 ui.write("%s\n" % f)
2284 2298
2285 2299 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2286 2300 def debugfsinfo(ui, path="."):
2287 2301 """show information detected about current filesystem"""
2288 2302 util.writefile('.debugfsinfo', '')
2289 2303 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2290 2304 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2291 2305 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2292 2306 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2293 2307 and 'yes' or 'no'))
2294 2308 os.unlink('.debugfsinfo')
2295 2309
2296 2310 @command('debuggetbundle',
2297 2311 [('H', 'head', [], _('id of head node'), _('ID')),
2298 2312 ('C', 'common', [], _('id of common node'), _('ID')),
2299 2313 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2300 2314 _('REPO FILE [-H|-C ID]...'),
2301 2315 norepo=True)
2302 2316 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2303 2317 """retrieves a bundle from a repo
2304 2318
2305 2319 Every ID must be a full-length hex node id string. Saves the bundle to the
2306 2320 given file.
2307 2321 """
2308 2322 repo = hg.peer(ui, opts, repopath)
2309 2323 if not repo.capable('getbundle'):
2310 2324 raise error.Abort("getbundle() not supported by target repository")
2311 2325 args = {}
2312 2326 if common:
2313 2327 args['common'] = [bin(s) for s in common]
2314 2328 if head:
2315 2329 args['heads'] = [bin(s) for s in head]
2316 2330 # TODO: get desired bundlecaps from command line.
2317 2331 args['bundlecaps'] = None
2318 2332 bundle = repo.getbundle('debug', **args)
2319 2333
2320 2334 bundletype = opts.get('type', 'bzip2').lower()
2321 2335 btypes = {'none': 'HG10UN',
2322 2336 'bzip2': 'HG10BZ',
2323 2337 'gzip': 'HG10GZ',
2324 2338 'bundle2': 'HG20'}
2325 2339 bundletype = btypes.get(bundletype)
2326 2340 if bundletype not in changegroup.bundletypes:
2327 2341 raise error.Abort(_('unknown bundle type specified with --type'))
2328 2342 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2329 2343
2330 2344 @command('debugignore', [], '')
2331 2345 def debugignore(ui, repo, *values, **opts):
2332 2346 """display the combined ignore pattern"""
2333 2347 ignore = repo.dirstate._ignore
2334 2348 includepat = getattr(ignore, 'includepat', None)
2335 2349 if includepat is not None:
2336 2350 ui.write("%s\n" % includepat)
2337 2351 else:
2338 2352 raise error.Abort(_("no ignore patterns found"))
2339 2353
2340 2354 @command('debugindex',
2341 2355 [('c', 'changelog', False, _('open changelog')),
2342 2356 ('m', 'manifest', False, _('open manifest')),
2343 2357 ('', 'dir', False, _('open directory manifest')),
2344 2358 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2345 2359 _('[-f FORMAT] -c|-m|FILE'),
2346 2360 optionalrepo=True)
2347 2361 def debugindex(ui, repo, file_=None, **opts):
2348 2362 """dump the contents of an index file"""
2349 2363 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2350 2364 format = opts.get('format', 0)
2351 2365 if format not in (0, 1):
2352 2366 raise error.Abort(_("unknown format %d") % format)
2353 2367
2354 2368 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2355 2369 if generaldelta:
2356 2370 basehdr = ' delta'
2357 2371 else:
2358 2372 basehdr = ' base'
2359 2373
2360 2374 if ui.debugflag:
2361 2375 shortfn = hex
2362 2376 else:
2363 2377 shortfn = short
2364 2378
2365 2379 # There might not be anything in r, so have a sane default
2366 2380 idlen = 12
2367 2381 for i in r:
2368 2382 idlen = len(shortfn(r.node(i)))
2369 2383 break
2370 2384
2371 2385 if format == 0:
2372 2386 ui.write(" rev offset length " + basehdr + " linkrev"
2373 2387 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2374 2388 elif format == 1:
2375 2389 ui.write(" rev flag offset length"
2376 2390 " size " + basehdr + " link p1 p2"
2377 2391 " %s\n" % "nodeid".rjust(idlen))
2378 2392
2379 2393 for i in r:
2380 2394 node = r.node(i)
2381 2395 if generaldelta:
2382 2396 base = r.deltaparent(i)
2383 2397 else:
2384 2398 base = r.chainbase(i)
2385 2399 if format == 0:
2386 2400 try:
2387 2401 pp = r.parents(node)
2388 2402 except Exception:
2389 2403 pp = [nullid, nullid]
2390 2404 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2391 2405 i, r.start(i), r.length(i), base, r.linkrev(i),
2392 2406 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2393 2407 elif format == 1:
2394 2408 pr = r.parentrevs(i)
2395 2409 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2396 2410 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2397 2411 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2398 2412
2399 2413 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2400 2414 def debugindexdot(ui, repo, file_):
2401 2415 """dump an index DAG as a graphviz dot file"""
2402 2416 r = None
2403 2417 if repo:
2404 2418 filelog = repo.file(file_)
2405 2419 if len(filelog):
2406 2420 r = filelog
2407 2421 if not r:
2408 2422 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2409 2423 ui.write(("digraph G {\n"))
2410 2424 for i in r:
2411 2425 node = r.node(i)
2412 2426 pp = r.parents(node)
2413 2427 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2414 2428 if pp[1] != nullid:
2415 2429 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2416 2430 ui.write("}\n")
2417 2431
2418 2432 @command('debuginstall', [], '', norepo=True)
2419 2433 def debuginstall(ui):
2420 2434 '''test Mercurial installation
2421 2435
2422 2436 Returns 0 on success.
2423 2437 '''
2424 2438
2425 2439 def writetemp(contents):
2426 2440 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2427 2441 f = os.fdopen(fd, "wb")
2428 2442 f.write(contents)
2429 2443 f.close()
2430 2444 return name
2431 2445
2432 2446 problems = 0
2433 2447
2434 2448 # encoding
2435 2449 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2436 2450 try:
2437 2451 encoding.fromlocal("test")
2438 2452 except error.Abort as inst:
2439 2453 ui.write(" %s\n" % inst)
2440 2454 ui.write(_(" (check that your locale is properly set)\n"))
2441 2455 problems += 1
2442 2456
2443 2457 # Python
2444 2458 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2445 2459 ui.status(_("checking Python version (%s)\n")
2446 2460 % ("%s.%s.%s" % sys.version_info[:3]))
2447 2461 ui.status(_("checking Python lib (%s)...\n")
2448 2462 % os.path.dirname(os.__file__))
2449 2463
2450 2464 # compiled modules
2451 2465 ui.status(_("checking installed modules (%s)...\n")
2452 2466 % os.path.dirname(__file__))
2453 2467 try:
2454 2468 import bdiff, mpatch, base85, osutil
2455 2469 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2456 2470 except Exception as inst:
2457 2471 ui.write(" %s\n" % inst)
2458 2472 ui.write(_(" One or more extensions could not be found"))
2459 2473 ui.write(_(" (check that you compiled the extensions)\n"))
2460 2474 problems += 1
2461 2475
2462 2476 # templates
2463 2477 import templater
2464 2478 p = templater.templatepaths()
2465 2479 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2466 2480 if p:
2467 2481 m = templater.templatepath("map-cmdline.default")
2468 2482 if m:
2469 2483 # template found, check if it is working
2470 2484 try:
2471 2485 templater.templater(m)
2472 2486 except Exception as inst:
2473 2487 ui.write(" %s\n" % inst)
2474 2488 p = None
2475 2489 else:
2476 2490 ui.write(_(" template 'default' not found\n"))
2477 2491 p = None
2478 2492 else:
2479 2493 ui.write(_(" no template directories found\n"))
2480 2494 if not p:
2481 2495 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2482 2496 problems += 1
2483 2497
2484 2498 # editor
2485 2499 ui.status(_("checking commit editor...\n"))
2486 2500 editor = ui.geteditor()
2487 2501 editor = util.expandpath(editor)
2488 2502 cmdpath = util.findexe(shlex.split(editor)[0])
2489 2503 if not cmdpath:
2490 2504 if editor == 'vi':
2491 2505 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2492 2506 ui.write(_(" (specify a commit editor in your configuration"
2493 2507 " file)\n"))
2494 2508 else:
2495 2509 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2496 2510 ui.write(_(" (specify a commit editor in your configuration"
2497 2511 " file)\n"))
2498 2512 problems += 1
2499 2513
2500 2514 # check username
2501 2515 ui.status(_("checking username...\n"))
2502 2516 try:
2503 2517 ui.username()
2504 2518 except error.Abort as e:
2505 2519 ui.write(" %s\n" % e)
2506 2520 ui.write(_(" (specify a username in your configuration file)\n"))
2507 2521 problems += 1
2508 2522
2509 2523 if not problems:
2510 2524 ui.status(_("no problems detected\n"))
2511 2525 else:
2512 2526 ui.write(_("%s problems detected,"
2513 2527 " please check your install!\n") % problems)
2514 2528
2515 2529 return problems
2516 2530
2517 2531 @command('debugknown', [], _('REPO ID...'), norepo=True)
2518 2532 def debugknown(ui, repopath, *ids, **opts):
2519 2533 """test whether node ids are known to a repo
2520 2534
2521 2535 Every ID must be a full-length hex node id string. Returns a list of 0s
2522 2536 and 1s indicating unknown/known.
2523 2537 """
2524 2538 repo = hg.peer(ui, opts, repopath)
2525 2539 if not repo.capable('known'):
2526 2540 raise error.Abort("known() not supported by target repository")
2527 2541 flags = repo.known([bin(s) for s in ids])
2528 2542 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2529 2543
2530 2544 @command('debuglabelcomplete', [], _('LABEL...'))
2531 2545 def debuglabelcomplete(ui, repo, *args):
2532 2546 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2533 2547 debugnamecomplete(ui, repo, *args)
2534 2548
2535 2549 @command('debugmergestate', [], '')
2536 2550 def debugmergestate(ui, repo, *args):
2537 2551 """print merge state
2538 2552
2539 2553 Use --verbose to print out information about whether v1 or v2 merge state
2540 2554 was chosen."""
2541 2555 def _hashornull(h):
2542 2556 if h == nullhex:
2543 2557 return 'null'
2544 2558 else:
2545 2559 return h
2546 2560
2547 2561 def printrecords(version):
2548 2562 ui.write(('* version %s records\n') % version)
2549 2563 if version == 1:
2550 2564 records = v1records
2551 2565 else:
2552 2566 records = v2records
2553 2567
2554 2568 for rtype, record in records:
2555 2569 # pretty print some record types
2556 2570 if rtype == 'L':
2557 2571 ui.write(('local: %s\n') % record)
2558 2572 elif rtype == 'O':
2559 2573 ui.write(('other: %s\n') % record)
2560 2574 elif rtype == 'm':
2561 2575 driver, mdstate = record.split('\0', 1)
2562 2576 ui.write(('merge driver: %s (state "%s")\n')
2563 2577 % (driver, mdstate))
2564 2578 elif rtype in 'FDC':
2565 2579 r = record.split('\0')
2566 2580 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2567 2581 if version == 1:
2568 2582 onode = 'not stored in v1 format'
2569 2583 flags = r[7]
2570 2584 else:
2571 2585 onode, flags = r[7:9]
2572 2586 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
2573 2587 % (f, rtype, state, _hashornull(hash)))
2574 2588 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2575 2589 ui.write((' ancestor path: %s (node %s)\n')
2576 2590 % (afile, _hashornull(anode)))
2577 2591 ui.write((' other path: %s (node %s)\n')
2578 2592 % (ofile, _hashornull(onode)))
2579 2593 else:
2580 2594 ui.write(('unrecognized entry: %s\t%s\n')
2581 2595 % (rtype, record.replace('\0', '\t')))
2582 2596
2583 2597 # Avoid mergestate.read() since it may raise an exception for unsupported
2584 2598 # merge state records. We shouldn't be doing this, but this is OK since this
2585 2599 # command is pretty low-level.
2586 2600 ms = mergemod.mergestate(repo)
2587 2601
2588 2602 # sort so that reasonable information is on top
2589 2603 v1records = ms._readrecordsv1()
2590 2604 v2records = ms._readrecordsv2()
2591 2605 order = 'LOm'
2592 2606 def key(r):
2593 2607 idx = order.find(r[0])
2594 2608 if idx == -1:
2595 2609 return (1, r[1])
2596 2610 else:
2597 2611 return (0, idx)
2598 2612 v1records.sort(key=key)
2599 2613 v2records.sort(key=key)
2600 2614
2601 2615 if not v1records and not v2records:
2602 2616 ui.write(('no merge state found\n'))
2603 2617 elif not v2records:
2604 2618 ui.note(('no version 2 merge state\n'))
2605 2619 printrecords(1)
2606 2620 elif ms._v1v2match(v1records, v2records):
2607 2621 ui.note(('v1 and v2 states match: using v2\n'))
2608 2622 printrecords(2)
2609 2623 else:
2610 2624 ui.note(('v1 and v2 states mismatch: using v1\n'))
2611 2625 printrecords(1)
2612 2626 if ui.verbose:
2613 2627 printrecords(2)
2614 2628
2615 2629 @command('debugnamecomplete', [], _('NAME...'))
2616 2630 def debugnamecomplete(ui, repo, *args):
2617 2631 '''complete "names" - tags, open branch names, bookmark names'''
2618 2632
2619 2633 names = set()
2620 2634 # since we previously only listed open branches, we will handle that
2621 2635 # specially (after this for loop)
2622 2636 for name, ns in repo.names.iteritems():
2623 2637 if name != 'branches':
2624 2638 names.update(ns.listnames(repo))
2625 2639 names.update(tag for (tag, heads, tip, closed)
2626 2640 in repo.branchmap().iterbranches() if not closed)
2627 2641 completions = set()
2628 2642 if not args:
2629 2643 args = ['']
2630 2644 for a in args:
2631 2645 completions.update(n for n in names if n.startswith(a))
2632 2646 ui.write('\n'.join(sorted(completions)))
2633 2647 ui.write('\n')
2634 2648
2635 2649 @command('debuglocks',
2636 2650 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2637 2651 ('W', 'force-wlock', None,
2638 2652 _('free the working state lock (DANGEROUS)'))],
2639 2653 _('[OPTION]...'))
2640 2654 def debuglocks(ui, repo, **opts):
2641 2655 """show or modify state of locks
2642 2656
2643 2657 By default, this command will show which locks are held. This
2644 2658 includes the user and process holding the lock, the amount of time
2645 2659 the lock has been held, and the machine name where the process is
2646 2660 running if it's not local.
2647 2661
2648 2662 Locks protect the integrity of Mercurial's data, so should be
2649 2663 treated with care. System crashes or other interruptions may cause
2650 2664 locks to not be properly released, though Mercurial will usually
2651 2665 detect and remove such stale locks automatically.
2652 2666
2653 2667 However, detecting stale locks may not always be possible (for
2654 2668 instance, on a shared filesystem). Removing locks may also be
2655 2669 blocked by filesystem permissions.
2656 2670
2657 2671 Returns 0 if no locks are held.
2658 2672
2659 2673 """
2660 2674
2661 2675 if opts.get('force_lock'):
2662 2676 repo.svfs.unlink('lock')
2663 2677 if opts.get('force_wlock'):
2664 2678 repo.vfs.unlink('wlock')
2665 2679 if opts.get('force_lock') or opts.get('force_lock'):
2666 2680 return 0
2667 2681
2668 2682 now = time.time()
2669 2683 held = 0
2670 2684
2671 2685 def report(vfs, name, method):
2672 2686 # this causes stale locks to get reaped for more accurate reporting
2673 2687 try:
2674 2688 l = method(False)
2675 2689 except error.LockHeld:
2676 2690 l = None
2677 2691
2678 2692 if l:
2679 2693 l.release()
2680 2694 else:
2681 2695 try:
2682 2696 stat = vfs.lstat(name)
2683 2697 age = now - stat.st_mtime
2684 2698 user = util.username(stat.st_uid)
2685 2699 locker = vfs.readlock(name)
2686 2700 if ":" in locker:
2687 2701 host, pid = locker.split(':')
2688 2702 if host == socket.gethostname():
2689 2703 locker = 'user %s, process %s' % (user, pid)
2690 2704 else:
2691 2705 locker = 'user %s, process %s, host %s' \
2692 2706 % (user, pid, host)
2693 2707 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2694 2708 return 1
2695 2709 except OSError as e:
2696 2710 if e.errno != errno.ENOENT:
2697 2711 raise
2698 2712
2699 2713 ui.write("%-6s free\n" % (name + ":"))
2700 2714 return 0
2701 2715
2702 2716 held += report(repo.svfs, "lock", repo.lock)
2703 2717 held += report(repo.vfs, "wlock", repo.wlock)
2704 2718
2705 2719 return held
2706 2720
2707 2721 @command('debugobsolete',
2708 2722 [('', 'flags', 0, _('markers flag')),
2709 2723 ('', 'record-parents', False,
2710 2724 _('record parent information for the precursor')),
2711 2725 ('r', 'rev', [], _('display markers relevant to REV')),
2712 2726 ] + commitopts2,
2713 2727 _('[OBSOLETED [REPLACEMENT ...]]'))
2714 2728 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2715 2729 """create arbitrary obsolete marker
2716 2730
2717 2731 With no arguments, displays the list of obsolescence markers."""
2718 2732
2719 2733 def parsenodeid(s):
2720 2734 try:
2721 2735 # We do not use revsingle/revrange functions here to accept
2722 2736 # arbitrary node identifiers, possibly not present in the
2723 2737 # local repository.
2724 2738 n = bin(s)
2725 2739 if len(n) != len(nullid):
2726 2740 raise TypeError()
2727 2741 return n
2728 2742 except TypeError:
2729 2743 raise error.Abort('changeset references must be full hexadecimal '
2730 2744 'node identifiers')
2731 2745
2732 2746 if precursor is not None:
2733 2747 if opts['rev']:
2734 2748 raise error.Abort('cannot select revision when creating marker')
2735 2749 metadata = {}
2736 2750 metadata['user'] = opts['user'] or ui.username()
2737 2751 succs = tuple(parsenodeid(succ) for succ in successors)
2738 2752 l = repo.lock()
2739 2753 try:
2740 2754 tr = repo.transaction('debugobsolete')
2741 2755 try:
2742 2756 date = opts.get('date')
2743 2757 if date:
2744 2758 date = util.parsedate(date)
2745 2759 else:
2746 2760 date = None
2747 2761 prec = parsenodeid(precursor)
2748 2762 parents = None
2749 2763 if opts['record_parents']:
2750 2764 if prec not in repo.unfiltered():
2751 2765 raise error.Abort('cannot used --record-parents on '
2752 2766 'unknown changesets')
2753 2767 parents = repo.unfiltered()[prec].parents()
2754 2768 parents = tuple(p.node() for p in parents)
2755 2769 repo.obsstore.create(tr, prec, succs, opts['flags'],
2756 2770 parents=parents, date=date,
2757 2771 metadata=metadata)
2758 2772 tr.close()
2759 2773 except ValueError as exc:
2760 2774 raise error.Abort(_('bad obsmarker input: %s') % exc)
2761 2775 finally:
2762 2776 tr.release()
2763 2777 finally:
2764 2778 l.release()
2765 2779 else:
2766 2780 if opts['rev']:
2767 2781 revs = scmutil.revrange(repo, opts['rev'])
2768 2782 nodes = [repo[r].node() for r in revs]
2769 2783 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2770 2784 markers.sort(key=lambda x: x._data)
2771 2785 else:
2772 2786 markers = obsolete.getmarkers(repo)
2773 2787
2774 2788 for m in markers:
2775 2789 cmdutil.showmarker(ui, m)
2776 2790
2777 2791 @command('debugpathcomplete',
2778 2792 [('f', 'full', None, _('complete an entire path')),
2779 2793 ('n', 'normal', None, _('show only normal files')),
2780 2794 ('a', 'added', None, _('show only added files')),
2781 2795 ('r', 'removed', None, _('show only removed files'))],
2782 2796 _('FILESPEC...'))
2783 2797 def debugpathcomplete(ui, repo, *specs, **opts):
2784 2798 '''complete part or all of a tracked path
2785 2799
2786 2800 This command supports shells that offer path name completion. It
2787 2801 currently completes only files already known to the dirstate.
2788 2802
2789 2803 Completion extends only to the next path segment unless
2790 2804 --full is specified, in which case entire paths are used.'''
2791 2805
2792 2806 def complete(path, acceptable):
2793 2807 dirstate = repo.dirstate
2794 2808 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2795 2809 rootdir = repo.root + os.sep
2796 2810 if spec != repo.root and not spec.startswith(rootdir):
2797 2811 return [], []
2798 2812 if os.path.isdir(spec):
2799 2813 spec += '/'
2800 2814 spec = spec[len(rootdir):]
2801 2815 fixpaths = os.sep != '/'
2802 2816 if fixpaths:
2803 2817 spec = spec.replace(os.sep, '/')
2804 2818 speclen = len(spec)
2805 2819 fullpaths = opts['full']
2806 2820 files, dirs = set(), set()
2807 2821 adddir, addfile = dirs.add, files.add
2808 2822 for f, st in dirstate.iteritems():
2809 2823 if f.startswith(spec) and st[0] in acceptable:
2810 2824 if fixpaths:
2811 2825 f = f.replace('/', os.sep)
2812 2826 if fullpaths:
2813 2827 addfile(f)
2814 2828 continue
2815 2829 s = f.find(os.sep, speclen)
2816 2830 if s >= 0:
2817 2831 adddir(f[:s])
2818 2832 else:
2819 2833 addfile(f)
2820 2834 return files, dirs
2821 2835
2822 2836 acceptable = ''
2823 2837 if opts['normal']:
2824 2838 acceptable += 'nm'
2825 2839 if opts['added']:
2826 2840 acceptable += 'a'
2827 2841 if opts['removed']:
2828 2842 acceptable += 'r'
2829 2843 cwd = repo.getcwd()
2830 2844 if not specs:
2831 2845 specs = ['.']
2832 2846
2833 2847 files, dirs = set(), set()
2834 2848 for spec in specs:
2835 2849 f, d = complete(spec, acceptable or 'nmar')
2836 2850 files.update(f)
2837 2851 dirs.update(d)
2838 2852 files.update(dirs)
2839 2853 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2840 2854 ui.write('\n')
2841 2855
2842 2856 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2843 2857 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2844 2858 '''access the pushkey key/value protocol
2845 2859
2846 2860 With two args, list the keys in the given namespace.
2847 2861
2848 2862 With five args, set a key to new if it currently is set to old.
2849 2863 Reports success or failure.
2850 2864 '''
2851 2865
2852 2866 target = hg.peer(ui, {}, repopath)
2853 2867 if keyinfo:
2854 2868 key, old, new = keyinfo
2855 2869 r = target.pushkey(namespace, key, old, new)
2856 2870 ui.status(str(r) + '\n')
2857 2871 return not r
2858 2872 else:
2859 2873 for k, v in sorted(target.listkeys(namespace).iteritems()):
2860 2874 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2861 2875 v.encode('string-escape')))
2862 2876
2863 2877 @command('debugpvec', [], _('A B'))
2864 2878 def debugpvec(ui, repo, a, b=None):
2865 2879 ca = scmutil.revsingle(repo, a)
2866 2880 cb = scmutil.revsingle(repo, b)
2867 2881 pa = pvec.ctxpvec(ca)
2868 2882 pb = pvec.ctxpvec(cb)
2869 2883 if pa == pb:
2870 2884 rel = "="
2871 2885 elif pa > pb:
2872 2886 rel = ">"
2873 2887 elif pa < pb:
2874 2888 rel = "<"
2875 2889 elif pa | pb:
2876 2890 rel = "|"
2877 2891 ui.write(_("a: %s\n") % pa)
2878 2892 ui.write(_("b: %s\n") % pb)
2879 2893 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2880 2894 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2881 2895 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2882 2896 pa.distance(pb), rel))
2883 2897
2884 2898 @command('debugrebuilddirstate|debugrebuildstate',
2885 2899 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
2886 2900 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
2887 2901 'the working copy parent')),
2888 2902 ],
2889 2903 _('[-r REV]'))
2890 2904 def debugrebuilddirstate(ui, repo, rev, **opts):
2891 2905 """rebuild the dirstate as it would look like for the given revision
2892 2906
2893 2907 If no revision is specified the first current parent will be used.
2894 2908
2895 2909 The dirstate will be set to the files of the given revision.
2896 2910 The actual working directory content or existing dirstate
2897 2911 information such as adds or removes is not considered.
2898 2912
2899 2913 ``minimal`` will only rebuild the dirstate status for files that claim to be
2900 2914 tracked but are not in the parent manifest, or that exist in the parent
2901 2915 manifest but are not in the dirstate. It will not change adds, removes, or
2902 2916 modified files that are in the working copy parent.
2903 2917
2904 2918 One use of this command is to make the next :hg:`status` invocation
2905 2919 check the actual file content.
2906 2920 """
2907 2921 ctx = scmutil.revsingle(repo, rev)
2908 2922 wlock = repo.wlock()
2909 2923 try:
2910 2924 dirstate = repo.dirstate
2911 2925
2912 2926 # See command doc for what minimal does.
2913 2927 if opts.get('minimal'):
2914 2928 dirstatefiles = set(dirstate)
2915 2929 ctxfiles = set(ctx.manifest().keys())
2916 2930 for file in (dirstatefiles | ctxfiles):
2917 2931 indirstate = file in dirstatefiles
2918 2932 inctx = file in ctxfiles
2919 2933
2920 2934 if indirstate and not inctx and dirstate[file] != 'a':
2921 2935 dirstate.drop(file)
2922 2936 elif inctx and not indirstate:
2923 2937 dirstate.normallookup(file)
2924 2938 else:
2925 2939 dirstate.rebuild(ctx.node(), ctx.manifest())
2926 2940 finally:
2927 2941 wlock.release()
2928 2942
2929 2943 @command('debugrebuildfncache', [], '')
2930 2944 def debugrebuildfncache(ui, repo):
2931 2945 """rebuild the fncache file"""
2932 2946 repair.rebuildfncache(ui, repo)
2933 2947
2934 2948 @command('debugrename',
2935 2949 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2936 2950 _('[-r REV] FILE'))
2937 2951 def debugrename(ui, repo, file1, *pats, **opts):
2938 2952 """dump rename information"""
2939 2953
2940 2954 ctx = scmutil.revsingle(repo, opts.get('rev'))
2941 2955 m = scmutil.match(ctx, (file1,) + pats, opts)
2942 2956 for abs in ctx.walk(m):
2943 2957 fctx = ctx[abs]
2944 2958 o = fctx.filelog().renamed(fctx.filenode())
2945 2959 rel = m.rel(abs)
2946 2960 if o:
2947 2961 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2948 2962 else:
2949 2963 ui.write(_("%s not renamed\n") % rel)
2950 2964
2951 2965 @command('debugrevlog',
2952 2966 [('c', 'changelog', False, _('open changelog')),
2953 2967 ('m', 'manifest', False, _('open manifest')),
2954 2968 ('', 'dir', False, _('open directory manifest')),
2955 2969 ('d', 'dump', False, _('dump index data'))],
2956 2970 _('-c|-m|FILE'),
2957 2971 optionalrepo=True)
2958 2972 def debugrevlog(ui, repo, file_=None, **opts):
2959 2973 """show data and statistics about a revlog"""
2960 2974 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2961 2975
2962 2976 if opts.get("dump"):
2963 2977 numrevs = len(r)
2964 2978 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2965 2979 " rawsize totalsize compression heads chainlen\n")
2966 2980 ts = 0
2967 2981 heads = set()
2968 2982
2969 2983 for rev in xrange(numrevs):
2970 2984 dbase = r.deltaparent(rev)
2971 2985 if dbase == -1:
2972 2986 dbase = rev
2973 2987 cbase = r.chainbase(rev)
2974 2988 clen = r.chainlen(rev)
2975 2989 p1, p2 = r.parentrevs(rev)
2976 2990 rs = r.rawsize(rev)
2977 2991 ts = ts + rs
2978 2992 heads -= set(r.parentrevs(rev))
2979 2993 heads.add(rev)
2980 2994 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2981 2995 "%11d %5d %8d\n" %
2982 2996 (rev, p1, p2, r.start(rev), r.end(rev),
2983 2997 r.start(dbase), r.start(cbase),
2984 2998 r.start(p1), r.start(p2),
2985 2999 rs, ts, ts / r.end(rev), len(heads), clen))
2986 3000 return 0
2987 3001
2988 3002 v = r.version
2989 3003 format = v & 0xFFFF
2990 3004 flags = []
2991 3005 gdelta = False
2992 3006 if v & revlog.REVLOGNGINLINEDATA:
2993 3007 flags.append('inline')
2994 3008 if v & revlog.REVLOGGENERALDELTA:
2995 3009 gdelta = True
2996 3010 flags.append('generaldelta')
2997 3011 if not flags:
2998 3012 flags = ['(none)']
2999 3013
3000 3014 nummerges = 0
3001 3015 numfull = 0
3002 3016 numprev = 0
3003 3017 nump1 = 0
3004 3018 nump2 = 0
3005 3019 numother = 0
3006 3020 nump1prev = 0
3007 3021 nump2prev = 0
3008 3022 chainlengths = []
3009 3023
3010 3024 datasize = [None, 0, 0L]
3011 3025 fullsize = [None, 0, 0L]
3012 3026 deltasize = [None, 0, 0L]
3013 3027
3014 3028 def addsize(size, l):
3015 3029 if l[0] is None or size < l[0]:
3016 3030 l[0] = size
3017 3031 if size > l[1]:
3018 3032 l[1] = size
3019 3033 l[2] += size
3020 3034
3021 3035 numrevs = len(r)
3022 3036 for rev in xrange(numrevs):
3023 3037 p1, p2 = r.parentrevs(rev)
3024 3038 delta = r.deltaparent(rev)
3025 3039 if format > 0:
3026 3040 addsize(r.rawsize(rev), datasize)
3027 3041 if p2 != nullrev:
3028 3042 nummerges += 1
3029 3043 size = r.length(rev)
3030 3044 if delta == nullrev:
3031 3045 chainlengths.append(0)
3032 3046 numfull += 1
3033 3047 addsize(size, fullsize)
3034 3048 else:
3035 3049 chainlengths.append(chainlengths[delta] + 1)
3036 3050 addsize(size, deltasize)
3037 3051 if delta == rev - 1:
3038 3052 numprev += 1
3039 3053 if delta == p1:
3040 3054 nump1prev += 1
3041 3055 elif delta == p2:
3042 3056 nump2prev += 1
3043 3057 elif delta == p1:
3044 3058 nump1 += 1
3045 3059 elif delta == p2:
3046 3060 nump2 += 1
3047 3061 elif delta != nullrev:
3048 3062 numother += 1
3049 3063
3050 3064 # Adjust size min value for empty cases
3051 3065 for size in (datasize, fullsize, deltasize):
3052 3066 if size[0] is None:
3053 3067 size[0] = 0
3054 3068
3055 3069 numdeltas = numrevs - numfull
3056 3070 numoprev = numprev - nump1prev - nump2prev
3057 3071 totalrawsize = datasize[2]
3058 3072 datasize[2] /= numrevs
3059 3073 fulltotal = fullsize[2]
3060 3074 fullsize[2] /= numfull
3061 3075 deltatotal = deltasize[2]
3062 3076 if numrevs - numfull > 0:
3063 3077 deltasize[2] /= numrevs - numfull
3064 3078 totalsize = fulltotal + deltatotal
3065 3079 avgchainlen = sum(chainlengths) / numrevs
3066 3080 maxchainlen = max(chainlengths)
3067 3081 compratio = 1
3068 3082 if totalsize:
3069 3083 compratio = totalrawsize / totalsize
3070 3084
3071 3085 basedfmtstr = '%%%dd\n'
3072 3086 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
3073 3087
3074 3088 def dfmtstr(max):
3075 3089 return basedfmtstr % len(str(max))
3076 3090 def pcfmtstr(max, padding=0):
3077 3091 return basepcfmtstr % (len(str(max)), ' ' * padding)
3078 3092
3079 3093 def pcfmt(value, total):
3080 3094 if total:
3081 3095 return (value, 100 * float(value) / total)
3082 3096 else:
3083 3097 return value, 100.0
3084 3098
3085 3099 ui.write(('format : %d\n') % format)
3086 3100 ui.write(('flags : %s\n') % ', '.join(flags))
3087 3101
3088 3102 ui.write('\n')
3089 3103 fmt = pcfmtstr(totalsize)
3090 3104 fmt2 = dfmtstr(totalsize)
3091 3105 ui.write(('revisions : ') + fmt2 % numrevs)
3092 3106 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
3093 3107 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
3094 3108 ui.write(('revisions : ') + fmt2 % numrevs)
3095 3109 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
3096 3110 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
3097 3111 ui.write(('revision size : ') + fmt2 % totalsize)
3098 3112 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
3099 3113 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
3100 3114
3101 3115 ui.write('\n')
3102 3116 fmt = dfmtstr(max(avgchainlen, compratio))
3103 3117 ui.write(('avg chain length : ') + fmt % avgchainlen)
3104 3118 ui.write(('max chain length : ') + fmt % maxchainlen)
3105 3119 ui.write(('compression ratio : ') + fmt % compratio)
3106 3120
3107 3121 if format > 0:
3108 3122 ui.write('\n')
3109 3123 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
3110 3124 % tuple(datasize))
3111 3125 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
3112 3126 % tuple(fullsize))
3113 3127 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
3114 3128 % tuple(deltasize))
3115 3129
3116 3130 if numdeltas > 0:
3117 3131 ui.write('\n')
3118 3132 fmt = pcfmtstr(numdeltas)
3119 3133 fmt2 = pcfmtstr(numdeltas, 4)
3120 3134 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
3121 3135 if numprev > 0:
3122 3136 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
3123 3137 numprev))
3124 3138 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
3125 3139 numprev))
3126 3140 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
3127 3141 numprev))
3128 3142 if gdelta:
3129 3143 ui.write(('deltas against p1 : ')
3130 3144 + fmt % pcfmt(nump1, numdeltas))
3131 3145 ui.write(('deltas against p2 : ')
3132 3146 + fmt % pcfmt(nump2, numdeltas))
3133 3147 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
3134 3148 numdeltas))
3135 3149
3136 3150 @command('debugrevspec',
3137 3151 [('', 'optimize', None, _('print parsed tree after optimizing'))],
3138 3152 ('REVSPEC'))
3139 3153 def debugrevspec(ui, repo, expr, **opts):
3140 3154 """parse and apply a revision specification
3141 3155
3142 3156 Use --verbose to print the parsed tree before and after aliases
3143 3157 expansion.
3144 3158 """
3145 3159 if ui.verbose:
3146 3160 tree = revset.parse(expr, lookup=repo.__contains__)
3147 3161 ui.note(revset.prettyformat(tree), "\n")
3148 3162 newtree = revset.findaliases(ui, tree)
3149 3163 if newtree != tree:
3150 3164 ui.note(revset.prettyformat(newtree), "\n")
3151 3165 tree = newtree
3152 3166 newtree = revset.foldconcat(tree)
3153 3167 if newtree != tree:
3154 3168 ui.note(revset.prettyformat(newtree), "\n")
3155 3169 if opts["optimize"]:
3156 3170 weight, optimizedtree = revset.optimize(newtree, True)
3157 3171 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
3158 3172 func = revset.match(ui, expr, repo)
3159 3173 revs = func(repo)
3160 3174 if ui.verbose:
3161 3175 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
3162 3176 for c in revs:
3163 3177 ui.write("%s\n" % c)
3164 3178
3165 3179 @command('debugsetparents', [], _('REV1 [REV2]'))
3166 3180 def debugsetparents(ui, repo, rev1, rev2=None):
3167 3181 """manually set the parents of the current working directory
3168 3182
3169 3183 This is useful for writing repository conversion tools, but should
3170 3184 be used with care. For example, neither the working directory nor the
3171 3185 dirstate is updated, so file status may be incorrect after running this
3172 3186 command.
3173 3187
3174 3188 Returns 0 on success.
3175 3189 """
3176 3190
3177 3191 r1 = scmutil.revsingle(repo, rev1).node()
3178 3192 r2 = scmutil.revsingle(repo, rev2, 'null').node()
3179 3193
3180 3194 wlock = repo.wlock()
3181 3195 try:
3182 3196 repo.dirstate.beginparentchange()
3183 3197 repo.setparents(r1, r2)
3184 3198 repo.dirstate.endparentchange()
3185 3199 finally:
3186 3200 wlock.release()
3187 3201
3188 3202 @command('debugdirstate|debugstate',
3189 3203 [('', 'nodates', None, _('do not display the saved mtime')),
3190 3204 ('', 'datesort', None, _('sort by saved mtime'))],
3191 3205 _('[OPTION]...'))
3192 3206 def debugstate(ui, repo, **opts):
3193 3207 """show the contents of the current dirstate"""
3194 3208
3195 3209 nodates = opts.get('nodates')
3196 3210 datesort = opts.get('datesort')
3197 3211
3198 3212 timestr = ""
3199 3213 if datesort:
3200 3214 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
3201 3215 else:
3202 3216 keyfunc = None # sort by filename
3203 3217 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
3204 3218 if ent[3] == -1:
3205 3219 timestr = 'unset '
3206 3220 elif nodates:
3207 3221 timestr = 'set '
3208 3222 else:
3209 3223 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
3210 3224 time.localtime(ent[3]))
3211 3225 if ent[1] & 0o20000:
3212 3226 mode = 'lnk'
3213 3227 else:
3214 3228 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3215 3229 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3216 3230 for f in repo.dirstate.copies():
3217 3231 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3218 3232
3219 3233 @command('debugsub',
3220 3234 [('r', 'rev', '',
3221 3235 _('revision to check'), _('REV'))],
3222 3236 _('[-r REV] [REV]'))
3223 3237 def debugsub(ui, repo, rev=None):
3224 3238 ctx = scmutil.revsingle(repo, rev, None)
3225 3239 for k, v in sorted(ctx.substate.items()):
3226 3240 ui.write(('path %s\n') % k)
3227 3241 ui.write((' source %s\n') % v[0])
3228 3242 ui.write((' revision %s\n') % v[1])
3229 3243
3230 3244 @command('debugsuccessorssets',
3231 3245 [],
3232 3246 _('[REV]'))
3233 3247 def debugsuccessorssets(ui, repo, *revs):
3234 3248 """show set of successors for revision
3235 3249
3236 3250 A successors set of changeset A is a consistent group of revisions that
3237 3251 succeed A. It contains non-obsolete changesets only.
3238 3252
3239 3253 In most cases a changeset A has a single successors set containing a single
3240 3254 successor (changeset A replaced by A').
3241 3255
3242 3256 A changeset that is made obsolete with no successors are called "pruned".
3243 3257 Such changesets have no successors sets at all.
3244 3258
3245 3259 A changeset that has been "split" will have a successors set containing
3246 3260 more than one successor.
3247 3261
3248 3262 A changeset that has been rewritten in multiple different ways is called
3249 3263 "divergent". Such changesets have multiple successor sets (each of which
3250 3264 may also be split, i.e. have multiple successors).
3251 3265
3252 3266 Results are displayed as follows::
3253 3267
3254 3268 <rev1>
3255 3269 <successors-1A>
3256 3270 <rev2>
3257 3271 <successors-2A>
3258 3272 <successors-2B1> <successors-2B2> <successors-2B3>
3259 3273
3260 3274 Here rev2 has two possible (i.e. divergent) successors sets. The first
3261 3275 holds one element, whereas the second holds three (i.e. the changeset has
3262 3276 been split).
3263 3277 """
3264 3278 # passed to successorssets caching computation from one call to another
3265 3279 cache = {}
3266 3280 ctx2str = str
3267 3281 node2str = short
3268 3282 if ui.debug():
3269 3283 def ctx2str(ctx):
3270 3284 return ctx.hex()
3271 3285 node2str = hex
3272 3286 for rev in scmutil.revrange(repo, revs):
3273 3287 ctx = repo[rev]
3274 3288 ui.write('%s\n'% ctx2str(ctx))
3275 3289 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3276 3290 if succsset:
3277 3291 ui.write(' ')
3278 3292 ui.write(node2str(succsset[0]))
3279 3293 for node in succsset[1:]:
3280 3294 ui.write(' ')
3281 3295 ui.write(node2str(node))
3282 3296 ui.write('\n')
3283 3297
3284 3298 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3285 3299 def debugwalk(ui, repo, *pats, **opts):
3286 3300 """show how files match on given patterns"""
3287 3301 m = scmutil.match(repo[None], pats, opts)
3288 3302 items = list(repo.walk(m))
3289 3303 if not items:
3290 3304 return
3291 3305 f = lambda fn: fn
3292 3306 if ui.configbool('ui', 'slash') and os.sep != '/':
3293 3307 f = lambda fn: util.normpath(fn)
3294 3308 fmt = 'f %%-%ds %%-%ds %%s' % (
3295 3309 max([len(abs) for abs in items]),
3296 3310 max([len(m.rel(abs)) for abs in items]))
3297 3311 for abs in items:
3298 3312 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3299 3313 ui.write("%s\n" % line.rstrip())
3300 3314
3301 3315 @command('debugwireargs',
3302 3316 [('', 'three', '', 'three'),
3303 3317 ('', 'four', '', 'four'),
3304 3318 ('', 'five', '', 'five'),
3305 3319 ] + remoteopts,
3306 3320 _('REPO [OPTIONS]... [ONE [TWO]]'),
3307 3321 norepo=True)
3308 3322 def debugwireargs(ui, repopath, *vals, **opts):
3309 3323 repo = hg.peer(ui, opts, repopath)
3310 3324 for opt in remoteopts:
3311 3325 del opts[opt[1]]
3312 3326 args = {}
3313 3327 for k, v in opts.iteritems():
3314 3328 if v:
3315 3329 args[k] = v
3316 3330 # run twice to check that we don't mess up the stream for the next command
3317 3331 res1 = repo.debugwireargs(*vals, **args)
3318 3332 res2 = repo.debugwireargs(*vals, **args)
3319 3333 ui.write("%s\n" % res1)
3320 3334 if res1 != res2:
3321 3335 ui.warn("%s\n" % res2)
3322 3336
3323 3337 @command('^diff',
3324 3338 [('r', 'rev', [], _('revision'), _('REV')),
3325 3339 ('c', 'change', '', _('change made by revision'), _('REV'))
3326 3340 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3327 3341 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3328 3342 inferrepo=True)
3329 3343 def diff(ui, repo, *pats, **opts):
3330 3344 """diff repository (or selected files)
3331 3345
3332 3346 Show differences between revisions for the specified files.
3333 3347
3334 3348 Differences between files are shown using the unified diff format.
3335 3349
3336 3350 .. note::
3337 3351
3338 3352 diff may generate unexpected results for merges, as it will
3339 3353 default to comparing against the working directory's first
3340 3354 parent changeset if no revisions are specified.
3341 3355
3342 3356 When two revision arguments are given, then changes are shown
3343 3357 between those revisions. If only one revision is specified then
3344 3358 that revision is compared to the working directory, and, when no
3345 3359 revisions are specified, the working directory files are compared
3346 3360 to its parent.
3347 3361
3348 3362 Alternatively you can specify -c/--change with a revision to see
3349 3363 the changes in that changeset relative to its first parent.
3350 3364
3351 3365 Without the -a/--text option, diff will avoid generating diffs of
3352 3366 files it detects as binary. With -a, diff will generate a diff
3353 3367 anyway, probably with undesirable results.
3354 3368
3355 3369 Use the -g/--git option to generate diffs in the git extended diff
3356 3370 format. For more information, read :hg:`help diffs`.
3357 3371
3358 3372 .. container:: verbose
3359 3373
3360 3374 Examples:
3361 3375
3362 3376 - compare a file in the current working directory to its parent::
3363 3377
3364 3378 hg diff foo.c
3365 3379
3366 3380 - compare two historical versions of a directory, with rename info::
3367 3381
3368 3382 hg diff --git -r 1.0:1.2 lib/
3369 3383
3370 3384 - get change stats relative to the last change on some date::
3371 3385
3372 3386 hg diff --stat -r "date('may 2')"
3373 3387
3374 3388 - diff all newly-added files that contain a keyword::
3375 3389
3376 3390 hg diff "set:added() and grep(GNU)"
3377 3391
3378 3392 - compare a revision and its parents::
3379 3393
3380 3394 hg diff -c 9353 # compare against first parent
3381 3395 hg diff -r 9353^:9353 # same using revset syntax
3382 3396 hg diff -r 9353^2:9353 # compare against the second parent
3383 3397
3384 3398 Returns 0 on success.
3385 3399 """
3386 3400
3387 3401 revs = opts.get('rev')
3388 3402 change = opts.get('change')
3389 3403 stat = opts.get('stat')
3390 3404 reverse = opts.get('reverse')
3391 3405
3392 3406 if revs and change:
3393 3407 msg = _('cannot specify --rev and --change at the same time')
3394 3408 raise error.Abort(msg)
3395 3409 elif change:
3396 3410 node2 = scmutil.revsingle(repo, change, None).node()
3397 3411 node1 = repo[node2].p1().node()
3398 3412 else:
3399 3413 node1, node2 = scmutil.revpair(repo, revs)
3400 3414
3401 3415 if reverse:
3402 3416 node1, node2 = node2, node1
3403 3417
3404 3418 diffopts = patch.diffallopts(ui, opts)
3405 3419 m = scmutil.match(repo[node2], pats, opts)
3406 3420 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3407 3421 listsubrepos=opts.get('subrepos'),
3408 3422 root=opts.get('root'))
3409 3423
3410 3424 @command('^export',
3411 3425 [('o', 'output', '',
3412 3426 _('print output to file with formatted name'), _('FORMAT')),
3413 3427 ('', 'switch-parent', None, _('diff against the second parent')),
3414 3428 ('r', 'rev', [], _('revisions to export'), _('REV')),
3415 3429 ] + diffopts,
3416 3430 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3417 3431 def export(ui, repo, *changesets, **opts):
3418 3432 """dump the header and diffs for one or more changesets
3419 3433
3420 3434 Print the changeset header and diffs for one or more revisions.
3421 3435 If no revision is given, the parent of the working directory is used.
3422 3436
3423 3437 The information shown in the changeset header is: author, date,
3424 3438 branch name (if non-default), changeset hash, parent(s) and commit
3425 3439 comment.
3426 3440
3427 3441 .. note::
3428 3442
3429 3443 export may generate unexpected diff output for merge
3430 3444 changesets, as it will compare the merge changeset against its
3431 3445 first parent only.
3432 3446
3433 3447 Output may be to a file, in which case the name of the file is
3434 3448 given using a format string. The formatting rules are as follows:
3435 3449
3436 3450 :``%%``: literal "%" character
3437 3451 :``%H``: changeset hash (40 hexadecimal digits)
3438 3452 :``%N``: number of patches being generated
3439 3453 :``%R``: changeset revision number
3440 3454 :``%b``: basename of the exporting repository
3441 3455 :``%h``: short-form changeset hash (12 hexadecimal digits)
3442 3456 :``%m``: first line of the commit message (only alphanumeric characters)
3443 3457 :``%n``: zero-padded sequence number, starting at 1
3444 3458 :``%r``: zero-padded changeset revision number
3445 3459
3446 3460 Without the -a/--text option, export will avoid generating diffs
3447 3461 of files it detects as binary. With -a, export will generate a
3448 3462 diff anyway, probably with undesirable results.
3449 3463
3450 3464 Use the -g/--git option to generate diffs in the git extended diff
3451 3465 format. See :hg:`help diffs` for more information.
3452 3466
3453 3467 With the --switch-parent option, the diff will be against the
3454 3468 second parent. It can be useful to review a merge.
3455 3469
3456 3470 .. container:: verbose
3457 3471
3458 3472 Examples:
3459 3473
3460 3474 - use export and import to transplant a bugfix to the current
3461 3475 branch::
3462 3476
3463 3477 hg export -r 9353 | hg import -
3464 3478
3465 3479 - export all the changesets between two revisions to a file with
3466 3480 rename information::
3467 3481
3468 3482 hg export --git -r 123:150 > changes.txt
3469 3483
3470 3484 - split outgoing changes into a series of patches with
3471 3485 descriptive names::
3472 3486
3473 3487 hg export -r "outgoing()" -o "%n-%m.patch"
3474 3488
3475 3489 Returns 0 on success.
3476 3490 """
3477 3491 changesets += tuple(opts.get('rev', []))
3478 3492 if not changesets:
3479 3493 changesets = ['.']
3480 3494 revs = scmutil.revrange(repo, changesets)
3481 3495 if not revs:
3482 3496 raise error.Abort(_("export requires at least one changeset"))
3483 3497 if len(revs) > 1:
3484 3498 ui.note(_('exporting patches:\n'))
3485 3499 else:
3486 3500 ui.note(_('exporting patch:\n'))
3487 3501 cmdutil.export(repo, revs, template=opts.get('output'),
3488 3502 switch_parent=opts.get('switch_parent'),
3489 3503 opts=patch.diffallopts(ui, opts))
3490 3504
3491 3505 @command('files',
3492 3506 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3493 3507 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3494 3508 ] + walkopts + formatteropts + subrepoopts,
3495 3509 _('[OPTION]... [PATTERN]...'))
3496 3510 def files(ui, repo, *pats, **opts):
3497 3511 """list tracked files
3498 3512
3499 3513 Print files under Mercurial control in the working directory or
3500 3514 specified revision whose names match the given patterns (excluding
3501 3515 removed files).
3502 3516
3503 3517 If no patterns are given to match, this command prints the names
3504 3518 of all files under Mercurial control in the working directory.
3505 3519
3506 3520 .. container:: verbose
3507 3521
3508 3522 Examples:
3509 3523
3510 3524 - list all files under the current directory::
3511 3525
3512 3526 hg files .
3513 3527
3514 3528 - shows sizes and flags for current revision::
3515 3529
3516 3530 hg files -vr .
3517 3531
3518 3532 - list all files named README::
3519 3533
3520 3534 hg files -I "**/README"
3521 3535
3522 3536 - list all binary files::
3523 3537
3524 3538 hg files "set:binary()"
3525 3539
3526 3540 - find files containing a regular expression::
3527 3541
3528 3542 hg files "set:grep('bob')"
3529 3543
3530 3544 - search tracked file contents with xargs and grep::
3531 3545
3532 3546 hg files -0 | xargs -0 grep foo
3533 3547
3534 3548 See :hg:`help patterns` and :hg:`help filesets` for more information
3535 3549 on specifying file patterns.
3536 3550
3537 3551 Returns 0 if a match is found, 1 otherwise.
3538 3552
3539 3553 """
3540 3554 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3541 3555
3542 3556 end = '\n'
3543 3557 if opts.get('print0'):
3544 3558 end = '\0'
3545 3559 fm = ui.formatter('files', opts)
3546 3560 fmt = '%s' + end
3547 3561
3548 3562 m = scmutil.match(ctx, pats, opts)
3549 3563 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3550 3564
3551 3565 fm.end()
3552 3566
3553 3567 return ret
3554 3568
3555 3569 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3556 3570 def forget(ui, repo, *pats, **opts):
3557 3571 """forget the specified files on the next commit
3558 3572
3559 3573 Mark the specified files so they will no longer be tracked
3560 3574 after the next commit.
3561 3575
3562 3576 This only removes files from the current branch, not from the
3563 3577 entire project history, and it does not delete them from the
3564 3578 working directory.
3565 3579
3566 3580 To delete the file from the working directory, see :hg:`remove`.
3567 3581
3568 3582 To undo a forget before the next commit, see :hg:`add`.
3569 3583
3570 3584 .. container:: verbose
3571 3585
3572 3586 Examples:
3573 3587
3574 3588 - forget newly-added binary files::
3575 3589
3576 3590 hg forget "set:added() and binary()"
3577 3591
3578 3592 - forget files that would be excluded by .hgignore::
3579 3593
3580 3594 hg forget "set:hgignore()"
3581 3595
3582 3596 Returns 0 on success.
3583 3597 """
3584 3598
3585 3599 if not pats:
3586 3600 raise error.Abort(_('no files specified'))
3587 3601
3588 3602 m = scmutil.match(repo[None], pats, opts)
3589 3603 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3590 3604 return rejected and 1 or 0
3591 3605
3592 3606 @command(
3593 3607 'graft',
3594 3608 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3595 3609 ('c', 'continue', False, _('resume interrupted graft')),
3596 3610 ('e', 'edit', False, _('invoke editor on commit messages')),
3597 3611 ('', 'log', None, _('append graft info to log message')),
3598 3612 ('f', 'force', False, _('force graft')),
3599 3613 ('D', 'currentdate', False,
3600 3614 _('record the current date as commit date')),
3601 3615 ('U', 'currentuser', False,
3602 3616 _('record the current user as committer'), _('DATE'))]
3603 3617 + commitopts2 + mergetoolopts + dryrunopts,
3604 3618 _('[OPTION]... [-r] REV...'))
3605 3619 def graft(ui, repo, *revs, **opts):
3606 3620 '''copy changes from other branches onto the current branch
3607 3621
3608 3622 This command uses Mercurial's merge logic to copy individual
3609 3623 changes from other branches without merging branches in the
3610 3624 history graph. This is sometimes known as 'backporting' or
3611 3625 'cherry-picking'. By default, graft will copy user, date, and
3612 3626 description from the source changesets.
3613 3627
3614 3628 Changesets that are ancestors of the current revision, that have
3615 3629 already been grafted, or that are merges will be skipped.
3616 3630
3617 3631 If --log is specified, log messages will have a comment appended
3618 3632 of the form::
3619 3633
3620 3634 (grafted from CHANGESETHASH)
3621 3635
3622 3636 If --force is specified, revisions will be grafted even if they
3623 3637 are already ancestors of or have been grafted to the destination.
3624 3638 This is useful when the revisions have since been backed out.
3625 3639
3626 3640 If a graft merge results in conflicts, the graft process is
3627 3641 interrupted so that the current merge can be manually resolved.
3628 3642 Once all conflicts are addressed, the graft process can be
3629 3643 continued with the -c/--continue option.
3630 3644
3631 3645 .. note::
3632 3646
3633 3647 The -c/--continue option does not reapply earlier options, except
3634 3648 for --force.
3635 3649
3636 3650 .. container:: verbose
3637 3651
3638 3652 Examples:
3639 3653
3640 3654 - copy a single change to the stable branch and edit its description::
3641 3655
3642 3656 hg update stable
3643 3657 hg graft --edit 9393
3644 3658
3645 3659 - graft a range of changesets with one exception, updating dates::
3646 3660
3647 3661 hg graft -D "2085::2093 and not 2091"
3648 3662
3649 3663 - continue a graft after resolving conflicts::
3650 3664
3651 3665 hg graft -c
3652 3666
3653 3667 - show the source of a grafted changeset::
3654 3668
3655 3669 hg log --debug -r .
3656 3670
3657 3671 See :hg:`help revisions` and :hg:`help revsets` for more about
3658 3672 specifying revisions.
3659 3673
3660 3674 Returns 0 on successful completion.
3661 3675 '''
3662 3676
3663 3677 revs = list(revs)
3664 3678 revs.extend(opts['rev'])
3665 3679
3666 3680 if not opts.get('user') and opts.get('currentuser'):
3667 3681 opts['user'] = ui.username()
3668 3682 if not opts.get('date') and opts.get('currentdate'):
3669 3683 opts['date'] = "%d %d" % util.makedate()
3670 3684
3671 3685 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3672 3686
3673 3687 cont = False
3674 3688 if opts['continue']:
3675 3689 cont = True
3676 3690 if revs:
3677 3691 raise error.Abort(_("can't specify --continue and revisions"))
3678 3692 # read in unfinished revisions
3679 3693 try:
3680 3694 nodes = repo.vfs.read('graftstate').splitlines()
3681 3695 revs = [repo[node].rev() for node in nodes]
3682 3696 except IOError as inst:
3683 3697 if inst.errno != errno.ENOENT:
3684 3698 raise
3685 3699 raise error.Abort(_("no graft state found, can't continue"))
3686 3700 else:
3687 3701 cmdutil.checkunfinished(repo)
3688 3702 cmdutil.bailifchanged(repo)
3689 3703 if not revs:
3690 3704 raise error.Abort(_('no revisions specified'))
3691 3705 revs = scmutil.revrange(repo, revs)
3692 3706
3693 3707 skipped = set()
3694 3708 # check for merges
3695 3709 for rev in repo.revs('%ld and merge()', revs):
3696 3710 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3697 3711 skipped.add(rev)
3698 3712 revs = [r for r in revs if r not in skipped]
3699 3713 if not revs:
3700 3714 return -1
3701 3715
3702 3716 # Don't check in the --continue case, in effect retaining --force across
3703 3717 # --continues. That's because without --force, any revisions we decided to
3704 3718 # skip would have been filtered out here, so they wouldn't have made their
3705 3719 # way to the graftstate. With --force, any revisions we would have otherwise
3706 3720 # skipped would not have been filtered out, and if they hadn't been applied
3707 3721 # already, they'd have been in the graftstate.
3708 3722 if not (cont or opts.get('force')):
3709 3723 # check for ancestors of dest branch
3710 3724 crev = repo['.'].rev()
3711 3725 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3712 3726 # Cannot use x.remove(y) on smart set, this has to be a list.
3713 3727 # XXX make this lazy in the future
3714 3728 revs = list(revs)
3715 3729 # don't mutate while iterating, create a copy
3716 3730 for rev in list(revs):
3717 3731 if rev in ancestors:
3718 3732 ui.warn(_('skipping ancestor revision %d:%s\n') %
3719 3733 (rev, repo[rev]))
3720 3734 # XXX remove on list is slow
3721 3735 revs.remove(rev)
3722 3736 if not revs:
3723 3737 return -1
3724 3738
3725 3739 # analyze revs for earlier grafts
3726 3740 ids = {}
3727 3741 for ctx in repo.set("%ld", revs):
3728 3742 ids[ctx.hex()] = ctx.rev()
3729 3743 n = ctx.extra().get('source')
3730 3744 if n:
3731 3745 ids[n] = ctx.rev()
3732 3746
3733 3747 # check ancestors for earlier grafts
3734 3748 ui.debug('scanning for duplicate grafts\n')
3735 3749
3736 3750 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3737 3751 ctx = repo[rev]
3738 3752 n = ctx.extra().get('source')
3739 3753 if n in ids:
3740 3754 try:
3741 3755 r = repo[n].rev()
3742 3756 except error.RepoLookupError:
3743 3757 r = None
3744 3758 if r in revs:
3745 3759 ui.warn(_('skipping revision %d:%s '
3746 3760 '(already grafted to %d:%s)\n')
3747 3761 % (r, repo[r], rev, ctx))
3748 3762 revs.remove(r)
3749 3763 elif ids[n] in revs:
3750 3764 if r is None:
3751 3765 ui.warn(_('skipping already grafted revision %d:%s '
3752 3766 '(%d:%s also has unknown origin %s)\n')
3753 3767 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3754 3768 else:
3755 3769 ui.warn(_('skipping already grafted revision %d:%s '
3756 3770 '(%d:%s also has origin %d:%s)\n')
3757 3771 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3758 3772 revs.remove(ids[n])
3759 3773 elif ctx.hex() in ids:
3760 3774 r = ids[ctx.hex()]
3761 3775 ui.warn(_('skipping already grafted revision %d:%s '
3762 3776 '(was grafted from %d:%s)\n') %
3763 3777 (r, repo[r], rev, ctx))
3764 3778 revs.remove(r)
3765 3779 if not revs:
3766 3780 return -1
3767 3781
3768 3782 wlock = repo.wlock()
3769 3783 try:
3770 3784 for pos, ctx in enumerate(repo.set("%ld", revs)):
3771 3785 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3772 3786 ctx.description().split('\n', 1)[0])
3773 3787 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3774 3788 if names:
3775 3789 desc += ' (%s)' % ' '.join(names)
3776 3790 ui.status(_('grafting %s\n') % desc)
3777 3791 if opts.get('dry_run'):
3778 3792 continue
3779 3793
3780 3794 source = ctx.extra().get('source')
3781 3795 extra = {}
3782 3796 if source:
3783 3797 extra['source'] = source
3784 3798 extra['intermediate-source'] = ctx.hex()
3785 3799 else:
3786 3800 extra['source'] = ctx.hex()
3787 3801 user = ctx.user()
3788 3802 if opts.get('user'):
3789 3803 user = opts['user']
3790 3804 date = ctx.date()
3791 3805 if opts.get('date'):
3792 3806 date = opts['date']
3793 3807 message = ctx.description()
3794 3808 if opts.get('log'):
3795 3809 message += '\n(grafted from %s)' % ctx.hex()
3796 3810
3797 3811 # we don't merge the first commit when continuing
3798 3812 if not cont:
3799 3813 # perform the graft merge with p1(rev) as 'ancestor'
3800 3814 try:
3801 3815 # ui.forcemerge is an internal variable, do not document
3802 3816 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3803 3817 'graft')
3804 3818 stats = mergemod.graft(repo, ctx, ctx.p1(),
3805 3819 ['local', 'graft'])
3806 3820 finally:
3807 3821 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3808 3822 # report any conflicts
3809 3823 if stats and stats[3] > 0:
3810 3824 # write out state for --continue
3811 3825 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3812 3826 repo.vfs.write('graftstate', ''.join(nodelines))
3813 3827 raise error.Abort(
3814 3828 _("unresolved conflicts, can't continue"),
3815 3829 hint=_('use hg resolve and hg graft --continue'))
3816 3830 else:
3817 3831 cont = False
3818 3832
3819 3833 # commit
3820 3834 node = repo.commit(text=message, user=user,
3821 3835 date=date, extra=extra, editor=editor)
3822 3836 if node is None:
3823 3837 ui.warn(
3824 3838 _('note: graft of %d:%s created no changes to commit\n') %
3825 3839 (ctx.rev(), ctx))
3826 3840 finally:
3827 3841 wlock.release()
3828 3842
3829 3843 # remove state when we complete successfully
3830 3844 if not opts.get('dry_run'):
3831 3845 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3832 3846
3833 3847 return 0
3834 3848
3835 3849 @command('grep',
3836 3850 [('0', 'print0', None, _('end fields with NUL')),
3837 3851 ('', 'all', None, _('print all revisions that match')),
3838 3852 ('a', 'text', None, _('treat all files as text')),
3839 3853 ('f', 'follow', None,
3840 3854 _('follow changeset history,'
3841 3855 ' or file history across copies and renames')),
3842 3856 ('i', 'ignore-case', None, _('ignore case when matching')),
3843 3857 ('l', 'files-with-matches', None,
3844 3858 _('print only filenames and revisions that match')),
3845 3859 ('n', 'line-number', None, _('print matching line numbers')),
3846 3860 ('r', 'rev', [],
3847 3861 _('only search files changed within revision range'), _('REV')),
3848 3862 ('u', 'user', None, _('list the author (long with -v)')),
3849 3863 ('d', 'date', None, _('list the date (short with -q)')),
3850 3864 ] + walkopts,
3851 3865 _('[OPTION]... PATTERN [FILE]...'),
3852 3866 inferrepo=True)
3853 3867 def grep(ui, repo, pattern, *pats, **opts):
3854 3868 """search for a pattern in specified files and revisions
3855 3869
3856 3870 Search revisions of files for a regular expression.
3857 3871
3858 3872 This command behaves differently than Unix grep. It only accepts
3859 3873 Python/Perl regexps. It searches repository history, not the
3860 3874 working directory. It always prints the revision number in which a
3861 3875 match appears.
3862 3876
3863 3877 By default, grep only prints output for the first revision of a
3864 3878 file in which it finds a match. To get it to print every revision
3865 3879 that contains a change in match status ("-" for a match that
3866 3880 becomes a non-match, or "+" for a non-match that becomes a match),
3867 3881 use the --all flag.
3868 3882
3869 3883 Returns 0 if a match is found, 1 otherwise.
3870 3884 """
3871 3885 reflags = re.M
3872 3886 if opts.get('ignore_case'):
3873 3887 reflags |= re.I
3874 3888 try:
3875 3889 regexp = util.re.compile(pattern, reflags)
3876 3890 except re.error as inst:
3877 3891 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3878 3892 return 1
3879 3893 sep, eol = ':', '\n'
3880 3894 if opts.get('print0'):
3881 3895 sep = eol = '\0'
3882 3896
3883 3897 getfile = util.lrucachefunc(repo.file)
3884 3898
3885 3899 def matchlines(body):
3886 3900 begin = 0
3887 3901 linenum = 0
3888 3902 while begin < len(body):
3889 3903 match = regexp.search(body, begin)
3890 3904 if not match:
3891 3905 break
3892 3906 mstart, mend = match.span()
3893 3907 linenum += body.count('\n', begin, mstart) + 1
3894 3908 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3895 3909 begin = body.find('\n', mend) + 1 or len(body) + 1
3896 3910 lend = begin - 1
3897 3911 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3898 3912
3899 3913 class linestate(object):
3900 3914 def __init__(self, line, linenum, colstart, colend):
3901 3915 self.line = line
3902 3916 self.linenum = linenum
3903 3917 self.colstart = colstart
3904 3918 self.colend = colend
3905 3919
3906 3920 def __hash__(self):
3907 3921 return hash((self.linenum, self.line))
3908 3922
3909 3923 def __eq__(self, other):
3910 3924 return self.line == other.line
3911 3925
3912 3926 def __iter__(self):
3913 3927 yield (self.line[:self.colstart], '')
3914 3928 yield (self.line[self.colstart:self.colend], 'grep.match')
3915 3929 rest = self.line[self.colend:]
3916 3930 while rest != '':
3917 3931 match = regexp.search(rest)
3918 3932 if not match:
3919 3933 yield (rest, '')
3920 3934 break
3921 3935 mstart, mend = match.span()
3922 3936 yield (rest[:mstart], '')
3923 3937 yield (rest[mstart:mend], 'grep.match')
3924 3938 rest = rest[mend:]
3925 3939
3926 3940 matches = {}
3927 3941 copies = {}
3928 3942 def grepbody(fn, rev, body):
3929 3943 matches[rev].setdefault(fn, [])
3930 3944 m = matches[rev][fn]
3931 3945 for lnum, cstart, cend, line in matchlines(body):
3932 3946 s = linestate(line, lnum, cstart, cend)
3933 3947 m.append(s)
3934 3948
3935 3949 def difflinestates(a, b):
3936 3950 sm = difflib.SequenceMatcher(None, a, b)
3937 3951 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3938 3952 if tag == 'insert':
3939 3953 for i in xrange(blo, bhi):
3940 3954 yield ('+', b[i])
3941 3955 elif tag == 'delete':
3942 3956 for i in xrange(alo, ahi):
3943 3957 yield ('-', a[i])
3944 3958 elif tag == 'replace':
3945 3959 for i in xrange(alo, ahi):
3946 3960 yield ('-', a[i])
3947 3961 for i in xrange(blo, bhi):
3948 3962 yield ('+', b[i])
3949 3963
3950 3964 def display(fn, ctx, pstates, states):
3951 3965 rev = ctx.rev()
3952 3966 if ui.quiet:
3953 3967 datefunc = util.shortdate
3954 3968 else:
3955 3969 datefunc = util.datestr
3956 3970 found = False
3957 3971 @util.cachefunc
3958 3972 def binary():
3959 3973 flog = getfile(fn)
3960 3974 return util.binary(flog.read(ctx.filenode(fn)))
3961 3975
3962 3976 if opts.get('all'):
3963 3977 iter = difflinestates(pstates, states)
3964 3978 else:
3965 3979 iter = [('', l) for l in states]
3966 3980 for change, l in iter:
3967 3981 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3968 3982
3969 3983 if opts.get('line_number'):
3970 3984 cols.append((str(l.linenum), 'grep.linenumber'))
3971 3985 if opts.get('all'):
3972 3986 cols.append((change, 'grep.change'))
3973 3987 if opts.get('user'):
3974 3988 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3975 3989 if opts.get('date'):
3976 3990 cols.append((datefunc(ctx.date()), 'grep.date'))
3977 3991 for col, label in cols[:-1]:
3978 3992 ui.write(col, label=label)
3979 3993 ui.write(sep, label='grep.sep')
3980 3994 ui.write(cols[-1][0], label=cols[-1][1])
3981 3995 if not opts.get('files_with_matches'):
3982 3996 ui.write(sep, label='grep.sep')
3983 3997 if not opts.get('text') and binary():
3984 3998 ui.write(" Binary file matches")
3985 3999 else:
3986 4000 for s, label in l:
3987 4001 ui.write(s, label=label)
3988 4002 ui.write(eol)
3989 4003 found = True
3990 4004 if opts.get('files_with_matches'):
3991 4005 break
3992 4006 return found
3993 4007
3994 4008 skip = {}
3995 4009 revfiles = {}
3996 4010 matchfn = scmutil.match(repo[None], pats, opts)
3997 4011 found = False
3998 4012 follow = opts.get('follow')
3999 4013
4000 4014 def prep(ctx, fns):
4001 4015 rev = ctx.rev()
4002 4016 pctx = ctx.p1()
4003 4017 parent = pctx.rev()
4004 4018 matches.setdefault(rev, {})
4005 4019 matches.setdefault(parent, {})
4006 4020 files = revfiles.setdefault(rev, [])
4007 4021 for fn in fns:
4008 4022 flog = getfile(fn)
4009 4023 try:
4010 4024 fnode = ctx.filenode(fn)
4011 4025 except error.LookupError:
4012 4026 continue
4013 4027
4014 4028 copied = flog.renamed(fnode)
4015 4029 copy = follow and copied and copied[0]
4016 4030 if copy:
4017 4031 copies.setdefault(rev, {})[fn] = copy
4018 4032 if fn in skip:
4019 4033 if copy:
4020 4034 skip[copy] = True
4021 4035 continue
4022 4036 files.append(fn)
4023 4037
4024 4038 if fn not in matches[rev]:
4025 4039 grepbody(fn, rev, flog.read(fnode))
4026 4040
4027 4041 pfn = copy or fn
4028 4042 if pfn not in matches[parent]:
4029 4043 try:
4030 4044 fnode = pctx.filenode(pfn)
4031 4045 grepbody(pfn, parent, flog.read(fnode))
4032 4046 except error.LookupError:
4033 4047 pass
4034 4048
4035 4049 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4036 4050 rev = ctx.rev()
4037 4051 parent = ctx.p1().rev()
4038 4052 for fn in sorted(revfiles.get(rev, [])):
4039 4053 states = matches[rev][fn]
4040 4054 copy = copies.get(rev, {}).get(fn)
4041 4055 if fn in skip:
4042 4056 if copy:
4043 4057 skip[copy] = True
4044 4058 continue
4045 4059 pstates = matches.get(parent, {}).get(copy or fn, [])
4046 4060 if pstates or states:
4047 4061 r = display(fn, ctx, pstates, states)
4048 4062 found = found or r
4049 4063 if r and not opts.get('all'):
4050 4064 skip[fn] = True
4051 4065 if copy:
4052 4066 skip[copy] = True
4053 4067 del matches[rev]
4054 4068 del revfiles[rev]
4055 4069
4056 4070 return not found
4057 4071
4058 4072 @command('heads',
4059 4073 [('r', 'rev', '',
4060 4074 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
4061 4075 ('t', 'topo', False, _('show topological heads only')),
4062 4076 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
4063 4077 ('c', 'closed', False, _('show normal and closed branch heads')),
4064 4078 ] + templateopts,
4065 4079 _('[-ct] [-r STARTREV] [REV]...'))
4066 4080 def heads(ui, repo, *branchrevs, **opts):
4067 4081 """show branch heads
4068 4082
4069 4083 With no arguments, show all open branch heads in the repository.
4070 4084 Branch heads are changesets that have no descendants on the
4071 4085 same branch. They are where development generally takes place and
4072 4086 are the usual targets for update and merge operations.
4073 4087
4074 4088 If one or more REVs are given, only open branch heads on the
4075 4089 branches associated with the specified changesets are shown. This
4076 4090 means that you can use :hg:`heads .` to see the heads on the
4077 4091 currently checked-out branch.
4078 4092
4079 4093 If -c/--closed is specified, also show branch heads marked closed
4080 4094 (see :hg:`commit --close-branch`).
4081 4095
4082 4096 If STARTREV is specified, only those heads that are descendants of
4083 4097 STARTREV will be displayed.
4084 4098
4085 4099 If -t/--topo is specified, named branch mechanics will be ignored and only
4086 4100 topological heads (changesets with no children) will be shown.
4087 4101
4088 4102 Returns 0 if matching heads are found, 1 if not.
4089 4103 """
4090 4104
4091 4105 start = None
4092 4106 if 'rev' in opts:
4093 4107 start = scmutil.revsingle(repo, opts['rev'], None).node()
4094 4108
4095 4109 if opts.get('topo'):
4096 4110 heads = [repo[h] for h in repo.heads(start)]
4097 4111 else:
4098 4112 heads = []
4099 4113 for branch in repo.branchmap():
4100 4114 heads += repo.branchheads(branch, start, opts.get('closed'))
4101 4115 heads = [repo[h] for h in heads]
4102 4116
4103 4117 if branchrevs:
4104 4118 branches = set(repo[br].branch() for br in branchrevs)
4105 4119 heads = [h for h in heads if h.branch() in branches]
4106 4120
4107 4121 if opts.get('active') and branchrevs:
4108 4122 dagheads = repo.heads(start)
4109 4123 heads = [h for h in heads if h.node() in dagheads]
4110 4124
4111 4125 if branchrevs:
4112 4126 haveheads = set(h.branch() for h in heads)
4113 4127 if branches - haveheads:
4114 4128 headless = ', '.join(b for b in branches - haveheads)
4115 4129 msg = _('no open branch heads found on branches %s')
4116 4130 if opts.get('rev'):
4117 4131 msg += _(' (started at %s)') % opts['rev']
4118 4132 ui.warn((msg + '\n') % headless)
4119 4133
4120 4134 if not heads:
4121 4135 return 1
4122 4136
4123 4137 heads = sorted(heads, key=lambda x: -x.rev())
4124 4138 displayer = cmdutil.show_changeset(ui, repo, opts)
4125 4139 for ctx in heads:
4126 4140 displayer.show(ctx)
4127 4141 displayer.close()
4128 4142
4129 4143 @command('help',
4130 4144 [('e', 'extension', None, _('show only help for extensions')),
4131 4145 ('c', 'command', None, _('show only help for commands')),
4132 4146 ('k', 'keyword', None, _('show topics matching keyword')),
4133 4147 ],
4134 4148 _('[-eck] [TOPIC]'),
4135 4149 norepo=True)
4136 4150 def help_(ui, name=None, **opts):
4137 4151 """show help for a given topic or a help overview
4138 4152
4139 4153 With no arguments, print a list of commands with short help messages.
4140 4154
4141 4155 Given a topic, extension, or command name, print help for that
4142 4156 topic.
4143 4157
4144 4158 Returns 0 if successful.
4145 4159 """
4146 4160
4147 4161 textwidth = min(ui.termwidth(), 80) - 2
4148 4162
4149 4163 keep = []
4150 4164 if ui.verbose:
4151 4165 keep.append('verbose')
4152 4166 if sys.platform.startswith('win'):
4153 4167 keep.append('windows')
4154 4168 elif sys.platform == 'OpenVMS':
4155 4169 keep.append('vms')
4156 4170 elif sys.platform == 'plan9':
4157 4171 keep.append('plan9')
4158 4172 else:
4159 4173 keep.append('unix')
4160 4174 keep.append(sys.platform.lower())
4161 4175
4162 4176 section = None
4163 4177 if name and '.' in name:
4164 4178 name, section = name.split('.', 1)
4165 4179 section = section.lower()
4166 4180
4167 4181 text = help.help_(ui, name, **opts)
4168 4182
4169 4183 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4170 4184 section=section)
4171 4185
4172 4186 # We could have been given a weird ".foo" section without a name
4173 4187 # to look for, or we could have simply failed to found "foo.bar"
4174 4188 # because bar isn't a section of foo
4175 4189 if section and not (formatted and name):
4176 4190 raise error.Abort(_("help section not found"))
4177 4191
4178 4192 if 'verbose' in pruned:
4179 4193 keep.append('omitted')
4180 4194 else:
4181 4195 keep.append('notomitted')
4182 4196 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4183 4197 section=section)
4184 4198 ui.write(formatted)
4185 4199
4186 4200
4187 4201 @command('identify|id',
4188 4202 [('r', 'rev', '',
4189 4203 _('identify the specified revision'), _('REV')),
4190 4204 ('n', 'num', None, _('show local revision number')),
4191 4205 ('i', 'id', None, _('show global revision id')),
4192 4206 ('b', 'branch', None, _('show branch')),
4193 4207 ('t', 'tags', None, _('show tags')),
4194 4208 ('B', 'bookmarks', None, _('show bookmarks')),
4195 4209 ] + remoteopts,
4196 4210 _('[-nibtB] [-r REV] [SOURCE]'),
4197 4211 optionalrepo=True)
4198 4212 def identify(ui, repo, source=None, rev=None,
4199 4213 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
4200 4214 """identify the working directory or specified revision
4201 4215
4202 4216 Print a summary identifying the repository state at REV using one or
4203 4217 two parent hash identifiers, followed by a "+" if the working
4204 4218 directory has uncommitted changes, the branch name (if not default),
4205 4219 a list of tags, and a list of bookmarks.
4206 4220
4207 4221 When REV is not given, print a summary of the current state of the
4208 4222 repository.
4209 4223
4210 4224 Specifying a path to a repository root or Mercurial bundle will
4211 4225 cause lookup to operate on that repository/bundle.
4212 4226
4213 4227 .. container:: verbose
4214 4228
4215 4229 Examples:
4216 4230
4217 4231 - generate a build identifier for the working directory::
4218 4232
4219 4233 hg id --id > build-id.dat
4220 4234
4221 4235 - find the revision corresponding to a tag::
4222 4236
4223 4237 hg id -n -r 1.3
4224 4238
4225 4239 - check the most recent revision of a remote repository::
4226 4240
4227 4241 hg id -r tip http://selenic.com/hg/
4228 4242
4229 4243 See :hg:`log` for generating more information about specific revisions,
4230 4244 including full hash identifiers.
4231 4245
4232 4246 Returns 0 if successful.
4233 4247 """
4234 4248
4235 4249 if not repo and not source:
4236 4250 raise error.Abort(_("there is no Mercurial repository here "
4237 4251 "(.hg not found)"))
4238 4252
4239 4253 if ui.debugflag:
4240 4254 hexfunc = hex
4241 4255 else:
4242 4256 hexfunc = short
4243 4257 default = not (num or id or branch or tags or bookmarks)
4244 4258 output = []
4245 4259 revs = []
4246 4260
4247 4261 if source:
4248 4262 source, branches = hg.parseurl(ui.expandpath(source))
4249 4263 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4250 4264 repo = peer.local()
4251 4265 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4252 4266
4253 4267 if not repo:
4254 4268 if num or branch or tags:
4255 4269 raise error.Abort(
4256 4270 _("can't query remote revision number, branch, or tags"))
4257 4271 if not rev and revs:
4258 4272 rev = revs[0]
4259 4273 if not rev:
4260 4274 rev = "tip"
4261 4275
4262 4276 remoterev = peer.lookup(rev)
4263 4277 if default or id:
4264 4278 output = [hexfunc(remoterev)]
4265 4279
4266 4280 def getbms():
4267 4281 bms = []
4268 4282
4269 4283 if 'bookmarks' in peer.listkeys('namespaces'):
4270 4284 hexremoterev = hex(remoterev)
4271 4285 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4272 4286 if bmr == hexremoterev]
4273 4287
4274 4288 return sorted(bms)
4275 4289
4276 4290 if bookmarks:
4277 4291 output.extend(getbms())
4278 4292 elif default and not ui.quiet:
4279 4293 # multiple bookmarks for a single parent separated by '/'
4280 4294 bm = '/'.join(getbms())
4281 4295 if bm:
4282 4296 output.append(bm)
4283 4297 else:
4284 4298 ctx = scmutil.revsingle(repo, rev, None)
4285 4299
4286 4300 if ctx.rev() is None:
4287 4301 ctx = repo[None]
4288 4302 parents = ctx.parents()
4289 4303 taglist = []
4290 4304 for p in parents:
4291 4305 taglist.extend(p.tags())
4292 4306
4293 4307 changed = ""
4294 4308 if default or id or num:
4295 4309 if (any(repo.status())
4296 4310 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4297 4311 changed = '+'
4298 4312 if default or id:
4299 4313 output = ["%s%s" %
4300 4314 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4301 4315 if num:
4302 4316 output.append("%s%s" %
4303 4317 ('+'.join([str(p.rev()) for p in parents]), changed))
4304 4318 else:
4305 4319 if default or id:
4306 4320 output = [hexfunc(ctx.node())]
4307 4321 if num:
4308 4322 output.append(str(ctx.rev()))
4309 4323 taglist = ctx.tags()
4310 4324
4311 4325 if default and not ui.quiet:
4312 4326 b = ctx.branch()
4313 4327 if b != 'default':
4314 4328 output.append("(%s)" % b)
4315 4329
4316 4330 # multiple tags for a single parent separated by '/'
4317 4331 t = '/'.join(taglist)
4318 4332 if t:
4319 4333 output.append(t)
4320 4334
4321 4335 # multiple bookmarks for a single parent separated by '/'
4322 4336 bm = '/'.join(ctx.bookmarks())
4323 4337 if bm:
4324 4338 output.append(bm)
4325 4339 else:
4326 4340 if branch:
4327 4341 output.append(ctx.branch())
4328 4342
4329 4343 if tags:
4330 4344 output.extend(taglist)
4331 4345
4332 4346 if bookmarks:
4333 4347 output.extend(ctx.bookmarks())
4334 4348
4335 4349 ui.write("%s\n" % ' '.join(output))
4336 4350
4337 4351 @command('import|patch',
4338 4352 [('p', 'strip', 1,
4339 4353 _('directory strip option for patch. This has the same '
4340 4354 'meaning as the corresponding patch option'), _('NUM')),
4341 4355 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4342 4356 ('e', 'edit', False, _('invoke editor on commit messages')),
4343 4357 ('f', 'force', None,
4344 4358 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4345 4359 ('', 'no-commit', None,
4346 4360 _("don't commit, just update the working directory")),
4347 4361 ('', 'bypass', None,
4348 4362 _("apply patch without touching the working directory")),
4349 4363 ('', 'partial', None,
4350 4364 _('commit even if some hunks fail')),
4351 4365 ('', 'exact', None,
4352 4366 _('apply patch to the nodes from which it was generated')),
4353 4367 ('', 'prefix', '',
4354 4368 _('apply patch to subdirectory'), _('DIR')),
4355 4369 ('', 'import-branch', None,
4356 4370 _('use any branch information in patch (implied by --exact)'))] +
4357 4371 commitopts + commitopts2 + similarityopts,
4358 4372 _('[OPTION]... PATCH...'))
4359 4373 def import_(ui, repo, patch1=None, *patches, **opts):
4360 4374 """import an ordered set of patches
4361 4375
4362 4376 Import a list of patches and commit them individually (unless
4363 4377 --no-commit is specified).
4364 4378
4365 4379 Because import first applies changes to the working directory,
4366 4380 import will abort if there are outstanding changes.
4367 4381
4368 4382 You can import a patch straight from a mail message. Even patches
4369 4383 as attachments work (to use the body part, it must have type
4370 4384 text/plain or text/x-patch). From and Subject headers of email
4371 4385 message are used as default committer and commit message. All
4372 4386 text/plain body parts before first diff are added to commit
4373 4387 message.
4374 4388
4375 4389 If the imported patch was generated by :hg:`export`, user and
4376 4390 description from patch override values from message headers and
4377 4391 body. Values given on command line with -m/--message and -u/--user
4378 4392 override these.
4379 4393
4380 4394 If --exact is specified, import will set the working directory to
4381 4395 the parent of each patch before applying it, and will abort if the
4382 4396 resulting changeset has a different ID than the one recorded in
4383 4397 the patch. This may happen due to character set problems or other
4384 4398 deficiencies in the text patch format.
4385 4399
4386 4400 Use --bypass to apply and commit patches directly to the
4387 4401 repository, not touching the working directory. Without --exact,
4388 4402 patches will be applied on top of the working directory parent
4389 4403 revision.
4390 4404
4391 4405 With -s/--similarity, hg will attempt to discover renames and
4392 4406 copies in the patch in the same way as :hg:`addremove`.
4393 4407
4394 4408 Use --partial to ensure a changeset will be created from the patch
4395 4409 even if some hunks fail to apply. Hunks that fail to apply will be
4396 4410 written to a <target-file>.rej file. Conflicts can then be resolved
4397 4411 by hand before :hg:`commit --amend` is run to update the created
4398 4412 changeset. This flag exists to let people import patches that
4399 4413 partially apply without losing the associated metadata (author,
4400 4414 date, description, ...). Note that when none of the hunk applies
4401 4415 cleanly, :hg:`import --partial` will create an empty changeset,
4402 4416 importing only the patch metadata.
4403 4417
4404 4418 It is possible to use external patch programs to perform the patch
4405 4419 by setting the ``ui.patch`` configuration option. For the default
4406 4420 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4407 4421 See :hg:`help config` for more information about configuration
4408 4422 files and how to use these options.
4409 4423
4410 4424 To read a patch from standard input, use "-" as the patch name. If
4411 4425 a URL is specified, the patch will be downloaded from it.
4412 4426 See :hg:`help dates` for a list of formats valid for -d/--date.
4413 4427
4414 4428 .. container:: verbose
4415 4429
4416 4430 Examples:
4417 4431
4418 4432 - import a traditional patch from a website and detect renames::
4419 4433
4420 4434 hg import -s 80 http://example.com/bugfix.patch
4421 4435
4422 4436 - import a changeset from an hgweb server::
4423 4437
4424 4438 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4425 4439
4426 4440 - import all the patches in an Unix-style mbox::
4427 4441
4428 4442 hg import incoming-patches.mbox
4429 4443
4430 4444 - attempt to exactly restore an exported changeset (not always
4431 4445 possible)::
4432 4446
4433 4447 hg import --exact proposed-fix.patch
4434 4448
4435 4449 - use an external tool to apply a patch which is too fuzzy for
4436 4450 the default internal tool.
4437 4451
4438 4452 hg import --config ui.patch="patch --merge" fuzzy.patch
4439 4453
4440 4454 - change the default fuzzing from 2 to a less strict 7
4441 4455
4442 4456 hg import --config ui.fuzz=7 fuzz.patch
4443 4457
4444 4458 Returns 0 on success, 1 on partial success (see --partial).
4445 4459 """
4446 4460
4447 4461 if not patch1:
4448 4462 raise error.Abort(_('need at least one patch to import'))
4449 4463
4450 4464 patches = (patch1,) + patches
4451 4465
4452 4466 date = opts.get('date')
4453 4467 if date:
4454 4468 opts['date'] = util.parsedate(date)
4455 4469
4456 4470 update = not opts.get('bypass')
4457 4471 if not update and opts.get('no_commit'):
4458 4472 raise error.Abort(_('cannot use --no-commit with --bypass'))
4459 4473 try:
4460 4474 sim = float(opts.get('similarity') or 0)
4461 4475 except ValueError:
4462 4476 raise error.Abort(_('similarity must be a number'))
4463 4477 if sim < 0 or sim > 100:
4464 4478 raise error.Abort(_('similarity must be between 0 and 100'))
4465 4479 if sim and not update:
4466 4480 raise error.Abort(_('cannot use --similarity with --bypass'))
4467 4481 if opts.get('exact') and opts.get('edit'):
4468 4482 raise error.Abort(_('cannot use --exact with --edit'))
4469 4483 if opts.get('exact') and opts.get('prefix'):
4470 4484 raise error.Abort(_('cannot use --exact with --prefix'))
4471 4485
4472 4486 if update:
4473 4487 cmdutil.checkunfinished(repo)
4474 4488 if (opts.get('exact') or not opts.get('force')) and update:
4475 4489 cmdutil.bailifchanged(repo)
4476 4490
4477 4491 base = opts["base"]
4478 4492 wlock = dsguard = lock = tr = None
4479 4493 msgs = []
4480 4494 ret = 0
4481 4495
4482 4496
4483 4497 try:
4484 4498 try:
4485 4499 wlock = repo.wlock()
4486 4500 if not opts.get('no_commit'):
4487 4501 lock = repo.lock()
4488 4502 tr = repo.transaction('import')
4489 4503 else:
4490 4504 dsguard = cmdutil.dirstateguard(repo, 'import')
4491 4505 parents = repo.parents()
4492 4506 for patchurl in patches:
4493 4507 if patchurl == '-':
4494 4508 ui.status(_('applying patch from stdin\n'))
4495 4509 patchfile = ui.fin
4496 4510 patchurl = 'stdin' # for error message
4497 4511 else:
4498 4512 patchurl = os.path.join(base, patchurl)
4499 4513 ui.status(_('applying %s\n') % patchurl)
4500 4514 patchfile = hg.openpath(ui, patchurl)
4501 4515
4502 4516 haspatch = False
4503 4517 for hunk in patch.split(patchfile):
4504 4518 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4505 4519 parents, opts,
4506 4520 msgs, hg.clean)
4507 4521 if msg:
4508 4522 haspatch = True
4509 4523 ui.note(msg + '\n')
4510 4524 if update or opts.get('exact'):
4511 4525 parents = repo.parents()
4512 4526 else:
4513 4527 parents = [repo[node]]
4514 4528 if rej:
4515 4529 ui.write_err(_("patch applied partially\n"))
4516 4530 ui.write_err(_("(fix the .rej files and run "
4517 4531 "`hg commit --amend`)\n"))
4518 4532 ret = 1
4519 4533 break
4520 4534
4521 4535 if not haspatch:
4522 4536 raise error.Abort(_('%s: no diffs found') % patchurl)
4523 4537
4524 4538 if tr:
4525 4539 tr.close()
4526 4540 if msgs:
4527 4541 repo.savecommitmessage('\n* * *\n'.join(msgs))
4528 4542 if dsguard:
4529 4543 dsguard.close()
4530 4544 return ret
4531 4545 finally:
4532 4546 # TODO: get rid of this meaningless try/finally enclosing.
4533 4547 # this is kept only to reduce changes in a patch.
4534 4548 pass
4535 4549 finally:
4536 4550 if tr:
4537 4551 tr.release()
4538 4552 release(lock, dsguard, wlock)
4539 4553
4540 4554 @command('incoming|in',
4541 4555 [('f', 'force', None,
4542 4556 _('run even if remote repository is unrelated')),
4543 4557 ('n', 'newest-first', None, _('show newest record first')),
4544 4558 ('', 'bundle', '',
4545 4559 _('file to store the bundles into'), _('FILE')),
4546 4560 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4547 4561 ('B', 'bookmarks', False, _("compare bookmarks")),
4548 4562 ('b', 'branch', [],
4549 4563 _('a specific branch you would like to pull'), _('BRANCH')),
4550 4564 ] + logopts + remoteopts + subrepoopts,
4551 4565 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4552 4566 def incoming(ui, repo, source="default", **opts):
4553 4567 """show new changesets found in source
4554 4568
4555 4569 Show new changesets found in the specified path/URL or the default
4556 4570 pull location. These are the changesets that would have been pulled
4557 4571 if a pull at the time you issued this command.
4558 4572
4559 4573 See pull for valid source format details.
4560 4574
4561 4575 .. container:: verbose
4562 4576
4563 4577 With -B/--bookmarks, the result of bookmark comparison between
4564 4578 local and remote repositories is displayed. With -v/--verbose,
4565 4579 status is also displayed for each bookmark like below::
4566 4580
4567 4581 BM1 01234567890a added
4568 4582 BM2 1234567890ab advanced
4569 4583 BM3 234567890abc diverged
4570 4584 BM4 34567890abcd changed
4571 4585
4572 4586 The action taken locally when pulling depends on the
4573 4587 status of each bookmark:
4574 4588
4575 4589 :``added``: pull will create it
4576 4590 :``advanced``: pull will update it
4577 4591 :``diverged``: pull will create a divergent bookmark
4578 4592 :``changed``: result depends on remote changesets
4579 4593
4580 4594 From the point of view of pulling behavior, bookmark
4581 4595 existing only in the remote repository are treated as ``added``,
4582 4596 even if it is in fact locally deleted.
4583 4597
4584 4598 .. container:: verbose
4585 4599
4586 4600 For remote repository, using --bundle avoids downloading the
4587 4601 changesets twice if the incoming is followed by a pull.
4588 4602
4589 4603 Examples:
4590 4604
4591 4605 - show incoming changes with patches and full description::
4592 4606
4593 4607 hg incoming -vp
4594 4608
4595 4609 - show incoming changes excluding merges, store a bundle::
4596 4610
4597 4611 hg in -vpM --bundle incoming.hg
4598 4612 hg pull incoming.hg
4599 4613
4600 4614 - briefly list changes inside a bundle::
4601 4615
4602 4616 hg in changes.hg -T "{desc|firstline}\\n"
4603 4617
4604 4618 Returns 0 if there are incoming changes, 1 otherwise.
4605 4619 """
4606 4620 if opts.get('graph'):
4607 4621 cmdutil.checkunsupportedgraphflags([], opts)
4608 4622 def display(other, chlist, displayer):
4609 4623 revdag = cmdutil.graphrevs(other, chlist, opts)
4610 4624 showparents = [ctx.node() for ctx in repo[None].parents()]
4611 4625 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4612 4626 graphmod.asciiedges)
4613 4627
4614 4628 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4615 4629 return 0
4616 4630
4617 4631 if opts.get('bundle') and opts.get('subrepos'):
4618 4632 raise error.Abort(_('cannot combine --bundle and --subrepos'))
4619 4633
4620 4634 if opts.get('bookmarks'):
4621 4635 source, branches = hg.parseurl(ui.expandpath(source),
4622 4636 opts.get('branch'))
4623 4637 other = hg.peer(repo, opts, source)
4624 4638 if 'bookmarks' not in other.listkeys('namespaces'):
4625 4639 ui.warn(_("remote doesn't support bookmarks\n"))
4626 4640 return 0
4627 4641 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4628 4642 return bookmarks.incoming(ui, repo, other)
4629 4643
4630 4644 repo._subtoppath = ui.expandpath(source)
4631 4645 try:
4632 4646 return hg.incoming(ui, repo, source, opts)
4633 4647 finally:
4634 4648 del repo._subtoppath
4635 4649
4636 4650
4637 4651 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4638 4652 norepo=True)
4639 4653 def init(ui, dest=".", **opts):
4640 4654 """create a new repository in the given directory
4641 4655
4642 4656 Initialize a new repository in the given directory. If the given
4643 4657 directory does not exist, it will be created.
4644 4658
4645 4659 If no directory is given, the current directory is used.
4646 4660
4647 4661 It is possible to specify an ``ssh://`` URL as the destination.
4648 4662 See :hg:`help urls` for more information.
4649 4663
4650 4664 Returns 0 on success.
4651 4665 """
4652 4666 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4653 4667
4654 4668 @command('locate',
4655 4669 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4656 4670 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4657 4671 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4658 4672 ] + walkopts,
4659 4673 _('[OPTION]... [PATTERN]...'))
4660 4674 def locate(ui, repo, *pats, **opts):
4661 4675 """locate files matching specific patterns (DEPRECATED)
4662 4676
4663 4677 Print files under Mercurial control in the working directory whose
4664 4678 names match the given patterns.
4665 4679
4666 4680 By default, this command searches all directories in the working
4667 4681 directory. To search just the current directory and its
4668 4682 subdirectories, use "--include .".
4669 4683
4670 4684 If no patterns are given to match, this command prints the names
4671 4685 of all files under Mercurial control in the working directory.
4672 4686
4673 4687 If you want to feed the output of this command into the "xargs"
4674 4688 command, use the -0 option to both this command and "xargs". This
4675 4689 will avoid the problem of "xargs" treating single filenames that
4676 4690 contain whitespace as multiple filenames.
4677 4691
4678 4692 See :hg:`help files` for a more versatile command.
4679 4693
4680 4694 Returns 0 if a match is found, 1 otherwise.
4681 4695 """
4682 4696 if opts.get('print0'):
4683 4697 end = '\0'
4684 4698 else:
4685 4699 end = '\n'
4686 4700 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4687 4701
4688 4702 ret = 1
4689 4703 ctx = repo[rev]
4690 4704 m = scmutil.match(ctx, pats, opts, default='relglob',
4691 4705 badfn=lambda x, y: False)
4692 4706
4693 4707 for abs in ctx.matches(m):
4694 4708 if opts.get('fullpath'):
4695 4709 ui.write(repo.wjoin(abs), end)
4696 4710 else:
4697 4711 ui.write(((pats and m.rel(abs)) or abs), end)
4698 4712 ret = 0
4699 4713
4700 4714 return ret
4701 4715
4702 4716 @command('^log|history',
4703 4717 [('f', 'follow', None,
4704 4718 _('follow changeset history, or file history across copies and renames')),
4705 4719 ('', 'follow-first', None,
4706 4720 _('only follow the first parent of merge changesets (DEPRECATED)')),
4707 4721 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4708 4722 ('C', 'copies', None, _('show copied files')),
4709 4723 ('k', 'keyword', [],
4710 4724 _('do case-insensitive search for a given text'), _('TEXT')),
4711 4725 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4712 4726 ('', 'removed', None, _('include revisions where files were removed')),
4713 4727 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4714 4728 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4715 4729 ('', 'only-branch', [],
4716 4730 _('show only changesets within the given named branch (DEPRECATED)'),
4717 4731 _('BRANCH')),
4718 4732 ('b', 'branch', [],
4719 4733 _('show changesets within the given named branch'), _('BRANCH')),
4720 4734 ('P', 'prune', [],
4721 4735 _('do not display revision or any of its ancestors'), _('REV')),
4722 4736 ] + logopts + walkopts,
4723 4737 _('[OPTION]... [FILE]'),
4724 4738 inferrepo=True)
4725 4739 def log(ui, repo, *pats, **opts):
4726 4740 """show revision history of entire repository or files
4727 4741
4728 4742 Print the revision history of the specified files or the entire
4729 4743 project.
4730 4744
4731 4745 If no revision range is specified, the default is ``tip:0`` unless
4732 4746 --follow is set, in which case the working directory parent is
4733 4747 used as the starting revision.
4734 4748
4735 4749 File history is shown without following rename or copy history of
4736 4750 files. Use -f/--follow with a filename to follow history across
4737 4751 renames and copies. --follow without a filename will only show
4738 4752 ancestors or descendants of the starting revision.
4739 4753
4740 4754 By default this command prints revision number and changeset id,
4741 4755 tags, non-trivial parents, user, date and time, and a summary for
4742 4756 each commit. When the -v/--verbose switch is used, the list of
4743 4757 changed files and full commit message are shown.
4744 4758
4745 4759 With --graph the revisions are shown as an ASCII art DAG with the most
4746 4760 recent changeset at the top.
4747 4761 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4748 4762 and '+' represents a fork where the changeset from the lines below is a
4749 4763 parent of the 'o' merge on the same line.
4750 4764
4751 4765 .. note::
4752 4766
4753 4767 log -p/--patch may generate unexpected diff output for merge
4754 4768 changesets, as it will only compare the merge changeset against
4755 4769 its first parent. Also, only files different from BOTH parents
4756 4770 will appear in files:.
4757 4771
4758 4772 .. note::
4759 4773
4760 4774 for performance reasons, log FILE may omit duplicate changes
4761 4775 made on branches and will not show removals or mode changes. To
4762 4776 see all such changes, use the --removed switch.
4763 4777
4764 4778 .. container:: verbose
4765 4779
4766 4780 Some examples:
4767 4781
4768 4782 - changesets with full descriptions and file lists::
4769 4783
4770 4784 hg log -v
4771 4785
4772 4786 - changesets ancestral to the working directory::
4773 4787
4774 4788 hg log -f
4775 4789
4776 4790 - last 10 commits on the current branch::
4777 4791
4778 4792 hg log -l 10 -b .
4779 4793
4780 4794 - changesets showing all modifications of a file, including removals::
4781 4795
4782 4796 hg log --removed file.c
4783 4797
4784 4798 - all changesets that touch a directory, with diffs, excluding merges::
4785 4799
4786 4800 hg log -Mp lib/
4787 4801
4788 4802 - all revision numbers that match a keyword::
4789 4803
4790 4804 hg log -k bug --template "{rev}\\n"
4791 4805
4792 4806 - the full hash identifier of the working directory parent::
4793 4807
4794 4808 hg log -r . --template "{node}\\n"
4795 4809
4796 4810 - list available log templates::
4797 4811
4798 4812 hg log -T list
4799 4813
4800 4814 - check if a given changeset is included in a tagged release::
4801 4815
4802 4816 hg log -r "a21ccf and ancestor(1.9)"
4803 4817
4804 4818 - find all changesets by some user in a date range::
4805 4819
4806 4820 hg log -k alice -d "may 2008 to jul 2008"
4807 4821
4808 4822 - summary of all changesets after the last tag::
4809 4823
4810 4824 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4811 4825
4812 4826 See :hg:`help dates` for a list of formats valid for -d/--date.
4813 4827
4814 4828 See :hg:`help revisions` and :hg:`help revsets` for more about
4815 4829 specifying revisions.
4816 4830
4817 4831 See :hg:`help templates` for more about pre-packaged styles and
4818 4832 specifying custom templates.
4819 4833
4820 4834 Returns 0 on success.
4821 4835
4822 4836 """
4823 4837 if opts.get('follow') and opts.get('rev'):
4824 4838 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4825 4839 del opts['follow']
4826 4840
4827 4841 if opts.get('graph'):
4828 4842 return cmdutil.graphlog(ui, repo, *pats, **opts)
4829 4843
4830 4844 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4831 4845 limit = cmdutil.loglimit(opts)
4832 4846 count = 0
4833 4847
4834 4848 getrenamed = None
4835 4849 if opts.get('copies'):
4836 4850 endrev = None
4837 4851 if opts.get('rev'):
4838 4852 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4839 4853 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4840 4854
4841 4855 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4842 4856 for rev in revs:
4843 4857 if count == limit:
4844 4858 break
4845 4859 ctx = repo[rev]
4846 4860 copies = None
4847 4861 if getrenamed is not None and rev:
4848 4862 copies = []
4849 4863 for fn in ctx.files():
4850 4864 rename = getrenamed(fn, rev)
4851 4865 if rename:
4852 4866 copies.append((fn, rename[0]))
4853 4867 if filematcher:
4854 4868 revmatchfn = filematcher(ctx.rev())
4855 4869 else:
4856 4870 revmatchfn = None
4857 4871 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4858 4872 if displayer.flush(ctx):
4859 4873 count += 1
4860 4874
4861 4875 displayer.close()
4862 4876
4863 4877 @command('manifest',
4864 4878 [('r', 'rev', '', _('revision to display'), _('REV')),
4865 4879 ('', 'all', False, _("list files from all revisions"))]
4866 4880 + formatteropts,
4867 4881 _('[-r REV]'))
4868 4882 def manifest(ui, repo, node=None, rev=None, **opts):
4869 4883 """output the current or given revision of the project manifest
4870 4884
4871 4885 Print a list of version controlled files for the given revision.
4872 4886 If no revision is given, the first parent of the working directory
4873 4887 is used, or the null revision if no revision is checked out.
4874 4888
4875 4889 With -v, print file permissions, symlink and executable bits.
4876 4890 With --debug, print file revision hashes.
4877 4891
4878 4892 If option --all is specified, the list of all files from all revisions
4879 4893 is printed. This includes deleted and renamed files.
4880 4894
4881 4895 Returns 0 on success.
4882 4896 """
4883 4897
4884 4898 fm = ui.formatter('manifest', opts)
4885 4899
4886 4900 if opts.get('all'):
4887 4901 if rev or node:
4888 4902 raise error.Abort(_("can't specify a revision with --all"))
4889 4903
4890 4904 res = []
4891 4905 prefix = "data/"
4892 4906 suffix = ".i"
4893 4907 plen = len(prefix)
4894 4908 slen = len(suffix)
4895 4909 lock = repo.lock()
4896 4910 try:
4897 4911 for fn, b, size in repo.store.datafiles():
4898 4912 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4899 4913 res.append(fn[plen:-slen])
4900 4914 finally:
4901 4915 lock.release()
4902 4916 for f in res:
4903 4917 fm.startitem()
4904 4918 fm.write("path", '%s\n', f)
4905 4919 fm.end()
4906 4920 return
4907 4921
4908 4922 if rev and node:
4909 4923 raise error.Abort(_("please specify just one revision"))
4910 4924
4911 4925 if not node:
4912 4926 node = rev
4913 4927
4914 4928 char = {'l': '@', 'x': '*', '': ''}
4915 4929 mode = {'l': '644', 'x': '755', '': '644'}
4916 4930 ctx = scmutil.revsingle(repo, node)
4917 4931 mf = ctx.manifest()
4918 4932 for f in ctx:
4919 4933 fm.startitem()
4920 4934 fl = ctx[f].flags()
4921 4935 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4922 4936 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4923 4937 fm.write('path', '%s\n', f)
4924 4938 fm.end()
4925 4939
4926 4940 @command('^merge',
4927 4941 [('f', 'force', None,
4928 4942 _('force a merge including outstanding changes (DEPRECATED)')),
4929 4943 ('r', 'rev', '', _('revision to merge'), _('REV')),
4930 4944 ('P', 'preview', None,
4931 4945 _('review revisions to merge (no merge is performed)'))
4932 4946 ] + mergetoolopts,
4933 4947 _('[-P] [-f] [[-r] REV]'))
4934 4948 def merge(ui, repo, node=None, **opts):
4935 4949 """merge another revision into working directory
4936 4950
4937 4951 The current working directory is updated with all changes made in
4938 4952 the requested revision since the last common predecessor revision.
4939 4953
4940 4954 Files that changed between either parent are marked as changed for
4941 4955 the next commit and a commit must be performed before any further
4942 4956 updates to the repository are allowed. The next commit will have
4943 4957 two parents.
4944 4958
4945 4959 ``--tool`` can be used to specify the merge tool used for file
4946 4960 merges. It overrides the HGMERGE environment variable and your
4947 4961 configuration files. See :hg:`help merge-tools` for options.
4948 4962
4949 4963 If no revision is specified, the working directory's parent is a
4950 4964 head revision, and the current branch contains exactly one other
4951 4965 head, the other head is merged with by default. Otherwise, an
4952 4966 explicit revision with which to merge with must be provided.
4953 4967
4954 4968 :hg:`resolve` must be used to resolve unresolved files.
4955 4969
4956 4970 To undo an uncommitted merge, use :hg:`update --clean .` which
4957 4971 will check out a clean copy of the original merge parent, losing
4958 4972 all changes.
4959 4973
4960 4974 Returns 0 on success, 1 if there are unresolved files.
4961 4975 """
4962 4976
4963 4977 if opts.get('rev') and node:
4964 4978 raise error.Abort(_("please specify just one revision"))
4965 4979 if not node:
4966 4980 node = opts.get('rev')
4967 4981
4968 4982 if node:
4969 4983 node = scmutil.revsingle(repo, node).node()
4970 4984
4971 4985 if not node:
4972 4986 node = repo[destutil.destmerge(repo)].node()
4973 4987
4974 4988 if opts.get('preview'):
4975 4989 # find nodes that are ancestors of p2 but not of p1
4976 4990 p1 = repo.lookup('.')
4977 4991 p2 = repo.lookup(node)
4978 4992 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4979 4993
4980 4994 displayer = cmdutil.show_changeset(ui, repo, opts)
4981 4995 for node in nodes:
4982 4996 displayer.show(repo[node])
4983 4997 displayer.close()
4984 4998 return 0
4985 4999
4986 5000 try:
4987 5001 # ui.forcemerge is an internal variable, do not document
4988 5002 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4989 5003 return hg.merge(repo, node, force=opts.get('force'))
4990 5004 finally:
4991 5005 ui.setconfig('ui', 'forcemerge', '', 'merge')
4992 5006
4993 5007 @command('outgoing|out',
4994 5008 [('f', 'force', None, _('run even when the destination is unrelated')),
4995 5009 ('r', 'rev', [],
4996 5010 _('a changeset intended to be included in the destination'), _('REV')),
4997 5011 ('n', 'newest-first', None, _('show newest record first')),
4998 5012 ('B', 'bookmarks', False, _('compare bookmarks')),
4999 5013 ('b', 'branch', [], _('a specific branch you would like to push'),
5000 5014 _('BRANCH')),
5001 5015 ] + logopts + remoteopts + subrepoopts,
5002 5016 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
5003 5017 def outgoing(ui, repo, dest=None, **opts):
5004 5018 """show changesets not found in the destination
5005 5019
5006 5020 Show changesets not found in the specified destination repository
5007 5021 or the default push location. These are the changesets that would
5008 5022 be pushed if a push was requested.
5009 5023
5010 5024 See pull for details of valid destination formats.
5011 5025
5012 5026 .. container:: verbose
5013 5027
5014 5028 With -B/--bookmarks, the result of bookmark comparison between
5015 5029 local and remote repositories is displayed. With -v/--verbose,
5016 5030 status is also displayed for each bookmark like below::
5017 5031
5018 5032 BM1 01234567890a added
5019 5033 BM2 deleted
5020 5034 BM3 234567890abc advanced
5021 5035 BM4 34567890abcd diverged
5022 5036 BM5 4567890abcde changed
5023 5037
5024 5038 The action taken when pushing depends on the
5025 5039 status of each bookmark:
5026 5040
5027 5041 :``added``: push with ``-B`` will create it
5028 5042 :``deleted``: push with ``-B`` will delete it
5029 5043 :``advanced``: push will update it
5030 5044 :``diverged``: push with ``-B`` will update it
5031 5045 :``changed``: push with ``-B`` will update it
5032 5046
5033 5047 From the point of view of pushing behavior, bookmarks
5034 5048 existing only in the remote repository are treated as
5035 5049 ``deleted``, even if it is in fact added remotely.
5036 5050
5037 5051 Returns 0 if there are outgoing changes, 1 otherwise.
5038 5052 """
5039 5053 if opts.get('graph'):
5040 5054 cmdutil.checkunsupportedgraphflags([], opts)
5041 5055 o, other = hg._outgoing(ui, repo, dest, opts)
5042 5056 if not o:
5043 5057 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5044 5058 return
5045 5059
5046 5060 revdag = cmdutil.graphrevs(repo, o, opts)
5047 5061 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
5048 5062 showparents = [ctx.node() for ctx in repo[None].parents()]
5049 5063 cmdutil.displaygraph(ui, revdag, displayer, showparents,
5050 5064 graphmod.asciiedges)
5051 5065 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5052 5066 return 0
5053 5067
5054 5068 if opts.get('bookmarks'):
5055 5069 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5056 5070 dest, branches = hg.parseurl(dest, opts.get('branch'))
5057 5071 other = hg.peer(repo, opts, dest)
5058 5072 if 'bookmarks' not in other.listkeys('namespaces'):
5059 5073 ui.warn(_("remote doesn't support bookmarks\n"))
5060 5074 return 0
5061 5075 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
5062 5076 return bookmarks.outgoing(ui, repo, other)
5063 5077
5064 5078 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
5065 5079 try:
5066 5080 return hg.outgoing(ui, repo, dest, opts)
5067 5081 finally:
5068 5082 del repo._subtoppath
5069 5083
5070 5084 @command('parents',
5071 5085 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
5072 5086 ] + templateopts,
5073 5087 _('[-r REV] [FILE]'),
5074 5088 inferrepo=True)
5075 5089 def parents(ui, repo, file_=None, **opts):
5076 5090 """show the parents of the working directory or revision (DEPRECATED)
5077 5091
5078 5092 Print the working directory's parent revisions. If a revision is
5079 5093 given via -r/--rev, the parent of that revision will be printed.
5080 5094 If a file argument is given, the revision in which the file was
5081 5095 last changed (before the working directory revision or the
5082 5096 argument to --rev if given) is printed.
5083 5097
5084 5098 See :hg:`summary` and :hg:`help revsets` for related information.
5085 5099
5086 5100 Returns 0 on success.
5087 5101 """
5088 5102
5089 5103 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
5090 5104
5091 5105 if file_:
5092 5106 m = scmutil.match(ctx, (file_,), opts)
5093 5107 if m.anypats() or len(m.files()) != 1:
5094 5108 raise error.Abort(_('can only specify an explicit filename'))
5095 5109 file_ = m.files()[0]
5096 5110 filenodes = []
5097 5111 for cp in ctx.parents():
5098 5112 if not cp:
5099 5113 continue
5100 5114 try:
5101 5115 filenodes.append(cp.filenode(file_))
5102 5116 except error.LookupError:
5103 5117 pass
5104 5118 if not filenodes:
5105 5119 raise error.Abort(_("'%s' not found in manifest!") % file_)
5106 5120 p = []
5107 5121 for fn in filenodes:
5108 5122 fctx = repo.filectx(file_, fileid=fn)
5109 5123 p.append(fctx.node())
5110 5124 else:
5111 5125 p = [cp.node() for cp in ctx.parents()]
5112 5126
5113 5127 displayer = cmdutil.show_changeset(ui, repo, opts)
5114 5128 for n in p:
5115 5129 if n != nullid:
5116 5130 displayer.show(repo[n])
5117 5131 displayer.close()
5118 5132
5119 5133 @command('paths', [], _('[NAME]'), optionalrepo=True)
5120 5134 def paths(ui, repo, search=None):
5121 5135 """show aliases for remote repositories
5122 5136
5123 5137 Show definition of symbolic path name NAME. If no name is given,
5124 5138 show definition of all available names.
5125 5139
5126 5140 Option -q/--quiet suppresses all output when searching for NAME
5127 5141 and shows only the path names when listing all definitions.
5128 5142
5129 5143 Path names are defined in the [paths] section of your
5130 5144 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5131 5145 repository, ``.hg/hgrc`` is used, too.
5132 5146
5133 5147 The path names ``default`` and ``default-push`` have a special
5134 5148 meaning. When performing a push or pull operation, they are used
5135 5149 as fallbacks if no location is specified on the command-line.
5136 5150 When ``default-push`` is set, it will be used for push and
5137 5151 ``default`` will be used for pull; otherwise ``default`` is used
5138 5152 as the fallback for both. When cloning a repository, the clone
5139 5153 source is written as ``default`` in ``.hg/hgrc``. Note that
5140 5154 ``default`` and ``default-push`` apply to all inbound (e.g.
5141 5155 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
5142 5156 :hg:`bundle`) operations.
5143 5157
5144 5158 See :hg:`help urls` for more information.
5145 5159
5146 5160 Returns 0 on success.
5147 5161 """
5148 5162 if search:
5149 5163 for name, path in sorted(ui.paths.iteritems()):
5150 5164 if name == search:
5151 5165 ui.status("%s\n" % util.hidepassword(path.loc))
5152 5166 return
5153 5167 if not ui.quiet:
5154 5168 ui.warn(_("not found!\n"))
5155 5169 return 1
5156 5170 else:
5157 5171 for name, path in sorted(ui.paths.iteritems()):
5158 5172 if ui.quiet:
5159 5173 ui.write("%s\n" % name)
5160 5174 else:
5161 5175 ui.write("%s = %s\n" % (name,
5162 5176 util.hidepassword(path.loc)))
5163 5177
5164 5178 @command('phase',
5165 5179 [('p', 'public', False, _('set changeset phase to public')),
5166 5180 ('d', 'draft', False, _('set changeset phase to draft')),
5167 5181 ('s', 'secret', False, _('set changeset phase to secret')),
5168 5182 ('f', 'force', False, _('allow to move boundary backward')),
5169 5183 ('r', 'rev', [], _('target revision'), _('REV')),
5170 5184 ],
5171 5185 _('[-p|-d|-s] [-f] [-r] [REV...]'))
5172 5186 def phase(ui, repo, *revs, **opts):
5173 5187 """set or show the current phase name
5174 5188
5175 5189 With no argument, show the phase name of the current revision(s).
5176 5190
5177 5191 With one of -p/--public, -d/--draft or -s/--secret, change the
5178 5192 phase value of the specified revisions.
5179 5193
5180 5194 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5181 5195 lower phase to an higher phase. Phases are ordered as follows::
5182 5196
5183 5197 public < draft < secret
5184 5198
5185 5199 Returns 0 on success, 1 if some phases could not be changed.
5186 5200
5187 5201 (For more information about the phases concept, see :hg:`help phases`.)
5188 5202 """
5189 5203 # search for a unique phase argument
5190 5204 targetphase = None
5191 5205 for idx, name in enumerate(phases.phasenames):
5192 5206 if opts[name]:
5193 5207 if targetphase is not None:
5194 5208 raise error.Abort(_('only one phase can be specified'))
5195 5209 targetphase = idx
5196 5210
5197 5211 # look for specified revision
5198 5212 revs = list(revs)
5199 5213 revs.extend(opts['rev'])
5200 5214 if not revs:
5201 5215 # display both parents as the second parent phase can influence
5202 5216 # the phase of a merge commit
5203 5217 revs = [c.rev() for c in repo[None].parents()]
5204 5218
5205 5219 revs = scmutil.revrange(repo, revs)
5206 5220
5207 5221 lock = None
5208 5222 ret = 0
5209 5223 if targetphase is None:
5210 5224 # display
5211 5225 for r in revs:
5212 5226 ctx = repo[r]
5213 5227 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5214 5228 else:
5215 5229 tr = None
5216 5230 lock = repo.lock()
5217 5231 try:
5218 5232 tr = repo.transaction("phase")
5219 5233 # set phase
5220 5234 if not revs:
5221 5235 raise error.Abort(_('empty revision set'))
5222 5236 nodes = [repo[r].node() for r in revs]
5223 5237 # moving revision from public to draft may hide them
5224 5238 # We have to check result on an unfiltered repository
5225 5239 unfi = repo.unfiltered()
5226 5240 getphase = unfi._phasecache.phase
5227 5241 olddata = [getphase(unfi, r) for r in unfi]
5228 5242 phases.advanceboundary(repo, tr, targetphase, nodes)
5229 5243 if opts['force']:
5230 5244 phases.retractboundary(repo, tr, targetphase, nodes)
5231 5245 tr.close()
5232 5246 finally:
5233 5247 if tr is not None:
5234 5248 tr.release()
5235 5249 lock.release()
5236 5250 getphase = unfi._phasecache.phase
5237 5251 newdata = [getphase(unfi, r) for r in unfi]
5238 5252 changes = sum(newdata[r] != olddata[r] for r in unfi)
5239 5253 cl = unfi.changelog
5240 5254 rejected = [n for n in nodes
5241 5255 if newdata[cl.rev(n)] < targetphase]
5242 5256 if rejected:
5243 5257 ui.warn(_('cannot move %i changesets to a higher '
5244 5258 'phase, use --force\n') % len(rejected))
5245 5259 ret = 1
5246 5260 if changes:
5247 5261 msg = _('phase changed for %i changesets\n') % changes
5248 5262 if ret:
5249 5263 ui.status(msg)
5250 5264 else:
5251 5265 ui.note(msg)
5252 5266 else:
5253 5267 ui.warn(_('no phases changed\n'))
5254 5268 return ret
5255 5269
5256 5270 def postincoming(ui, repo, modheads, optupdate, checkout):
5257 5271 if modheads == 0:
5258 5272 return
5259 5273 if optupdate:
5260 5274 try:
5261 5275 brev = checkout
5262 5276 movemarkfrom = None
5263 5277 if not checkout:
5264 5278 updata = destutil.destupdate(repo)
5265 5279 checkout, movemarkfrom, brev = updata
5266 5280 ret = hg.update(repo, checkout)
5267 5281 except error.UpdateAbort as inst:
5268 5282 msg = _("not updating: %s") % str(inst)
5269 5283 hint = inst.hint
5270 5284 raise error.UpdateAbort(msg, hint=hint)
5271 5285 if not ret and not checkout:
5272 5286 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5273 5287 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5274 5288 return ret
5275 5289 if modheads > 1:
5276 5290 currentbranchheads = len(repo.branchheads())
5277 5291 if currentbranchheads == modheads:
5278 5292 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5279 5293 elif currentbranchheads > 1:
5280 5294 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5281 5295 "merge)\n"))
5282 5296 else:
5283 5297 ui.status(_("(run 'hg heads' to see heads)\n"))
5284 5298 else:
5285 5299 ui.status(_("(run 'hg update' to get a working copy)\n"))
5286 5300
5287 5301 @command('^pull',
5288 5302 [('u', 'update', None,
5289 5303 _('update to new branch head if changesets were pulled')),
5290 5304 ('f', 'force', None, _('run even when remote repository is unrelated')),
5291 5305 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5292 5306 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5293 5307 ('b', 'branch', [], _('a specific branch you would like to pull'),
5294 5308 _('BRANCH')),
5295 5309 ] + remoteopts,
5296 5310 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5297 5311 def pull(ui, repo, source="default", **opts):
5298 5312 """pull changes from the specified source
5299 5313
5300 5314 Pull changes from a remote repository to a local one.
5301 5315
5302 5316 This finds all changes from the repository at the specified path
5303 5317 or URL and adds them to a local repository (the current one unless
5304 5318 -R is specified). By default, this does not update the copy of the
5305 5319 project in the working directory.
5306 5320
5307 5321 Use :hg:`incoming` if you want to see what would have been added
5308 5322 by a pull at the time you issued this command. If you then decide
5309 5323 to add those changes to the repository, you should use :hg:`pull
5310 5324 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5311 5325
5312 5326 If SOURCE is omitted, the 'default' path will be used.
5313 5327 See :hg:`help urls` for more information.
5314 5328
5315 5329 Returns 0 on success, 1 if an update had unresolved files.
5316 5330 """
5317 5331 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5318 5332 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5319 5333 other = hg.peer(repo, opts, source)
5320 5334 try:
5321 5335 revs, checkout = hg.addbranchrevs(repo, other, branches,
5322 5336 opts.get('rev'))
5323 5337
5324 5338
5325 5339 pullopargs = {}
5326 5340 if opts.get('bookmark'):
5327 5341 if not revs:
5328 5342 revs = []
5329 5343 # The list of bookmark used here is not the one used to actually
5330 5344 # update the bookmark name. This can result in the revision pulled
5331 5345 # not ending up with the name of the bookmark because of a race
5332 5346 # condition on the server. (See issue 4689 for details)
5333 5347 remotebookmarks = other.listkeys('bookmarks')
5334 5348 pullopargs['remotebookmarks'] = remotebookmarks
5335 5349 for b in opts['bookmark']:
5336 5350 if b not in remotebookmarks:
5337 5351 raise error.Abort(_('remote bookmark %s not found!') % b)
5338 5352 revs.append(remotebookmarks[b])
5339 5353
5340 5354 if revs:
5341 5355 try:
5342 5356 # When 'rev' is a bookmark name, we cannot guarantee that it
5343 5357 # will be updated with that name because of a race condition
5344 5358 # server side. (See issue 4689 for details)
5345 5359 oldrevs = revs
5346 5360 revs = [] # actually, nodes
5347 5361 for r in oldrevs:
5348 5362 node = other.lookup(r)
5349 5363 revs.append(node)
5350 5364 if r == checkout:
5351 5365 checkout = node
5352 5366 except error.CapabilityError:
5353 5367 err = _("other repository doesn't support revision lookup, "
5354 5368 "so a rev cannot be specified.")
5355 5369 raise error.Abort(err)
5356 5370
5357 5371 pullopargs.update(opts.get('opargs', {}))
5358 5372 modheads = exchange.pull(repo, other, heads=revs,
5359 5373 force=opts.get('force'),
5360 5374 bookmarks=opts.get('bookmark', ()),
5361 5375 opargs=pullopargs).cgresult
5362 5376 if checkout:
5363 5377 checkout = str(repo.changelog.rev(checkout))
5364 5378 repo._subtoppath = source
5365 5379 try:
5366 5380 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5367 5381
5368 5382 finally:
5369 5383 del repo._subtoppath
5370 5384
5371 5385 finally:
5372 5386 other.close()
5373 5387 return ret
5374 5388
5375 5389 @command('^push',
5376 5390 [('f', 'force', None, _('force push')),
5377 5391 ('r', 'rev', [],
5378 5392 _('a changeset intended to be included in the destination'),
5379 5393 _('REV')),
5380 5394 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5381 5395 ('b', 'branch', [],
5382 5396 _('a specific branch you would like to push'), _('BRANCH')),
5383 5397 ('', 'new-branch', False, _('allow pushing a new branch')),
5384 5398 ] + remoteopts,
5385 5399 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5386 5400 def push(ui, repo, dest=None, **opts):
5387 5401 """push changes to the specified destination
5388 5402
5389 5403 Push changesets from the local repository to the specified
5390 5404 destination.
5391 5405
5392 5406 This operation is symmetrical to pull: it is identical to a pull
5393 5407 in the destination repository from the current one.
5394 5408
5395 5409 By default, push will not allow creation of new heads at the
5396 5410 destination, since multiple heads would make it unclear which head
5397 5411 to use. In this situation, it is recommended to pull and merge
5398 5412 before pushing.
5399 5413
5400 5414 Use --new-branch if you want to allow push to create a new named
5401 5415 branch that is not present at the destination. This allows you to
5402 5416 only create a new branch without forcing other changes.
5403 5417
5404 5418 .. note::
5405 5419
5406 5420 Extra care should be taken with the -f/--force option,
5407 5421 which will push all new heads on all branches, an action which will
5408 5422 almost always cause confusion for collaborators.
5409 5423
5410 5424 If -r/--rev is used, the specified revision and all its ancestors
5411 5425 will be pushed to the remote repository.
5412 5426
5413 5427 If -B/--bookmark is used, the specified bookmarked revision, its
5414 5428 ancestors, and the bookmark will be pushed to the remote
5415 5429 repository.
5416 5430
5417 5431 Please see :hg:`help urls` for important details about ``ssh://``
5418 5432 URLs. If DESTINATION is omitted, a default path will be used.
5419 5433
5420 5434 Returns 0 if push was successful, 1 if nothing to push.
5421 5435 """
5422 5436
5423 5437 if opts.get('bookmark'):
5424 5438 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5425 5439 for b in opts['bookmark']:
5426 5440 # translate -B options to -r so changesets get pushed
5427 5441 if b in repo._bookmarks:
5428 5442 opts.setdefault('rev', []).append(b)
5429 5443 else:
5430 5444 # if we try to push a deleted bookmark, translate it to null
5431 5445 # this lets simultaneous -r, -b options continue working
5432 5446 opts.setdefault('rev', []).append("null")
5433 5447
5434 5448 path = ui.paths.getpath(dest, default='default')
5435 5449 if not path:
5436 5450 raise error.Abort(_('default repository not configured!'),
5437 5451 hint=_('see the "path" section in "hg help config"'))
5438 5452 dest, branches = path.pushloc, (path.branch, opts.get('branch') or [])
5439 5453 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5440 5454 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5441 5455 other = hg.peer(repo, opts, dest)
5442 5456
5443 5457 if revs:
5444 5458 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5445 5459 if not revs:
5446 5460 raise error.Abort(_("specified revisions evaluate to an empty set"),
5447 5461 hint=_("use different revision arguments"))
5448 5462
5449 5463 repo._subtoppath = dest
5450 5464 try:
5451 5465 # push subrepos depth-first for coherent ordering
5452 5466 c = repo['']
5453 5467 subs = c.substate # only repos that are committed
5454 5468 for s in sorted(subs):
5455 5469 result = c.sub(s).push(opts)
5456 5470 if result == 0:
5457 5471 return not result
5458 5472 finally:
5459 5473 del repo._subtoppath
5460 5474 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5461 5475 newbranch=opts.get('new_branch'),
5462 5476 bookmarks=opts.get('bookmark', ()),
5463 5477 opargs=opts.get('opargs'))
5464 5478
5465 5479 result = not pushop.cgresult
5466 5480
5467 5481 if pushop.bkresult is not None:
5468 5482 if pushop.bkresult == 2:
5469 5483 result = 2
5470 5484 elif not result and pushop.bkresult:
5471 5485 result = 2
5472 5486
5473 5487 return result
5474 5488
5475 5489 @command('recover', [])
5476 5490 def recover(ui, repo):
5477 5491 """roll back an interrupted transaction
5478 5492
5479 5493 Recover from an interrupted commit or pull.
5480 5494
5481 5495 This command tries to fix the repository status after an
5482 5496 interrupted operation. It should only be necessary when Mercurial
5483 5497 suggests it.
5484 5498
5485 5499 Returns 0 if successful, 1 if nothing to recover or verify fails.
5486 5500 """
5487 5501 if repo.recover():
5488 5502 return hg.verify(repo)
5489 5503 return 1
5490 5504
5491 5505 @command('^remove|rm',
5492 5506 [('A', 'after', None, _('record delete for missing files')),
5493 5507 ('f', 'force', None,
5494 5508 _('remove (and delete) file even if added or modified')),
5495 5509 ] + subrepoopts + walkopts,
5496 5510 _('[OPTION]... FILE...'),
5497 5511 inferrepo=True)
5498 5512 def remove(ui, repo, *pats, **opts):
5499 5513 """remove the specified files on the next commit
5500 5514
5501 5515 Schedule the indicated files for removal from the current branch.
5502 5516
5503 5517 This command schedules the files to be removed at the next commit.
5504 5518 To undo a remove before that, see :hg:`revert`. To undo added
5505 5519 files, see :hg:`forget`.
5506 5520
5507 5521 .. container:: verbose
5508 5522
5509 5523 -A/--after can be used to remove only files that have already
5510 5524 been deleted, -f/--force can be used to force deletion, and -Af
5511 5525 can be used to remove files from the next revision without
5512 5526 deleting them from the working directory.
5513 5527
5514 5528 The following table details the behavior of remove for different
5515 5529 file states (columns) and option combinations (rows). The file
5516 5530 states are Added [A], Clean [C], Modified [M] and Missing [!]
5517 5531 (as reported by :hg:`status`). The actions are Warn, Remove
5518 5532 (from branch) and Delete (from disk):
5519 5533
5520 5534 ========= == == == ==
5521 5535 opt/state A C M !
5522 5536 ========= == == == ==
5523 5537 none W RD W R
5524 5538 -f R RD RD R
5525 5539 -A W W W R
5526 5540 -Af R R R R
5527 5541 ========= == == == ==
5528 5542
5529 5543 Note that remove never deletes files in Added [A] state from the
5530 5544 working directory, not even if option --force is specified.
5531 5545
5532 5546 Returns 0 on success, 1 if any warnings encountered.
5533 5547 """
5534 5548
5535 5549 after, force = opts.get('after'), opts.get('force')
5536 5550 if not pats and not after:
5537 5551 raise error.Abort(_('no files specified'))
5538 5552
5539 5553 m = scmutil.match(repo[None], pats, opts)
5540 5554 subrepos = opts.get('subrepos')
5541 5555 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5542 5556
5543 5557 @command('rename|move|mv',
5544 5558 [('A', 'after', None, _('record a rename that has already occurred')),
5545 5559 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5546 5560 ] + walkopts + dryrunopts,
5547 5561 _('[OPTION]... SOURCE... DEST'))
5548 5562 def rename(ui, repo, *pats, **opts):
5549 5563 """rename files; equivalent of copy + remove
5550 5564
5551 5565 Mark dest as copies of sources; mark sources for deletion. If dest
5552 5566 is a directory, copies are put in that directory. If dest is a
5553 5567 file, there can only be one source.
5554 5568
5555 5569 By default, this command copies the contents of files as they
5556 5570 exist in the working directory. If invoked with -A/--after, the
5557 5571 operation is recorded, but no copying is performed.
5558 5572
5559 5573 This command takes effect at the next commit. To undo a rename
5560 5574 before that, see :hg:`revert`.
5561 5575
5562 5576 Returns 0 on success, 1 if errors are encountered.
5563 5577 """
5564 5578 wlock = repo.wlock(False)
5565 5579 try:
5566 5580 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5567 5581 finally:
5568 5582 wlock.release()
5569 5583
5570 5584 @command('resolve',
5571 5585 [('a', 'all', None, _('select all unresolved files')),
5572 5586 ('l', 'list', None, _('list state of files needing merge')),
5573 5587 ('m', 'mark', None, _('mark files as resolved')),
5574 5588 ('u', 'unmark', None, _('mark files as unresolved')),
5575 5589 ('n', 'no-status', None, _('hide status prefix'))]
5576 5590 + mergetoolopts + walkopts + formatteropts,
5577 5591 _('[OPTION]... [FILE]...'),
5578 5592 inferrepo=True)
5579 5593 def resolve(ui, repo, *pats, **opts):
5580 5594 """redo merges or set/view the merge status of files
5581 5595
5582 5596 Merges with unresolved conflicts are often the result of
5583 5597 non-interactive merging using the ``internal:merge`` configuration
5584 5598 setting, or a command-line merge tool like ``diff3``. The resolve
5585 5599 command is used to manage the files involved in a merge, after
5586 5600 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5587 5601 working directory must have two parents). See :hg:`help
5588 5602 merge-tools` for information on configuring merge tools.
5589 5603
5590 5604 The resolve command can be used in the following ways:
5591 5605
5592 5606 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5593 5607 files, discarding any previous merge attempts. Re-merging is not
5594 5608 performed for files already marked as resolved. Use ``--all/-a``
5595 5609 to select all unresolved files. ``--tool`` can be used to specify
5596 5610 the merge tool used for the given files. It overrides the HGMERGE
5597 5611 environment variable and your configuration files. Previous file
5598 5612 contents are saved with a ``.orig`` suffix.
5599 5613
5600 5614 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5601 5615 (e.g. after having manually fixed-up the files). The default is
5602 5616 to mark all unresolved files.
5603 5617
5604 5618 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5605 5619 default is to mark all resolved files.
5606 5620
5607 5621 - :hg:`resolve -l`: list files which had or still have conflicts.
5608 5622 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5609 5623
5610 5624 Note that Mercurial will not let you commit files with unresolved
5611 5625 merge conflicts. You must use :hg:`resolve -m ...` before you can
5612 5626 commit after a conflicting merge.
5613 5627
5614 5628 Returns 0 on success, 1 if any files fail a resolve attempt.
5615 5629 """
5616 5630
5617 5631 all, mark, unmark, show, nostatus = \
5618 5632 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5619 5633
5620 5634 if (show and (mark or unmark)) or (mark and unmark):
5621 5635 raise error.Abort(_("too many options specified"))
5622 5636 if pats and all:
5623 5637 raise error.Abort(_("can't specify --all and patterns"))
5624 5638 if not (all or pats or show or mark or unmark):
5625 5639 raise error.Abort(_('no files or directories specified'),
5626 5640 hint=('use --all to re-merge all unresolved files'))
5627 5641
5628 5642 if show:
5629 5643 fm = ui.formatter('resolve', opts)
5630 5644 ms = mergemod.mergestate.read(repo)
5631 5645 m = scmutil.match(repo[None], pats, opts)
5632 5646 for f in ms:
5633 5647 if not m(f):
5634 5648 continue
5635 5649 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
5636 5650 'd': 'driverresolved'}[ms[f]]
5637 5651 fm.startitem()
5638 5652 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5639 5653 fm.write('path', '%s\n', f, label=l)
5640 5654 fm.end()
5641 5655 return 0
5642 5656
5643 5657 wlock = repo.wlock()
5644 5658 try:
5645 5659 ms = mergemod.mergestate.read(repo)
5646 5660
5647 5661 if not (ms.active() or repo.dirstate.p2() != nullid):
5648 5662 raise error.Abort(
5649 5663 _('resolve command not applicable when not merging'))
5650 5664
5651 5665 wctx = repo[None]
5652 5666
5653 5667 if ms.mergedriver and ms.mdstate() == 'u':
5654 5668 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5655 5669 ms.commit()
5656 5670 # allow mark and unmark to go through
5657 5671 if not mark and not unmark and not proceed:
5658 5672 return 1
5659 5673
5660 5674 m = scmutil.match(wctx, pats, opts)
5661 5675 ret = 0
5662 5676 didwork = False
5663 5677 runconclude = False
5664 5678
5665 5679 tocomplete = []
5666 5680 for f in ms:
5667 5681 if not m(f):
5668 5682 continue
5669 5683
5670 5684 didwork = True
5671 5685
5672 5686 # don't let driver-resolved files be marked, and run the conclude
5673 5687 # step if asked to resolve
5674 5688 if ms[f] == "d":
5675 5689 exact = m.exact(f)
5676 5690 if mark:
5677 5691 if exact:
5678 5692 ui.warn(_('not marking %s as it is driver-resolved\n')
5679 5693 % f)
5680 5694 elif unmark:
5681 5695 if exact:
5682 5696 ui.warn(_('not unmarking %s as it is driver-resolved\n')
5683 5697 % f)
5684 5698 else:
5685 5699 runconclude = True
5686 5700 continue
5687 5701
5688 5702 if mark:
5689 5703 ms.mark(f, "r")
5690 5704 elif unmark:
5691 5705 ms.mark(f, "u")
5692 5706 else:
5693 5707 # backup pre-resolve (merge uses .orig for its own purposes)
5694 5708 a = repo.wjoin(f)
5695 5709 try:
5696 5710 util.copyfile(a, a + ".resolve")
5697 5711 except (IOError, OSError) as inst:
5698 5712 if inst.errno != errno.ENOENT:
5699 5713 raise
5700 5714
5701 5715 try:
5702 5716 # preresolve file
5703 5717 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5704 5718 'resolve')
5705 5719 complete, r = ms.preresolve(f, wctx)
5706 5720 if not complete:
5707 5721 tocomplete.append(f)
5708 5722 elif r:
5709 5723 ret = 1
5710 5724 finally:
5711 5725 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5712 5726 ms.commit()
5713 5727
5714 5728 # replace filemerge's .orig file with our resolve file, but only
5715 5729 # for merges that are complete
5716 5730 if complete:
5717 5731 try:
5718 5732 util.rename(a + ".resolve",
5719 5733 cmdutil.origpath(ui, repo, a))
5720 5734 except OSError as inst:
5721 5735 if inst.errno != errno.ENOENT:
5722 5736 raise
5723 5737
5724 5738 for f in tocomplete:
5725 5739 try:
5726 5740 # resolve file
5727 5741 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5728 5742 'resolve')
5729 5743 r = ms.resolve(f, wctx)
5730 5744 if r:
5731 5745 ret = 1
5732 5746 finally:
5733 5747 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5734 5748 ms.commit()
5735 5749
5736 5750 # replace filemerge's .orig file with our resolve file
5737 5751 a = repo.wjoin(f)
5738 5752 try:
5739 5753 util.rename(a + ".resolve", cmdutil.origpath(ui, repo, a))
5740 5754 except OSError as inst:
5741 5755 if inst.errno != errno.ENOENT:
5742 5756 raise
5743 5757
5744 5758 ms.commit()
5745 5759 ms.recordactions()
5746 5760
5747 5761 if not didwork and pats:
5748 5762 ui.warn(_("arguments do not match paths that need resolving\n"))
5749 5763 elif ms.mergedriver and ms.mdstate() != 's':
5750 5764 # run conclude step when either a driver-resolved file is requested
5751 5765 # or there are no driver-resolved files
5752 5766 # we can't use 'ret' to determine whether any files are unresolved
5753 5767 # because we might not have tried to resolve some
5754 5768 if ((runconclude or not list(ms.driverresolved()))
5755 5769 and not list(ms.unresolved())):
5756 5770 proceed = mergemod.driverconclude(repo, ms, wctx)
5757 5771 ms.commit()
5758 5772 if not proceed:
5759 5773 return 1
5760 5774
5761 5775 finally:
5762 5776 wlock.release()
5763 5777
5764 5778 # Nudge users into finishing an unfinished operation
5765 5779 unresolvedf = list(ms.unresolved())
5766 5780 driverresolvedf = list(ms.driverresolved())
5767 5781 if not unresolvedf and not driverresolvedf:
5768 5782 ui.status(_('(no more unresolved files)\n'))
5769 5783 elif not unresolvedf:
5770 5784 ui.status(_('(no more unresolved files -- '
5771 5785 'run "hg resolve --all" to conclude)\n'))
5772 5786
5773 5787 return ret
5774 5788
5775 5789 @command('revert',
5776 5790 [('a', 'all', None, _('revert all changes when no arguments given')),
5777 5791 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5778 5792 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5779 5793 ('C', 'no-backup', None, _('do not save backup copies of files')),
5780 5794 ('i', 'interactive', None,
5781 5795 _('interactively select the changes (EXPERIMENTAL)')),
5782 5796 ] + walkopts + dryrunopts,
5783 5797 _('[OPTION]... [-r REV] [NAME]...'))
5784 5798 def revert(ui, repo, *pats, **opts):
5785 5799 """restore files to their checkout state
5786 5800
5787 5801 .. note::
5788 5802
5789 5803 To check out earlier revisions, you should use :hg:`update REV`.
5790 5804 To cancel an uncommitted merge (and lose your changes),
5791 5805 use :hg:`update --clean .`.
5792 5806
5793 5807 With no revision specified, revert the specified files or directories
5794 5808 to the contents they had in the parent of the working directory.
5795 5809 This restores the contents of files to an unmodified
5796 5810 state and unschedules adds, removes, copies, and renames. If the
5797 5811 working directory has two parents, you must explicitly specify a
5798 5812 revision.
5799 5813
5800 5814 Using the -r/--rev or -d/--date options, revert the given files or
5801 5815 directories to their states as of a specific revision. Because
5802 5816 revert does not change the working directory parents, this will
5803 5817 cause these files to appear modified. This can be helpful to "back
5804 5818 out" some or all of an earlier change. See :hg:`backout` for a
5805 5819 related method.
5806 5820
5807 5821 Modified files are saved with a .orig suffix before reverting.
5808 5822 To disable these backups, use --no-backup.
5809 5823
5810 5824 See :hg:`help dates` for a list of formats valid for -d/--date.
5811 5825
5812 5826 See :hg:`help backout` for a way to reverse the effect of an
5813 5827 earlier changeset.
5814 5828
5815 5829 Returns 0 on success.
5816 5830 """
5817 5831
5818 5832 if opts.get("date"):
5819 5833 if opts.get("rev"):
5820 5834 raise error.Abort(_("you can't specify a revision and a date"))
5821 5835 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5822 5836
5823 5837 parent, p2 = repo.dirstate.parents()
5824 5838 if not opts.get('rev') and p2 != nullid:
5825 5839 # revert after merge is a trap for new users (issue2915)
5826 5840 raise error.Abort(_('uncommitted merge with no revision specified'),
5827 5841 hint=_('use "hg update" or see "hg help revert"'))
5828 5842
5829 5843 ctx = scmutil.revsingle(repo, opts.get('rev'))
5830 5844
5831 5845 if (not (pats or opts.get('include') or opts.get('exclude') or
5832 5846 opts.get('all') or opts.get('interactive'))):
5833 5847 msg = _("no files or directories specified")
5834 5848 if p2 != nullid:
5835 5849 hint = _("uncommitted merge, use --all to discard all changes,"
5836 5850 " or 'hg update -C .' to abort the merge")
5837 5851 raise error.Abort(msg, hint=hint)
5838 5852 dirty = any(repo.status())
5839 5853 node = ctx.node()
5840 5854 if node != parent:
5841 5855 if dirty:
5842 5856 hint = _("uncommitted changes, use --all to discard all"
5843 5857 " changes, or 'hg update %s' to update") % ctx.rev()
5844 5858 else:
5845 5859 hint = _("use --all to revert all files,"
5846 5860 " or 'hg update %s' to update") % ctx.rev()
5847 5861 elif dirty:
5848 5862 hint = _("uncommitted changes, use --all to discard all changes")
5849 5863 else:
5850 5864 hint = _("use --all to revert all files")
5851 5865 raise error.Abort(msg, hint=hint)
5852 5866
5853 5867 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5854 5868
5855 5869 @command('rollback', dryrunopts +
5856 5870 [('f', 'force', False, _('ignore safety measures'))])
5857 5871 def rollback(ui, repo, **opts):
5858 5872 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5859 5873
5860 5874 Please use :hg:`commit --amend` instead of rollback to correct
5861 5875 mistakes in the last commit.
5862 5876
5863 5877 This command should be used with care. There is only one level of
5864 5878 rollback, and there is no way to undo a rollback. It will also
5865 5879 restore the dirstate at the time of the last transaction, losing
5866 5880 any dirstate changes since that time. This command does not alter
5867 5881 the working directory.
5868 5882
5869 5883 Transactions are used to encapsulate the effects of all commands
5870 5884 that create new changesets or propagate existing changesets into a
5871 5885 repository.
5872 5886
5873 5887 .. container:: verbose
5874 5888
5875 5889 For example, the following commands are transactional, and their
5876 5890 effects can be rolled back:
5877 5891
5878 5892 - commit
5879 5893 - import
5880 5894 - pull
5881 5895 - push (with this repository as the destination)
5882 5896 - unbundle
5883 5897
5884 5898 To avoid permanent data loss, rollback will refuse to rollback a
5885 5899 commit transaction if it isn't checked out. Use --force to
5886 5900 override this protection.
5887 5901
5888 5902 This command is not intended for use on public repositories. Once
5889 5903 changes are visible for pull by other users, rolling a transaction
5890 5904 back locally is ineffective (someone else may already have pulled
5891 5905 the changes). Furthermore, a race is possible with readers of the
5892 5906 repository; for example an in-progress pull from the repository
5893 5907 may fail if a rollback is performed.
5894 5908
5895 5909 Returns 0 on success, 1 if no rollback data is available.
5896 5910 """
5897 5911 return repo.rollback(dryrun=opts.get('dry_run'),
5898 5912 force=opts.get('force'))
5899 5913
5900 5914 @command('root', [])
5901 5915 def root(ui, repo):
5902 5916 """print the root (top) of the current working directory
5903 5917
5904 5918 Print the root directory of the current repository.
5905 5919
5906 5920 Returns 0 on success.
5907 5921 """
5908 5922 ui.write(repo.root + "\n")
5909 5923
5910 5924 @command('^serve',
5911 5925 [('A', 'accesslog', '', _('name of access log file to write to'),
5912 5926 _('FILE')),
5913 5927 ('d', 'daemon', None, _('run server in background')),
5914 5928 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5915 5929 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5916 5930 # use string type, then we can check if something was passed
5917 5931 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5918 5932 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5919 5933 _('ADDR')),
5920 5934 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5921 5935 _('PREFIX')),
5922 5936 ('n', 'name', '',
5923 5937 _('name to show in web pages (default: working directory)'), _('NAME')),
5924 5938 ('', 'web-conf', '',
5925 5939 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5926 5940 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5927 5941 _('FILE')),
5928 5942 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5929 5943 ('', 'stdio', None, _('for remote clients')),
5930 5944 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5931 5945 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5932 5946 ('', 'style', '', _('template style to use'), _('STYLE')),
5933 5947 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5934 5948 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5935 5949 _('[OPTION]...'),
5936 5950 optionalrepo=True)
5937 5951 def serve(ui, repo, **opts):
5938 5952 """start stand-alone webserver
5939 5953
5940 5954 Start a local HTTP repository browser and pull server. You can use
5941 5955 this for ad-hoc sharing and browsing of repositories. It is
5942 5956 recommended to use a real web server to serve a repository for
5943 5957 longer periods of time.
5944 5958
5945 5959 Please note that the server does not implement access control.
5946 5960 This means that, by default, anybody can read from the server and
5947 5961 nobody can write to it by default. Set the ``web.allow_push``
5948 5962 option to ``*`` to allow everybody to push to the server. You
5949 5963 should use a real web server if you need to authenticate users.
5950 5964
5951 5965 By default, the server logs accesses to stdout and errors to
5952 5966 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5953 5967 files.
5954 5968
5955 5969 To have the server choose a free port number to listen on, specify
5956 5970 a port number of 0; in this case, the server will print the port
5957 5971 number it uses.
5958 5972
5959 5973 Returns 0 on success.
5960 5974 """
5961 5975
5962 5976 if opts["stdio"] and opts["cmdserver"]:
5963 5977 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5964 5978
5965 5979 if opts["stdio"]:
5966 5980 if repo is None:
5967 5981 raise error.RepoError(_("there is no Mercurial repository here"
5968 5982 " (.hg not found)"))
5969 5983 s = sshserver.sshserver(ui, repo)
5970 5984 s.serve_forever()
5971 5985
5972 5986 if opts["cmdserver"]:
5973 5987 import commandserver
5974 5988 service = commandserver.createservice(ui, repo, opts)
5975 5989 else:
5976 5990 service = hgweb.createservice(ui, repo, opts)
5977 5991 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5978 5992
5979 5993 @command('^status|st',
5980 5994 [('A', 'all', None, _('show status of all files')),
5981 5995 ('m', 'modified', None, _('show only modified files')),
5982 5996 ('a', 'added', None, _('show only added files')),
5983 5997 ('r', 'removed', None, _('show only removed files')),
5984 5998 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5985 5999 ('c', 'clean', None, _('show only files without changes')),
5986 6000 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5987 6001 ('i', 'ignored', None, _('show only ignored files')),
5988 6002 ('n', 'no-status', None, _('hide status prefix')),
5989 6003 ('C', 'copies', None, _('show source of copied files')),
5990 6004 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5991 6005 ('', 'rev', [], _('show difference from revision'), _('REV')),
5992 6006 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5993 6007 ] + walkopts + subrepoopts + formatteropts,
5994 6008 _('[OPTION]... [FILE]...'),
5995 6009 inferrepo=True)
5996 6010 def status(ui, repo, *pats, **opts):
5997 6011 """show changed files in the working directory
5998 6012
5999 6013 Show status of files in the repository. If names are given, only
6000 6014 files that match are shown. Files that are clean or ignored or
6001 6015 the source of a copy/move operation, are not listed unless
6002 6016 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6003 6017 Unless options described with "show only ..." are given, the
6004 6018 options -mardu are used.
6005 6019
6006 6020 Option -q/--quiet hides untracked (unknown and ignored) files
6007 6021 unless explicitly requested with -u/--unknown or -i/--ignored.
6008 6022
6009 6023 .. note::
6010 6024
6011 6025 status may appear to disagree with diff if permissions have
6012 6026 changed or a merge has occurred. The standard diff format does
6013 6027 not report permission changes and diff only reports changes
6014 6028 relative to one merge parent.
6015 6029
6016 6030 If one revision is given, it is used as the base revision.
6017 6031 If two revisions are given, the differences between them are
6018 6032 shown. The --change option can also be used as a shortcut to list
6019 6033 the changed files of a revision from its first parent.
6020 6034
6021 6035 The codes used to show the status of files are::
6022 6036
6023 6037 M = modified
6024 6038 A = added
6025 6039 R = removed
6026 6040 C = clean
6027 6041 ! = missing (deleted by non-hg command, but still tracked)
6028 6042 ? = not tracked
6029 6043 I = ignored
6030 6044 = origin of the previous file (with --copies)
6031 6045
6032 6046 .. container:: verbose
6033 6047
6034 6048 Examples:
6035 6049
6036 6050 - show changes in the working directory relative to a
6037 6051 changeset::
6038 6052
6039 6053 hg status --rev 9353
6040 6054
6041 6055 - show changes in the working directory relative to the
6042 6056 current directory (see :hg:`help patterns` for more information)::
6043 6057
6044 6058 hg status re:
6045 6059
6046 6060 - show all changes including copies in an existing changeset::
6047 6061
6048 6062 hg status --copies --change 9353
6049 6063
6050 6064 - get a NUL separated list of added files, suitable for xargs::
6051 6065
6052 6066 hg status -an0
6053 6067
6054 6068 Returns 0 on success.
6055 6069 """
6056 6070
6057 6071 revs = opts.get('rev')
6058 6072 change = opts.get('change')
6059 6073
6060 6074 if revs and change:
6061 6075 msg = _('cannot specify --rev and --change at the same time')
6062 6076 raise error.Abort(msg)
6063 6077 elif change:
6064 6078 node2 = scmutil.revsingle(repo, change, None).node()
6065 6079 node1 = repo[node2].p1().node()
6066 6080 else:
6067 6081 node1, node2 = scmutil.revpair(repo, revs)
6068 6082
6069 6083 if pats:
6070 6084 cwd = repo.getcwd()
6071 6085 else:
6072 6086 cwd = ''
6073 6087
6074 6088 if opts.get('print0'):
6075 6089 end = '\0'
6076 6090 else:
6077 6091 end = '\n'
6078 6092 copy = {}
6079 6093 states = 'modified added removed deleted unknown ignored clean'.split()
6080 6094 show = [k for k in states if opts.get(k)]
6081 6095 if opts.get('all'):
6082 6096 show += ui.quiet and (states[:4] + ['clean']) or states
6083 6097 if not show:
6084 6098 if ui.quiet:
6085 6099 show = states[:4]
6086 6100 else:
6087 6101 show = states[:5]
6088 6102
6089 6103 m = scmutil.match(repo[node2], pats, opts)
6090 6104 stat = repo.status(node1, node2, m,
6091 6105 'ignored' in show, 'clean' in show, 'unknown' in show,
6092 6106 opts.get('subrepos'))
6093 6107 changestates = zip(states, 'MAR!?IC', stat)
6094 6108
6095 6109 if (opts.get('all') or opts.get('copies')
6096 6110 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
6097 6111 copy = copies.pathcopies(repo[node1], repo[node2], m)
6098 6112
6099 6113 fm = ui.formatter('status', opts)
6100 6114 fmt = '%s' + end
6101 6115 showchar = not opts.get('no_status')
6102 6116
6103 6117 for state, char, files in changestates:
6104 6118 if state in show:
6105 6119 label = 'status.' + state
6106 6120 for f in files:
6107 6121 fm.startitem()
6108 6122 fm.condwrite(showchar, 'status', '%s ', char, label=label)
6109 6123 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
6110 6124 if f in copy:
6111 6125 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
6112 6126 label='status.copied')
6113 6127 fm.end()
6114 6128
6115 6129 @command('^summary|sum',
6116 6130 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
6117 6131 def summary(ui, repo, **opts):
6118 6132 """summarize working directory state
6119 6133
6120 6134 This generates a brief summary of the working directory state,
6121 6135 including parents, branch, commit status, phase and available updates.
6122 6136
6123 6137 With the --remote option, this will check the default paths for
6124 6138 incoming and outgoing changes. This can be time-consuming.
6125 6139
6126 6140 Returns 0 on success.
6127 6141 """
6128 6142
6129 6143 ctx = repo[None]
6130 6144 parents = ctx.parents()
6131 6145 pnode = parents[0].node()
6132 6146 marks = []
6133 6147
6134 6148 for p in parents:
6135 6149 # label with log.changeset (instead of log.parent) since this
6136 6150 # shows a working directory parent *changeset*:
6137 6151 # i18n: column positioning for "hg summary"
6138 6152 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
6139 6153 label='log.changeset changeset.%s' % p.phasestr())
6140 6154 ui.write(' '.join(p.tags()), label='log.tag')
6141 6155 if p.bookmarks():
6142 6156 marks.extend(p.bookmarks())
6143 6157 if p.rev() == -1:
6144 6158 if not len(repo):
6145 6159 ui.write(_(' (empty repository)'))
6146 6160 else:
6147 6161 ui.write(_(' (no revision checked out)'))
6148 6162 ui.write('\n')
6149 6163 if p.description():
6150 6164 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
6151 6165 label='log.summary')
6152 6166
6153 6167 branch = ctx.branch()
6154 6168 bheads = repo.branchheads(branch)
6155 6169 # i18n: column positioning for "hg summary"
6156 6170 m = _('branch: %s\n') % branch
6157 6171 if branch != 'default':
6158 6172 ui.write(m, label='log.branch')
6159 6173 else:
6160 6174 ui.status(m, label='log.branch')
6161 6175
6162 6176 if marks:
6163 6177 active = repo._activebookmark
6164 6178 # i18n: column positioning for "hg summary"
6165 6179 ui.write(_('bookmarks:'), label='log.bookmark')
6166 6180 if active is not None:
6167 6181 if active in marks:
6168 6182 ui.write(' *' + active, label=activebookmarklabel)
6169 6183 marks.remove(active)
6170 6184 else:
6171 6185 ui.write(' [%s]' % active, label=activebookmarklabel)
6172 6186 for m in marks:
6173 6187 ui.write(' ' + m, label='log.bookmark')
6174 6188 ui.write('\n', label='log.bookmark')
6175 6189
6176 6190 status = repo.status(unknown=True)
6177 6191
6178 6192 c = repo.dirstate.copies()
6179 6193 copied, renamed = [], []
6180 6194 for d, s in c.iteritems():
6181 6195 if s in status.removed:
6182 6196 status.removed.remove(s)
6183 6197 renamed.append(d)
6184 6198 else:
6185 6199 copied.append(d)
6186 6200 if d in status.added:
6187 6201 status.added.remove(d)
6188 6202
6189 6203 try:
6190 6204 ms = mergemod.mergestate.read(repo)
6191 6205 except error.UnsupportedMergeRecords as e:
6192 6206 s = ' '.join(e.recordtypes)
6193 6207 ui.warn(
6194 6208 _('warning: merge state has unsupported record types: %s\n') % s)
6195 6209 unresolved = 0
6196 6210 else:
6197 6211 unresolved = [f for f in ms if ms[f] == 'u']
6198 6212
6199 6213 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6200 6214
6201 6215 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6202 6216 (ui.label(_('%d added'), 'status.added'), status.added),
6203 6217 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6204 6218 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6205 6219 (ui.label(_('%d copied'), 'status.copied'), copied),
6206 6220 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6207 6221 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6208 6222 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6209 6223 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6210 6224 t = []
6211 6225 for l, s in labels:
6212 6226 if s:
6213 6227 t.append(l % len(s))
6214 6228
6215 6229 t = ', '.join(t)
6216 6230 cleanworkdir = False
6217 6231
6218 6232 if repo.vfs.exists('updatestate'):
6219 6233 t += _(' (interrupted update)')
6220 6234 elif len(parents) > 1:
6221 6235 t += _(' (merge)')
6222 6236 elif branch != parents[0].branch():
6223 6237 t += _(' (new branch)')
6224 6238 elif (parents[0].closesbranch() and
6225 6239 pnode in repo.branchheads(branch, closed=True)):
6226 6240 t += _(' (head closed)')
6227 6241 elif not (status.modified or status.added or status.removed or renamed or
6228 6242 copied or subs):
6229 6243 t += _(' (clean)')
6230 6244 cleanworkdir = True
6231 6245 elif pnode not in bheads:
6232 6246 t += _(' (new branch head)')
6233 6247
6234 6248 if parents:
6235 6249 pendingphase = max(p.phase() for p in parents)
6236 6250 else:
6237 6251 pendingphase = phases.public
6238 6252
6239 6253 if pendingphase > phases.newcommitphase(ui):
6240 6254 t += ' (%s)' % phases.phasenames[pendingphase]
6241 6255
6242 6256 if cleanworkdir:
6243 6257 # i18n: column positioning for "hg summary"
6244 6258 ui.status(_('commit: %s\n') % t.strip())
6245 6259 else:
6246 6260 # i18n: column positioning for "hg summary"
6247 6261 ui.write(_('commit: %s\n') % t.strip())
6248 6262
6249 6263 # all ancestors of branch heads - all ancestors of parent = new csets
6250 6264 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6251 6265 bheads))
6252 6266
6253 6267 if new == 0:
6254 6268 # i18n: column positioning for "hg summary"
6255 6269 ui.status(_('update: (current)\n'))
6256 6270 elif pnode not in bheads:
6257 6271 # i18n: column positioning for "hg summary"
6258 6272 ui.write(_('update: %d new changesets (update)\n') % new)
6259 6273 else:
6260 6274 # i18n: column positioning for "hg summary"
6261 6275 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6262 6276 (new, len(bheads)))
6263 6277
6264 6278 t = []
6265 6279 draft = len(repo.revs('draft()'))
6266 6280 if draft:
6267 6281 t.append(_('%d draft') % draft)
6268 6282 secret = len(repo.revs('secret()'))
6269 6283 if secret:
6270 6284 t.append(_('%d secret') % secret)
6271 6285
6272 6286 if draft or secret:
6273 6287 ui.status(_('phases: %s\n') % ', '.join(t))
6274 6288
6275 6289 cmdutil.summaryhooks(ui, repo)
6276 6290
6277 6291 if opts.get('remote'):
6278 6292 needsincoming, needsoutgoing = True, True
6279 6293 else:
6280 6294 needsincoming, needsoutgoing = False, False
6281 6295 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6282 6296 if i:
6283 6297 needsincoming = True
6284 6298 if o:
6285 6299 needsoutgoing = True
6286 6300 if not needsincoming and not needsoutgoing:
6287 6301 return
6288 6302
6289 6303 def getincoming():
6290 6304 source, branches = hg.parseurl(ui.expandpath('default'))
6291 6305 sbranch = branches[0]
6292 6306 try:
6293 6307 other = hg.peer(repo, {}, source)
6294 6308 except error.RepoError:
6295 6309 if opts.get('remote'):
6296 6310 raise
6297 6311 return source, sbranch, None, None, None
6298 6312 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6299 6313 if revs:
6300 6314 revs = [other.lookup(rev) for rev in revs]
6301 6315 ui.debug('comparing with %s\n' % util.hidepassword(source))
6302 6316 repo.ui.pushbuffer()
6303 6317 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6304 6318 repo.ui.popbuffer()
6305 6319 return source, sbranch, other, commoninc, commoninc[1]
6306 6320
6307 6321 if needsincoming:
6308 6322 source, sbranch, sother, commoninc, incoming = getincoming()
6309 6323 else:
6310 6324 source = sbranch = sother = commoninc = incoming = None
6311 6325
6312 6326 def getoutgoing():
6313 6327 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6314 6328 dbranch = branches[0]
6315 6329 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6316 6330 if source != dest:
6317 6331 try:
6318 6332 dother = hg.peer(repo, {}, dest)
6319 6333 except error.RepoError:
6320 6334 if opts.get('remote'):
6321 6335 raise
6322 6336 return dest, dbranch, None, None
6323 6337 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6324 6338 elif sother is None:
6325 6339 # there is no explicit destination peer, but source one is invalid
6326 6340 return dest, dbranch, None, None
6327 6341 else:
6328 6342 dother = sother
6329 6343 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6330 6344 common = None
6331 6345 else:
6332 6346 common = commoninc
6333 6347 if revs:
6334 6348 revs = [repo.lookup(rev) for rev in revs]
6335 6349 repo.ui.pushbuffer()
6336 6350 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6337 6351 commoninc=common)
6338 6352 repo.ui.popbuffer()
6339 6353 return dest, dbranch, dother, outgoing
6340 6354
6341 6355 if needsoutgoing:
6342 6356 dest, dbranch, dother, outgoing = getoutgoing()
6343 6357 else:
6344 6358 dest = dbranch = dother = outgoing = None
6345 6359
6346 6360 if opts.get('remote'):
6347 6361 t = []
6348 6362 if incoming:
6349 6363 t.append(_('1 or more incoming'))
6350 6364 o = outgoing.missing
6351 6365 if o:
6352 6366 t.append(_('%d outgoing') % len(o))
6353 6367 other = dother or sother
6354 6368 if 'bookmarks' in other.listkeys('namespaces'):
6355 6369 counts = bookmarks.summary(repo, other)
6356 6370 if counts[0] > 0:
6357 6371 t.append(_('%d incoming bookmarks') % counts[0])
6358 6372 if counts[1] > 0:
6359 6373 t.append(_('%d outgoing bookmarks') % counts[1])
6360 6374
6361 6375 if t:
6362 6376 # i18n: column positioning for "hg summary"
6363 6377 ui.write(_('remote: %s\n') % (', '.join(t)))
6364 6378 else:
6365 6379 # i18n: column positioning for "hg summary"
6366 6380 ui.status(_('remote: (synced)\n'))
6367 6381
6368 6382 cmdutil.summaryremotehooks(ui, repo, opts,
6369 6383 ((source, sbranch, sother, commoninc),
6370 6384 (dest, dbranch, dother, outgoing)))
6371 6385
6372 6386 @command('tag',
6373 6387 [('f', 'force', None, _('force tag')),
6374 6388 ('l', 'local', None, _('make the tag local')),
6375 6389 ('r', 'rev', '', _('revision to tag'), _('REV')),
6376 6390 ('', 'remove', None, _('remove a tag')),
6377 6391 # -l/--local is already there, commitopts cannot be used
6378 6392 ('e', 'edit', None, _('invoke editor on commit messages')),
6379 6393 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6380 6394 ] + commitopts2,
6381 6395 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6382 6396 def tag(ui, repo, name1, *names, **opts):
6383 6397 """add one or more tags for the current or given revision
6384 6398
6385 6399 Name a particular revision using <name>.
6386 6400
6387 6401 Tags are used to name particular revisions of the repository and are
6388 6402 very useful to compare different revisions, to go back to significant
6389 6403 earlier versions or to mark branch points as releases, etc. Changing
6390 6404 an existing tag is normally disallowed; use -f/--force to override.
6391 6405
6392 6406 If no revision is given, the parent of the working directory is
6393 6407 used.
6394 6408
6395 6409 To facilitate version control, distribution, and merging of tags,
6396 6410 they are stored as a file named ".hgtags" which is managed similarly
6397 6411 to other project files and can be hand-edited if necessary. This
6398 6412 also means that tagging creates a new commit. The file
6399 6413 ".hg/localtags" is used for local tags (not shared among
6400 6414 repositories).
6401 6415
6402 6416 Tag commits are usually made at the head of a branch. If the parent
6403 6417 of the working directory is not a branch head, :hg:`tag` aborts; use
6404 6418 -f/--force to force the tag commit to be based on a non-head
6405 6419 changeset.
6406 6420
6407 6421 See :hg:`help dates` for a list of formats valid for -d/--date.
6408 6422
6409 6423 Since tag names have priority over branch names during revision
6410 6424 lookup, using an existing branch name as a tag name is discouraged.
6411 6425
6412 6426 Returns 0 on success.
6413 6427 """
6414 6428 wlock = lock = None
6415 6429 try:
6416 6430 wlock = repo.wlock()
6417 6431 lock = repo.lock()
6418 6432 rev_ = "."
6419 6433 names = [t.strip() for t in (name1,) + names]
6420 6434 if len(names) != len(set(names)):
6421 6435 raise error.Abort(_('tag names must be unique'))
6422 6436 for n in names:
6423 6437 scmutil.checknewlabel(repo, n, 'tag')
6424 6438 if not n:
6425 6439 raise error.Abort(_('tag names cannot consist entirely of '
6426 6440 'whitespace'))
6427 6441 if opts.get('rev') and opts.get('remove'):
6428 6442 raise error.Abort(_("--rev and --remove are incompatible"))
6429 6443 if opts.get('rev'):
6430 6444 rev_ = opts['rev']
6431 6445 message = opts.get('message')
6432 6446 if opts.get('remove'):
6433 6447 if opts.get('local'):
6434 6448 expectedtype = 'local'
6435 6449 else:
6436 6450 expectedtype = 'global'
6437 6451
6438 6452 for n in names:
6439 6453 if not repo.tagtype(n):
6440 6454 raise error.Abort(_("tag '%s' does not exist") % n)
6441 6455 if repo.tagtype(n) != expectedtype:
6442 6456 if expectedtype == 'global':
6443 6457 raise error.Abort(_("tag '%s' is not a global tag") % n)
6444 6458 else:
6445 6459 raise error.Abort(_("tag '%s' is not a local tag") % n)
6446 6460 rev_ = 'null'
6447 6461 if not message:
6448 6462 # we don't translate commit messages
6449 6463 message = 'Removed tag %s' % ', '.join(names)
6450 6464 elif not opts.get('force'):
6451 6465 for n in names:
6452 6466 if n in repo.tags():
6453 6467 raise error.Abort(_("tag '%s' already exists "
6454 6468 "(use -f to force)") % n)
6455 6469 if not opts.get('local'):
6456 6470 p1, p2 = repo.dirstate.parents()
6457 6471 if p2 != nullid:
6458 6472 raise error.Abort(_('uncommitted merge'))
6459 6473 bheads = repo.branchheads()
6460 6474 if not opts.get('force') and bheads and p1 not in bheads:
6461 6475 raise error.Abort(_('not at a branch head (use -f to force)'))
6462 6476 r = scmutil.revsingle(repo, rev_).node()
6463 6477
6464 6478 if not message:
6465 6479 # we don't translate commit messages
6466 6480 message = ('Added tag %s for changeset %s' %
6467 6481 (', '.join(names), short(r)))
6468 6482
6469 6483 date = opts.get('date')
6470 6484 if date:
6471 6485 date = util.parsedate(date)
6472 6486
6473 6487 if opts.get('remove'):
6474 6488 editform = 'tag.remove'
6475 6489 else:
6476 6490 editform = 'tag.add'
6477 6491 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6478 6492
6479 6493 # don't allow tagging the null rev
6480 6494 if (not opts.get('remove') and
6481 6495 scmutil.revsingle(repo, rev_).rev() == nullrev):
6482 6496 raise error.Abort(_("cannot tag null revision"))
6483 6497
6484 6498 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6485 6499 editor=editor)
6486 6500 finally:
6487 6501 release(lock, wlock)
6488 6502
6489 6503 @command('tags', formatteropts, '')
6490 6504 def tags(ui, repo, **opts):
6491 6505 """list repository tags
6492 6506
6493 6507 This lists both regular and local tags. When the -v/--verbose
6494 6508 switch is used, a third column "local" is printed for local tags.
6495 6509
6496 6510 Returns 0 on success.
6497 6511 """
6498 6512
6499 6513 fm = ui.formatter('tags', opts)
6500 6514 hexfunc = fm.hexfunc
6501 6515 tagtype = ""
6502 6516
6503 6517 for t, n in reversed(repo.tagslist()):
6504 6518 hn = hexfunc(n)
6505 6519 label = 'tags.normal'
6506 6520 tagtype = ''
6507 6521 if repo.tagtype(t) == 'local':
6508 6522 label = 'tags.local'
6509 6523 tagtype = 'local'
6510 6524
6511 6525 fm.startitem()
6512 6526 fm.write('tag', '%s', t, label=label)
6513 6527 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6514 6528 fm.condwrite(not ui.quiet, 'rev node', fmt,
6515 6529 repo.changelog.rev(n), hn, label=label)
6516 6530 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6517 6531 tagtype, label=label)
6518 6532 fm.plain('\n')
6519 6533 fm.end()
6520 6534
6521 6535 @command('tip',
6522 6536 [('p', 'patch', None, _('show patch')),
6523 6537 ('g', 'git', None, _('use git extended diff format')),
6524 6538 ] + templateopts,
6525 6539 _('[-p] [-g]'))
6526 6540 def tip(ui, repo, **opts):
6527 6541 """show the tip revision (DEPRECATED)
6528 6542
6529 6543 The tip revision (usually just called the tip) is the changeset
6530 6544 most recently added to the repository (and therefore the most
6531 6545 recently changed head).
6532 6546
6533 6547 If you have just made a commit, that commit will be the tip. If
6534 6548 you have just pulled changes from another repository, the tip of
6535 6549 that repository becomes the current tip. The "tip" tag is special
6536 6550 and cannot be renamed or assigned to a different changeset.
6537 6551
6538 6552 This command is deprecated, please use :hg:`heads` instead.
6539 6553
6540 6554 Returns 0 on success.
6541 6555 """
6542 6556 displayer = cmdutil.show_changeset(ui, repo, opts)
6543 6557 displayer.show(repo['tip'])
6544 6558 displayer.close()
6545 6559
6546 6560 @command('unbundle',
6547 6561 [('u', 'update', None,
6548 6562 _('update to new branch head if changesets were unbundled'))],
6549 6563 _('[-u] FILE...'))
6550 6564 def unbundle(ui, repo, fname1, *fnames, **opts):
6551 6565 """apply one or more changegroup files
6552 6566
6553 6567 Apply one or more compressed changegroup files generated by the
6554 6568 bundle command.
6555 6569
6556 6570 Returns 0 on success, 1 if an update has unresolved files.
6557 6571 """
6558 6572 fnames = (fname1,) + fnames
6559 6573
6560 6574 lock = repo.lock()
6561 6575 try:
6562 6576 for fname in fnames:
6563 6577 f = hg.openpath(ui, fname)
6564 6578 gen = exchange.readbundle(ui, f, fname)
6565 6579 if isinstance(gen, bundle2.unbundle20):
6566 6580 tr = repo.transaction('unbundle')
6567 6581 try:
6568 6582 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6569 6583 url='bundle:' + fname)
6570 6584 tr.close()
6571 6585 except error.BundleUnknownFeatureError as exc:
6572 6586 raise error.Abort(_('%s: unknown bundle feature, %s')
6573 6587 % (fname, exc),
6574 6588 hint=_("see https://mercurial-scm.org/"
6575 6589 "wiki/BundleFeature for more "
6576 6590 "information"))
6577 6591 finally:
6578 6592 if tr:
6579 6593 tr.release()
6580 6594 changes = [r.get('return', 0)
6581 6595 for r in op.records['changegroup']]
6582 6596 modheads = changegroup.combineresults(changes)
6583 6597 elif isinstance(gen, streamclone.streamcloneapplier):
6584 6598 raise error.Abort(
6585 6599 _('packed bundles cannot be applied with '
6586 6600 '"hg unbundle"'),
6587 6601 hint=_('use "hg debugapplystreamclonebundle"'))
6588 6602 else:
6589 6603 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
6590 6604 finally:
6591 6605 lock.release()
6592 6606
6593 6607 return postincoming(ui, repo, modheads, opts.get('update'), None)
6594 6608
6595 6609 @command('^update|up|checkout|co',
6596 6610 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6597 6611 ('c', 'check', None,
6598 6612 _('update across branches if no uncommitted changes')),
6599 6613 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6600 6614 ('r', 'rev', '', _('revision'), _('REV'))
6601 6615 ] + mergetoolopts,
6602 6616 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6603 6617 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6604 6618 tool=None):
6605 6619 """update working directory (or switch revisions)
6606 6620
6607 6621 Update the repository's working directory to the specified
6608 6622 changeset. If no changeset is specified, update to the tip of the
6609 6623 current named branch and move the active bookmark (see :hg:`help
6610 6624 bookmarks`).
6611 6625
6612 6626 Update sets the working directory's parent revision to the specified
6613 6627 changeset (see :hg:`help parents`).
6614 6628
6615 6629 If the changeset is not a descendant or ancestor of the working
6616 6630 directory's parent, the update is aborted. With the -c/--check
6617 6631 option, the working directory is checked for uncommitted changes; if
6618 6632 none are found, the working directory is updated to the specified
6619 6633 changeset.
6620 6634
6621 6635 .. container:: verbose
6622 6636
6623 6637 The following rules apply when the working directory contains
6624 6638 uncommitted changes:
6625 6639
6626 6640 1. If neither -c/--check nor -C/--clean is specified, and if
6627 6641 the requested changeset is an ancestor or descendant of
6628 6642 the working directory's parent, the uncommitted changes
6629 6643 are merged into the requested changeset and the merged
6630 6644 result is left uncommitted. If the requested changeset is
6631 6645 not an ancestor or descendant (that is, it is on another
6632 6646 branch), the update is aborted and the uncommitted changes
6633 6647 are preserved.
6634 6648
6635 6649 2. With the -c/--check option, the update is aborted and the
6636 6650 uncommitted changes are preserved.
6637 6651
6638 6652 3. With the -C/--clean option, uncommitted changes are discarded and
6639 6653 the working directory is updated to the requested changeset.
6640 6654
6641 6655 To cancel an uncommitted merge (and lose your changes), use
6642 6656 :hg:`update --clean .`.
6643 6657
6644 6658 Use null as the changeset to remove the working directory (like
6645 6659 :hg:`clone -U`).
6646 6660
6647 6661 If you want to revert just one file to an older revision, use
6648 6662 :hg:`revert [-r REV] NAME`.
6649 6663
6650 6664 See :hg:`help dates` for a list of formats valid for -d/--date.
6651 6665
6652 6666 Returns 0 on success, 1 if there are unresolved files.
6653 6667 """
6654 6668 movemarkfrom = None
6655 6669 if rev and node:
6656 6670 raise error.Abort(_("please specify just one revision"))
6657 6671
6658 6672 if rev is None or rev == '':
6659 6673 rev = node
6660 6674
6661 6675 wlock = repo.wlock()
6662 6676 try:
6663 6677 cmdutil.clearunfinished(repo)
6664 6678
6665 6679 if date:
6666 6680 if rev is not None:
6667 6681 raise error.Abort(_("you can't specify a revision and a date"))
6668 6682 rev = cmdutil.finddate(ui, repo, date)
6669 6683
6670 6684 # if we defined a bookmark, we have to remember the original name
6671 6685 brev = rev
6672 6686 rev = scmutil.revsingle(repo, rev, rev).rev()
6673 6687
6674 6688 if check and clean:
6675 6689 raise error.Abort(_("cannot specify both -c/--check and -C/--clean")
6676 6690 )
6677 6691
6678 6692 if check:
6679 6693 cmdutil.bailifchanged(repo, merge=False)
6680 6694 if rev is None:
6681 6695 updata = destutil.destupdate(repo, clean=clean, check=check)
6682 6696 rev, movemarkfrom, brev = updata
6683 6697
6684 6698 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6685 6699
6686 6700 if clean:
6687 6701 ret = hg.clean(repo, rev)
6688 6702 else:
6689 6703 ret = hg.update(repo, rev)
6690 6704
6691 6705 if not ret and movemarkfrom:
6692 6706 if movemarkfrom == repo['.'].node():
6693 6707 pass # no-op update
6694 6708 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6695 6709 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6696 6710 else:
6697 6711 # this can happen with a non-linear update
6698 6712 ui.status(_("(leaving bookmark %s)\n") %
6699 6713 repo._activebookmark)
6700 6714 bookmarks.deactivate(repo)
6701 6715 elif brev in repo._bookmarks:
6702 6716 bookmarks.activate(repo, brev)
6703 6717 ui.status(_("(activating bookmark %s)\n") % brev)
6704 6718 elif brev:
6705 6719 if repo._activebookmark:
6706 6720 ui.status(_("(leaving bookmark %s)\n") %
6707 6721 repo._activebookmark)
6708 6722 bookmarks.deactivate(repo)
6709 6723 finally:
6710 6724 wlock.release()
6711 6725
6712 6726 return ret
6713 6727
6714 6728 @command('verify', [])
6715 6729 def verify(ui, repo):
6716 6730 """verify the integrity of the repository
6717 6731
6718 6732 Verify the integrity of the current repository.
6719 6733
6720 6734 This will perform an extensive check of the repository's
6721 6735 integrity, validating the hashes and checksums of each entry in
6722 6736 the changelog, manifest, and tracked files, as well as the
6723 6737 integrity of their crosslinks and indices.
6724 6738
6725 6739 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6726 6740 for more information about recovery from corruption of the
6727 6741 repository.
6728 6742
6729 6743 Returns 0 on success, 1 if errors are encountered.
6730 6744 """
6731 6745 return hg.verify(repo)
6732 6746
6733 6747 @command('version', [], norepo=True)
6734 6748 def version_(ui):
6735 6749 """output version and copyright information"""
6736 6750 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6737 6751 % util.version())
6738 6752 ui.status(_(
6739 6753 "(see https://mercurial-scm.org for more information)\n"
6740 6754 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6741 6755 "This is free software; see the source for copying conditions. "
6742 6756 "There is NO\nwarranty; "
6743 6757 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6744 6758 ))
6745 6759
6746 6760 ui.note(_("\nEnabled extensions:\n\n"))
6747 6761 if ui.verbose:
6748 6762 # format names and versions into columns
6749 6763 names = []
6750 6764 vers = []
6751 6765 for name, module in extensions.extensions():
6752 6766 names.append(name)
6753 6767 vers.append(extensions.moduleversion(module))
6754 6768 if names:
6755 6769 maxnamelen = max(len(n) for n in names)
6756 6770 for i, name in enumerate(names):
6757 6771 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
@@ -1,2386 +1,2413 b''
1 1 Short help:
2 2
3 3 $ hg
4 4 Mercurial Distributed SCM
5 5
6 6 basic commands:
7 7
8 8 add add the specified files on the next commit
9 9 annotate show changeset information by line for each file
10 10 clone make a copy of an existing repository
11 11 commit commit the specified files or all outstanding changes
12 12 diff diff repository (or selected files)
13 13 export dump the header and diffs for one or more changesets
14 14 forget forget the specified files on the next commit
15 15 init create a new repository in the given directory
16 16 log show revision history of entire repository or files
17 17 merge merge another revision into working directory
18 18 pull pull changes from the specified source
19 19 push push changes to the specified destination
20 20 remove remove the specified files on the next commit
21 21 serve start stand-alone webserver
22 22 status show changed files in the working directory
23 23 summary summarize working directory state
24 24 update update working directory (or switch revisions)
25 25
26 26 (use "hg help" for the full list of commands or "hg -v" for details)
27 27
28 28 $ hg -q
29 29 add add the specified files on the next commit
30 30 annotate show changeset information by line for each file
31 31 clone make a copy of an existing repository
32 32 commit commit the specified files or all outstanding changes
33 33 diff diff repository (or selected files)
34 34 export dump the header and diffs for one or more changesets
35 35 forget forget the specified files on the next commit
36 36 init create a new repository in the given directory
37 37 log show revision history of entire repository or files
38 38 merge merge another revision into working directory
39 39 pull pull changes from the specified source
40 40 push push changes to the specified destination
41 41 remove remove the specified files on the next commit
42 42 serve start stand-alone webserver
43 43 status show changed files in the working directory
44 44 summary summarize working directory state
45 45 update update working directory (or switch revisions)
46 46
47 47 $ hg help
48 48 Mercurial Distributed SCM
49 49
50 50 list of commands:
51 51
52 52 add add the specified files on the next commit
53 53 addremove add all new files, delete all missing files
54 54 annotate show changeset information by line for each file
55 55 archive create an unversioned archive of a repository revision
56 56 backout reverse effect of earlier changeset
57 57 bisect subdivision search of changesets
58 58 bookmarks create a new bookmark or list existing bookmarks
59 59 branch set or show the current branch name
60 60 branches list repository named branches
61 61 bundle create a changegroup file
62 62 cat output the current or given revision of files
63 63 clone make a copy of an existing repository
64 64 commit commit the specified files or all outstanding changes
65 65 config show combined config settings from all hgrc files
66 66 copy mark files as copied for the next commit
67 67 diff diff repository (or selected files)
68 68 export dump the header and diffs for one or more changesets
69 69 files list tracked files
70 70 forget forget the specified files on the next commit
71 71 graft copy changes from other branches onto the current branch
72 72 grep search for a pattern in specified files and revisions
73 73 heads show branch heads
74 74 help show help for a given topic or a help overview
75 75 identify identify the working directory or specified revision
76 76 import import an ordered set of patches
77 77 incoming show new changesets found in source
78 78 init create a new repository in the given directory
79 79 log show revision history of entire repository or files
80 80 manifest output the current or given revision of the project manifest
81 81 merge merge another revision into working directory
82 82 outgoing show changesets not found in the destination
83 83 paths show aliases for remote repositories
84 84 phase set or show the current phase name
85 85 pull pull changes from the specified source
86 86 push push changes to the specified destination
87 87 recover roll back an interrupted transaction
88 88 remove remove the specified files on the next commit
89 89 rename rename files; equivalent of copy + remove
90 90 resolve redo merges or set/view the merge status of files
91 91 revert restore files to their checkout state
92 92 root print the root (top) of the current working directory
93 93 serve start stand-alone webserver
94 94 status show changed files in the working directory
95 95 summary summarize working directory state
96 96 tag add one or more tags for the current or given revision
97 97 tags list repository tags
98 98 unbundle apply one or more changegroup files
99 99 update update working directory (or switch revisions)
100 100 verify verify the integrity of the repository
101 101 version output version and copyright information
102 102
103 103 additional help topics:
104 104
105 105 config Configuration Files
106 106 dates Date Formats
107 107 diffs Diff Formats
108 108 environment Environment Variables
109 109 extensions Using Additional Features
110 110 filesets Specifying File Sets
111 111 glossary Glossary
112 112 hgignore Syntax for Mercurial Ignore Files
113 113 hgweb Configuring hgweb
114 114 merge-tools Merge Tools
115 115 multirevs Specifying Multiple Revisions
116 116 patterns File Name Patterns
117 117 phases Working with Phases
118 118 revisions Specifying Single Revisions
119 119 revsets Specifying Revision Sets
120 120 scripting Using Mercurial from scripts and automation
121 121 subrepos Subrepositories
122 122 templating Template Usage
123 123 urls URL Paths
124 124
125 125 (use "hg help -v" to show built-in aliases and global options)
126 126
127 127 $ hg -q help
128 128 add add the specified files on the next commit
129 129 addremove add all new files, delete all missing files
130 130 annotate show changeset information by line for each file
131 131 archive create an unversioned archive of a repository revision
132 132 backout reverse effect of earlier changeset
133 133 bisect subdivision search of changesets
134 134 bookmarks create a new bookmark or list existing bookmarks
135 135 branch set or show the current branch name
136 136 branches list repository named branches
137 137 bundle create a changegroup file
138 138 cat output the current or given revision of files
139 139 clone make a copy of an existing repository
140 140 commit commit the specified files or all outstanding changes
141 141 config show combined config settings from all hgrc files
142 142 copy mark files as copied for the next commit
143 143 diff diff repository (or selected files)
144 144 export dump the header and diffs for one or more changesets
145 145 files list tracked files
146 146 forget forget the specified files on the next commit
147 147 graft copy changes from other branches onto the current branch
148 148 grep search for a pattern in specified files and revisions
149 149 heads show branch heads
150 150 help show help for a given topic or a help overview
151 151 identify identify the working directory or specified revision
152 152 import import an ordered set of patches
153 153 incoming show new changesets found in source
154 154 init create a new repository in the given directory
155 155 log show revision history of entire repository or files
156 156 manifest output the current or given revision of the project manifest
157 157 merge merge another revision into working directory
158 158 outgoing show changesets not found in the destination
159 159 paths show aliases for remote repositories
160 160 phase set or show the current phase name
161 161 pull pull changes from the specified source
162 162 push push changes to the specified destination
163 163 recover roll back an interrupted transaction
164 164 remove remove the specified files on the next commit
165 165 rename rename files; equivalent of copy + remove
166 166 resolve redo merges or set/view the merge status of files
167 167 revert restore files to their checkout state
168 168 root print the root (top) of the current working directory
169 169 serve start stand-alone webserver
170 170 status show changed files in the working directory
171 171 summary summarize working directory state
172 172 tag add one or more tags for the current or given revision
173 173 tags list repository tags
174 174 unbundle apply one or more changegroup files
175 175 update update working directory (or switch revisions)
176 176 verify verify the integrity of the repository
177 177 version output version and copyright information
178 178
179 179 additional help topics:
180 180
181 181 config Configuration Files
182 182 dates Date Formats
183 183 diffs Diff Formats
184 184 environment Environment Variables
185 185 extensions Using Additional Features
186 186 filesets Specifying File Sets
187 187 glossary Glossary
188 188 hgignore Syntax for Mercurial Ignore Files
189 189 hgweb Configuring hgweb
190 190 merge-tools Merge Tools
191 191 multirevs Specifying Multiple Revisions
192 192 patterns File Name Patterns
193 193 phases Working with Phases
194 194 revisions Specifying Single Revisions
195 195 revsets Specifying Revision Sets
196 196 scripting Using Mercurial from scripts and automation
197 197 subrepos Subrepositories
198 198 templating Template Usage
199 199 urls URL Paths
200 200
201 201 Test extension help:
202 202 $ hg help extensions --config extensions.rebase= --config extensions.children=
203 203 Using Additional Features
204 204 """""""""""""""""""""""""
205 205
206 206 Mercurial has the ability to add new features through the use of
207 207 extensions. Extensions may add new commands, add options to existing
208 208 commands, change the default behavior of commands, or implement hooks.
209 209
210 210 To enable the "foo" extension, either shipped with Mercurial or in the
211 211 Python search path, create an entry for it in your configuration file,
212 212 like this:
213 213
214 214 [extensions]
215 215 foo =
216 216
217 217 You may also specify the full path to an extension:
218 218
219 219 [extensions]
220 220 myfeature = ~/.hgext/myfeature.py
221 221
222 222 See "hg help config" for more information on configuration files.
223 223
224 224 Extensions are not loaded by default for a variety of reasons: they can
225 225 increase startup overhead; they may be meant for advanced usage only; they
226 226 may provide potentially dangerous abilities (such as letting you destroy
227 227 or modify history); they might not be ready for prime time; or they may
228 228 alter some usual behaviors of stock Mercurial. It is thus up to the user
229 229 to activate extensions as needed.
230 230
231 231 To explicitly disable an extension enabled in a configuration file of
232 232 broader scope, prepend its path with !:
233 233
234 234 [extensions]
235 235 # disabling extension bar residing in /path/to/extension/bar.py
236 236 bar = !/path/to/extension/bar.py
237 237 # ditto, but no path was supplied for extension baz
238 238 baz = !
239 239
240 240 enabled extensions:
241 241
242 242 children command to display child changesets (DEPRECATED)
243 243 rebase command to move sets of revisions to a different ancestor
244 244
245 245 disabled extensions:
246 246
247 247 acl hooks for controlling repository access
248 248 blackbox log repository events to a blackbox for debugging
249 249 bugzilla hooks for integrating with the Bugzilla bug tracker
250 250 censor erase file content at a given revision
251 251 churn command to display statistics about repository history
252 252 clonebundles advertise pre-generated bundles to seed clones
253 253 (experimental)
254 254 color colorize output from some commands
255 255 convert import revisions from foreign VCS repositories into
256 256 Mercurial
257 257 eol automatically manage newlines in repository files
258 258 extdiff command to allow external programs to compare revisions
259 259 factotum http authentication with factotum
260 260 gpg commands to sign and verify changesets
261 261 hgcia hooks for integrating with the CIA.vc notification service
262 262 hgk browse the repository in a graphical way
263 263 highlight syntax highlighting for hgweb (requires Pygments)
264 264 histedit interactive history editing
265 265 keyword expand keywords in tracked files
266 266 largefiles track large binary files
267 267 mq manage a stack of patches
268 268 notify hooks for sending email push notifications
269 269 pager browse command output with an external pager
270 270 patchbomb command to send changesets as (a series of) patch emails
271 271 purge command to delete untracked files from the working
272 272 directory
273 273 record commands to interactively select changes for
274 274 commit/qrefresh
275 275 relink recreates hardlinks between repository clones
276 276 schemes extend schemes with shortcuts to repository swarms
277 277 share share a common history between several working directories
278 278 shelve save and restore changes to the working directory
279 279 strip strip changesets and their descendants from history
280 280 transplant command to transplant changesets from another branch
281 281 win32mbcs allow the use of MBCS paths with problematic encodings
282 282 zeroconf discover and advertise repositories on the local network
283 283
284 284 Verify that extension keywords appear in help templates
285 285
286 286 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
287 287
288 288 Test short command list with verbose option
289 289
290 290 $ hg -v help shortlist
291 291 Mercurial Distributed SCM
292 292
293 293 basic commands:
294 294
295 295 add add the specified files on the next commit
296 296 annotate, blame
297 297 show changeset information by line for each file
298 298 clone make a copy of an existing repository
299 299 commit, ci commit the specified files or all outstanding changes
300 300 diff diff repository (or selected files)
301 301 export dump the header and diffs for one or more changesets
302 302 forget forget the specified files on the next commit
303 303 init create a new repository in the given directory
304 304 log, history show revision history of entire repository or files
305 305 merge merge another revision into working directory
306 306 pull pull changes from the specified source
307 307 push push changes to the specified destination
308 308 remove, rm remove the specified files on the next commit
309 309 serve start stand-alone webserver
310 310 status, st show changed files in the working directory
311 311 summary, sum summarize working directory state
312 312 update, up, checkout, co
313 313 update working directory (or switch revisions)
314 314
315 315 global options ([+] can be repeated):
316 316
317 317 -R --repository REPO repository root directory or name of overlay bundle
318 318 file
319 319 --cwd DIR change working directory
320 320 -y --noninteractive do not prompt, automatically pick the first choice for
321 321 all prompts
322 322 -q --quiet suppress output
323 323 -v --verbose enable additional output
324 324 --config CONFIG [+] set/override config option (use 'section.name=value')
325 325 --debug enable debugging output
326 326 --debugger start debugger
327 327 --encoding ENCODE set the charset encoding (default: ascii)
328 328 --encodingmode MODE set the charset encoding mode (default: strict)
329 329 --traceback always print a traceback on exception
330 330 --time time how long the command takes
331 331 --profile print command execution profile
332 332 --version output version information and exit
333 333 -h --help display help and exit
334 334 --hidden consider hidden changesets
335 335
336 336 (use "hg help" for the full list of commands)
337 337
338 338 $ hg add -h
339 339 hg add [OPTION]... [FILE]...
340 340
341 341 add the specified files on the next commit
342 342
343 343 Schedule files to be version controlled and added to the repository.
344 344
345 345 The files will be added to the repository at the next commit. To undo an
346 346 add before that, see "hg forget".
347 347
348 348 If no names are given, add all files to the repository.
349 349
350 350 Returns 0 if all files are successfully added.
351 351
352 352 options ([+] can be repeated):
353 353
354 354 -I --include PATTERN [+] include names matching the given patterns
355 355 -X --exclude PATTERN [+] exclude names matching the given patterns
356 356 -S --subrepos recurse into subrepositories
357 357 -n --dry-run do not perform actions, just print output
358 358
359 359 (some details hidden, use --verbose to show complete help)
360 360
361 361 Verbose help for add
362 362
363 363 $ hg add -hv
364 364 hg add [OPTION]... [FILE]...
365 365
366 366 add the specified files on the next commit
367 367
368 368 Schedule files to be version controlled and added to the repository.
369 369
370 370 The files will be added to the repository at the next commit. To undo an
371 371 add before that, see "hg forget".
372 372
373 373 If no names are given, add all files to the repository.
374 374
375 An example showing how new (unknown) files are added automatically by "hg
376 add":
375 Examples:
376
377 - New (unknown) files are added automatically by "hg add":
377 378
378 $ ls
379 foo.c
380 $ hg status
381 ? foo.c
382 $ hg add
383 adding foo.c
384 $ hg status
385 A foo.c
379 $ ls
380 foo.c
381 $ hg status
382 ? foo.c
383 $ hg add
384 adding foo.c
385 $ hg status
386 A foo.c
387
388 - Specific files to be added can be specified:
389
390 $ ls
391 bar.c foo.c
392 $ hg status
393 ? bar.c
394 ? foo.c
395 $ hg add bar.c
396 $ hg status
397 A bar.c
398 ? foo.c
386 399
387 400 Returns 0 if all files are successfully added.
388 401
389 402 options ([+] can be repeated):
390 403
391 404 -I --include PATTERN [+] include names matching the given patterns
392 405 -X --exclude PATTERN [+] exclude names matching the given patterns
393 406 -S --subrepos recurse into subrepositories
394 407 -n --dry-run do not perform actions, just print output
395 408
396 409 global options ([+] can be repeated):
397 410
398 411 -R --repository REPO repository root directory or name of overlay bundle
399 412 file
400 413 --cwd DIR change working directory
401 414 -y --noninteractive do not prompt, automatically pick the first choice for
402 415 all prompts
403 416 -q --quiet suppress output
404 417 -v --verbose enable additional output
405 418 --config CONFIG [+] set/override config option (use 'section.name=value')
406 419 --debug enable debugging output
407 420 --debugger start debugger
408 421 --encoding ENCODE set the charset encoding (default: ascii)
409 422 --encodingmode MODE set the charset encoding mode (default: strict)
410 423 --traceback always print a traceback on exception
411 424 --time time how long the command takes
412 425 --profile print command execution profile
413 426 --version output version information and exit
414 427 -h --help display help and exit
415 428 --hidden consider hidden changesets
416 429
417 430 Test help option with version option
418 431
419 432 $ hg add -h --version
420 433 Mercurial Distributed SCM (version *) (glob)
421 434 (see https://mercurial-scm.org for more information)
422 435
423 436 Copyright (C) 2005-2015 Matt Mackall and others
424 437 This is free software; see the source for copying conditions. There is NO
425 438 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
426 439
427 440 $ hg add --skjdfks
428 441 hg add: option --skjdfks not recognized
429 442 hg add [OPTION]... [FILE]...
430 443
431 444 add the specified files on the next commit
432 445
433 446 options ([+] can be repeated):
434 447
435 448 -I --include PATTERN [+] include names matching the given patterns
436 449 -X --exclude PATTERN [+] exclude names matching the given patterns
437 450 -S --subrepos recurse into subrepositories
438 451 -n --dry-run do not perform actions, just print output
439 452
440 453 (use "hg add -h" to show more help)
441 454 [255]
442 455
443 456 Test ambiguous command help
444 457
445 458 $ hg help ad
446 459 list of commands:
447 460
448 461 add add the specified files on the next commit
449 462 addremove add all new files, delete all missing files
450 463
451 464 (use "hg help -v ad" to show built-in aliases and global options)
452 465
453 466 Test command without options
454 467
455 468 $ hg help verify
456 469 hg verify
457 470
458 471 verify the integrity of the repository
459 472
460 473 Verify the integrity of the current repository.
461 474
462 475 This will perform an extensive check of the repository's integrity,
463 476 validating the hashes and checksums of each entry in the changelog,
464 477 manifest, and tracked files, as well as the integrity of their crosslinks
465 478 and indices.
466 479
467 480 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
468 481 information about recovery from corruption of the repository.
469 482
470 483 Returns 0 on success, 1 if errors are encountered.
471 484
472 485 (some details hidden, use --verbose to show complete help)
473 486
474 487 $ hg help diff
475 488 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
476 489
477 490 diff repository (or selected files)
478 491
479 492 Show differences between revisions for the specified files.
480 493
481 494 Differences between files are shown using the unified diff format.
482 495
483 496 Note:
484 497 diff may generate unexpected results for merges, as it will default to
485 498 comparing against the working directory's first parent changeset if no
486 499 revisions are specified.
487 500
488 501 When two revision arguments are given, then changes are shown between
489 502 those revisions. If only one revision is specified then that revision is
490 503 compared to the working directory, and, when no revisions are specified,
491 504 the working directory files are compared to its parent.
492 505
493 506 Alternatively you can specify -c/--change with a revision to see the
494 507 changes in that changeset relative to its first parent.
495 508
496 509 Without the -a/--text option, diff will avoid generating diffs of files it
497 510 detects as binary. With -a, diff will generate a diff anyway, probably
498 511 with undesirable results.
499 512
500 513 Use the -g/--git option to generate diffs in the git extended diff format.
501 514 For more information, read "hg help diffs".
502 515
503 516 Returns 0 on success.
504 517
505 518 options ([+] can be repeated):
506 519
507 520 -r --rev REV [+] revision
508 521 -c --change REV change made by revision
509 522 -a --text treat all files as text
510 523 -g --git use git extended diff format
511 524 --nodates omit dates from diff headers
512 525 --noprefix omit a/ and b/ prefixes from filenames
513 526 -p --show-function show which function each change is in
514 527 --reverse produce a diff that undoes the changes
515 528 -w --ignore-all-space ignore white space when comparing lines
516 529 -b --ignore-space-change ignore changes in the amount of white space
517 530 -B --ignore-blank-lines ignore changes whose lines are all blank
518 531 -U --unified NUM number of lines of context to show
519 532 --stat output diffstat-style summary of changes
520 533 --root DIR produce diffs relative to subdirectory
521 534 -I --include PATTERN [+] include names matching the given patterns
522 535 -X --exclude PATTERN [+] exclude names matching the given patterns
523 536 -S --subrepos recurse into subrepositories
524 537
525 538 (some details hidden, use --verbose to show complete help)
526 539
527 540 $ hg help status
528 541 hg status [OPTION]... [FILE]...
529 542
530 543 aliases: st
531 544
532 545 show changed files in the working directory
533 546
534 547 Show status of files in the repository. If names are given, only files
535 548 that match are shown. Files that are clean or ignored or the source of a
536 549 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
537 550 -C/--copies or -A/--all are given. Unless options described with "show
538 551 only ..." are given, the options -mardu are used.
539 552
540 553 Option -q/--quiet hides untracked (unknown and ignored) files unless
541 554 explicitly requested with -u/--unknown or -i/--ignored.
542 555
543 556 Note:
544 557 status may appear to disagree with diff if permissions have changed or
545 558 a merge has occurred. The standard diff format does not report
546 559 permission changes and diff only reports changes relative to one merge
547 560 parent.
548 561
549 562 If one revision is given, it is used as the base revision. If two
550 563 revisions are given, the differences between them are shown. The --change
551 564 option can also be used as a shortcut to list the changed files of a
552 565 revision from its first parent.
553 566
554 567 The codes used to show the status of files are:
555 568
556 569 M = modified
557 570 A = added
558 571 R = removed
559 572 C = clean
560 573 ! = missing (deleted by non-hg command, but still tracked)
561 574 ? = not tracked
562 575 I = ignored
563 576 = origin of the previous file (with --copies)
564 577
565 578 Returns 0 on success.
566 579
567 580 options ([+] can be repeated):
568 581
569 582 -A --all show status of all files
570 583 -m --modified show only modified files
571 584 -a --added show only added files
572 585 -r --removed show only removed files
573 586 -d --deleted show only deleted (but tracked) files
574 587 -c --clean show only files without changes
575 588 -u --unknown show only unknown (not tracked) files
576 589 -i --ignored show only ignored files
577 590 -n --no-status hide status prefix
578 591 -C --copies show source of copied files
579 592 -0 --print0 end filenames with NUL, for use with xargs
580 593 --rev REV [+] show difference from revision
581 594 --change REV list the changed files of a revision
582 595 -I --include PATTERN [+] include names matching the given patterns
583 596 -X --exclude PATTERN [+] exclude names matching the given patterns
584 597 -S --subrepos recurse into subrepositories
585 598
586 599 (some details hidden, use --verbose to show complete help)
587 600
588 601 $ hg -q help status
589 602 hg status [OPTION]... [FILE]...
590 603
591 604 show changed files in the working directory
592 605
593 606 $ hg help foo
594 607 abort: no such help topic: foo
595 608 (try "hg help --keyword foo")
596 609 [255]
597 610
598 611 $ hg skjdfks
599 612 hg: unknown command 'skjdfks'
600 613 Mercurial Distributed SCM
601 614
602 615 basic commands:
603 616
604 617 add add the specified files on the next commit
605 618 annotate show changeset information by line for each file
606 619 clone make a copy of an existing repository
607 620 commit commit the specified files or all outstanding changes
608 621 diff diff repository (or selected files)
609 622 export dump the header and diffs for one or more changesets
610 623 forget forget the specified files on the next commit
611 624 init create a new repository in the given directory
612 625 log show revision history of entire repository or files
613 626 merge merge another revision into working directory
614 627 pull pull changes from the specified source
615 628 push push changes to the specified destination
616 629 remove remove the specified files on the next commit
617 630 serve start stand-alone webserver
618 631 status show changed files in the working directory
619 632 summary summarize working directory state
620 633 update update working directory (or switch revisions)
621 634
622 635 (use "hg help" for the full list of commands or "hg -v" for details)
623 636 [255]
624 637
625 638
626 639 Make sure that we don't run afoul of the help system thinking that
627 640 this is a section and erroring out weirdly.
628 641
629 642 $ hg .log
630 643 hg: unknown command '.log'
631 644 (did you mean one of log?)
632 645 [255]
633 646
634 647 $ hg log.
635 648 hg: unknown command 'log.'
636 649 (did you mean one of log?)
637 650 [255]
638 651 $ hg pu.lh
639 652 hg: unknown command 'pu.lh'
640 653 (did you mean one of pull, push?)
641 654 [255]
642 655
643 656 $ cat > helpext.py <<EOF
644 657 > import os
645 658 > from mercurial import cmdutil, commands
646 659 >
647 660 > cmdtable = {}
648 661 > command = cmdutil.command(cmdtable)
649 662 >
650 663 > @command('nohelp',
651 664 > [('', 'longdesc', 3, 'x'*90),
652 665 > ('n', '', None, 'normal desc'),
653 666 > ('', 'newline', '', 'line1\nline2')],
654 667 > 'hg nohelp',
655 668 > norepo=True)
656 669 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
657 670 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
658 671 > def nohelp(ui, *args, **kwargs):
659 672 > pass
660 673 >
661 674 > EOF
662 675 $ echo '[extensions]' >> $HGRCPATH
663 676 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
664 677
665 678 Test command with no help text
666 679
667 680 $ hg help nohelp
668 681 hg nohelp
669 682
670 683 (no help text available)
671 684
672 685 options:
673 686
674 687 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
675 688 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
676 689 -n -- normal desc
677 690 --newline VALUE line1 line2
678 691
679 692 (some details hidden, use --verbose to show complete help)
680 693
681 694 $ hg help -k nohelp
682 695 Commands:
683 696
684 697 nohelp hg nohelp
685 698
686 699 Extension Commands:
687 700
688 701 nohelp (no help text available)
689 702
690 703 Test that default list of commands omits extension commands
691 704
692 705 $ hg help
693 706 Mercurial Distributed SCM
694 707
695 708 list of commands:
696 709
697 710 add add the specified files on the next commit
698 711 addremove add all new files, delete all missing files
699 712 annotate show changeset information by line for each file
700 713 archive create an unversioned archive of a repository revision
701 714 backout reverse effect of earlier changeset
702 715 bisect subdivision search of changesets
703 716 bookmarks create a new bookmark or list existing bookmarks
704 717 branch set or show the current branch name
705 718 branches list repository named branches
706 719 bundle create a changegroup file
707 720 cat output the current or given revision of files
708 721 clone make a copy of an existing repository
709 722 commit commit the specified files or all outstanding changes
710 723 config show combined config settings from all hgrc files
711 724 copy mark files as copied for the next commit
712 725 diff diff repository (or selected files)
713 726 export dump the header and diffs for one or more changesets
714 727 files list tracked files
715 728 forget forget the specified files on the next commit
716 729 graft copy changes from other branches onto the current branch
717 730 grep search for a pattern in specified files and revisions
718 731 heads show branch heads
719 732 help show help for a given topic or a help overview
720 733 identify identify the working directory or specified revision
721 734 import import an ordered set of patches
722 735 incoming show new changesets found in source
723 736 init create a new repository in the given directory
724 737 log show revision history of entire repository or files
725 738 manifest output the current or given revision of the project manifest
726 739 merge merge another revision into working directory
727 740 outgoing show changesets not found in the destination
728 741 paths show aliases for remote repositories
729 742 phase set or show the current phase name
730 743 pull pull changes from the specified source
731 744 push push changes to the specified destination
732 745 recover roll back an interrupted transaction
733 746 remove remove the specified files on the next commit
734 747 rename rename files; equivalent of copy + remove
735 748 resolve redo merges or set/view the merge status of files
736 749 revert restore files to their checkout state
737 750 root print the root (top) of the current working directory
738 751 serve start stand-alone webserver
739 752 status show changed files in the working directory
740 753 summary summarize working directory state
741 754 tag add one or more tags for the current or given revision
742 755 tags list repository tags
743 756 unbundle apply one or more changegroup files
744 757 update update working directory (or switch revisions)
745 758 verify verify the integrity of the repository
746 759 version output version and copyright information
747 760
748 761 enabled extensions:
749 762
750 763 helpext (no help text available)
751 764
752 765 additional help topics:
753 766
754 767 config Configuration Files
755 768 dates Date Formats
756 769 diffs Diff Formats
757 770 environment Environment Variables
758 771 extensions Using Additional Features
759 772 filesets Specifying File Sets
760 773 glossary Glossary
761 774 hgignore Syntax for Mercurial Ignore Files
762 775 hgweb Configuring hgweb
763 776 merge-tools Merge Tools
764 777 multirevs Specifying Multiple Revisions
765 778 patterns File Name Patterns
766 779 phases Working with Phases
767 780 revisions Specifying Single Revisions
768 781 revsets Specifying Revision Sets
769 782 scripting Using Mercurial from scripts and automation
770 783 subrepos Subrepositories
771 784 templating Template Usage
772 785 urls URL Paths
773 786
774 787 (use "hg help -v" to show built-in aliases and global options)
775 788
776 789
777 790 Test list of internal help commands
778 791
779 792 $ hg help debug
780 793 debug commands (internal and unsupported):
781 794
782 795 debugancestor
783 796 find the ancestor revision of two revisions in a given index
784 797 debugapplystreamclonebundle
785 798 apply a stream clone bundle file
786 799 debugbuilddag
787 800 builds a repo with a given DAG from scratch in the current
788 801 empty repo
789 802 debugbundle lists the contents of a bundle
790 803 debugcheckstate
791 804 validate the correctness of the current dirstate
792 805 debugcommands
793 806 list all available commands and options
794 807 debugcomplete
795 808 returns the completion list associated with the given command
796 809 debugcreatestreamclonebundle
797 810 create a stream clone bundle file
798 811 debugdag format the changelog or an index DAG as a concise textual
799 812 description
800 813 debugdata dump the contents of a data file revision
801 814 debugdate parse and display a date
802 815 debugdirstate
803 816 show the contents of the current dirstate
804 817 debugdiscovery
805 818 runs the changeset discovery protocol in isolation
806 819 debugextensions
807 820 show information about active extensions
808 821 debugfileset parse and apply a fileset specification
809 822 debugfsinfo show information detected about current filesystem
810 823 debuggetbundle
811 824 retrieves a bundle from a repo
812 825 debugignore display the combined ignore pattern
813 826 debugindex dump the contents of an index file
814 827 debugindexdot
815 828 dump an index DAG as a graphviz dot file
816 829 debuginstall test Mercurial installation
817 830 debugknown test whether node ids are known to a repo
818 831 debuglocks show or modify state of locks
819 832 debugmergestate
820 833 print merge state
821 834 debugnamecomplete
822 835 complete "names" - tags, open branch names, bookmark names
823 836 debugobsolete
824 837 create arbitrary obsolete marker
825 838 debugoptDEP (no help text available)
826 839 debugoptEXP (no help text available)
827 840 debugpathcomplete
828 841 complete part or all of a tracked path
829 842 debugpushkey access the pushkey key/value protocol
830 843 debugpvec (no help text available)
831 844 debugrebuilddirstate
832 845 rebuild the dirstate as it would look like for the given
833 846 revision
834 847 debugrebuildfncache
835 848 rebuild the fncache file
836 849 debugrename dump rename information
837 850 debugrevlog show data and statistics about a revlog
838 851 debugrevspec parse and apply a revision specification
839 852 debugsetparents
840 853 manually set the parents of the current working directory
841 854 debugsub (no help text available)
842 855 debugsuccessorssets
843 856 show set of successors for revision
844 857 debugwalk show how files match on given patterns
845 858 debugwireargs
846 859 (no help text available)
847 860
848 861 (use "hg help -v debug" to show built-in aliases and global options)
849 862
850 863
851 864 Test list of commands with command with no help text
852 865
853 866 $ hg help helpext
854 867 helpext extension - no help text available
855 868
856 869 list of commands:
857 870
858 871 nohelp (no help text available)
859 872
860 873 (use "hg help -v helpext" to show built-in aliases and global options)
861 874
862 875
863 876 test deprecated and experimental options are hidden in command help
864 877 $ hg help debugoptDEP
865 878 hg debugoptDEP
866 879
867 880 (no help text available)
868 881
869 882 options:
870 883
871 884 (some details hidden, use --verbose to show complete help)
872 885
873 886 $ hg help debugoptEXP
874 887 hg debugoptEXP
875 888
876 889 (no help text available)
877 890
878 891 options:
879 892
880 893 (some details hidden, use --verbose to show complete help)
881 894
882 895 test deprecated and experimental options is shown with -v
883 896 $ hg help -v debugoptDEP | grep dopt
884 897 --dopt option is (DEPRECATED)
885 898 $ hg help -v debugoptEXP | grep eopt
886 899 --eopt option is (EXPERIMENTAL)
887 900
888 901 #if gettext
889 902 test deprecated option is hidden with translation with untranslated description
890 903 (use many globy for not failing on changed transaction)
891 904 $ LANGUAGE=sv hg help debugoptDEP
892 905 hg debugoptDEP
893 906
894 907 (*) (glob)
895 908
896 909 options:
897 910
898 911 (some details hidden, use --verbose to show complete help)
899 912 #endif
900 913
901 914 Test commands that collide with topics (issue4240)
902 915
903 916 $ hg config -hq
904 917 hg config [-u] [NAME]...
905 918
906 919 show combined config settings from all hgrc files
907 920 $ hg showconfig -hq
908 921 hg config [-u] [NAME]...
909 922
910 923 show combined config settings from all hgrc files
911 924
912 925 Test a help topic
913 926
914 927 $ hg help revs
915 928 Specifying Single Revisions
916 929 """""""""""""""""""""""""""
917 930
918 931 Mercurial supports several ways to specify individual revisions.
919 932
920 933 A plain integer is treated as a revision number. Negative integers are
921 934 treated as sequential offsets from the tip, with -1 denoting the tip, -2
922 935 denoting the revision prior to the tip, and so forth.
923 936
924 937 A 40-digit hexadecimal string is treated as a unique revision identifier.
925 938
926 939 A hexadecimal string less than 40 characters long is treated as a unique
927 940 revision identifier and is referred to as a short-form identifier. A
928 941 short-form identifier is only valid if it is the prefix of exactly one
929 942 full-length identifier.
930 943
931 944 Any other string is treated as a bookmark, tag, or branch name. A bookmark
932 945 is a movable pointer to a revision. A tag is a permanent name associated
933 946 with a revision. A branch name denotes the tipmost open branch head of
934 947 that branch - or if they are all closed, the tipmost closed head of the
935 948 branch. Bookmark, tag, and branch names must not contain the ":"
936 949 character.
937 950
938 951 The reserved name "tip" always identifies the most recent revision.
939 952
940 953 The reserved name "null" indicates the null revision. This is the revision
941 954 of an empty repository, and the parent of revision 0.
942 955
943 956 The reserved name "." indicates the working directory parent. If no
944 957 working directory is checked out, it is equivalent to null. If an
945 958 uncommitted merge is in progress, "." is the revision of the first parent.
946 959
947 960 Test repeated config section name
948 961
949 962 $ hg help config.host
950 963 "http_proxy.host"
951 964 Host name and (optional) port of the proxy server, for example
952 965 "myproxy:8000".
953 966
954 967 "smtp.host"
955 968 Host name of mail server, e.g. "mail.example.com".
956 969
957 970 Unrelated trailing paragraphs shouldn't be included
958 971
959 972 $ hg help config.extramsg | grep '^$'
960 973
961 974
962 975 Test capitalized section name
963 976
964 977 $ hg help scripting.HGPLAIN > /dev/null
965 978
966 979 Help subsection:
967 980
968 981 $ hg help config.charsets |grep "Email example:" > /dev/null
969 982 [1]
970 983
971 984 Show nested definitions
972 985 ("profiling.type"[break]"ls"[break]"stat"[break])
973 986
974 987 $ hg help config.type | egrep '^$'|wc -l
975 988 \s*3 (re)
976 989
977 990 Last item in help config.*:
978 991
979 992 $ hg help config.`hg help config|grep '^ "'| \
980 993 > tail -1|sed 's![ "]*!!g'`| \
981 994 > grep "hg help -c config" > /dev/null
982 995 [1]
983 996
984 997 note to use help -c for general hg help config:
985 998
986 999 $ hg help config |grep "hg help -c config" > /dev/null
987 1000
988 1001 Test templating help
989 1002
990 1003 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
991 1004 desc String. The text of the changeset description.
992 1005 diffstat String. Statistics of changes with the following format:
993 1006 firstline Any text. Returns the first line of text.
994 1007 nonempty Any text. Returns '(none)' if the string is empty.
995 1008
996 1009 Test deprecated items
997 1010
998 1011 $ hg help -v templating | grep currentbookmark
999 1012 currentbookmark
1000 1013 $ hg help templating | (grep currentbookmark || true)
1001 1014
1002 1015 Test help hooks
1003 1016
1004 1017 $ cat > helphook1.py <<EOF
1005 1018 > from mercurial import help
1006 1019 >
1007 1020 > def rewrite(ui, topic, doc):
1008 1021 > return doc + '\nhelphook1\n'
1009 1022 >
1010 1023 > def extsetup(ui):
1011 1024 > help.addtopichook('revsets', rewrite)
1012 1025 > EOF
1013 1026 $ cat > helphook2.py <<EOF
1014 1027 > from mercurial import help
1015 1028 >
1016 1029 > def rewrite(ui, topic, doc):
1017 1030 > return doc + '\nhelphook2\n'
1018 1031 >
1019 1032 > def extsetup(ui):
1020 1033 > help.addtopichook('revsets', rewrite)
1021 1034 > EOF
1022 1035 $ echo '[extensions]' >> $HGRCPATH
1023 1036 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1024 1037 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1025 1038 $ hg help revsets | grep helphook
1026 1039 helphook1
1027 1040 helphook2
1028 1041
1029 1042 Test -e / -c / -k combinations
1030 1043
1031 1044 $ hg help -c schemes
1032 1045 abort: no such help topic: schemes
1033 1046 (try "hg help --keyword schemes")
1034 1047 [255]
1035 1048 $ hg help -e schemes |head -1
1036 1049 schemes extension - extend schemes with shortcuts to repository swarms
1037 1050 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1038 1051 Commands:
1039 1052 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1040 1053 Extensions:
1041 1054 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1042 1055 Extensions:
1043 1056 Commands:
1044 1057 $ hg help -c commit > /dev/null
1045 1058 $ hg help -e -c commit > /dev/null
1046 1059 $ hg help -e commit > /dev/null
1047 1060 abort: no such help topic: commit
1048 1061 (try "hg help --keyword commit")
1049 1062 [255]
1050 1063
1051 1064 Test keyword search help
1052 1065
1053 1066 $ cat > prefixedname.py <<EOF
1054 1067 > '''matched against word "clone"
1055 1068 > '''
1056 1069 > EOF
1057 1070 $ echo '[extensions]' >> $HGRCPATH
1058 1071 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1059 1072 $ hg help -k clone
1060 1073 Topics:
1061 1074
1062 1075 config Configuration Files
1063 1076 extensions Using Additional Features
1064 1077 glossary Glossary
1065 1078 phases Working with Phases
1066 1079 subrepos Subrepositories
1067 1080 urls URL Paths
1068 1081
1069 1082 Commands:
1070 1083
1071 1084 bookmarks create a new bookmark or list existing bookmarks
1072 1085 clone make a copy of an existing repository
1073 1086 debugapplystreamclonebundle apply a stream clone bundle file
1074 1087 debugcreatestreamclonebundle create a stream clone bundle file
1075 1088 paths show aliases for remote repositories
1076 1089 update update working directory (or switch revisions)
1077 1090
1078 1091 Extensions:
1079 1092
1080 1093 clonebundles advertise pre-generated bundles to seed clones (experimental)
1081 1094 prefixedname matched against word "clone"
1082 1095 relink recreates hardlinks between repository clones
1083 1096
1084 1097 Extension Commands:
1085 1098
1086 1099 qclone clone main and patch repository at same time
1087 1100
1088 1101 Test unfound topic
1089 1102
1090 1103 $ hg help nonexistingtopicthatwillneverexisteverever
1091 1104 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1092 1105 (try "hg help --keyword nonexistingtopicthatwillneverexisteverever")
1093 1106 [255]
1094 1107
1095 1108 Test unfound keyword
1096 1109
1097 1110 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1098 1111 abort: no matches
1099 1112 (try "hg help" for a list of topics)
1100 1113 [255]
1101 1114
1102 1115 Test omit indicating for help
1103 1116
1104 1117 $ cat > addverboseitems.py <<EOF
1105 1118 > '''extension to test omit indicating.
1106 1119 >
1107 1120 > This paragraph is never omitted (for extension)
1108 1121 >
1109 1122 > .. container:: verbose
1110 1123 >
1111 1124 > This paragraph is omitted,
1112 1125 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1113 1126 >
1114 1127 > This paragraph is never omitted, too (for extension)
1115 1128 > '''
1116 1129 >
1117 1130 > from mercurial import help, commands
1118 1131 > testtopic = """This paragraph is never omitted (for topic).
1119 1132 >
1120 1133 > .. container:: verbose
1121 1134 >
1122 1135 > This paragraph is omitted,
1123 1136 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1124 1137 >
1125 1138 > This paragraph is never omitted, too (for topic)
1126 1139 > """
1127 1140 > def extsetup(ui):
1128 1141 > help.helptable.append((["topic-containing-verbose"],
1129 1142 > "This is the topic to test omit indicating.",
1130 1143 > lambda ui: testtopic))
1131 1144 > EOF
1132 1145 $ echo '[extensions]' >> $HGRCPATH
1133 1146 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1134 1147 $ hg help addverboseitems
1135 1148 addverboseitems extension - extension to test omit indicating.
1136 1149
1137 1150 This paragraph is never omitted (for extension)
1138 1151
1139 1152 This paragraph is never omitted, too (for extension)
1140 1153
1141 1154 (some details hidden, use --verbose to show complete help)
1142 1155
1143 1156 no commands defined
1144 1157 $ hg help -v addverboseitems
1145 1158 addverboseitems extension - extension to test omit indicating.
1146 1159
1147 1160 This paragraph is never omitted (for extension)
1148 1161
1149 1162 This paragraph is omitted, if "hg help" is invoked without "-v" (for
1150 1163 extension)
1151 1164
1152 1165 This paragraph is never omitted, too (for extension)
1153 1166
1154 1167 no commands defined
1155 1168 $ hg help topic-containing-verbose
1156 1169 This is the topic to test omit indicating.
1157 1170 """"""""""""""""""""""""""""""""""""""""""
1158 1171
1159 1172 This paragraph is never omitted (for topic).
1160 1173
1161 1174 This paragraph is never omitted, too (for topic)
1162 1175
1163 1176 (some details hidden, use --verbose to show complete help)
1164 1177 $ hg help -v topic-containing-verbose
1165 1178 This is the topic to test omit indicating.
1166 1179 """"""""""""""""""""""""""""""""""""""""""
1167 1180
1168 1181 This paragraph is never omitted (for topic).
1169 1182
1170 1183 This paragraph is omitted, if "hg help" is invoked without "-v" (for
1171 1184 topic)
1172 1185
1173 1186 This paragraph is never omitted, too (for topic)
1174 1187
1175 1188 Test section lookup
1176 1189
1177 1190 $ hg help revset.merge
1178 1191 "merge()"
1179 1192 Changeset is a merge changeset.
1180 1193
1181 1194 $ hg help glossary.dag
1182 1195 DAG
1183 1196 The repository of changesets of a distributed version control system
1184 1197 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1185 1198 of nodes and edges, where nodes correspond to changesets and edges
1186 1199 imply a parent -> child relation. This graph can be visualized by
1187 1200 graphical tools such as "hg log --graph". In Mercurial, the DAG is
1188 1201 limited by the requirement for children to have at most two parents.
1189 1202
1190 1203
1191 1204 $ hg help hgrc.paths
1192 1205 "paths"
1193 1206 -------
1194 1207
1195 1208 Assigns symbolic names to repositories. The left side is the symbolic
1196 1209 name, and the right gives the directory or URL that is the location of the
1197 1210 repository. Default paths can be declared by setting the following
1198 1211 entries.
1199 1212
1200 1213 "default"
1201 1214 Directory or URL to use when pulling if no source is specified.
1202 1215 (default: repository from which the current repository was cloned)
1203 1216
1204 1217 "default-push"
1205 1218 Optional. Directory or URL to use when pushing if no destination is
1206 1219 specified.
1207 1220
1208 1221 Custom paths can be defined by assigning the path to a name that later can
1209 1222 be used from the command line. Example:
1210 1223
1211 1224 [paths]
1212 1225 my_path = http://example.com/path
1213 1226
1214 1227 To push to the path defined in "my_path" run the command:
1215 1228
1216 1229 hg push my_path
1217 1230
1218 1231 $ hg help glossary.mcguffin
1219 1232 abort: help section not found
1220 1233 [255]
1221 1234
1222 1235 $ hg help glossary.mc.guffin
1223 1236 abort: help section not found
1224 1237 [255]
1225 1238
1226 1239 $ hg help template.files
1227 1240 files List of strings. All files modified, added, or removed by
1228 1241 this changeset.
1229 1242
1230 1243 Test dynamic list of merge tools only shows up once
1231 1244 $ hg help merge-tools
1232 1245 Merge Tools
1233 1246 """""""""""
1234 1247
1235 1248 To merge files Mercurial uses merge tools.
1236 1249
1237 1250 A merge tool combines two different versions of a file into a merged file.
1238 1251 Merge tools are given the two files and the greatest common ancestor of
1239 1252 the two file versions, so they can determine the changes made on both
1240 1253 branches.
1241 1254
1242 1255 Merge tools are used both for "hg resolve", "hg merge", "hg update", "hg
1243 1256 backout" and in several extensions.
1244 1257
1245 1258 Usually, the merge tool tries to automatically reconcile the files by
1246 1259 combining all non-overlapping changes that occurred separately in the two
1247 1260 different evolutions of the same initial base file. Furthermore, some
1248 1261 interactive merge programs make it easier to manually resolve conflicting
1249 1262 merges, either in a graphical way, or by inserting some conflict markers.
1250 1263 Mercurial does not include any interactive merge programs but relies on
1251 1264 external tools for that.
1252 1265
1253 1266 Available merge tools
1254 1267 =====================
1255 1268
1256 1269 External merge tools and their properties are configured in the merge-
1257 1270 tools configuration section - see hgrc(5) - but they can often just be
1258 1271 named by their executable.
1259 1272
1260 1273 A merge tool is generally usable if its executable can be found on the
1261 1274 system and if it can handle the merge. The executable is found if it is an
1262 1275 absolute or relative executable path or the name of an application in the
1263 1276 executable search path. The tool is assumed to be able to handle the merge
1264 1277 if it can handle symlinks if the file is a symlink, if it can handle
1265 1278 binary files if the file is binary, and if a GUI is available if the tool
1266 1279 requires a GUI.
1267 1280
1268 1281 There are some internal merge tools which can be used. The internal merge
1269 1282 tools are:
1270 1283
1271 1284 ":dump"
1272 1285 Creates three versions of the files to merge, containing the contents of
1273 1286 local, other and base. These files can then be used to perform a merge
1274 1287 manually. If the file to be merged is named "a.txt", these files will
1275 1288 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1276 1289 they will be placed in the same directory as "a.txt".
1277 1290
1278 1291 ":fail"
1279 1292 Rather than attempting to merge files that were modified on both
1280 1293 branches, it marks them as unresolved. The resolve command must be used
1281 1294 to resolve these conflicts.
1282 1295
1283 1296 ":local"
1284 1297 Uses the local version of files as the merged version.
1285 1298
1286 1299 ":merge"
1287 1300 Uses the internal non-interactive simple merge algorithm for merging
1288 1301 files. It will fail if there are any conflicts and leave markers in the
1289 1302 partially merged file. Markers will have two sections, one for each side
1290 1303 of merge.
1291 1304
1292 1305 ":merge-local"
1293 1306 Like :merge, but resolve all conflicts non-interactively in favor of the
1294 1307 local changes.
1295 1308
1296 1309 ":merge-other"
1297 1310 Like :merge, but resolve all conflicts non-interactively in favor of the
1298 1311 other changes.
1299 1312
1300 1313 ":merge3"
1301 1314 Uses the internal non-interactive simple merge algorithm for merging
1302 1315 files. It will fail if there are any conflicts and leave markers in the
1303 1316 partially merged file. Marker will have three sections, one from each
1304 1317 side of the merge and one for the base content.
1305 1318
1306 1319 ":other"
1307 1320 Uses the other version of files as the merged version.
1308 1321
1309 1322 ":prompt"
1310 1323 Asks the user which of the local or the other version to keep as the
1311 1324 merged version.
1312 1325
1313 1326 ":tagmerge"
1314 1327 Uses the internal tag merge algorithm (experimental).
1315 1328
1316 1329 ":union"
1317 1330 Uses the internal non-interactive simple merge algorithm for merging
1318 1331 files. It will use both left and right sides for conflict regions. No
1319 1332 markers are inserted.
1320 1333
1321 1334 Internal tools are always available and do not require a GUI but will by
1322 1335 default not handle symlinks or binary files.
1323 1336
1324 1337 Choosing a merge tool
1325 1338 =====================
1326 1339
1327 1340 Mercurial uses these rules when deciding which merge tool to use:
1328 1341
1329 1342 1. If a tool has been specified with the --tool option to merge or
1330 1343 resolve, it is used. If it is the name of a tool in the merge-tools
1331 1344 configuration, its configuration is used. Otherwise the specified tool
1332 1345 must be executable by the shell.
1333 1346 2. If the "HGMERGE" environment variable is present, its value is used and
1334 1347 must be executable by the shell.
1335 1348 3. If the filename of the file to be merged matches any of the patterns in
1336 1349 the merge-patterns configuration section, the first usable merge tool
1337 1350 corresponding to a matching pattern is used. Here, binary capabilities
1338 1351 of the merge tool are not considered.
1339 1352 4. If ui.merge is set it will be considered next. If the value is not the
1340 1353 name of a configured tool, the specified value is used and must be
1341 1354 executable by the shell. Otherwise the named tool is used if it is
1342 1355 usable.
1343 1356 5. If any usable merge tools are present in the merge-tools configuration
1344 1357 section, the one with the highest priority is used.
1345 1358 6. If a program named "hgmerge" can be found on the system, it is used -
1346 1359 but it will by default not be used for symlinks and binary files.
1347 1360 7. If the file to be merged is not binary and is not a symlink, then
1348 1361 internal ":merge" is used.
1349 1362 8. The merge of the file fails and must be resolved before commit.
1350 1363
1351 1364 Note:
1352 1365 After selecting a merge program, Mercurial will by default attempt to
1353 1366 merge the files using a simple merge algorithm first. Only if it
1354 1367 doesn't succeed because of conflicting changes Mercurial will actually
1355 1368 execute the merge program. Whether to use the simple merge algorithm
1356 1369 first can be controlled by the premerge setting of the merge tool.
1357 1370 Premerge is enabled by default unless the file is binary or a symlink.
1358 1371
1359 1372 See the merge-tools and ui sections of hgrc(5) for details on the
1360 1373 configuration of merge tools.
1361 1374
1362 1375 Test usage of section marks in help documents
1363 1376
1364 1377 $ cd "$TESTDIR"/../doc
1365 1378 $ python check-seclevel.py
1366 1379 $ cd $TESTTMP
1367 1380
1368 1381 #if serve
1369 1382
1370 1383 Test the help pages in hgweb.
1371 1384
1372 1385 Dish up an empty repo; serve it cold.
1373 1386
1374 1387 $ hg init "$TESTTMP/test"
1375 1388 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1376 1389 $ cat hg.pid >> $DAEMON_PIDS
1377 1390
1378 1391 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1379 1392 200 Script output follows
1380 1393
1381 1394 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1382 1395 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1383 1396 <head>
1384 1397 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1385 1398 <meta name="robots" content="index, nofollow" />
1386 1399 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1387 1400 <script type="text/javascript" src="/static/mercurial.js"></script>
1388 1401
1389 1402 <title>Help: Index</title>
1390 1403 </head>
1391 1404 <body>
1392 1405
1393 1406 <div class="container">
1394 1407 <div class="menu">
1395 1408 <div class="logo">
1396 1409 <a href="https://mercurial-scm.org/">
1397 1410 <img src="/static/hglogo.png" alt="mercurial" /></a>
1398 1411 </div>
1399 1412 <ul>
1400 1413 <li><a href="/shortlog">log</a></li>
1401 1414 <li><a href="/graph">graph</a></li>
1402 1415 <li><a href="/tags">tags</a></li>
1403 1416 <li><a href="/bookmarks">bookmarks</a></li>
1404 1417 <li><a href="/branches">branches</a></li>
1405 1418 </ul>
1406 1419 <ul>
1407 1420 <li class="active">help</li>
1408 1421 </ul>
1409 1422 </div>
1410 1423
1411 1424 <div class="main">
1412 1425 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1413 1426 <form class="search" action="/log">
1414 1427
1415 1428 <p><input name="rev" id="search1" type="text" size="30" /></p>
1416 1429 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1417 1430 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1418 1431 </form>
1419 1432 <table class="bigtable">
1420 1433 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
1421 1434
1422 1435 <tr><td>
1423 1436 <a href="/help/config">
1424 1437 config
1425 1438 </a>
1426 1439 </td><td>
1427 1440 Configuration Files
1428 1441 </td></tr>
1429 1442 <tr><td>
1430 1443 <a href="/help/dates">
1431 1444 dates
1432 1445 </a>
1433 1446 </td><td>
1434 1447 Date Formats
1435 1448 </td></tr>
1436 1449 <tr><td>
1437 1450 <a href="/help/diffs">
1438 1451 diffs
1439 1452 </a>
1440 1453 </td><td>
1441 1454 Diff Formats
1442 1455 </td></tr>
1443 1456 <tr><td>
1444 1457 <a href="/help/environment">
1445 1458 environment
1446 1459 </a>
1447 1460 </td><td>
1448 1461 Environment Variables
1449 1462 </td></tr>
1450 1463 <tr><td>
1451 1464 <a href="/help/extensions">
1452 1465 extensions
1453 1466 </a>
1454 1467 </td><td>
1455 1468 Using Additional Features
1456 1469 </td></tr>
1457 1470 <tr><td>
1458 1471 <a href="/help/filesets">
1459 1472 filesets
1460 1473 </a>
1461 1474 </td><td>
1462 1475 Specifying File Sets
1463 1476 </td></tr>
1464 1477 <tr><td>
1465 1478 <a href="/help/glossary">
1466 1479 glossary
1467 1480 </a>
1468 1481 </td><td>
1469 1482 Glossary
1470 1483 </td></tr>
1471 1484 <tr><td>
1472 1485 <a href="/help/hgignore">
1473 1486 hgignore
1474 1487 </a>
1475 1488 </td><td>
1476 1489 Syntax for Mercurial Ignore Files
1477 1490 </td></tr>
1478 1491 <tr><td>
1479 1492 <a href="/help/hgweb">
1480 1493 hgweb
1481 1494 </a>
1482 1495 </td><td>
1483 1496 Configuring hgweb
1484 1497 </td></tr>
1485 1498 <tr><td>
1486 1499 <a href="/help/merge-tools">
1487 1500 merge-tools
1488 1501 </a>
1489 1502 </td><td>
1490 1503 Merge Tools
1491 1504 </td></tr>
1492 1505 <tr><td>
1493 1506 <a href="/help/multirevs">
1494 1507 multirevs
1495 1508 </a>
1496 1509 </td><td>
1497 1510 Specifying Multiple Revisions
1498 1511 </td></tr>
1499 1512 <tr><td>
1500 1513 <a href="/help/patterns">
1501 1514 patterns
1502 1515 </a>
1503 1516 </td><td>
1504 1517 File Name Patterns
1505 1518 </td></tr>
1506 1519 <tr><td>
1507 1520 <a href="/help/phases">
1508 1521 phases
1509 1522 </a>
1510 1523 </td><td>
1511 1524 Working with Phases
1512 1525 </td></tr>
1513 1526 <tr><td>
1514 1527 <a href="/help/revisions">
1515 1528 revisions
1516 1529 </a>
1517 1530 </td><td>
1518 1531 Specifying Single Revisions
1519 1532 </td></tr>
1520 1533 <tr><td>
1521 1534 <a href="/help/revsets">
1522 1535 revsets
1523 1536 </a>
1524 1537 </td><td>
1525 1538 Specifying Revision Sets
1526 1539 </td></tr>
1527 1540 <tr><td>
1528 1541 <a href="/help/scripting">
1529 1542 scripting
1530 1543 </a>
1531 1544 </td><td>
1532 1545 Using Mercurial from scripts and automation
1533 1546 </td></tr>
1534 1547 <tr><td>
1535 1548 <a href="/help/subrepos">
1536 1549 subrepos
1537 1550 </a>
1538 1551 </td><td>
1539 1552 Subrepositories
1540 1553 </td></tr>
1541 1554 <tr><td>
1542 1555 <a href="/help/templating">
1543 1556 templating
1544 1557 </a>
1545 1558 </td><td>
1546 1559 Template Usage
1547 1560 </td></tr>
1548 1561 <tr><td>
1549 1562 <a href="/help/urls">
1550 1563 urls
1551 1564 </a>
1552 1565 </td><td>
1553 1566 URL Paths
1554 1567 </td></tr>
1555 1568 <tr><td>
1556 1569 <a href="/help/topic-containing-verbose">
1557 1570 topic-containing-verbose
1558 1571 </a>
1559 1572 </td><td>
1560 1573 This is the topic to test omit indicating.
1561 1574 </td></tr>
1562 1575
1563 1576 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1564 1577
1565 1578 <tr><td>
1566 1579 <a href="/help/add">
1567 1580 add
1568 1581 </a>
1569 1582 </td><td>
1570 1583 add the specified files on the next commit
1571 1584 </td></tr>
1572 1585 <tr><td>
1573 1586 <a href="/help/annotate">
1574 1587 annotate
1575 1588 </a>
1576 1589 </td><td>
1577 1590 show changeset information by line for each file
1578 1591 </td></tr>
1579 1592 <tr><td>
1580 1593 <a href="/help/clone">
1581 1594 clone
1582 1595 </a>
1583 1596 </td><td>
1584 1597 make a copy of an existing repository
1585 1598 </td></tr>
1586 1599 <tr><td>
1587 1600 <a href="/help/commit">
1588 1601 commit
1589 1602 </a>
1590 1603 </td><td>
1591 1604 commit the specified files or all outstanding changes
1592 1605 </td></tr>
1593 1606 <tr><td>
1594 1607 <a href="/help/diff">
1595 1608 diff
1596 1609 </a>
1597 1610 </td><td>
1598 1611 diff repository (or selected files)
1599 1612 </td></tr>
1600 1613 <tr><td>
1601 1614 <a href="/help/export">
1602 1615 export
1603 1616 </a>
1604 1617 </td><td>
1605 1618 dump the header and diffs for one or more changesets
1606 1619 </td></tr>
1607 1620 <tr><td>
1608 1621 <a href="/help/forget">
1609 1622 forget
1610 1623 </a>
1611 1624 </td><td>
1612 1625 forget the specified files on the next commit
1613 1626 </td></tr>
1614 1627 <tr><td>
1615 1628 <a href="/help/init">
1616 1629 init
1617 1630 </a>
1618 1631 </td><td>
1619 1632 create a new repository in the given directory
1620 1633 </td></tr>
1621 1634 <tr><td>
1622 1635 <a href="/help/log">
1623 1636 log
1624 1637 </a>
1625 1638 </td><td>
1626 1639 show revision history of entire repository or files
1627 1640 </td></tr>
1628 1641 <tr><td>
1629 1642 <a href="/help/merge">
1630 1643 merge
1631 1644 </a>
1632 1645 </td><td>
1633 1646 merge another revision into working directory
1634 1647 </td></tr>
1635 1648 <tr><td>
1636 1649 <a href="/help/pull">
1637 1650 pull
1638 1651 </a>
1639 1652 </td><td>
1640 1653 pull changes from the specified source
1641 1654 </td></tr>
1642 1655 <tr><td>
1643 1656 <a href="/help/push">
1644 1657 push
1645 1658 </a>
1646 1659 </td><td>
1647 1660 push changes to the specified destination
1648 1661 </td></tr>
1649 1662 <tr><td>
1650 1663 <a href="/help/remove">
1651 1664 remove
1652 1665 </a>
1653 1666 </td><td>
1654 1667 remove the specified files on the next commit
1655 1668 </td></tr>
1656 1669 <tr><td>
1657 1670 <a href="/help/serve">
1658 1671 serve
1659 1672 </a>
1660 1673 </td><td>
1661 1674 start stand-alone webserver
1662 1675 </td></tr>
1663 1676 <tr><td>
1664 1677 <a href="/help/status">
1665 1678 status
1666 1679 </a>
1667 1680 </td><td>
1668 1681 show changed files in the working directory
1669 1682 </td></tr>
1670 1683 <tr><td>
1671 1684 <a href="/help/summary">
1672 1685 summary
1673 1686 </a>
1674 1687 </td><td>
1675 1688 summarize working directory state
1676 1689 </td></tr>
1677 1690 <tr><td>
1678 1691 <a href="/help/update">
1679 1692 update
1680 1693 </a>
1681 1694 </td><td>
1682 1695 update working directory (or switch revisions)
1683 1696 </td></tr>
1684 1697
1685 1698 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1686 1699
1687 1700 <tr><td>
1688 1701 <a href="/help/addremove">
1689 1702 addremove
1690 1703 </a>
1691 1704 </td><td>
1692 1705 add all new files, delete all missing files
1693 1706 </td></tr>
1694 1707 <tr><td>
1695 1708 <a href="/help/archive">
1696 1709 archive
1697 1710 </a>
1698 1711 </td><td>
1699 1712 create an unversioned archive of a repository revision
1700 1713 </td></tr>
1701 1714 <tr><td>
1702 1715 <a href="/help/backout">
1703 1716 backout
1704 1717 </a>
1705 1718 </td><td>
1706 1719 reverse effect of earlier changeset
1707 1720 </td></tr>
1708 1721 <tr><td>
1709 1722 <a href="/help/bisect">
1710 1723 bisect
1711 1724 </a>
1712 1725 </td><td>
1713 1726 subdivision search of changesets
1714 1727 </td></tr>
1715 1728 <tr><td>
1716 1729 <a href="/help/bookmarks">
1717 1730 bookmarks
1718 1731 </a>
1719 1732 </td><td>
1720 1733 create a new bookmark or list existing bookmarks
1721 1734 </td></tr>
1722 1735 <tr><td>
1723 1736 <a href="/help/branch">
1724 1737 branch
1725 1738 </a>
1726 1739 </td><td>
1727 1740 set or show the current branch name
1728 1741 </td></tr>
1729 1742 <tr><td>
1730 1743 <a href="/help/branches">
1731 1744 branches
1732 1745 </a>
1733 1746 </td><td>
1734 1747 list repository named branches
1735 1748 </td></tr>
1736 1749 <tr><td>
1737 1750 <a href="/help/bundle">
1738 1751 bundle
1739 1752 </a>
1740 1753 </td><td>
1741 1754 create a changegroup file
1742 1755 </td></tr>
1743 1756 <tr><td>
1744 1757 <a href="/help/cat">
1745 1758 cat
1746 1759 </a>
1747 1760 </td><td>
1748 1761 output the current or given revision of files
1749 1762 </td></tr>
1750 1763 <tr><td>
1751 1764 <a href="/help/config">
1752 1765 config
1753 1766 </a>
1754 1767 </td><td>
1755 1768 show combined config settings from all hgrc files
1756 1769 </td></tr>
1757 1770 <tr><td>
1758 1771 <a href="/help/copy">
1759 1772 copy
1760 1773 </a>
1761 1774 </td><td>
1762 1775 mark files as copied for the next commit
1763 1776 </td></tr>
1764 1777 <tr><td>
1765 1778 <a href="/help/files">
1766 1779 files
1767 1780 </a>
1768 1781 </td><td>
1769 1782 list tracked files
1770 1783 </td></tr>
1771 1784 <tr><td>
1772 1785 <a href="/help/graft">
1773 1786 graft
1774 1787 </a>
1775 1788 </td><td>
1776 1789 copy changes from other branches onto the current branch
1777 1790 </td></tr>
1778 1791 <tr><td>
1779 1792 <a href="/help/grep">
1780 1793 grep
1781 1794 </a>
1782 1795 </td><td>
1783 1796 search for a pattern in specified files and revisions
1784 1797 </td></tr>
1785 1798 <tr><td>
1786 1799 <a href="/help/heads">
1787 1800 heads
1788 1801 </a>
1789 1802 </td><td>
1790 1803 show branch heads
1791 1804 </td></tr>
1792 1805 <tr><td>
1793 1806 <a href="/help/help">
1794 1807 help
1795 1808 </a>
1796 1809 </td><td>
1797 1810 show help for a given topic or a help overview
1798 1811 </td></tr>
1799 1812 <tr><td>
1800 1813 <a href="/help/identify">
1801 1814 identify
1802 1815 </a>
1803 1816 </td><td>
1804 1817 identify the working directory or specified revision
1805 1818 </td></tr>
1806 1819 <tr><td>
1807 1820 <a href="/help/import">
1808 1821 import
1809 1822 </a>
1810 1823 </td><td>
1811 1824 import an ordered set of patches
1812 1825 </td></tr>
1813 1826 <tr><td>
1814 1827 <a href="/help/incoming">
1815 1828 incoming
1816 1829 </a>
1817 1830 </td><td>
1818 1831 show new changesets found in source
1819 1832 </td></tr>
1820 1833 <tr><td>
1821 1834 <a href="/help/manifest">
1822 1835 manifest
1823 1836 </a>
1824 1837 </td><td>
1825 1838 output the current or given revision of the project manifest
1826 1839 </td></tr>
1827 1840 <tr><td>
1828 1841 <a href="/help/nohelp">
1829 1842 nohelp
1830 1843 </a>
1831 1844 </td><td>
1832 1845 (no help text available)
1833 1846 </td></tr>
1834 1847 <tr><td>
1835 1848 <a href="/help/outgoing">
1836 1849 outgoing
1837 1850 </a>
1838 1851 </td><td>
1839 1852 show changesets not found in the destination
1840 1853 </td></tr>
1841 1854 <tr><td>
1842 1855 <a href="/help/paths">
1843 1856 paths
1844 1857 </a>
1845 1858 </td><td>
1846 1859 show aliases for remote repositories
1847 1860 </td></tr>
1848 1861 <tr><td>
1849 1862 <a href="/help/phase">
1850 1863 phase
1851 1864 </a>
1852 1865 </td><td>
1853 1866 set or show the current phase name
1854 1867 </td></tr>
1855 1868 <tr><td>
1856 1869 <a href="/help/recover">
1857 1870 recover
1858 1871 </a>
1859 1872 </td><td>
1860 1873 roll back an interrupted transaction
1861 1874 </td></tr>
1862 1875 <tr><td>
1863 1876 <a href="/help/rename">
1864 1877 rename
1865 1878 </a>
1866 1879 </td><td>
1867 1880 rename files; equivalent of copy + remove
1868 1881 </td></tr>
1869 1882 <tr><td>
1870 1883 <a href="/help/resolve">
1871 1884 resolve
1872 1885 </a>
1873 1886 </td><td>
1874 1887 redo merges or set/view the merge status of files
1875 1888 </td></tr>
1876 1889 <tr><td>
1877 1890 <a href="/help/revert">
1878 1891 revert
1879 1892 </a>
1880 1893 </td><td>
1881 1894 restore files to their checkout state
1882 1895 </td></tr>
1883 1896 <tr><td>
1884 1897 <a href="/help/root">
1885 1898 root
1886 1899 </a>
1887 1900 </td><td>
1888 1901 print the root (top) of the current working directory
1889 1902 </td></tr>
1890 1903 <tr><td>
1891 1904 <a href="/help/tag">
1892 1905 tag
1893 1906 </a>
1894 1907 </td><td>
1895 1908 add one or more tags for the current or given revision
1896 1909 </td></tr>
1897 1910 <tr><td>
1898 1911 <a href="/help/tags">
1899 1912 tags
1900 1913 </a>
1901 1914 </td><td>
1902 1915 list repository tags
1903 1916 </td></tr>
1904 1917 <tr><td>
1905 1918 <a href="/help/unbundle">
1906 1919 unbundle
1907 1920 </a>
1908 1921 </td><td>
1909 1922 apply one or more changegroup files
1910 1923 </td></tr>
1911 1924 <tr><td>
1912 1925 <a href="/help/verify">
1913 1926 verify
1914 1927 </a>
1915 1928 </td><td>
1916 1929 verify the integrity of the repository
1917 1930 </td></tr>
1918 1931 <tr><td>
1919 1932 <a href="/help/version">
1920 1933 version
1921 1934 </a>
1922 1935 </td><td>
1923 1936 output version and copyright information
1924 1937 </td></tr>
1925 1938 </table>
1926 1939 </div>
1927 1940 </div>
1928 1941
1929 1942 <script type="text/javascript">process_dates()</script>
1930 1943
1931 1944
1932 1945 </body>
1933 1946 </html>
1934 1947
1935 1948
1936 1949 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
1937 1950 200 Script output follows
1938 1951
1939 1952 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1940 1953 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1941 1954 <head>
1942 1955 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1943 1956 <meta name="robots" content="index, nofollow" />
1944 1957 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1945 1958 <script type="text/javascript" src="/static/mercurial.js"></script>
1946 1959
1947 1960 <title>Help: add</title>
1948 1961 </head>
1949 1962 <body>
1950 1963
1951 1964 <div class="container">
1952 1965 <div class="menu">
1953 1966 <div class="logo">
1954 1967 <a href="https://mercurial-scm.org/">
1955 1968 <img src="/static/hglogo.png" alt="mercurial" /></a>
1956 1969 </div>
1957 1970 <ul>
1958 1971 <li><a href="/shortlog">log</a></li>
1959 1972 <li><a href="/graph">graph</a></li>
1960 1973 <li><a href="/tags">tags</a></li>
1961 1974 <li><a href="/bookmarks">bookmarks</a></li>
1962 1975 <li><a href="/branches">branches</a></li>
1963 1976 </ul>
1964 1977 <ul>
1965 1978 <li class="active"><a href="/help">help</a></li>
1966 1979 </ul>
1967 1980 </div>
1968 1981
1969 1982 <div class="main">
1970 1983 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1971 1984 <h3>Help: add</h3>
1972 1985
1973 1986 <form class="search" action="/log">
1974 1987
1975 1988 <p><input name="rev" id="search1" type="text" size="30" /></p>
1976 1989 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1977 1990 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1978 1991 </form>
1979 1992 <div id="doc">
1980 1993 <p>
1981 1994 hg add [OPTION]... [FILE]...
1982 1995 </p>
1983 1996 <p>
1984 1997 add the specified files on the next commit
1985 1998 </p>
1986 1999 <p>
1987 2000 Schedule files to be version controlled and added to the
1988 2001 repository.
1989 2002 </p>
1990 2003 <p>
1991 2004 The files will be added to the repository at the next commit. To
1992 2005 undo an add before that, see &quot;hg forget&quot;.
1993 2006 </p>
1994 2007 <p>
1995 2008 If no names are given, add all files to the repository.
1996 2009 </p>
1997 2010 <p>
1998 An example showing how new (unknown) files are added
1999 automatically by &quot;hg add&quot;:
2011 Examples:
2000 2012 </p>
2013 <ul>
2014 <li> New (unknown) files are added automatically by &quot;hg add&quot;:
2001 2015 <pre>
2002 2016 \$ ls (re)
2003 2017 foo.c
2004 2018 \$ hg status (re)
2005 2019 ? foo.c
2006 2020 \$ hg add (re)
2007 2021 adding foo.c
2008 2022 \$ hg status (re)
2009 2023 A foo.c
2010 2024 </pre>
2025 <li> Specific files to be added can be specified:
2026 <pre>
2027 \$ ls (re)
2028 bar.c foo.c
2029 \$ hg status (re)
2030 ? bar.c
2031 ? foo.c
2032 \$ hg add bar.c (re)
2033 \$ hg status (re)
2034 A bar.c
2035 ? foo.c
2036 </pre>
2037 </ul>
2011 2038 <p>
2012 2039 Returns 0 if all files are successfully added.
2013 2040 </p>
2014 2041 <p>
2015 2042 options ([+] can be repeated):
2016 2043 </p>
2017 2044 <table>
2018 2045 <tr><td>-I</td>
2019 2046 <td>--include PATTERN [+]</td>
2020 2047 <td>include names matching the given patterns</td></tr>
2021 2048 <tr><td>-X</td>
2022 2049 <td>--exclude PATTERN [+]</td>
2023 2050 <td>exclude names matching the given patterns</td></tr>
2024 2051 <tr><td>-S</td>
2025 2052 <td>--subrepos</td>
2026 2053 <td>recurse into subrepositories</td></tr>
2027 2054 <tr><td>-n</td>
2028 2055 <td>--dry-run</td>
2029 2056 <td>do not perform actions, just print output</td></tr>
2030 2057 </table>
2031 2058 <p>
2032 2059 global options ([+] can be repeated):
2033 2060 </p>
2034 2061 <table>
2035 2062 <tr><td>-R</td>
2036 2063 <td>--repository REPO</td>
2037 2064 <td>repository root directory or name of overlay bundle file</td></tr>
2038 2065 <tr><td></td>
2039 2066 <td>--cwd DIR</td>
2040 2067 <td>change working directory</td></tr>
2041 2068 <tr><td>-y</td>
2042 2069 <td>--noninteractive</td>
2043 2070 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2044 2071 <tr><td>-q</td>
2045 2072 <td>--quiet</td>
2046 2073 <td>suppress output</td></tr>
2047 2074 <tr><td>-v</td>
2048 2075 <td>--verbose</td>
2049 2076 <td>enable additional output</td></tr>
2050 2077 <tr><td></td>
2051 2078 <td>--config CONFIG [+]</td>
2052 2079 <td>set/override config option (use 'section.name=value')</td></tr>
2053 2080 <tr><td></td>
2054 2081 <td>--debug</td>
2055 2082 <td>enable debugging output</td></tr>
2056 2083 <tr><td></td>
2057 2084 <td>--debugger</td>
2058 2085 <td>start debugger</td></tr>
2059 2086 <tr><td></td>
2060 2087 <td>--encoding ENCODE</td>
2061 2088 <td>set the charset encoding (default: ascii)</td></tr>
2062 2089 <tr><td></td>
2063 2090 <td>--encodingmode MODE</td>
2064 2091 <td>set the charset encoding mode (default: strict)</td></tr>
2065 2092 <tr><td></td>
2066 2093 <td>--traceback</td>
2067 2094 <td>always print a traceback on exception</td></tr>
2068 2095 <tr><td></td>
2069 2096 <td>--time</td>
2070 2097 <td>time how long the command takes</td></tr>
2071 2098 <tr><td></td>
2072 2099 <td>--profile</td>
2073 2100 <td>print command execution profile</td></tr>
2074 2101 <tr><td></td>
2075 2102 <td>--version</td>
2076 2103 <td>output version information and exit</td></tr>
2077 2104 <tr><td>-h</td>
2078 2105 <td>--help</td>
2079 2106 <td>display help and exit</td></tr>
2080 2107 <tr><td></td>
2081 2108 <td>--hidden</td>
2082 2109 <td>consider hidden changesets</td></tr>
2083 2110 </table>
2084 2111
2085 2112 </div>
2086 2113 </div>
2087 2114 </div>
2088 2115
2089 2116 <script type="text/javascript">process_dates()</script>
2090 2117
2091 2118
2092 2119 </body>
2093 2120 </html>
2094 2121
2095 2122
2096 2123 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2097 2124 200 Script output follows
2098 2125
2099 2126 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2100 2127 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2101 2128 <head>
2102 2129 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2103 2130 <meta name="robots" content="index, nofollow" />
2104 2131 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2105 2132 <script type="text/javascript" src="/static/mercurial.js"></script>
2106 2133
2107 2134 <title>Help: remove</title>
2108 2135 </head>
2109 2136 <body>
2110 2137
2111 2138 <div class="container">
2112 2139 <div class="menu">
2113 2140 <div class="logo">
2114 2141 <a href="https://mercurial-scm.org/">
2115 2142 <img src="/static/hglogo.png" alt="mercurial" /></a>
2116 2143 </div>
2117 2144 <ul>
2118 2145 <li><a href="/shortlog">log</a></li>
2119 2146 <li><a href="/graph">graph</a></li>
2120 2147 <li><a href="/tags">tags</a></li>
2121 2148 <li><a href="/bookmarks">bookmarks</a></li>
2122 2149 <li><a href="/branches">branches</a></li>
2123 2150 </ul>
2124 2151 <ul>
2125 2152 <li class="active"><a href="/help">help</a></li>
2126 2153 </ul>
2127 2154 </div>
2128 2155
2129 2156 <div class="main">
2130 2157 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2131 2158 <h3>Help: remove</h3>
2132 2159
2133 2160 <form class="search" action="/log">
2134 2161
2135 2162 <p><input name="rev" id="search1" type="text" size="30" /></p>
2136 2163 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2137 2164 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2138 2165 </form>
2139 2166 <div id="doc">
2140 2167 <p>
2141 2168 hg remove [OPTION]... FILE...
2142 2169 </p>
2143 2170 <p>
2144 2171 aliases: rm
2145 2172 </p>
2146 2173 <p>
2147 2174 remove the specified files on the next commit
2148 2175 </p>
2149 2176 <p>
2150 2177 Schedule the indicated files for removal from the current branch.
2151 2178 </p>
2152 2179 <p>
2153 2180 This command schedules the files to be removed at the next commit.
2154 2181 To undo a remove before that, see &quot;hg revert&quot;. To undo added
2155 2182 files, see &quot;hg forget&quot;.
2156 2183 </p>
2157 2184 <p>
2158 2185 -A/--after can be used to remove only files that have already
2159 2186 been deleted, -f/--force can be used to force deletion, and -Af
2160 2187 can be used to remove files from the next revision without
2161 2188 deleting them from the working directory.
2162 2189 </p>
2163 2190 <p>
2164 2191 The following table details the behavior of remove for different
2165 2192 file states (columns) and option combinations (rows). The file
2166 2193 states are Added [A], Clean [C], Modified [M] and Missing [!]
2167 2194 (as reported by &quot;hg status&quot;). The actions are Warn, Remove
2168 2195 (from branch) and Delete (from disk):
2169 2196 </p>
2170 2197 <table>
2171 2198 <tr><td>opt/state</td>
2172 2199 <td>A</td>
2173 2200 <td>C</td>
2174 2201 <td>M</td>
2175 2202 <td>!</td></tr>
2176 2203 <tr><td>none</td>
2177 2204 <td>W</td>
2178 2205 <td>RD</td>
2179 2206 <td>W</td>
2180 2207 <td>R</td></tr>
2181 2208 <tr><td>-f</td>
2182 2209 <td>R</td>
2183 2210 <td>RD</td>
2184 2211 <td>RD</td>
2185 2212 <td>R</td></tr>
2186 2213 <tr><td>-A</td>
2187 2214 <td>W</td>
2188 2215 <td>W</td>
2189 2216 <td>W</td>
2190 2217 <td>R</td></tr>
2191 2218 <tr><td>-Af</td>
2192 2219 <td>R</td>
2193 2220 <td>R</td>
2194 2221 <td>R</td>
2195 2222 <td>R</td></tr>
2196 2223 </table>
2197 2224 <p>
2198 2225 Note that remove never deletes files in Added [A] state from the
2199 2226 working directory, not even if option --force is specified.
2200 2227 </p>
2201 2228 <p>
2202 2229 Returns 0 on success, 1 if any warnings encountered.
2203 2230 </p>
2204 2231 <p>
2205 2232 options ([+] can be repeated):
2206 2233 </p>
2207 2234 <table>
2208 2235 <tr><td>-A</td>
2209 2236 <td>--after</td>
2210 2237 <td>record delete for missing files</td></tr>
2211 2238 <tr><td>-f</td>
2212 2239 <td>--force</td>
2213 2240 <td>remove (and delete) file even if added or modified</td></tr>
2214 2241 <tr><td>-S</td>
2215 2242 <td>--subrepos</td>
2216 2243 <td>recurse into subrepositories</td></tr>
2217 2244 <tr><td>-I</td>
2218 2245 <td>--include PATTERN [+]</td>
2219 2246 <td>include names matching the given patterns</td></tr>
2220 2247 <tr><td>-X</td>
2221 2248 <td>--exclude PATTERN [+]</td>
2222 2249 <td>exclude names matching the given patterns</td></tr>
2223 2250 </table>
2224 2251 <p>
2225 2252 global options ([+] can be repeated):
2226 2253 </p>
2227 2254 <table>
2228 2255 <tr><td>-R</td>
2229 2256 <td>--repository REPO</td>
2230 2257 <td>repository root directory or name of overlay bundle file</td></tr>
2231 2258 <tr><td></td>
2232 2259 <td>--cwd DIR</td>
2233 2260 <td>change working directory</td></tr>
2234 2261 <tr><td>-y</td>
2235 2262 <td>--noninteractive</td>
2236 2263 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2237 2264 <tr><td>-q</td>
2238 2265 <td>--quiet</td>
2239 2266 <td>suppress output</td></tr>
2240 2267 <tr><td>-v</td>
2241 2268 <td>--verbose</td>
2242 2269 <td>enable additional output</td></tr>
2243 2270 <tr><td></td>
2244 2271 <td>--config CONFIG [+]</td>
2245 2272 <td>set/override config option (use 'section.name=value')</td></tr>
2246 2273 <tr><td></td>
2247 2274 <td>--debug</td>
2248 2275 <td>enable debugging output</td></tr>
2249 2276 <tr><td></td>
2250 2277 <td>--debugger</td>
2251 2278 <td>start debugger</td></tr>
2252 2279 <tr><td></td>
2253 2280 <td>--encoding ENCODE</td>
2254 2281 <td>set the charset encoding (default: ascii)</td></tr>
2255 2282 <tr><td></td>
2256 2283 <td>--encodingmode MODE</td>
2257 2284 <td>set the charset encoding mode (default: strict)</td></tr>
2258 2285 <tr><td></td>
2259 2286 <td>--traceback</td>
2260 2287 <td>always print a traceback on exception</td></tr>
2261 2288 <tr><td></td>
2262 2289 <td>--time</td>
2263 2290 <td>time how long the command takes</td></tr>
2264 2291 <tr><td></td>
2265 2292 <td>--profile</td>
2266 2293 <td>print command execution profile</td></tr>
2267 2294 <tr><td></td>
2268 2295 <td>--version</td>
2269 2296 <td>output version information and exit</td></tr>
2270 2297 <tr><td>-h</td>
2271 2298 <td>--help</td>
2272 2299 <td>display help and exit</td></tr>
2273 2300 <tr><td></td>
2274 2301 <td>--hidden</td>
2275 2302 <td>consider hidden changesets</td></tr>
2276 2303 </table>
2277 2304
2278 2305 </div>
2279 2306 </div>
2280 2307 </div>
2281 2308
2282 2309 <script type="text/javascript">process_dates()</script>
2283 2310
2284 2311
2285 2312 </body>
2286 2313 </html>
2287 2314
2288 2315
2289 2316 $ get-with-headers.py 127.0.0.1:$HGPORT "help/revisions"
2290 2317 200 Script output follows
2291 2318
2292 2319 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2293 2320 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2294 2321 <head>
2295 2322 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2296 2323 <meta name="robots" content="index, nofollow" />
2297 2324 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2298 2325 <script type="text/javascript" src="/static/mercurial.js"></script>
2299 2326
2300 2327 <title>Help: revisions</title>
2301 2328 </head>
2302 2329 <body>
2303 2330
2304 2331 <div class="container">
2305 2332 <div class="menu">
2306 2333 <div class="logo">
2307 2334 <a href="https://mercurial-scm.org/">
2308 2335 <img src="/static/hglogo.png" alt="mercurial" /></a>
2309 2336 </div>
2310 2337 <ul>
2311 2338 <li><a href="/shortlog">log</a></li>
2312 2339 <li><a href="/graph">graph</a></li>
2313 2340 <li><a href="/tags">tags</a></li>
2314 2341 <li><a href="/bookmarks">bookmarks</a></li>
2315 2342 <li><a href="/branches">branches</a></li>
2316 2343 </ul>
2317 2344 <ul>
2318 2345 <li class="active"><a href="/help">help</a></li>
2319 2346 </ul>
2320 2347 </div>
2321 2348
2322 2349 <div class="main">
2323 2350 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2324 2351 <h3>Help: revisions</h3>
2325 2352
2326 2353 <form class="search" action="/log">
2327 2354
2328 2355 <p><input name="rev" id="search1" type="text" size="30" /></p>
2329 2356 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2330 2357 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2331 2358 </form>
2332 2359 <div id="doc">
2333 2360 <h1>Specifying Single Revisions</h1>
2334 2361 <p>
2335 2362 Mercurial supports several ways to specify individual revisions.
2336 2363 </p>
2337 2364 <p>
2338 2365 A plain integer is treated as a revision number. Negative integers are
2339 2366 treated as sequential offsets from the tip, with -1 denoting the tip,
2340 2367 -2 denoting the revision prior to the tip, and so forth.
2341 2368 </p>
2342 2369 <p>
2343 2370 A 40-digit hexadecimal string is treated as a unique revision
2344 2371 identifier.
2345 2372 </p>
2346 2373 <p>
2347 2374 A hexadecimal string less than 40 characters long is treated as a
2348 2375 unique revision identifier and is referred to as a short-form
2349 2376 identifier. A short-form identifier is only valid if it is the prefix
2350 2377 of exactly one full-length identifier.
2351 2378 </p>
2352 2379 <p>
2353 2380 Any other string is treated as a bookmark, tag, or branch name. A
2354 2381 bookmark is a movable pointer to a revision. A tag is a permanent name
2355 2382 associated with a revision. A branch name denotes the tipmost open branch head
2356 2383 of that branch - or if they are all closed, the tipmost closed head of the
2357 2384 branch. Bookmark, tag, and branch names must not contain the &quot;:&quot; character.
2358 2385 </p>
2359 2386 <p>
2360 2387 The reserved name &quot;tip&quot; always identifies the most recent revision.
2361 2388 </p>
2362 2389 <p>
2363 2390 The reserved name &quot;null&quot; indicates the null revision. This is the
2364 2391 revision of an empty repository, and the parent of revision 0.
2365 2392 </p>
2366 2393 <p>
2367 2394 The reserved name &quot;.&quot; indicates the working directory parent. If no
2368 2395 working directory is checked out, it is equivalent to null. If an
2369 2396 uncommitted merge is in progress, &quot;.&quot; is the revision of the first
2370 2397 parent.
2371 2398 </p>
2372 2399
2373 2400 </div>
2374 2401 </div>
2375 2402 </div>
2376 2403
2377 2404 <script type="text/javascript">process_dates()</script>
2378 2405
2379 2406
2380 2407 </body>
2381 2408 </html>
2382 2409
2383 2410
2384 2411 $ killdaemons.py
2385 2412
2386 2413 #endif
General Comments 0
You need to be logged in to leave comments. Login now