##// END OF EJS Templates
diff: add --from and --to flags as clearer alternative to -r -r...
Martin von Zweigbergk -
r46703:64292add default
parent child Browse files
Show More
@@ -1,7732 +1,7744 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 __future__ import absolute_import
9 9
10 10 import errno
11 11 import os
12 12 import re
13 13 import sys
14 14
15 15 from .i18n import _
16 16 from .node import (
17 17 hex,
18 18 nullid,
19 19 nullrev,
20 20 short,
21 21 wdirhex,
22 22 wdirrev,
23 23 )
24 24 from .pycompat import open
25 25 from . import (
26 26 archival,
27 27 bookmarks,
28 28 bundle2,
29 29 bundlecaches,
30 30 changegroup,
31 31 cmdutil,
32 32 copies,
33 33 debugcommands as debugcommandsmod,
34 34 destutil,
35 35 dirstateguard,
36 36 discovery,
37 37 encoding,
38 38 error,
39 39 exchange,
40 40 extensions,
41 41 filemerge,
42 42 formatter,
43 43 graphmod,
44 44 grep as grepmod,
45 45 hbisect,
46 46 help,
47 47 hg,
48 48 logcmdutil,
49 49 merge as mergemod,
50 50 mergestate as mergestatemod,
51 51 narrowspec,
52 52 obsolete,
53 53 obsutil,
54 54 patch,
55 55 phases,
56 56 pycompat,
57 57 rcutil,
58 58 registrar,
59 59 requirements,
60 60 revsetlang,
61 61 rewriteutil,
62 62 scmutil,
63 63 server,
64 64 shelve as shelvemod,
65 65 state as statemod,
66 66 streamclone,
67 67 tags as tagsmod,
68 68 ui as uimod,
69 69 util,
70 70 verify as verifymod,
71 71 vfs as vfsmod,
72 72 wireprotoserver,
73 73 )
74 74 from .utils import (
75 75 dateutil,
76 76 stringutil,
77 77 )
78 78
79 79 table = {}
80 80 table.update(debugcommandsmod.command._table)
81 81
82 82 command = registrar.command(table)
83 83 INTENT_READONLY = registrar.INTENT_READONLY
84 84
85 85 # common command options
86 86
87 87 globalopts = [
88 88 (
89 89 b'R',
90 90 b'repository',
91 91 b'',
92 92 _(b'repository root directory or name of overlay bundle file'),
93 93 _(b'REPO'),
94 94 ),
95 95 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
96 96 (
97 97 b'y',
98 98 b'noninteractive',
99 99 None,
100 100 _(
101 101 b'do not prompt, automatically pick the first choice for all prompts'
102 102 ),
103 103 ),
104 104 (b'q', b'quiet', None, _(b'suppress output')),
105 105 (b'v', b'verbose', None, _(b'enable additional output')),
106 106 (
107 107 b'',
108 108 b'color',
109 109 b'',
110 110 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
111 111 # and should not be translated
112 112 _(b"when to colorize (boolean, always, auto, never, or debug)"),
113 113 _(b'TYPE'),
114 114 ),
115 115 (
116 116 b'',
117 117 b'config',
118 118 [],
119 119 _(b'set/override config option (use \'section.name=value\')'),
120 120 _(b'CONFIG'),
121 121 ),
122 122 (b'', b'debug', None, _(b'enable debugging output')),
123 123 (b'', b'debugger', None, _(b'start debugger')),
124 124 (
125 125 b'',
126 126 b'encoding',
127 127 encoding.encoding,
128 128 _(b'set the charset encoding'),
129 129 _(b'ENCODE'),
130 130 ),
131 131 (
132 132 b'',
133 133 b'encodingmode',
134 134 encoding.encodingmode,
135 135 _(b'set the charset encoding mode'),
136 136 _(b'MODE'),
137 137 ),
138 138 (b'', b'traceback', None, _(b'always print a traceback on exception')),
139 139 (b'', b'time', None, _(b'time how long the command takes')),
140 140 (b'', b'profile', None, _(b'print command execution profile')),
141 141 (b'', b'version', None, _(b'output version information and exit')),
142 142 (b'h', b'help', None, _(b'display help and exit')),
143 143 (b'', b'hidden', False, _(b'consider hidden changesets')),
144 144 (
145 145 b'',
146 146 b'pager',
147 147 b'auto',
148 148 _(b"when to paginate (boolean, always, auto, or never)"),
149 149 _(b'TYPE'),
150 150 ),
151 151 ]
152 152
153 153 dryrunopts = cmdutil.dryrunopts
154 154 remoteopts = cmdutil.remoteopts
155 155 walkopts = cmdutil.walkopts
156 156 commitopts = cmdutil.commitopts
157 157 commitopts2 = cmdutil.commitopts2
158 158 commitopts3 = cmdutil.commitopts3
159 159 formatteropts = cmdutil.formatteropts
160 160 templateopts = cmdutil.templateopts
161 161 logopts = cmdutil.logopts
162 162 diffopts = cmdutil.diffopts
163 163 diffwsopts = cmdutil.diffwsopts
164 164 diffopts2 = cmdutil.diffopts2
165 165 mergetoolopts = cmdutil.mergetoolopts
166 166 similarityopts = cmdutil.similarityopts
167 167 subrepoopts = cmdutil.subrepoopts
168 168 debugrevlogopts = cmdutil.debugrevlogopts
169 169
170 170 # Commands start here, listed alphabetically
171 171
172 172
173 173 @command(
174 174 b'abort',
175 175 dryrunopts,
176 176 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
177 177 helpbasic=True,
178 178 )
179 179 def abort(ui, repo, **opts):
180 180 """abort an unfinished operation (EXPERIMENTAL)
181 181
182 182 Aborts a multistep operation like graft, histedit, rebase, merge,
183 183 and unshelve if they are in an unfinished state.
184 184
185 185 use --dry-run/-n to dry run the command.
186 186 """
187 187 dryrun = opts.get('dry_run')
188 188 abortstate = cmdutil.getunfinishedstate(repo)
189 189 if not abortstate:
190 190 raise error.StateError(_(b'no operation in progress'))
191 191 if not abortstate.abortfunc:
192 192 raise error.InputError(
193 193 (
194 194 _(b"%s in progress but does not support 'hg abort'")
195 195 % (abortstate._opname)
196 196 ),
197 197 hint=abortstate.hint(),
198 198 )
199 199 if dryrun:
200 200 ui.status(
201 201 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
202 202 )
203 203 return
204 204 return abortstate.abortfunc(ui, repo)
205 205
206 206
207 207 @command(
208 208 b'add',
209 209 walkopts + subrepoopts + dryrunopts,
210 210 _(b'[OPTION]... [FILE]...'),
211 211 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
212 212 helpbasic=True,
213 213 inferrepo=True,
214 214 )
215 215 def add(ui, repo, *pats, **opts):
216 216 """add the specified files on the next commit
217 217
218 218 Schedule files to be version controlled and added to the
219 219 repository.
220 220
221 221 The files will be added to the repository at the next commit. To
222 222 undo an add before that, see :hg:`forget`.
223 223
224 224 If no names are given, add all files to the repository (except
225 225 files matching ``.hgignore``).
226 226
227 227 .. container:: verbose
228 228
229 229 Examples:
230 230
231 231 - New (unknown) files are added
232 232 automatically by :hg:`add`::
233 233
234 234 $ ls
235 235 foo.c
236 236 $ hg status
237 237 ? foo.c
238 238 $ hg add
239 239 adding foo.c
240 240 $ hg status
241 241 A foo.c
242 242
243 243 - Specific files to be added can be specified::
244 244
245 245 $ ls
246 246 bar.c foo.c
247 247 $ hg status
248 248 ? bar.c
249 249 ? foo.c
250 250 $ hg add bar.c
251 251 $ hg status
252 252 A bar.c
253 253 ? foo.c
254 254
255 255 Returns 0 if all files are successfully added.
256 256 """
257 257
258 258 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
259 259 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
260 260 rejected = cmdutil.add(ui, repo, m, b"", uipathfn, False, **opts)
261 261 return rejected and 1 or 0
262 262
263 263
264 264 @command(
265 265 b'addremove',
266 266 similarityopts + subrepoopts + walkopts + dryrunopts,
267 267 _(b'[OPTION]... [FILE]...'),
268 268 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
269 269 inferrepo=True,
270 270 )
271 271 def addremove(ui, repo, *pats, **opts):
272 272 """add all new files, delete all missing files
273 273
274 274 Add all new files and remove all missing files from the
275 275 repository.
276 276
277 277 Unless names are given, new files are ignored if they match any of
278 278 the patterns in ``.hgignore``. As with add, these changes take
279 279 effect at the next commit.
280 280
281 281 Use the -s/--similarity option to detect renamed files. This
282 282 option takes a percentage between 0 (disabled) and 100 (files must
283 283 be identical) as its parameter. With a parameter greater than 0,
284 284 this compares every removed file with every added file and records
285 285 those similar enough as renames. Detecting renamed files this way
286 286 can be expensive. After using this option, :hg:`status -C` can be
287 287 used to check which files were identified as moved or renamed. If
288 288 not specified, -s/--similarity defaults to 100 and only renames of
289 289 identical files are detected.
290 290
291 291 .. container:: verbose
292 292
293 293 Examples:
294 294
295 295 - A number of files (bar.c and foo.c) are new,
296 296 while foobar.c has been removed (without using :hg:`remove`)
297 297 from the repository::
298 298
299 299 $ ls
300 300 bar.c foo.c
301 301 $ hg status
302 302 ! foobar.c
303 303 ? bar.c
304 304 ? foo.c
305 305 $ hg addremove
306 306 adding bar.c
307 307 adding foo.c
308 308 removing foobar.c
309 309 $ hg status
310 310 A bar.c
311 311 A foo.c
312 312 R foobar.c
313 313
314 314 - A file foobar.c was moved to foo.c without using :hg:`rename`.
315 315 Afterwards, it was edited slightly::
316 316
317 317 $ ls
318 318 foo.c
319 319 $ hg status
320 320 ! foobar.c
321 321 ? foo.c
322 322 $ hg addremove --similarity 90
323 323 removing foobar.c
324 324 adding foo.c
325 325 recording removal of foobar.c as rename to foo.c (94% similar)
326 326 $ hg status -C
327 327 A foo.c
328 328 foobar.c
329 329 R foobar.c
330 330
331 331 Returns 0 if all files are successfully added.
332 332 """
333 333 opts = pycompat.byteskwargs(opts)
334 334 if not opts.get(b'similarity'):
335 335 opts[b'similarity'] = b'100'
336 336 matcher = scmutil.match(repo[None], pats, opts)
337 337 relative = scmutil.anypats(pats, opts)
338 338 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
339 339 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
340 340
341 341
342 342 @command(
343 343 b'annotate|blame',
344 344 [
345 345 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
346 346 (
347 347 b'',
348 348 b'follow',
349 349 None,
350 350 _(b'follow copies/renames and list the filename (DEPRECATED)'),
351 351 ),
352 352 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
353 353 (b'a', b'text', None, _(b'treat all files as text')),
354 354 (b'u', b'user', None, _(b'list the author (long with -v)')),
355 355 (b'f', b'file', None, _(b'list the filename')),
356 356 (b'd', b'date', None, _(b'list the date (short with -q)')),
357 357 (b'n', b'number', None, _(b'list the revision number (default)')),
358 358 (b'c', b'changeset', None, _(b'list the changeset')),
359 359 (
360 360 b'l',
361 361 b'line-number',
362 362 None,
363 363 _(b'show line number at the first appearance'),
364 364 ),
365 365 (
366 366 b'',
367 367 b'skip',
368 368 [],
369 369 _(b'revset to not display (EXPERIMENTAL)'),
370 370 _(b'REV'),
371 371 ),
372 372 ]
373 373 + diffwsopts
374 374 + walkopts
375 375 + formatteropts,
376 376 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
377 377 helpcategory=command.CATEGORY_FILE_CONTENTS,
378 378 helpbasic=True,
379 379 inferrepo=True,
380 380 )
381 381 def annotate(ui, repo, *pats, **opts):
382 382 """show changeset information by line for each file
383 383
384 384 List changes in files, showing the revision id responsible for
385 385 each line.
386 386
387 387 This command is useful for discovering when a change was made and
388 388 by whom.
389 389
390 390 If you include --file, --user, or --date, the revision number is
391 391 suppressed unless you also include --number.
392 392
393 393 Without the -a/--text option, annotate will avoid processing files
394 394 it detects as binary. With -a, annotate will annotate the file
395 395 anyway, although the results will probably be neither useful
396 396 nor desirable.
397 397
398 398 .. container:: verbose
399 399
400 400 Template:
401 401
402 402 The following keywords are supported in addition to the common template
403 403 keywords and functions. See also :hg:`help templates`.
404 404
405 405 :lines: List of lines with annotation data.
406 406 :path: String. Repository-absolute path of the specified file.
407 407
408 408 And each entry of ``{lines}`` provides the following sub-keywords in
409 409 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
410 410
411 411 :line: String. Line content.
412 412 :lineno: Integer. Line number at that revision.
413 413 :path: String. Repository-absolute path of the file at that revision.
414 414
415 415 See :hg:`help templates.operators` for the list expansion syntax.
416 416
417 417 Returns 0 on success.
418 418 """
419 419 opts = pycompat.byteskwargs(opts)
420 420 if not pats:
421 421 raise error.InputError(
422 422 _(b'at least one filename or pattern is required')
423 423 )
424 424
425 425 if opts.get(b'follow'):
426 426 # --follow is deprecated and now just an alias for -f/--file
427 427 # to mimic the behavior of Mercurial before version 1.5
428 428 opts[b'file'] = True
429 429
430 430 if (
431 431 not opts.get(b'user')
432 432 and not opts.get(b'changeset')
433 433 and not opts.get(b'date')
434 434 and not opts.get(b'file')
435 435 ):
436 436 opts[b'number'] = True
437 437
438 438 linenumber = opts.get(b'line_number') is not None
439 439 if (
440 440 linenumber
441 441 and (not opts.get(b'changeset'))
442 442 and (not opts.get(b'number'))
443 443 ):
444 444 raise error.InputError(_(b'at least one of -n/-c is required for -l'))
445 445
446 446 rev = opts.get(b'rev')
447 447 if rev:
448 448 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
449 449 ctx = scmutil.revsingle(repo, rev)
450 450
451 451 ui.pager(b'annotate')
452 452 rootfm = ui.formatter(b'annotate', opts)
453 453 if ui.debugflag:
454 454 shorthex = pycompat.identity
455 455 else:
456 456
457 457 def shorthex(h):
458 458 return h[:12]
459 459
460 460 if ui.quiet:
461 461 datefunc = dateutil.shortdate
462 462 else:
463 463 datefunc = dateutil.datestr
464 464 if ctx.rev() is None:
465 465 if opts.get(b'changeset'):
466 466 # omit "+" suffix which is appended to node hex
467 467 def formatrev(rev):
468 468 if rev == wdirrev:
469 469 return b'%d' % ctx.p1().rev()
470 470 else:
471 471 return b'%d' % rev
472 472
473 473 else:
474 474
475 475 def formatrev(rev):
476 476 if rev == wdirrev:
477 477 return b'%d+' % ctx.p1().rev()
478 478 else:
479 479 return b'%d ' % rev
480 480
481 481 def formathex(h):
482 482 if h == wdirhex:
483 483 return b'%s+' % shorthex(hex(ctx.p1().node()))
484 484 else:
485 485 return b'%s ' % shorthex(h)
486 486
487 487 else:
488 488 formatrev = b'%d'.__mod__
489 489 formathex = shorthex
490 490
491 491 opmap = [
492 492 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
493 493 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
494 494 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
495 495 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
496 496 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
497 497 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
498 498 ]
499 499 opnamemap = {
500 500 b'rev': b'number',
501 501 b'node': b'changeset',
502 502 b'path': b'file',
503 503 b'lineno': b'line_number',
504 504 }
505 505
506 506 if rootfm.isplain():
507 507
508 508 def makefunc(get, fmt):
509 509 return lambda x: fmt(get(x))
510 510
511 511 else:
512 512
513 513 def makefunc(get, fmt):
514 514 return get
515 515
516 516 datahint = rootfm.datahint()
517 517 funcmap = [
518 518 (makefunc(get, fmt), sep)
519 519 for fn, sep, get, fmt in opmap
520 520 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
521 521 ]
522 522 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
523 523 fields = b' '.join(
524 524 fn
525 525 for fn, sep, get, fmt in opmap
526 526 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
527 527 )
528 528
529 529 def bad(x, y):
530 530 raise error.Abort(b"%s: %s" % (x, y))
531 531
532 532 m = scmutil.match(ctx, pats, opts, badfn=bad)
533 533
534 534 follow = not opts.get(b'no_follow')
535 535 diffopts = patch.difffeatureopts(
536 536 ui, opts, section=b'annotate', whitespace=True
537 537 )
538 538 skiprevs = opts.get(b'skip')
539 539 if skiprevs:
540 540 skiprevs = scmutil.revrange(repo, skiprevs)
541 541
542 542 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
543 543 for abs in ctx.walk(m):
544 544 fctx = ctx[abs]
545 545 rootfm.startitem()
546 546 rootfm.data(path=abs)
547 547 if not opts.get(b'text') and fctx.isbinary():
548 548 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
549 549 continue
550 550
551 551 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
552 552 lines = fctx.annotate(
553 553 follow=follow, skiprevs=skiprevs, diffopts=diffopts
554 554 )
555 555 if not lines:
556 556 fm.end()
557 557 continue
558 558 formats = []
559 559 pieces = []
560 560
561 561 for f, sep in funcmap:
562 562 l = [f(n) for n in lines]
563 563 if fm.isplain():
564 564 sizes = [encoding.colwidth(x) for x in l]
565 565 ml = max(sizes)
566 566 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
567 567 else:
568 568 formats.append([b'%s'] * len(l))
569 569 pieces.append(l)
570 570
571 571 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
572 572 fm.startitem()
573 573 fm.context(fctx=n.fctx)
574 574 fm.write(fields, b"".join(f), *p)
575 575 if n.skip:
576 576 fmt = b"* %s"
577 577 else:
578 578 fmt = b": %s"
579 579 fm.write(b'line', fmt, n.text)
580 580
581 581 if not lines[-1].text.endswith(b'\n'):
582 582 fm.plain(b'\n')
583 583 fm.end()
584 584
585 585 rootfm.end()
586 586
587 587
588 588 @command(
589 589 b'archive',
590 590 [
591 591 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
592 592 (
593 593 b'p',
594 594 b'prefix',
595 595 b'',
596 596 _(b'directory prefix for files in archive'),
597 597 _(b'PREFIX'),
598 598 ),
599 599 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
600 600 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
601 601 ]
602 602 + subrepoopts
603 603 + walkopts,
604 604 _(b'[OPTION]... DEST'),
605 605 helpcategory=command.CATEGORY_IMPORT_EXPORT,
606 606 )
607 607 def archive(ui, repo, dest, **opts):
608 608 """create an unversioned archive of a repository revision
609 609
610 610 By default, the revision used is the parent of the working
611 611 directory; use -r/--rev to specify a different revision.
612 612
613 613 The archive type is automatically detected based on file
614 614 extension (to override, use -t/--type).
615 615
616 616 .. container:: verbose
617 617
618 618 Examples:
619 619
620 620 - create a zip file containing the 1.0 release::
621 621
622 622 hg archive -r 1.0 project-1.0.zip
623 623
624 624 - create a tarball excluding .hg files::
625 625
626 626 hg archive project.tar.gz -X ".hg*"
627 627
628 628 Valid types are:
629 629
630 630 :``files``: a directory full of files (default)
631 631 :``tar``: tar archive, uncompressed
632 632 :``tbz2``: tar archive, compressed using bzip2
633 633 :``tgz``: tar archive, compressed using gzip
634 634 :``txz``: tar archive, compressed using lzma (only in Python 3)
635 635 :``uzip``: zip archive, uncompressed
636 636 :``zip``: zip archive, compressed using deflate
637 637
638 638 The exact name of the destination archive or directory is given
639 639 using a format string; see :hg:`help export` for details.
640 640
641 641 Each member added to an archive file has a directory prefix
642 642 prepended. Use -p/--prefix to specify a format string for the
643 643 prefix. The default is the basename of the archive, with suffixes
644 644 removed.
645 645
646 646 Returns 0 on success.
647 647 """
648 648
649 649 opts = pycompat.byteskwargs(opts)
650 650 rev = opts.get(b'rev')
651 651 if rev:
652 652 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
653 653 ctx = scmutil.revsingle(repo, rev)
654 654 if not ctx:
655 655 raise error.InputError(
656 656 _(b'no working directory: please specify a revision')
657 657 )
658 658 node = ctx.node()
659 659 dest = cmdutil.makefilename(ctx, dest)
660 660 if os.path.realpath(dest) == repo.root:
661 661 raise error.InputError(_(b'repository root cannot be destination'))
662 662
663 663 kind = opts.get(b'type') or archival.guesskind(dest) or b'files'
664 664 prefix = opts.get(b'prefix')
665 665
666 666 if dest == b'-':
667 667 if kind == b'files':
668 668 raise error.InputError(_(b'cannot archive plain files to stdout'))
669 669 dest = cmdutil.makefileobj(ctx, dest)
670 670 if not prefix:
671 671 prefix = os.path.basename(repo.root) + b'-%h'
672 672
673 673 prefix = cmdutil.makefilename(ctx, prefix)
674 674 match = scmutil.match(ctx, [], opts)
675 675 archival.archive(
676 676 repo,
677 677 dest,
678 678 node,
679 679 kind,
680 680 not opts.get(b'no_decode'),
681 681 match,
682 682 prefix,
683 683 subrepos=opts.get(b'subrepos'),
684 684 )
685 685
686 686
687 687 @command(
688 688 b'backout',
689 689 [
690 690 (
691 691 b'',
692 692 b'merge',
693 693 None,
694 694 _(b'merge with old dirstate parent after backout'),
695 695 ),
696 696 (
697 697 b'',
698 698 b'commit',
699 699 None,
700 700 _(b'commit if no conflicts were encountered (DEPRECATED)'),
701 701 ),
702 702 (b'', b'no-commit', None, _(b'do not commit')),
703 703 (
704 704 b'',
705 705 b'parent',
706 706 b'',
707 707 _(b'parent to choose when backing out merge (DEPRECATED)'),
708 708 _(b'REV'),
709 709 ),
710 710 (b'r', b'rev', b'', _(b'revision to backout'), _(b'REV')),
711 711 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
712 712 ]
713 713 + mergetoolopts
714 714 + walkopts
715 715 + commitopts
716 716 + commitopts2,
717 717 _(b'[OPTION]... [-r] REV'),
718 718 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
719 719 )
720 720 def backout(ui, repo, node=None, rev=None, **opts):
721 721 """reverse effect of earlier changeset
722 722
723 723 Prepare a new changeset with the effect of REV undone in the
724 724 current working directory. If no conflicts were encountered,
725 725 it will be committed immediately.
726 726
727 727 If REV is the parent of the working directory, then this new changeset
728 728 is committed automatically (unless --no-commit is specified).
729 729
730 730 .. note::
731 731
732 732 :hg:`backout` cannot be used to fix either an unwanted or
733 733 incorrect merge.
734 734
735 735 .. container:: verbose
736 736
737 737 Examples:
738 738
739 739 - Reverse the effect of the parent of the working directory.
740 740 This backout will be committed immediately::
741 741
742 742 hg backout -r .
743 743
744 744 - Reverse the effect of previous bad revision 23::
745 745
746 746 hg backout -r 23
747 747
748 748 - Reverse the effect of previous bad revision 23 and
749 749 leave changes uncommitted::
750 750
751 751 hg backout -r 23 --no-commit
752 752 hg commit -m "Backout revision 23"
753 753
754 754 By default, the pending changeset will have one parent,
755 755 maintaining a linear history. With --merge, the pending
756 756 changeset will instead have two parents: the old parent of the
757 757 working directory and a new child of REV that simply undoes REV.
758 758
759 759 Before version 1.7, the behavior without --merge was equivalent
760 760 to specifying --merge followed by :hg:`update --clean .` to
761 761 cancel the merge and leave the child of REV as a head to be
762 762 merged separately.
763 763
764 764 See :hg:`help dates` for a list of formats valid for -d/--date.
765 765
766 766 See :hg:`help revert` for a way to restore files to the state
767 767 of another revision.
768 768
769 769 Returns 0 on success, 1 if nothing to backout or there are unresolved
770 770 files.
771 771 """
772 772 with repo.wlock(), repo.lock():
773 773 return _dobackout(ui, repo, node, rev, **opts)
774 774
775 775
776 776 def _dobackout(ui, repo, node=None, rev=None, **opts):
777 777 cmdutil.check_incompatible_arguments(opts, 'no_commit', ['commit', 'merge'])
778 778 opts = pycompat.byteskwargs(opts)
779 779
780 780 if rev and node:
781 781 raise error.InputError(_(b"please specify just one revision"))
782 782
783 783 if not rev:
784 784 rev = node
785 785
786 786 if not rev:
787 787 raise error.InputError(_(b"please specify a revision to backout"))
788 788
789 789 date = opts.get(b'date')
790 790 if date:
791 791 opts[b'date'] = dateutil.parsedate(date)
792 792
793 793 cmdutil.checkunfinished(repo)
794 794 cmdutil.bailifchanged(repo)
795 795 ctx = scmutil.revsingle(repo, rev)
796 796 node = ctx.node()
797 797
798 798 op1, op2 = repo.dirstate.parents()
799 799 if not repo.changelog.isancestor(node, op1):
800 800 raise error.InputError(
801 801 _(b'cannot backout change that is not an ancestor')
802 802 )
803 803
804 804 p1, p2 = repo.changelog.parents(node)
805 805 if p1 == nullid:
806 806 raise error.InputError(_(b'cannot backout a change with no parents'))
807 807 if p2 != nullid:
808 808 if not opts.get(b'parent'):
809 809 raise error.InputError(_(b'cannot backout a merge changeset'))
810 810 p = repo.lookup(opts[b'parent'])
811 811 if p not in (p1, p2):
812 812 raise error.InputError(
813 813 _(b'%s is not a parent of %s') % (short(p), short(node))
814 814 )
815 815 parent = p
816 816 else:
817 817 if opts.get(b'parent'):
818 818 raise error.InputError(
819 819 _(b'cannot use --parent on non-merge changeset')
820 820 )
821 821 parent = p1
822 822
823 823 # the backout should appear on the same branch
824 824 branch = repo.dirstate.branch()
825 825 bheads = repo.branchheads(branch)
826 826 rctx = scmutil.revsingle(repo, hex(parent))
827 827 if not opts.get(b'merge') and op1 != node:
828 828 with dirstateguard.dirstateguard(repo, b'backout'):
829 829 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
830 830 with ui.configoverride(overrides, b'backout'):
831 831 stats = mergemod.back_out(ctx, parent=repo[parent])
832 832 repo.setparents(op1, op2)
833 833 hg._showstats(repo, stats)
834 834 if stats.unresolvedcount:
835 835 repo.ui.status(
836 836 _(b"use 'hg resolve' to retry unresolved file merges\n")
837 837 )
838 838 return 1
839 839 else:
840 840 hg.clean(repo, node, show_stats=False)
841 841 repo.dirstate.setbranch(branch)
842 842 cmdutil.revert(ui, repo, rctx)
843 843
844 844 if opts.get(b'no_commit'):
845 845 msg = _(b"changeset %s backed out, don't forget to commit.\n")
846 846 ui.status(msg % short(node))
847 847 return 0
848 848
849 849 def commitfunc(ui, repo, message, match, opts):
850 850 editform = b'backout'
851 851 e = cmdutil.getcommiteditor(
852 852 editform=editform, **pycompat.strkwargs(opts)
853 853 )
854 854 if not message:
855 855 # we don't translate commit messages
856 856 message = b"Backed out changeset %s" % short(node)
857 857 e = cmdutil.getcommiteditor(edit=True, editform=editform)
858 858 return repo.commit(
859 859 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
860 860 )
861 861
862 862 # save to detect changes
863 863 tip = repo.changelog.tip()
864 864
865 865 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
866 866 if not newnode:
867 867 ui.status(_(b"nothing changed\n"))
868 868 return 1
869 869 cmdutil.commitstatus(repo, newnode, branch, bheads, tip)
870 870
871 871 def nice(node):
872 872 return b'%d:%s' % (repo.changelog.rev(node), short(node))
873 873
874 874 ui.status(
875 875 _(b'changeset %s backs out changeset %s\n')
876 876 % (nice(newnode), nice(node))
877 877 )
878 878 if opts.get(b'merge') and op1 != node:
879 879 hg.clean(repo, op1, show_stats=False)
880 880 ui.status(_(b'merging with changeset %s\n') % nice(newnode))
881 881 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
882 882 with ui.configoverride(overrides, b'backout'):
883 883 return hg.merge(repo[b'tip'])
884 884 return 0
885 885
886 886
887 887 @command(
888 888 b'bisect',
889 889 [
890 890 (b'r', b'reset', False, _(b'reset bisect state')),
891 891 (b'g', b'good', False, _(b'mark changeset good')),
892 892 (b'b', b'bad', False, _(b'mark changeset bad')),
893 893 (b's', b'skip', False, _(b'skip testing changeset')),
894 894 (b'e', b'extend', False, _(b'extend the bisect range')),
895 895 (
896 896 b'c',
897 897 b'command',
898 898 b'',
899 899 _(b'use command to check changeset state'),
900 900 _(b'CMD'),
901 901 ),
902 902 (b'U', b'noupdate', False, _(b'do not update to target')),
903 903 ],
904 904 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
905 905 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
906 906 )
907 907 def bisect(
908 908 ui,
909 909 repo,
910 910 positional_1=None,
911 911 positional_2=None,
912 912 command=None,
913 913 reset=None,
914 914 good=None,
915 915 bad=None,
916 916 skip=None,
917 917 extend=None,
918 918 noupdate=None,
919 919 ):
920 920 """subdivision search of changesets
921 921
922 922 This command helps to find changesets which introduce problems. To
923 923 use, mark the earliest changeset you know exhibits the problem as
924 924 bad, then mark the latest changeset which is free from the problem
925 925 as good. Bisect will update your working directory to a revision
926 926 for testing (unless the -U/--noupdate option is specified). Once
927 927 you have performed tests, mark the working directory as good or
928 928 bad, and bisect will either update to another candidate changeset
929 929 or announce that it has found the bad revision.
930 930
931 931 As a shortcut, you can also use the revision argument to mark a
932 932 revision as good or bad without checking it out first.
933 933
934 934 If you supply a command, it will be used for automatic bisection.
935 935 The environment variable HG_NODE will contain the ID of the
936 936 changeset being tested. The exit status of the command will be
937 937 used to mark revisions as good or bad: status 0 means good, 125
938 938 means to skip the revision, 127 (command not found) will abort the
939 939 bisection, and any other non-zero exit status means the revision
940 940 is bad.
941 941
942 942 .. container:: verbose
943 943
944 944 Some examples:
945 945
946 946 - start a bisection with known bad revision 34, and good revision 12::
947 947
948 948 hg bisect --bad 34
949 949 hg bisect --good 12
950 950
951 951 - advance the current bisection by marking current revision as good or
952 952 bad::
953 953
954 954 hg bisect --good
955 955 hg bisect --bad
956 956
957 957 - mark the current revision, or a known revision, to be skipped (e.g. if
958 958 that revision is not usable because of another issue)::
959 959
960 960 hg bisect --skip
961 961 hg bisect --skip 23
962 962
963 963 - skip all revisions that do not touch directories ``foo`` or ``bar``::
964 964
965 965 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
966 966
967 967 - forget the current bisection::
968 968
969 969 hg bisect --reset
970 970
971 971 - use 'make && make tests' to automatically find the first broken
972 972 revision::
973 973
974 974 hg bisect --reset
975 975 hg bisect --bad 34
976 976 hg bisect --good 12
977 977 hg bisect --command "make && make tests"
978 978
979 979 - see all changesets whose states are already known in the current
980 980 bisection::
981 981
982 982 hg log -r "bisect(pruned)"
983 983
984 984 - see the changeset currently being bisected (especially useful
985 985 if running with -U/--noupdate)::
986 986
987 987 hg log -r "bisect(current)"
988 988
989 989 - see all changesets that took part in the current bisection::
990 990
991 991 hg log -r "bisect(range)"
992 992
993 993 - you can even get a nice graph::
994 994
995 995 hg log --graph -r "bisect(range)"
996 996
997 997 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
998 998
999 999 Returns 0 on success.
1000 1000 """
1001 1001 rev = []
1002 1002 # backward compatibility
1003 1003 if positional_1 in (b"good", b"bad", b"reset", b"init"):
1004 1004 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
1005 1005 cmd = positional_1
1006 1006 rev.append(positional_2)
1007 1007 if cmd == b"good":
1008 1008 good = True
1009 1009 elif cmd == b"bad":
1010 1010 bad = True
1011 1011 else:
1012 1012 reset = True
1013 1013 elif positional_2:
1014 1014 raise error.InputError(_(b'incompatible arguments'))
1015 1015 elif positional_1 is not None:
1016 1016 rev.append(positional_1)
1017 1017
1018 1018 incompatibles = {
1019 1019 b'--bad': bad,
1020 1020 b'--command': bool(command),
1021 1021 b'--extend': extend,
1022 1022 b'--good': good,
1023 1023 b'--reset': reset,
1024 1024 b'--skip': skip,
1025 1025 }
1026 1026
1027 1027 enabled = [x for x in incompatibles if incompatibles[x]]
1028 1028
1029 1029 if len(enabled) > 1:
1030 1030 raise error.InputError(
1031 1031 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1032 1032 )
1033 1033
1034 1034 if reset:
1035 1035 hbisect.resetstate(repo)
1036 1036 return
1037 1037
1038 1038 state = hbisect.load_state(repo)
1039 1039
1040 1040 if rev:
1041 1041 nodes = [repo[i].node() for i in scmutil.revrange(repo, rev)]
1042 1042 else:
1043 1043 nodes = [repo.lookup(b'.')]
1044 1044
1045 1045 # update state
1046 1046 if good or bad or skip:
1047 1047 if good:
1048 1048 state[b'good'] += nodes
1049 1049 elif bad:
1050 1050 state[b'bad'] += nodes
1051 1051 elif skip:
1052 1052 state[b'skip'] += nodes
1053 1053 hbisect.save_state(repo, state)
1054 1054 if not (state[b'good'] and state[b'bad']):
1055 1055 return
1056 1056
1057 1057 def mayupdate(repo, node, show_stats=True):
1058 1058 """common used update sequence"""
1059 1059 if noupdate:
1060 1060 return
1061 1061 cmdutil.checkunfinished(repo)
1062 1062 cmdutil.bailifchanged(repo)
1063 1063 return hg.clean(repo, node, show_stats=show_stats)
1064 1064
1065 1065 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1066 1066
1067 1067 if command:
1068 1068 changesets = 1
1069 1069 if noupdate:
1070 1070 try:
1071 1071 node = state[b'current'][0]
1072 1072 except LookupError:
1073 1073 raise error.StateError(
1074 1074 _(
1075 1075 b'current bisect revision is unknown - '
1076 1076 b'start a new bisect to fix'
1077 1077 )
1078 1078 )
1079 1079 else:
1080 1080 node, p2 = repo.dirstate.parents()
1081 1081 if p2 != nullid:
1082 1082 raise error.StateError(_(b'current bisect revision is a merge'))
1083 1083 if rev:
1084 1084 if not nodes:
1085 1085 raise error.Abort(_(b'empty revision set'))
1086 1086 node = repo[nodes.last()].node()
1087 1087 with hbisect.restore_state(repo, state, node):
1088 1088 while changesets:
1089 1089 # update state
1090 1090 state[b'current'] = [node]
1091 1091 hbisect.save_state(repo, state)
1092 1092 status = ui.system(
1093 1093 command,
1094 1094 environ={b'HG_NODE': hex(node)},
1095 1095 blockedtag=b'bisect_check',
1096 1096 )
1097 1097 if status == 125:
1098 1098 transition = b"skip"
1099 1099 elif status == 0:
1100 1100 transition = b"good"
1101 1101 # status < 0 means process was killed
1102 1102 elif status == 127:
1103 1103 raise error.Abort(_(b"failed to execute %s") % command)
1104 1104 elif status < 0:
1105 1105 raise error.Abort(_(b"%s killed") % command)
1106 1106 else:
1107 1107 transition = b"bad"
1108 1108 state[transition].append(node)
1109 1109 ctx = repo[node]
1110 1110 ui.status(
1111 1111 _(b'changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
1112 1112 )
1113 1113 hbisect.checkstate(state)
1114 1114 # bisect
1115 1115 nodes, changesets, bgood = hbisect.bisect(repo, state)
1116 1116 # update to next check
1117 1117 node = nodes[0]
1118 1118 mayupdate(repo, node, show_stats=False)
1119 1119 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1120 1120 return
1121 1121
1122 1122 hbisect.checkstate(state)
1123 1123
1124 1124 # actually bisect
1125 1125 nodes, changesets, good = hbisect.bisect(repo, state)
1126 1126 if extend:
1127 1127 if not changesets:
1128 1128 extendnode = hbisect.extendrange(repo, state, nodes, good)
1129 1129 if extendnode is not None:
1130 1130 ui.write(
1131 1131 _(b"Extending search to changeset %d:%s\n")
1132 1132 % (extendnode.rev(), extendnode)
1133 1133 )
1134 1134 state[b'current'] = [extendnode.node()]
1135 1135 hbisect.save_state(repo, state)
1136 1136 return mayupdate(repo, extendnode.node())
1137 1137 raise error.StateError(_(b"nothing to extend"))
1138 1138
1139 1139 if changesets == 0:
1140 1140 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1141 1141 else:
1142 1142 assert len(nodes) == 1 # only a single node can be tested next
1143 1143 node = nodes[0]
1144 1144 # compute the approximate number of remaining tests
1145 1145 tests, size = 0, 2
1146 1146 while size <= changesets:
1147 1147 tests, size = tests + 1, size * 2
1148 1148 rev = repo.changelog.rev(node)
1149 1149 ui.write(
1150 1150 _(
1151 1151 b"Testing changeset %d:%s "
1152 1152 b"(%d changesets remaining, ~%d tests)\n"
1153 1153 )
1154 1154 % (rev, short(node), changesets, tests)
1155 1155 )
1156 1156 state[b'current'] = [node]
1157 1157 hbisect.save_state(repo, state)
1158 1158 return mayupdate(repo, node)
1159 1159
1160 1160
1161 1161 @command(
1162 1162 b'bookmarks|bookmark',
1163 1163 [
1164 1164 (b'f', b'force', False, _(b'force')),
1165 1165 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1166 1166 (b'd', b'delete', False, _(b'delete a given bookmark')),
1167 1167 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1168 1168 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1169 1169 (b'l', b'list', False, _(b'list existing bookmarks')),
1170 1170 ]
1171 1171 + formatteropts,
1172 1172 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1173 1173 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1174 1174 )
1175 1175 def bookmark(ui, repo, *names, **opts):
1176 1176 """create a new bookmark or list existing bookmarks
1177 1177
1178 1178 Bookmarks are labels on changesets to help track lines of development.
1179 1179 Bookmarks are unversioned and can be moved, renamed and deleted.
1180 1180 Deleting or moving a bookmark has no effect on the associated changesets.
1181 1181
1182 1182 Creating or updating to a bookmark causes it to be marked as 'active'.
1183 1183 The active bookmark is indicated with a '*'.
1184 1184 When a commit is made, the active bookmark will advance to the new commit.
1185 1185 A plain :hg:`update` will also advance an active bookmark, if possible.
1186 1186 Updating away from a bookmark will cause it to be deactivated.
1187 1187
1188 1188 Bookmarks can be pushed and pulled between repositories (see
1189 1189 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1190 1190 diverged, a new 'divergent bookmark' of the form 'name@path' will
1191 1191 be created. Using :hg:`merge` will resolve the divergence.
1192 1192
1193 1193 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1194 1194 the active bookmark's name.
1195 1195
1196 1196 A bookmark named '@' has the special property that :hg:`clone` will
1197 1197 check it out by default if it exists.
1198 1198
1199 1199 .. container:: verbose
1200 1200
1201 1201 Template:
1202 1202
1203 1203 The following keywords are supported in addition to the common template
1204 1204 keywords and functions such as ``{bookmark}``. See also
1205 1205 :hg:`help templates`.
1206 1206
1207 1207 :active: Boolean. True if the bookmark is active.
1208 1208
1209 1209 Examples:
1210 1210
1211 1211 - create an active bookmark for a new line of development::
1212 1212
1213 1213 hg book new-feature
1214 1214
1215 1215 - create an inactive bookmark as a place marker::
1216 1216
1217 1217 hg book -i reviewed
1218 1218
1219 1219 - create an inactive bookmark on another changeset::
1220 1220
1221 1221 hg book -r .^ tested
1222 1222
1223 1223 - rename bookmark turkey to dinner::
1224 1224
1225 1225 hg book -m turkey dinner
1226 1226
1227 1227 - move the '@' bookmark from another branch::
1228 1228
1229 1229 hg book -f @
1230 1230
1231 1231 - print only the active bookmark name::
1232 1232
1233 1233 hg book -ql .
1234 1234 """
1235 1235 opts = pycompat.byteskwargs(opts)
1236 1236 force = opts.get(b'force')
1237 1237 rev = opts.get(b'rev')
1238 1238 inactive = opts.get(b'inactive') # meaning add/rename to inactive bookmark
1239 1239
1240 1240 action = cmdutil.check_at_most_one_arg(opts, b'delete', b'rename', b'list')
1241 1241 if action:
1242 1242 cmdutil.check_incompatible_arguments(opts, action, [b'rev'])
1243 1243 elif names or rev:
1244 1244 action = b'add'
1245 1245 elif inactive:
1246 1246 action = b'inactive' # meaning deactivate
1247 1247 else:
1248 1248 action = b'list'
1249 1249
1250 1250 cmdutil.check_incompatible_arguments(
1251 1251 opts, b'inactive', [b'delete', b'list']
1252 1252 )
1253 1253 if not names and action in {b'add', b'delete'}:
1254 1254 raise error.InputError(_(b"bookmark name required"))
1255 1255
1256 1256 if action in {b'add', b'delete', b'rename', b'inactive'}:
1257 1257 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1258 1258 if action == b'delete':
1259 1259 names = pycompat.maplist(repo._bookmarks.expandname, names)
1260 1260 bookmarks.delete(repo, tr, names)
1261 1261 elif action == b'rename':
1262 1262 if not names:
1263 1263 raise error.InputError(_(b"new bookmark name required"))
1264 1264 elif len(names) > 1:
1265 1265 raise error.InputError(
1266 1266 _(b"only one new bookmark name allowed")
1267 1267 )
1268 1268 oldname = repo._bookmarks.expandname(opts[b'rename'])
1269 1269 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1270 1270 elif action == b'add':
1271 1271 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1272 1272 elif action == b'inactive':
1273 1273 if len(repo._bookmarks) == 0:
1274 1274 ui.status(_(b"no bookmarks set\n"))
1275 1275 elif not repo._activebookmark:
1276 1276 ui.status(_(b"no active bookmark\n"))
1277 1277 else:
1278 1278 bookmarks.deactivate(repo)
1279 1279 elif action == b'list':
1280 1280 names = pycompat.maplist(repo._bookmarks.expandname, names)
1281 1281 with ui.formatter(b'bookmarks', opts) as fm:
1282 1282 bookmarks.printbookmarks(ui, repo, fm, names)
1283 1283 else:
1284 1284 raise error.ProgrammingError(b'invalid action: %s' % action)
1285 1285
1286 1286
1287 1287 @command(
1288 1288 b'branch',
1289 1289 [
1290 1290 (
1291 1291 b'f',
1292 1292 b'force',
1293 1293 None,
1294 1294 _(b'set branch name even if it shadows an existing branch'),
1295 1295 ),
1296 1296 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1297 1297 (
1298 1298 b'r',
1299 1299 b'rev',
1300 1300 [],
1301 1301 _(b'change branches of the given revs (EXPERIMENTAL)'),
1302 1302 ),
1303 1303 ],
1304 1304 _(b'[-fC] [NAME]'),
1305 1305 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1306 1306 )
1307 1307 def branch(ui, repo, label=None, **opts):
1308 1308 """set or show the current branch name
1309 1309
1310 1310 .. note::
1311 1311
1312 1312 Branch names are permanent and global. Use :hg:`bookmark` to create a
1313 1313 light-weight bookmark instead. See :hg:`help glossary` for more
1314 1314 information about named branches and bookmarks.
1315 1315
1316 1316 With no argument, show the current branch name. With one argument,
1317 1317 set the working directory branch name (the branch will not exist
1318 1318 in the repository until the next commit). Standard practice
1319 1319 recommends that primary development take place on the 'default'
1320 1320 branch.
1321 1321
1322 1322 Unless -f/--force is specified, branch will not let you set a
1323 1323 branch name that already exists.
1324 1324
1325 1325 Use -C/--clean to reset the working directory branch to that of
1326 1326 the parent of the working directory, negating a previous branch
1327 1327 change.
1328 1328
1329 1329 Use the command :hg:`update` to switch to an existing branch. Use
1330 1330 :hg:`commit --close-branch` to mark this branch head as closed.
1331 1331 When all heads of a branch are closed, the branch will be
1332 1332 considered closed.
1333 1333
1334 1334 Returns 0 on success.
1335 1335 """
1336 1336 opts = pycompat.byteskwargs(opts)
1337 1337 revs = opts.get(b'rev')
1338 1338 if label:
1339 1339 label = label.strip()
1340 1340
1341 1341 if not opts.get(b'clean') and not label:
1342 1342 if revs:
1343 1343 raise error.InputError(
1344 1344 _(b"no branch name specified for the revisions")
1345 1345 )
1346 1346 ui.write(b"%s\n" % repo.dirstate.branch())
1347 1347 return
1348 1348
1349 1349 with repo.wlock():
1350 1350 if opts.get(b'clean'):
1351 1351 label = repo[b'.'].branch()
1352 1352 repo.dirstate.setbranch(label)
1353 1353 ui.status(_(b'reset working directory to branch %s\n') % label)
1354 1354 elif label:
1355 1355
1356 1356 scmutil.checknewlabel(repo, label, b'branch')
1357 1357 if revs:
1358 1358 return cmdutil.changebranch(ui, repo, revs, label, opts)
1359 1359
1360 1360 if not opts.get(b'force') and label in repo.branchmap():
1361 1361 if label not in [p.branch() for p in repo[None].parents()]:
1362 1362 raise error.InputError(
1363 1363 _(b'a branch of the same name already exists'),
1364 1364 # i18n: "it" refers to an existing branch
1365 1365 hint=_(b"use 'hg update' to switch to it"),
1366 1366 )
1367 1367
1368 1368 repo.dirstate.setbranch(label)
1369 1369 ui.status(_(b'marked working directory as branch %s\n') % label)
1370 1370
1371 1371 # find any open named branches aside from default
1372 1372 for n, h, t, c in repo.branchmap().iterbranches():
1373 1373 if n != b"default" and not c:
1374 1374 return 0
1375 1375 ui.status(
1376 1376 _(
1377 1377 b'(branches are permanent and global, '
1378 1378 b'did you want a bookmark?)\n'
1379 1379 )
1380 1380 )
1381 1381
1382 1382
1383 1383 @command(
1384 1384 b'branches',
1385 1385 [
1386 1386 (
1387 1387 b'a',
1388 1388 b'active',
1389 1389 False,
1390 1390 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1391 1391 ),
1392 1392 (b'c', b'closed', False, _(b'show normal and closed branches')),
1393 1393 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1394 1394 ]
1395 1395 + formatteropts,
1396 1396 _(b'[-c]'),
1397 1397 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1398 1398 intents={INTENT_READONLY},
1399 1399 )
1400 1400 def branches(ui, repo, active=False, closed=False, **opts):
1401 1401 """list repository named branches
1402 1402
1403 1403 List the repository's named branches, indicating which ones are
1404 1404 inactive. If -c/--closed is specified, also list branches which have
1405 1405 been marked closed (see :hg:`commit --close-branch`).
1406 1406
1407 1407 Use the command :hg:`update` to switch to an existing branch.
1408 1408
1409 1409 .. container:: verbose
1410 1410
1411 1411 Template:
1412 1412
1413 1413 The following keywords are supported in addition to the common template
1414 1414 keywords and functions such as ``{branch}``. See also
1415 1415 :hg:`help templates`.
1416 1416
1417 1417 :active: Boolean. True if the branch is active.
1418 1418 :closed: Boolean. True if the branch is closed.
1419 1419 :current: Boolean. True if it is the current branch.
1420 1420
1421 1421 Returns 0.
1422 1422 """
1423 1423
1424 1424 opts = pycompat.byteskwargs(opts)
1425 1425 revs = opts.get(b'rev')
1426 1426 selectedbranches = None
1427 1427 if revs:
1428 1428 revs = scmutil.revrange(repo, revs)
1429 1429 getbi = repo.revbranchcache().branchinfo
1430 1430 selectedbranches = {getbi(r)[0] for r in revs}
1431 1431
1432 1432 ui.pager(b'branches')
1433 1433 fm = ui.formatter(b'branches', opts)
1434 1434 hexfunc = fm.hexfunc
1435 1435
1436 1436 allheads = set(repo.heads())
1437 1437 branches = []
1438 1438 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1439 1439 if selectedbranches is not None and tag not in selectedbranches:
1440 1440 continue
1441 1441 isactive = False
1442 1442 if not isclosed:
1443 1443 openheads = set(repo.branchmap().iteropen(heads))
1444 1444 isactive = bool(openheads & allheads)
1445 1445 branches.append((tag, repo[tip], isactive, not isclosed))
1446 1446 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1447 1447
1448 1448 for tag, ctx, isactive, isopen in branches:
1449 1449 if active and not isactive:
1450 1450 continue
1451 1451 if isactive:
1452 1452 label = b'branches.active'
1453 1453 notice = b''
1454 1454 elif not isopen:
1455 1455 if not closed:
1456 1456 continue
1457 1457 label = b'branches.closed'
1458 1458 notice = _(b' (closed)')
1459 1459 else:
1460 1460 label = b'branches.inactive'
1461 1461 notice = _(b' (inactive)')
1462 1462 current = tag == repo.dirstate.branch()
1463 1463 if current:
1464 1464 label = b'branches.current'
1465 1465
1466 1466 fm.startitem()
1467 1467 fm.write(b'branch', b'%s', tag, label=label)
1468 1468 rev = ctx.rev()
1469 1469 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1470 1470 fmt = b' ' * padsize + b' %d:%s'
1471 1471 fm.condwrite(
1472 1472 not ui.quiet,
1473 1473 b'rev node',
1474 1474 fmt,
1475 1475 rev,
1476 1476 hexfunc(ctx.node()),
1477 1477 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1478 1478 )
1479 1479 fm.context(ctx=ctx)
1480 1480 fm.data(active=isactive, closed=not isopen, current=current)
1481 1481 if not ui.quiet:
1482 1482 fm.plain(notice)
1483 1483 fm.plain(b'\n')
1484 1484 fm.end()
1485 1485
1486 1486
1487 1487 @command(
1488 1488 b'bundle',
1489 1489 [
1490 1490 (
1491 1491 b'f',
1492 1492 b'force',
1493 1493 None,
1494 1494 _(b'run even when the destination is unrelated'),
1495 1495 ),
1496 1496 (
1497 1497 b'r',
1498 1498 b'rev',
1499 1499 [],
1500 1500 _(b'a changeset intended to be added to the destination'),
1501 1501 _(b'REV'),
1502 1502 ),
1503 1503 (
1504 1504 b'b',
1505 1505 b'branch',
1506 1506 [],
1507 1507 _(b'a specific branch you would like to bundle'),
1508 1508 _(b'BRANCH'),
1509 1509 ),
1510 1510 (
1511 1511 b'',
1512 1512 b'base',
1513 1513 [],
1514 1514 _(b'a base changeset assumed to be available at the destination'),
1515 1515 _(b'REV'),
1516 1516 ),
1517 1517 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1518 1518 (
1519 1519 b't',
1520 1520 b'type',
1521 1521 b'bzip2',
1522 1522 _(b'bundle compression type to use'),
1523 1523 _(b'TYPE'),
1524 1524 ),
1525 1525 ]
1526 1526 + remoteopts,
1527 1527 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1528 1528 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1529 1529 )
1530 1530 def bundle(ui, repo, fname, dest=None, **opts):
1531 1531 """create a bundle file
1532 1532
1533 1533 Generate a bundle file containing data to be transferred to another
1534 1534 repository.
1535 1535
1536 1536 To create a bundle containing all changesets, use -a/--all
1537 1537 (or --base null). Otherwise, hg assumes the destination will have
1538 1538 all the nodes you specify with --base parameters. Otherwise, hg
1539 1539 will assume the repository has all the nodes in destination, or
1540 1540 default-push/default if no destination is specified, where destination
1541 1541 is the repository you provide through DEST option.
1542 1542
1543 1543 You can change bundle format with the -t/--type option. See
1544 1544 :hg:`help bundlespec` for documentation on this format. By default,
1545 1545 the most appropriate format is used and compression defaults to
1546 1546 bzip2.
1547 1547
1548 1548 The bundle file can then be transferred using conventional means
1549 1549 and applied to another repository with the unbundle or pull
1550 1550 command. This is useful when direct push and pull are not
1551 1551 available or when exporting an entire repository is undesirable.
1552 1552
1553 1553 Applying bundles preserves all changeset contents including
1554 1554 permissions, copy/rename information, and revision history.
1555 1555
1556 1556 Returns 0 on success, 1 if no changes found.
1557 1557 """
1558 1558 opts = pycompat.byteskwargs(opts)
1559 1559 revs = None
1560 1560 if b'rev' in opts:
1561 1561 revstrings = opts[b'rev']
1562 1562 revs = scmutil.revrange(repo, revstrings)
1563 1563 if revstrings and not revs:
1564 1564 raise error.InputError(_(b'no commits to bundle'))
1565 1565
1566 1566 bundletype = opts.get(b'type', b'bzip2').lower()
1567 1567 try:
1568 1568 bundlespec = bundlecaches.parsebundlespec(
1569 1569 repo, bundletype, strict=False
1570 1570 )
1571 1571 except error.UnsupportedBundleSpecification as e:
1572 1572 raise error.InputError(
1573 1573 pycompat.bytestr(e),
1574 1574 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1575 1575 )
1576 1576 cgversion = bundlespec.contentopts[b"cg.version"]
1577 1577
1578 1578 # Packed bundles are a pseudo bundle format for now.
1579 1579 if cgversion == b's1':
1580 1580 raise error.InputError(
1581 1581 _(b'packed bundles cannot be produced by "hg bundle"'),
1582 1582 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1583 1583 )
1584 1584
1585 1585 if opts.get(b'all'):
1586 1586 if dest:
1587 1587 raise error.InputError(
1588 1588 _(b"--all is incompatible with specifying a destination")
1589 1589 )
1590 1590 if opts.get(b'base'):
1591 1591 ui.warn(_(b"ignoring --base because --all was specified\n"))
1592 1592 base = [nullrev]
1593 1593 else:
1594 1594 base = scmutil.revrange(repo, opts.get(b'base'))
1595 1595 if cgversion not in changegroup.supportedoutgoingversions(repo):
1596 1596 raise error.Abort(
1597 1597 _(b"repository does not support bundle version %s") % cgversion
1598 1598 )
1599 1599
1600 1600 if base:
1601 1601 if dest:
1602 1602 raise error.InputError(
1603 1603 _(b"--base is incompatible with specifying a destination")
1604 1604 )
1605 1605 common = [repo[rev].node() for rev in base]
1606 1606 heads = [repo[r].node() for r in revs] if revs else None
1607 1607 outgoing = discovery.outgoing(repo, common, heads)
1608 1608 else:
1609 1609 dest = ui.expandpath(dest or b'default-push', dest or b'default')
1610 1610 dest, branches = hg.parseurl(dest, opts.get(b'branch'))
1611 1611 other = hg.peer(repo, opts, dest)
1612 1612 revs = [repo[r].hex() for r in revs]
1613 1613 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1614 1614 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1615 1615 outgoing = discovery.findcommonoutgoing(
1616 1616 repo,
1617 1617 other,
1618 1618 onlyheads=heads,
1619 1619 force=opts.get(b'force'),
1620 1620 portable=True,
1621 1621 )
1622 1622
1623 1623 if not outgoing.missing:
1624 1624 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1625 1625 return 1
1626 1626
1627 1627 if cgversion == b'01': # bundle1
1628 1628 bversion = b'HG10' + bundlespec.wirecompression
1629 1629 bcompression = None
1630 1630 elif cgversion in (b'02', b'03'):
1631 1631 bversion = b'HG20'
1632 1632 bcompression = bundlespec.wirecompression
1633 1633 else:
1634 1634 raise error.ProgrammingError(
1635 1635 b'bundle: unexpected changegroup version %s' % cgversion
1636 1636 )
1637 1637
1638 1638 # TODO compression options should be derived from bundlespec parsing.
1639 1639 # This is a temporary hack to allow adjusting bundle compression
1640 1640 # level without a) formalizing the bundlespec changes to declare it
1641 1641 # b) introducing a command flag.
1642 1642 compopts = {}
1643 1643 complevel = ui.configint(
1644 1644 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1645 1645 )
1646 1646 if complevel is None:
1647 1647 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1648 1648 if complevel is not None:
1649 1649 compopts[b'level'] = complevel
1650 1650
1651 1651 # Allow overriding the bundling of obsmarker in phases through
1652 1652 # configuration while we don't have a bundle version that include them
1653 1653 if repo.ui.configbool(b'experimental', b'evolution.bundle-obsmarker'):
1654 1654 bundlespec.contentopts[b'obsolescence'] = True
1655 1655 if repo.ui.configbool(b'experimental', b'bundle-phases'):
1656 1656 bundlespec.contentopts[b'phases'] = True
1657 1657
1658 1658 bundle2.writenewbundle(
1659 1659 ui,
1660 1660 repo,
1661 1661 b'bundle',
1662 1662 fname,
1663 1663 bversion,
1664 1664 outgoing,
1665 1665 bundlespec.contentopts,
1666 1666 compression=bcompression,
1667 1667 compopts=compopts,
1668 1668 )
1669 1669
1670 1670
1671 1671 @command(
1672 1672 b'cat',
1673 1673 [
1674 1674 (
1675 1675 b'o',
1676 1676 b'output',
1677 1677 b'',
1678 1678 _(b'print output to file with formatted name'),
1679 1679 _(b'FORMAT'),
1680 1680 ),
1681 1681 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1682 1682 (b'', b'decode', None, _(b'apply any matching decode filter')),
1683 1683 ]
1684 1684 + walkopts
1685 1685 + formatteropts,
1686 1686 _(b'[OPTION]... FILE...'),
1687 1687 helpcategory=command.CATEGORY_FILE_CONTENTS,
1688 1688 inferrepo=True,
1689 1689 intents={INTENT_READONLY},
1690 1690 )
1691 1691 def cat(ui, repo, file1, *pats, **opts):
1692 1692 """output the current or given revision of files
1693 1693
1694 1694 Print the specified files as they were at the given revision. If
1695 1695 no revision is given, the parent of the working directory is used.
1696 1696
1697 1697 Output may be to a file, in which case the name of the file is
1698 1698 given using a template string. See :hg:`help templates`. In addition
1699 1699 to the common template keywords, the following formatting rules are
1700 1700 supported:
1701 1701
1702 1702 :``%%``: literal "%" character
1703 1703 :``%s``: basename of file being printed
1704 1704 :``%d``: dirname of file being printed, or '.' if in repository root
1705 1705 :``%p``: root-relative path name of file being printed
1706 1706 :``%H``: changeset hash (40 hexadecimal digits)
1707 1707 :``%R``: changeset revision number
1708 1708 :``%h``: short-form changeset hash (12 hexadecimal digits)
1709 1709 :``%r``: zero-padded changeset revision number
1710 1710 :``%b``: basename of the exporting repository
1711 1711 :``\\``: literal "\\" character
1712 1712
1713 1713 .. container:: verbose
1714 1714
1715 1715 Template:
1716 1716
1717 1717 The following keywords are supported in addition to the common template
1718 1718 keywords and functions. See also :hg:`help templates`.
1719 1719
1720 1720 :data: String. File content.
1721 1721 :path: String. Repository-absolute path of the file.
1722 1722
1723 1723 Returns 0 on success.
1724 1724 """
1725 1725 opts = pycompat.byteskwargs(opts)
1726 1726 rev = opts.get(b'rev')
1727 1727 if rev:
1728 1728 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1729 1729 ctx = scmutil.revsingle(repo, rev)
1730 1730 m = scmutil.match(ctx, (file1,) + pats, opts)
1731 1731 fntemplate = opts.pop(b'output', b'')
1732 1732 if cmdutil.isstdiofilename(fntemplate):
1733 1733 fntemplate = b''
1734 1734
1735 1735 if fntemplate:
1736 1736 fm = formatter.nullformatter(ui, b'cat', opts)
1737 1737 else:
1738 1738 ui.pager(b'cat')
1739 1739 fm = ui.formatter(b'cat', opts)
1740 1740 with fm:
1741 1741 return cmdutil.cat(
1742 1742 ui, repo, ctx, m, fm, fntemplate, b'', **pycompat.strkwargs(opts)
1743 1743 )
1744 1744
1745 1745
1746 1746 @command(
1747 1747 b'clone',
1748 1748 [
1749 1749 (
1750 1750 b'U',
1751 1751 b'noupdate',
1752 1752 None,
1753 1753 _(
1754 1754 b'the clone will include an empty working '
1755 1755 b'directory (only a repository)'
1756 1756 ),
1757 1757 ),
1758 1758 (
1759 1759 b'u',
1760 1760 b'updaterev',
1761 1761 b'',
1762 1762 _(b'revision, tag, or branch to check out'),
1763 1763 _(b'REV'),
1764 1764 ),
1765 1765 (
1766 1766 b'r',
1767 1767 b'rev',
1768 1768 [],
1769 1769 _(
1770 1770 b'do not clone everything, but include this changeset'
1771 1771 b' and its ancestors'
1772 1772 ),
1773 1773 _(b'REV'),
1774 1774 ),
1775 1775 (
1776 1776 b'b',
1777 1777 b'branch',
1778 1778 [],
1779 1779 _(
1780 1780 b'do not clone everything, but include this branch\'s'
1781 1781 b' changesets and their ancestors'
1782 1782 ),
1783 1783 _(b'BRANCH'),
1784 1784 ),
1785 1785 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1786 1786 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1787 1787 (b'', b'stream', None, _(b'clone with minimal data processing')),
1788 1788 ]
1789 1789 + remoteopts,
1790 1790 _(b'[OPTION]... SOURCE [DEST]'),
1791 1791 helpcategory=command.CATEGORY_REPO_CREATION,
1792 1792 helpbasic=True,
1793 1793 norepo=True,
1794 1794 )
1795 1795 def clone(ui, source, dest=None, **opts):
1796 1796 """make a copy of an existing repository
1797 1797
1798 1798 Create a copy of an existing repository in a new directory.
1799 1799
1800 1800 If no destination directory name is specified, it defaults to the
1801 1801 basename of the source.
1802 1802
1803 1803 The location of the source is added to the new repository's
1804 1804 ``.hg/hgrc`` file, as the default to be used for future pulls.
1805 1805
1806 1806 Only local paths and ``ssh://`` URLs are supported as
1807 1807 destinations. For ``ssh://`` destinations, no working directory or
1808 1808 ``.hg/hgrc`` will be created on the remote side.
1809 1809
1810 1810 If the source repository has a bookmark called '@' set, that
1811 1811 revision will be checked out in the new repository by default.
1812 1812
1813 1813 To check out a particular version, use -u/--update, or
1814 1814 -U/--noupdate to create a clone with no working directory.
1815 1815
1816 1816 To pull only a subset of changesets, specify one or more revisions
1817 1817 identifiers with -r/--rev or branches with -b/--branch. The
1818 1818 resulting clone will contain only the specified changesets and
1819 1819 their ancestors. These options (or 'clone src#rev dest') imply
1820 1820 --pull, even for local source repositories.
1821 1821
1822 1822 In normal clone mode, the remote normalizes repository data into a common
1823 1823 exchange format and the receiving end translates this data into its local
1824 1824 storage format. --stream activates a different clone mode that essentially
1825 1825 copies repository files from the remote with minimal data processing. This
1826 1826 significantly reduces the CPU cost of a clone both remotely and locally.
1827 1827 However, it often increases the transferred data size by 30-40%. This can
1828 1828 result in substantially faster clones where I/O throughput is plentiful,
1829 1829 especially for larger repositories. A side-effect of --stream clones is
1830 1830 that storage settings and requirements on the remote are applied locally:
1831 1831 a modern client may inherit legacy or inefficient storage used by the
1832 1832 remote or a legacy Mercurial client may not be able to clone from a
1833 1833 modern Mercurial remote.
1834 1834
1835 1835 .. note::
1836 1836
1837 1837 Specifying a tag will include the tagged changeset but not the
1838 1838 changeset containing the tag.
1839 1839
1840 1840 .. container:: verbose
1841 1841
1842 1842 For efficiency, hardlinks are used for cloning whenever the
1843 1843 source and destination are on the same filesystem (note this
1844 1844 applies only to the repository data, not to the working
1845 1845 directory). Some filesystems, such as AFS, implement hardlinking
1846 1846 incorrectly, but do not report errors. In these cases, use the
1847 1847 --pull option to avoid hardlinking.
1848 1848
1849 1849 Mercurial will update the working directory to the first applicable
1850 1850 revision from this list:
1851 1851
1852 1852 a) null if -U or the source repository has no changesets
1853 1853 b) if -u . and the source repository is local, the first parent of
1854 1854 the source repository's working directory
1855 1855 c) the changeset specified with -u (if a branch name, this means the
1856 1856 latest head of that branch)
1857 1857 d) the changeset specified with -r
1858 1858 e) the tipmost head specified with -b
1859 1859 f) the tipmost head specified with the url#branch source syntax
1860 1860 g) the revision marked with the '@' bookmark, if present
1861 1861 h) the tipmost head of the default branch
1862 1862 i) tip
1863 1863
1864 1864 When cloning from servers that support it, Mercurial may fetch
1865 1865 pre-generated data from a server-advertised URL or inline from the
1866 1866 same stream. When this is done, hooks operating on incoming changesets
1867 1867 and changegroups may fire more than once, once for each pre-generated
1868 1868 bundle and as well as for any additional remaining data. In addition,
1869 1869 if an error occurs, the repository may be rolled back to a partial
1870 1870 clone. This behavior may change in future releases.
1871 1871 See :hg:`help -e clonebundles` for more.
1872 1872
1873 1873 Examples:
1874 1874
1875 1875 - clone a remote repository to a new directory named hg/::
1876 1876
1877 1877 hg clone https://www.mercurial-scm.org/repo/hg/
1878 1878
1879 1879 - create a lightweight local clone::
1880 1880
1881 1881 hg clone project/ project-feature/
1882 1882
1883 1883 - clone from an absolute path on an ssh server (note double-slash)::
1884 1884
1885 1885 hg clone ssh://user@server//home/projects/alpha/
1886 1886
1887 1887 - do a streaming clone while checking out a specified version::
1888 1888
1889 1889 hg clone --stream http://server/repo -u 1.5
1890 1890
1891 1891 - create a repository without changesets after a particular revision::
1892 1892
1893 1893 hg clone -r 04e544 experimental/ good/
1894 1894
1895 1895 - clone (and track) a particular named branch::
1896 1896
1897 1897 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1898 1898
1899 1899 See :hg:`help urls` for details on specifying URLs.
1900 1900
1901 1901 Returns 0 on success.
1902 1902 """
1903 1903 opts = pycompat.byteskwargs(opts)
1904 1904 cmdutil.check_at_most_one_arg(opts, b'noupdate', b'updaterev')
1905 1905
1906 1906 # --include/--exclude can come from narrow or sparse.
1907 1907 includepats, excludepats = None, None
1908 1908
1909 1909 # hg.clone() differentiates between None and an empty set. So make sure
1910 1910 # patterns are sets if narrow is requested without patterns.
1911 1911 if opts.get(b'narrow'):
1912 1912 includepats = set()
1913 1913 excludepats = set()
1914 1914
1915 1915 if opts.get(b'include'):
1916 1916 includepats = narrowspec.parsepatterns(opts.get(b'include'))
1917 1917 if opts.get(b'exclude'):
1918 1918 excludepats = narrowspec.parsepatterns(opts.get(b'exclude'))
1919 1919
1920 1920 r = hg.clone(
1921 1921 ui,
1922 1922 opts,
1923 1923 source,
1924 1924 dest,
1925 1925 pull=opts.get(b'pull'),
1926 1926 stream=opts.get(b'stream') or opts.get(b'uncompressed'),
1927 1927 revs=opts.get(b'rev'),
1928 1928 update=opts.get(b'updaterev') or not opts.get(b'noupdate'),
1929 1929 branch=opts.get(b'branch'),
1930 1930 shareopts=opts.get(b'shareopts'),
1931 1931 storeincludepats=includepats,
1932 1932 storeexcludepats=excludepats,
1933 1933 depth=opts.get(b'depth') or None,
1934 1934 )
1935 1935
1936 1936 return r is None
1937 1937
1938 1938
1939 1939 @command(
1940 1940 b'commit|ci',
1941 1941 [
1942 1942 (
1943 1943 b'A',
1944 1944 b'addremove',
1945 1945 None,
1946 1946 _(b'mark new/missing files as added/removed before committing'),
1947 1947 ),
1948 1948 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
1949 1949 (b'', b'amend', None, _(b'amend the parent of the working directory')),
1950 1950 (b's', b'secret', None, _(b'use the secret phase for committing')),
1951 1951 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
1952 1952 (
1953 1953 b'',
1954 1954 b'force-close-branch',
1955 1955 None,
1956 1956 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
1957 1957 ),
1958 1958 (b'i', b'interactive', None, _(b'use interactive mode')),
1959 1959 ]
1960 1960 + walkopts
1961 1961 + commitopts
1962 1962 + commitopts2
1963 1963 + subrepoopts,
1964 1964 _(b'[OPTION]... [FILE]...'),
1965 1965 helpcategory=command.CATEGORY_COMMITTING,
1966 1966 helpbasic=True,
1967 1967 inferrepo=True,
1968 1968 )
1969 1969 def commit(ui, repo, *pats, **opts):
1970 1970 """commit the specified files or all outstanding changes
1971 1971
1972 1972 Commit changes to the given files into the repository. Unlike a
1973 1973 centralized SCM, this operation is a local operation. See
1974 1974 :hg:`push` for a way to actively distribute your changes.
1975 1975
1976 1976 If a list of files is omitted, all changes reported by :hg:`status`
1977 1977 will be committed.
1978 1978
1979 1979 If you are committing the result of a merge, do not provide any
1980 1980 filenames or -I/-X filters.
1981 1981
1982 1982 If no commit message is specified, Mercurial starts your
1983 1983 configured editor where you can enter a message. In case your
1984 1984 commit fails, you will find a backup of your message in
1985 1985 ``.hg/last-message.txt``.
1986 1986
1987 1987 The --close-branch flag can be used to mark the current branch
1988 1988 head closed. When all heads of a branch are closed, the branch
1989 1989 will be considered closed and no longer listed.
1990 1990
1991 1991 The --amend flag can be used to amend the parent of the
1992 1992 working directory with a new commit that contains the changes
1993 1993 in the parent in addition to those currently reported by :hg:`status`,
1994 1994 if there are any. The old commit is stored in a backup bundle in
1995 1995 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1996 1996 on how to restore it).
1997 1997
1998 1998 Message, user and date are taken from the amended commit unless
1999 1999 specified. When a message isn't specified on the command line,
2000 2000 the editor will open with the message of the amended commit.
2001 2001
2002 2002 It is not possible to amend public changesets (see :hg:`help phases`)
2003 2003 or changesets that have children.
2004 2004
2005 2005 See :hg:`help dates` for a list of formats valid for -d/--date.
2006 2006
2007 2007 Returns 0 on success, 1 if nothing changed.
2008 2008
2009 2009 .. container:: verbose
2010 2010
2011 2011 Examples:
2012 2012
2013 2013 - commit all files ending in .py::
2014 2014
2015 2015 hg commit --include "set:**.py"
2016 2016
2017 2017 - commit all non-binary files::
2018 2018
2019 2019 hg commit --exclude "set:binary()"
2020 2020
2021 2021 - amend the current commit and set the date to now::
2022 2022
2023 2023 hg commit --amend --date now
2024 2024 """
2025 2025 with repo.wlock(), repo.lock():
2026 2026 return _docommit(ui, repo, *pats, **opts)
2027 2027
2028 2028
2029 2029 def _docommit(ui, repo, *pats, **opts):
2030 2030 if opts.get('interactive'):
2031 2031 opts.pop('interactive')
2032 2032 ret = cmdutil.dorecord(
2033 2033 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2034 2034 )
2035 2035 # ret can be 0 (no changes to record) or the value returned by
2036 2036 # commit(), 1 if nothing changed or None on success.
2037 2037 return 1 if ret == 0 else ret
2038 2038
2039 2039 opts = pycompat.byteskwargs(opts)
2040 2040 if opts.get(b'subrepos'):
2041 2041 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'amend'])
2042 2042 # Let --subrepos on the command line override config setting.
2043 2043 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2044 2044
2045 2045 cmdutil.checkunfinished(repo, commit=True)
2046 2046
2047 2047 branch = repo[None].branch()
2048 2048 bheads = repo.branchheads(branch)
2049 2049 tip = repo.changelog.tip()
2050 2050
2051 2051 extra = {}
2052 2052 if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
2053 2053 extra[b'close'] = b'1'
2054 2054
2055 2055 if repo[b'.'].closesbranch():
2056 2056 raise error.InputError(
2057 2057 _(b'current revision is already a branch closing head')
2058 2058 )
2059 2059 elif not bheads:
2060 2060 raise error.InputError(
2061 2061 _(b'branch "%s" has no heads to close') % branch
2062 2062 )
2063 2063 elif (
2064 2064 branch == repo[b'.'].branch()
2065 2065 and repo[b'.'].node() not in bheads
2066 2066 and not opts.get(b'force_close_branch')
2067 2067 ):
2068 2068 hint = _(
2069 2069 b'use --force-close-branch to close branch from a non-head'
2070 2070 b' changeset'
2071 2071 )
2072 2072 raise error.InputError(_(b'can only close branch heads'), hint=hint)
2073 2073 elif opts.get(b'amend'):
2074 2074 if (
2075 2075 repo[b'.'].p1().branch() != branch
2076 2076 and repo[b'.'].p2().branch() != branch
2077 2077 ):
2078 2078 raise error.InputError(_(b'can only close branch heads'))
2079 2079
2080 2080 if opts.get(b'amend'):
2081 2081 if ui.configbool(b'ui', b'commitsubrepos'):
2082 2082 raise error.InputError(
2083 2083 _(b'cannot amend with ui.commitsubrepos enabled')
2084 2084 )
2085 2085
2086 2086 old = repo[b'.']
2087 2087 rewriteutil.precheck(repo, [old.rev()], b'amend')
2088 2088
2089 2089 # Currently histedit gets confused if an amend happens while histedit
2090 2090 # is in progress. Since we have a checkunfinished command, we are
2091 2091 # temporarily honoring it.
2092 2092 #
2093 2093 # Note: eventually this guard will be removed. Please do not expect
2094 2094 # this behavior to remain.
2095 2095 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2096 2096 cmdutil.checkunfinished(repo)
2097 2097
2098 2098 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2099 2099 if node == old.node():
2100 2100 ui.status(_(b"nothing changed\n"))
2101 2101 return 1
2102 2102 else:
2103 2103
2104 2104 def commitfunc(ui, repo, message, match, opts):
2105 2105 overrides = {}
2106 2106 if opts.get(b'secret'):
2107 2107 overrides[(b'phases', b'new-commit')] = b'secret'
2108 2108
2109 2109 baseui = repo.baseui
2110 2110 with baseui.configoverride(overrides, b'commit'):
2111 2111 with ui.configoverride(overrides, b'commit'):
2112 2112 editform = cmdutil.mergeeditform(
2113 2113 repo[None], b'commit.normal'
2114 2114 )
2115 2115 editor = cmdutil.getcommiteditor(
2116 2116 editform=editform, **pycompat.strkwargs(opts)
2117 2117 )
2118 2118 return repo.commit(
2119 2119 message,
2120 2120 opts.get(b'user'),
2121 2121 opts.get(b'date'),
2122 2122 match,
2123 2123 editor=editor,
2124 2124 extra=extra,
2125 2125 )
2126 2126
2127 2127 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
2128 2128
2129 2129 if not node:
2130 2130 stat = cmdutil.postcommitstatus(repo, pats, opts)
2131 2131 if stat.deleted:
2132 2132 ui.status(
2133 2133 _(
2134 2134 b"nothing changed (%d missing files, see "
2135 2135 b"'hg status')\n"
2136 2136 )
2137 2137 % len(stat.deleted)
2138 2138 )
2139 2139 else:
2140 2140 ui.status(_(b"nothing changed\n"))
2141 2141 return 1
2142 2142
2143 2143 cmdutil.commitstatus(repo, node, branch, bheads, tip, opts)
2144 2144
2145 2145 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2146 2146 status(
2147 2147 ui,
2148 2148 repo,
2149 2149 modified=True,
2150 2150 added=True,
2151 2151 removed=True,
2152 2152 deleted=True,
2153 2153 unknown=True,
2154 2154 subrepos=opts.get(b'subrepos'),
2155 2155 )
2156 2156
2157 2157
2158 2158 @command(
2159 2159 b'config|showconfig|debugconfig',
2160 2160 [
2161 2161 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2162 2162 (b'e', b'edit', None, _(b'edit user config')),
2163 2163 (b'l', b'local', None, _(b'edit repository config')),
2164 2164 (
2165 2165 b'',
2166 2166 b'shared',
2167 2167 None,
2168 2168 _(b'edit shared source repository config (EXPERIMENTAL)'),
2169 2169 ),
2170 2170 (b'', b'non-shared', None, _(b'edit non shared config (EXPERIMENTAL)')),
2171 2171 (b'g', b'global', None, _(b'edit global config')),
2172 2172 ]
2173 2173 + formatteropts,
2174 2174 _(b'[-u] [NAME]...'),
2175 2175 helpcategory=command.CATEGORY_HELP,
2176 2176 optionalrepo=True,
2177 2177 intents={INTENT_READONLY},
2178 2178 )
2179 2179 def config(ui, repo, *values, **opts):
2180 2180 """show combined config settings from all hgrc files
2181 2181
2182 2182 With no arguments, print names and values of all config items.
2183 2183
2184 2184 With one argument of the form section.name, print just the value
2185 2185 of that config item.
2186 2186
2187 2187 With multiple arguments, print names and values of all config
2188 2188 items with matching section names or section.names.
2189 2189
2190 2190 With --edit, start an editor on the user-level config file. With
2191 2191 --global, edit the system-wide config file. With --local, edit the
2192 2192 repository-level config file.
2193 2193
2194 2194 With --debug, the source (filename and line number) is printed
2195 2195 for each config item.
2196 2196
2197 2197 See :hg:`help config` for more information about config files.
2198 2198
2199 2199 .. container:: verbose
2200 2200
2201 2201 --non-shared flag is used to edit `.hg/hgrc-not-shared` config file.
2202 2202 This file is not shared across shares when in share-safe mode.
2203 2203
2204 2204 Template:
2205 2205
2206 2206 The following keywords are supported. See also :hg:`help templates`.
2207 2207
2208 2208 :name: String. Config name.
2209 2209 :source: String. Filename and line number where the item is defined.
2210 2210 :value: String. Config value.
2211 2211
2212 2212 The --shared flag can be used to edit the config file of shared source
2213 2213 repository. It only works when you have shared using the experimental
2214 2214 share safe feature.
2215 2215
2216 2216 Returns 0 on success, 1 if NAME does not exist.
2217 2217
2218 2218 """
2219 2219
2220 2220 opts = pycompat.byteskwargs(opts)
2221 2221 editopts = (b'edit', b'local', b'global', b'shared', b'non_shared')
2222 2222 if any(opts.get(o) for o in editopts):
2223 2223 cmdutil.check_at_most_one_arg(opts, *editopts[1:])
2224 2224 if opts.get(b'local'):
2225 2225 if not repo:
2226 2226 raise error.InputError(
2227 2227 _(b"can't use --local outside a repository")
2228 2228 )
2229 2229 paths = [repo.vfs.join(b'hgrc')]
2230 2230 elif opts.get(b'global'):
2231 2231 paths = rcutil.systemrcpath()
2232 2232 elif opts.get(b'shared'):
2233 2233 if not repo.shared():
2234 2234 raise error.InputError(
2235 2235 _(b"repository is not shared; can't use --shared")
2236 2236 )
2237 2237 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
2238 2238 raise error.InputError(
2239 2239 _(
2240 2240 b"share safe feature not enabled; "
2241 2241 b"unable to edit shared source repository config"
2242 2242 )
2243 2243 )
2244 2244 paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
2245 2245 elif opts.get(b'non_shared'):
2246 2246 paths = [repo.vfs.join(b'hgrc-not-shared')]
2247 2247 else:
2248 2248 paths = rcutil.userrcpath()
2249 2249
2250 2250 for f in paths:
2251 2251 if os.path.exists(f):
2252 2252 break
2253 2253 else:
2254 2254 if opts.get(b'global'):
2255 2255 samplehgrc = uimod.samplehgrcs[b'global']
2256 2256 elif opts.get(b'local'):
2257 2257 samplehgrc = uimod.samplehgrcs[b'local']
2258 2258 else:
2259 2259 samplehgrc = uimod.samplehgrcs[b'user']
2260 2260
2261 2261 f = paths[0]
2262 2262 fp = open(f, b"wb")
2263 2263 fp.write(util.tonativeeol(samplehgrc))
2264 2264 fp.close()
2265 2265
2266 2266 editor = ui.geteditor()
2267 2267 ui.system(
2268 2268 b"%s \"%s\"" % (editor, f),
2269 2269 onerr=error.InputError,
2270 2270 errprefix=_(b"edit failed"),
2271 2271 blockedtag=b'config_edit',
2272 2272 )
2273 2273 return
2274 2274 ui.pager(b'config')
2275 2275 fm = ui.formatter(b'config', opts)
2276 2276 for t, f in rcutil.rccomponents():
2277 2277 if t == b'path':
2278 2278 ui.debug(b'read config from: %s\n' % f)
2279 2279 elif t == b'resource':
2280 2280 ui.debug(b'read config from: resource:%s.%s\n' % (f[0], f[1]))
2281 2281 elif t == b'items':
2282 2282 # Don't print anything for 'items'.
2283 2283 pass
2284 2284 else:
2285 2285 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2286 2286 untrusted = bool(opts.get(b'untrusted'))
2287 2287
2288 2288 selsections = selentries = []
2289 2289 if values:
2290 2290 selsections = [v for v in values if b'.' not in v]
2291 2291 selentries = [v for v in values if b'.' in v]
2292 2292 uniquesel = len(selentries) == 1 and not selsections
2293 2293 selsections = set(selsections)
2294 2294 selentries = set(selentries)
2295 2295
2296 2296 matched = False
2297 2297 for section, name, value in ui.walkconfig(untrusted=untrusted):
2298 2298 source = ui.configsource(section, name, untrusted)
2299 2299 value = pycompat.bytestr(value)
2300 2300 defaultvalue = ui.configdefault(section, name)
2301 2301 if fm.isplain():
2302 2302 source = source or b'none'
2303 2303 value = value.replace(b'\n', b'\\n')
2304 2304 entryname = section + b'.' + name
2305 2305 if values and not (section in selsections or entryname in selentries):
2306 2306 continue
2307 2307 fm.startitem()
2308 2308 fm.condwrite(ui.debugflag, b'source', b'%s: ', source)
2309 2309 if uniquesel:
2310 2310 fm.data(name=entryname)
2311 2311 fm.write(b'value', b'%s\n', value)
2312 2312 else:
2313 2313 fm.write(b'name value', b'%s=%s\n', entryname, value)
2314 2314 if formatter.isprintable(defaultvalue):
2315 2315 fm.data(defaultvalue=defaultvalue)
2316 2316 elif isinstance(defaultvalue, list) and all(
2317 2317 formatter.isprintable(e) for e in defaultvalue
2318 2318 ):
2319 2319 fm.data(defaultvalue=fm.formatlist(defaultvalue, name=b'value'))
2320 2320 # TODO: no idea how to process unsupported defaultvalue types
2321 2321 matched = True
2322 2322 fm.end()
2323 2323 if matched:
2324 2324 return 0
2325 2325 return 1
2326 2326
2327 2327
2328 2328 @command(
2329 2329 b'continue',
2330 2330 dryrunopts,
2331 2331 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2332 2332 helpbasic=True,
2333 2333 )
2334 2334 def continuecmd(ui, repo, **opts):
2335 2335 """resumes an interrupted operation (EXPERIMENTAL)
2336 2336
2337 2337 Finishes a multistep operation like graft, histedit, rebase, merge,
2338 2338 and unshelve if they are in an interrupted state.
2339 2339
2340 2340 use --dry-run/-n to dry run the command.
2341 2341 """
2342 2342 dryrun = opts.get('dry_run')
2343 2343 contstate = cmdutil.getunfinishedstate(repo)
2344 2344 if not contstate:
2345 2345 raise error.StateError(_(b'no operation in progress'))
2346 2346 if not contstate.continuefunc:
2347 2347 raise error.StateError(
2348 2348 (
2349 2349 _(b"%s in progress but does not support 'hg continue'")
2350 2350 % (contstate._opname)
2351 2351 ),
2352 2352 hint=contstate.continuemsg(),
2353 2353 )
2354 2354 if dryrun:
2355 2355 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2356 2356 return
2357 2357 return contstate.continuefunc(ui, repo)
2358 2358
2359 2359
2360 2360 @command(
2361 2361 b'copy|cp',
2362 2362 [
2363 2363 (b'', b'forget', None, _(b'unmark a destination file as copied')),
2364 2364 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2365 2365 (
2366 2366 b'',
2367 2367 b'at-rev',
2368 2368 b'',
2369 2369 _(b'(un)mark copies in the given revision (EXPERIMENTAL)'),
2370 2370 _(b'REV'),
2371 2371 ),
2372 2372 (
2373 2373 b'f',
2374 2374 b'force',
2375 2375 None,
2376 2376 _(b'forcibly copy over an existing managed file'),
2377 2377 ),
2378 2378 ]
2379 2379 + walkopts
2380 2380 + dryrunopts,
2381 2381 _(b'[OPTION]... (SOURCE... DEST | --forget DEST...)'),
2382 2382 helpcategory=command.CATEGORY_FILE_CONTENTS,
2383 2383 )
2384 2384 def copy(ui, repo, *pats, **opts):
2385 2385 """mark files as copied for the next commit
2386 2386
2387 2387 Mark dest as having copies of source files. If dest is a
2388 2388 directory, copies are put in that directory. If dest is a file,
2389 2389 the source must be a single file.
2390 2390
2391 2391 By default, this command copies the contents of files as they
2392 2392 exist in the working directory. If invoked with -A/--after, the
2393 2393 operation is recorded, but no copying is performed.
2394 2394
2395 2395 To undo marking a destination file as copied, use --forget. With that
2396 2396 option, all given (positional) arguments are unmarked as copies. The
2397 2397 destination file(s) will be left in place (still tracked).
2398 2398
2399 2399 This command takes effect with the next commit by default.
2400 2400
2401 2401 Returns 0 on success, 1 if errors are encountered.
2402 2402 """
2403 2403 opts = pycompat.byteskwargs(opts)
2404 2404 with repo.wlock():
2405 2405 return cmdutil.copy(ui, repo, pats, opts)
2406 2406
2407 2407
2408 2408 @command(
2409 2409 b'debugcommands',
2410 2410 [],
2411 2411 _(b'[COMMAND]'),
2412 2412 helpcategory=command.CATEGORY_HELP,
2413 2413 norepo=True,
2414 2414 )
2415 2415 def debugcommands(ui, cmd=b'', *args):
2416 2416 """list all available commands and options"""
2417 2417 for cmd, vals in sorted(pycompat.iteritems(table)):
2418 2418 cmd = cmd.split(b'|')[0]
2419 2419 opts = b', '.join([i[1] for i in vals[1]])
2420 2420 ui.write(b'%s: %s\n' % (cmd, opts))
2421 2421
2422 2422
2423 2423 @command(
2424 2424 b'debugcomplete',
2425 2425 [(b'o', b'options', None, _(b'show the command options'))],
2426 2426 _(b'[-o] CMD'),
2427 2427 helpcategory=command.CATEGORY_HELP,
2428 2428 norepo=True,
2429 2429 )
2430 2430 def debugcomplete(ui, cmd=b'', **opts):
2431 2431 """returns the completion list associated with the given command"""
2432 2432
2433 2433 if opts.get('options'):
2434 2434 options = []
2435 2435 otables = [globalopts]
2436 2436 if cmd:
2437 2437 aliases, entry = cmdutil.findcmd(cmd, table, False)
2438 2438 otables.append(entry[1])
2439 2439 for t in otables:
2440 2440 for o in t:
2441 2441 if b"(DEPRECATED)" in o[3]:
2442 2442 continue
2443 2443 if o[0]:
2444 2444 options.append(b'-%s' % o[0])
2445 2445 options.append(b'--%s' % o[1])
2446 2446 ui.write(b"%s\n" % b"\n".join(options))
2447 2447 return
2448 2448
2449 2449 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2450 2450 if ui.verbose:
2451 2451 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2452 2452 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2453 2453
2454 2454
2455 2455 @command(
2456 2456 b'diff',
2457 2457 [
2458 2458 (b'r', b'rev', [], _(b'revision'), _(b'REV')),
2459 (b'', b'from', b'', _(b'revision to diff from'), _(b'REV')),
2460 (b'', b'to', b'', _(b'revision to diff to'), _(b'REV')),
2459 2461 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2460 2462 ]
2461 2463 + diffopts
2462 2464 + diffopts2
2463 2465 + walkopts
2464 2466 + subrepoopts,
2465 2467 _(b'[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
2466 2468 helpcategory=command.CATEGORY_FILE_CONTENTS,
2467 2469 helpbasic=True,
2468 2470 inferrepo=True,
2469 2471 intents={INTENT_READONLY},
2470 2472 )
2471 2473 def diff(ui, repo, *pats, **opts):
2472 2474 """diff repository (or selected files)
2473 2475
2474 2476 Show differences between revisions for the specified files.
2475 2477
2476 2478 Differences between files are shown using the unified diff format.
2477 2479
2478 2480 .. note::
2479 2481
2480 2482 :hg:`diff` may generate unexpected results for merges, as it will
2481 2483 default to comparing against the working directory's first
2482 2484 parent changeset if no revisions are specified.
2483 2485
2484 2486 When two revision arguments are given, then changes are shown
2485 2487 between those revisions. If only one revision is specified then
2486 2488 that revision is compared to the working directory, and, when no
2487 2489 revisions are specified, the working directory files are compared
2488 2490 to its first parent.
2489 2491
2490 2492 Alternatively you can specify -c/--change with a revision to see
2491 2493 the changes in that changeset relative to its first parent.
2492 2494
2493 2495 Without the -a/--text option, diff will avoid generating diffs of
2494 2496 files it detects as binary. With -a, diff will generate a diff
2495 2497 anyway, probably with undesirable results.
2496 2498
2497 2499 Use the -g/--git option to generate diffs in the git extended diff
2498 2500 format. For more information, read :hg:`help diffs`.
2499 2501
2500 2502 .. container:: verbose
2501 2503
2502 2504 Examples:
2503 2505
2504 2506 - compare a file in the current working directory to its parent::
2505 2507
2506 2508 hg diff foo.c
2507 2509
2508 2510 - compare two historical versions of a directory, with rename info::
2509 2511
2510 2512 hg diff --git -r 1.0:1.2 lib/
2511 2513
2512 2514 - get change stats relative to the last change on some date::
2513 2515
2514 2516 hg diff --stat -r "date('may 2')"
2515 2517
2516 2518 - diff all newly-added files that contain a keyword::
2517 2519
2518 2520 hg diff "set:added() and grep(GNU)"
2519 2521
2520 2522 - compare a revision and its parents::
2521 2523
2522 2524 hg diff -c 9353 # compare against first parent
2523 2525 hg diff -r 9353^:9353 # same using revset syntax
2524 2526 hg diff -r 9353^2:9353 # compare against the second parent
2525 2527
2526 2528 Returns 0 on success.
2527 2529 """
2528 2530
2529 2531 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
2530 2532 opts = pycompat.byteskwargs(opts)
2531 2533 revs = opts.get(b'rev')
2532 2534 change = opts.get(b'change')
2535 from_rev = opts.get(b'from')
2536 to_rev = opts.get(b'to')
2533 2537 stat = opts.get(b'stat')
2534 2538 reverse = opts.get(b'reverse')
2535 2539
2540 cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
2541 cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
2536 2542 if change:
2537 2543 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2538 2544 ctx2 = scmutil.revsingle(repo, change, None)
2539 2545 ctx1 = ctx2.p1()
2546 elif from_rev or to_rev:
2547 repo = scmutil.unhidehashlikerevs(
2548 repo, [from_rev] + [to_rev], b'nowarn'
2549 )
2550 ctx1 = scmutil.revsingle(repo, from_rev, None)
2551 ctx2 = scmutil.revsingle(repo, to_rev, None)
2540 2552 else:
2541 2553 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2542 2554 ctx1, ctx2 = scmutil.revpair(repo, revs)
2543 2555
2544 2556 if reverse:
2545 2557 ctxleft = ctx2
2546 2558 ctxright = ctx1
2547 2559 else:
2548 2560 ctxleft = ctx1
2549 2561 ctxright = ctx2
2550 2562
2551 2563 diffopts = patch.diffallopts(ui, opts)
2552 2564 m = scmutil.match(ctx2, pats, opts)
2553 2565 m = repo.narrowmatch(m)
2554 2566 ui.pager(b'diff')
2555 2567 logcmdutil.diffordiffstat(
2556 2568 ui,
2557 2569 repo,
2558 2570 diffopts,
2559 2571 ctxleft,
2560 2572 ctxright,
2561 2573 m,
2562 2574 stat=stat,
2563 2575 listsubrepos=opts.get(b'subrepos'),
2564 2576 root=opts.get(b'root'),
2565 2577 )
2566 2578
2567 2579
2568 2580 @command(
2569 2581 b'export',
2570 2582 [
2571 2583 (
2572 2584 b'B',
2573 2585 b'bookmark',
2574 2586 b'',
2575 2587 _(b'export changes only reachable by given bookmark'),
2576 2588 _(b'BOOKMARK'),
2577 2589 ),
2578 2590 (
2579 2591 b'o',
2580 2592 b'output',
2581 2593 b'',
2582 2594 _(b'print output to file with formatted name'),
2583 2595 _(b'FORMAT'),
2584 2596 ),
2585 2597 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2586 2598 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2587 2599 ]
2588 2600 + diffopts
2589 2601 + formatteropts,
2590 2602 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2591 2603 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2592 2604 helpbasic=True,
2593 2605 intents={INTENT_READONLY},
2594 2606 )
2595 2607 def export(ui, repo, *changesets, **opts):
2596 2608 """dump the header and diffs for one or more changesets
2597 2609
2598 2610 Print the changeset header and diffs for one or more revisions.
2599 2611 If no revision is given, the parent of the working directory is used.
2600 2612
2601 2613 The information shown in the changeset header is: author, date,
2602 2614 branch name (if non-default), changeset hash, parent(s) and commit
2603 2615 comment.
2604 2616
2605 2617 .. note::
2606 2618
2607 2619 :hg:`export` may generate unexpected diff output for merge
2608 2620 changesets, as it will compare the merge changeset against its
2609 2621 first parent only.
2610 2622
2611 2623 Output may be to a file, in which case the name of the file is
2612 2624 given using a template string. See :hg:`help templates`. In addition
2613 2625 to the common template keywords, the following formatting rules are
2614 2626 supported:
2615 2627
2616 2628 :``%%``: literal "%" character
2617 2629 :``%H``: changeset hash (40 hexadecimal digits)
2618 2630 :``%N``: number of patches being generated
2619 2631 :``%R``: changeset revision number
2620 2632 :``%b``: basename of the exporting repository
2621 2633 :``%h``: short-form changeset hash (12 hexadecimal digits)
2622 2634 :``%m``: first line of the commit message (only alphanumeric characters)
2623 2635 :``%n``: zero-padded sequence number, starting at 1
2624 2636 :``%r``: zero-padded changeset revision number
2625 2637 :``\\``: literal "\\" character
2626 2638
2627 2639 Without the -a/--text option, export will avoid generating diffs
2628 2640 of files it detects as binary. With -a, export will generate a
2629 2641 diff anyway, probably with undesirable results.
2630 2642
2631 2643 With -B/--bookmark changesets reachable by the given bookmark are
2632 2644 selected.
2633 2645
2634 2646 Use the -g/--git option to generate diffs in the git extended diff
2635 2647 format. See :hg:`help diffs` for more information.
2636 2648
2637 2649 With the --switch-parent option, the diff will be against the
2638 2650 second parent. It can be useful to review a merge.
2639 2651
2640 2652 .. container:: verbose
2641 2653
2642 2654 Template:
2643 2655
2644 2656 The following keywords are supported in addition to the common template
2645 2657 keywords and functions. See also :hg:`help templates`.
2646 2658
2647 2659 :diff: String. Diff content.
2648 2660 :parents: List of strings. Parent nodes of the changeset.
2649 2661
2650 2662 Examples:
2651 2663
2652 2664 - use export and import to transplant a bugfix to the current
2653 2665 branch::
2654 2666
2655 2667 hg export -r 9353 | hg import -
2656 2668
2657 2669 - export all the changesets between two revisions to a file with
2658 2670 rename information::
2659 2671
2660 2672 hg export --git -r 123:150 > changes.txt
2661 2673
2662 2674 - split outgoing changes into a series of patches with
2663 2675 descriptive names::
2664 2676
2665 2677 hg export -r "outgoing()" -o "%n-%m.patch"
2666 2678
2667 2679 Returns 0 on success.
2668 2680 """
2669 2681 opts = pycompat.byteskwargs(opts)
2670 2682 bookmark = opts.get(b'bookmark')
2671 2683 changesets += tuple(opts.get(b'rev', []))
2672 2684
2673 2685 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2674 2686
2675 2687 if bookmark:
2676 2688 if bookmark not in repo._bookmarks:
2677 2689 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2678 2690
2679 2691 revs = scmutil.bookmarkrevs(repo, bookmark)
2680 2692 else:
2681 2693 if not changesets:
2682 2694 changesets = [b'.']
2683 2695
2684 2696 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2685 2697 revs = scmutil.revrange(repo, changesets)
2686 2698
2687 2699 if not revs:
2688 2700 raise error.InputError(_(b"export requires at least one changeset"))
2689 2701 if len(revs) > 1:
2690 2702 ui.note(_(b'exporting patches:\n'))
2691 2703 else:
2692 2704 ui.note(_(b'exporting patch:\n'))
2693 2705
2694 2706 fntemplate = opts.get(b'output')
2695 2707 if cmdutil.isstdiofilename(fntemplate):
2696 2708 fntemplate = b''
2697 2709
2698 2710 if fntemplate:
2699 2711 fm = formatter.nullformatter(ui, b'export', opts)
2700 2712 else:
2701 2713 ui.pager(b'export')
2702 2714 fm = ui.formatter(b'export', opts)
2703 2715 with fm:
2704 2716 cmdutil.export(
2705 2717 repo,
2706 2718 revs,
2707 2719 fm,
2708 2720 fntemplate=fntemplate,
2709 2721 switch_parent=opts.get(b'switch_parent'),
2710 2722 opts=patch.diffallopts(ui, opts),
2711 2723 )
2712 2724
2713 2725
2714 2726 @command(
2715 2727 b'files',
2716 2728 [
2717 2729 (
2718 2730 b'r',
2719 2731 b'rev',
2720 2732 b'',
2721 2733 _(b'search the repository as it is in REV'),
2722 2734 _(b'REV'),
2723 2735 ),
2724 2736 (
2725 2737 b'0',
2726 2738 b'print0',
2727 2739 None,
2728 2740 _(b'end filenames with NUL, for use with xargs'),
2729 2741 ),
2730 2742 ]
2731 2743 + walkopts
2732 2744 + formatteropts
2733 2745 + subrepoopts,
2734 2746 _(b'[OPTION]... [FILE]...'),
2735 2747 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2736 2748 intents={INTENT_READONLY},
2737 2749 )
2738 2750 def files(ui, repo, *pats, **opts):
2739 2751 """list tracked files
2740 2752
2741 2753 Print files under Mercurial control in the working directory or
2742 2754 specified revision for given files (excluding removed files).
2743 2755 Files can be specified as filenames or filesets.
2744 2756
2745 2757 If no files are given to match, this command prints the names
2746 2758 of all files under Mercurial control.
2747 2759
2748 2760 .. container:: verbose
2749 2761
2750 2762 Template:
2751 2763
2752 2764 The following keywords are supported in addition to the common template
2753 2765 keywords and functions. See also :hg:`help templates`.
2754 2766
2755 2767 :flags: String. Character denoting file's symlink and executable bits.
2756 2768 :path: String. Repository-absolute path of the file.
2757 2769 :size: Integer. Size of the file in bytes.
2758 2770
2759 2771 Examples:
2760 2772
2761 2773 - list all files under the current directory::
2762 2774
2763 2775 hg files .
2764 2776
2765 2777 - shows sizes and flags for current revision::
2766 2778
2767 2779 hg files -vr .
2768 2780
2769 2781 - list all files named README::
2770 2782
2771 2783 hg files -I "**/README"
2772 2784
2773 2785 - list all binary files::
2774 2786
2775 2787 hg files "set:binary()"
2776 2788
2777 2789 - find files containing a regular expression::
2778 2790
2779 2791 hg files "set:grep('bob')"
2780 2792
2781 2793 - search tracked file contents with xargs and grep::
2782 2794
2783 2795 hg files -0 | xargs -0 grep foo
2784 2796
2785 2797 See :hg:`help patterns` and :hg:`help filesets` for more information
2786 2798 on specifying file patterns.
2787 2799
2788 2800 Returns 0 if a match is found, 1 otherwise.
2789 2801
2790 2802 """
2791 2803
2792 2804 opts = pycompat.byteskwargs(opts)
2793 2805 rev = opts.get(b'rev')
2794 2806 if rev:
2795 2807 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2796 2808 ctx = scmutil.revsingle(repo, rev, None)
2797 2809
2798 2810 end = b'\n'
2799 2811 if opts.get(b'print0'):
2800 2812 end = b'\0'
2801 2813 fmt = b'%s' + end
2802 2814
2803 2815 m = scmutil.match(ctx, pats, opts)
2804 2816 ui.pager(b'files')
2805 2817 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2806 2818 with ui.formatter(b'files', opts) as fm:
2807 2819 return cmdutil.files(
2808 2820 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2809 2821 )
2810 2822
2811 2823
2812 2824 @command(
2813 2825 b'forget',
2814 2826 [
2815 2827 (b'i', b'interactive', None, _(b'use interactive mode')),
2816 2828 ]
2817 2829 + walkopts
2818 2830 + dryrunopts,
2819 2831 _(b'[OPTION]... FILE...'),
2820 2832 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2821 2833 helpbasic=True,
2822 2834 inferrepo=True,
2823 2835 )
2824 2836 def forget(ui, repo, *pats, **opts):
2825 2837 """forget the specified files on the next commit
2826 2838
2827 2839 Mark the specified files so they will no longer be tracked
2828 2840 after the next commit.
2829 2841
2830 2842 This only removes files from the current branch, not from the
2831 2843 entire project history, and it does not delete them from the
2832 2844 working directory.
2833 2845
2834 2846 To delete the file from the working directory, see :hg:`remove`.
2835 2847
2836 2848 To undo a forget before the next commit, see :hg:`add`.
2837 2849
2838 2850 .. container:: verbose
2839 2851
2840 2852 Examples:
2841 2853
2842 2854 - forget newly-added binary files::
2843 2855
2844 2856 hg forget "set:added() and binary()"
2845 2857
2846 2858 - forget files that would be excluded by .hgignore::
2847 2859
2848 2860 hg forget "set:hgignore()"
2849 2861
2850 2862 Returns 0 on success.
2851 2863 """
2852 2864
2853 2865 opts = pycompat.byteskwargs(opts)
2854 2866 if not pats:
2855 2867 raise error.InputError(_(b'no files specified'))
2856 2868
2857 2869 m = scmutil.match(repo[None], pats, opts)
2858 2870 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2859 2871 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2860 2872 rejected = cmdutil.forget(
2861 2873 ui,
2862 2874 repo,
2863 2875 m,
2864 2876 prefix=b"",
2865 2877 uipathfn=uipathfn,
2866 2878 explicitonly=False,
2867 2879 dryrun=dryrun,
2868 2880 interactive=interactive,
2869 2881 )[0]
2870 2882 return rejected and 1 or 0
2871 2883
2872 2884
2873 2885 @command(
2874 2886 b'graft',
2875 2887 [
2876 2888 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
2877 2889 (
2878 2890 b'',
2879 2891 b'base',
2880 2892 b'',
2881 2893 _(b'base revision when doing the graft merge (ADVANCED)'),
2882 2894 _(b'REV'),
2883 2895 ),
2884 2896 (b'c', b'continue', False, _(b'resume interrupted graft')),
2885 2897 (b'', b'stop', False, _(b'stop interrupted graft')),
2886 2898 (b'', b'abort', False, _(b'abort interrupted graft')),
2887 2899 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
2888 2900 (b'', b'log', None, _(b'append graft info to log message')),
2889 2901 (
2890 2902 b'',
2891 2903 b'no-commit',
2892 2904 None,
2893 2905 _(b"don't commit, just apply the changes in working directory"),
2894 2906 ),
2895 2907 (b'f', b'force', False, _(b'force graft')),
2896 2908 (
2897 2909 b'D',
2898 2910 b'currentdate',
2899 2911 False,
2900 2912 _(b'record the current date as commit date'),
2901 2913 ),
2902 2914 (
2903 2915 b'U',
2904 2916 b'currentuser',
2905 2917 False,
2906 2918 _(b'record the current user as committer'),
2907 2919 ),
2908 2920 ]
2909 2921 + commitopts2
2910 2922 + mergetoolopts
2911 2923 + dryrunopts,
2912 2924 _(b'[OPTION]... [-r REV]... REV...'),
2913 2925 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2914 2926 )
2915 2927 def graft(ui, repo, *revs, **opts):
2916 2928 """copy changes from other branches onto the current branch
2917 2929
2918 2930 This command uses Mercurial's merge logic to copy individual
2919 2931 changes from other branches without merging branches in the
2920 2932 history graph. This is sometimes known as 'backporting' or
2921 2933 'cherry-picking'. By default, graft will copy user, date, and
2922 2934 description from the source changesets.
2923 2935
2924 2936 Changesets that are ancestors of the current revision, that have
2925 2937 already been grafted, or that are merges will be skipped.
2926 2938
2927 2939 If --log is specified, log messages will have a comment appended
2928 2940 of the form::
2929 2941
2930 2942 (grafted from CHANGESETHASH)
2931 2943
2932 2944 If --force is specified, revisions will be grafted even if they
2933 2945 are already ancestors of, or have been grafted to, the destination.
2934 2946 This is useful when the revisions have since been backed out.
2935 2947
2936 2948 If a graft merge results in conflicts, the graft process is
2937 2949 interrupted so that the current merge can be manually resolved.
2938 2950 Once all conflicts are addressed, the graft process can be
2939 2951 continued with the -c/--continue option.
2940 2952
2941 2953 The -c/--continue option reapplies all the earlier options.
2942 2954
2943 2955 .. container:: verbose
2944 2956
2945 2957 The --base option exposes more of how graft internally uses merge with a
2946 2958 custom base revision. --base can be used to specify another ancestor than
2947 2959 the first and only parent.
2948 2960
2949 2961 The command::
2950 2962
2951 2963 hg graft -r 345 --base 234
2952 2964
2953 2965 is thus pretty much the same as::
2954 2966
2955 2967 hg diff -r 234 -r 345 | hg import
2956 2968
2957 2969 but using merge to resolve conflicts and track moved files.
2958 2970
2959 2971 The result of a merge can thus be backported as a single commit by
2960 2972 specifying one of the merge parents as base, and thus effectively
2961 2973 grafting the changes from the other side.
2962 2974
2963 2975 It is also possible to collapse multiple changesets and clean up history
2964 2976 by specifying another ancestor as base, much like rebase --collapse
2965 2977 --keep.
2966 2978
2967 2979 The commit message can be tweaked after the fact using commit --amend .
2968 2980
2969 2981 For using non-ancestors as the base to backout changes, see the backout
2970 2982 command and the hidden --parent option.
2971 2983
2972 2984 .. container:: verbose
2973 2985
2974 2986 Examples:
2975 2987
2976 2988 - copy a single change to the stable branch and edit its description::
2977 2989
2978 2990 hg update stable
2979 2991 hg graft --edit 9393
2980 2992
2981 2993 - graft a range of changesets with one exception, updating dates::
2982 2994
2983 2995 hg graft -D "2085::2093 and not 2091"
2984 2996
2985 2997 - continue a graft after resolving conflicts::
2986 2998
2987 2999 hg graft -c
2988 3000
2989 3001 - show the source of a grafted changeset::
2990 3002
2991 3003 hg log --debug -r .
2992 3004
2993 3005 - show revisions sorted by date::
2994 3006
2995 3007 hg log -r "sort(all(), date)"
2996 3008
2997 3009 - backport the result of a merge as a single commit::
2998 3010
2999 3011 hg graft -r 123 --base 123^
3000 3012
3001 3013 - land a feature branch as one changeset::
3002 3014
3003 3015 hg up -cr default
3004 3016 hg graft -r featureX --base "ancestor('featureX', 'default')"
3005 3017
3006 3018 See :hg:`help revisions` for more about specifying revisions.
3007 3019
3008 3020 Returns 0 on successful completion, 1 if there are unresolved files.
3009 3021 """
3010 3022 with repo.wlock():
3011 3023 return _dograft(ui, repo, *revs, **opts)
3012 3024
3013 3025
3014 3026 def _dograft(ui, repo, *revs, **opts):
3015 3027 opts = pycompat.byteskwargs(opts)
3016 3028 if revs and opts.get(b'rev'):
3017 3029 ui.warn(
3018 3030 _(
3019 3031 b'warning: inconsistent use of --rev might give unexpected '
3020 3032 b'revision ordering!\n'
3021 3033 )
3022 3034 )
3023 3035
3024 3036 revs = list(revs)
3025 3037 revs.extend(opts.get(b'rev'))
3026 3038 # a dict of data to be stored in state file
3027 3039 statedata = {}
3028 3040 # list of new nodes created by ongoing graft
3029 3041 statedata[b'newnodes'] = []
3030 3042
3031 3043 cmdutil.resolvecommitoptions(ui, opts)
3032 3044
3033 3045 editor = cmdutil.getcommiteditor(
3034 3046 editform=b'graft', **pycompat.strkwargs(opts)
3035 3047 )
3036 3048
3037 3049 cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue')
3038 3050
3039 3051 cont = False
3040 3052 if opts.get(b'no_commit'):
3041 3053 cmdutil.check_incompatible_arguments(
3042 3054 opts,
3043 3055 b'no_commit',
3044 3056 [b'edit', b'currentuser', b'currentdate', b'log'],
3045 3057 )
3046 3058
3047 3059 graftstate = statemod.cmdstate(repo, b'graftstate')
3048 3060
3049 3061 if opts.get(b'stop'):
3050 3062 cmdutil.check_incompatible_arguments(
3051 3063 opts,
3052 3064 b'stop',
3053 3065 [
3054 3066 b'edit',
3055 3067 b'log',
3056 3068 b'user',
3057 3069 b'date',
3058 3070 b'currentdate',
3059 3071 b'currentuser',
3060 3072 b'rev',
3061 3073 ],
3062 3074 )
3063 3075 return _stopgraft(ui, repo, graftstate)
3064 3076 elif opts.get(b'abort'):
3065 3077 cmdutil.check_incompatible_arguments(
3066 3078 opts,
3067 3079 b'abort',
3068 3080 [
3069 3081 b'edit',
3070 3082 b'log',
3071 3083 b'user',
3072 3084 b'date',
3073 3085 b'currentdate',
3074 3086 b'currentuser',
3075 3087 b'rev',
3076 3088 ],
3077 3089 )
3078 3090 return cmdutil.abortgraft(ui, repo, graftstate)
3079 3091 elif opts.get(b'continue'):
3080 3092 cont = True
3081 3093 if revs:
3082 3094 raise error.InputError(_(b"can't specify --continue and revisions"))
3083 3095 # read in unfinished revisions
3084 3096 if graftstate.exists():
3085 3097 statedata = cmdutil.readgraftstate(repo, graftstate)
3086 3098 if statedata.get(b'date'):
3087 3099 opts[b'date'] = statedata[b'date']
3088 3100 if statedata.get(b'user'):
3089 3101 opts[b'user'] = statedata[b'user']
3090 3102 if statedata.get(b'log'):
3091 3103 opts[b'log'] = True
3092 3104 if statedata.get(b'no_commit'):
3093 3105 opts[b'no_commit'] = statedata.get(b'no_commit')
3094 3106 if statedata.get(b'base'):
3095 3107 opts[b'base'] = statedata.get(b'base')
3096 3108 nodes = statedata[b'nodes']
3097 3109 revs = [repo[node].rev() for node in nodes]
3098 3110 else:
3099 3111 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3100 3112 else:
3101 3113 if not revs:
3102 3114 raise error.InputError(_(b'no revisions specified'))
3103 3115 cmdutil.checkunfinished(repo)
3104 3116 cmdutil.bailifchanged(repo)
3105 3117 revs = scmutil.revrange(repo, revs)
3106 3118
3107 3119 skipped = set()
3108 3120 basectx = None
3109 3121 if opts.get(b'base'):
3110 3122 basectx = scmutil.revsingle(repo, opts[b'base'], None)
3111 3123 if basectx is None:
3112 3124 # check for merges
3113 3125 for rev in repo.revs(b'%ld and merge()', revs):
3114 3126 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3115 3127 skipped.add(rev)
3116 3128 revs = [r for r in revs if r not in skipped]
3117 3129 if not revs:
3118 3130 return -1
3119 3131 if basectx is not None and len(revs) != 1:
3120 3132 raise error.InputError(_(b'only one revision allowed with --base '))
3121 3133
3122 3134 # Don't check in the --continue case, in effect retaining --force across
3123 3135 # --continues. That's because without --force, any revisions we decided to
3124 3136 # skip would have been filtered out here, so they wouldn't have made their
3125 3137 # way to the graftstate. With --force, any revisions we would have otherwise
3126 3138 # skipped would not have been filtered out, and if they hadn't been applied
3127 3139 # already, they'd have been in the graftstate.
3128 3140 if not (cont or opts.get(b'force')) and basectx is None:
3129 3141 # check for ancestors of dest branch
3130 3142 ancestors = repo.revs(b'%ld & (::.)', revs)
3131 3143 for rev in ancestors:
3132 3144 ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev]))
3133 3145
3134 3146 revs = [r for r in revs if r not in ancestors]
3135 3147
3136 3148 if not revs:
3137 3149 return -1
3138 3150
3139 3151 # analyze revs for earlier grafts
3140 3152 ids = {}
3141 3153 for ctx in repo.set(b"%ld", revs):
3142 3154 ids[ctx.hex()] = ctx.rev()
3143 3155 n = ctx.extra().get(b'source')
3144 3156 if n:
3145 3157 ids[n] = ctx.rev()
3146 3158
3147 3159 # check ancestors for earlier grafts
3148 3160 ui.debug(b'scanning for duplicate grafts\n')
3149 3161
3150 3162 # The only changesets we can be sure doesn't contain grafts of any
3151 3163 # revs, are the ones that are common ancestors of *all* revs:
3152 3164 for rev in repo.revs(b'only(%d,ancestor(%ld))', repo[b'.'].rev(), revs):
3153 3165 ctx = repo[rev]
3154 3166 n = ctx.extra().get(b'source')
3155 3167 if n in ids:
3156 3168 try:
3157 3169 r = repo[n].rev()
3158 3170 except error.RepoLookupError:
3159 3171 r = None
3160 3172 if r in revs:
3161 3173 ui.warn(
3162 3174 _(
3163 3175 b'skipping revision %d:%s '
3164 3176 b'(already grafted to %d:%s)\n'
3165 3177 )
3166 3178 % (r, repo[r], rev, ctx)
3167 3179 )
3168 3180 revs.remove(r)
3169 3181 elif ids[n] in revs:
3170 3182 if r is None:
3171 3183 ui.warn(
3172 3184 _(
3173 3185 b'skipping already grafted revision %d:%s '
3174 3186 b'(%d:%s also has unknown origin %s)\n'
3175 3187 )
3176 3188 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3177 3189 )
3178 3190 else:
3179 3191 ui.warn(
3180 3192 _(
3181 3193 b'skipping already grafted revision %d:%s '
3182 3194 b'(%d:%s also has origin %d:%s)\n'
3183 3195 )
3184 3196 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3185 3197 )
3186 3198 revs.remove(ids[n])
3187 3199 elif ctx.hex() in ids:
3188 3200 r = ids[ctx.hex()]
3189 3201 if r in revs:
3190 3202 ui.warn(
3191 3203 _(
3192 3204 b'skipping already grafted revision %d:%s '
3193 3205 b'(was grafted from %d:%s)\n'
3194 3206 )
3195 3207 % (r, repo[r], rev, ctx)
3196 3208 )
3197 3209 revs.remove(r)
3198 3210 if not revs:
3199 3211 return -1
3200 3212
3201 3213 if opts.get(b'no_commit'):
3202 3214 statedata[b'no_commit'] = True
3203 3215 if opts.get(b'base'):
3204 3216 statedata[b'base'] = opts[b'base']
3205 3217 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3206 3218 desc = b'%d:%s "%s"' % (
3207 3219 ctx.rev(),
3208 3220 ctx,
3209 3221 ctx.description().split(b'\n', 1)[0],
3210 3222 )
3211 3223 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3212 3224 if names:
3213 3225 desc += b' (%s)' % b' '.join(names)
3214 3226 ui.status(_(b'grafting %s\n') % desc)
3215 3227 if opts.get(b'dry_run'):
3216 3228 continue
3217 3229
3218 3230 source = ctx.extra().get(b'source')
3219 3231 extra = {}
3220 3232 if source:
3221 3233 extra[b'source'] = source
3222 3234 extra[b'intermediate-source'] = ctx.hex()
3223 3235 else:
3224 3236 extra[b'source'] = ctx.hex()
3225 3237 user = ctx.user()
3226 3238 if opts.get(b'user'):
3227 3239 user = opts[b'user']
3228 3240 statedata[b'user'] = user
3229 3241 date = ctx.date()
3230 3242 if opts.get(b'date'):
3231 3243 date = opts[b'date']
3232 3244 statedata[b'date'] = date
3233 3245 message = ctx.description()
3234 3246 if opts.get(b'log'):
3235 3247 message += b'\n(grafted from %s)' % ctx.hex()
3236 3248 statedata[b'log'] = True
3237 3249
3238 3250 # we don't merge the first commit when continuing
3239 3251 if not cont:
3240 3252 # perform the graft merge with p1(rev) as 'ancestor'
3241 3253 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
3242 3254 base = ctx.p1() if basectx is None else basectx
3243 3255 with ui.configoverride(overrides, b'graft'):
3244 3256 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
3245 3257 # report any conflicts
3246 3258 if stats.unresolvedcount > 0:
3247 3259 # write out state for --continue
3248 3260 nodes = [repo[rev].hex() for rev in revs[pos:]]
3249 3261 statedata[b'nodes'] = nodes
3250 3262 stateversion = 1
3251 3263 graftstate.save(stateversion, statedata)
3252 3264 ui.error(_(b"abort: unresolved conflicts, can't continue\n"))
3253 3265 ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n"))
3254 3266 return 1
3255 3267 else:
3256 3268 cont = False
3257 3269
3258 3270 # commit if --no-commit is false
3259 3271 if not opts.get(b'no_commit'):
3260 3272 node = repo.commit(
3261 3273 text=message, user=user, date=date, extra=extra, editor=editor
3262 3274 )
3263 3275 if node is None:
3264 3276 ui.warn(
3265 3277 _(b'note: graft of %d:%s created no changes to commit\n')
3266 3278 % (ctx.rev(), ctx)
3267 3279 )
3268 3280 # checking that newnodes exist because old state files won't have it
3269 3281 elif statedata.get(b'newnodes') is not None:
3270 3282 statedata[b'newnodes'].append(node)
3271 3283
3272 3284 # remove state when we complete successfully
3273 3285 if not opts.get(b'dry_run'):
3274 3286 graftstate.delete()
3275 3287
3276 3288 return 0
3277 3289
3278 3290
3279 3291 def _stopgraft(ui, repo, graftstate):
3280 3292 """stop the interrupted graft"""
3281 3293 if not graftstate.exists():
3282 3294 raise error.StateError(_(b"no interrupted graft found"))
3283 3295 pctx = repo[b'.']
3284 3296 mergemod.clean_update(pctx)
3285 3297 graftstate.delete()
3286 3298 ui.status(_(b"stopped the interrupted graft\n"))
3287 3299 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3288 3300 return 0
3289 3301
3290 3302
3291 3303 statemod.addunfinished(
3292 3304 b'graft',
3293 3305 fname=b'graftstate',
3294 3306 clearable=True,
3295 3307 stopflag=True,
3296 3308 continueflag=True,
3297 3309 abortfunc=cmdutil.hgabortgraft,
3298 3310 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3299 3311 )
3300 3312
3301 3313
3302 3314 @command(
3303 3315 b'grep',
3304 3316 [
3305 3317 (b'0', b'print0', None, _(b'end fields with NUL')),
3306 3318 (b'', b'all', None, _(b'an alias to --diff (DEPRECATED)')),
3307 3319 (
3308 3320 b'',
3309 3321 b'diff',
3310 3322 None,
3311 3323 _(
3312 3324 b'search revision differences for when the pattern was added '
3313 3325 b'or removed'
3314 3326 ),
3315 3327 ),
3316 3328 (b'a', b'text', None, _(b'treat all files as text')),
3317 3329 (
3318 3330 b'f',
3319 3331 b'follow',
3320 3332 None,
3321 3333 _(
3322 3334 b'follow changeset history,'
3323 3335 b' or file history across copies and renames'
3324 3336 ),
3325 3337 ),
3326 3338 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3327 3339 (
3328 3340 b'l',
3329 3341 b'files-with-matches',
3330 3342 None,
3331 3343 _(b'print only filenames and revisions that match'),
3332 3344 ),
3333 3345 (b'n', b'line-number', None, _(b'print matching line numbers')),
3334 3346 (
3335 3347 b'r',
3336 3348 b'rev',
3337 3349 [],
3338 3350 _(b'search files changed within revision range'),
3339 3351 _(b'REV'),
3340 3352 ),
3341 3353 (
3342 3354 b'',
3343 3355 b'all-files',
3344 3356 None,
3345 3357 _(
3346 3358 b'include all files in the changeset while grepping (DEPRECATED)'
3347 3359 ),
3348 3360 ),
3349 3361 (b'u', b'user', None, _(b'list the author (long with -v)')),
3350 3362 (b'd', b'date', None, _(b'list the date (short with -q)')),
3351 3363 ]
3352 3364 + formatteropts
3353 3365 + walkopts,
3354 3366 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3355 3367 helpcategory=command.CATEGORY_FILE_CONTENTS,
3356 3368 inferrepo=True,
3357 3369 intents={INTENT_READONLY},
3358 3370 )
3359 3371 def grep(ui, repo, pattern, *pats, **opts):
3360 3372 """search for a pattern in specified files
3361 3373
3362 3374 Search the working directory or revision history for a regular
3363 3375 expression in the specified files for the entire repository.
3364 3376
3365 3377 By default, grep searches the repository files in the working
3366 3378 directory and prints the files where it finds a match. To specify
3367 3379 historical revisions instead of the working directory, use the
3368 3380 --rev flag.
3369 3381
3370 3382 To search instead historical revision differences that contains a
3371 3383 change in match status ("-" for a match that becomes a non-match,
3372 3384 or "+" for a non-match that becomes a match), use the --diff flag.
3373 3385
3374 3386 PATTERN can be any Python (roughly Perl-compatible) regular
3375 3387 expression.
3376 3388
3377 3389 If no FILEs are specified and the --rev flag isn't supplied, all
3378 3390 files in the working directory are searched. When using the --rev
3379 3391 flag and specifying FILEs, use the --follow argument to also
3380 3392 follow the specified FILEs across renames and copies.
3381 3393
3382 3394 .. container:: verbose
3383 3395
3384 3396 Template:
3385 3397
3386 3398 The following keywords are supported in addition to the common template
3387 3399 keywords and functions. See also :hg:`help templates`.
3388 3400
3389 3401 :change: String. Character denoting insertion ``+`` or removal ``-``.
3390 3402 Available if ``--diff`` is specified.
3391 3403 :lineno: Integer. Line number of the match.
3392 3404 :path: String. Repository-absolute path of the file.
3393 3405 :texts: List of text chunks.
3394 3406
3395 3407 And each entry of ``{texts}`` provides the following sub-keywords.
3396 3408
3397 3409 :matched: Boolean. True if the chunk matches the specified pattern.
3398 3410 :text: String. Chunk content.
3399 3411
3400 3412 See :hg:`help templates.operators` for the list expansion syntax.
3401 3413
3402 3414 Returns 0 if a match is found, 1 otherwise.
3403 3415
3404 3416 """
3405 3417 cmdutil.check_incompatible_arguments(opts, 'all_files', ['all', 'diff'])
3406 3418 opts = pycompat.byteskwargs(opts)
3407 3419 diff = opts.get(b'all') or opts.get(b'diff')
3408 3420 follow = opts.get(b'follow')
3409 3421 if opts.get(b'all_files') is None and not diff:
3410 3422 opts[b'all_files'] = True
3411 3423 plaingrep = (
3412 3424 opts.get(b'all_files')
3413 3425 and not opts.get(b'rev')
3414 3426 and not opts.get(b'follow')
3415 3427 )
3416 3428 all_files = opts.get(b'all_files')
3417 3429 if plaingrep:
3418 3430 opts[b'rev'] = [b'wdir()']
3419 3431
3420 3432 reflags = re.M
3421 3433 if opts.get(b'ignore_case'):
3422 3434 reflags |= re.I
3423 3435 try:
3424 3436 regexp = util.re.compile(pattern, reflags)
3425 3437 except re.error as inst:
3426 3438 ui.warn(
3427 3439 _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
3428 3440 )
3429 3441 return 1
3430 3442 sep, eol = b':', b'\n'
3431 3443 if opts.get(b'print0'):
3432 3444 sep = eol = b'\0'
3433 3445
3434 3446 searcher = grepmod.grepsearcher(
3435 3447 ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
3436 3448 )
3437 3449
3438 3450 getfile = searcher._getfile
3439 3451
3440 3452 uipathfn = scmutil.getuipathfn(repo)
3441 3453
3442 3454 def display(fm, fn, ctx, pstates, states):
3443 3455 rev = scmutil.intrev(ctx)
3444 3456 if fm.isplain():
3445 3457 formatuser = ui.shortuser
3446 3458 else:
3447 3459 formatuser = pycompat.bytestr
3448 3460 if ui.quiet:
3449 3461 datefmt = b'%Y-%m-%d'
3450 3462 else:
3451 3463 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3452 3464 found = False
3453 3465
3454 3466 @util.cachefunc
3455 3467 def binary():
3456 3468 flog = getfile(fn)
3457 3469 try:
3458 3470 return stringutil.binary(flog.read(ctx.filenode(fn)))
3459 3471 except error.WdirUnsupported:
3460 3472 return ctx[fn].isbinary()
3461 3473
3462 3474 fieldnamemap = {b'linenumber': b'lineno'}
3463 3475 if diff:
3464 3476 iter = grepmod.difflinestates(pstates, states)
3465 3477 else:
3466 3478 iter = [(b'', l) for l in states]
3467 3479 for change, l in iter:
3468 3480 fm.startitem()
3469 3481 fm.context(ctx=ctx)
3470 3482 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3471 3483 fm.plain(uipathfn(fn), label=b'grep.filename')
3472 3484
3473 3485 cols = [
3474 3486 (b'rev', b'%d', rev, not plaingrep, b''),
3475 3487 (
3476 3488 b'linenumber',
3477 3489 b'%d',
3478 3490 l.linenum,
3479 3491 opts.get(b'line_number'),
3480 3492 b'',
3481 3493 ),
3482 3494 ]
3483 3495 if diff:
3484 3496 cols.append(
3485 3497 (
3486 3498 b'change',
3487 3499 b'%s',
3488 3500 change,
3489 3501 True,
3490 3502 b'grep.inserted '
3491 3503 if change == b'+'
3492 3504 else b'grep.deleted ',
3493 3505 )
3494 3506 )
3495 3507 cols.extend(
3496 3508 [
3497 3509 (
3498 3510 b'user',
3499 3511 b'%s',
3500 3512 formatuser(ctx.user()),
3501 3513 opts.get(b'user'),
3502 3514 b'',
3503 3515 ),
3504 3516 (
3505 3517 b'date',
3506 3518 b'%s',
3507 3519 fm.formatdate(ctx.date(), datefmt),
3508 3520 opts.get(b'date'),
3509 3521 b'',
3510 3522 ),
3511 3523 ]
3512 3524 )
3513 3525 for name, fmt, data, cond, extra_label in cols:
3514 3526 if cond:
3515 3527 fm.plain(sep, label=b'grep.sep')
3516 3528 field = fieldnamemap.get(name, name)
3517 3529 label = extra_label + (b'grep.%s' % name)
3518 3530 fm.condwrite(cond, field, fmt, data, label=label)
3519 3531 if not opts.get(b'files_with_matches'):
3520 3532 fm.plain(sep, label=b'grep.sep')
3521 3533 if not opts.get(b'text') and binary():
3522 3534 fm.plain(_(b" Binary file matches"))
3523 3535 else:
3524 3536 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3525 3537 fm.plain(eol)
3526 3538 found = True
3527 3539 if opts.get(b'files_with_matches'):
3528 3540 break
3529 3541 return found
3530 3542
3531 3543 def displaymatches(fm, l):
3532 3544 p = 0
3533 3545 for s, e in l.findpos(regexp):
3534 3546 if p < s:
3535 3547 fm.startitem()
3536 3548 fm.write(b'text', b'%s', l.line[p:s])
3537 3549 fm.data(matched=False)
3538 3550 fm.startitem()
3539 3551 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3540 3552 fm.data(matched=True)
3541 3553 p = e
3542 3554 if p < len(l.line):
3543 3555 fm.startitem()
3544 3556 fm.write(b'text', b'%s', l.line[p:])
3545 3557 fm.data(matched=False)
3546 3558 fm.end()
3547 3559
3548 3560 found = False
3549 3561
3550 3562 wopts = logcmdutil.walkopts(
3551 3563 pats=pats,
3552 3564 opts=opts,
3553 3565 revspec=opts[b'rev'],
3554 3566 include_pats=opts[b'include'],
3555 3567 exclude_pats=opts[b'exclude'],
3556 3568 follow=follow,
3557 3569 force_changelog_traversal=all_files,
3558 3570 filter_revisions_by_pats=not all_files,
3559 3571 )
3560 3572 revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
3561 3573
3562 3574 ui.pager(b'grep')
3563 3575 fm = ui.formatter(b'grep', opts)
3564 3576 for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
3565 3577 r = display(fm, fn, ctx, pstates, states)
3566 3578 found = found or r
3567 3579 if r and not diff and not all_files:
3568 3580 searcher.skipfile(fn, ctx.rev())
3569 3581 fm.end()
3570 3582
3571 3583 return not found
3572 3584
3573 3585
3574 3586 @command(
3575 3587 b'heads',
3576 3588 [
3577 3589 (
3578 3590 b'r',
3579 3591 b'rev',
3580 3592 b'',
3581 3593 _(b'show only heads which are descendants of STARTREV'),
3582 3594 _(b'STARTREV'),
3583 3595 ),
3584 3596 (b't', b'topo', False, _(b'show topological heads only')),
3585 3597 (
3586 3598 b'a',
3587 3599 b'active',
3588 3600 False,
3589 3601 _(b'show active branchheads only (DEPRECATED)'),
3590 3602 ),
3591 3603 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3592 3604 ]
3593 3605 + templateopts,
3594 3606 _(b'[-ct] [-r STARTREV] [REV]...'),
3595 3607 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3596 3608 intents={INTENT_READONLY},
3597 3609 )
3598 3610 def heads(ui, repo, *branchrevs, **opts):
3599 3611 """show branch heads
3600 3612
3601 3613 With no arguments, show all open branch heads in the repository.
3602 3614 Branch heads are changesets that have no descendants on the
3603 3615 same branch. They are where development generally takes place and
3604 3616 are the usual targets for update and merge operations.
3605 3617
3606 3618 If one or more REVs are given, only open branch heads on the
3607 3619 branches associated with the specified changesets are shown. This
3608 3620 means that you can use :hg:`heads .` to see the heads on the
3609 3621 currently checked-out branch.
3610 3622
3611 3623 If -c/--closed is specified, also show branch heads marked closed
3612 3624 (see :hg:`commit --close-branch`).
3613 3625
3614 3626 If STARTREV is specified, only those heads that are descendants of
3615 3627 STARTREV will be displayed.
3616 3628
3617 3629 If -t/--topo is specified, named branch mechanics will be ignored and only
3618 3630 topological heads (changesets with no children) will be shown.
3619 3631
3620 3632 Returns 0 if matching heads are found, 1 if not.
3621 3633 """
3622 3634
3623 3635 opts = pycompat.byteskwargs(opts)
3624 3636 start = None
3625 3637 rev = opts.get(b'rev')
3626 3638 if rev:
3627 3639 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3628 3640 start = scmutil.revsingle(repo, rev, None).node()
3629 3641
3630 3642 if opts.get(b'topo'):
3631 3643 heads = [repo[h] for h in repo.heads(start)]
3632 3644 else:
3633 3645 heads = []
3634 3646 for branch in repo.branchmap():
3635 3647 heads += repo.branchheads(branch, start, opts.get(b'closed'))
3636 3648 heads = [repo[h] for h in heads]
3637 3649
3638 3650 if branchrevs:
3639 3651 branches = {
3640 3652 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3641 3653 }
3642 3654 heads = [h for h in heads if h.branch() in branches]
3643 3655
3644 3656 if opts.get(b'active') and branchrevs:
3645 3657 dagheads = repo.heads(start)
3646 3658 heads = [h for h in heads if h.node() in dagheads]
3647 3659
3648 3660 if branchrevs:
3649 3661 haveheads = {h.branch() for h in heads}
3650 3662 if branches - haveheads:
3651 3663 headless = b', '.join(b for b in branches - haveheads)
3652 3664 msg = _(b'no open branch heads found on branches %s')
3653 3665 if opts.get(b'rev'):
3654 3666 msg += _(b' (started at %s)') % opts[b'rev']
3655 3667 ui.warn((msg + b'\n') % headless)
3656 3668
3657 3669 if not heads:
3658 3670 return 1
3659 3671
3660 3672 ui.pager(b'heads')
3661 3673 heads = sorted(heads, key=lambda x: -(x.rev()))
3662 3674 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3663 3675 for ctx in heads:
3664 3676 displayer.show(ctx)
3665 3677 displayer.close()
3666 3678
3667 3679
3668 3680 @command(
3669 3681 b'help',
3670 3682 [
3671 3683 (b'e', b'extension', None, _(b'show only help for extensions')),
3672 3684 (b'c', b'command', None, _(b'show only help for commands')),
3673 3685 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3674 3686 (
3675 3687 b's',
3676 3688 b'system',
3677 3689 [],
3678 3690 _(b'show help for specific platform(s)'),
3679 3691 _(b'PLATFORM'),
3680 3692 ),
3681 3693 ],
3682 3694 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3683 3695 helpcategory=command.CATEGORY_HELP,
3684 3696 norepo=True,
3685 3697 intents={INTENT_READONLY},
3686 3698 )
3687 3699 def help_(ui, name=None, **opts):
3688 3700 """show help for a given topic or a help overview
3689 3701
3690 3702 With no arguments, print a list of commands with short help messages.
3691 3703
3692 3704 Given a topic, extension, or command name, print help for that
3693 3705 topic.
3694 3706
3695 3707 Returns 0 if successful.
3696 3708 """
3697 3709
3698 3710 keep = opts.get('system') or []
3699 3711 if len(keep) == 0:
3700 3712 if pycompat.sysplatform.startswith(b'win'):
3701 3713 keep.append(b'windows')
3702 3714 elif pycompat.sysplatform == b'OpenVMS':
3703 3715 keep.append(b'vms')
3704 3716 elif pycompat.sysplatform == b'plan9':
3705 3717 keep.append(b'plan9')
3706 3718 else:
3707 3719 keep.append(b'unix')
3708 3720 keep.append(pycompat.sysplatform.lower())
3709 3721 if ui.verbose:
3710 3722 keep.append(b'verbose')
3711 3723
3712 3724 commands = sys.modules[__name__]
3713 3725 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3714 3726 ui.pager(b'help')
3715 3727 ui.write(formatted)
3716 3728
3717 3729
3718 3730 @command(
3719 3731 b'identify|id',
3720 3732 [
3721 3733 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3722 3734 (b'n', b'num', None, _(b'show local revision number')),
3723 3735 (b'i', b'id', None, _(b'show global revision id')),
3724 3736 (b'b', b'branch', None, _(b'show branch')),
3725 3737 (b't', b'tags', None, _(b'show tags')),
3726 3738 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3727 3739 ]
3728 3740 + remoteopts
3729 3741 + formatteropts,
3730 3742 _(b'[-nibtB] [-r REV] [SOURCE]'),
3731 3743 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3732 3744 optionalrepo=True,
3733 3745 intents={INTENT_READONLY},
3734 3746 )
3735 3747 def identify(
3736 3748 ui,
3737 3749 repo,
3738 3750 source=None,
3739 3751 rev=None,
3740 3752 num=None,
3741 3753 id=None,
3742 3754 branch=None,
3743 3755 tags=None,
3744 3756 bookmarks=None,
3745 3757 **opts
3746 3758 ):
3747 3759 """identify the working directory or specified revision
3748 3760
3749 3761 Print a summary identifying the repository state at REV using one or
3750 3762 two parent hash identifiers, followed by a "+" if the working
3751 3763 directory has uncommitted changes, the branch name (if not default),
3752 3764 a list of tags, and a list of bookmarks.
3753 3765
3754 3766 When REV is not given, print a summary of the current state of the
3755 3767 repository including the working directory. Specify -r. to get information
3756 3768 of the working directory parent without scanning uncommitted changes.
3757 3769
3758 3770 Specifying a path to a repository root or Mercurial bundle will
3759 3771 cause lookup to operate on that repository/bundle.
3760 3772
3761 3773 .. container:: verbose
3762 3774
3763 3775 Template:
3764 3776
3765 3777 The following keywords are supported in addition to the common template
3766 3778 keywords and functions. See also :hg:`help templates`.
3767 3779
3768 3780 :dirty: String. Character ``+`` denoting if the working directory has
3769 3781 uncommitted changes.
3770 3782 :id: String. One or two nodes, optionally followed by ``+``.
3771 3783 :parents: List of strings. Parent nodes of the changeset.
3772 3784
3773 3785 Examples:
3774 3786
3775 3787 - generate a build identifier for the working directory::
3776 3788
3777 3789 hg id --id > build-id.dat
3778 3790
3779 3791 - find the revision corresponding to a tag::
3780 3792
3781 3793 hg id -n -r 1.3
3782 3794
3783 3795 - check the most recent revision of a remote repository::
3784 3796
3785 3797 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3786 3798
3787 3799 See :hg:`log` for generating more information about specific revisions,
3788 3800 including full hash identifiers.
3789 3801
3790 3802 Returns 0 if successful.
3791 3803 """
3792 3804
3793 3805 opts = pycompat.byteskwargs(opts)
3794 3806 if not repo and not source:
3795 3807 raise error.InputError(
3796 3808 _(b"there is no Mercurial repository here (.hg not found)")
3797 3809 )
3798 3810
3799 3811 default = not (num or id or branch or tags or bookmarks)
3800 3812 output = []
3801 3813 revs = []
3802 3814
3803 3815 if source:
3804 3816 source, branches = hg.parseurl(ui.expandpath(source))
3805 3817 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3806 3818 repo = peer.local()
3807 3819 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3808 3820
3809 3821 fm = ui.formatter(b'identify', opts)
3810 3822 fm.startitem()
3811 3823
3812 3824 if not repo:
3813 3825 if num or branch or tags:
3814 3826 raise error.InputError(
3815 3827 _(b"can't query remote revision number, branch, or tags")
3816 3828 )
3817 3829 if not rev and revs:
3818 3830 rev = revs[0]
3819 3831 if not rev:
3820 3832 rev = b"tip"
3821 3833
3822 3834 remoterev = peer.lookup(rev)
3823 3835 hexrev = fm.hexfunc(remoterev)
3824 3836 if default or id:
3825 3837 output = [hexrev]
3826 3838 fm.data(id=hexrev)
3827 3839
3828 3840 @util.cachefunc
3829 3841 def getbms():
3830 3842 bms = []
3831 3843
3832 3844 if b'bookmarks' in peer.listkeys(b'namespaces'):
3833 3845 hexremoterev = hex(remoterev)
3834 3846 bms = [
3835 3847 bm
3836 3848 for bm, bmr in pycompat.iteritems(
3837 3849 peer.listkeys(b'bookmarks')
3838 3850 )
3839 3851 if bmr == hexremoterev
3840 3852 ]
3841 3853
3842 3854 return sorted(bms)
3843 3855
3844 3856 if fm.isplain():
3845 3857 if bookmarks:
3846 3858 output.extend(getbms())
3847 3859 elif default and not ui.quiet:
3848 3860 # multiple bookmarks for a single parent separated by '/'
3849 3861 bm = b'/'.join(getbms())
3850 3862 if bm:
3851 3863 output.append(bm)
3852 3864 else:
3853 3865 fm.data(node=hex(remoterev))
3854 3866 if bookmarks or b'bookmarks' in fm.datahint():
3855 3867 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3856 3868 else:
3857 3869 if rev:
3858 3870 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3859 3871 ctx = scmutil.revsingle(repo, rev, None)
3860 3872
3861 3873 if ctx.rev() is None:
3862 3874 ctx = repo[None]
3863 3875 parents = ctx.parents()
3864 3876 taglist = []
3865 3877 for p in parents:
3866 3878 taglist.extend(p.tags())
3867 3879
3868 3880 dirty = b""
3869 3881 if ctx.dirty(missing=True, merge=False, branch=False):
3870 3882 dirty = b'+'
3871 3883 fm.data(dirty=dirty)
3872 3884
3873 3885 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3874 3886 if default or id:
3875 3887 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
3876 3888 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
3877 3889
3878 3890 if num:
3879 3891 numoutput = [b"%d" % p.rev() for p in parents]
3880 3892 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
3881 3893
3882 3894 fm.data(
3883 3895 parents=fm.formatlist(
3884 3896 [fm.hexfunc(p.node()) for p in parents], name=b'node'
3885 3897 )
3886 3898 )
3887 3899 else:
3888 3900 hexoutput = fm.hexfunc(ctx.node())
3889 3901 if default or id:
3890 3902 output = [hexoutput]
3891 3903 fm.data(id=hexoutput)
3892 3904
3893 3905 if num:
3894 3906 output.append(pycompat.bytestr(ctx.rev()))
3895 3907 taglist = ctx.tags()
3896 3908
3897 3909 if default and not ui.quiet:
3898 3910 b = ctx.branch()
3899 3911 if b != b'default':
3900 3912 output.append(b"(%s)" % b)
3901 3913
3902 3914 # multiple tags for a single parent separated by '/'
3903 3915 t = b'/'.join(taglist)
3904 3916 if t:
3905 3917 output.append(t)
3906 3918
3907 3919 # multiple bookmarks for a single parent separated by '/'
3908 3920 bm = b'/'.join(ctx.bookmarks())
3909 3921 if bm:
3910 3922 output.append(bm)
3911 3923 else:
3912 3924 if branch:
3913 3925 output.append(ctx.branch())
3914 3926
3915 3927 if tags:
3916 3928 output.extend(taglist)
3917 3929
3918 3930 if bookmarks:
3919 3931 output.extend(ctx.bookmarks())
3920 3932
3921 3933 fm.data(node=ctx.hex())
3922 3934 fm.data(branch=ctx.branch())
3923 3935 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
3924 3936 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
3925 3937 fm.context(ctx=ctx)
3926 3938
3927 3939 fm.plain(b"%s\n" % b' '.join(output))
3928 3940 fm.end()
3929 3941
3930 3942
3931 3943 @command(
3932 3944 b'import|patch',
3933 3945 [
3934 3946 (
3935 3947 b'p',
3936 3948 b'strip',
3937 3949 1,
3938 3950 _(
3939 3951 b'directory strip option for patch. This has the same '
3940 3952 b'meaning as the corresponding patch option'
3941 3953 ),
3942 3954 _(b'NUM'),
3943 3955 ),
3944 3956 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
3945 3957 (b'', b'secret', None, _(b'use the secret phase for committing')),
3946 3958 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
3947 3959 (
3948 3960 b'f',
3949 3961 b'force',
3950 3962 None,
3951 3963 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
3952 3964 ),
3953 3965 (
3954 3966 b'',
3955 3967 b'no-commit',
3956 3968 None,
3957 3969 _(b"don't commit, just update the working directory"),
3958 3970 ),
3959 3971 (
3960 3972 b'',
3961 3973 b'bypass',
3962 3974 None,
3963 3975 _(b"apply patch without touching the working directory"),
3964 3976 ),
3965 3977 (b'', b'partial', None, _(b'commit even if some hunks fail')),
3966 3978 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
3967 3979 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
3968 3980 (
3969 3981 b'',
3970 3982 b'import-branch',
3971 3983 None,
3972 3984 _(b'use any branch information in patch (implied by --exact)'),
3973 3985 ),
3974 3986 ]
3975 3987 + commitopts
3976 3988 + commitopts2
3977 3989 + similarityopts,
3978 3990 _(b'[OPTION]... PATCH...'),
3979 3991 helpcategory=command.CATEGORY_IMPORT_EXPORT,
3980 3992 )
3981 3993 def import_(ui, repo, patch1=None, *patches, **opts):
3982 3994 """import an ordered set of patches
3983 3995
3984 3996 Import a list of patches and commit them individually (unless
3985 3997 --no-commit is specified).
3986 3998
3987 3999 To read a patch from standard input (stdin), use "-" as the patch
3988 4000 name. If a URL is specified, the patch will be downloaded from
3989 4001 there.
3990 4002
3991 4003 Import first applies changes to the working directory (unless
3992 4004 --bypass is specified), import will abort if there are outstanding
3993 4005 changes.
3994 4006
3995 4007 Use --bypass to apply and commit patches directly to the
3996 4008 repository, without affecting the working directory. Without
3997 4009 --exact, patches will be applied on top of the working directory
3998 4010 parent revision.
3999 4011
4000 4012 You can import a patch straight from a mail message. Even patches
4001 4013 as attachments work (to use the body part, it must have type
4002 4014 text/plain or text/x-patch). From and Subject headers of email
4003 4015 message are used as default committer and commit message. All
4004 4016 text/plain body parts before first diff are added to the commit
4005 4017 message.
4006 4018
4007 4019 If the imported patch was generated by :hg:`export`, user and
4008 4020 description from patch override values from message headers and
4009 4021 body. Values given on command line with -m/--message and -u/--user
4010 4022 override these.
4011 4023
4012 4024 If --exact is specified, import will set the working directory to
4013 4025 the parent of each patch before applying it, and will abort if the
4014 4026 resulting changeset has a different ID than the one recorded in
4015 4027 the patch. This will guard against various ways that portable
4016 4028 patch formats and mail systems might fail to transfer Mercurial
4017 4029 data or metadata. See :hg:`bundle` for lossless transmission.
4018 4030
4019 4031 Use --partial to ensure a changeset will be created from the patch
4020 4032 even if some hunks fail to apply. Hunks that fail to apply will be
4021 4033 written to a <target-file>.rej file. Conflicts can then be resolved
4022 4034 by hand before :hg:`commit --amend` is run to update the created
4023 4035 changeset. This flag exists to let people import patches that
4024 4036 partially apply without losing the associated metadata (author,
4025 4037 date, description, ...).
4026 4038
4027 4039 .. note::
4028 4040
4029 4041 When no hunks apply cleanly, :hg:`import --partial` will create
4030 4042 an empty changeset, importing only the patch metadata.
4031 4043
4032 4044 With -s/--similarity, hg will attempt to discover renames and
4033 4045 copies in the patch in the same way as :hg:`addremove`.
4034 4046
4035 4047 It is possible to use external patch programs to perform the patch
4036 4048 by setting the ``ui.patch`` configuration option. For the default
4037 4049 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4038 4050 See :hg:`help config` for more information about configuration
4039 4051 files and how to use these options.
4040 4052
4041 4053 See :hg:`help dates` for a list of formats valid for -d/--date.
4042 4054
4043 4055 .. container:: verbose
4044 4056
4045 4057 Examples:
4046 4058
4047 4059 - import a traditional patch from a website and detect renames::
4048 4060
4049 4061 hg import -s 80 http://example.com/bugfix.patch
4050 4062
4051 4063 - import a changeset from an hgweb server::
4052 4064
4053 4065 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4054 4066
4055 4067 - import all the patches in an Unix-style mbox::
4056 4068
4057 4069 hg import incoming-patches.mbox
4058 4070
4059 4071 - import patches from stdin::
4060 4072
4061 4073 hg import -
4062 4074
4063 4075 - attempt to exactly restore an exported changeset (not always
4064 4076 possible)::
4065 4077
4066 4078 hg import --exact proposed-fix.patch
4067 4079
4068 4080 - use an external tool to apply a patch which is too fuzzy for
4069 4081 the default internal tool.
4070 4082
4071 4083 hg import --config ui.patch="patch --merge" fuzzy.patch
4072 4084
4073 4085 - change the default fuzzing from 2 to a less strict 7
4074 4086
4075 4087 hg import --config ui.fuzz=7 fuzz.patch
4076 4088
4077 4089 Returns 0 on success, 1 on partial success (see --partial).
4078 4090 """
4079 4091
4080 4092 cmdutil.check_incompatible_arguments(
4081 4093 opts, 'no_commit', ['bypass', 'secret']
4082 4094 )
4083 4095 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4084 4096 opts = pycompat.byteskwargs(opts)
4085 4097 if not patch1:
4086 4098 raise error.InputError(_(b'need at least one patch to import'))
4087 4099
4088 4100 patches = (patch1,) + patches
4089 4101
4090 4102 date = opts.get(b'date')
4091 4103 if date:
4092 4104 opts[b'date'] = dateutil.parsedate(date)
4093 4105
4094 4106 exact = opts.get(b'exact')
4095 4107 update = not opts.get(b'bypass')
4096 4108 try:
4097 4109 sim = float(opts.get(b'similarity') or 0)
4098 4110 except ValueError:
4099 4111 raise error.InputError(_(b'similarity must be a number'))
4100 4112 if sim < 0 or sim > 100:
4101 4113 raise error.InputError(_(b'similarity must be between 0 and 100'))
4102 4114 if sim and not update:
4103 4115 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4104 4116
4105 4117 base = opts[b"base"]
4106 4118 msgs = []
4107 4119 ret = 0
4108 4120
4109 4121 with repo.wlock():
4110 4122 if update:
4111 4123 cmdutil.checkunfinished(repo)
4112 4124 if exact or not opts.get(b'force'):
4113 4125 cmdutil.bailifchanged(repo)
4114 4126
4115 4127 if not opts.get(b'no_commit'):
4116 4128 lock = repo.lock
4117 4129 tr = lambda: repo.transaction(b'import')
4118 4130 dsguard = util.nullcontextmanager
4119 4131 else:
4120 4132 lock = util.nullcontextmanager
4121 4133 tr = util.nullcontextmanager
4122 4134 dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
4123 4135 with lock(), tr(), dsguard():
4124 4136 parents = repo[None].parents()
4125 4137 for patchurl in patches:
4126 4138 if patchurl == b'-':
4127 4139 ui.status(_(b'applying patch from stdin\n'))
4128 4140 patchfile = ui.fin
4129 4141 patchurl = b'stdin' # for error message
4130 4142 else:
4131 4143 patchurl = os.path.join(base, patchurl)
4132 4144 ui.status(_(b'applying %s\n') % patchurl)
4133 4145 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4134 4146
4135 4147 haspatch = False
4136 4148 for hunk in patch.split(patchfile):
4137 4149 with patch.extract(ui, hunk) as patchdata:
4138 4150 msg, node, rej = cmdutil.tryimportone(
4139 4151 ui, repo, patchdata, parents, opts, msgs, hg.clean
4140 4152 )
4141 4153 if msg:
4142 4154 haspatch = True
4143 4155 ui.note(msg + b'\n')
4144 4156 if update or exact:
4145 4157 parents = repo[None].parents()
4146 4158 else:
4147 4159 parents = [repo[node]]
4148 4160 if rej:
4149 4161 ui.write_err(_(b"patch applied partially\n"))
4150 4162 ui.write_err(
4151 4163 _(
4152 4164 b"(fix the .rej files and run "
4153 4165 b"`hg commit --amend`)\n"
4154 4166 )
4155 4167 )
4156 4168 ret = 1
4157 4169 break
4158 4170
4159 4171 if not haspatch:
4160 4172 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4161 4173
4162 4174 if msgs:
4163 4175 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4164 4176 return ret
4165 4177
4166 4178
4167 4179 @command(
4168 4180 b'incoming|in',
4169 4181 [
4170 4182 (
4171 4183 b'f',
4172 4184 b'force',
4173 4185 None,
4174 4186 _(b'run even if remote repository is unrelated'),
4175 4187 ),
4176 4188 (b'n', b'newest-first', None, _(b'show newest record first')),
4177 4189 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4178 4190 (
4179 4191 b'r',
4180 4192 b'rev',
4181 4193 [],
4182 4194 _(b'a remote changeset intended to be added'),
4183 4195 _(b'REV'),
4184 4196 ),
4185 4197 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4186 4198 (
4187 4199 b'b',
4188 4200 b'branch',
4189 4201 [],
4190 4202 _(b'a specific branch you would like to pull'),
4191 4203 _(b'BRANCH'),
4192 4204 ),
4193 4205 ]
4194 4206 + logopts
4195 4207 + remoteopts
4196 4208 + subrepoopts,
4197 4209 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4198 4210 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4199 4211 )
4200 4212 def incoming(ui, repo, source=b"default", **opts):
4201 4213 """show new changesets found in source
4202 4214
4203 4215 Show new changesets found in the specified path/URL or the default
4204 4216 pull location. These are the changesets that would have been pulled
4205 4217 by :hg:`pull` at the time you issued this command.
4206 4218
4207 4219 See pull for valid source format details.
4208 4220
4209 4221 .. container:: verbose
4210 4222
4211 4223 With -B/--bookmarks, the result of bookmark comparison between
4212 4224 local and remote repositories is displayed. With -v/--verbose,
4213 4225 status is also displayed for each bookmark like below::
4214 4226
4215 4227 BM1 01234567890a added
4216 4228 BM2 1234567890ab advanced
4217 4229 BM3 234567890abc diverged
4218 4230 BM4 34567890abcd changed
4219 4231
4220 4232 The action taken locally when pulling depends on the
4221 4233 status of each bookmark:
4222 4234
4223 4235 :``added``: pull will create it
4224 4236 :``advanced``: pull will update it
4225 4237 :``diverged``: pull will create a divergent bookmark
4226 4238 :``changed``: result depends on remote changesets
4227 4239
4228 4240 From the point of view of pulling behavior, bookmark
4229 4241 existing only in the remote repository are treated as ``added``,
4230 4242 even if it is in fact locally deleted.
4231 4243
4232 4244 .. container:: verbose
4233 4245
4234 4246 For remote repository, using --bundle avoids downloading the
4235 4247 changesets twice if the incoming is followed by a pull.
4236 4248
4237 4249 Examples:
4238 4250
4239 4251 - show incoming changes with patches and full description::
4240 4252
4241 4253 hg incoming -vp
4242 4254
4243 4255 - show incoming changes excluding merges, store a bundle::
4244 4256
4245 4257 hg in -vpM --bundle incoming.hg
4246 4258 hg pull incoming.hg
4247 4259
4248 4260 - briefly list changes inside a bundle::
4249 4261
4250 4262 hg in changes.hg -T "{desc|firstline}\\n"
4251 4263
4252 4264 Returns 0 if there are incoming changes, 1 otherwise.
4253 4265 """
4254 4266 opts = pycompat.byteskwargs(opts)
4255 4267 if opts.get(b'graph'):
4256 4268 logcmdutil.checkunsupportedgraphflags([], opts)
4257 4269
4258 4270 def display(other, chlist, displayer):
4259 4271 revdag = logcmdutil.graphrevs(other, chlist, opts)
4260 4272 logcmdutil.displaygraph(
4261 4273 ui, repo, revdag, displayer, graphmod.asciiedges
4262 4274 )
4263 4275
4264 4276 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4265 4277 return 0
4266 4278
4267 4279 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'bundle'])
4268 4280
4269 4281 if opts.get(b'bookmarks'):
4270 4282 source, branches = hg.parseurl(
4271 4283 ui.expandpath(source), opts.get(b'branch')
4272 4284 )
4273 4285 other = hg.peer(repo, opts, source)
4274 4286 if b'bookmarks' not in other.listkeys(b'namespaces'):
4275 4287 ui.warn(_(b"remote doesn't support bookmarks\n"))
4276 4288 return 0
4277 4289 ui.pager(b'incoming')
4278 4290 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
4279 4291 return bookmarks.incoming(ui, repo, other)
4280 4292
4281 4293 repo._subtoppath = ui.expandpath(source)
4282 4294 try:
4283 4295 return hg.incoming(ui, repo, source, opts)
4284 4296 finally:
4285 4297 del repo._subtoppath
4286 4298
4287 4299
4288 4300 @command(
4289 4301 b'init',
4290 4302 remoteopts,
4291 4303 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4292 4304 helpcategory=command.CATEGORY_REPO_CREATION,
4293 4305 helpbasic=True,
4294 4306 norepo=True,
4295 4307 )
4296 4308 def init(ui, dest=b".", **opts):
4297 4309 """create a new repository in the given directory
4298 4310
4299 4311 Initialize a new repository in the given directory. If the given
4300 4312 directory does not exist, it will be created.
4301 4313
4302 4314 If no directory is given, the current directory is used.
4303 4315
4304 4316 It is possible to specify an ``ssh://`` URL as the destination.
4305 4317 See :hg:`help urls` for more information.
4306 4318
4307 4319 Returns 0 on success.
4308 4320 """
4309 4321 opts = pycompat.byteskwargs(opts)
4310 4322 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4311 4323
4312 4324
4313 4325 @command(
4314 4326 b'locate',
4315 4327 [
4316 4328 (
4317 4329 b'r',
4318 4330 b'rev',
4319 4331 b'',
4320 4332 _(b'search the repository as it is in REV'),
4321 4333 _(b'REV'),
4322 4334 ),
4323 4335 (
4324 4336 b'0',
4325 4337 b'print0',
4326 4338 None,
4327 4339 _(b'end filenames with NUL, for use with xargs'),
4328 4340 ),
4329 4341 (
4330 4342 b'f',
4331 4343 b'fullpath',
4332 4344 None,
4333 4345 _(b'print complete paths from the filesystem root'),
4334 4346 ),
4335 4347 ]
4336 4348 + walkopts,
4337 4349 _(b'[OPTION]... [PATTERN]...'),
4338 4350 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4339 4351 )
4340 4352 def locate(ui, repo, *pats, **opts):
4341 4353 """locate files matching specific patterns (DEPRECATED)
4342 4354
4343 4355 Print files under Mercurial control in the working directory whose
4344 4356 names match the given patterns.
4345 4357
4346 4358 By default, this command searches all directories in the working
4347 4359 directory. To search just the current directory and its
4348 4360 subdirectories, use "--include .".
4349 4361
4350 4362 If no patterns are given to match, this command prints the names
4351 4363 of all files under Mercurial control in the working directory.
4352 4364
4353 4365 If you want to feed the output of this command into the "xargs"
4354 4366 command, use the -0 option to both this command and "xargs". This
4355 4367 will avoid the problem of "xargs" treating single filenames that
4356 4368 contain whitespace as multiple filenames.
4357 4369
4358 4370 See :hg:`help files` for a more versatile command.
4359 4371
4360 4372 Returns 0 if a match is found, 1 otherwise.
4361 4373 """
4362 4374 opts = pycompat.byteskwargs(opts)
4363 4375 if opts.get(b'print0'):
4364 4376 end = b'\0'
4365 4377 else:
4366 4378 end = b'\n'
4367 4379 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
4368 4380
4369 4381 ret = 1
4370 4382 m = scmutil.match(
4371 4383 ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
4372 4384 )
4373 4385
4374 4386 ui.pager(b'locate')
4375 4387 if ctx.rev() is None:
4376 4388 # When run on the working copy, "locate" includes removed files, so
4377 4389 # we get the list of files from the dirstate.
4378 4390 filesgen = sorted(repo.dirstate.matches(m))
4379 4391 else:
4380 4392 filesgen = ctx.matches(m)
4381 4393 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4382 4394 for abs in filesgen:
4383 4395 if opts.get(b'fullpath'):
4384 4396 ui.write(repo.wjoin(abs), end)
4385 4397 else:
4386 4398 ui.write(uipathfn(abs), end)
4387 4399 ret = 0
4388 4400
4389 4401 return ret
4390 4402
4391 4403
4392 4404 @command(
4393 4405 b'log|history',
4394 4406 [
4395 4407 (
4396 4408 b'f',
4397 4409 b'follow',
4398 4410 None,
4399 4411 _(
4400 4412 b'follow changeset history, or file history across copies and renames'
4401 4413 ),
4402 4414 ),
4403 4415 (
4404 4416 b'',
4405 4417 b'follow-first',
4406 4418 None,
4407 4419 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4408 4420 ),
4409 4421 (
4410 4422 b'd',
4411 4423 b'date',
4412 4424 b'',
4413 4425 _(b'show revisions matching date spec'),
4414 4426 _(b'DATE'),
4415 4427 ),
4416 4428 (b'C', b'copies', None, _(b'show copied files')),
4417 4429 (
4418 4430 b'k',
4419 4431 b'keyword',
4420 4432 [],
4421 4433 _(b'do case-insensitive search for a given text'),
4422 4434 _(b'TEXT'),
4423 4435 ),
4424 4436 (
4425 4437 b'r',
4426 4438 b'rev',
4427 4439 [],
4428 4440 _(b'show the specified revision or revset'),
4429 4441 _(b'REV'),
4430 4442 ),
4431 4443 (
4432 4444 b'L',
4433 4445 b'line-range',
4434 4446 [],
4435 4447 _(b'follow line range of specified file (EXPERIMENTAL)'),
4436 4448 _(b'FILE,RANGE'),
4437 4449 ),
4438 4450 (
4439 4451 b'',
4440 4452 b'removed',
4441 4453 None,
4442 4454 _(b'include revisions where files were removed'),
4443 4455 ),
4444 4456 (
4445 4457 b'm',
4446 4458 b'only-merges',
4447 4459 None,
4448 4460 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4449 4461 ),
4450 4462 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4451 4463 (
4452 4464 b'',
4453 4465 b'only-branch',
4454 4466 [],
4455 4467 _(
4456 4468 b'show only changesets within the given named branch (DEPRECATED)'
4457 4469 ),
4458 4470 _(b'BRANCH'),
4459 4471 ),
4460 4472 (
4461 4473 b'b',
4462 4474 b'branch',
4463 4475 [],
4464 4476 _(b'show changesets within the given named branch'),
4465 4477 _(b'BRANCH'),
4466 4478 ),
4467 4479 (
4468 4480 b'B',
4469 4481 b'bookmark',
4470 4482 [],
4471 4483 _(b"show changesets within the given bookmark"),
4472 4484 _(b'BOOKMARK'),
4473 4485 ),
4474 4486 (
4475 4487 b'P',
4476 4488 b'prune',
4477 4489 [],
4478 4490 _(b'do not display revision or any of its ancestors'),
4479 4491 _(b'REV'),
4480 4492 ),
4481 4493 ]
4482 4494 + logopts
4483 4495 + walkopts,
4484 4496 _(b'[OPTION]... [FILE]'),
4485 4497 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4486 4498 helpbasic=True,
4487 4499 inferrepo=True,
4488 4500 intents={INTENT_READONLY},
4489 4501 )
4490 4502 def log(ui, repo, *pats, **opts):
4491 4503 """show revision history of entire repository or files
4492 4504
4493 4505 Print the revision history of the specified files or the entire
4494 4506 project.
4495 4507
4496 4508 If no revision range is specified, the default is ``tip:0`` unless
4497 4509 --follow is set, in which case the working directory parent is
4498 4510 used as the starting revision.
4499 4511
4500 4512 File history is shown without following rename or copy history of
4501 4513 files. Use -f/--follow with a filename to follow history across
4502 4514 renames and copies. --follow without a filename will only show
4503 4515 ancestors of the starting revision.
4504 4516
4505 4517 By default this command prints revision number and changeset id,
4506 4518 tags, non-trivial parents, user, date and time, and a summary for
4507 4519 each commit. When the -v/--verbose switch is used, the list of
4508 4520 changed files and full commit message are shown.
4509 4521
4510 4522 With --graph the revisions are shown as an ASCII art DAG with the most
4511 4523 recent changeset at the top.
4512 4524 'o' is a changeset, '@' is a working directory parent, '%' is a changeset
4513 4525 involved in an unresolved merge conflict, '_' closes a branch,
4514 4526 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4515 4527 changeset from the lines below is a parent of the 'o' merge on the same
4516 4528 line.
4517 4529 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4518 4530 of a '|' indicates one or more revisions in a path are omitted.
4519 4531
4520 4532 .. container:: verbose
4521 4533
4522 4534 Use -L/--line-range FILE,M:N options to follow the history of lines
4523 4535 from M to N in FILE. With -p/--patch only diff hunks affecting
4524 4536 specified line range will be shown. This option requires --follow;
4525 4537 it can be specified multiple times. Currently, this option is not
4526 4538 compatible with --graph. This option is experimental.
4527 4539
4528 4540 .. note::
4529 4541
4530 4542 :hg:`log --patch` may generate unexpected diff output for merge
4531 4543 changesets, as it will only compare the merge changeset against
4532 4544 its first parent. Also, only files different from BOTH parents
4533 4545 will appear in files:.
4534 4546
4535 4547 .. note::
4536 4548
4537 4549 For performance reasons, :hg:`log FILE` may omit duplicate changes
4538 4550 made on branches and will not show removals or mode changes. To
4539 4551 see all such changes, use the --removed switch.
4540 4552
4541 4553 .. container:: verbose
4542 4554
4543 4555 .. note::
4544 4556
4545 4557 The history resulting from -L/--line-range options depends on diff
4546 4558 options; for instance if white-spaces are ignored, respective changes
4547 4559 with only white-spaces in specified line range will not be listed.
4548 4560
4549 4561 .. container:: verbose
4550 4562
4551 4563 Some examples:
4552 4564
4553 4565 - changesets with full descriptions and file lists::
4554 4566
4555 4567 hg log -v
4556 4568
4557 4569 - changesets ancestral to the working directory::
4558 4570
4559 4571 hg log -f
4560 4572
4561 4573 - last 10 commits on the current branch::
4562 4574
4563 4575 hg log -l 10 -b .
4564 4576
4565 4577 - changesets showing all modifications of a file, including removals::
4566 4578
4567 4579 hg log --removed file.c
4568 4580
4569 4581 - all changesets that touch a directory, with diffs, excluding merges::
4570 4582
4571 4583 hg log -Mp lib/
4572 4584
4573 4585 - all revision numbers that match a keyword::
4574 4586
4575 4587 hg log -k bug --template "{rev}\\n"
4576 4588
4577 4589 - the full hash identifier of the working directory parent::
4578 4590
4579 4591 hg log -r . --template "{node}\\n"
4580 4592
4581 4593 - list available log templates::
4582 4594
4583 4595 hg log -T list
4584 4596
4585 4597 - check if a given changeset is included in a tagged release::
4586 4598
4587 4599 hg log -r "a21ccf and ancestor(1.9)"
4588 4600
4589 4601 - find all changesets by some user in a date range::
4590 4602
4591 4603 hg log -k alice -d "may 2008 to jul 2008"
4592 4604
4593 4605 - summary of all changesets after the last tag::
4594 4606
4595 4607 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4596 4608
4597 4609 - changesets touching lines 13 to 23 for file.c::
4598 4610
4599 4611 hg log -L file.c,13:23
4600 4612
4601 4613 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4602 4614 main.c with patch::
4603 4615
4604 4616 hg log -L file.c,13:23 -L main.c,2:6 -p
4605 4617
4606 4618 See :hg:`help dates` for a list of formats valid for -d/--date.
4607 4619
4608 4620 See :hg:`help revisions` for more about specifying and ordering
4609 4621 revisions.
4610 4622
4611 4623 See :hg:`help templates` for more about pre-packaged styles and
4612 4624 specifying custom templates. The default template used by the log
4613 4625 command can be customized via the ``command-templates.log`` configuration
4614 4626 setting.
4615 4627
4616 4628 Returns 0 on success.
4617 4629
4618 4630 """
4619 4631 opts = pycompat.byteskwargs(opts)
4620 4632 linerange = opts.get(b'line_range')
4621 4633
4622 4634 if linerange and not opts.get(b'follow'):
4623 4635 raise error.InputError(_(b'--line-range requires --follow'))
4624 4636
4625 4637 if linerange and pats:
4626 4638 # TODO: take pats as patterns with no line-range filter
4627 4639 raise error.InputError(
4628 4640 _(b'FILE arguments are not compatible with --line-range option')
4629 4641 )
4630 4642
4631 4643 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4632 4644 walk_opts = logcmdutil.parseopts(ui, pats, opts)
4633 4645 revs, differ = logcmdutil.getrevs(repo, walk_opts)
4634 4646 if linerange:
4635 4647 # TODO: should follow file history from logcmdutil._initialrevs(),
4636 4648 # then filter the result by logcmdutil._makerevset() and --limit
4637 4649 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4638 4650
4639 4651 getcopies = None
4640 4652 if opts.get(b'copies'):
4641 4653 endrev = None
4642 4654 if revs:
4643 4655 endrev = revs.max() + 1
4644 4656 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4645 4657
4646 4658 ui.pager(b'log')
4647 4659 displayer = logcmdutil.changesetdisplayer(
4648 4660 ui, repo, opts, differ, buffered=True
4649 4661 )
4650 4662 if opts.get(b'graph'):
4651 4663 displayfn = logcmdutil.displaygraphrevs
4652 4664 else:
4653 4665 displayfn = logcmdutil.displayrevs
4654 4666 displayfn(ui, repo, revs, displayer, getcopies)
4655 4667
4656 4668
4657 4669 @command(
4658 4670 b'manifest',
4659 4671 [
4660 4672 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4661 4673 (b'', b'all', False, _(b"list files from all revisions")),
4662 4674 ]
4663 4675 + formatteropts,
4664 4676 _(b'[-r REV]'),
4665 4677 helpcategory=command.CATEGORY_MAINTENANCE,
4666 4678 intents={INTENT_READONLY},
4667 4679 )
4668 4680 def manifest(ui, repo, node=None, rev=None, **opts):
4669 4681 """output the current or given revision of the project manifest
4670 4682
4671 4683 Print a list of version controlled files for the given revision.
4672 4684 If no revision is given, the first parent of the working directory
4673 4685 is used, or the null revision if no revision is checked out.
4674 4686
4675 4687 With -v, print file permissions, symlink and executable bits.
4676 4688 With --debug, print file revision hashes.
4677 4689
4678 4690 If option --all is specified, the list of all files from all revisions
4679 4691 is printed. This includes deleted and renamed files.
4680 4692
4681 4693 Returns 0 on success.
4682 4694 """
4683 4695 opts = pycompat.byteskwargs(opts)
4684 4696 fm = ui.formatter(b'manifest', opts)
4685 4697
4686 4698 if opts.get(b'all'):
4687 4699 if rev or node:
4688 4700 raise error.InputError(_(b"can't specify a revision with --all"))
4689 4701
4690 4702 res = set()
4691 4703 for rev in repo:
4692 4704 ctx = repo[rev]
4693 4705 res |= set(ctx.files())
4694 4706
4695 4707 ui.pager(b'manifest')
4696 4708 for f in sorted(res):
4697 4709 fm.startitem()
4698 4710 fm.write(b"path", b'%s\n', f)
4699 4711 fm.end()
4700 4712 return
4701 4713
4702 4714 if rev and node:
4703 4715 raise error.InputError(_(b"please specify just one revision"))
4704 4716
4705 4717 if not node:
4706 4718 node = rev
4707 4719
4708 4720 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4709 4721 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4710 4722 if node:
4711 4723 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4712 4724 ctx = scmutil.revsingle(repo, node)
4713 4725 mf = ctx.manifest()
4714 4726 ui.pager(b'manifest')
4715 4727 for f in ctx:
4716 4728 fm.startitem()
4717 4729 fm.context(ctx=ctx)
4718 4730 fl = ctx[f].flags()
4719 4731 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4720 4732 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4721 4733 fm.write(b'path', b'%s\n', f)
4722 4734 fm.end()
4723 4735
4724 4736
4725 4737 @command(
4726 4738 b'merge',
4727 4739 [
4728 4740 (
4729 4741 b'f',
4730 4742 b'force',
4731 4743 None,
4732 4744 _(b'force a merge including outstanding changes (DEPRECATED)'),
4733 4745 ),
4734 4746 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4735 4747 (
4736 4748 b'P',
4737 4749 b'preview',
4738 4750 None,
4739 4751 _(b'review revisions to merge (no merge is performed)'),
4740 4752 ),
4741 4753 (b'', b'abort', None, _(b'abort the ongoing merge')),
4742 4754 ]
4743 4755 + mergetoolopts,
4744 4756 _(b'[-P] [[-r] REV]'),
4745 4757 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4746 4758 helpbasic=True,
4747 4759 )
4748 4760 def merge(ui, repo, node=None, **opts):
4749 4761 """merge another revision into working directory
4750 4762
4751 4763 The current working directory is updated with all changes made in
4752 4764 the requested revision since the last common predecessor revision.
4753 4765
4754 4766 Files that changed between either parent are marked as changed for
4755 4767 the next commit and a commit must be performed before any further
4756 4768 updates to the repository are allowed. The next commit will have
4757 4769 two parents.
4758 4770
4759 4771 ``--tool`` can be used to specify the merge tool used for file
4760 4772 merges. It overrides the HGMERGE environment variable and your
4761 4773 configuration files. See :hg:`help merge-tools` for options.
4762 4774
4763 4775 If no revision is specified, the working directory's parent is a
4764 4776 head revision, and the current branch contains exactly one other
4765 4777 head, the other head is merged with by default. Otherwise, an
4766 4778 explicit revision with which to merge must be provided.
4767 4779
4768 4780 See :hg:`help resolve` for information on handling file conflicts.
4769 4781
4770 4782 To undo an uncommitted merge, use :hg:`merge --abort` which
4771 4783 will check out a clean copy of the original merge parent, losing
4772 4784 all changes.
4773 4785
4774 4786 Returns 0 on success, 1 if there are unresolved files.
4775 4787 """
4776 4788
4777 4789 opts = pycompat.byteskwargs(opts)
4778 4790 abort = opts.get(b'abort')
4779 4791 if abort and repo.dirstate.p2() == nullid:
4780 4792 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4781 4793 cmdutil.check_incompatible_arguments(opts, b'abort', [b'rev', b'preview'])
4782 4794 if abort:
4783 4795 state = cmdutil.getunfinishedstate(repo)
4784 4796 if state and state._opname != b'merge':
4785 4797 raise error.StateError(
4786 4798 _(b'cannot abort merge with %s in progress') % (state._opname),
4787 4799 hint=state.hint(),
4788 4800 )
4789 4801 if node:
4790 4802 raise error.InputError(_(b"cannot specify a node with --abort"))
4791 4803 return hg.abortmerge(repo.ui, repo)
4792 4804
4793 4805 if opts.get(b'rev') and node:
4794 4806 raise error.InputError(_(b"please specify just one revision"))
4795 4807 if not node:
4796 4808 node = opts.get(b'rev')
4797 4809
4798 4810 if node:
4799 4811 ctx = scmutil.revsingle(repo, node)
4800 4812 else:
4801 4813 if ui.configbool(b'commands', b'merge.require-rev'):
4802 4814 raise error.InputError(
4803 4815 _(
4804 4816 b'configuration requires specifying revision to merge '
4805 4817 b'with'
4806 4818 )
4807 4819 )
4808 4820 ctx = repo[destutil.destmerge(repo)]
4809 4821
4810 4822 if ctx.node() is None:
4811 4823 raise error.InputError(
4812 4824 _(b'merging with the working copy has no effect')
4813 4825 )
4814 4826
4815 4827 if opts.get(b'preview'):
4816 4828 # find nodes that are ancestors of p2 but not of p1
4817 4829 p1 = repo[b'.'].node()
4818 4830 p2 = ctx.node()
4819 4831 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4820 4832
4821 4833 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4822 4834 for node in nodes:
4823 4835 displayer.show(repo[node])
4824 4836 displayer.close()
4825 4837 return 0
4826 4838
4827 4839 # ui.forcemerge is an internal variable, do not document
4828 4840 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
4829 4841 with ui.configoverride(overrides, b'merge'):
4830 4842 force = opts.get(b'force')
4831 4843 labels = [b'working copy', b'merge rev']
4832 4844 return hg.merge(ctx, force=force, labels=labels)
4833 4845
4834 4846
4835 4847 statemod.addunfinished(
4836 4848 b'merge',
4837 4849 fname=None,
4838 4850 clearable=True,
4839 4851 allowcommit=True,
4840 4852 cmdmsg=_(b'outstanding uncommitted merge'),
4841 4853 abortfunc=hg.abortmerge,
4842 4854 statushint=_(
4843 4855 b'To continue: hg commit\nTo abort: hg merge --abort'
4844 4856 ),
4845 4857 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4846 4858 )
4847 4859
4848 4860
4849 4861 @command(
4850 4862 b'outgoing|out',
4851 4863 [
4852 4864 (
4853 4865 b'f',
4854 4866 b'force',
4855 4867 None,
4856 4868 _(b'run even when the destination is unrelated'),
4857 4869 ),
4858 4870 (
4859 4871 b'r',
4860 4872 b'rev',
4861 4873 [],
4862 4874 _(b'a changeset intended to be included in the destination'),
4863 4875 _(b'REV'),
4864 4876 ),
4865 4877 (b'n', b'newest-first', None, _(b'show newest record first')),
4866 4878 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
4867 4879 (
4868 4880 b'b',
4869 4881 b'branch',
4870 4882 [],
4871 4883 _(b'a specific branch you would like to push'),
4872 4884 _(b'BRANCH'),
4873 4885 ),
4874 4886 ]
4875 4887 + logopts
4876 4888 + remoteopts
4877 4889 + subrepoopts,
4878 4890 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4879 4891 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4880 4892 )
4881 4893 def outgoing(ui, repo, dest=None, **opts):
4882 4894 """show changesets not found in the destination
4883 4895
4884 4896 Show changesets not found in the specified destination repository
4885 4897 or the default push location. These are the changesets that would
4886 4898 be pushed if a push was requested.
4887 4899
4888 4900 See pull for details of valid destination formats.
4889 4901
4890 4902 .. container:: verbose
4891 4903
4892 4904 With -B/--bookmarks, the result of bookmark comparison between
4893 4905 local and remote repositories is displayed. With -v/--verbose,
4894 4906 status is also displayed for each bookmark like below::
4895 4907
4896 4908 BM1 01234567890a added
4897 4909 BM2 deleted
4898 4910 BM3 234567890abc advanced
4899 4911 BM4 34567890abcd diverged
4900 4912 BM5 4567890abcde changed
4901 4913
4902 4914 The action taken when pushing depends on the
4903 4915 status of each bookmark:
4904 4916
4905 4917 :``added``: push with ``-B`` will create it
4906 4918 :``deleted``: push with ``-B`` will delete it
4907 4919 :``advanced``: push will update it
4908 4920 :``diverged``: push with ``-B`` will update it
4909 4921 :``changed``: push with ``-B`` will update it
4910 4922
4911 4923 From the point of view of pushing behavior, bookmarks
4912 4924 existing only in the remote repository are treated as
4913 4925 ``deleted``, even if it is in fact added remotely.
4914 4926
4915 4927 Returns 0 if there are outgoing changes, 1 otherwise.
4916 4928 """
4917 4929 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4918 4930 # style URLs, so don't overwrite dest.
4919 4931 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
4920 4932 if not path:
4921 4933 raise error.ConfigError(
4922 4934 _(b'default repository not configured!'),
4923 4935 hint=_(b"see 'hg help config.paths'"),
4924 4936 )
4925 4937
4926 4938 opts = pycompat.byteskwargs(opts)
4927 4939 if opts.get(b'graph'):
4928 4940 logcmdutil.checkunsupportedgraphflags([], opts)
4929 4941 o, other = hg._outgoing(ui, repo, dest, opts)
4930 4942 if not o:
4931 4943 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4932 4944 return
4933 4945
4934 4946 revdag = logcmdutil.graphrevs(repo, o, opts)
4935 4947 ui.pager(b'outgoing')
4936 4948 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4937 4949 logcmdutil.displaygraph(
4938 4950 ui, repo, revdag, displayer, graphmod.asciiedges
4939 4951 )
4940 4952 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4941 4953 return 0
4942 4954
4943 4955 if opts.get(b'bookmarks'):
4944 4956 dest = path.pushloc or path.loc
4945 4957 other = hg.peer(repo, opts, dest)
4946 4958 if b'bookmarks' not in other.listkeys(b'namespaces'):
4947 4959 ui.warn(_(b"remote doesn't support bookmarks\n"))
4948 4960 return 0
4949 4961 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
4950 4962 ui.pager(b'outgoing')
4951 4963 return bookmarks.outgoing(ui, repo, other)
4952 4964
4953 4965 repo._subtoppath = path.pushloc or path.loc
4954 4966 try:
4955 4967 return hg.outgoing(ui, repo, dest, opts)
4956 4968 finally:
4957 4969 del repo._subtoppath
4958 4970
4959 4971
4960 4972 @command(
4961 4973 b'parents',
4962 4974 [
4963 4975 (
4964 4976 b'r',
4965 4977 b'rev',
4966 4978 b'',
4967 4979 _(b'show parents of the specified revision'),
4968 4980 _(b'REV'),
4969 4981 ),
4970 4982 ]
4971 4983 + templateopts,
4972 4984 _(b'[-r REV] [FILE]'),
4973 4985 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4974 4986 inferrepo=True,
4975 4987 )
4976 4988 def parents(ui, repo, file_=None, **opts):
4977 4989 """show the parents of the working directory or revision (DEPRECATED)
4978 4990
4979 4991 Print the working directory's parent revisions. If a revision is
4980 4992 given via -r/--rev, the parent of that revision will be printed.
4981 4993 If a file argument is given, the revision in which the file was
4982 4994 last changed (before the working directory revision or the
4983 4995 argument to --rev if given) is printed.
4984 4996
4985 4997 This command is equivalent to::
4986 4998
4987 4999 hg log -r "p1()+p2()" or
4988 5000 hg log -r "p1(REV)+p2(REV)" or
4989 5001 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4990 5002 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4991 5003
4992 5004 See :hg:`summary` and :hg:`help revsets` for related information.
4993 5005
4994 5006 Returns 0 on success.
4995 5007 """
4996 5008
4997 5009 opts = pycompat.byteskwargs(opts)
4998 5010 rev = opts.get(b'rev')
4999 5011 if rev:
5000 5012 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5001 5013 ctx = scmutil.revsingle(repo, rev, None)
5002 5014
5003 5015 if file_:
5004 5016 m = scmutil.match(ctx, (file_,), opts)
5005 5017 if m.anypats() or len(m.files()) != 1:
5006 5018 raise error.InputError(_(b'can only specify an explicit filename'))
5007 5019 file_ = m.files()[0]
5008 5020 filenodes = []
5009 5021 for cp in ctx.parents():
5010 5022 if not cp:
5011 5023 continue
5012 5024 try:
5013 5025 filenodes.append(cp.filenode(file_))
5014 5026 except error.LookupError:
5015 5027 pass
5016 5028 if not filenodes:
5017 5029 raise error.InputError(_(b"'%s' not found in manifest") % file_)
5018 5030 p = []
5019 5031 for fn in filenodes:
5020 5032 fctx = repo.filectx(file_, fileid=fn)
5021 5033 p.append(fctx.node())
5022 5034 else:
5023 5035 p = [cp.node() for cp in ctx.parents()]
5024 5036
5025 5037 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5026 5038 for n in p:
5027 5039 if n != nullid:
5028 5040 displayer.show(repo[n])
5029 5041 displayer.close()
5030 5042
5031 5043
5032 5044 @command(
5033 5045 b'paths',
5034 5046 formatteropts,
5035 5047 _(b'[NAME]'),
5036 5048 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5037 5049 optionalrepo=True,
5038 5050 intents={INTENT_READONLY},
5039 5051 )
5040 5052 def paths(ui, repo, search=None, **opts):
5041 5053 """show aliases for remote repositories
5042 5054
5043 5055 Show definition of symbolic path name NAME. If no name is given,
5044 5056 show definition of all available names.
5045 5057
5046 5058 Option -q/--quiet suppresses all output when searching for NAME
5047 5059 and shows only the path names when listing all definitions.
5048 5060
5049 5061 Path names are defined in the [paths] section of your
5050 5062 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5051 5063 repository, ``.hg/hgrc`` is used, too.
5052 5064
5053 5065 The path names ``default`` and ``default-push`` have a special
5054 5066 meaning. When performing a push or pull operation, they are used
5055 5067 as fallbacks if no location is specified on the command-line.
5056 5068 When ``default-push`` is set, it will be used for push and
5057 5069 ``default`` will be used for pull; otherwise ``default`` is used
5058 5070 as the fallback for both. When cloning a repository, the clone
5059 5071 source is written as ``default`` in ``.hg/hgrc``.
5060 5072
5061 5073 .. note::
5062 5074
5063 5075 ``default`` and ``default-push`` apply to all inbound (e.g.
5064 5076 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5065 5077 and :hg:`bundle`) operations.
5066 5078
5067 5079 See :hg:`help urls` for more information.
5068 5080
5069 5081 .. container:: verbose
5070 5082
5071 5083 Template:
5072 5084
5073 5085 The following keywords are supported. See also :hg:`help templates`.
5074 5086
5075 5087 :name: String. Symbolic name of the path alias.
5076 5088 :pushurl: String. URL for push operations.
5077 5089 :url: String. URL or directory path for the other operations.
5078 5090
5079 5091 Returns 0 on success.
5080 5092 """
5081 5093
5082 5094 opts = pycompat.byteskwargs(opts)
5083 5095 ui.pager(b'paths')
5084 5096 if search:
5085 5097 pathitems = [
5086 5098 (name, path)
5087 5099 for name, path in pycompat.iteritems(ui.paths)
5088 5100 if name == search
5089 5101 ]
5090 5102 else:
5091 5103 pathitems = sorted(pycompat.iteritems(ui.paths))
5092 5104
5093 5105 fm = ui.formatter(b'paths', opts)
5094 5106 if fm.isplain():
5095 5107 hidepassword = util.hidepassword
5096 5108 else:
5097 5109 hidepassword = bytes
5098 5110 if ui.quiet:
5099 5111 namefmt = b'%s\n'
5100 5112 else:
5101 5113 namefmt = b'%s = '
5102 5114 showsubopts = not search and not ui.quiet
5103 5115
5104 5116 for name, path in pathitems:
5105 5117 fm.startitem()
5106 5118 fm.condwrite(not search, b'name', namefmt, name)
5107 5119 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5108 5120 for subopt, value in sorted(path.suboptions.items()):
5109 5121 assert subopt not in (b'name', b'url')
5110 5122 if showsubopts:
5111 5123 fm.plain(b'%s:%s = ' % (name, subopt))
5112 5124 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5113 5125
5114 5126 fm.end()
5115 5127
5116 5128 if search and not pathitems:
5117 5129 if not ui.quiet:
5118 5130 ui.warn(_(b"not found!\n"))
5119 5131 return 1
5120 5132 else:
5121 5133 return 0
5122 5134
5123 5135
5124 5136 @command(
5125 5137 b'phase',
5126 5138 [
5127 5139 (b'p', b'public', False, _(b'set changeset phase to public')),
5128 5140 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5129 5141 (b's', b'secret', False, _(b'set changeset phase to secret')),
5130 5142 (b'f', b'force', False, _(b'allow to move boundary backward')),
5131 5143 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5132 5144 ],
5133 5145 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5134 5146 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5135 5147 )
5136 5148 def phase(ui, repo, *revs, **opts):
5137 5149 """set or show the current phase name
5138 5150
5139 5151 With no argument, show the phase name of the current revision(s).
5140 5152
5141 5153 With one of -p/--public, -d/--draft or -s/--secret, change the
5142 5154 phase value of the specified revisions.
5143 5155
5144 5156 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5145 5157 lower phase to a higher phase. Phases are ordered as follows::
5146 5158
5147 5159 public < draft < secret
5148 5160
5149 5161 Returns 0 on success, 1 if some phases could not be changed.
5150 5162
5151 5163 (For more information about the phases concept, see :hg:`help phases`.)
5152 5164 """
5153 5165 opts = pycompat.byteskwargs(opts)
5154 5166 # search for a unique phase argument
5155 5167 targetphase = None
5156 5168 for idx, name in enumerate(phases.cmdphasenames):
5157 5169 if opts[name]:
5158 5170 if targetphase is not None:
5159 5171 raise error.InputError(_(b'only one phase can be specified'))
5160 5172 targetphase = idx
5161 5173
5162 5174 # look for specified revision
5163 5175 revs = list(revs)
5164 5176 revs.extend(opts[b'rev'])
5165 5177 if not revs:
5166 5178 # display both parents as the second parent phase can influence
5167 5179 # the phase of a merge commit
5168 5180 revs = [c.rev() for c in repo[None].parents()]
5169 5181
5170 5182 revs = scmutil.revrange(repo, revs)
5171 5183
5172 5184 ret = 0
5173 5185 if targetphase is None:
5174 5186 # display
5175 5187 for r in revs:
5176 5188 ctx = repo[r]
5177 5189 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5178 5190 else:
5179 5191 with repo.lock(), repo.transaction(b"phase") as tr:
5180 5192 # set phase
5181 5193 if not revs:
5182 5194 raise error.InputError(_(b'empty revision set'))
5183 5195 nodes = [repo[r].node() for r in revs]
5184 5196 # moving revision from public to draft may hide them
5185 5197 # We have to check result on an unfiltered repository
5186 5198 unfi = repo.unfiltered()
5187 5199 getphase = unfi._phasecache.phase
5188 5200 olddata = [getphase(unfi, r) for r in unfi]
5189 5201 phases.advanceboundary(repo, tr, targetphase, nodes)
5190 5202 if opts[b'force']:
5191 5203 phases.retractboundary(repo, tr, targetphase, nodes)
5192 5204 getphase = unfi._phasecache.phase
5193 5205 newdata = [getphase(unfi, r) for r in unfi]
5194 5206 changes = sum(newdata[r] != olddata[r] for r in unfi)
5195 5207 cl = unfi.changelog
5196 5208 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5197 5209 if rejected:
5198 5210 ui.warn(
5199 5211 _(
5200 5212 b'cannot move %i changesets to a higher '
5201 5213 b'phase, use --force\n'
5202 5214 )
5203 5215 % len(rejected)
5204 5216 )
5205 5217 ret = 1
5206 5218 if changes:
5207 5219 msg = _(b'phase changed for %i changesets\n') % changes
5208 5220 if ret:
5209 5221 ui.status(msg)
5210 5222 else:
5211 5223 ui.note(msg)
5212 5224 else:
5213 5225 ui.warn(_(b'no phases changed\n'))
5214 5226 return ret
5215 5227
5216 5228
5217 5229 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5218 5230 """Run after a changegroup has been added via pull/unbundle
5219 5231
5220 5232 This takes arguments below:
5221 5233
5222 5234 :modheads: change of heads by pull/unbundle
5223 5235 :optupdate: updating working directory is needed or not
5224 5236 :checkout: update destination revision (or None to default destination)
5225 5237 :brev: a name, which might be a bookmark to be activated after updating
5226 5238 """
5227 5239 if modheads == 0:
5228 5240 return
5229 5241 if optupdate:
5230 5242 try:
5231 5243 return hg.updatetotally(ui, repo, checkout, brev)
5232 5244 except error.UpdateAbort as inst:
5233 5245 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5234 5246 hint = inst.hint
5235 5247 raise error.UpdateAbort(msg, hint=hint)
5236 5248 if modheads is not None and modheads > 1:
5237 5249 currentbranchheads = len(repo.branchheads())
5238 5250 if currentbranchheads == modheads:
5239 5251 ui.status(
5240 5252 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5241 5253 )
5242 5254 elif currentbranchheads > 1:
5243 5255 ui.status(
5244 5256 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5245 5257 )
5246 5258 else:
5247 5259 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5248 5260 elif not ui.configbool(b'commands', b'update.requiredest'):
5249 5261 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5250 5262
5251 5263
5252 5264 @command(
5253 5265 b'pull',
5254 5266 [
5255 5267 (
5256 5268 b'u',
5257 5269 b'update',
5258 5270 None,
5259 5271 _(b'update to new branch head if new descendants were pulled'),
5260 5272 ),
5261 5273 (
5262 5274 b'f',
5263 5275 b'force',
5264 5276 None,
5265 5277 _(b'run even when remote repository is unrelated'),
5266 5278 ),
5267 5279 (
5268 5280 b'',
5269 5281 b'confirm',
5270 5282 None,
5271 5283 _(b'confirm pull before applying changes'),
5272 5284 ),
5273 5285 (
5274 5286 b'r',
5275 5287 b'rev',
5276 5288 [],
5277 5289 _(b'a remote changeset intended to be added'),
5278 5290 _(b'REV'),
5279 5291 ),
5280 5292 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5281 5293 (
5282 5294 b'b',
5283 5295 b'branch',
5284 5296 [],
5285 5297 _(b'a specific branch you would like to pull'),
5286 5298 _(b'BRANCH'),
5287 5299 ),
5288 5300 ]
5289 5301 + remoteopts,
5290 5302 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
5291 5303 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5292 5304 helpbasic=True,
5293 5305 )
5294 5306 def pull(ui, repo, source=b"default", **opts):
5295 5307 """pull changes from the specified source
5296 5308
5297 5309 Pull changes from a remote repository to a local one.
5298 5310
5299 5311 This finds all changes from the repository at the specified path
5300 5312 or URL and adds them to a local repository (the current one unless
5301 5313 -R is specified). By default, this does not update the copy of the
5302 5314 project in the working directory.
5303 5315
5304 5316 When cloning from servers that support it, Mercurial may fetch
5305 5317 pre-generated data. When this is done, hooks operating on incoming
5306 5318 changesets and changegroups may fire more than once, once for each
5307 5319 pre-generated bundle and as well as for any additional remaining
5308 5320 data. See :hg:`help -e clonebundles` for more.
5309 5321
5310 5322 Use :hg:`incoming` if you want to see what would have been added
5311 5323 by a pull at the time you issued this command. If you then decide
5312 5324 to add those changes to the repository, you should use :hg:`pull
5313 5325 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5314 5326
5315 5327 If SOURCE is omitted, the 'default' path will be used.
5316 5328 See :hg:`help urls` for more information.
5317 5329
5318 5330 Specifying bookmark as ``.`` is equivalent to specifying the active
5319 5331 bookmark's name.
5320 5332
5321 5333 Returns 0 on success, 1 if an update had unresolved files.
5322 5334 """
5323 5335
5324 5336 opts = pycompat.byteskwargs(opts)
5325 5337 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5326 5338 b'update'
5327 5339 ):
5328 5340 msg = _(b'update destination required by configuration')
5329 5341 hint = _(b'use hg pull followed by hg update DEST')
5330 5342 raise error.InputError(msg, hint=hint)
5331 5343
5332 5344 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5333 5345 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5334 5346 ui.flush()
5335 5347 other = hg.peer(repo, opts, source)
5336 5348 try:
5337 5349 revs, checkout = hg.addbranchrevs(
5338 5350 repo, other, branches, opts.get(b'rev')
5339 5351 )
5340 5352
5341 5353 pullopargs = {}
5342 5354
5343 5355 nodes = None
5344 5356 if opts.get(b'bookmark') or revs:
5345 5357 # The list of bookmark used here is the same used to actually update
5346 5358 # the bookmark names, to avoid the race from issue 4689 and we do
5347 5359 # all lookup and bookmark queries in one go so they see the same
5348 5360 # version of the server state (issue 4700).
5349 5361 nodes = []
5350 5362 fnodes = []
5351 5363 revs = revs or []
5352 5364 if revs and not other.capable(b'lookup'):
5353 5365 err = _(
5354 5366 b"other repository doesn't support revision lookup, "
5355 5367 b"so a rev cannot be specified."
5356 5368 )
5357 5369 raise error.Abort(err)
5358 5370 with other.commandexecutor() as e:
5359 5371 fremotebookmarks = e.callcommand(
5360 5372 b'listkeys', {b'namespace': b'bookmarks'}
5361 5373 )
5362 5374 for r in revs:
5363 5375 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5364 5376 remotebookmarks = fremotebookmarks.result()
5365 5377 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5366 5378 pullopargs[b'remotebookmarks'] = remotebookmarks
5367 5379 for b in opts.get(b'bookmark', []):
5368 5380 b = repo._bookmarks.expandname(b)
5369 5381 if b not in remotebookmarks:
5370 5382 raise error.InputError(
5371 5383 _(b'remote bookmark %s not found!') % b
5372 5384 )
5373 5385 nodes.append(remotebookmarks[b])
5374 5386 for i, rev in enumerate(revs):
5375 5387 node = fnodes[i].result()
5376 5388 nodes.append(node)
5377 5389 if rev == checkout:
5378 5390 checkout = node
5379 5391
5380 5392 wlock = util.nullcontextmanager()
5381 5393 if opts.get(b'update'):
5382 5394 wlock = repo.wlock()
5383 5395 with wlock:
5384 5396 pullopargs.update(opts.get(b'opargs', {}))
5385 5397 modheads = exchange.pull(
5386 5398 repo,
5387 5399 other,
5388 5400 heads=nodes,
5389 5401 force=opts.get(b'force'),
5390 5402 bookmarks=opts.get(b'bookmark', ()),
5391 5403 opargs=pullopargs,
5392 5404 confirm=opts.get(b'confirm'),
5393 5405 ).cgresult
5394 5406
5395 5407 # brev is a name, which might be a bookmark to be activated at
5396 5408 # the end of the update. In other words, it is an explicit
5397 5409 # destination of the update
5398 5410 brev = None
5399 5411
5400 5412 if checkout:
5401 5413 checkout = repo.unfiltered().changelog.rev(checkout)
5402 5414
5403 5415 # order below depends on implementation of
5404 5416 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5405 5417 # because 'checkout' is determined without it.
5406 5418 if opts.get(b'rev'):
5407 5419 brev = opts[b'rev'][0]
5408 5420 elif opts.get(b'branch'):
5409 5421 brev = opts[b'branch'][0]
5410 5422 else:
5411 5423 brev = branches[0]
5412 5424 repo._subtoppath = source
5413 5425 try:
5414 5426 ret = postincoming(
5415 5427 ui, repo, modheads, opts.get(b'update'), checkout, brev
5416 5428 )
5417 5429 except error.FilteredRepoLookupError as exc:
5418 5430 msg = _(b'cannot update to target: %s') % exc.args[0]
5419 5431 exc.args = (msg,) + exc.args[1:]
5420 5432 raise
5421 5433 finally:
5422 5434 del repo._subtoppath
5423 5435
5424 5436 finally:
5425 5437 other.close()
5426 5438 return ret
5427 5439
5428 5440
5429 5441 @command(
5430 5442 b'push',
5431 5443 [
5432 5444 (b'f', b'force', None, _(b'force push')),
5433 5445 (
5434 5446 b'r',
5435 5447 b'rev',
5436 5448 [],
5437 5449 _(b'a changeset intended to be included in the destination'),
5438 5450 _(b'REV'),
5439 5451 ),
5440 5452 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5441 5453 (b'', b'all-bookmarks', None, _(b"push all bookmarks (EXPERIMENTAL)")),
5442 5454 (
5443 5455 b'b',
5444 5456 b'branch',
5445 5457 [],
5446 5458 _(b'a specific branch you would like to push'),
5447 5459 _(b'BRANCH'),
5448 5460 ),
5449 5461 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5450 5462 (
5451 5463 b'',
5452 5464 b'pushvars',
5453 5465 [],
5454 5466 _(b'variables that can be sent to server (ADVANCED)'),
5455 5467 ),
5456 5468 (
5457 5469 b'',
5458 5470 b'publish',
5459 5471 False,
5460 5472 _(b'push the changeset as public (EXPERIMENTAL)'),
5461 5473 ),
5462 5474 ]
5463 5475 + remoteopts,
5464 5476 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
5465 5477 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5466 5478 helpbasic=True,
5467 5479 )
5468 5480 def push(ui, repo, dest=None, **opts):
5469 5481 """push changes to the specified destination
5470 5482
5471 5483 Push changesets from the local repository to the specified
5472 5484 destination.
5473 5485
5474 5486 This operation is symmetrical to pull: it is identical to a pull
5475 5487 in the destination repository from the current one.
5476 5488
5477 5489 By default, push will not allow creation of new heads at the
5478 5490 destination, since multiple heads would make it unclear which head
5479 5491 to use. In this situation, it is recommended to pull and merge
5480 5492 before pushing.
5481 5493
5482 5494 Use --new-branch if you want to allow push to create a new named
5483 5495 branch that is not present at the destination. This allows you to
5484 5496 only create a new branch without forcing other changes.
5485 5497
5486 5498 .. note::
5487 5499
5488 5500 Extra care should be taken with the -f/--force option,
5489 5501 which will push all new heads on all branches, an action which will
5490 5502 almost always cause confusion for collaborators.
5491 5503
5492 5504 If -r/--rev is used, the specified revision and all its ancestors
5493 5505 will be pushed to the remote repository.
5494 5506
5495 5507 If -B/--bookmark is used, the specified bookmarked revision, its
5496 5508 ancestors, and the bookmark will be pushed to the remote
5497 5509 repository. Specifying ``.`` is equivalent to specifying the active
5498 5510 bookmark's name. Use the --all-bookmarks option for pushing all
5499 5511 current bookmarks.
5500 5512
5501 5513 Please see :hg:`help urls` for important details about ``ssh://``
5502 5514 URLs. If DESTINATION is omitted, a default path will be used.
5503 5515
5504 5516 .. container:: verbose
5505 5517
5506 5518 The --pushvars option sends strings to the server that become
5507 5519 environment variables prepended with ``HG_USERVAR_``. For example,
5508 5520 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5509 5521 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5510 5522
5511 5523 pushvars can provide for user-overridable hooks as well as set debug
5512 5524 levels. One example is having a hook that blocks commits containing
5513 5525 conflict markers, but enables the user to override the hook if the file
5514 5526 is using conflict markers for testing purposes or the file format has
5515 5527 strings that look like conflict markers.
5516 5528
5517 5529 By default, servers will ignore `--pushvars`. To enable it add the
5518 5530 following to your configuration file::
5519 5531
5520 5532 [push]
5521 5533 pushvars.server = true
5522 5534
5523 5535 Returns 0 if push was successful, 1 if nothing to push.
5524 5536 """
5525 5537
5526 5538 opts = pycompat.byteskwargs(opts)
5527 5539
5528 5540 if opts.get(b'all_bookmarks'):
5529 5541 cmdutil.check_incompatible_arguments(
5530 5542 opts,
5531 5543 b'all_bookmarks',
5532 5544 [b'bookmark', b'rev'],
5533 5545 )
5534 5546 opts[b'bookmark'] = list(repo._bookmarks)
5535 5547
5536 5548 if opts.get(b'bookmark'):
5537 5549 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5538 5550 for b in opts[b'bookmark']:
5539 5551 # translate -B options to -r so changesets get pushed
5540 5552 b = repo._bookmarks.expandname(b)
5541 5553 if b in repo._bookmarks:
5542 5554 opts.setdefault(b'rev', []).append(b)
5543 5555 else:
5544 5556 # if we try to push a deleted bookmark, translate it to null
5545 5557 # this lets simultaneous -r, -b options continue working
5546 5558 opts.setdefault(b'rev', []).append(b"null")
5547 5559
5548 5560 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
5549 5561 if not path:
5550 5562 raise error.ConfigError(
5551 5563 _(b'default repository not configured!'),
5552 5564 hint=_(b"see 'hg help config.paths'"),
5553 5565 )
5554 5566 dest = path.pushloc or path.loc
5555 5567 branches = (path.branch, opts.get(b'branch') or [])
5556 5568 ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
5557 5569 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
5558 5570 other = hg.peer(repo, opts, dest)
5559 5571
5560 5572 if revs:
5561 5573 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5562 5574 if not revs:
5563 5575 raise error.InputError(
5564 5576 _(b"specified revisions evaluate to an empty set"),
5565 5577 hint=_(b"use different revision arguments"),
5566 5578 )
5567 5579 elif path.pushrev:
5568 5580 # It doesn't make any sense to specify ancestor revisions. So limit
5569 5581 # to DAG heads to make discovery simpler.
5570 5582 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5571 5583 revs = scmutil.revrange(repo, [expr])
5572 5584 revs = [repo[rev].node() for rev in revs]
5573 5585 if not revs:
5574 5586 raise error.InputError(
5575 5587 _(b'default push revset for path evaluates to an empty set')
5576 5588 )
5577 5589 elif ui.configbool(b'commands', b'push.require-revs'):
5578 5590 raise error.InputError(
5579 5591 _(b'no revisions specified to push'),
5580 5592 hint=_(b'did you mean "hg push -r ."?'),
5581 5593 )
5582 5594
5583 5595 repo._subtoppath = dest
5584 5596 try:
5585 5597 # push subrepos depth-first for coherent ordering
5586 5598 c = repo[b'.']
5587 5599 subs = c.substate # only repos that are committed
5588 5600 for s in sorted(subs):
5589 5601 result = c.sub(s).push(opts)
5590 5602 if result == 0:
5591 5603 return not result
5592 5604 finally:
5593 5605 del repo._subtoppath
5594 5606
5595 5607 opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
5596 5608 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5597 5609
5598 5610 pushop = exchange.push(
5599 5611 repo,
5600 5612 other,
5601 5613 opts.get(b'force'),
5602 5614 revs=revs,
5603 5615 newbranch=opts.get(b'new_branch'),
5604 5616 bookmarks=opts.get(b'bookmark', ()),
5605 5617 publish=opts.get(b'publish'),
5606 5618 opargs=opargs,
5607 5619 )
5608 5620
5609 5621 result = not pushop.cgresult
5610 5622
5611 5623 if pushop.bkresult is not None:
5612 5624 if pushop.bkresult == 2:
5613 5625 result = 2
5614 5626 elif not result and pushop.bkresult:
5615 5627 result = 2
5616 5628
5617 5629 return result
5618 5630
5619 5631
5620 5632 @command(
5621 5633 b'recover',
5622 5634 [
5623 5635 (b'', b'verify', False, b"run `hg verify` after successful recover"),
5624 5636 ],
5625 5637 helpcategory=command.CATEGORY_MAINTENANCE,
5626 5638 )
5627 5639 def recover(ui, repo, **opts):
5628 5640 """roll back an interrupted transaction
5629 5641
5630 5642 Recover from an interrupted commit or pull.
5631 5643
5632 5644 This command tries to fix the repository status after an
5633 5645 interrupted operation. It should only be necessary when Mercurial
5634 5646 suggests it.
5635 5647
5636 5648 Returns 0 if successful, 1 if nothing to recover or verify fails.
5637 5649 """
5638 5650 ret = repo.recover()
5639 5651 if ret:
5640 5652 if opts['verify']:
5641 5653 return hg.verify(repo)
5642 5654 else:
5643 5655 msg = _(
5644 5656 b"(verify step skipped, run `hg verify` to check your "
5645 5657 b"repository content)\n"
5646 5658 )
5647 5659 ui.warn(msg)
5648 5660 return 0
5649 5661 return 1
5650 5662
5651 5663
5652 5664 @command(
5653 5665 b'remove|rm',
5654 5666 [
5655 5667 (b'A', b'after', None, _(b'record delete for missing files')),
5656 5668 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5657 5669 ]
5658 5670 + subrepoopts
5659 5671 + walkopts
5660 5672 + dryrunopts,
5661 5673 _(b'[OPTION]... FILE...'),
5662 5674 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5663 5675 helpbasic=True,
5664 5676 inferrepo=True,
5665 5677 )
5666 5678 def remove(ui, repo, *pats, **opts):
5667 5679 """remove the specified files on the next commit
5668 5680
5669 5681 Schedule the indicated files for removal from the current branch.
5670 5682
5671 5683 This command schedules the files to be removed at the next commit.
5672 5684 To undo a remove before that, see :hg:`revert`. To undo added
5673 5685 files, see :hg:`forget`.
5674 5686
5675 5687 .. container:: verbose
5676 5688
5677 5689 -A/--after can be used to remove only files that have already
5678 5690 been deleted, -f/--force can be used to force deletion, and -Af
5679 5691 can be used to remove files from the next revision without
5680 5692 deleting them from the working directory.
5681 5693
5682 5694 The following table details the behavior of remove for different
5683 5695 file states (columns) and option combinations (rows). The file
5684 5696 states are Added [A], Clean [C], Modified [M] and Missing [!]
5685 5697 (as reported by :hg:`status`). The actions are Warn, Remove
5686 5698 (from branch) and Delete (from disk):
5687 5699
5688 5700 ========= == == == ==
5689 5701 opt/state A C M !
5690 5702 ========= == == == ==
5691 5703 none W RD W R
5692 5704 -f R RD RD R
5693 5705 -A W W W R
5694 5706 -Af R R R R
5695 5707 ========= == == == ==
5696 5708
5697 5709 .. note::
5698 5710
5699 5711 :hg:`remove` never deletes files in Added [A] state from the
5700 5712 working directory, not even if ``--force`` is specified.
5701 5713
5702 5714 Returns 0 on success, 1 if any warnings encountered.
5703 5715 """
5704 5716
5705 5717 opts = pycompat.byteskwargs(opts)
5706 5718 after, force = opts.get(b'after'), opts.get(b'force')
5707 5719 dryrun = opts.get(b'dry_run')
5708 5720 if not pats and not after:
5709 5721 raise error.InputError(_(b'no files specified'))
5710 5722
5711 5723 m = scmutil.match(repo[None], pats, opts)
5712 5724 subrepos = opts.get(b'subrepos')
5713 5725 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5714 5726 return cmdutil.remove(
5715 5727 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5716 5728 )
5717 5729
5718 5730
5719 5731 @command(
5720 5732 b'rename|move|mv',
5721 5733 [
5722 5734 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5723 5735 (
5724 5736 b'',
5725 5737 b'at-rev',
5726 5738 b'',
5727 5739 _(b'(un)mark renames in the given revision (EXPERIMENTAL)'),
5728 5740 _(b'REV'),
5729 5741 ),
5730 5742 (
5731 5743 b'f',
5732 5744 b'force',
5733 5745 None,
5734 5746 _(b'forcibly move over an existing managed file'),
5735 5747 ),
5736 5748 ]
5737 5749 + walkopts
5738 5750 + dryrunopts,
5739 5751 _(b'[OPTION]... SOURCE... DEST'),
5740 5752 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5741 5753 )
5742 5754 def rename(ui, repo, *pats, **opts):
5743 5755 """rename files; equivalent of copy + remove
5744 5756
5745 5757 Mark dest as copies of sources; mark sources for deletion. If dest
5746 5758 is a directory, copies are put in that directory. If dest is a
5747 5759 file, there can only be one source.
5748 5760
5749 5761 By default, this command copies the contents of files as they
5750 5762 exist in the working directory. If invoked with -A/--after, the
5751 5763 operation is recorded, but no copying is performed.
5752 5764
5753 5765 This command takes effect at the next commit. To undo a rename
5754 5766 before that, see :hg:`revert`.
5755 5767
5756 5768 Returns 0 on success, 1 if errors are encountered.
5757 5769 """
5758 5770 opts = pycompat.byteskwargs(opts)
5759 5771 with repo.wlock():
5760 5772 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5761 5773
5762 5774
5763 5775 @command(
5764 5776 b'resolve',
5765 5777 [
5766 5778 (b'a', b'all', None, _(b'select all unresolved files')),
5767 5779 (b'l', b'list', None, _(b'list state of files needing merge')),
5768 5780 (b'm', b'mark', None, _(b'mark files as resolved')),
5769 5781 (b'u', b'unmark', None, _(b'mark files as unresolved')),
5770 5782 (b'n', b'no-status', None, _(b'hide status prefix')),
5771 5783 (b'', b're-merge', None, _(b're-merge files')),
5772 5784 ]
5773 5785 + mergetoolopts
5774 5786 + walkopts
5775 5787 + formatteropts,
5776 5788 _(b'[OPTION]... [FILE]...'),
5777 5789 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5778 5790 inferrepo=True,
5779 5791 )
5780 5792 def resolve(ui, repo, *pats, **opts):
5781 5793 """redo merges or set/view the merge status of files
5782 5794
5783 5795 Merges with unresolved conflicts are often the result of
5784 5796 non-interactive merging using the ``internal:merge`` configuration
5785 5797 setting, or a command-line merge tool like ``diff3``. The resolve
5786 5798 command is used to manage the files involved in a merge, after
5787 5799 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5788 5800 working directory must have two parents). See :hg:`help
5789 5801 merge-tools` for information on configuring merge tools.
5790 5802
5791 5803 The resolve command can be used in the following ways:
5792 5804
5793 5805 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
5794 5806 the specified files, discarding any previous merge attempts. Re-merging
5795 5807 is not performed for files already marked as resolved. Use ``--all/-a``
5796 5808 to select all unresolved files. ``--tool`` can be used to specify
5797 5809 the merge tool used for the given files. It overrides the HGMERGE
5798 5810 environment variable and your configuration files. Previous file
5799 5811 contents are saved with a ``.orig`` suffix.
5800 5812
5801 5813 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5802 5814 (e.g. after having manually fixed-up the files). The default is
5803 5815 to mark all unresolved files.
5804 5816
5805 5817 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5806 5818 default is to mark all resolved files.
5807 5819
5808 5820 - :hg:`resolve -l`: list files which had or still have conflicts.
5809 5821 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5810 5822 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
5811 5823 the list. See :hg:`help filesets` for details.
5812 5824
5813 5825 .. note::
5814 5826
5815 5827 Mercurial will not let you commit files with unresolved merge
5816 5828 conflicts. You must use :hg:`resolve -m ...` before you can
5817 5829 commit after a conflicting merge.
5818 5830
5819 5831 .. container:: verbose
5820 5832
5821 5833 Template:
5822 5834
5823 5835 The following keywords are supported in addition to the common template
5824 5836 keywords and functions. See also :hg:`help templates`.
5825 5837
5826 5838 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
5827 5839 :path: String. Repository-absolute path of the file.
5828 5840
5829 5841 Returns 0 on success, 1 if any files fail a resolve attempt.
5830 5842 """
5831 5843
5832 5844 opts = pycompat.byteskwargs(opts)
5833 5845 confirm = ui.configbool(b'commands', b'resolve.confirm')
5834 5846 flaglist = b'all mark unmark list no_status re_merge'.split()
5835 5847 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5836 5848
5837 5849 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5838 5850 if actioncount > 1:
5839 5851 raise error.InputError(_(b"too many actions specified"))
5840 5852 elif actioncount == 0 and ui.configbool(
5841 5853 b'commands', b'resolve.explicit-re-merge'
5842 5854 ):
5843 5855 hint = _(b'use --mark, --unmark, --list or --re-merge')
5844 5856 raise error.InputError(_(b'no action specified'), hint=hint)
5845 5857 if pats and all:
5846 5858 raise error.InputError(_(b"can't specify --all and patterns"))
5847 5859 if not (all or pats or show or mark or unmark):
5848 5860 raise error.InputError(
5849 5861 _(b'no files or directories specified'),
5850 5862 hint=b'use --all to re-merge all unresolved files',
5851 5863 )
5852 5864
5853 5865 if confirm:
5854 5866 if all:
5855 5867 if ui.promptchoice(
5856 5868 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
5857 5869 ):
5858 5870 raise error.CanceledError(_(b'user quit'))
5859 5871 if mark and not pats:
5860 5872 if ui.promptchoice(
5861 5873 _(
5862 5874 b'mark all unresolved files as resolved (yn)?'
5863 5875 b'$$ &Yes $$ &No'
5864 5876 )
5865 5877 ):
5866 5878 raise error.CanceledError(_(b'user quit'))
5867 5879 if unmark and not pats:
5868 5880 if ui.promptchoice(
5869 5881 _(
5870 5882 b'mark all resolved files as unresolved (yn)?'
5871 5883 b'$$ &Yes $$ &No'
5872 5884 )
5873 5885 ):
5874 5886 raise error.CanceledError(_(b'user quit'))
5875 5887
5876 5888 uipathfn = scmutil.getuipathfn(repo)
5877 5889
5878 5890 if show:
5879 5891 ui.pager(b'resolve')
5880 5892 fm = ui.formatter(b'resolve', opts)
5881 5893 ms = mergestatemod.mergestate.read(repo)
5882 5894 wctx = repo[None]
5883 5895 m = scmutil.match(wctx, pats, opts)
5884 5896
5885 5897 # Labels and keys based on merge state. Unresolved path conflicts show
5886 5898 # as 'P'. Resolved path conflicts show as 'R', the same as normal
5887 5899 # resolved conflicts.
5888 5900 mergestateinfo = {
5889 5901 mergestatemod.MERGE_RECORD_UNRESOLVED: (
5890 5902 b'resolve.unresolved',
5891 5903 b'U',
5892 5904 ),
5893 5905 mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
5894 5906 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
5895 5907 b'resolve.unresolved',
5896 5908 b'P',
5897 5909 ),
5898 5910 mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
5899 5911 b'resolve.resolved',
5900 5912 b'R',
5901 5913 ),
5902 5914 }
5903 5915
5904 5916 for f in ms:
5905 5917 if not m(f):
5906 5918 continue
5907 5919
5908 5920 label, key = mergestateinfo[ms[f]]
5909 5921 fm.startitem()
5910 5922 fm.context(ctx=wctx)
5911 5923 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
5912 5924 fm.data(path=f)
5913 5925 fm.plain(b'%s\n' % uipathfn(f), label=label)
5914 5926 fm.end()
5915 5927 return 0
5916 5928
5917 5929 with repo.wlock():
5918 5930 ms = mergestatemod.mergestate.read(repo)
5919 5931
5920 5932 if not (ms.active() or repo.dirstate.p2() != nullid):
5921 5933 raise error.StateError(
5922 5934 _(b'resolve command not applicable when not merging')
5923 5935 )
5924 5936
5925 5937 wctx = repo[None]
5926 5938 m = scmutil.match(wctx, pats, opts)
5927 5939 ret = 0
5928 5940 didwork = False
5929 5941
5930 5942 tocomplete = []
5931 5943 hasconflictmarkers = []
5932 5944 if mark:
5933 5945 markcheck = ui.config(b'commands', b'resolve.mark-check')
5934 5946 if markcheck not in [b'warn', b'abort']:
5935 5947 # Treat all invalid / unrecognized values as 'none'.
5936 5948 markcheck = False
5937 5949 for f in ms:
5938 5950 if not m(f):
5939 5951 continue
5940 5952
5941 5953 didwork = True
5942 5954
5943 5955 # path conflicts must be resolved manually
5944 5956 if ms[f] in (
5945 5957 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
5946 5958 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
5947 5959 ):
5948 5960 if mark:
5949 5961 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
5950 5962 elif unmark:
5951 5963 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
5952 5964 elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
5953 5965 ui.warn(
5954 5966 _(b'%s: path conflict must be resolved manually\n')
5955 5967 % uipathfn(f)
5956 5968 )
5957 5969 continue
5958 5970
5959 5971 if mark:
5960 5972 if markcheck:
5961 5973 fdata = repo.wvfs.tryread(f)
5962 5974 if (
5963 5975 filemerge.hasconflictmarkers(fdata)
5964 5976 and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
5965 5977 ):
5966 5978 hasconflictmarkers.append(f)
5967 5979 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
5968 5980 elif unmark:
5969 5981 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
5970 5982 else:
5971 5983 # backup pre-resolve (merge uses .orig for its own purposes)
5972 5984 a = repo.wjoin(f)
5973 5985 try:
5974 5986 util.copyfile(a, a + b".resolve")
5975 5987 except (IOError, OSError) as inst:
5976 5988 if inst.errno != errno.ENOENT:
5977 5989 raise
5978 5990
5979 5991 try:
5980 5992 # preresolve file
5981 5993 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
5982 5994 with ui.configoverride(overrides, b'resolve'):
5983 5995 complete, r = ms.preresolve(f, wctx)
5984 5996 if not complete:
5985 5997 tocomplete.append(f)
5986 5998 elif r:
5987 5999 ret = 1
5988 6000 finally:
5989 6001 ms.commit()
5990 6002
5991 6003 # replace filemerge's .orig file with our resolve file, but only
5992 6004 # for merges that are complete
5993 6005 if complete:
5994 6006 try:
5995 6007 util.rename(
5996 6008 a + b".resolve", scmutil.backuppath(ui, repo, f)
5997 6009 )
5998 6010 except OSError as inst:
5999 6011 if inst.errno != errno.ENOENT:
6000 6012 raise
6001 6013
6002 6014 if hasconflictmarkers:
6003 6015 ui.warn(
6004 6016 _(
6005 6017 b'warning: the following files still have conflict '
6006 6018 b'markers:\n'
6007 6019 )
6008 6020 + b''.join(
6009 6021 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6010 6022 )
6011 6023 )
6012 6024 if markcheck == b'abort' and not all and not pats:
6013 6025 raise error.StateError(
6014 6026 _(b'conflict markers detected'),
6015 6027 hint=_(b'use --all to mark anyway'),
6016 6028 )
6017 6029
6018 6030 for f in tocomplete:
6019 6031 try:
6020 6032 # resolve file
6021 6033 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6022 6034 with ui.configoverride(overrides, b'resolve'):
6023 6035 r = ms.resolve(f, wctx)
6024 6036 if r:
6025 6037 ret = 1
6026 6038 finally:
6027 6039 ms.commit()
6028 6040
6029 6041 # replace filemerge's .orig file with our resolve file
6030 6042 a = repo.wjoin(f)
6031 6043 try:
6032 6044 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
6033 6045 except OSError as inst:
6034 6046 if inst.errno != errno.ENOENT:
6035 6047 raise
6036 6048
6037 6049 ms.commit()
6038 6050 branchmerge = repo.dirstate.p2() != nullid
6039 6051 mergestatemod.recordupdates(repo, ms.actions(), branchmerge, None)
6040 6052
6041 6053 if not didwork and pats:
6042 6054 hint = None
6043 6055 if not any([p for p in pats if p.find(b':') >= 0]):
6044 6056 pats = [b'path:%s' % p for p in pats]
6045 6057 m = scmutil.match(wctx, pats, opts)
6046 6058 for f in ms:
6047 6059 if not m(f):
6048 6060 continue
6049 6061
6050 6062 def flag(o):
6051 6063 if o == b're_merge':
6052 6064 return b'--re-merge '
6053 6065 return b'-%s ' % o[0:1]
6054 6066
6055 6067 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6056 6068 hint = _(b"(try: hg resolve %s%s)\n") % (
6057 6069 flags,
6058 6070 b' '.join(pats),
6059 6071 )
6060 6072 break
6061 6073 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6062 6074 if hint:
6063 6075 ui.warn(hint)
6064 6076
6065 6077 unresolvedf = list(ms.unresolved())
6066 6078 if not unresolvedf:
6067 6079 ui.status(_(b'(no more unresolved files)\n'))
6068 6080 cmdutil.checkafterresolved(repo)
6069 6081
6070 6082 return ret
6071 6083
6072 6084
6073 6085 @command(
6074 6086 b'revert',
6075 6087 [
6076 6088 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6077 6089 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6078 6090 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6079 6091 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6080 6092 (b'i', b'interactive', None, _(b'interactively select the changes')),
6081 6093 ]
6082 6094 + walkopts
6083 6095 + dryrunopts,
6084 6096 _(b'[OPTION]... [-r REV] [NAME]...'),
6085 6097 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6086 6098 )
6087 6099 def revert(ui, repo, *pats, **opts):
6088 6100 """restore files to their checkout state
6089 6101
6090 6102 .. note::
6091 6103
6092 6104 To check out earlier revisions, you should use :hg:`update REV`.
6093 6105 To cancel an uncommitted merge (and lose your changes),
6094 6106 use :hg:`merge --abort`.
6095 6107
6096 6108 With no revision specified, revert the specified files or directories
6097 6109 to the contents they had in the parent of the working directory.
6098 6110 This restores the contents of files to an unmodified
6099 6111 state and unschedules adds, removes, copies, and renames. If the
6100 6112 working directory has two parents, you must explicitly specify a
6101 6113 revision.
6102 6114
6103 6115 Using the -r/--rev or -d/--date options, revert the given files or
6104 6116 directories to their states as of a specific revision. Because
6105 6117 revert does not change the working directory parents, this will
6106 6118 cause these files to appear modified. This can be helpful to "back
6107 6119 out" some or all of an earlier change. See :hg:`backout` for a
6108 6120 related method.
6109 6121
6110 6122 Modified files are saved with a .orig suffix before reverting.
6111 6123 To disable these backups, use --no-backup. It is possible to store
6112 6124 the backup files in a custom directory relative to the root of the
6113 6125 repository by setting the ``ui.origbackuppath`` configuration
6114 6126 option.
6115 6127
6116 6128 See :hg:`help dates` for a list of formats valid for -d/--date.
6117 6129
6118 6130 See :hg:`help backout` for a way to reverse the effect of an
6119 6131 earlier changeset.
6120 6132
6121 6133 Returns 0 on success.
6122 6134 """
6123 6135
6124 6136 opts = pycompat.byteskwargs(opts)
6125 6137 if opts.get(b"date"):
6126 6138 cmdutil.check_incompatible_arguments(opts, b'date', [b'rev'])
6127 6139 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6128 6140
6129 6141 parent, p2 = repo.dirstate.parents()
6130 6142 if not opts.get(b'rev') and p2 != nullid:
6131 6143 # revert after merge is a trap for new users (issue2915)
6132 6144 raise error.InputError(
6133 6145 _(b'uncommitted merge with no revision specified'),
6134 6146 hint=_(b"use 'hg update' or see 'hg help revert'"),
6135 6147 )
6136 6148
6137 6149 rev = opts.get(b'rev')
6138 6150 if rev:
6139 6151 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6140 6152 ctx = scmutil.revsingle(repo, rev)
6141 6153
6142 6154 if not (
6143 6155 pats
6144 6156 or opts.get(b'include')
6145 6157 or opts.get(b'exclude')
6146 6158 or opts.get(b'all')
6147 6159 or opts.get(b'interactive')
6148 6160 ):
6149 6161 msg = _(b"no files or directories specified")
6150 6162 if p2 != nullid:
6151 6163 hint = _(
6152 6164 b"uncommitted merge, use --all to discard all changes,"
6153 6165 b" or 'hg update -C .' to abort the merge"
6154 6166 )
6155 6167 raise error.InputError(msg, hint=hint)
6156 6168 dirty = any(repo.status())
6157 6169 node = ctx.node()
6158 6170 if node != parent:
6159 6171 if dirty:
6160 6172 hint = (
6161 6173 _(
6162 6174 b"uncommitted changes, use --all to discard all"
6163 6175 b" changes, or 'hg update %d' to update"
6164 6176 )
6165 6177 % ctx.rev()
6166 6178 )
6167 6179 else:
6168 6180 hint = (
6169 6181 _(
6170 6182 b"use --all to revert all files,"
6171 6183 b" or 'hg update %d' to update"
6172 6184 )
6173 6185 % ctx.rev()
6174 6186 )
6175 6187 elif dirty:
6176 6188 hint = _(b"uncommitted changes, use --all to discard all changes")
6177 6189 else:
6178 6190 hint = _(b"use --all to revert all files")
6179 6191 raise error.InputError(msg, hint=hint)
6180 6192
6181 6193 return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts))
6182 6194
6183 6195
6184 6196 @command(
6185 6197 b'rollback',
6186 6198 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6187 6199 helpcategory=command.CATEGORY_MAINTENANCE,
6188 6200 )
6189 6201 def rollback(ui, repo, **opts):
6190 6202 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6191 6203
6192 6204 Please use :hg:`commit --amend` instead of rollback to correct
6193 6205 mistakes in the last commit.
6194 6206
6195 6207 This command should be used with care. There is only one level of
6196 6208 rollback, and there is no way to undo a rollback. It will also
6197 6209 restore the dirstate at the time of the last transaction, losing
6198 6210 any dirstate changes since that time. This command does not alter
6199 6211 the working directory.
6200 6212
6201 6213 Transactions are used to encapsulate the effects of all commands
6202 6214 that create new changesets or propagate existing changesets into a
6203 6215 repository.
6204 6216
6205 6217 .. container:: verbose
6206 6218
6207 6219 For example, the following commands are transactional, and their
6208 6220 effects can be rolled back:
6209 6221
6210 6222 - commit
6211 6223 - import
6212 6224 - pull
6213 6225 - push (with this repository as the destination)
6214 6226 - unbundle
6215 6227
6216 6228 To avoid permanent data loss, rollback will refuse to rollback a
6217 6229 commit transaction if it isn't checked out. Use --force to
6218 6230 override this protection.
6219 6231
6220 6232 The rollback command can be entirely disabled by setting the
6221 6233 ``ui.rollback`` configuration setting to false. If you're here
6222 6234 because you want to use rollback and it's disabled, you can
6223 6235 re-enable the command by setting ``ui.rollback`` to true.
6224 6236
6225 6237 This command is not intended for use on public repositories. Once
6226 6238 changes are visible for pull by other users, rolling a transaction
6227 6239 back locally is ineffective (someone else may already have pulled
6228 6240 the changes). Furthermore, a race is possible with readers of the
6229 6241 repository; for example an in-progress pull from the repository
6230 6242 may fail if a rollback is performed.
6231 6243
6232 6244 Returns 0 on success, 1 if no rollback data is available.
6233 6245 """
6234 6246 if not ui.configbool(b'ui', b'rollback'):
6235 6247 raise error.Abort(
6236 6248 _(b'rollback is disabled because it is unsafe'),
6237 6249 hint=b'see `hg help -v rollback` for information',
6238 6250 )
6239 6251 return repo.rollback(dryrun=opts.get('dry_run'), force=opts.get('force'))
6240 6252
6241 6253
6242 6254 @command(
6243 6255 b'root',
6244 6256 [] + formatteropts,
6245 6257 intents={INTENT_READONLY},
6246 6258 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6247 6259 )
6248 6260 def root(ui, repo, **opts):
6249 6261 """print the root (top) of the current working directory
6250 6262
6251 6263 Print the root directory of the current repository.
6252 6264
6253 6265 .. container:: verbose
6254 6266
6255 6267 Template:
6256 6268
6257 6269 The following keywords are supported in addition to the common template
6258 6270 keywords and functions. See also :hg:`help templates`.
6259 6271
6260 6272 :hgpath: String. Path to the .hg directory.
6261 6273 :storepath: String. Path to the directory holding versioned data.
6262 6274
6263 6275 Returns 0 on success.
6264 6276 """
6265 6277 opts = pycompat.byteskwargs(opts)
6266 6278 with ui.formatter(b'root', opts) as fm:
6267 6279 fm.startitem()
6268 6280 fm.write(b'reporoot', b'%s\n', repo.root)
6269 6281 fm.data(hgpath=repo.path, storepath=repo.spath)
6270 6282
6271 6283
6272 6284 @command(
6273 6285 b'serve',
6274 6286 [
6275 6287 (
6276 6288 b'A',
6277 6289 b'accesslog',
6278 6290 b'',
6279 6291 _(b'name of access log file to write to'),
6280 6292 _(b'FILE'),
6281 6293 ),
6282 6294 (b'd', b'daemon', None, _(b'run server in background')),
6283 6295 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6284 6296 (
6285 6297 b'E',
6286 6298 b'errorlog',
6287 6299 b'',
6288 6300 _(b'name of error log file to write to'),
6289 6301 _(b'FILE'),
6290 6302 ),
6291 6303 # use string type, then we can check if something was passed
6292 6304 (
6293 6305 b'p',
6294 6306 b'port',
6295 6307 b'',
6296 6308 _(b'port to listen on (default: 8000)'),
6297 6309 _(b'PORT'),
6298 6310 ),
6299 6311 (
6300 6312 b'a',
6301 6313 b'address',
6302 6314 b'',
6303 6315 _(b'address to listen on (default: all interfaces)'),
6304 6316 _(b'ADDR'),
6305 6317 ),
6306 6318 (
6307 6319 b'',
6308 6320 b'prefix',
6309 6321 b'',
6310 6322 _(b'prefix path to serve from (default: server root)'),
6311 6323 _(b'PREFIX'),
6312 6324 ),
6313 6325 (
6314 6326 b'n',
6315 6327 b'name',
6316 6328 b'',
6317 6329 _(b'name to show in web pages (default: working directory)'),
6318 6330 _(b'NAME'),
6319 6331 ),
6320 6332 (
6321 6333 b'',
6322 6334 b'web-conf',
6323 6335 b'',
6324 6336 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6325 6337 _(b'FILE'),
6326 6338 ),
6327 6339 (
6328 6340 b'',
6329 6341 b'webdir-conf',
6330 6342 b'',
6331 6343 _(b'name of the hgweb config file (DEPRECATED)'),
6332 6344 _(b'FILE'),
6333 6345 ),
6334 6346 (
6335 6347 b'',
6336 6348 b'pid-file',
6337 6349 b'',
6338 6350 _(b'name of file to write process ID to'),
6339 6351 _(b'FILE'),
6340 6352 ),
6341 6353 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6342 6354 (
6343 6355 b'',
6344 6356 b'cmdserver',
6345 6357 b'',
6346 6358 _(b'for remote clients (ADVANCED)'),
6347 6359 _(b'MODE'),
6348 6360 ),
6349 6361 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6350 6362 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6351 6363 (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
6352 6364 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6353 6365 (b'', b'print-url', None, _(b'start and print only the URL')),
6354 6366 ]
6355 6367 + subrepoopts,
6356 6368 _(b'[OPTION]...'),
6357 6369 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6358 6370 helpbasic=True,
6359 6371 optionalrepo=True,
6360 6372 )
6361 6373 def serve(ui, repo, **opts):
6362 6374 """start stand-alone webserver
6363 6375
6364 6376 Start a local HTTP repository browser and pull server. You can use
6365 6377 this for ad-hoc sharing and browsing of repositories. It is
6366 6378 recommended to use a real web server to serve a repository for
6367 6379 longer periods of time.
6368 6380
6369 6381 Please note that the server does not implement access control.
6370 6382 This means that, by default, anybody can read from the server and
6371 6383 nobody can write to it by default. Set the ``web.allow-push``
6372 6384 option to ``*`` to allow everybody to push to the server. You
6373 6385 should use a real web server if you need to authenticate users.
6374 6386
6375 6387 By default, the server logs accesses to stdout and errors to
6376 6388 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6377 6389 files.
6378 6390
6379 6391 To have the server choose a free port number to listen on, specify
6380 6392 a port number of 0; in this case, the server will print the port
6381 6393 number it uses.
6382 6394
6383 6395 Returns 0 on success.
6384 6396 """
6385 6397
6386 6398 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6387 6399 opts = pycompat.byteskwargs(opts)
6388 6400 if opts[b"print_url"] and ui.verbose:
6389 6401 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6390 6402
6391 6403 if opts[b"stdio"]:
6392 6404 if repo is None:
6393 6405 raise error.RepoError(
6394 6406 _(b"there is no Mercurial repository here (.hg not found)")
6395 6407 )
6396 6408 s = wireprotoserver.sshserver(ui, repo)
6397 6409 s.serve_forever()
6398 6410 return
6399 6411
6400 6412 service = server.createservice(ui, repo, opts)
6401 6413 return server.runservice(opts, initfn=service.init, runfn=service.run)
6402 6414
6403 6415
6404 6416 @command(
6405 6417 b'shelve',
6406 6418 [
6407 6419 (
6408 6420 b'A',
6409 6421 b'addremove',
6410 6422 None,
6411 6423 _(b'mark new/missing files as added/removed before shelving'),
6412 6424 ),
6413 6425 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6414 6426 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6415 6427 (
6416 6428 b'',
6417 6429 b'date',
6418 6430 b'',
6419 6431 _(b'shelve with the specified commit date'),
6420 6432 _(b'DATE'),
6421 6433 ),
6422 6434 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6423 6435 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6424 6436 (
6425 6437 b'k',
6426 6438 b'keep',
6427 6439 False,
6428 6440 _(b'shelve, but keep changes in the working directory'),
6429 6441 ),
6430 6442 (b'l', b'list', None, _(b'list current shelves')),
6431 6443 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6432 6444 (
6433 6445 b'n',
6434 6446 b'name',
6435 6447 b'',
6436 6448 _(b'use the given name for the shelved commit'),
6437 6449 _(b'NAME'),
6438 6450 ),
6439 6451 (
6440 6452 b'p',
6441 6453 b'patch',
6442 6454 None,
6443 6455 _(
6444 6456 b'output patches for changes (provide the names of the shelved '
6445 6457 b'changes as positional arguments)'
6446 6458 ),
6447 6459 ),
6448 6460 (b'i', b'interactive', None, _(b'interactive mode')),
6449 6461 (
6450 6462 b'',
6451 6463 b'stat',
6452 6464 None,
6453 6465 _(
6454 6466 b'output diffstat-style summary of changes (provide the names of '
6455 6467 b'the shelved changes as positional arguments)'
6456 6468 ),
6457 6469 ),
6458 6470 ]
6459 6471 + cmdutil.walkopts,
6460 6472 _(b'hg shelve [OPTION]... [FILE]...'),
6461 6473 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6462 6474 )
6463 6475 def shelve(ui, repo, *pats, **opts):
6464 6476 """save and set aside changes from the working directory
6465 6477
6466 6478 Shelving takes files that "hg status" reports as not clean, saves
6467 6479 the modifications to a bundle (a shelved change), and reverts the
6468 6480 files so that their state in the working directory becomes clean.
6469 6481
6470 6482 To restore these changes to the working directory, using "hg
6471 6483 unshelve"; this will work even if you switch to a different
6472 6484 commit.
6473 6485
6474 6486 When no files are specified, "hg shelve" saves all not-clean
6475 6487 files. If specific files or directories are named, only changes to
6476 6488 those files are shelved.
6477 6489
6478 6490 In bare shelve (when no files are specified, without interactive,
6479 6491 include and exclude option), shelving remembers information if the
6480 6492 working directory was on newly created branch, in other words working
6481 6493 directory was on different branch than its first parent. In this
6482 6494 situation unshelving restores branch information to the working directory.
6483 6495
6484 6496 Each shelved change has a name that makes it easier to find later.
6485 6497 The name of a shelved change defaults to being based on the active
6486 6498 bookmark, or if there is no active bookmark, the current named
6487 6499 branch. To specify a different name, use ``--name``.
6488 6500
6489 6501 To see a list of existing shelved changes, use the ``--list``
6490 6502 option. For each shelved change, this will print its name, age,
6491 6503 and description; use ``--patch`` or ``--stat`` for more details.
6492 6504
6493 6505 To delete specific shelved changes, use ``--delete``. To delete
6494 6506 all shelved changes, use ``--cleanup``.
6495 6507 """
6496 6508 opts = pycompat.byteskwargs(opts)
6497 6509 allowables = [
6498 6510 (b'addremove', {b'create'}), # 'create' is pseudo action
6499 6511 (b'unknown', {b'create'}),
6500 6512 (b'cleanup', {b'cleanup'}),
6501 6513 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6502 6514 (b'delete', {b'delete'}),
6503 6515 (b'edit', {b'create'}),
6504 6516 (b'keep', {b'create'}),
6505 6517 (b'list', {b'list'}),
6506 6518 (b'message', {b'create'}),
6507 6519 (b'name', {b'create'}),
6508 6520 (b'patch', {b'patch', b'list'}),
6509 6521 (b'stat', {b'stat', b'list'}),
6510 6522 ]
6511 6523
6512 6524 def checkopt(opt):
6513 6525 if opts.get(opt):
6514 6526 for i, allowable in allowables:
6515 6527 if opts[i] and opt not in allowable:
6516 6528 raise error.InputError(
6517 6529 _(
6518 6530 b"options '--%s' and '--%s' may not be "
6519 6531 b"used together"
6520 6532 )
6521 6533 % (opt, i)
6522 6534 )
6523 6535 return True
6524 6536
6525 6537 if checkopt(b'cleanup'):
6526 6538 if pats:
6527 6539 raise error.InputError(
6528 6540 _(b"cannot specify names when using '--cleanup'")
6529 6541 )
6530 6542 return shelvemod.cleanupcmd(ui, repo)
6531 6543 elif checkopt(b'delete'):
6532 6544 return shelvemod.deletecmd(ui, repo, pats)
6533 6545 elif checkopt(b'list'):
6534 6546 return shelvemod.listcmd(ui, repo, pats, opts)
6535 6547 elif checkopt(b'patch') or checkopt(b'stat'):
6536 6548 return shelvemod.patchcmds(ui, repo, pats, opts)
6537 6549 else:
6538 6550 return shelvemod.createcmd(ui, repo, pats, opts)
6539 6551
6540 6552
6541 6553 _NOTTERSE = b'nothing'
6542 6554
6543 6555
6544 6556 @command(
6545 6557 b'status|st',
6546 6558 [
6547 6559 (b'A', b'all', None, _(b'show status of all files')),
6548 6560 (b'm', b'modified', None, _(b'show only modified files')),
6549 6561 (b'a', b'added', None, _(b'show only added files')),
6550 6562 (b'r', b'removed', None, _(b'show only removed files')),
6551 6563 (b'd', b'deleted', None, _(b'show only missing files')),
6552 6564 (b'c', b'clean', None, _(b'show only files without changes')),
6553 6565 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6554 6566 (b'i', b'ignored', None, _(b'show only ignored files')),
6555 6567 (b'n', b'no-status', None, _(b'hide status prefix')),
6556 6568 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6557 6569 (
6558 6570 b'C',
6559 6571 b'copies',
6560 6572 None,
6561 6573 _(b'show source of copied files (DEFAULT: ui.statuscopies)'),
6562 6574 ),
6563 6575 (
6564 6576 b'0',
6565 6577 b'print0',
6566 6578 None,
6567 6579 _(b'end filenames with NUL, for use with xargs'),
6568 6580 ),
6569 6581 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6570 6582 (
6571 6583 b'',
6572 6584 b'change',
6573 6585 b'',
6574 6586 _(b'list the changed files of a revision'),
6575 6587 _(b'REV'),
6576 6588 ),
6577 6589 ]
6578 6590 + walkopts
6579 6591 + subrepoopts
6580 6592 + formatteropts,
6581 6593 _(b'[OPTION]... [FILE]...'),
6582 6594 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6583 6595 helpbasic=True,
6584 6596 inferrepo=True,
6585 6597 intents={INTENT_READONLY},
6586 6598 )
6587 6599 def status(ui, repo, *pats, **opts):
6588 6600 """show changed files in the working directory
6589 6601
6590 6602 Show status of files in the repository. If names are given, only
6591 6603 files that match are shown. Files that are clean or ignored or
6592 6604 the source of a copy/move operation, are not listed unless
6593 6605 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6594 6606 Unless options described with "show only ..." are given, the
6595 6607 options -mardu are used.
6596 6608
6597 6609 Option -q/--quiet hides untracked (unknown and ignored) files
6598 6610 unless explicitly requested with -u/--unknown or -i/--ignored.
6599 6611
6600 6612 .. note::
6601 6613
6602 6614 :hg:`status` may appear to disagree with diff if permissions have
6603 6615 changed or a merge has occurred. The standard diff format does
6604 6616 not report permission changes and diff only reports changes
6605 6617 relative to one merge parent.
6606 6618
6607 6619 If one revision is given, it is used as the base revision.
6608 6620 If two revisions are given, the differences between them are
6609 6621 shown. The --change option can also be used as a shortcut to list
6610 6622 the changed files of a revision from its first parent.
6611 6623
6612 6624 The codes used to show the status of files are::
6613 6625
6614 6626 M = modified
6615 6627 A = added
6616 6628 R = removed
6617 6629 C = clean
6618 6630 ! = missing (deleted by non-hg command, but still tracked)
6619 6631 ? = not tracked
6620 6632 I = ignored
6621 6633 = origin of the previous file (with --copies)
6622 6634
6623 6635 .. container:: verbose
6624 6636
6625 6637 The -t/--terse option abbreviates the output by showing only the directory
6626 6638 name if all the files in it share the same status. The option takes an
6627 6639 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6628 6640 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6629 6641 for 'ignored' and 'c' for clean.
6630 6642
6631 6643 It abbreviates only those statuses which are passed. Note that clean and
6632 6644 ignored files are not displayed with '--terse ic' unless the -c/--clean
6633 6645 and -i/--ignored options are also used.
6634 6646
6635 6647 The -v/--verbose option shows information when the repository is in an
6636 6648 unfinished merge, shelve, rebase state etc. You can have this behavior
6637 6649 turned on by default by enabling the ``commands.status.verbose`` option.
6638 6650
6639 6651 You can skip displaying some of these states by setting
6640 6652 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6641 6653 'histedit', 'merge', 'rebase', or 'unshelve'.
6642 6654
6643 6655 Template:
6644 6656
6645 6657 The following keywords are supported in addition to the common template
6646 6658 keywords and functions. See also :hg:`help templates`.
6647 6659
6648 6660 :path: String. Repository-absolute path of the file.
6649 6661 :source: String. Repository-absolute path of the file originated from.
6650 6662 Available if ``--copies`` is specified.
6651 6663 :status: String. Character denoting file's status.
6652 6664
6653 6665 Examples:
6654 6666
6655 6667 - show changes in the working directory relative to a
6656 6668 changeset::
6657 6669
6658 6670 hg status --rev 9353
6659 6671
6660 6672 - show changes in the working directory relative to the
6661 6673 current directory (see :hg:`help patterns` for more information)::
6662 6674
6663 6675 hg status re:
6664 6676
6665 6677 - show all changes including copies in an existing changeset::
6666 6678
6667 6679 hg status --copies --change 9353
6668 6680
6669 6681 - get a NUL separated list of added files, suitable for xargs::
6670 6682
6671 6683 hg status -an0
6672 6684
6673 6685 - show more information about the repository status, abbreviating
6674 6686 added, removed, modified, deleted, and untracked paths::
6675 6687
6676 6688 hg status -v -t mardu
6677 6689
6678 6690 Returns 0 on success.
6679 6691
6680 6692 """
6681 6693
6682 6694 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
6683 6695 opts = pycompat.byteskwargs(opts)
6684 6696 revs = opts.get(b'rev')
6685 6697 change = opts.get(b'change')
6686 6698 terse = opts.get(b'terse')
6687 6699 if terse is _NOTTERSE:
6688 6700 if revs:
6689 6701 terse = b''
6690 6702 else:
6691 6703 terse = ui.config(b'commands', b'status.terse')
6692 6704
6693 6705 if revs and terse:
6694 6706 msg = _(b'cannot use --terse with --rev')
6695 6707 raise error.InputError(msg)
6696 6708 elif change:
6697 6709 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6698 6710 ctx2 = scmutil.revsingle(repo, change, None)
6699 6711 ctx1 = ctx2.p1()
6700 6712 else:
6701 6713 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6702 6714 ctx1, ctx2 = scmutil.revpair(repo, revs)
6703 6715
6704 6716 forcerelativevalue = None
6705 6717 if ui.hasconfig(b'commands', b'status.relative'):
6706 6718 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
6707 6719 uipathfn = scmutil.getuipathfn(
6708 6720 repo,
6709 6721 legacyrelativevalue=bool(pats),
6710 6722 forcerelativevalue=forcerelativevalue,
6711 6723 )
6712 6724
6713 6725 if opts.get(b'print0'):
6714 6726 end = b'\0'
6715 6727 else:
6716 6728 end = b'\n'
6717 6729 states = b'modified added removed deleted unknown ignored clean'.split()
6718 6730 show = [k for k in states if opts.get(k)]
6719 6731 if opts.get(b'all'):
6720 6732 show += ui.quiet and (states[:4] + [b'clean']) or states
6721 6733
6722 6734 if not show:
6723 6735 if ui.quiet:
6724 6736 show = states[:4]
6725 6737 else:
6726 6738 show = states[:5]
6727 6739
6728 6740 m = scmutil.match(ctx2, pats, opts)
6729 6741 if terse:
6730 6742 # we need to compute clean and unknown to terse
6731 6743 stat = repo.status(
6732 6744 ctx1.node(),
6733 6745 ctx2.node(),
6734 6746 m,
6735 6747 b'ignored' in show or b'i' in terse,
6736 6748 clean=True,
6737 6749 unknown=True,
6738 6750 listsubrepos=opts.get(b'subrepos'),
6739 6751 )
6740 6752
6741 6753 stat = cmdutil.tersedir(stat, terse)
6742 6754 else:
6743 6755 stat = repo.status(
6744 6756 ctx1.node(),
6745 6757 ctx2.node(),
6746 6758 m,
6747 6759 b'ignored' in show,
6748 6760 b'clean' in show,
6749 6761 b'unknown' in show,
6750 6762 opts.get(b'subrepos'),
6751 6763 )
6752 6764
6753 6765 changestates = zip(
6754 6766 states,
6755 6767 pycompat.iterbytestr(b'MAR!?IC'),
6756 6768 [getattr(stat, s.decode('utf8')) for s in states],
6757 6769 )
6758 6770
6759 6771 copy = {}
6760 6772 if (
6761 6773 opts.get(b'all')
6762 6774 or opts.get(b'copies')
6763 6775 or ui.configbool(b'ui', b'statuscopies')
6764 6776 ) and not opts.get(b'no_status'):
6765 6777 copy = copies.pathcopies(ctx1, ctx2, m)
6766 6778
6767 6779 morestatus = None
6768 6780 if (
6769 6781 (ui.verbose or ui.configbool(b'commands', b'status.verbose'))
6770 6782 and not ui.plain()
6771 6783 and not opts.get(b'print0')
6772 6784 ):
6773 6785 morestatus = cmdutil.readmorestatus(repo)
6774 6786
6775 6787 ui.pager(b'status')
6776 6788 fm = ui.formatter(b'status', opts)
6777 6789 fmt = b'%s' + end
6778 6790 showchar = not opts.get(b'no_status')
6779 6791
6780 6792 for state, char, files in changestates:
6781 6793 if state in show:
6782 6794 label = b'status.' + state
6783 6795 for f in files:
6784 6796 fm.startitem()
6785 6797 fm.context(ctx=ctx2)
6786 6798 fm.data(itemtype=b'file', path=f)
6787 6799 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
6788 6800 fm.plain(fmt % uipathfn(f), label=label)
6789 6801 if f in copy:
6790 6802 fm.data(source=copy[f])
6791 6803 fm.plain(
6792 6804 (b' %s' + end) % uipathfn(copy[f]),
6793 6805 label=b'status.copied',
6794 6806 )
6795 6807 if morestatus:
6796 6808 morestatus.formatfile(f, fm)
6797 6809
6798 6810 if morestatus:
6799 6811 morestatus.formatfooter(fm)
6800 6812 fm.end()
6801 6813
6802 6814
6803 6815 @command(
6804 6816 b'summary|sum',
6805 6817 [(b'', b'remote', None, _(b'check for push and pull'))],
6806 6818 b'[--remote]',
6807 6819 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6808 6820 helpbasic=True,
6809 6821 intents={INTENT_READONLY},
6810 6822 )
6811 6823 def summary(ui, repo, **opts):
6812 6824 """summarize working directory state
6813 6825
6814 6826 This generates a brief summary of the working directory state,
6815 6827 including parents, branch, commit status, phase and available updates.
6816 6828
6817 6829 With the --remote option, this will check the default paths for
6818 6830 incoming and outgoing changes. This can be time-consuming.
6819 6831
6820 6832 Returns 0 on success.
6821 6833 """
6822 6834
6823 6835 opts = pycompat.byteskwargs(opts)
6824 6836 ui.pager(b'summary')
6825 6837 ctx = repo[None]
6826 6838 parents = ctx.parents()
6827 6839 pnode = parents[0].node()
6828 6840 marks = []
6829 6841
6830 6842 try:
6831 6843 ms = mergestatemod.mergestate.read(repo)
6832 6844 except error.UnsupportedMergeRecords as e:
6833 6845 s = b' '.join(e.recordtypes)
6834 6846 ui.warn(
6835 6847 _(b'warning: merge state has unsupported record types: %s\n') % s
6836 6848 )
6837 6849 unresolved = []
6838 6850 else:
6839 6851 unresolved = list(ms.unresolved())
6840 6852
6841 6853 for p in parents:
6842 6854 # label with log.changeset (instead of log.parent) since this
6843 6855 # shows a working directory parent *changeset*:
6844 6856 # i18n: column positioning for "hg summary"
6845 6857 ui.write(
6846 6858 _(b'parent: %d:%s ') % (p.rev(), p),
6847 6859 label=logcmdutil.changesetlabels(p),
6848 6860 )
6849 6861 ui.write(b' '.join(p.tags()), label=b'log.tag')
6850 6862 if p.bookmarks():
6851 6863 marks.extend(p.bookmarks())
6852 6864 if p.rev() == -1:
6853 6865 if not len(repo):
6854 6866 ui.write(_(b' (empty repository)'))
6855 6867 else:
6856 6868 ui.write(_(b' (no revision checked out)'))
6857 6869 if p.obsolete():
6858 6870 ui.write(_(b' (obsolete)'))
6859 6871 if p.isunstable():
6860 6872 instabilities = (
6861 6873 ui.label(instability, b'trouble.%s' % instability)
6862 6874 for instability in p.instabilities()
6863 6875 )
6864 6876 ui.write(b' (' + b', '.join(instabilities) + b')')
6865 6877 ui.write(b'\n')
6866 6878 if p.description():
6867 6879 ui.status(
6868 6880 b' ' + p.description().splitlines()[0].strip() + b'\n',
6869 6881 label=b'log.summary',
6870 6882 )
6871 6883
6872 6884 branch = ctx.branch()
6873 6885 bheads = repo.branchheads(branch)
6874 6886 # i18n: column positioning for "hg summary"
6875 6887 m = _(b'branch: %s\n') % branch
6876 6888 if branch != b'default':
6877 6889 ui.write(m, label=b'log.branch')
6878 6890 else:
6879 6891 ui.status(m, label=b'log.branch')
6880 6892
6881 6893 if marks:
6882 6894 active = repo._activebookmark
6883 6895 # i18n: column positioning for "hg summary"
6884 6896 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
6885 6897 if active is not None:
6886 6898 if active in marks:
6887 6899 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
6888 6900 marks.remove(active)
6889 6901 else:
6890 6902 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
6891 6903 for m in marks:
6892 6904 ui.write(b' ' + m, label=b'log.bookmark')
6893 6905 ui.write(b'\n', label=b'log.bookmark')
6894 6906
6895 6907 status = repo.status(unknown=True)
6896 6908
6897 6909 c = repo.dirstate.copies()
6898 6910 copied, renamed = [], []
6899 6911 for d, s in pycompat.iteritems(c):
6900 6912 if s in status.removed:
6901 6913 status.removed.remove(s)
6902 6914 renamed.append(d)
6903 6915 else:
6904 6916 copied.append(d)
6905 6917 if d in status.added:
6906 6918 status.added.remove(d)
6907 6919
6908 6920 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6909 6921
6910 6922 labels = [
6911 6923 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
6912 6924 (ui.label(_(b'%d added'), b'status.added'), status.added),
6913 6925 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
6914 6926 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
6915 6927 (ui.label(_(b'%d copied'), b'status.copied'), copied),
6916 6928 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
6917 6929 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
6918 6930 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
6919 6931 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
6920 6932 ]
6921 6933 t = []
6922 6934 for l, s in labels:
6923 6935 if s:
6924 6936 t.append(l % len(s))
6925 6937
6926 6938 t = b', '.join(t)
6927 6939 cleanworkdir = False
6928 6940
6929 6941 if repo.vfs.exists(b'graftstate'):
6930 6942 t += _(b' (graft in progress)')
6931 6943 if repo.vfs.exists(b'updatestate'):
6932 6944 t += _(b' (interrupted update)')
6933 6945 elif len(parents) > 1:
6934 6946 t += _(b' (merge)')
6935 6947 elif branch != parents[0].branch():
6936 6948 t += _(b' (new branch)')
6937 6949 elif parents[0].closesbranch() and pnode in repo.branchheads(
6938 6950 branch, closed=True
6939 6951 ):
6940 6952 t += _(b' (head closed)')
6941 6953 elif not (
6942 6954 status.modified
6943 6955 or status.added
6944 6956 or status.removed
6945 6957 or renamed
6946 6958 or copied
6947 6959 or subs
6948 6960 ):
6949 6961 t += _(b' (clean)')
6950 6962 cleanworkdir = True
6951 6963 elif pnode not in bheads:
6952 6964 t += _(b' (new branch head)')
6953 6965
6954 6966 if parents:
6955 6967 pendingphase = max(p.phase() for p in parents)
6956 6968 else:
6957 6969 pendingphase = phases.public
6958 6970
6959 6971 if pendingphase > phases.newcommitphase(ui):
6960 6972 t += b' (%s)' % phases.phasenames[pendingphase]
6961 6973
6962 6974 if cleanworkdir:
6963 6975 # i18n: column positioning for "hg summary"
6964 6976 ui.status(_(b'commit: %s\n') % t.strip())
6965 6977 else:
6966 6978 # i18n: column positioning for "hg summary"
6967 6979 ui.write(_(b'commit: %s\n') % t.strip())
6968 6980
6969 6981 # all ancestors of branch heads - all ancestors of parent = new csets
6970 6982 new = len(
6971 6983 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
6972 6984 )
6973 6985
6974 6986 if new == 0:
6975 6987 # i18n: column positioning for "hg summary"
6976 6988 ui.status(_(b'update: (current)\n'))
6977 6989 elif pnode not in bheads:
6978 6990 # i18n: column positioning for "hg summary"
6979 6991 ui.write(_(b'update: %d new changesets (update)\n') % new)
6980 6992 else:
6981 6993 # i18n: column positioning for "hg summary"
6982 6994 ui.write(
6983 6995 _(b'update: %d new changesets, %d branch heads (merge)\n')
6984 6996 % (new, len(bheads))
6985 6997 )
6986 6998
6987 6999 t = []
6988 7000 draft = len(repo.revs(b'draft()'))
6989 7001 if draft:
6990 7002 t.append(_(b'%d draft') % draft)
6991 7003 secret = len(repo.revs(b'secret()'))
6992 7004 if secret:
6993 7005 t.append(_(b'%d secret') % secret)
6994 7006
6995 7007 if draft or secret:
6996 7008 ui.status(_(b'phases: %s\n') % b', '.join(t))
6997 7009
6998 7010 if obsolete.isenabled(repo, obsolete.createmarkersopt):
6999 7011 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7000 7012 numtrouble = len(repo.revs(trouble + b"()"))
7001 7013 # We write all the possibilities to ease translation
7002 7014 troublemsg = {
7003 7015 b"orphan": _(b"orphan: %d changesets"),
7004 7016 b"contentdivergent": _(b"content-divergent: %d changesets"),
7005 7017 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7006 7018 }
7007 7019 if numtrouble > 0:
7008 7020 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7009 7021
7010 7022 cmdutil.summaryhooks(ui, repo)
7011 7023
7012 7024 if opts.get(b'remote'):
7013 7025 needsincoming, needsoutgoing = True, True
7014 7026 else:
7015 7027 needsincoming, needsoutgoing = False, False
7016 7028 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
7017 7029 if i:
7018 7030 needsincoming = True
7019 7031 if o:
7020 7032 needsoutgoing = True
7021 7033 if not needsincoming and not needsoutgoing:
7022 7034 return
7023 7035
7024 7036 def getincoming():
7025 7037 source, branches = hg.parseurl(ui.expandpath(b'default'))
7026 7038 sbranch = branches[0]
7027 7039 try:
7028 7040 other = hg.peer(repo, {}, source)
7029 7041 except error.RepoError:
7030 7042 if opts.get(b'remote'):
7031 7043 raise
7032 7044 return source, sbranch, None, None, None
7033 7045 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7034 7046 if revs:
7035 7047 revs = [other.lookup(rev) for rev in revs]
7036 7048 ui.debug(b'comparing with %s\n' % util.hidepassword(source))
7037 7049 repo.ui.pushbuffer()
7038 7050 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7039 7051 repo.ui.popbuffer()
7040 7052 return source, sbranch, other, commoninc, commoninc[1]
7041 7053
7042 7054 if needsincoming:
7043 7055 source, sbranch, sother, commoninc, incoming = getincoming()
7044 7056 else:
7045 7057 source = sbranch = sother = commoninc = incoming = None
7046 7058
7047 7059 def getoutgoing():
7048 7060 dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
7049 7061 dbranch = branches[0]
7050 7062 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
7051 7063 if source != dest:
7052 7064 try:
7053 7065 dother = hg.peer(repo, {}, dest)
7054 7066 except error.RepoError:
7055 7067 if opts.get(b'remote'):
7056 7068 raise
7057 7069 return dest, dbranch, None, None
7058 7070 ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
7059 7071 elif sother is None:
7060 7072 # there is no explicit destination peer, but source one is invalid
7061 7073 return dest, dbranch, None, None
7062 7074 else:
7063 7075 dother = sother
7064 7076 if source != dest or (sbranch is not None and sbranch != dbranch):
7065 7077 common = None
7066 7078 else:
7067 7079 common = commoninc
7068 7080 if revs:
7069 7081 revs = [repo.lookup(rev) for rev in revs]
7070 7082 repo.ui.pushbuffer()
7071 7083 outgoing = discovery.findcommonoutgoing(
7072 7084 repo, dother, onlyheads=revs, commoninc=common
7073 7085 )
7074 7086 repo.ui.popbuffer()
7075 7087 return dest, dbranch, dother, outgoing
7076 7088
7077 7089 if needsoutgoing:
7078 7090 dest, dbranch, dother, outgoing = getoutgoing()
7079 7091 else:
7080 7092 dest = dbranch = dother = outgoing = None
7081 7093
7082 7094 if opts.get(b'remote'):
7083 7095 t = []
7084 7096 if incoming:
7085 7097 t.append(_(b'1 or more incoming'))
7086 7098 o = outgoing.missing
7087 7099 if o:
7088 7100 t.append(_(b'%d outgoing') % len(o))
7089 7101 other = dother or sother
7090 7102 if b'bookmarks' in other.listkeys(b'namespaces'):
7091 7103 counts = bookmarks.summary(repo, other)
7092 7104 if counts[0] > 0:
7093 7105 t.append(_(b'%d incoming bookmarks') % counts[0])
7094 7106 if counts[1] > 0:
7095 7107 t.append(_(b'%d outgoing bookmarks') % counts[1])
7096 7108
7097 7109 if t:
7098 7110 # i18n: column positioning for "hg summary"
7099 7111 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7100 7112 else:
7101 7113 # i18n: column positioning for "hg summary"
7102 7114 ui.status(_(b'remote: (synced)\n'))
7103 7115
7104 7116 cmdutil.summaryremotehooks(
7105 7117 ui,
7106 7118 repo,
7107 7119 opts,
7108 7120 (
7109 7121 (source, sbranch, sother, commoninc),
7110 7122 (dest, dbranch, dother, outgoing),
7111 7123 ),
7112 7124 )
7113 7125
7114 7126
7115 7127 @command(
7116 7128 b'tag',
7117 7129 [
7118 7130 (b'f', b'force', None, _(b'force tag')),
7119 7131 (b'l', b'local', None, _(b'make the tag local')),
7120 7132 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7121 7133 (b'', b'remove', None, _(b'remove a tag')),
7122 7134 # -l/--local is already there, commitopts cannot be used
7123 7135 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7124 7136 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7125 7137 ]
7126 7138 + commitopts2,
7127 7139 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7128 7140 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7129 7141 )
7130 7142 def tag(ui, repo, name1, *names, **opts):
7131 7143 """add one or more tags for the current or given revision
7132 7144
7133 7145 Name a particular revision using <name>.
7134 7146
7135 7147 Tags are used to name particular revisions of the repository and are
7136 7148 very useful to compare different revisions, to go back to significant
7137 7149 earlier versions or to mark branch points as releases, etc. Changing
7138 7150 an existing tag is normally disallowed; use -f/--force to override.
7139 7151
7140 7152 If no revision is given, the parent of the working directory is
7141 7153 used.
7142 7154
7143 7155 To facilitate version control, distribution, and merging of tags,
7144 7156 they are stored as a file named ".hgtags" which is managed similarly
7145 7157 to other project files and can be hand-edited if necessary. This
7146 7158 also means that tagging creates a new commit. The file
7147 7159 ".hg/localtags" is used for local tags (not shared among
7148 7160 repositories).
7149 7161
7150 7162 Tag commits are usually made at the head of a branch. If the parent
7151 7163 of the working directory is not a branch head, :hg:`tag` aborts; use
7152 7164 -f/--force to force the tag commit to be based on a non-head
7153 7165 changeset.
7154 7166
7155 7167 See :hg:`help dates` for a list of formats valid for -d/--date.
7156 7168
7157 7169 Since tag names have priority over branch names during revision
7158 7170 lookup, using an existing branch name as a tag name is discouraged.
7159 7171
7160 7172 Returns 0 on success.
7161 7173 """
7162 7174 cmdutil.check_incompatible_arguments(opts, 'remove', ['rev'])
7163 7175 opts = pycompat.byteskwargs(opts)
7164 7176 with repo.wlock(), repo.lock():
7165 7177 rev_ = b"."
7166 7178 names = [t.strip() for t in (name1,) + names]
7167 7179 if len(names) != len(set(names)):
7168 7180 raise error.InputError(_(b'tag names must be unique'))
7169 7181 for n in names:
7170 7182 scmutil.checknewlabel(repo, n, b'tag')
7171 7183 if not n:
7172 7184 raise error.InputError(
7173 7185 _(b'tag names cannot consist entirely of whitespace')
7174 7186 )
7175 7187 if opts.get(b'rev'):
7176 7188 rev_ = opts[b'rev']
7177 7189 message = opts.get(b'message')
7178 7190 if opts.get(b'remove'):
7179 7191 if opts.get(b'local'):
7180 7192 expectedtype = b'local'
7181 7193 else:
7182 7194 expectedtype = b'global'
7183 7195
7184 7196 for n in names:
7185 7197 if repo.tagtype(n) == b'global':
7186 7198 alltags = tagsmod.findglobaltags(ui, repo)
7187 7199 if alltags[n][0] == nullid:
7188 7200 raise error.InputError(
7189 7201 _(b"tag '%s' is already removed") % n
7190 7202 )
7191 7203 if not repo.tagtype(n):
7192 7204 raise error.InputError(_(b"tag '%s' does not exist") % n)
7193 7205 if repo.tagtype(n) != expectedtype:
7194 7206 if expectedtype == b'global':
7195 7207 raise error.InputError(
7196 7208 _(b"tag '%s' is not a global tag") % n
7197 7209 )
7198 7210 else:
7199 7211 raise error.InputError(
7200 7212 _(b"tag '%s' is not a local tag") % n
7201 7213 )
7202 7214 rev_ = b'null'
7203 7215 if not message:
7204 7216 # we don't translate commit messages
7205 7217 message = b'Removed tag %s' % b', '.join(names)
7206 7218 elif not opts.get(b'force'):
7207 7219 for n in names:
7208 7220 if n in repo.tags():
7209 7221 raise error.InputError(
7210 7222 _(b"tag '%s' already exists (use -f to force)") % n
7211 7223 )
7212 7224 if not opts.get(b'local'):
7213 7225 p1, p2 = repo.dirstate.parents()
7214 7226 if p2 != nullid:
7215 7227 raise error.StateError(_(b'uncommitted merge'))
7216 7228 bheads = repo.branchheads()
7217 7229 if not opts.get(b'force') and bheads and p1 not in bheads:
7218 7230 raise error.InputError(
7219 7231 _(
7220 7232 b'working directory is not at a branch head '
7221 7233 b'(use -f to force)'
7222 7234 )
7223 7235 )
7224 7236 node = scmutil.revsingle(repo, rev_).node()
7225 7237
7226 7238 if not message:
7227 7239 # we don't translate commit messages
7228 7240 message = b'Added tag %s for changeset %s' % (
7229 7241 b', '.join(names),
7230 7242 short(node),
7231 7243 )
7232 7244
7233 7245 date = opts.get(b'date')
7234 7246 if date:
7235 7247 date = dateutil.parsedate(date)
7236 7248
7237 7249 if opts.get(b'remove'):
7238 7250 editform = b'tag.remove'
7239 7251 else:
7240 7252 editform = b'tag.add'
7241 7253 editor = cmdutil.getcommiteditor(
7242 7254 editform=editform, **pycompat.strkwargs(opts)
7243 7255 )
7244 7256
7245 7257 # don't allow tagging the null rev
7246 7258 if (
7247 7259 not opts.get(b'remove')
7248 7260 and scmutil.revsingle(repo, rev_).rev() == nullrev
7249 7261 ):
7250 7262 raise error.InputError(_(b"cannot tag null revision"))
7251 7263
7252 7264 tagsmod.tag(
7253 7265 repo,
7254 7266 names,
7255 7267 node,
7256 7268 message,
7257 7269 opts.get(b'local'),
7258 7270 opts.get(b'user'),
7259 7271 date,
7260 7272 editor=editor,
7261 7273 )
7262 7274
7263 7275
7264 7276 @command(
7265 7277 b'tags',
7266 7278 formatteropts,
7267 7279 b'',
7268 7280 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7269 7281 intents={INTENT_READONLY},
7270 7282 )
7271 7283 def tags(ui, repo, **opts):
7272 7284 """list repository tags
7273 7285
7274 7286 This lists both regular and local tags. When the -v/--verbose
7275 7287 switch is used, a third column "local" is printed for local tags.
7276 7288 When the -q/--quiet switch is used, only the tag name is printed.
7277 7289
7278 7290 .. container:: verbose
7279 7291
7280 7292 Template:
7281 7293
7282 7294 The following keywords are supported in addition to the common template
7283 7295 keywords and functions such as ``{tag}``. See also
7284 7296 :hg:`help templates`.
7285 7297
7286 7298 :type: String. ``local`` for local tags.
7287 7299
7288 7300 Returns 0 on success.
7289 7301 """
7290 7302
7291 7303 opts = pycompat.byteskwargs(opts)
7292 7304 ui.pager(b'tags')
7293 7305 fm = ui.formatter(b'tags', opts)
7294 7306 hexfunc = fm.hexfunc
7295 7307
7296 7308 for t, n in reversed(repo.tagslist()):
7297 7309 hn = hexfunc(n)
7298 7310 label = b'tags.normal'
7299 7311 tagtype = b''
7300 7312 if repo.tagtype(t) == b'local':
7301 7313 label = b'tags.local'
7302 7314 tagtype = b'local'
7303 7315
7304 7316 fm.startitem()
7305 7317 fm.context(repo=repo)
7306 7318 fm.write(b'tag', b'%s', t, label=label)
7307 7319 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7308 7320 fm.condwrite(
7309 7321 not ui.quiet,
7310 7322 b'rev node',
7311 7323 fmt,
7312 7324 repo.changelog.rev(n),
7313 7325 hn,
7314 7326 label=label,
7315 7327 )
7316 7328 fm.condwrite(
7317 7329 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7318 7330 )
7319 7331 fm.plain(b'\n')
7320 7332 fm.end()
7321 7333
7322 7334
7323 7335 @command(
7324 7336 b'tip',
7325 7337 [
7326 7338 (b'p', b'patch', None, _(b'show patch')),
7327 7339 (b'g', b'git', None, _(b'use git extended diff format')),
7328 7340 ]
7329 7341 + templateopts,
7330 7342 _(b'[-p] [-g]'),
7331 7343 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7332 7344 )
7333 7345 def tip(ui, repo, **opts):
7334 7346 """show the tip revision (DEPRECATED)
7335 7347
7336 7348 The tip revision (usually just called the tip) is the changeset
7337 7349 most recently added to the repository (and therefore the most
7338 7350 recently changed head).
7339 7351
7340 7352 If you have just made a commit, that commit will be the tip. If
7341 7353 you have just pulled changes from another repository, the tip of
7342 7354 that repository becomes the current tip. The "tip" tag is special
7343 7355 and cannot be renamed or assigned to a different changeset.
7344 7356
7345 7357 This command is deprecated, please use :hg:`heads` instead.
7346 7358
7347 7359 Returns 0 on success.
7348 7360 """
7349 7361 opts = pycompat.byteskwargs(opts)
7350 7362 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7351 7363 displayer.show(repo[b'tip'])
7352 7364 displayer.close()
7353 7365
7354 7366
7355 7367 @command(
7356 7368 b'unbundle',
7357 7369 [
7358 7370 (
7359 7371 b'u',
7360 7372 b'update',
7361 7373 None,
7362 7374 _(b'update to new branch head if changesets were unbundled'),
7363 7375 )
7364 7376 ],
7365 7377 _(b'[-u] FILE...'),
7366 7378 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7367 7379 )
7368 7380 def unbundle(ui, repo, fname1, *fnames, **opts):
7369 7381 """apply one or more bundle files
7370 7382
7371 7383 Apply one or more bundle files generated by :hg:`bundle`.
7372 7384
7373 7385 Returns 0 on success, 1 if an update has unresolved files.
7374 7386 """
7375 7387 fnames = (fname1,) + fnames
7376 7388
7377 7389 with repo.lock():
7378 7390 for fname in fnames:
7379 7391 f = hg.openpath(ui, fname)
7380 7392 gen = exchange.readbundle(ui, f, fname)
7381 7393 if isinstance(gen, streamclone.streamcloneapplier):
7382 7394 raise error.InputError(
7383 7395 _(
7384 7396 b'packed bundles cannot be applied with '
7385 7397 b'"hg unbundle"'
7386 7398 ),
7387 7399 hint=_(b'use "hg debugapplystreamclonebundle"'),
7388 7400 )
7389 7401 url = b'bundle:' + fname
7390 7402 try:
7391 7403 txnname = b'unbundle'
7392 7404 if not isinstance(gen, bundle2.unbundle20):
7393 7405 txnname = b'unbundle\n%s' % util.hidepassword(url)
7394 7406 with repo.transaction(txnname) as tr:
7395 7407 op = bundle2.applybundle(
7396 7408 repo, gen, tr, source=b'unbundle', url=url
7397 7409 )
7398 7410 except error.BundleUnknownFeatureError as exc:
7399 7411 raise error.Abort(
7400 7412 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7401 7413 hint=_(
7402 7414 b"see https://mercurial-scm.org/"
7403 7415 b"wiki/BundleFeature for more "
7404 7416 b"information"
7405 7417 ),
7406 7418 )
7407 7419 modheads = bundle2.combinechangegroupresults(op)
7408 7420
7409 7421 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
7410 7422
7411 7423
7412 7424 @command(
7413 7425 b'unshelve',
7414 7426 [
7415 7427 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7416 7428 (
7417 7429 b'c',
7418 7430 b'continue',
7419 7431 None,
7420 7432 _(b'continue an incomplete unshelve operation'),
7421 7433 ),
7422 7434 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7423 7435 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7424 7436 (
7425 7437 b'n',
7426 7438 b'name',
7427 7439 b'',
7428 7440 _(b'restore shelved change with given name'),
7429 7441 _(b'NAME'),
7430 7442 ),
7431 7443 (b't', b'tool', b'', _(b'specify merge tool')),
7432 7444 (
7433 7445 b'',
7434 7446 b'date',
7435 7447 b'',
7436 7448 _(b'set date for temporary commits (DEPRECATED)'),
7437 7449 _(b'DATE'),
7438 7450 ),
7439 7451 ],
7440 7452 _(b'hg unshelve [OPTION]... [[-n] SHELVED]'),
7441 7453 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7442 7454 )
7443 7455 def unshelve(ui, repo, *shelved, **opts):
7444 7456 """restore a shelved change to the working directory
7445 7457
7446 7458 This command accepts an optional name of a shelved change to
7447 7459 restore. If none is given, the most recent shelved change is used.
7448 7460
7449 7461 If a shelved change is applied successfully, the bundle that
7450 7462 contains the shelved changes is moved to a backup location
7451 7463 (.hg/shelve-backup).
7452 7464
7453 7465 Since you can restore a shelved change on top of an arbitrary
7454 7466 commit, it is possible that unshelving will result in a conflict
7455 7467 between your changes and the commits you are unshelving onto. If
7456 7468 this occurs, you must resolve the conflict, then use
7457 7469 ``--continue`` to complete the unshelve operation. (The bundle
7458 7470 will not be moved until you successfully complete the unshelve.)
7459 7471
7460 7472 (Alternatively, you can use ``--abort`` to abandon an unshelve
7461 7473 that causes a conflict. This reverts the unshelved changes, and
7462 7474 leaves the bundle in place.)
7463 7475
7464 7476 If bare shelved change (without interactive, include and exclude
7465 7477 option) was done on newly created branch it would restore branch
7466 7478 information to the working directory.
7467 7479
7468 7480 After a successful unshelve, the shelved changes are stored in a
7469 7481 backup directory. Only the N most recent backups are kept. N
7470 7482 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7471 7483 configuration option.
7472 7484
7473 7485 .. container:: verbose
7474 7486
7475 7487 Timestamp in seconds is used to decide order of backups. More
7476 7488 than ``maxbackups`` backups are kept, if same timestamp
7477 7489 prevents from deciding exact order of them, for safety.
7478 7490
7479 7491 Selected changes can be unshelved with ``--interactive`` flag.
7480 7492 The working directory is updated with the selected changes, and
7481 7493 only the unselected changes remain shelved.
7482 7494 Note: The whole shelve is applied to working directory first before
7483 7495 running interactively. So, this will bring up all the conflicts between
7484 7496 working directory and the shelve, irrespective of which changes will be
7485 7497 unshelved.
7486 7498 """
7487 7499 with repo.wlock():
7488 7500 return shelvemod.unshelvecmd(ui, repo, *shelved, **opts)
7489 7501
7490 7502
7491 7503 statemod.addunfinished(
7492 7504 b'unshelve',
7493 7505 fname=b'shelvedstate',
7494 7506 continueflag=True,
7495 7507 abortfunc=shelvemod.hgabortunshelve,
7496 7508 continuefunc=shelvemod.hgcontinueunshelve,
7497 7509 cmdmsg=_(b'unshelve already in progress'),
7498 7510 )
7499 7511
7500 7512
7501 7513 @command(
7502 7514 b'update|up|checkout|co',
7503 7515 [
7504 7516 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7505 7517 (b'c', b'check', None, _(b'require clean working directory')),
7506 7518 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7507 7519 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7508 7520 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7509 7521 ]
7510 7522 + mergetoolopts,
7511 7523 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7512 7524 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7513 7525 helpbasic=True,
7514 7526 )
7515 7527 def update(ui, repo, node=None, **opts):
7516 7528 """update working directory (or switch revisions)
7517 7529
7518 7530 Update the repository's working directory to the specified
7519 7531 changeset. If no changeset is specified, update to the tip of the
7520 7532 current named branch and move the active bookmark (see :hg:`help
7521 7533 bookmarks`).
7522 7534
7523 7535 Update sets the working directory's parent revision to the specified
7524 7536 changeset (see :hg:`help parents`).
7525 7537
7526 7538 If the changeset is not a descendant or ancestor of the working
7527 7539 directory's parent and there are uncommitted changes, the update is
7528 7540 aborted. With the -c/--check option, the working directory is checked
7529 7541 for uncommitted changes; if none are found, the working directory is
7530 7542 updated to the specified changeset.
7531 7543
7532 7544 .. container:: verbose
7533 7545
7534 7546 The -C/--clean, -c/--check, and -m/--merge options control what
7535 7547 happens if the working directory contains uncommitted changes.
7536 7548 At most of one of them can be specified.
7537 7549
7538 7550 1. If no option is specified, and if
7539 7551 the requested changeset is an ancestor or descendant of
7540 7552 the working directory's parent, the uncommitted changes
7541 7553 are merged into the requested changeset and the merged
7542 7554 result is left uncommitted. If the requested changeset is
7543 7555 not an ancestor or descendant (that is, it is on another
7544 7556 branch), the update is aborted and the uncommitted changes
7545 7557 are preserved.
7546 7558
7547 7559 2. With the -m/--merge option, the update is allowed even if the
7548 7560 requested changeset is not an ancestor or descendant of
7549 7561 the working directory's parent.
7550 7562
7551 7563 3. With the -c/--check option, the update is aborted and the
7552 7564 uncommitted changes are preserved.
7553 7565
7554 7566 4. With the -C/--clean option, uncommitted changes are discarded and
7555 7567 the working directory is updated to the requested changeset.
7556 7568
7557 7569 To cancel an uncommitted merge (and lose your changes), use
7558 7570 :hg:`merge --abort`.
7559 7571
7560 7572 Use null as the changeset to remove the working directory (like
7561 7573 :hg:`clone -U`).
7562 7574
7563 7575 If you want to revert just one file to an older revision, use
7564 7576 :hg:`revert [-r REV] NAME`.
7565 7577
7566 7578 See :hg:`help dates` for a list of formats valid for -d/--date.
7567 7579
7568 7580 Returns 0 on success, 1 if there are unresolved files.
7569 7581 """
7570 7582 cmdutil.check_at_most_one_arg(opts, 'clean', 'check', 'merge')
7571 7583 rev = opts.get('rev')
7572 7584 date = opts.get('date')
7573 7585 clean = opts.get('clean')
7574 7586 check = opts.get('check')
7575 7587 merge = opts.get('merge')
7576 7588 if rev and node:
7577 7589 raise error.InputError(_(b"please specify just one revision"))
7578 7590
7579 7591 if ui.configbool(b'commands', b'update.requiredest'):
7580 7592 if not node and not rev and not date:
7581 7593 raise error.InputError(
7582 7594 _(b'you must specify a destination'),
7583 7595 hint=_(b'for example: hg update ".::"'),
7584 7596 )
7585 7597
7586 7598 if rev is None or rev == b'':
7587 7599 rev = node
7588 7600
7589 7601 if date and rev is not None:
7590 7602 raise error.InputError(_(b"you can't specify a revision and a date"))
7591 7603
7592 7604 updatecheck = None
7593 7605 if check:
7594 7606 updatecheck = b'abort'
7595 7607 elif merge:
7596 7608 updatecheck = b'none'
7597 7609
7598 7610 with repo.wlock():
7599 7611 cmdutil.clearunfinished(repo)
7600 7612 if date:
7601 7613 rev = cmdutil.finddate(ui, repo, date)
7602 7614
7603 7615 # if we defined a bookmark, we have to remember the original name
7604 7616 brev = rev
7605 7617 if rev:
7606 7618 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7607 7619 ctx = scmutil.revsingle(repo, rev, default=None)
7608 7620 rev = ctx.rev()
7609 7621 hidden = ctx.hidden()
7610 7622 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
7611 7623 with ui.configoverride(overrides, b'update'):
7612 7624 ret = hg.updatetotally(
7613 7625 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7614 7626 )
7615 7627 if hidden:
7616 7628 ctxstr = ctx.hex()[:12]
7617 7629 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7618 7630
7619 7631 if ctx.obsolete():
7620 7632 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7621 7633 ui.warn(b"(%s)\n" % obsfatemsg)
7622 7634 return ret
7623 7635
7624 7636
7625 7637 @command(
7626 7638 b'verify',
7627 7639 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7628 7640 helpcategory=command.CATEGORY_MAINTENANCE,
7629 7641 )
7630 7642 def verify(ui, repo, **opts):
7631 7643 """verify the integrity of the repository
7632 7644
7633 7645 Verify the integrity of the current repository.
7634 7646
7635 7647 This will perform an extensive check of the repository's
7636 7648 integrity, validating the hashes and checksums of each entry in
7637 7649 the changelog, manifest, and tracked files, as well as the
7638 7650 integrity of their crosslinks and indices.
7639 7651
7640 7652 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7641 7653 for more information about recovery from corruption of the
7642 7654 repository.
7643 7655
7644 7656 Returns 0 on success, 1 if errors are encountered.
7645 7657 """
7646 7658 opts = pycompat.byteskwargs(opts)
7647 7659
7648 7660 level = None
7649 7661 if opts[b'full']:
7650 7662 level = verifymod.VERIFY_FULL
7651 7663 return hg.verify(repo, level)
7652 7664
7653 7665
7654 7666 @command(
7655 7667 b'version',
7656 7668 [] + formatteropts,
7657 7669 helpcategory=command.CATEGORY_HELP,
7658 7670 norepo=True,
7659 7671 intents={INTENT_READONLY},
7660 7672 )
7661 7673 def version_(ui, **opts):
7662 7674 """output version and copyright information
7663 7675
7664 7676 .. container:: verbose
7665 7677
7666 7678 Template:
7667 7679
7668 7680 The following keywords are supported. See also :hg:`help templates`.
7669 7681
7670 7682 :extensions: List of extensions.
7671 7683 :ver: String. Version number.
7672 7684
7673 7685 And each entry of ``{extensions}`` provides the following sub-keywords
7674 7686 in addition to ``{ver}``.
7675 7687
7676 7688 :bundled: Boolean. True if included in the release.
7677 7689 :name: String. Extension name.
7678 7690 """
7679 7691 opts = pycompat.byteskwargs(opts)
7680 7692 if ui.verbose:
7681 7693 ui.pager(b'version')
7682 7694 fm = ui.formatter(b"version", opts)
7683 7695 fm.startitem()
7684 7696 fm.write(
7685 7697 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
7686 7698 )
7687 7699 license = _(
7688 7700 b"(see https://mercurial-scm.org for more information)\n"
7689 7701 b"\nCopyright (C) 2005-2020 Matt Mackall and others\n"
7690 7702 b"This is free software; see the source for copying conditions. "
7691 7703 b"There is NO\nwarranty; "
7692 7704 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7693 7705 )
7694 7706 if not ui.quiet:
7695 7707 fm.plain(license)
7696 7708
7697 7709 if ui.verbose:
7698 7710 fm.plain(_(b"\nEnabled extensions:\n\n"))
7699 7711 # format names and versions into columns
7700 7712 names = []
7701 7713 vers = []
7702 7714 isinternals = []
7703 7715 for name, module in sorted(extensions.extensions()):
7704 7716 names.append(name)
7705 7717 vers.append(extensions.moduleversion(module) or None)
7706 7718 isinternals.append(extensions.ismoduleinternal(module))
7707 7719 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
7708 7720 if names:
7709 7721 namefmt = b" %%-%ds " % max(len(n) for n in names)
7710 7722 places = [_(b"external"), _(b"internal")]
7711 7723 for n, v, p in zip(names, vers, isinternals):
7712 7724 fn.startitem()
7713 7725 fn.condwrite(ui.verbose, b"name", namefmt, n)
7714 7726 if ui.verbose:
7715 7727 fn.plain(b"%s " % places[p])
7716 7728 fn.data(bundled=p)
7717 7729 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
7718 7730 if ui.verbose:
7719 7731 fn.plain(b"\n")
7720 7732 fn.end()
7721 7733 fm.end()
7722 7734
7723 7735
7724 7736 def loadcmdtable(ui, name, cmdtable):
7725 7737 """Load command functions from specified cmdtable"""
7726 7738 overrides = [cmd for cmd in cmdtable if cmd in table]
7727 7739 if overrides:
7728 7740 ui.warn(
7729 7741 _(b"extension '%s' overrides commands: %s\n")
7730 7742 % (name, b" ".join(overrides))
7731 7743 )
7732 7744 table.update(cmdtable)
@@ -1,40 +1,43 b''
1 1 == New Features ==
2 2
3 3 * There is a new config section for templates used by hg commands. It
4 4 is called `[command-templates]`. Some existing config options have
5 5 been deprecated in favor of config options in the new
6 6 section. These are: `ui.logtemplate` to `command-templates.log`,
7 7 `ui.graphnodetemplate` to `command-templates.graphnode`,
8 8 `ui.mergemarkertemplate` to `command-templates.mergemarker`,
9 9 `ui.pre-merge-tool-output-template` to
10 10 `command-templates.pre-merge-tool-output`.
11 11
12 12 * There is a new set of config options for the template used for the
13 13 one-line commit summary displayed by various commands, such as `hg
14 14 rebase`. The main one is `command-templates.oneline-summary`. That
15 15 can be overridden per command with
16 16 `command-templates.oneline-summary.<command>`, where `<command>`
17 17 can be e.g. `rebase`. As part of this effort, the default format
18 18 from `hg rebase` was reorganized a bit.
19 19
20 20 * `hg strip`, from the strip extension, is now a core command, `hg
21 21 debugstrip`. The extension remains for compatibility.
22 22
23 * `hg diff` now supports `--from <rev>` and `--to <rev>` arguments as
24 clearer alternatives to `-r <revs>`.
25
23 26 * The memory footprint per changeset during pull/unbundle
24 27 operations has been further reduced.
25 28
26 29 == New Experimental Features ==
27 30
28 31
29 32
30 33 == Bug Fixes ==
31 34
32 35
33 36
34 37 == Backwards Compatibility Changes ==
35 38
36 39
37 40
38 41 == Internal API Changes ==
39 42
40 43
@@ -1,439 +1,439 b''
1 1 Show all commands except debug commands
2 2 $ hg debugcomplete
3 3 abort
4 4 add
5 5 addremove
6 6 annotate
7 7 archive
8 8 backout
9 9 bisect
10 10 bookmarks
11 11 branch
12 12 branches
13 13 bundle
14 14 cat
15 15 clone
16 16 commit
17 17 config
18 18 continue
19 19 copy
20 20 diff
21 21 export
22 22 files
23 23 forget
24 24 graft
25 25 grep
26 26 heads
27 27 help
28 28 identify
29 29 import
30 30 incoming
31 31 init
32 32 locate
33 33 log
34 34 manifest
35 35 merge
36 36 outgoing
37 37 parents
38 38 paths
39 39 phase
40 40 pull
41 41 push
42 42 recover
43 43 remove
44 44 rename
45 45 resolve
46 46 revert
47 47 rollback
48 48 root
49 49 serve
50 50 shelve
51 51 status
52 52 summary
53 53 tag
54 54 tags
55 55 tip
56 56 unbundle
57 57 unshelve
58 58 update
59 59 verify
60 60 version
61 61
62 62 Show all commands that start with "a"
63 63 $ hg debugcomplete a
64 64 abort
65 65 add
66 66 addremove
67 67 annotate
68 68 archive
69 69
70 70 Do not show debug commands if there are other candidates
71 71 $ hg debugcomplete d
72 72 diff
73 73
74 74 Show debug commands if there are no other candidates
75 75 $ hg debugcomplete debug
76 76 debugancestor
77 77 debugantivirusrunning
78 78 debugapplystreamclonebundle
79 79 debugbackupbundle
80 80 debugbuilddag
81 81 debugbundle
82 82 debugcapabilities
83 83 debugchangedfiles
84 84 debugcheckstate
85 85 debugcolor
86 86 debugcommands
87 87 debugcomplete
88 88 debugconfig
89 89 debugcreatestreamclonebundle
90 90 debugdag
91 91 debugdata
92 92 debugdate
93 93 debugdeltachain
94 94 debugdirstate
95 95 debugdiscovery
96 96 debugdownload
97 97 debugextensions
98 98 debugfileset
99 99 debugformat
100 100 debugfsinfo
101 101 debuggetbundle
102 102 debugignore
103 103 debugindex
104 104 debugindexdot
105 105 debugindexstats
106 106 debuginstall
107 107 debugknown
108 108 debuglabelcomplete
109 109 debuglocks
110 110 debugmanifestfulltextcache
111 111 debugmergestate
112 112 debugnamecomplete
113 113 debugnodemap
114 114 debugobsolete
115 115 debugp1copies
116 116 debugp2copies
117 117 debugpathcomplete
118 118 debugpathcopies
119 119 debugpeer
120 120 debugpickmergetool
121 121 debugpushkey
122 122 debugpvec
123 123 debugrebuilddirstate
124 124 debugrebuildfncache
125 125 debugrename
126 126 debugrequires
127 127 debugrevlog
128 128 debugrevlogindex
129 129 debugrevspec
130 130 debugserve
131 131 debugsetparents
132 132 debugsidedata
133 133 debugssl
134 134 debugstrip
135 135 debugsub
136 136 debugsuccessorssets
137 137 debugtagscache
138 138 debugtemplate
139 139 debuguigetpass
140 140 debuguiprompt
141 141 debugupdatecaches
142 142 debugupgraderepo
143 143 debugwalk
144 144 debugwhyunstable
145 145 debugwireargs
146 146 debugwireproto
147 147
148 148 Do not show the alias of a debug command if there are other candidates
149 149 (this should hide rawcommit)
150 150 $ hg debugcomplete r
151 151 recover
152 152 remove
153 153 rename
154 154 resolve
155 155 revert
156 156 rollback
157 157 root
158 158 Show the alias of a debug command if there are no other candidates
159 159 $ hg debugcomplete rawc
160 160
161 161
162 162 Show the global options
163 163 $ hg debugcomplete --options | sort
164 164 --color
165 165 --config
166 166 --cwd
167 167 --debug
168 168 --debugger
169 169 --encoding
170 170 --encodingmode
171 171 --help
172 172 --hidden
173 173 --noninteractive
174 174 --pager
175 175 --profile
176 176 --quiet
177 177 --repository
178 178 --time
179 179 --traceback
180 180 --verbose
181 181 --version
182 182 -R
183 183 -h
184 184 -q
185 185 -v
186 186 -y
187 187
188 188 Show the options for the "serve" command
189 189 $ hg debugcomplete --options serve | sort
190 190 --accesslog
191 191 --address
192 192 --certificate
193 193 --cmdserver
194 194 --color
195 195 --config
196 196 --cwd
197 197 --daemon
198 198 --daemon-postexec
199 199 --debug
200 200 --debugger
201 201 --encoding
202 202 --encodingmode
203 203 --errorlog
204 204 --help
205 205 --hidden
206 206 --ipv6
207 207 --name
208 208 --noninteractive
209 209 --pager
210 210 --pid-file
211 211 --port
212 212 --prefix
213 213 --print-url
214 214 --profile
215 215 --quiet
216 216 --repository
217 217 --stdio
218 218 --style
219 219 --subrepos
220 220 --templates
221 221 --time
222 222 --traceback
223 223 --verbose
224 224 --version
225 225 --web-conf
226 226 -6
227 227 -A
228 228 -E
229 229 -R
230 230 -S
231 231 -a
232 232 -d
233 233 -h
234 234 -n
235 235 -p
236 236 -q
237 237 -t
238 238 -v
239 239 -y
240 240
241 241 Show an error if we use --options with an ambiguous abbreviation
242 242 $ hg debugcomplete --options s
243 243 hg: command 's' is ambiguous:
244 244 serve shelve showconfig status summary
245 245 [255]
246 246
247 247 Show all commands + options
248 248 $ hg debugcommands
249 249 abort: dry-run
250 250 add: include, exclude, subrepos, dry-run
251 251 addremove: similarity, subrepos, include, exclude, dry-run
252 252 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
253 253 archive: no-decode, prefix, rev, type, subrepos, include, exclude
254 254 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
255 255 bisect: reset, good, bad, skip, extend, command, noupdate
256 256 bookmarks: force, rev, delete, rename, inactive, list, template
257 257 branch: force, clean, rev
258 258 branches: active, closed, rev, template
259 259 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
260 260 cat: output, rev, decode, include, exclude, template
261 261 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
262 262 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
263 263 config: untrusted, edit, local, shared, non-shared, global, template
264 264 continue: dry-run
265 265 copy: forget, after, at-rev, force, include, exclude, dry-run
266 266 debugancestor:
267 267 debugantivirusrunning:
268 268 debugapplystreamclonebundle:
269 269 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
270 270 debugbuilddag: mergeable-file, overwritten-file, new-file
271 271 debugbundle: all, part-type, spec
272 272 debugcapabilities:
273 273 debugchangedfiles:
274 274 debugcheckstate:
275 275 debugcolor: style
276 276 debugcommands:
277 277 debugcomplete: options
278 278 debugcreatestreamclonebundle:
279 279 debugdag: tags, branches, dots, spaces
280 280 debugdata: changelog, manifest, dir
281 281 debugdate: extended
282 282 debugdeltachain: changelog, manifest, dir, template
283 283 debugdirstate: nodates, dates, datesort
284 284 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
285 285 debugdownload: output
286 286 debugextensions: template
287 287 debugfileset: rev, all-files, show-matcher, show-stage
288 288 debugformat: template
289 289 debugfsinfo:
290 290 debuggetbundle: head, common, type
291 291 debugignore:
292 292 debugindex: changelog, manifest, dir, template
293 293 debugindexdot: changelog, manifest, dir
294 294 debugindexstats:
295 295 debuginstall: template
296 296 debugknown:
297 297 debuglabelcomplete:
298 298 debuglocks: force-lock, force-wlock, set-lock, set-wlock
299 299 debugmanifestfulltextcache: clear, add
300 300 debugmergestate: style, template
301 301 debugnamecomplete:
302 302 debugnodemap: dump-new, dump-disk, check, metadata
303 303 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
304 304 debugp1copies: rev
305 305 debugp2copies: rev
306 306 debugpathcomplete: full, normal, added, removed
307 307 debugpathcopies: include, exclude
308 308 debugpeer:
309 309 debugpickmergetool: rev, changedelete, include, exclude, tool
310 310 debugpushkey:
311 311 debugpvec:
312 312 debugrebuilddirstate: rev, minimal
313 313 debugrebuildfncache:
314 314 debugrename: rev
315 315 debugrequires:
316 316 debugrevlog: changelog, manifest, dir, dump
317 317 debugrevlogindex: changelog, manifest, dir, format
318 318 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
319 319 debugserve: sshstdio, logiofd, logiofile
320 320 debugsetparents:
321 321 debugsidedata: changelog, manifest, dir
322 322 debugssl:
323 323 debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft
324 324 debugsub: rev
325 325 debugsuccessorssets: closest
326 326 debugtagscache:
327 327 debugtemplate: rev, define
328 328 debuguigetpass: prompt
329 329 debuguiprompt: prompt
330 330 debugupdatecaches:
331 331 debugupgraderepo: optimize, run, backup, changelog, manifest, filelogs
332 332 debugwalk: include, exclude
333 333 debugwhyunstable:
334 334 debugwireargs: three, four, five, ssh, remotecmd, insecure
335 335 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
336 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
336 diff: rev, from, to, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
337 337 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
338 338 files: rev, print0, include, exclude, template, subrepos
339 339 forget: interactive, include, exclude, dry-run
340 340 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
341 341 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
342 342 heads: rev, topo, active, closed, style, template
343 343 help: extension, command, keyword, system
344 344 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
345 345 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
346 346 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
347 347 init: ssh, remotecmd, insecure
348 348 locate: rev, print0, fullpath, include, exclude
349 349 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, bookmark, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
350 350 manifest: rev, all, template
351 351 merge: force, rev, preview, abort, tool
352 352 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
353 353 parents: rev, style, template
354 354 paths: template
355 355 phase: public, draft, secret, force, rev
356 356 pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure
357 357 push: force, rev, bookmark, all-bookmarks, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
358 358 recover: verify
359 359 remove: after, force, subrepos, include, exclude, dry-run
360 360 rename: after, at-rev, force, include, exclude, dry-run
361 361 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
362 362 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
363 363 rollback: dry-run, force
364 364 root: template
365 365 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
366 366 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
367 367 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
368 368 summary: remote
369 369 tag: force, local, rev, remove, edit, message, date, user
370 370 tags: template
371 371 tip: patch, git, style, template
372 372 unbundle: update
373 373 unshelve: abort, continue, interactive, keep, name, tool, date
374 374 update: clean, check, merge, date, rev, tool
375 375 verify: full
376 376 version: template
377 377
378 378 $ hg init a
379 379 $ cd a
380 380 $ echo fee > fee
381 381 $ hg ci -q -Amfee
382 382 $ hg tag fee
383 383 $ mkdir fie
384 384 $ echo dead > fie/dead
385 385 $ echo live > fie/live
386 386 $ hg bookmark fo
387 387 $ hg branch -q fie
388 388 $ hg ci -q -Amfie
389 389 $ echo fo > fo
390 390 $ hg branch -qf default
391 391 $ hg ci -q -Amfo
392 392 $ echo Fum > Fum
393 393 $ hg ci -q -AmFum
394 394 $ hg bookmark Fum
395 395
396 396 Test debugpathcomplete
397 397
398 398 $ hg debugpathcomplete f
399 399 fee
400 400 fie
401 401 fo
402 402 $ hg debugpathcomplete -f f
403 403 fee
404 404 fie/dead
405 405 fie/live
406 406 fo
407 407
408 408 $ hg rm Fum
409 409 $ hg debugpathcomplete -r F
410 410 Fum
411 411
412 412 Test debugnamecomplete
413 413
414 414 $ hg debugnamecomplete
415 415 Fum
416 416 default
417 417 fee
418 418 fie
419 419 fo
420 420 tip
421 421 $ hg debugnamecomplete f
422 422 fee
423 423 fie
424 424 fo
425 425
426 426 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
427 427 used for completions in some shells.
428 428
429 429 $ hg debuglabelcomplete
430 430 Fum
431 431 default
432 432 fee
433 433 fie
434 434 fo
435 435 tip
436 436 $ hg debuglabelcomplete f
437 437 fee
438 438 fie
439 439 fo
@@ -1,144 +1,197 b''
1 Testing diff --change
1 Testing diff --change, --from, --to
2 2
3 3 $ hg init a
4 4 $ cd a
5 5
6 6 $ echo "first" > file.txt
7 7 $ hg add file.txt
8 8 $ hg commit -m 'first commit' # 0
9 9
10 10 $ echo "second" > file.txt
11 11 $ hg commit -m 'second commit' # 1
12 12
13 13 $ echo "third" > file.txt
14 14 $ hg commit -m 'third commit' # 2
15 15
16 16 $ hg diff --nodates --change 1
17 17 diff -r 4bb65dda5db4 -r e9b286083166 file.txt
18 18 --- a/file.txt
19 19 +++ b/file.txt
20 20 @@ -1,1 +1,1 @@
21 21 -first
22 22 +second
23 23
24 24 $ hg diff --change e9b286083166
25 25 diff -r 4bb65dda5db4 -r e9b286083166 file.txt
26 26 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
27 27 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
28 28 @@ -1,1 +1,1 @@
29 29 -first
30 30 +second
31 31
32 Test --from and --to
33
34 $ hg diff --from . --rev .
35 abort: cannot specify both --from and --rev
36 [10]
37 $ hg diff --to . --rev .
38 abort: cannot specify both --to and --rev
39 [10]
40 $ hg diff --from . --change .
41 abort: cannot specify both --from and --change
42 [10]
43 $ hg diff --to . --change .
44 abort: cannot specify both --to and --change
45 [10]
46 $ echo dirty > file.txt
47 $ hg diff --from .
48 diff -r bf5ff72eb7e0 file.txt
49 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
50 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
51 @@ -1,1 +1,1 @@
52 -third
53 +dirty
54 $ hg diff --from . --reverse
55 diff -r bf5ff72eb7e0 file.txt
56 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
57 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
58 @@ -1,1 +1,1 @@
59 -dirty
60 +third
61 $ hg diff --to .
62 diff -r bf5ff72eb7e0 file.txt
63 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
64 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
65 @@ -1,1 +1,1 @@
66 -dirty
67 +third
68 $ hg diff --from 0 --to 2
69 diff -r 4bb65dda5db4 -r bf5ff72eb7e0 file.txt
70 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
71 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
72 @@ -1,1 +1,1 @@
73 -first
74 +third
75 $ hg diff --from 2 --to 0
76 diff -r bf5ff72eb7e0 -r 4bb65dda5db4 file.txt
77 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
78 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
79 @@ -1,1 +1,1 @@
80 -third
81 +first
82 $ hg co -C .
83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84
32 85 $ cd ..
33 86
34 87 Test dumb revspecs: top-level "x:y", "x:", ":y" and ":" ranges should be handled
35 88 as pairs even if x == y, but not for "f(x:y)" nor "x::y" (issue3474, issue4774)
36 89
37 90 $ hg clone -q a dumbspec
38 91 $ cd dumbspec
39 92 $ echo "wdir" > file.txt
40 93
41 94 $ hg diff -r 2:2
42 95 $ hg diff -r 2:.
43 96 $ hg diff -r 2:
44 97 $ hg diff -r :0
45 98 $ hg diff -r '2:first(2:2)'
46 99 $ hg diff -r 'first(2:2)' --nodates
47 100 diff -r bf5ff72eb7e0 file.txt
48 101 --- a/file.txt
49 102 +++ b/file.txt
50 103 @@ -1,1 +1,1 @@
51 104 -third
52 105 +wdir
53 106 $ hg diff -r '(2:2)' --nodates
54 107 diff -r bf5ff72eb7e0 file.txt
55 108 --- a/file.txt
56 109 +++ b/file.txt
57 110 @@ -1,1 +1,1 @@
58 111 -third
59 112 +wdir
60 113 $ hg diff -r 2::2 --nodates
61 114 diff -r bf5ff72eb7e0 file.txt
62 115 --- a/file.txt
63 116 +++ b/file.txt
64 117 @@ -1,1 +1,1 @@
65 118 -third
66 119 +wdir
67 120 $ hg diff -r "2 and 1"
68 121 abort: empty revision range
69 122 [255]
70 123
71 124 $ cd ..
72 125
73 126 $ hg clone -qr0 a dumbspec-rev0
74 127 $ cd dumbspec-rev0
75 128 $ echo "wdir" > file.txt
76 129
77 130 $ hg diff -r :
78 131 $ hg diff -r 'first(:)' --nodates
79 132 diff -r 4bb65dda5db4 file.txt
80 133 --- a/file.txt
81 134 +++ b/file.txt
82 135 @@ -1,1 +1,1 @@
83 136 -first
84 137 +wdir
85 138
86 139 $ cd ..
87 140
88 141 Testing diff --change when merge:
89 142
90 143 $ cd a
91 144
92 145 $ for i in 1 2 3 4 5 6 7 8 9 10; do
93 146 > echo $i >> file.txt
94 147 > done
95 148 $ hg commit -m "lots of text" # 3
96 149
97 150 $ sed -e 's,^2$,x,' file.txt > file.txt.tmp
98 151 $ mv file.txt.tmp file.txt
99 152 $ hg commit -m "change 2 to x" # 4
100 153
101 154 $ hg up -r 3
102 155 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 156 $ sed -e 's,^8$,y,' file.txt > file.txt.tmp
104 157 $ mv file.txt.tmp file.txt
105 158 $ hg commit -m "change 8 to y"
106 159 created new head
107 160
108 161 $ hg up -C -r 4
109 162 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 163 $ hg merge -r 5
111 164 merging file.txt
112 165 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
113 166 (branch merge, don't forget to commit)
114 167 $ hg commit -m "merge 8 to y" # 6
115 168
116 169 $ hg diff --change 5
117 170 diff -r ae119d680c82 -r 9085c5c02e52 file.txt
118 171 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
119 172 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
120 173 @@ -6,6 +6,6 @@
121 174 5
122 175 6
123 176 7
124 177 -8
125 178 +y
126 179 9
127 180 10
128 181
129 182 must be similar to 'hg diff --change 5':
130 183
131 184 $ hg diff -c 6
132 185 diff -r 273b50f17c6d -r 979ca961fd2e file.txt
133 186 --- a/file.txt Thu Jan 01 00:00:00 1970 +0000
134 187 +++ b/file.txt Thu Jan 01 00:00:00 1970 +0000
135 188 @@ -6,6 +6,6 @@
136 189 5
137 190 6
138 191 7
139 192 -8
140 193 +y
141 194 9
142 195 10
143 196
144 197 $ cd ..
@@ -1,3919 +1,3921 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 Extra extensions will be printed in help output in a non-reliable order since
48 48 the extension is unknown.
49 49 #if no-extraextensions
50 50
51 51 $ hg help
52 52 Mercurial Distributed SCM
53 53
54 54 list of commands:
55 55
56 56 Repository creation:
57 57
58 58 clone make a copy of an existing repository
59 59 init create a new repository in the given directory
60 60
61 61 Remote repository management:
62 62
63 63 incoming show new changesets found in source
64 64 outgoing show changesets not found in the destination
65 65 paths show aliases for remote repositories
66 66 pull pull changes from the specified source
67 67 push push changes to the specified destination
68 68 serve start stand-alone webserver
69 69
70 70 Change creation:
71 71
72 72 commit commit the specified files or all outstanding changes
73 73
74 74 Change manipulation:
75 75
76 76 backout reverse effect of earlier changeset
77 77 graft copy changes from other branches onto the current branch
78 78 merge merge another revision into working directory
79 79
80 80 Change organization:
81 81
82 82 bookmarks create a new bookmark or list existing bookmarks
83 83 branch set or show the current branch name
84 84 branches list repository named branches
85 85 phase set or show the current phase name
86 86 tag add one or more tags for the current or given revision
87 87 tags list repository tags
88 88
89 89 File content management:
90 90
91 91 annotate show changeset information by line for each file
92 92 cat output the current or given revision of files
93 93 copy mark files as copied for the next commit
94 94 diff diff repository (or selected files)
95 95 grep search for a pattern in specified files
96 96
97 97 Change navigation:
98 98
99 99 bisect subdivision search of changesets
100 100 heads show branch heads
101 101 identify identify the working directory or specified revision
102 102 log show revision history of entire repository or files
103 103
104 104 Working directory management:
105 105
106 106 add add the specified files on the next commit
107 107 addremove add all new files, delete all missing files
108 108 files list tracked files
109 109 forget forget the specified files on the next commit
110 110 remove remove the specified files on the next commit
111 111 rename rename files; equivalent of copy + remove
112 112 resolve redo merges or set/view the merge status of files
113 113 revert restore files to their checkout state
114 114 root print the root (top) of the current working directory
115 115 shelve save and set aside changes from the working directory
116 116 status show changed files in the working directory
117 117 summary summarize working directory state
118 118 unshelve restore a shelved change to the working directory
119 119 update update working directory (or switch revisions)
120 120
121 121 Change import/export:
122 122
123 123 archive create an unversioned archive of a repository revision
124 124 bundle create a bundle file
125 125 export dump the header and diffs for one or more changesets
126 126 import import an ordered set of patches
127 127 unbundle apply one or more bundle files
128 128
129 129 Repository maintenance:
130 130
131 131 manifest output the current or given revision of the project manifest
132 132 recover roll back an interrupted transaction
133 133 verify verify the integrity of the repository
134 134
135 135 Help:
136 136
137 137 config show combined config settings from all hgrc files
138 138 help show help for a given topic or a help overview
139 139 version output version and copyright information
140 140
141 141 additional help topics:
142 142
143 143 Mercurial identifiers:
144 144
145 145 filesets Specifying File Sets
146 146 hgignore Syntax for Mercurial Ignore Files
147 147 patterns File Name Patterns
148 148 revisions Specifying Revisions
149 149 urls URL Paths
150 150
151 151 Mercurial output:
152 152
153 153 color Colorizing Outputs
154 154 dates Date Formats
155 155 diffs Diff Formats
156 156 templating Template Usage
157 157
158 158 Mercurial configuration:
159 159
160 160 config Configuration Files
161 161 environment Environment Variables
162 162 extensions Using Additional Features
163 163 flags Command-line flags
164 164 hgweb Configuring hgweb
165 165 merge-tools Merge Tools
166 166 pager Pager Support
167 167
168 168 Concepts:
169 169
170 170 bundlespec Bundle File Formats
171 171 glossary Glossary
172 172 phases Working with Phases
173 173 subrepos Subrepositories
174 174
175 175 Miscellaneous:
176 176
177 177 deprecated Deprecated Features
178 178 internals Technical implementation topics
179 179 scripting Using Mercurial from scripts and automation
180 180
181 181 (use 'hg help -v' to show built-in aliases and global options)
182 182
183 183 $ hg -q help
184 184 Repository creation:
185 185
186 186 clone make a copy of an existing repository
187 187 init create a new repository in the given directory
188 188
189 189 Remote repository management:
190 190
191 191 incoming show new changesets found in source
192 192 outgoing show changesets not found in the destination
193 193 paths show aliases for remote repositories
194 194 pull pull changes from the specified source
195 195 push push changes to the specified destination
196 196 serve start stand-alone webserver
197 197
198 198 Change creation:
199 199
200 200 commit commit the specified files or all outstanding changes
201 201
202 202 Change manipulation:
203 203
204 204 backout reverse effect of earlier changeset
205 205 graft copy changes from other branches onto the current branch
206 206 merge merge another revision into working directory
207 207
208 208 Change organization:
209 209
210 210 bookmarks create a new bookmark or list existing bookmarks
211 211 branch set or show the current branch name
212 212 branches list repository named branches
213 213 phase set or show the current phase name
214 214 tag add one or more tags for the current or given revision
215 215 tags list repository tags
216 216
217 217 File content management:
218 218
219 219 annotate show changeset information by line for each file
220 220 cat output the current or given revision of files
221 221 copy mark files as copied for the next commit
222 222 diff diff repository (or selected files)
223 223 grep search for a pattern in specified files
224 224
225 225 Change navigation:
226 226
227 227 bisect subdivision search of changesets
228 228 heads show branch heads
229 229 identify identify the working directory or specified revision
230 230 log show revision history of entire repository or files
231 231
232 232 Working directory management:
233 233
234 234 add add the specified files on the next commit
235 235 addremove add all new files, delete all missing files
236 236 files list tracked files
237 237 forget forget the specified files on the next commit
238 238 remove remove the specified files on the next commit
239 239 rename rename files; equivalent of copy + remove
240 240 resolve redo merges or set/view the merge status of files
241 241 revert restore files to their checkout state
242 242 root print the root (top) of the current working directory
243 243 shelve save and set aside changes from the working directory
244 244 status show changed files in the working directory
245 245 summary summarize working directory state
246 246 unshelve restore a shelved change to the working directory
247 247 update update working directory (or switch revisions)
248 248
249 249 Change import/export:
250 250
251 251 archive create an unversioned archive of a repository revision
252 252 bundle create a bundle file
253 253 export dump the header and diffs for one or more changesets
254 254 import import an ordered set of patches
255 255 unbundle apply one or more bundle files
256 256
257 257 Repository maintenance:
258 258
259 259 manifest output the current or given revision of the project manifest
260 260 recover roll back an interrupted transaction
261 261 verify verify the integrity of the repository
262 262
263 263 Help:
264 264
265 265 config show combined config settings from all hgrc files
266 266 help show help for a given topic or a help overview
267 267 version output version and copyright information
268 268
269 269 additional help topics:
270 270
271 271 Mercurial identifiers:
272 272
273 273 filesets Specifying File Sets
274 274 hgignore Syntax for Mercurial Ignore Files
275 275 patterns File Name Patterns
276 276 revisions Specifying Revisions
277 277 urls URL Paths
278 278
279 279 Mercurial output:
280 280
281 281 color Colorizing Outputs
282 282 dates Date Formats
283 283 diffs Diff Formats
284 284 templating Template Usage
285 285
286 286 Mercurial configuration:
287 287
288 288 config Configuration Files
289 289 environment Environment Variables
290 290 extensions Using Additional Features
291 291 flags Command-line flags
292 292 hgweb Configuring hgweb
293 293 merge-tools Merge Tools
294 294 pager Pager Support
295 295
296 296 Concepts:
297 297
298 298 bundlespec Bundle File Formats
299 299 glossary Glossary
300 300 phases Working with Phases
301 301 subrepos Subrepositories
302 302
303 303 Miscellaneous:
304 304
305 305 deprecated Deprecated Features
306 306 internals Technical implementation topics
307 307 scripting Using Mercurial from scripts and automation
308 308
309 309 Test extension help:
310 310 $ hg help extensions --config extensions.rebase= --config extensions.children=
311 311 Using Additional Features
312 312 """""""""""""""""""""""""
313 313
314 314 Mercurial has the ability to add new features through the use of
315 315 extensions. Extensions may add new commands, add options to existing
316 316 commands, change the default behavior of commands, or implement hooks.
317 317
318 318 To enable the "foo" extension, either shipped with Mercurial or in the
319 319 Python search path, create an entry for it in your configuration file,
320 320 like this:
321 321
322 322 [extensions]
323 323 foo =
324 324
325 325 You may also specify the full path to an extension:
326 326
327 327 [extensions]
328 328 myfeature = ~/.hgext/myfeature.py
329 329
330 330 See 'hg help config' for more information on configuration files.
331 331
332 332 Extensions are not loaded by default for a variety of reasons: they can
333 333 increase startup overhead; they may be meant for advanced usage only; they
334 334 may provide potentially dangerous abilities (such as letting you destroy
335 335 or modify history); they might not be ready for prime time; or they may
336 336 alter some usual behaviors of stock Mercurial. It is thus up to the user
337 337 to activate extensions as needed.
338 338
339 339 To explicitly disable an extension enabled in a configuration file of
340 340 broader scope, prepend its path with !:
341 341
342 342 [extensions]
343 343 # disabling extension bar residing in /path/to/extension/bar.py
344 344 bar = !/path/to/extension/bar.py
345 345 # ditto, but no path was supplied for extension baz
346 346 baz = !
347 347
348 348 enabled extensions:
349 349
350 350 children command to display child changesets (DEPRECATED)
351 351 rebase command to move sets of revisions to a different ancestor
352 352
353 353 disabled extensions:
354 354
355 355 acl hooks for controlling repository access
356 356 blackbox log repository events to a blackbox for debugging
357 357 bugzilla hooks for integrating with the Bugzilla bug tracker
358 358 censor erase file content at a given revision
359 359 churn command to display statistics about repository history
360 360 clonebundles advertise pre-generated bundles to seed clones
361 361 closehead close arbitrary heads without checking them out first
362 362 convert import revisions from foreign VCS repositories into
363 363 Mercurial
364 364 eol automatically manage newlines in repository files
365 365 extdiff command to allow external programs to compare revisions
366 366 factotum http authentication with factotum
367 367 fastexport export repositories as git fast-import stream
368 368 githelp try mapping git commands to Mercurial commands
369 369 gpg commands to sign and verify changesets
370 370 hgk browse the repository in a graphical way
371 371 highlight syntax highlighting for hgweb (requires Pygments)
372 372 histedit interactive history editing
373 373 keyword expand keywords in tracked files
374 374 largefiles track large binary files
375 375 mq manage a stack of patches
376 376 notify hooks for sending email push notifications
377 377 patchbomb command to send changesets as (a series of) patch emails
378 378 purge command to delete untracked files from the working
379 379 directory
380 380 relink recreates hardlinks between repository clones
381 381 schemes extend schemes with shortcuts to repository swarms
382 382 share share a common history between several working directories
383 383 transplant command to transplant changesets from another branch
384 384 win32mbcs allow the use of MBCS paths with problematic encodings
385 385 zeroconf discover and advertise repositories on the local network
386 386
387 387 #endif
388 388
389 389 Verify that deprecated extensions are included if --verbose:
390 390
391 391 $ hg -v help extensions | grep children
392 392 children command to display child changesets (DEPRECATED)
393 393
394 394 Verify that extension keywords appear in help templates
395 395
396 396 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
397 397
398 398 Test short command list with verbose option
399 399
400 400 $ hg -v help shortlist
401 401 Mercurial Distributed SCM
402 402
403 403 basic commands:
404 404
405 405 abort abort an unfinished operation (EXPERIMENTAL)
406 406 add add the specified files on the next commit
407 407 annotate, blame
408 408 show changeset information by line for each file
409 409 clone make a copy of an existing repository
410 410 commit, ci commit the specified files or all outstanding changes
411 411 continue resumes an interrupted operation (EXPERIMENTAL)
412 412 diff diff repository (or selected files)
413 413 export dump the header and diffs for one or more changesets
414 414 forget forget the specified files on the next commit
415 415 init create a new repository in the given directory
416 416 log, history show revision history of entire repository or files
417 417 merge merge another revision into working directory
418 418 pull pull changes from the specified source
419 419 push push changes to the specified destination
420 420 remove, rm remove the specified files on the next commit
421 421 serve start stand-alone webserver
422 422 status, st show changed files in the working directory
423 423 summary, sum summarize working directory state
424 424 update, up, checkout, co
425 425 update working directory (or switch revisions)
426 426
427 427 global options ([+] can be repeated):
428 428
429 429 -R --repository REPO repository root directory or name of overlay bundle
430 430 file
431 431 --cwd DIR change working directory
432 432 -y --noninteractive do not prompt, automatically pick the first choice for
433 433 all prompts
434 434 -q --quiet suppress output
435 435 -v --verbose enable additional output
436 436 --color TYPE when to colorize (boolean, always, auto, never, or
437 437 debug)
438 438 --config CONFIG [+] set/override config option (use 'section.name=value')
439 439 --debug enable debugging output
440 440 --debugger start debugger
441 441 --encoding ENCODE set the charset encoding (default: ascii)
442 442 --encodingmode MODE set the charset encoding mode (default: strict)
443 443 --traceback always print a traceback on exception
444 444 --time time how long the command takes
445 445 --profile print command execution profile
446 446 --version output version information and exit
447 447 -h --help display help and exit
448 448 --hidden consider hidden changesets
449 449 --pager TYPE when to paginate (boolean, always, auto, or never)
450 450 (default: auto)
451 451
452 452 (use 'hg help' for the full list of commands)
453 453
454 454 $ hg add -h
455 455 hg add [OPTION]... [FILE]...
456 456
457 457 add the specified files on the next commit
458 458
459 459 Schedule files to be version controlled and added to the repository.
460 460
461 461 The files will be added to the repository at the next commit. To undo an
462 462 add before that, see 'hg forget'.
463 463
464 464 If no names are given, add all files to the repository (except files
465 465 matching ".hgignore").
466 466
467 467 Returns 0 if all files are successfully added.
468 468
469 469 options ([+] can be repeated):
470 470
471 471 -I --include PATTERN [+] include names matching the given patterns
472 472 -X --exclude PATTERN [+] exclude names matching the given patterns
473 473 -S --subrepos recurse into subrepositories
474 474 -n --dry-run do not perform actions, just print output
475 475
476 476 (some details hidden, use --verbose to show complete help)
477 477
478 478 Verbose help for add
479 479
480 480 $ hg add -hv
481 481 hg add [OPTION]... [FILE]...
482 482
483 483 add the specified files on the next commit
484 484
485 485 Schedule files to be version controlled and added to the repository.
486 486
487 487 The files will be added to the repository at the next commit. To undo an
488 488 add before that, see 'hg forget'.
489 489
490 490 If no names are given, add all files to the repository (except files
491 491 matching ".hgignore").
492 492
493 493 Examples:
494 494
495 495 - New (unknown) files are added automatically by 'hg add':
496 496
497 497 $ ls
498 498 foo.c
499 499 $ hg status
500 500 ? foo.c
501 501 $ hg add
502 502 adding foo.c
503 503 $ hg status
504 504 A foo.c
505 505
506 506 - Specific files to be added can be specified:
507 507
508 508 $ ls
509 509 bar.c foo.c
510 510 $ hg status
511 511 ? bar.c
512 512 ? foo.c
513 513 $ hg add bar.c
514 514 $ hg status
515 515 A bar.c
516 516 ? foo.c
517 517
518 518 Returns 0 if all files are successfully added.
519 519
520 520 options ([+] can be repeated):
521 521
522 522 -I --include PATTERN [+] include names matching the given patterns
523 523 -X --exclude PATTERN [+] exclude names matching the given patterns
524 524 -S --subrepos recurse into subrepositories
525 525 -n --dry-run do not perform actions, just print output
526 526
527 527 global options ([+] can be repeated):
528 528
529 529 -R --repository REPO repository root directory or name of overlay bundle
530 530 file
531 531 --cwd DIR change working directory
532 532 -y --noninteractive do not prompt, automatically pick the first choice for
533 533 all prompts
534 534 -q --quiet suppress output
535 535 -v --verbose enable additional output
536 536 --color TYPE when to colorize (boolean, always, auto, never, or
537 537 debug)
538 538 --config CONFIG [+] set/override config option (use 'section.name=value')
539 539 --debug enable debugging output
540 540 --debugger start debugger
541 541 --encoding ENCODE set the charset encoding (default: ascii)
542 542 --encodingmode MODE set the charset encoding mode (default: strict)
543 543 --traceback always print a traceback on exception
544 544 --time time how long the command takes
545 545 --profile print command execution profile
546 546 --version output version information and exit
547 547 -h --help display help and exit
548 548 --hidden consider hidden changesets
549 549 --pager TYPE when to paginate (boolean, always, auto, or never)
550 550 (default: auto)
551 551
552 552 Test the textwidth config option
553 553
554 554 $ hg root -h --config ui.textwidth=50
555 555 hg root
556 556
557 557 print the root (top) of the current working
558 558 directory
559 559
560 560 Print the root directory of the current
561 561 repository.
562 562
563 563 Returns 0 on success.
564 564
565 565 options:
566 566
567 567 -T --template TEMPLATE display with template
568 568
569 569 (some details hidden, use --verbose to show
570 570 complete help)
571 571
572 572 Test help option with version option
573 573
574 574 $ hg add -h --version
575 575 Mercurial Distributed SCM (version *) (glob)
576 576 (see https://mercurial-scm.org for more information)
577 577
578 578 Copyright (C) 2005-* Matt Mackall and others (glob)
579 579 This is free software; see the source for copying conditions. There is NO
580 580 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
581 581
582 582 $ hg add --skjdfks
583 583 hg add: option --skjdfks not recognized
584 584 hg add [OPTION]... [FILE]...
585 585
586 586 add the specified files on the next commit
587 587
588 588 options ([+] can be repeated):
589 589
590 590 -I --include PATTERN [+] include names matching the given patterns
591 591 -X --exclude PATTERN [+] exclude names matching the given patterns
592 592 -S --subrepos recurse into subrepositories
593 593 -n --dry-run do not perform actions, just print output
594 594
595 595 (use 'hg add -h' to show more help)
596 596 [255]
597 597
598 598 Test ambiguous command help
599 599
600 600 $ hg help ad
601 601 list of commands:
602 602
603 603 add add the specified files on the next commit
604 604 addremove add all new files, delete all missing files
605 605
606 606 (use 'hg help -v ad' to show built-in aliases and global options)
607 607
608 608 Test command without options
609 609
610 610 $ hg help verify
611 611 hg verify
612 612
613 613 verify the integrity of the repository
614 614
615 615 Verify the integrity of the current repository.
616 616
617 617 This will perform an extensive check of the repository's integrity,
618 618 validating the hashes and checksums of each entry in the changelog,
619 619 manifest, and tracked files, as well as the integrity of their crosslinks
620 620 and indices.
621 621
622 622 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
623 623 information about recovery from corruption of the repository.
624 624
625 625 Returns 0 on success, 1 if errors are encountered.
626 626
627 627 options:
628 628
629 629 (some details hidden, use --verbose to show complete help)
630 630
631 631 $ hg help diff
632 632 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
633 633
634 634 diff repository (or selected files)
635 635
636 636 Show differences between revisions for the specified files.
637 637
638 638 Differences between files are shown using the unified diff format.
639 639
640 640 Note:
641 641 'hg diff' may generate unexpected results for merges, as it will
642 642 default to comparing against the working directory's first parent
643 643 changeset if no revisions are specified.
644 644
645 645 When two revision arguments are given, then changes are shown between
646 646 those revisions. If only one revision is specified then that revision is
647 647 compared to the working directory, and, when no revisions are specified,
648 648 the working directory files are compared to its first parent.
649 649
650 650 Alternatively you can specify -c/--change with a revision to see the
651 651 changes in that changeset relative to its first parent.
652 652
653 653 Without the -a/--text option, diff will avoid generating diffs of files it
654 654 detects as binary. With -a, diff will generate a diff anyway, probably
655 655 with undesirable results.
656 656
657 657 Use the -g/--git option to generate diffs in the git extended diff format.
658 658 For more information, read 'hg help diffs'.
659 659
660 660 Returns 0 on success.
661 661
662 662 options ([+] can be repeated):
663 663
664 664 -r --rev REV [+] revision
665 --from REV revision to diff from
666 --to REV revision to diff to
665 667 -c --change REV change made by revision
666 668 -a --text treat all files as text
667 669 -g --git use git extended diff format
668 670 --binary generate binary diffs in git mode (default)
669 671 --nodates omit dates from diff headers
670 672 --noprefix omit a/ and b/ prefixes from filenames
671 673 -p --show-function show which function each change is in
672 674 --reverse produce a diff that undoes the changes
673 675 -w --ignore-all-space ignore white space when comparing lines
674 676 -b --ignore-space-change ignore changes in the amount of white space
675 677 -B --ignore-blank-lines ignore changes whose lines are all blank
676 678 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
677 679 -U --unified NUM number of lines of context to show
678 680 --stat output diffstat-style summary of changes
679 681 --root DIR produce diffs relative to subdirectory
680 682 -I --include PATTERN [+] include names matching the given patterns
681 683 -X --exclude PATTERN [+] exclude names matching the given patterns
682 684 -S --subrepos recurse into subrepositories
683 685
684 686 (some details hidden, use --verbose to show complete help)
685 687
686 688 $ hg help status
687 689 hg status [OPTION]... [FILE]...
688 690
689 691 aliases: st
690 692
691 693 show changed files in the working directory
692 694
693 695 Show status of files in the repository. If names are given, only files
694 696 that match are shown. Files that are clean or ignored or the source of a
695 697 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
696 698 -C/--copies or -A/--all are given. Unless options described with "show
697 699 only ..." are given, the options -mardu are used.
698 700
699 701 Option -q/--quiet hides untracked (unknown and ignored) files unless
700 702 explicitly requested with -u/--unknown or -i/--ignored.
701 703
702 704 Note:
703 705 'hg status' may appear to disagree with diff if permissions have
704 706 changed or a merge has occurred. The standard diff format does not
705 707 report permission changes and diff only reports changes relative to one
706 708 merge parent.
707 709
708 710 If one revision is given, it is used as the base revision. If two
709 711 revisions are given, the differences between them are shown. The --change
710 712 option can also be used as a shortcut to list the changed files of a
711 713 revision from its first parent.
712 714
713 715 The codes used to show the status of files are:
714 716
715 717 M = modified
716 718 A = added
717 719 R = removed
718 720 C = clean
719 721 ! = missing (deleted by non-hg command, but still tracked)
720 722 ? = not tracked
721 723 I = ignored
722 724 = origin of the previous file (with --copies)
723 725
724 726 Returns 0 on success.
725 727
726 728 options ([+] can be repeated):
727 729
728 730 -A --all show status of all files
729 731 -m --modified show only modified files
730 732 -a --added show only added files
731 733 -r --removed show only removed files
732 734 -d --deleted show only missing files
733 735 -c --clean show only files without changes
734 736 -u --unknown show only unknown (not tracked) files
735 737 -i --ignored show only ignored files
736 738 -n --no-status hide status prefix
737 739 -C --copies show source of copied files
738 740 -0 --print0 end filenames with NUL, for use with xargs
739 741 --rev REV [+] show difference from revision
740 742 --change REV list the changed files of a revision
741 743 -I --include PATTERN [+] include names matching the given patterns
742 744 -X --exclude PATTERN [+] exclude names matching the given patterns
743 745 -S --subrepos recurse into subrepositories
744 746 -T --template TEMPLATE display with template
745 747
746 748 (some details hidden, use --verbose to show complete help)
747 749
748 750 $ hg -q help status
749 751 hg status [OPTION]... [FILE]...
750 752
751 753 show changed files in the working directory
752 754
753 755 $ hg help foo
754 756 abort: no such help topic: foo
755 757 (try 'hg help --keyword foo')
756 758 [255]
757 759
758 760 $ hg skjdfks
759 761 hg: unknown command 'skjdfks'
760 762 (use 'hg help' for a list of commands)
761 763 [255]
762 764
763 765 Typoed command gives suggestion
764 766 $ hg puls
765 767 hg: unknown command 'puls'
766 768 (did you mean one of pull, push?)
767 769 [255]
768 770
769 771 Not enabled extension gets suggested
770 772
771 773 $ hg rebase
772 774 hg: unknown command 'rebase'
773 775 'rebase' is provided by the following extension:
774 776
775 777 rebase command to move sets of revisions to a different ancestor
776 778
777 779 (use 'hg help extensions' for information on enabling extensions)
778 780 [255]
779 781
780 782 Disabled extension gets suggested
781 783 $ hg --config extensions.rebase=! rebase
782 784 hg: unknown command 'rebase'
783 785 'rebase' is provided by the following extension:
784 786
785 787 rebase command to move sets of revisions to a different ancestor
786 788
787 789 (use 'hg help extensions' for information on enabling extensions)
788 790 [255]
789 791
790 792 Checking that help adapts based on the config:
791 793
792 794 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
793 795 -g --[no-]git use git extended diff format (default: on from
794 796 config)
795 797
796 798 Make sure that we don't run afoul of the help system thinking that
797 799 this is a section and erroring out weirdly.
798 800
799 801 $ hg .log
800 802 hg: unknown command '.log'
801 803 (did you mean log?)
802 804 [255]
803 805
804 806 $ hg log.
805 807 hg: unknown command 'log.'
806 808 (did you mean log?)
807 809 [255]
808 810 $ hg pu.lh
809 811 hg: unknown command 'pu.lh'
810 812 (did you mean one of pull, push?)
811 813 [255]
812 814
813 815 $ cat > helpext.py <<EOF
814 816 > import os
815 817 > from mercurial import commands, fancyopts, registrar
816 818 >
817 819 > def func(arg):
818 820 > return '%sfoo' % arg
819 821 > class customopt(fancyopts.customopt):
820 822 > def newstate(self, oldstate, newparam, abort):
821 823 > return '%sbar' % oldstate
822 824 > cmdtable = {}
823 825 > command = registrar.command(cmdtable)
824 826 >
825 827 > @command(b'nohelp',
826 828 > [(b'', b'longdesc', 3, b'x'*67),
827 829 > (b'n', b'', None, b'normal desc'),
828 830 > (b'', b'newline', b'', b'line1\nline2'),
829 831 > (b'', b'default-off', False, b'enable X'),
830 832 > (b'', b'default-on', True, b'enable Y'),
831 833 > (b'', b'callableopt', func, b'adds foo'),
832 834 > (b'', b'customopt', customopt(''), b'adds bar'),
833 835 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
834 836 > b'hg nohelp',
835 837 > norepo=True)
836 838 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
837 839 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
838 840 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
839 841 > def nohelp(ui, *args, **kwargs):
840 842 > pass
841 843 >
842 844 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
843 845 > def hashelp(ui, *args, **kwargs):
844 846 > """Extension command's help"""
845 847 >
846 848 > def uisetup(ui):
847 849 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
848 850 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
849 851 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
850 852 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
851 853 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
852 854 >
853 855 > EOF
854 856 $ echo '[extensions]' >> $HGRCPATH
855 857 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
856 858
857 859 Test for aliases
858 860
859 861 $ hg help | grep hgalias
860 862 hgalias My doc
861 863
862 864 $ hg help hgalias
863 865 hg hgalias [--remote]
864 866
865 867 alias for: hg summary
866 868
867 869 My doc
868 870
869 871 defined by: helpext
870 872
871 873 options:
872 874
873 875 --remote check for push and pull
874 876
875 877 (some details hidden, use --verbose to show complete help)
876 878 $ hg help hgaliasnodoc
877 879 hg hgaliasnodoc [--remote]
878 880
879 881 alias for: hg summary
880 882
881 883 summarize working directory state
882 884
883 885 This generates a brief summary of the working directory state, including
884 886 parents, branch, commit status, phase and available updates.
885 887
886 888 With the --remote option, this will check the default paths for incoming
887 889 and outgoing changes. This can be time-consuming.
888 890
889 891 Returns 0 on success.
890 892
891 893 defined by: helpext
892 894
893 895 options:
894 896
895 897 --remote check for push and pull
896 898
897 899 (some details hidden, use --verbose to show complete help)
898 900
899 901 $ hg help shellalias
900 902 hg shellalias
901 903
902 904 shell alias for: echo hi
903 905
904 906 (no help text available)
905 907
906 908 defined by: helpext
907 909
908 910 (some details hidden, use --verbose to show complete help)
909 911
910 912 Test command with no help text
911 913
912 914 $ hg help nohelp
913 915 hg nohelp
914 916
915 917 (no help text available)
916 918
917 919 options:
918 920
919 921 --longdesc VALUE
920 922 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
921 923 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
922 924 -n -- normal desc
923 925 --newline VALUE line1 line2
924 926 --default-off enable X
925 927 --[no-]default-on enable Y (default: on)
926 928 --callableopt VALUE adds foo
927 929 --customopt VALUE adds bar
928 930 --customopt-withdefault VALUE adds bar (default: foo)
929 931
930 932 (some details hidden, use --verbose to show complete help)
931 933
932 934 Test that default list of commands includes extension commands that have help,
933 935 but not those that don't, except in verbose mode, when a keyword is passed, or
934 936 when help about the extension is requested.
935 937
936 938 #if no-extraextensions
937 939
938 940 $ hg help | grep hashelp
939 941 hashelp Extension command's help
940 942 $ hg help | grep nohelp
941 943 [1]
942 944 $ hg help -v | grep nohelp
943 945 nohelp (no help text available)
944 946
945 947 $ hg help -k nohelp
946 948 Commands:
947 949
948 950 nohelp hg nohelp
949 951
950 952 Extension Commands:
951 953
952 954 nohelp (no help text available)
953 955
954 956 $ hg help helpext
955 957 helpext extension - no help text available
956 958
957 959 list of commands:
958 960
959 961 hashelp Extension command's help
960 962 nohelp (no help text available)
961 963
962 964 (use 'hg help -v helpext' to show built-in aliases and global options)
963 965
964 966 #endif
965 967
966 968 Test list of internal help commands
967 969
968 970 $ hg help debug
969 971 debug commands (internal and unsupported):
970 972
971 973 debugancestor
972 974 find the ancestor revision of two revisions in a given index
973 975 debugantivirusrunning
974 976 attempt to trigger an antivirus scanner to see if one is active
975 977 debugapplystreamclonebundle
976 978 apply a stream clone bundle file
977 979 debugbackupbundle
978 980 lists the changesets available in backup bundles
979 981 debugbuilddag
980 982 builds a repo with a given DAG from scratch in the current
981 983 empty repo
982 984 debugbundle lists the contents of a bundle
983 985 debugcapabilities
984 986 lists the capabilities of a remote peer
985 987 debugchangedfiles
986 988 list the stored files changes for a revision
987 989 debugcheckstate
988 990 validate the correctness of the current dirstate
989 991 debugcolor show available color, effects or style
990 992 debugcommands
991 993 list all available commands and options
992 994 debugcomplete
993 995 returns the completion list associated with the given command
994 996 debugcreatestreamclonebundle
995 997 create a stream clone bundle file
996 998 debugdag format the changelog or an index DAG as a concise textual
997 999 description
998 1000 debugdata dump the contents of a data file revision
999 1001 debugdate parse and display a date
1000 1002 debugdeltachain
1001 1003 dump information about delta chains in a revlog
1002 1004 debugdirstate
1003 1005 show the contents of the current dirstate
1004 1006 debugdiscovery
1005 1007 runs the changeset discovery protocol in isolation
1006 1008 debugdownload
1007 1009 download a resource using Mercurial logic and config
1008 1010 debugextensions
1009 1011 show information about active extensions
1010 1012 debugfileset parse and apply a fileset specification
1011 1013 debugformat display format information about the current repository
1012 1014 debugfsinfo show information detected about current filesystem
1013 1015 debuggetbundle
1014 1016 retrieves a bundle from a repo
1015 1017 debugignore display the combined ignore pattern and information about
1016 1018 ignored files
1017 1019 debugindex dump index data for a storage primitive
1018 1020 debugindexdot
1019 1021 dump an index DAG as a graphviz dot file
1020 1022 debugindexstats
1021 1023 show stats related to the changelog index
1022 1024 debuginstall test Mercurial installation
1023 1025 debugknown test whether node ids are known to a repo
1024 1026 debuglocks show or modify state of locks
1025 1027 debugmanifestfulltextcache
1026 1028 show, clear or amend the contents of the manifest fulltext
1027 1029 cache
1028 1030 debugmergestate
1029 1031 print merge state
1030 1032 debugnamecomplete
1031 1033 complete "names" - tags, open branch names, bookmark names
1032 1034 debugnodemap write and inspect on disk nodemap
1033 1035 debugobsolete
1034 1036 create arbitrary obsolete marker
1035 1037 debugoptADV (no help text available)
1036 1038 debugoptDEP (no help text available)
1037 1039 debugoptEXP (no help text available)
1038 1040 debugp1copies
1039 1041 dump copy information compared to p1
1040 1042 debugp2copies
1041 1043 dump copy information compared to p2
1042 1044 debugpathcomplete
1043 1045 complete part or all of a tracked path
1044 1046 debugpathcopies
1045 1047 show copies between two revisions
1046 1048 debugpeer establish a connection to a peer repository
1047 1049 debugpickmergetool
1048 1050 examine which merge tool is chosen for specified file
1049 1051 debugpushkey access the pushkey key/value protocol
1050 1052 debugpvec (no help text available)
1051 1053 debugrebuilddirstate
1052 1054 rebuild the dirstate as it would look like for the given
1053 1055 revision
1054 1056 debugrebuildfncache
1055 1057 rebuild the fncache file
1056 1058 debugrename dump rename information
1057 1059 debugrequires
1058 1060 print the current repo requirements
1059 1061 debugrevlog show data and statistics about a revlog
1060 1062 debugrevlogindex
1061 1063 dump the contents of a revlog index
1062 1064 debugrevspec parse and apply a revision specification
1063 1065 debugserve run a server with advanced settings
1064 1066 debugsetparents
1065 1067 manually set the parents of the current working directory
1066 1068 debugsidedata
1067 1069 dump the side data for a cl/manifest/file revision
1068 1070 debugssl test a secure connection to a server
1069 1071 debugstrip strip changesets and all their descendants from the repository
1070 1072 debugsub (no help text available)
1071 1073 debugsuccessorssets
1072 1074 show set of successors for revision
1073 1075 debugtagscache
1074 1076 display the contents of .hg/cache/hgtagsfnodes1
1075 1077 debugtemplate
1076 1078 parse and apply a template
1077 1079 debuguigetpass
1078 1080 show prompt to type password
1079 1081 debuguiprompt
1080 1082 show plain prompt
1081 1083 debugupdatecaches
1082 1084 warm all known caches in the repository
1083 1085 debugupgraderepo
1084 1086 upgrade a repository to use different features
1085 1087 debugwalk show how files match on given patterns
1086 1088 debugwhyunstable
1087 1089 explain instabilities of a changeset
1088 1090 debugwireargs
1089 1091 (no help text available)
1090 1092 debugwireproto
1091 1093 send wire protocol commands to a server
1092 1094
1093 1095 (use 'hg help -v debug' to show built-in aliases and global options)
1094 1096
1095 1097 internals topic renders index of available sub-topics
1096 1098
1097 1099 $ hg help internals
1098 1100 Technical implementation topics
1099 1101 """""""""""""""""""""""""""""""
1100 1102
1101 1103 To access a subtopic, use "hg help internals.{subtopic-name}"
1102 1104
1103 1105 bid-merge Bid Merge Algorithm
1104 1106 bundle2 Bundle2
1105 1107 bundles Bundles
1106 1108 cbor CBOR
1107 1109 censor Censor
1108 1110 changegroups Changegroups
1109 1111 config Config Registrar
1110 1112 extensions Extension API
1111 1113 mergestate Mergestate
1112 1114 requirements Repository Requirements
1113 1115 revlogs Revision Logs
1114 1116 wireprotocol Wire Protocol
1115 1117 wireprotocolrpc
1116 1118 Wire Protocol RPC
1117 1119 wireprotocolv2
1118 1120 Wire Protocol Version 2
1119 1121
1120 1122 sub-topics can be accessed
1121 1123
1122 1124 $ hg help internals.changegroups
1123 1125 Changegroups
1124 1126 """"""""""""
1125 1127
1126 1128 Changegroups are representations of repository revlog data, specifically
1127 1129 the changelog data, root/flat manifest data, treemanifest data, and
1128 1130 filelogs.
1129 1131
1130 1132 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1131 1133 level, versions "1" and "2" are almost exactly the same, with the only
1132 1134 difference being an additional item in the *delta header*. Version "3"
1133 1135 adds support for storage flags in the *delta header* and optionally
1134 1136 exchanging treemanifests (enabled by setting an option on the
1135 1137 "changegroup" part in the bundle2).
1136 1138
1137 1139 Changegroups when not exchanging treemanifests consist of 3 logical
1138 1140 segments:
1139 1141
1140 1142 +---------------------------------+
1141 1143 | | | |
1142 1144 | changeset | manifest | filelogs |
1143 1145 | | | |
1144 1146 | | | |
1145 1147 +---------------------------------+
1146 1148
1147 1149 When exchanging treemanifests, there are 4 logical segments:
1148 1150
1149 1151 +-------------------------------------------------+
1150 1152 | | | | |
1151 1153 | changeset | root | treemanifests | filelogs |
1152 1154 | | manifest | | |
1153 1155 | | | | |
1154 1156 +-------------------------------------------------+
1155 1157
1156 1158 The principle building block of each segment is a *chunk*. A *chunk* is a
1157 1159 framed piece of data:
1158 1160
1159 1161 +---------------------------------------+
1160 1162 | | |
1161 1163 | length | data |
1162 1164 | (4 bytes) | (<length - 4> bytes) |
1163 1165 | | |
1164 1166 +---------------------------------------+
1165 1167
1166 1168 All integers are big-endian signed integers. Each chunk starts with a
1167 1169 32-bit integer indicating the length of the entire chunk (including the
1168 1170 length field itself).
1169 1171
1170 1172 There is a special case chunk that has a value of 0 for the length
1171 1173 ("0x00000000"). We call this an *empty chunk*.
1172 1174
1173 1175 Delta Groups
1174 1176 ============
1175 1177
1176 1178 A *delta group* expresses the content of a revlog as a series of deltas,
1177 1179 or patches against previous revisions.
1178 1180
1179 1181 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1180 1182 to signal the end of the delta group:
1181 1183
1182 1184 +------------------------------------------------------------------------+
1183 1185 | | | | | |
1184 1186 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1185 1187 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1186 1188 | | | | | |
1187 1189 +------------------------------------------------------------------------+
1188 1190
1189 1191 Each *chunk*'s data consists of the following:
1190 1192
1191 1193 +---------------------------------------+
1192 1194 | | |
1193 1195 | delta header | delta data |
1194 1196 | (various by version) | (various) |
1195 1197 | | |
1196 1198 +---------------------------------------+
1197 1199
1198 1200 The *delta data* is a series of *delta*s that describe a diff from an
1199 1201 existing entry (either that the recipient already has, or previously
1200 1202 specified in the bundle/changegroup).
1201 1203
1202 1204 The *delta header* is different between versions "1", "2", and "3" of the
1203 1205 changegroup format.
1204 1206
1205 1207 Version 1 (headerlen=80):
1206 1208
1207 1209 +------------------------------------------------------+
1208 1210 | | | | |
1209 1211 | node | p1 node | p2 node | link node |
1210 1212 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1211 1213 | | | | |
1212 1214 +------------------------------------------------------+
1213 1215
1214 1216 Version 2 (headerlen=100):
1215 1217
1216 1218 +------------------------------------------------------------------+
1217 1219 | | | | | |
1218 1220 | node | p1 node | p2 node | base node | link node |
1219 1221 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1220 1222 | | | | | |
1221 1223 +------------------------------------------------------------------+
1222 1224
1223 1225 Version 3 (headerlen=102):
1224 1226
1225 1227 +------------------------------------------------------------------------------+
1226 1228 | | | | | | |
1227 1229 | node | p1 node | p2 node | base node | link node | flags |
1228 1230 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1229 1231 | | | | | | |
1230 1232 +------------------------------------------------------------------------------+
1231 1233
1232 1234 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1233 1235 contain a series of *delta*s, densely packed (no separators). These deltas
1234 1236 describe a diff from an existing entry (either that the recipient already
1235 1237 has, or previously specified in the bundle/changegroup). The format is
1236 1238 described more fully in "hg help internals.bdiff", but briefly:
1237 1239
1238 1240 +---------------------------------------------------------------+
1239 1241 | | | | |
1240 1242 | start offset | end offset | new length | content |
1241 1243 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1242 1244 | | | | |
1243 1245 +---------------------------------------------------------------+
1244 1246
1245 1247 Please note that the length field in the delta data does *not* include
1246 1248 itself.
1247 1249
1248 1250 In version 1, the delta is always applied against the previous node from
1249 1251 the changegroup or the first parent if this is the first entry in the
1250 1252 changegroup.
1251 1253
1252 1254 In version 2 and up, the delta base node is encoded in the entry in the
1253 1255 changegroup. This allows the delta to be expressed against any parent,
1254 1256 which can result in smaller deltas and more efficient encoding of data.
1255 1257
1256 1258 The *flags* field holds bitwise flags affecting the processing of revision
1257 1259 data. The following flags are defined:
1258 1260
1259 1261 32768
1260 1262 Censored revision. The revision's fulltext has been replaced by censor
1261 1263 metadata. May only occur on file revisions.
1262 1264
1263 1265 16384
1264 1266 Ellipsis revision. Revision hash does not match data (likely due to
1265 1267 rewritten parents).
1266 1268
1267 1269 8192
1268 1270 Externally stored. The revision fulltext contains "key:value" "\n"
1269 1271 delimited metadata defining an object stored elsewhere. Used by the LFS
1270 1272 extension.
1271 1273
1272 1274 For historical reasons, the integer values are identical to revlog version
1273 1275 1 per-revision storage flags and correspond to bits being set in this
1274 1276 2-byte field. Bits were allocated starting from the most-significant bit,
1275 1277 hence the reverse ordering and allocation of these flags.
1276 1278
1277 1279 Changeset Segment
1278 1280 =================
1279 1281
1280 1282 The *changeset segment* consists of a single *delta group* holding
1281 1283 changelog data. The *empty chunk* at the end of the *delta group* denotes
1282 1284 the boundary to the *manifest segment*.
1283 1285
1284 1286 Manifest Segment
1285 1287 ================
1286 1288
1287 1289 The *manifest segment* consists of a single *delta group* holding manifest
1288 1290 data. If treemanifests are in use, it contains only the manifest for the
1289 1291 root directory of the repository. Otherwise, it contains the entire
1290 1292 manifest data. The *empty chunk* at the end of the *delta group* denotes
1291 1293 the boundary to the next segment (either the *treemanifests segment* or
1292 1294 the *filelogs segment*, depending on version and the request options).
1293 1295
1294 1296 Treemanifests Segment
1295 1297 ---------------------
1296 1298
1297 1299 The *treemanifests segment* only exists in changegroup version "3", and
1298 1300 only if the 'treemanifest' param is part of the bundle2 changegroup part
1299 1301 (it is not possible to use changegroup version 3 outside of bundle2).
1300 1302 Aside from the filenames in the *treemanifests segment* containing a
1301 1303 trailing "/" character, it behaves identically to the *filelogs segment*
1302 1304 (see below). The final sub-segment is followed by an *empty chunk*
1303 1305 (logically, a sub-segment with filename size 0). This denotes the boundary
1304 1306 to the *filelogs segment*.
1305 1307
1306 1308 Filelogs Segment
1307 1309 ================
1308 1310
1309 1311 The *filelogs segment* consists of multiple sub-segments, each
1310 1312 corresponding to an individual file whose data is being described:
1311 1313
1312 1314 +--------------------------------------------------+
1313 1315 | | | | | |
1314 1316 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1315 1317 | | | | | (4 bytes) |
1316 1318 | | | | | |
1317 1319 +--------------------------------------------------+
1318 1320
1319 1321 The final filelog sub-segment is followed by an *empty chunk* (logically,
1320 1322 a sub-segment with filename size 0). This denotes the end of the segment
1321 1323 and of the overall changegroup.
1322 1324
1323 1325 Each filelog sub-segment consists of the following:
1324 1326
1325 1327 +------------------------------------------------------+
1326 1328 | | | |
1327 1329 | filename length | filename | delta group |
1328 1330 | (4 bytes) | (<length - 4> bytes) | (various) |
1329 1331 | | | |
1330 1332 +------------------------------------------------------+
1331 1333
1332 1334 That is, a *chunk* consisting of the filename (not terminated or padded)
1333 1335 followed by N chunks constituting the *delta group* for this file. The
1334 1336 *empty chunk* at the end of each *delta group* denotes the boundary to the
1335 1337 next filelog sub-segment.
1336 1338
1337 1339 non-existent subtopics print an error
1338 1340
1339 1341 $ hg help internals.foo
1340 1342 abort: no such help topic: internals.foo
1341 1343 (try 'hg help --keyword foo')
1342 1344 [255]
1343 1345
1344 1346 test advanced, deprecated and experimental options are hidden in command help
1345 1347 $ hg help debugoptADV
1346 1348 hg debugoptADV
1347 1349
1348 1350 (no help text available)
1349 1351
1350 1352 options:
1351 1353
1352 1354 (some details hidden, use --verbose to show complete help)
1353 1355 $ hg help debugoptDEP
1354 1356 hg debugoptDEP
1355 1357
1356 1358 (no help text available)
1357 1359
1358 1360 options:
1359 1361
1360 1362 (some details hidden, use --verbose to show complete help)
1361 1363
1362 1364 $ hg help debugoptEXP
1363 1365 hg debugoptEXP
1364 1366
1365 1367 (no help text available)
1366 1368
1367 1369 options:
1368 1370
1369 1371 (some details hidden, use --verbose to show complete help)
1370 1372
1371 1373 test advanced, deprecated and experimental options are shown with -v
1372 1374 $ hg help -v debugoptADV | grep aopt
1373 1375 --aopt option is (ADVANCED)
1374 1376 $ hg help -v debugoptDEP | grep dopt
1375 1377 --dopt option is (DEPRECATED)
1376 1378 $ hg help -v debugoptEXP | grep eopt
1377 1379 --eopt option is (EXPERIMENTAL)
1378 1380
1379 1381 #if gettext
1380 1382 test deprecated option is hidden with translation with untranslated description
1381 1383 (use many globy for not failing on changed transaction)
1382 1384 $ LANGUAGE=sv hg help debugoptDEP
1383 1385 hg debugoptDEP
1384 1386
1385 1387 (*) (glob)
1386 1388
1387 1389 options:
1388 1390
1389 1391 (some details hidden, use --verbose to show complete help)
1390 1392 #endif
1391 1393
1392 1394 Test commands that collide with topics (issue4240)
1393 1395
1394 1396 $ hg config -hq
1395 1397 hg config [-u] [NAME]...
1396 1398
1397 1399 show combined config settings from all hgrc files
1398 1400 $ hg showconfig -hq
1399 1401 hg config [-u] [NAME]...
1400 1402
1401 1403 show combined config settings from all hgrc files
1402 1404
1403 1405 Test a help topic
1404 1406
1405 1407 $ hg help dates
1406 1408 Date Formats
1407 1409 """"""""""""
1408 1410
1409 1411 Some commands allow the user to specify a date, e.g.:
1410 1412
1411 1413 - backout, commit, import, tag: Specify the commit date.
1412 1414 - log, revert, update: Select revision(s) by date.
1413 1415
1414 1416 Many date formats are valid. Here are some examples:
1415 1417
1416 1418 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1417 1419 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1418 1420 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1419 1421 - "Dec 6" (midnight)
1420 1422 - "13:18" (today assumed)
1421 1423 - "3:39" (3:39AM assumed)
1422 1424 - "3:39pm" (15:39)
1423 1425 - "2006-12-06 13:18:29" (ISO 8601 format)
1424 1426 - "2006-12-6 13:18"
1425 1427 - "2006-12-6"
1426 1428 - "12-6"
1427 1429 - "12/6"
1428 1430 - "12/6/6" (Dec 6 2006)
1429 1431 - "today" (midnight)
1430 1432 - "yesterday" (midnight)
1431 1433 - "now" - right now
1432 1434
1433 1435 Lastly, there is Mercurial's internal format:
1434 1436
1435 1437 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1436 1438
1437 1439 This is the internal representation format for dates. The first number is
1438 1440 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1439 1441 is the offset of the local timezone, in seconds west of UTC (negative if
1440 1442 the timezone is east of UTC).
1441 1443
1442 1444 The log command also accepts date ranges:
1443 1445
1444 1446 - "<DATE" - at or before a given date/time
1445 1447 - ">DATE" - on or after a given date/time
1446 1448 - "DATE to DATE" - a date range, inclusive
1447 1449 - "-DAYS" - within a given number of days from today
1448 1450
1449 1451 Test repeated config section name
1450 1452
1451 1453 $ hg help config.host
1452 1454 "http_proxy.host"
1453 1455 Host name and (optional) port of the proxy server, for example
1454 1456 "myproxy:8000".
1455 1457
1456 1458 "smtp.host"
1457 1459 Host name of mail server, e.g. "mail.example.com".
1458 1460
1459 1461
1460 1462 Test section name with dot
1461 1463
1462 1464 $ hg help config.ui.username
1463 1465 "ui.username"
1464 1466 The committer of a changeset created when running "commit". Typically
1465 1467 a person's name and email address, e.g. "Fred Widget
1466 1468 <fred@example.com>". Environment variables in the username are
1467 1469 expanded.
1468 1470
1469 1471 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1470 1472 empty, e.g. if the system admin set "username =" in the system hgrc,
1471 1473 it has to be specified manually or in a different hgrc file)
1472 1474
1473 1475
1474 1476 $ hg help config.annotate.git
1475 1477 abort: help section not found: config.annotate.git
1476 1478 [255]
1477 1479
1478 1480 $ hg help config.update.check
1479 1481 "commands.update.check"
1480 1482 Determines what level of checking 'hg update' will perform before
1481 1483 moving to a destination revision. Valid values are "abort", "none",
1482 1484 "linear", and "noconflict". "abort" always fails if the working
1483 1485 directory has uncommitted changes. "none" performs no checking, and
1484 1486 may result in a merge with uncommitted changes. "linear" allows any
1485 1487 update as long as it follows a straight line in the revision history,
1486 1488 and may trigger a merge with uncommitted changes. "noconflict" will
1487 1489 allow any update which would not trigger a merge with uncommitted
1488 1490 changes, if any are present. (default: "linear")
1489 1491
1490 1492
1491 1493 $ hg help config.commands.update.check
1492 1494 "commands.update.check"
1493 1495 Determines what level of checking 'hg update' will perform before
1494 1496 moving to a destination revision. Valid values are "abort", "none",
1495 1497 "linear", and "noconflict". "abort" always fails if the working
1496 1498 directory has uncommitted changes. "none" performs no checking, and
1497 1499 may result in a merge with uncommitted changes. "linear" allows any
1498 1500 update as long as it follows a straight line in the revision history,
1499 1501 and may trigger a merge with uncommitted changes. "noconflict" will
1500 1502 allow any update which would not trigger a merge with uncommitted
1501 1503 changes, if any are present. (default: "linear")
1502 1504
1503 1505
1504 1506 $ hg help config.ommands.update.check
1505 1507 abort: help section not found: config.ommands.update.check
1506 1508 [255]
1507 1509
1508 1510 Unrelated trailing paragraphs shouldn't be included
1509 1511
1510 1512 $ hg help config.extramsg | grep '^$'
1511 1513
1512 1514
1513 1515 Test capitalized section name
1514 1516
1515 1517 $ hg help scripting.HGPLAIN > /dev/null
1516 1518
1517 1519 Help subsection:
1518 1520
1519 1521 $ hg help config.charsets |grep "Email example:" > /dev/null
1520 1522 [1]
1521 1523
1522 1524 Show nested definitions
1523 1525 ("profiling.type"[break]"ls"[break]"stat"[break])
1524 1526
1525 1527 $ hg help config.type | egrep '^$'|wc -l
1526 1528 \s*3 (re)
1527 1529
1528 1530 $ hg help config.profiling.type.ls
1529 1531 "profiling.type.ls"
1530 1532 Use Python's built-in instrumenting profiler. This profiler works on
1531 1533 all platforms, but each line number it reports is the first line of
1532 1534 a function. This restriction makes it difficult to identify the
1533 1535 expensive parts of a non-trivial function.
1534 1536
1535 1537
1536 1538 Separate sections from subsections
1537 1539
1538 1540 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1539 1541 "format"
1540 1542 --------
1541 1543
1542 1544 "usegeneraldelta"
1543 1545
1544 1546 "dotencode"
1545 1547
1546 1548 "usefncache"
1547 1549
1548 1550 "usestore"
1549 1551
1550 1552 "sparse-revlog"
1551 1553
1552 1554 "revlog-compression"
1553 1555
1554 1556 "bookmarks-in-store"
1555 1557
1556 1558 "profiling"
1557 1559 -----------
1558 1560
1559 1561 "format"
1560 1562
1561 1563 "progress"
1562 1564 ----------
1563 1565
1564 1566 "format"
1565 1567
1566 1568
1567 1569 Last item in help config.*:
1568 1570
1569 1571 $ hg help config.`hg help config|grep '^ "'| \
1570 1572 > tail -1|sed 's![ "]*!!g'`| \
1571 1573 > grep 'hg help -c config' > /dev/null
1572 1574 [1]
1573 1575
1574 1576 note to use help -c for general hg help config:
1575 1577
1576 1578 $ hg help config |grep 'hg help -c config' > /dev/null
1577 1579
1578 1580 Test templating help
1579 1581
1580 1582 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1581 1583 desc String. The text of the changeset description.
1582 1584 diffstat String. Statistics of changes with the following format:
1583 1585 firstline Any text. Returns the first line of text.
1584 1586 nonempty Any text. Returns '(none)' if the string is empty.
1585 1587
1586 1588 Test deprecated items
1587 1589
1588 1590 $ hg help -v templating | grep currentbookmark
1589 1591 currentbookmark
1590 1592 $ hg help templating | (grep currentbookmark || true)
1591 1593
1592 1594 Test help hooks
1593 1595
1594 1596 $ cat > helphook1.py <<EOF
1595 1597 > from mercurial import help
1596 1598 >
1597 1599 > def rewrite(ui, topic, doc):
1598 1600 > return doc + b'\nhelphook1\n'
1599 1601 >
1600 1602 > def extsetup(ui):
1601 1603 > help.addtopichook(b'revisions', rewrite)
1602 1604 > EOF
1603 1605 $ cat > helphook2.py <<EOF
1604 1606 > from mercurial import help
1605 1607 >
1606 1608 > def rewrite(ui, topic, doc):
1607 1609 > return doc + b'\nhelphook2\n'
1608 1610 >
1609 1611 > def extsetup(ui):
1610 1612 > help.addtopichook(b'revisions', rewrite)
1611 1613 > EOF
1612 1614 $ echo '[extensions]' >> $HGRCPATH
1613 1615 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1614 1616 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1615 1617 $ hg help revsets | grep helphook
1616 1618 helphook1
1617 1619 helphook2
1618 1620
1619 1621 help -c should only show debug --debug
1620 1622
1621 1623 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1622 1624 [1]
1623 1625
1624 1626 help -c should only show deprecated for -v
1625 1627
1626 1628 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1627 1629 [1]
1628 1630
1629 1631 Test -s / --system
1630 1632
1631 1633 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1632 1634 > wc -l | sed -e 's/ //g'
1633 1635 0
1634 1636 $ hg help config.files --system unix | grep 'USER' | \
1635 1637 > wc -l | sed -e 's/ //g'
1636 1638 0
1637 1639
1638 1640 Test -e / -c / -k combinations
1639 1641
1640 1642 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1641 1643 Commands:
1642 1644 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1643 1645 Extensions:
1644 1646 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1645 1647 Topics:
1646 1648 Commands:
1647 1649 Extensions:
1648 1650 Extension Commands:
1649 1651 $ hg help -c schemes
1650 1652 abort: no such help topic: schemes
1651 1653 (try 'hg help --keyword schemes')
1652 1654 [255]
1653 1655 $ hg help -e schemes |head -1
1654 1656 schemes extension - extend schemes with shortcuts to repository swarms
1655 1657 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1656 1658 Commands:
1657 1659 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1658 1660 Extensions:
1659 1661 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1660 1662 Extensions:
1661 1663 Commands:
1662 1664 $ hg help -c commit > /dev/null
1663 1665 $ hg help -e -c commit > /dev/null
1664 1666 $ hg help -e commit
1665 1667 abort: no such help topic: commit
1666 1668 (try 'hg help --keyword commit')
1667 1669 [255]
1668 1670
1669 1671 Test keyword search help
1670 1672
1671 1673 $ cat > prefixedname.py <<EOF
1672 1674 > '''matched against word "clone"
1673 1675 > '''
1674 1676 > EOF
1675 1677 $ echo '[extensions]' >> $HGRCPATH
1676 1678 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1677 1679 $ hg help -k clone
1678 1680 Topics:
1679 1681
1680 1682 config Configuration Files
1681 1683 extensions Using Additional Features
1682 1684 glossary Glossary
1683 1685 phases Working with Phases
1684 1686 subrepos Subrepositories
1685 1687 urls URL Paths
1686 1688
1687 1689 Commands:
1688 1690
1689 1691 bookmarks create a new bookmark or list existing bookmarks
1690 1692 clone make a copy of an existing repository
1691 1693 paths show aliases for remote repositories
1692 1694 pull pull changes from the specified source
1693 1695 update update working directory (or switch revisions)
1694 1696
1695 1697 Extensions:
1696 1698
1697 1699 clonebundles advertise pre-generated bundles to seed clones
1698 1700 narrow create clones which fetch history data for subset of files
1699 1701 (EXPERIMENTAL)
1700 1702 prefixedname matched against word "clone"
1701 1703 relink recreates hardlinks between repository clones
1702 1704
1703 1705 Extension Commands:
1704 1706
1705 1707 qclone clone main and patch repository at same time
1706 1708
1707 1709 Test unfound topic
1708 1710
1709 1711 $ hg help nonexistingtopicthatwillneverexisteverever
1710 1712 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1711 1713 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1712 1714 [255]
1713 1715
1714 1716 Test unfound keyword
1715 1717
1716 1718 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1717 1719 abort: no matches
1718 1720 (try 'hg help' for a list of topics)
1719 1721 [255]
1720 1722
1721 1723 Test omit indicating for help
1722 1724
1723 1725 $ cat > addverboseitems.py <<EOF
1724 1726 > r'''extension to test omit indicating.
1725 1727 >
1726 1728 > This paragraph is never omitted (for extension)
1727 1729 >
1728 1730 > .. container:: verbose
1729 1731 >
1730 1732 > This paragraph is omitted,
1731 1733 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1732 1734 >
1733 1735 > This paragraph is never omitted, too (for extension)
1734 1736 > '''
1735 1737 > from __future__ import absolute_import
1736 1738 > from mercurial import commands, help
1737 1739 > testtopic = br"""This paragraph is never omitted (for topic).
1738 1740 >
1739 1741 > .. container:: verbose
1740 1742 >
1741 1743 > This paragraph is omitted,
1742 1744 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1743 1745 >
1744 1746 > This paragraph is never omitted, too (for topic)
1745 1747 > """
1746 1748 > def extsetup(ui):
1747 1749 > help.helptable.append(([b"topic-containing-verbose"],
1748 1750 > b"This is the topic to test omit indicating.",
1749 1751 > lambda ui: testtopic))
1750 1752 > EOF
1751 1753 $ echo '[extensions]' >> $HGRCPATH
1752 1754 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1753 1755 $ hg help addverboseitems
1754 1756 addverboseitems extension - extension to test omit indicating.
1755 1757
1756 1758 This paragraph is never omitted (for extension)
1757 1759
1758 1760 This paragraph is never omitted, too (for extension)
1759 1761
1760 1762 (some details hidden, use --verbose to show complete help)
1761 1763
1762 1764 no commands defined
1763 1765 $ hg help -v addverboseitems
1764 1766 addverboseitems extension - extension to test omit indicating.
1765 1767
1766 1768 This paragraph is never omitted (for extension)
1767 1769
1768 1770 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1769 1771 extension)
1770 1772
1771 1773 This paragraph is never omitted, too (for extension)
1772 1774
1773 1775 no commands defined
1774 1776 $ hg help topic-containing-verbose
1775 1777 This is the topic to test omit indicating.
1776 1778 """"""""""""""""""""""""""""""""""""""""""
1777 1779
1778 1780 This paragraph is never omitted (for topic).
1779 1781
1780 1782 This paragraph is never omitted, too (for topic)
1781 1783
1782 1784 (some details hidden, use --verbose to show complete help)
1783 1785 $ hg help -v topic-containing-verbose
1784 1786 This is the topic to test omit indicating.
1785 1787 """"""""""""""""""""""""""""""""""""""""""
1786 1788
1787 1789 This paragraph is never omitted (for topic).
1788 1790
1789 1791 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1790 1792 topic)
1791 1793
1792 1794 This paragraph is never omitted, too (for topic)
1793 1795
1794 1796 Test section lookup
1795 1797
1796 1798 $ hg help revset.merge
1797 1799 "merge()"
1798 1800 Changeset is a merge changeset.
1799 1801
1800 1802 $ hg help glossary.dag
1801 1803 DAG
1802 1804 The repository of changesets of a distributed version control system
1803 1805 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1804 1806 of nodes and edges, where nodes correspond to changesets and edges
1805 1807 imply a parent -> child relation. This graph can be visualized by
1806 1808 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1807 1809 limited by the requirement for children to have at most two parents.
1808 1810
1809 1811
1810 1812 $ hg help hgrc.paths
1811 1813 "paths"
1812 1814 -------
1813 1815
1814 1816 Assigns symbolic names and behavior to repositories.
1815 1817
1816 1818 Options are symbolic names defining the URL or directory that is the
1817 1819 location of the repository. Example:
1818 1820
1819 1821 [paths]
1820 1822 my_server = https://example.com/my_repo
1821 1823 local_path = /home/me/repo
1822 1824
1823 1825 These symbolic names can be used from the command line. To pull from
1824 1826 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1825 1827 local_path'.
1826 1828
1827 1829 Options containing colons (":") denote sub-options that can influence
1828 1830 behavior for that specific path. Example:
1829 1831
1830 1832 [paths]
1831 1833 my_server = https://example.com/my_path
1832 1834 my_server:pushurl = ssh://example.com/my_path
1833 1835
1834 1836 The following sub-options can be defined:
1835 1837
1836 1838 "pushurl"
1837 1839 The URL to use for push operations. If not defined, the location
1838 1840 defined by the path's main entry is used.
1839 1841
1840 1842 "pushrev"
1841 1843 A revset defining which revisions to push by default.
1842 1844
1843 1845 When 'hg push' is executed without a "-r" argument, the revset defined
1844 1846 by this sub-option is evaluated to determine what to push.
1845 1847
1846 1848 For example, a value of "." will push the working directory's revision
1847 1849 by default.
1848 1850
1849 1851 Revsets specifying bookmarks will not result in the bookmark being
1850 1852 pushed.
1851 1853
1852 1854 The following special named paths exist:
1853 1855
1854 1856 "default"
1855 1857 The URL or directory to use when no source or remote is specified.
1856 1858
1857 1859 'hg clone' will automatically define this path to the location the
1858 1860 repository was cloned from.
1859 1861
1860 1862 "default-push"
1861 1863 (deprecated) The URL or directory for the default 'hg push' location.
1862 1864 "default:pushurl" should be used instead.
1863 1865
1864 1866 $ hg help glossary.mcguffin
1865 1867 abort: help section not found: glossary.mcguffin
1866 1868 [255]
1867 1869
1868 1870 $ hg help glossary.mc.guffin
1869 1871 abort: help section not found: glossary.mc.guffin
1870 1872 [255]
1871 1873
1872 1874 $ hg help template.files
1873 1875 files List of strings. All files modified, added, or removed by
1874 1876 this changeset.
1875 1877 files(pattern)
1876 1878 All files of the current changeset matching the pattern. See
1877 1879 'hg help patterns'.
1878 1880
1879 1881 Test section lookup by translated message
1880 1882
1881 1883 str.lower() instead of encoding.lower(str) on translated message might
1882 1884 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1883 1885 as the second or later byte of multi-byte character.
1884 1886
1885 1887 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1886 1888 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1887 1889 replacement makes message meaningless.
1888 1890
1889 1891 This tests that section lookup by translated string isn't broken by
1890 1892 such str.lower().
1891 1893
1892 1894 $ "$PYTHON" <<EOF
1893 1895 > def escape(s):
1894 1896 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1895 1897 > # translation of "record" in ja_JP.cp932
1896 1898 > upper = b"\x8bL\x98^"
1897 1899 > # str.lower()-ed section name should be treated as different one
1898 1900 > lower = b"\x8bl\x98^"
1899 1901 > with open('ambiguous.py', 'wb') as fp:
1900 1902 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1901 1903 > u'''summary of extension
1902 1904 >
1903 1905 > %s
1904 1906 > ----
1905 1907 >
1906 1908 > Upper name should show only this message
1907 1909 >
1908 1910 > %s
1909 1911 > ----
1910 1912 >
1911 1913 > Lower name should show only this message
1912 1914 >
1913 1915 > subsequent section
1914 1916 > ------------------
1915 1917 >
1916 1918 > This should be hidden at 'hg help ambiguous' with section name.
1917 1919 > '''
1918 1920 > """ % (escape(upper), escape(lower)))
1919 1921 > EOF
1920 1922
1921 1923 $ cat >> $HGRCPATH <<EOF
1922 1924 > [extensions]
1923 1925 > ambiguous = ./ambiguous.py
1924 1926 > EOF
1925 1927
1926 1928 $ "$PYTHON" <<EOF | sh
1927 1929 > from mercurial.utils import procutil
1928 1930 > upper = b"\x8bL\x98^"
1929 1931 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1930 1932 > EOF
1931 1933 \x8bL\x98^ (esc)
1932 1934 ----
1933 1935
1934 1936 Upper name should show only this message
1935 1937
1936 1938
1937 1939 $ "$PYTHON" <<EOF | sh
1938 1940 > from mercurial.utils import procutil
1939 1941 > lower = b"\x8bl\x98^"
1940 1942 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1941 1943 > EOF
1942 1944 \x8bl\x98^ (esc)
1943 1945 ----
1944 1946
1945 1947 Lower name should show only this message
1946 1948
1947 1949
1948 1950 $ cat >> $HGRCPATH <<EOF
1949 1951 > [extensions]
1950 1952 > ambiguous = !
1951 1953 > EOF
1952 1954
1953 1955 Show help content of disabled extensions
1954 1956
1955 1957 $ cat >> $HGRCPATH <<EOF
1956 1958 > [extensions]
1957 1959 > ambiguous = !./ambiguous.py
1958 1960 > EOF
1959 1961 $ hg help -e ambiguous
1960 1962 ambiguous extension - (no help text available)
1961 1963
1962 1964 (use 'hg help extensions' for information on enabling extensions)
1963 1965
1964 1966 Test dynamic list of merge tools only shows up once
1965 1967 $ hg help merge-tools
1966 1968 Merge Tools
1967 1969 """""""""""
1968 1970
1969 1971 To merge files Mercurial uses merge tools.
1970 1972
1971 1973 A merge tool combines two different versions of a file into a merged file.
1972 1974 Merge tools are given the two files and the greatest common ancestor of
1973 1975 the two file versions, so they can determine the changes made on both
1974 1976 branches.
1975 1977
1976 1978 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1977 1979 backout' and in several extensions.
1978 1980
1979 1981 Usually, the merge tool tries to automatically reconcile the files by
1980 1982 combining all non-overlapping changes that occurred separately in the two
1981 1983 different evolutions of the same initial base file. Furthermore, some
1982 1984 interactive merge programs make it easier to manually resolve conflicting
1983 1985 merges, either in a graphical way, or by inserting some conflict markers.
1984 1986 Mercurial does not include any interactive merge programs but relies on
1985 1987 external tools for that.
1986 1988
1987 1989 Available merge tools
1988 1990 =====================
1989 1991
1990 1992 External merge tools and their properties are configured in the merge-
1991 1993 tools configuration section - see hgrc(5) - but they can often just be
1992 1994 named by their executable.
1993 1995
1994 1996 A merge tool is generally usable if its executable can be found on the
1995 1997 system and if it can handle the merge. The executable is found if it is an
1996 1998 absolute or relative executable path or the name of an application in the
1997 1999 executable search path. The tool is assumed to be able to handle the merge
1998 2000 if it can handle symlinks if the file is a symlink, if it can handle
1999 2001 binary files if the file is binary, and if a GUI is available if the tool
2000 2002 requires a GUI.
2001 2003
2002 2004 There are some internal merge tools which can be used. The internal merge
2003 2005 tools are:
2004 2006
2005 2007 ":dump"
2006 2008 Creates three versions of the files to merge, containing the contents of
2007 2009 local, other and base. These files can then be used to perform a merge
2008 2010 manually. If the file to be merged is named "a.txt", these files will
2009 2011 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2010 2012 they will be placed in the same directory as "a.txt".
2011 2013
2012 2014 This implies premerge. Therefore, files aren't dumped, if premerge runs
2013 2015 successfully. Use :forcedump to forcibly write files out.
2014 2016
2015 2017 (actual capabilities: binary, symlink)
2016 2018
2017 2019 ":fail"
2018 2020 Rather than attempting to merge files that were modified on both
2019 2021 branches, it marks them as unresolved. The resolve command must be used
2020 2022 to resolve these conflicts.
2021 2023
2022 2024 (actual capabilities: binary, symlink)
2023 2025
2024 2026 ":forcedump"
2025 2027 Creates three versions of the files as same as :dump, but omits
2026 2028 premerge.
2027 2029
2028 2030 (actual capabilities: binary, symlink)
2029 2031
2030 2032 ":local"
2031 2033 Uses the local 'p1()' version of files as the merged version.
2032 2034
2033 2035 (actual capabilities: binary, symlink)
2034 2036
2035 2037 ":merge"
2036 2038 Uses the internal non-interactive simple merge algorithm for merging
2037 2039 files. It will fail if there are any conflicts and leave markers in the
2038 2040 partially merged file. Markers will have two sections, one for each side
2039 2041 of merge.
2040 2042
2041 2043 ":merge-local"
2042 2044 Like :merge, but resolve all conflicts non-interactively in favor of the
2043 2045 local 'p1()' changes.
2044 2046
2045 2047 ":merge-other"
2046 2048 Like :merge, but resolve all conflicts non-interactively in favor of the
2047 2049 other 'p2()' changes.
2048 2050
2049 2051 ":merge3"
2050 2052 Uses the internal non-interactive simple merge algorithm for merging
2051 2053 files. It will fail if there are any conflicts and leave markers in the
2052 2054 partially merged file. Marker will have three sections, one from each
2053 2055 side of the merge and one for the base content.
2054 2056
2055 2057 ":other"
2056 2058 Uses the other 'p2()' version of files as the merged version.
2057 2059
2058 2060 (actual capabilities: binary, symlink)
2059 2061
2060 2062 ":prompt"
2061 2063 Asks the user which of the local 'p1()' or the other 'p2()' version to
2062 2064 keep as the merged version.
2063 2065
2064 2066 (actual capabilities: binary, symlink)
2065 2067
2066 2068 ":tagmerge"
2067 2069 Uses the internal tag merge algorithm (experimental).
2068 2070
2069 2071 ":union"
2070 2072 Uses the internal non-interactive simple merge algorithm for merging
2071 2073 files. It will use both left and right sides for conflict regions. No
2072 2074 markers are inserted.
2073 2075
2074 2076 Internal tools are always available and do not require a GUI but will by
2075 2077 default not handle symlinks or binary files. See next section for detail
2076 2078 about "actual capabilities" described above.
2077 2079
2078 2080 Choosing a merge tool
2079 2081 =====================
2080 2082
2081 2083 Mercurial uses these rules when deciding which merge tool to use:
2082 2084
2083 2085 1. If a tool has been specified with the --tool option to merge or
2084 2086 resolve, it is used. If it is the name of a tool in the merge-tools
2085 2087 configuration, its configuration is used. Otherwise the specified tool
2086 2088 must be executable by the shell.
2087 2089 2. If the "HGMERGE" environment variable is present, its value is used and
2088 2090 must be executable by the shell.
2089 2091 3. If the filename of the file to be merged matches any of the patterns in
2090 2092 the merge-patterns configuration section, the first usable merge tool
2091 2093 corresponding to a matching pattern is used.
2092 2094 4. If ui.merge is set it will be considered next. If the value is not the
2093 2095 name of a configured tool, the specified value is used and must be
2094 2096 executable by the shell. Otherwise the named tool is used if it is
2095 2097 usable.
2096 2098 5. If any usable merge tools are present in the merge-tools configuration
2097 2099 section, the one with the highest priority is used.
2098 2100 6. If a program named "hgmerge" can be found on the system, it is used -
2099 2101 but it will by default not be used for symlinks and binary files.
2100 2102 7. If the file to be merged is not binary and is not a symlink, then
2101 2103 internal ":merge" is used.
2102 2104 8. Otherwise, ":prompt" is used.
2103 2105
2104 2106 For historical reason, Mercurial treats merge tools as below while
2105 2107 examining rules above.
2106 2108
2107 2109 step specified via binary symlink
2108 2110 ----------------------------------
2109 2111 1. --tool o/o o/o
2110 2112 2. HGMERGE o/o o/o
2111 2113 3. merge-patterns o/o(*) x/?(*)
2112 2114 4. ui.merge x/?(*) x/?(*)
2113 2115
2114 2116 Each capability column indicates Mercurial behavior for internal/external
2115 2117 merge tools at examining each rule.
2116 2118
2117 2119 - "o": "assume that a tool has capability"
2118 2120 - "x": "assume that a tool does not have capability"
2119 2121 - "?": "check actual capability of a tool"
2120 2122
2121 2123 If "merge.strict-capability-check" configuration is true, Mercurial checks
2122 2124 capabilities of merge tools strictly in (*) cases above (= each capability
2123 2125 column becomes "?/?"). It is false by default for backward compatibility.
2124 2126
2125 2127 Note:
2126 2128 After selecting a merge program, Mercurial will by default attempt to
2127 2129 merge the files using a simple merge algorithm first. Only if it
2128 2130 doesn't succeed because of conflicting changes will Mercurial actually
2129 2131 execute the merge program. Whether to use the simple merge algorithm
2130 2132 first can be controlled by the premerge setting of the merge tool.
2131 2133 Premerge is enabled by default unless the file is binary or a symlink.
2132 2134
2133 2135 See the merge-tools and ui sections of hgrc(5) for details on the
2134 2136 configuration of merge tools.
2135 2137
2136 2138 Compression engines listed in `hg help bundlespec`
2137 2139
2138 2140 $ hg help bundlespec | grep gzip
2139 2141 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2140 2142 An algorithm that produces smaller bundles than "gzip".
2141 2143 This engine will likely produce smaller bundles than "gzip" but will be
2142 2144 "gzip"
2143 2145 better compression than "gzip". It also frequently yields better (?)
2144 2146
2145 2147 Test usage of section marks in help documents
2146 2148
2147 2149 $ cd "$TESTDIR"/../doc
2148 2150 $ "$PYTHON" check-seclevel.py
2149 2151 $ cd $TESTTMP
2150 2152
2151 2153 #if serve
2152 2154
2153 2155 Test the help pages in hgweb.
2154 2156
2155 2157 Dish up an empty repo; serve it cold.
2156 2158
2157 2159 $ hg init "$TESTTMP/test"
2158 2160 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2159 2161 $ cat hg.pid >> $DAEMON_PIDS
2160 2162
2161 2163 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2162 2164 200 Script output follows
2163 2165
2164 2166 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2165 2167 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2166 2168 <head>
2167 2169 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2168 2170 <meta name="robots" content="index, nofollow" />
2169 2171 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2170 2172 <script type="text/javascript" src="/static/mercurial.js"></script>
2171 2173
2172 2174 <title>Help: Index</title>
2173 2175 </head>
2174 2176 <body>
2175 2177
2176 2178 <div class="container">
2177 2179 <div class="menu">
2178 2180 <div class="logo">
2179 2181 <a href="https://mercurial-scm.org/">
2180 2182 <img src="/static/hglogo.png" alt="mercurial" /></a>
2181 2183 </div>
2182 2184 <ul>
2183 2185 <li><a href="/shortlog">log</a></li>
2184 2186 <li><a href="/graph">graph</a></li>
2185 2187 <li><a href="/tags">tags</a></li>
2186 2188 <li><a href="/bookmarks">bookmarks</a></li>
2187 2189 <li><a href="/branches">branches</a></li>
2188 2190 </ul>
2189 2191 <ul>
2190 2192 <li class="active">help</li>
2191 2193 </ul>
2192 2194 </div>
2193 2195
2194 2196 <div class="main">
2195 2197 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2196 2198
2197 2199 <form class="search" action="/log">
2198 2200
2199 2201 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2200 2202 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2201 2203 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2202 2204 </form>
2203 2205 <table class="bigtable">
2204 2206 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2205 2207
2206 2208 <tr><td>
2207 2209 <a href="/help/bundlespec">
2208 2210 bundlespec
2209 2211 </a>
2210 2212 </td><td>
2211 2213 Bundle File Formats
2212 2214 </td></tr>
2213 2215 <tr><td>
2214 2216 <a href="/help/color">
2215 2217 color
2216 2218 </a>
2217 2219 </td><td>
2218 2220 Colorizing Outputs
2219 2221 </td></tr>
2220 2222 <tr><td>
2221 2223 <a href="/help/config">
2222 2224 config
2223 2225 </a>
2224 2226 </td><td>
2225 2227 Configuration Files
2226 2228 </td></tr>
2227 2229 <tr><td>
2228 2230 <a href="/help/dates">
2229 2231 dates
2230 2232 </a>
2231 2233 </td><td>
2232 2234 Date Formats
2233 2235 </td></tr>
2234 2236 <tr><td>
2235 2237 <a href="/help/deprecated">
2236 2238 deprecated
2237 2239 </a>
2238 2240 </td><td>
2239 2241 Deprecated Features
2240 2242 </td></tr>
2241 2243 <tr><td>
2242 2244 <a href="/help/diffs">
2243 2245 diffs
2244 2246 </a>
2245 2247 </td><td>
2246 2248 Diff Formats
2247 2249 </td></tr>
2248 2250 <tr><td>
2249 2251 <a href="/help/environment">
2250 2252 environment
2251 2253 </a>
2252 2254 </td><td>
2253 2255 Environment Variables
2254 2256 </td></tr>
2255 2257 <tr><td>
2256 2258 <a href="/help/extensions">
2257 2259 extensions
2258 2260 </a>
2259 2261 </td><td>
2260 2262 Using Additional Features
2261 2263 </td></tr>
2262 2264 <tr><td>
2263 2265 <a href="/help/filesets">
2264 2266 filesets
2265 2267 </a>
2266 2268 </td><td>
2267 2269 Specifying File Sets
2268 2270 </td></tr>
2269 2271 <tr><td>
2270 2272 <a href="/help/flags">
2271 2273 flags
2272 2274 </a>
2273 2275 </td><td>
2274 2276 Command-line flags
2275 2277 </td></tr>
2276 2278 <tr><td>
2277 2279 <a href="/help/glossary">
2278 2280 glossary
2279 2281 </a>
2280 2282 </td><td>
2281 2283 Glossary
2282 2284 </td></tr>
2283 2285 <tr><td>
2284 2286 <a href="/help/hgignore">
2285 2287 hgignore
2286 2288 </a>
2287 2289 </td><td>
2288 2290 Syntax for Mercurial Ignore Files
2289 2291 </td></tr>
2290 2292 <tr><td>
2291 2293 <a href="/help/hgweb">
2292 2294 hgweb
2293 2295 </a>
2294 2296 </td><td>
2295 2297 Configuring hgweb
2296 2298 </td></tr>
2297 2299 <tr><td>
2298 2300 <a href="/help/internals">
2299 2301 internals
2300 2302 </a>
2301 2303 </td><td>
2302 2304 Technical implementation topics
2303 2305 </td></tr>
2304 2306 <tr><td>
2305 2307 <a href="/help/merge-tools">
2306 2308 merge-tools
2307 2309 </a>
2308 2310 </td><td>
2309 2311 Merge Tools
2310 2312 </td></tr>
2311 2313 <tr><td>
2312 2314 <a href="/help/pager">
2313 2315 pager
2314 2316 </a>
2315 2317 </td><td>
2316 2318 Pager Support
2317 2319 </td></tr>
2318 2320 <tr><td>
2319 2321 <a href="/help/patterns">
2320 2322 patterns
2321 2323 </a>
2322 2324 </td><td>
2323 2325 File Name Patterns
2324 2326 </td></tr>
2325 2327 <tr><td>
2326 2328 <a href="/help/phases">
2327 2329 phases
2328 2330 </a>
2329 2331 </td><td>
2330 2332 Working with Phases
2331 2333 </td></tr>
2332 2334 <tr><td>
2333 2335 <a href="/help/revisions">
2334 2336 revisions
2335 2337 </a>
2336 2338 </td><td>
2337 2339 Specifying Revisions
2338 2340 </td></tr>
2339 2341 <tr><td>
2340 2342 <a href="/help/scripting">
2341 2343 scripting
2342 2344 </a>
2343 2345 </td><td>
2344 2346 Using Mercurial from scripts and automation
2345 2347 </td></tr>
2346 2348 <tr><td>
2347 2349 <a href="/help/subrepos">
2348 2350 subrepos
2349 2351 </a>
2350 2352 </td><td>
2351 2353 Subrepositories
2352 2354 </td></tr>
2353 2355 <tr><td>
2354 2356 <a href="/help/templating">
2355 2357 templating
2356 2358 </a>
2357 2359 </td><td>
2358 2360 Template Usage
2359 2361 </td></tr>
2360 2362 <tr><td>
2361 2363 <a href="/help/urls">
2362 2364 urls
2363 2365 </a>
2364 2366 </td><td>
2365 2367 URL Paths
2366 2368 </td></tr>
2367 2369 <tr><td>
2368 2370 <a href="/help/topic-containing-verbose">
2369 2371 topic-containing-verbose
2370 2372 </a>
2371 2373 </td><td>
2372 2374 This is the topic to test omit indicating.
2373 2375 </td></tr>
2374 2376
2375 2377
2376 2378 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2377 2379
2378 2380 <tr><td>
2379 2381 <a href="/help/abort">
2380 2382 abort
2381 2383 </a>
2382 2384 </td><td>
2383 2385 abort an unfinished operation (EXPERIMENTAL)
2384 2386 </td></tr>
2385 2387 <tr><td>
2386 2388 <a href="/help/add">
2387 2389 add
2388 2390 </a>
2389 2391 </td><td>
2390 2392 add the specified files on the next commit
2391 2393 </td></tr>
2392 2394 <tr><td>
2393 2395 <a href="/help/annotate">
2394 2396 annotate
2395 2397 </a>
2396 2398 </td><td>
2397 2399 show changeset information by line for each file
2398 2400 </td></tr>
2399 2401 <tr><td>
2400 2402 <a href="/help/clone">
2401 2403 clone
2402 2404 </a>
2403 2405 </td><td>
2404 2406 make a copy of an existing repository
2405 2407 </td></tr>
2406 2408 <tr><td>
2407 2409 <a href="/help/commit">
2408 2410 commit
2409 2411 </a>
2410 2412 </td><td>
2411 2413 commit the specified files or all outstanding changes
2412 2414 </td></tr>
2413 2415 <tr><td>
2414 2416 <a href="/help/continue">
2415 2417 continue
2416 2418 </a>
2417 2419 </td><td>
2418 2420 resumes an interrupted operation (EXPERIMENTAL)
2419 2421 </td></tr>
2420 2422 <tr><td>
2421 2423 <a href="/help/diff">
2422 2424 diff
2423 2425 </a>
2424 2426 </td><td>
2425 2427 diff repository (or selected files)
2426 2428 </td></tr>
2427 2429 <tr><td>
2428 2430 <a href="/help/export">
2429 2431 export
2430 2432 </a>
2431 2433 </td><td>
2432 2434 dump the header and diffs for one or more changesets
2433 2435 </td></tr>
2434 2436 <tr><td>
2435 2437 <a href="/help/forget">
2436 2438 forget
2437 2439 </a>
2438 2440 </td><td>
2439 2441 forget the specified files on the next commit
2440 2442 </td></tr>
2441 2443 <tr><td>
2442 2444 <a href="/help/init">
2443 2445 init
2444 2446 </a>
2445 2447 </td><td>
2446 2448 create a new repository in the given directory
2447 2449 </td></tr>
2448 2450 <tr><td>
2449 2451 <a href="/help/log">
2450 2452 log
2451 2453 </a>
2452 2454 </td><td>
2453 2455 show revision history of entire repository or files
2454 2456 </td></tr>
2455 2457 <tr><td>
2456 2458 <a href="/help/merge">
2457 2459 merge
2458 2460 </a>
2459 2461 </td><td>
2460 2462 merge another revision into working directory
2461 2463 </td></tr>
2462 2464 <tr><td>
2463 2465 <a href="/help/pull">
2464 2466 pull
2465 2467 </a>
2466 2468 </td><td>
2467 2469 pull changes from the specified source
2468 2470 </td></tr>
2469 2471 <tr><td>
2470 2472 <a href="/help/push">
2471 2473 push
2472 2474 </a>
2473 2475 </td><td>
2474 2476 push changes to the specified destination
2475 2477 </td></tr>
2476 2478 <tr><td>
2477 2479 <a href="/help/remove">
2478 2480 remove
2479 2481 </a>
2480 2482 </td><td>
2481 2483 remove the specified files on the next commit
2482 2484 </td></tr>
2483 2485 <tr><td>
2484 2486 <a href="/help/serve">
2485 2487 serve
2486 2488 </a>
2487 2489 </td><td>
2488 2490 start stand-alone webserver
2489 2491 </td></tr>
2490 2492 <tr><td>
2491 2493 <a href="/help/status">
2492 2494 status
2493 2495 </a>
2494 2496 </td><td>
2495 2497 show changed files in the working directory
2496 2498 </td></tr>
2497 2499 <tr><td>
2498 2500 <a href="/help/summary">
2499 2501 summary
2500 2502 </a>
2501 2503 </td><td>
2502 2504 summarize working directory state
2503 2505 </td></tr>
2504 2506 <tr><td>
2505 2507 <a href="/help/update">
2506 2508 update
2507 2509 </a>
2508 2510 </td><td>
2509 2511 update working directory (or switch revisions)
2510 2512 </td></tr>
2511 2513
2512 2514
2513 2515
2514 2516 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2515 2517
2516 2518 <tr><td>
2517 2519 <a href="/help/addremove">
2518 2520 addremove
2519 2521 </a>
2520 2522 </td><td>
2521 2523 add all new files, delete all missing files
2522 2524 </td></tr>
2523 2525 <tr><td>
2524 2526 <a href="/help/archive">
2525 2527 archive
2526 2528 </a>
2527 2529 </td><td>
2528 2530 create an unversioned archive of a repository revision
2529 2531 </td></tr>
2530 2532 <tr><td>
2531 2533 <a href="/help/backout">
2532 2534 backout
2533 2535 </a>
2534 2536 </td><td>
2535 2537 reverse effect of earlier changeset
2536 2538 </td></tr>
2537 2539 <tr><td>
2538 2540 <a href="/help/bisect">
2539 2541 bisect
2540 2542 </a>
2541 2543 </td><td>
2542 2544 subdivision search of changesets
2543 2545 </td></tr>
2544 2546 <tr><td>
2545 2547 <a href="/help/bookmarks">
2546 2548 bookmarks
2547 2549 </a>
2548 2550 </td><td>
2549 2551 create a new bookmark or list existing bookmarks
2550 2552 </td></tr>
2551 2553 <tr><td>
2552 2554 <a href="/help/branch">
2553 2555 branch
2554 2556 </a>
2555 2557 </td><td>
2556 2558 set or show the current branch name
2557 2559 </td></tr>
2558 2560 <tr><td>
2559 2561 <a href="/help/branches">
2560 2562 branches
2561 2563 </a>
2562 2564 </td><td>
2563 2565 list repository named branches
2564 2566 </td></tr>
2565 2567 <tr><td>
2566 2568 <a href="/help/bundle">
2567 2569 bundle
2568 2570 </a>
2569 2571 </td><td>
2570 2572 create a bundle file
2571 2573 </td></tr>
2572 2574 <tr><td>
2573 2575 <a href="/help/cat">
2574 2576 cat
2575 2577 </a>
2576 2578 </td><td>
2577 2579 output the current or given revision of files
2578 2580 </td></tr>
2579 2581 <tr><td>
2580 2582 <a href="/help/config">
2581 2583 config
2582 2584 </a>
2583 2585 </td><td>
2584 2586 show combined config settings from all hgrc files
2585 2587 </td></tr>
2586 2588 <tr><td>
2587 2589 <a href="/help/copy">
2588 2590 copy
2589 2591 </a>
2590 2592 </td><td>
2591 2593 mark files as copied for the next commit
2592 2594 </td></tr>
2593 2595 <tr><td>
2594 2596 <a href="/help/files">
2595 2597 files
2596 2598 </a>
2597 2599 </td><td>
2598 2600 list tracked files
2599 2601 </td></tr>
2600 2602 <tr><td>
2601 2603 <a href="/help/graft">
2602 2604 graft
2603 2605 </a>
2604 2606 </td><td>
2605 2607 copy changes from other branches onto the current branch
2606 2608 </td></tr>
2607 2609 <tr><td>
2608 2610 <a href="/help/grep">
2609 2611 grep
2610 2612 </a>
2611 2613 </td><td>
2612 2614 search for a pattern in specified files
2613 2615 </td></tr>
2614 2616 <tr><td>
2615 2617 <a href="/help/hashelp">
2616 2618 hashelp
2617 2619 </a>
2618 2620 </td><td>
2619 2621 Extension command's help
2620 2622 </td></tr>
2621 2623 <tr><td>
2622 2624 <a href="/help/heads">
2623 2625 heads
2624 2626 </a>
2625 2627 </td><td>
2626 2628 show branch heads
2627 2629 </td></tr>
2628 2630 <tr><td>
2629 2631 <a href="/help/help">
2630 2632 help
2631 2633 </a>
2632 2634 </td><td>
2633 2635 show help for a given topic or a help overview
2634 2636 </td></tr>
2635 2637 <tr><td>
2636 2638 <a href="/help/hgalias">
2637 2639 hgalias
2638 2640 </a>
2639 2641 </td><td>
2640 2642 My doc
2641 2643 </td></tr>
2642 2644 <tr><td>
2643 2645 <a href="/help/hgaliasnodoc">
2644 2646 hgaliasnodoc
2645 2647 </a>
2646 2648 </td><td>
2647 2649 summarize working directory state
2648 2650 </td></tr>
2649 2651 <tr><td>
2650 2652 <a href="/help/identify">
2651 2653 identify
2652 2654 </a>
2653 2655 </td><td>
2654 2656 identify the working directory or specified revision
2655 2657 </td></tr>
2656 2658 <tr><td>
2657 2659 <a href="/help/import">
2658 2660 import
2659 2661 </a>
2660 2662 </td><td>
2661 2663 import an ordered set of patches
2662 2664 </td></tr>
2663 2665 <tr><td>
2664 2666 <a href="/help/incoming">
2665 2667 incoming
2666 2668 </a>
2667 2669 </td><td>
2668 2670 show new changesets found in source
2669 2671 </td></tr>
2670 2672 <tr><td>
2671 2673 <a href="/help/manifest">
2672 2674 manifest
2673 2675 </a>
2674 2676 </td><td>
2675 2677 output the current or given revision of the project manifest
2676 2678 </td></tr>
2677 2679 <tr><td>
2678 2680 <a href="/help/nohelp">
2679 2681 nohelp
2680 2682 </a>
2681 2683 </td><td>
2682 2684 (no help text available)
2683 2685 </td></tr>
2684 2686 <tr><td>
2685 2687 <a href="/help/outgoing">
2686 2688 outgoing
2687 2689 </a>
2688 2690 </td><td>
2689 2691 show changesets not found in the destination
2690 2692 </td></tr>
2691 2693 <tr><td>
2692 2694 <a href="/help/paths">
2693 2695 paths
2694 2696 </a>
2695 2697 </td><td>
2696 2698 show aliases for remote repositories
2697 2699 </td></tr>
2698 2700 <tr><td>
2699 2701 <a href="/help/phase">
2700 2702 phase
2701 2703 </a>
2702 2704 </td><td>
2703 2705 set or show the current phase name
2704 2706 </td></tr>
2705 2707 <tr><td>
2706 2708 <a href="/help/recover">
2707 2709 recover
2708 2710 </a>
2709 2711 </td><td>
2710 2712 roll back an interrupted transaction
2711 2713 </td></tr>
2712 2714 <tr><td>
2713 2715 <a href="/help/rename">
2714 2716 rename
2715 2717 </a>
2716 2718 </td><td>
2717 2719 rename files; equivalent of copy + remove
2718 2720 </td></tr>
2719 2721 <tr><td>
2720 2722 <a href="/help/resolve">
2721 2723 resolve
2722 2724 </a>
2723 2725 </td><td>
2724 2726 redo merges or set/view the merge status of files
2725 2727 </td></tr>
2726 2728 <tr><td>
2727 2729 <a href="/help/revert">
2728 2730 revert
2729 2731 </a>
2730 2732 </td><td>
2731 2733 restore files to their checkout state
2732 2734 </td></tr>
2733 2735 <tr><td>
2734 2736 <a href="/help/root">
2735 2737 root
2736 2738 </a>
2737 2739 </td><td>
2738 2740 print the root (top) of the current working directory
2739 2741 </td></tr>
2740 2742 <tr><td>
2741 2743 <a href="/help/shellalias">
2742 2744 shellalias
2743 2745 </a>
2744 2746 </td><td>
2745 2747 (no help text available)
2746 2748 </td></tr>
2747 2749 <tr><td>
2748 2750 <a href="/help/shelve">
2749 2751 shelve
2750 2752 </a>
2751 2753 </td><td>
2752 2754 save and set aside changes from the working directory
2753 2755 </td></tr>
2754 2756 <tr><td>
2755 2757 <a href="/help/tag">
2756 2758 tag
2757 2759 </a>
2758 2760 </td><td>
2759 2761 add one or more tags for the current or given revision
2760 2762 </td></tr>
2761 2763 <tr><td>
2762 2764 <a href="/help/tags">
2763 2765 tags
2764 2766 </a>
2765 2767 </td><td>
2766 2768 list repository tags
2767 2769 </td></tr>
2768 2770 <tr><td>
2769 2771 <a href="/help/unbundle">
2770 2772 unbundle
2771 2773 </a>
2772 2774 </td><td>
2773 2775 apply one or more bundle files
2774 2776 </td></tr>
2775 2777 <tr><td>
2776 2778 <a href="/help/unshelve">
2777 2779 unshelve
2778 2780 </a>
2779 2781 </td><td>
2780 2782 restore a shelved change to the working directory
2781 2783 </td></tr>
2782 2784 <tr><td>
2783 2785 <a href="/help/verify">
2784 2786 verify
2785 2787 </a>
2786 2788 </td><td>
2787 2789 verify the integrity of the repository
2788 2790 </td></tr>
2789 2791 <tr><td>
2790 2792 <a href="/help/version">
2791 2793 version
2792 2794 </a>
2793 2795 </td><td>
2794 2796 output version and copyright information
2795 2797 </td></tr>
2796 2798
2797 2799
2798 2800 </table>
2799 2801 </div>
2800 2802 </div>
2801 2803
2802 2804
2803 2805
2804 2806 </body>
2805 2807 </html>
2806 2808
2807 2809
2808 2810 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2809 2811 200 Script output follows
2810 2812
2811 2813 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2812 2814 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2813 2815 <head>
2814 2816 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2815 2817 <meta name="robots" content="index, nofollow" />
2816 2818 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2817 2819 <script type="text/javascript" src="/static/mercurial.js"></script>
2818 2820
2819 2821 <title>Help: add</title>
2820 2822 </head>
2821 2823 <body>
2822 2824
2823 2825 <div class="container">
2824 2826 <div class="menu">
2825 2827 <div class="logo">
2826 2828 <a href="https://mercurial-scm.org/">
2827 2829 <img src="/static/hglogo.png" alt="mercurial" /></a>
2828 2830 </div>
2829 2831 <ul>
2830 2832 <li><a href="/shortlog">log</a></li>
2831 2833 <li><a href="/graph">graph</a></li>
2832 2834 <li><a href="/tags">tags</a></li>
2833 2835 <li><a href="/bookmarks">bookmarks</a></li>
2834 2836 <li><a href="/branches">branches</a></li>
2835 2837 </ul>
2836 2838 <ul>
2837 2839 <li class="active"><a href="/help">help</a></li>
2838 2840 </ul>
2839 2841 </div>
2840 2842
2841 2843 <div class="main">
2842 2844 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2843 2845 <h3>Help: add</h3>
2844 2846
2845 2847 <form class="search" action="/log">
2846 2848
2847 2849 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2848 2850 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2849 2851 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2850 2852 </form>
2851 2853 <div id="doc">
2852 2854 <p>
2853 2855 hg add [OPTION]... [FILE]...
2854 2856 </p>
2855 2857 <p>
2856 2858 add the specified files on the next commit
2857 2859 </p>
2858 2860 <p>
2859 2861 Schedule files to be version controlled and added to the
2860 2862 repository.
2861 2863 </p>
2862 2864 <p>
2863 2865 The files will be added to the repository at the next commit. To
2864 2866 undo an add before that, see 'hg forget'.
2865 2867 </p>
2866 2868 <p>
2867 2869 If no names are given, add all files to the repository (except
2868 2870 files matching &quot;.hgignore&quot;).
2869 2871 </p>
2870 2872 <p>
2871 2873 Examples:
2872 2874 </p>
2873 2875 <ul>
2874 2876 <li> New (unknown) files are added automatically by 'hg add':
2875 2877 <pre>
2876 2878 \$ ls (re)
2877 2879 foo.c
2878 2880 \$ hg status (re)
2879 2881 ? foo.c
2880 2882 \$ hg add (re)
2881 2883 adding foo.c
2882 2884 \$ hg status (re)
2883 2885 A foo.c
2884 2886 </pre>
2885 2887 <li> Specific files to be added can be specified:
2886 2888 <pre>
2887 2889 \$ ls (re)
2888 2890 bar.c foo.c
2889 2891 \$ hg status (re)
2890 2892 ? bar.c
2891 2893 ? foo.c
2892 2894 \$ hg add bar.c (re)
2893 2895 \$ hg status (re)
2894 2896 A bar.c
2895 2897 ? foo.c
2896 2898 </pre>
2897 2899 </ul>
2898 2900 <p>
2899 2901 Returns 0 if all files are successfully added.
2900 2902 </p>
2901 2903 <p>
2902 2904 options ([+] can be repeated):
2903 2905 </p>
2904 2906 <table>
2905 2907 <tr><td>-I</td>
2906 2908 <td>--include PATTERN [+]</td>
2907 2909 <td>include names matching the given patterns</td></tr>
2908 2910 <tr><td>-X</td>
2909 2911 <td>--exclude PATTERN [+]</td>
2910 2912 <td>exclude names matching the given patterns</td></tr>
2911 2913 <tr><td>-S</td>
2912 2914 <td>--subrepos</td>
2913 2915 <td>recurse into subrepositories</td></tr>
2914 2916 <tr><td>-n</td>
2915 2917 <td>--dry-run</td>
2916 2918 <td>do not perform actions, just print output</td></tr>
2917 2919 </table>
2918 2920 <p>
2919 2921 global options ([+] can be repeated):
2920 2922 </p>
2921 2923 <table>
2922 2924 <tr><td>-R</td>
2923 2925 <td>--repository REPO</td>
2924 2926 <td>repository root directory or name of overlay bundle file</td></tr>
2925 2927 <tr><td></td>
2926 2928 <td>--cwd DIR</td>
2927 2929 <td>change working directory</td></tr>
2928 2930 <tr><td>-y</td>
2929 2931 <td>--noninteractive</td>
2930 2932 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2931 2933 <tr><td>-q</td>
2932 2934 <td>--quiet</td>
2933 2935 <td>suppress output</td></tr>
2934 2936 <tr><td>-v</td>
2935 2937 <td>--verbose</td>
2936 2938 <td>enable additional output</td></tr>
2937 2939 <tr><td></td>
2938 2940 <td>--color TYPE</td>
2939 2941 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2940 2942 <tr><td></td>
2941 2943 <td>--config CONFIG [+]</td>
2942 2944 <td>set/override config option (use 'section.name=value')</td></tr>
2943 2945 <tr><td></td>
2944 2946 <td>--debug</td>
2945 2947 <td>enable debugging output</td></tr>
2946 2948 <tr><td></td>
2947 2949 <td>--debugger</td>
2948 2950 <td>start debugger</td></tr>
2949 2951 <tr><td></td>
2950 2952 <td>--encoding ENCODE</td>
2951 2953 <td>set the charset encoding (default: ascii)</td></tr>
2952 2954 <tr><td></td>
2953 2955 <td>--encodingmode MODE</td>
2954 2956 <td>set the charset encoding mode (default: strict)</td></tr>
2955 2957 <tr><td></td>
2956 2958 <td>--traceback</td>
2957 2959 <td>always print a traceback on exception</td></tr>
2958 2960 <tr><td></td>
2959 2961 <td>--time</td>
2960 2962 <td>time how long the command takes</td></tr>
2961 2963 <tr><td></td>
2962 2964 <td>--profile</td>
2963 2965 <td>print command execution profile</td></tr>
2964 2966 <tr><td></td>
2965 2967 <td>--version</td>
2966 2968 <td>output version information and exit</td></tr>
2967 2969 <tr><td>-h</td>
2968 2970 <td>--help</td>
2969 2971 <td>display help and exit</td></tr>
2970 2972 <tr><td></td>
2971 2973 <td>--hidden</td>
2972 2974 <td>consider hidden changesets</td></tr>
2973 2975 <tr><td></td>
2974 2976 <td>--pager TYPE</td>
2975 2977 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2976 2978 </table>
2977 2979
2978 2980 </div>
2979 2981 </div>
2980 2982 </div>
2981 2983
2982 2984
2983 2985
2984 2986 </body>
2985 2987 </html>
2986 2988
2987 2989
2988 2990 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2989 2991 200 Script output follows
2990 2992
2991 2993 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2992 2994 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2993 2995 <head>
2994 2996 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2995 2997 <meta name="robots" content="index, nofollow" />
2996 2998 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2997 2999 <script type="text/javascript" src="/static/mercurial.js"></script>
2998 3000
2999 3001 <title>Help: remove</title>
3000 3002 </head>
3001 3003 <body>
3002 3004
3003 3005 <div class="container">
3004 3006 <div class="menu">
3005 3007 <div class="logo">
3006 3008 <a href="https://mercurial-scm.org/">
3007 3009 <img src="/static/hglogo.png" alt="mercurial" /></a>
3008 3010 </div>
3009 3011 <ul>
3010 3012 <li><a href="/shortlog">log</a></li>
3011 3013 <li><a href="/graph">graph</a></li>
3012 3014 <li><a href="/tags">tags</a></li>
3013 3015 <li><a href="/bookmarks">bookmarks</a></li>
3014 3016 <li><a href="/branches">branches</a></li>
3015 3017 </ul>
3016 3018 <ul>
3017 3019 <li class="active"><a href="/help">help</a></li>
3018 3020 </ul>
3019 3021 </div>
3020 3022
3021 3023 <div class="main">
3022 3024 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3023 3025 <h3>Help: remove</h3>
3024 3026
3025 3027 <form class="search" action="/log">
3026 3028
3027 3029 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3028 3030 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3029 3031 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3030 3032 </form>
3031 3033 <div id="doc">
3032 3034 <p>
3033 3035 hg remove [OPTION]... FILE...
3034 3036 </p>
3035 3037 <p>
3036 3038 aliases: rm
3037 3039 </p>
3038 3040 <p>
3039 3041 remove the specified files on the next commit
3040 3042 </p>
3041 3043 <p>
3042 3044 Schedule the indicated files for removal from the current branch.
3043 3045 </p>
3044 3046 <p>
3045 3047 This command schedules the files to be removed at the next commit.
3046 3048 To undo a remove before that, see 'hg revert'. To undo added
3047 3049 files, see 'hg forget'.
3048 3050 </p>
3049 3051 <p>
3050 3052 -A/--after can be used to remove only files that have already
3051 3053 been deleted, -f/--force can be used to force deletion, and -Af
3052 3054 can be used to remove files from the next revision without
3053 3055 deleting them from the working directory.
3054 3056 </p>
3055 3057 <p>
3056 3058 The following table details the behavior of remove for different
3057 3059 file states (columns) and option combinations (rows). The file
3058 3060 states are Added [A], Clean [C], Modified [M] and Missing [!]
3059 3061 (as reported by 'hg status'). The actions are Warn, Remove
3060 3062 (from branch) and Delete (from disk):
3061 3063 </p>
3062 3064 <table>
3063 3065 <tr><td>opt/state</td>
3064 3066 <td>A</td>
3065 3067 <td>C</td>
3066 3068 <td>M</td>
3067 3069 <td>!</td></tr>
3068 3070 <tr><td>none</td>
3069 3071 <td>W</td>
3070 3072 <td>RD</td>
3071 3073 <td>W</td>
3072 3074 <td>R</td></tr>
3073 3075 <tr><td>-f</td>
3074 3076 <td>R</td>
3075 3077 <td>RD</td>
3076 3078 <td>RD</td>
3077 3079 <td>R</td></tr>
3078 3080 <tr><td>-A</td>
3079 3081 <td>W</td>
3080 3082 <td>W</td>
3081 3083 <td>W</td>
3082 3084 <td>R</td></tr>
3083 3085 <tr><td>-Af</td>
3084 3086 <td>R</td>
3085 3087 <td>R</td>
3086 3088 <td>R</td>
3087 3089 <td>R</td></tr>
3088 3090 </table>
3089 3091 <p>
3090 3092 <b>Note:</b>
3091 3093 </p>
3092 3094 <p>
3093 3095 'hg remove' never deletes files in Added [A] state from the
3094 3096 working directory, not even if &quot;--force&quot; is specified.
3095 3097 </p>
3096 3098 <p>
3097 3099 Returns 0 on success, 1 if any warnings encountered.
3098 3100 </p>
3099 3101 <p>
3100 3102 options ([+] can be repeated):
3101 3103 </p>
3102 3104 <table>
3103 3105 <tr><td>-A</td>
3104 3106 <td>--after</td>
3105 3107 <td>record delete for missing files</td></tr>
3106 3108 <tr><td>-f</td>
3107 3109 <td>--force</td>
3108 3110 <td>forget added files, delete modified files</td></tr>
3109 3111 <tr><td>-S</td>
3110 3112 <td>--subrepos</td>
3111 3113 <td>recurse into subrepositories</td></tr>
3112 3114 <tr><td>-I</td>
3113 3115 <td>--include PATTERN [+]</td>
3114 3116 <td>include names matching the given patterns</td></tr>
3115 3117 <tr><td>-X</td>
3116 3118 <td>--exclude PATTERN [+]</td>
3117 3119 <td>exclude names matching the given patterns</td></tr>
3118 3120 <tr><td>-n</td>
3119 3121 <td>--dry-run</td>
3120 3122 <td>do not perform actions, just print output</td></tr>
3121 3123 </table>
3122 3124 <p>
3123 3125 global options ([+] can be repeated):
3124 3126 </p>
3125 3127 <table>
3126 3128 <tr><td>-R</td>
3127 3129 <td>--repository REPO</td>
3128 3130 <td>repository root directory or name of overlay bundle file</td></tr>
3129 3131 <tr><td></td>
3130 3132 <td>--cwd DIR</td>
3131 3133 <td>change working directory</td></tr>
3132 3134 <tr><td>-y</td>
3133 3135 <td>--noninteractive</td>
3134 3136 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3135 3137 <tr><td>-q</td>
3136 3138 <td>--quiet</td>
3137 3139 <td>suppress output</td></tr>
3138 3140 <tr><td>-v</td>
3139 3141 <td>--verbose</td>
3140 3142 <td>enable additional output</td></tr>
3141 3143 <tr><td></td>
3142 3144 <td>--color TYPE</td>
3143 3145 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3144 3146 <tr><td></td>
3145 3147 <td>--config CONFIG [+]</td>
3146 3148 <td>set/override config option (use 'section.name=value')</td></tr>
3147 3149 <tr><td></td>
3148 3150 <td>--debug</td>
3149 3151 <td>enable debugging output</td></tr>
3150 3152 <tr><td></td>
3151 3153 <td>--debugger</td>
3152 3154 <td>start debugger</td></tr>
3153 3155 <tr><td></td>
3154 3156 <td>--encoding ENCODE</td>
3155 3157 <td>set the charset encoding (default: ascii)</td></tr>
3156 3158 <tr><td></td>
3157 3159 <td>--encodingmode MODE</td>
3158 3160 <td>set the charset encoding mode (default: strict)</td></tr>
3159 3161 <tr><td></td>
3160 3162 <td>--traceback</td>
3161 3163 <td>always print a traceback on exception</td></tr>
3162 3164 <tr><td></td>
3163 3165 <td>--time</td>
3164 3166 <td>time how long the command takes</td></tr>
3165 3167 <tr><td></td>
3166 3168 <td>--profile</td>
3167 3169 <td>print command execution profile</td></tr>
3168 3170 <tr><td></td>
3169 3171 <td>--version</td>
3170 3172 <td>output version information and exit</td></tr>
3171 3173 <tr><td>-h</td>
3172 3174 <td>--help</td>
3173 3175 <td>display help and exit</td></tr>
3174 3176 <tr><td></td>
3175 3177 <td>--hidden</td>
3176 3178 <td>consider hidden changesets</td></tr>
3177 3179 <tr><td></td>
3178 3180 <td>--pager TYPE</td>
3179 3181 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3180 3182 </table>
3181 3183
3182 3184 </div>
3183 3185 </div>
3184 3186 </div>
3185 3187
3186 3188
3187 3189
3188 3190 </body>
3189 3191 </html>
3190 3192
3191 3193
3192 3194 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3193 3195 200 Script output follows
3194 3196
3195 3197 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3196 3198 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3197 3199 <head>
3198 3200 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3199 3201 <meta name="robots" content="index, nofollow" />
3200 3202 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3201 3203 <script type="text/javascript" src="/static/mercurial.js"></script>
3202 3204
3203 3205 <title>Help: dates</title>
3204 3206 </head>
3205 3207 <body>
3206 3208
3207 3209 <div class="container">
3208 3210 <div class="menu">
3209 3211 <div class="logo">
3210 3212 <a href="https://mercurial-scm.org/">
3211 3213 <img src="/static/hglogo.png" alt="mercurial" /></a>
3212 3214 </div>
3213 3215 <ul>
3214 3216 <li><a href="/shortlog">log</a></li>
3215 3217 <li><a href="/graph">graph</a></li>
3216 3218 <li><a href="/tags">tags</a></li>
3217 3219 <li><a href="/bookmarks">bookmarks</a></li>
3218 3220 <li><a href="/branches">branches</a></li>
3219 3221 </ul>
3220 3222 <ul>
3221 3223 <li class="active"><a href="/help">help</a></li>
3222 3224 </ul>
3223 3225 </div>
3224 3226
3225 3227 <div class="main">
3226 3228 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3227 3229 <h3>Help: dates</h3>
3228 3230
3229 3231 <form class="search" action="/log">
3230 3232
3231 3233 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3232 3234 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3233 3235 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3234 3236 </form>
3235 3237 <div id="doc">
3236 3238 <h1>Date Formats</h1>
3237 3239 <p>
3238 3240 Some commands allow the user to specify a date, e.g.:
3239 3241 </p>
3240 3242 <ul>
3241 3243 <li> backout, commit, import, tag: Specify the commit date.
3242 3244 <li> log, revert, update: Select revision(s) by date.
3243 3245 </ul>
3244 3246 <p>
3245 3247 Many date formats are valid. Here are some examples:
3246 3248 </p>
3247 3249 <ul>
3248 3250 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3249 3251 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3250 3252 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3251 3253 <li> &quot;Dec 6&quot; (midnight)
3252 3254 <li> &quot;13:18&quot; (today assumed)
3253 3255 <li> &quot;3:39&quot; (3:39AM assumed)
3254 3256 <li> &quot;3:39pm&quot; (15:39)
3255 3257 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3256 3258 <li> &quot;2006-12-6 13:18&quot;
3257 3259 <li> &quot;2006-12-6&quot;
3258 3260 <li> &quot;12-6&quot;
3259 3261 <li> &quot;12/6&quot;
3260 3262 <li> &quot;12/6/6&quot; (Dec 6 2006)
3261 3263 <li> &quot;today&quot; (midnight)
3262 3264 <li> &quot;yesterday&quot; (midnight)
3263 3265 <li> &quot;now&quot; - right now
3264 3266 </ul>
3265 3267 <p>
3266 3268 Lastly, there is Mercurial's internal format:
3267 3269 </p>
3268 3270 <ul>
3269 3271 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3270 3272 </ul>
3271 3273 <p>
3272 3274 This is the internal representation format for dates. The first number
3273 3275 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3274 3276 second is the offset of the local timezone, in seconds west of UTC
3275 3277 (negative if the timezone is east of UTC).
3276 3278 </p>
3277 3279 <p>
3278 3280 The log command also accepts date ranges:
3279 3281 </p>
3280 3282 <ul>
3281 3283 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3282 3284 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3283 3285 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3284 3286 <li> &quot;-DAYS&quot; - within a given number of days from today
3285 3287 </ul>
3286 3288
3287 3289 </div>
3288 3290 </div>
3289 3291 </div>
3290 3292
3291 3293
3292 3294
3293 3295 </body>
3294 3296 </html>
3295 3297
3296 3298
3297 3299 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3298 3300 200 Script output follows
3299 3301
3300 3302 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3301 3303 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3302 3304 <head>
3303 3305 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3304 3306 <meta name="robots" content="index, nofollow" />
3305 3307 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3306 3308 <script type="text/javascript" src="/static/mercurial.js"></script>
3307 3309
3308 3310 <title>Help: pager</title>
3309 3311 </head>
3310 3312 <body>
3311 3313
3312 3314 <div class="container">
3313 3315 <div class="menu">
3314 3316 <div class="logo">
3315 3317 <a href="https://mercurial-scm.org/">
3316 3318 <img src="/static/hglogo.png" alt="mercurial" /></a>
3317 3319 </div>
3318 3320 <ul>
3319 3321 <li><a href="/shortlog">log</a></li>
3320 3322 <li><a href="/graph">graph</a></li>
3321 3323 <li><a href="/tags">tags</a></li>
3322 3324 <li><a href="/bookmarks">bookmarks</a></li>
3323 3325 <li><a href="/branches">branches</a></li>
3324 3326 </ul>
3325 3327 <ul>
3326 3328 <li class="active"><a href="/help">help</a></li>
3327 3329 </ul>
3328 3330 </div>
3329 3331
3330 3332 <div class="main">
3331 3333 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3332 3334 <h3>Help: pager</h3>
3333 3335
3334 3336 <form class="search" action="/log">
3335 3337
3336 3338 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3337 3339 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3338 3340 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3339 3341 </form>
3340 3342 <div id="doc">
3341 3343 <h1>Pager Support</h1>
3342 3344 <p>
3343 3345 Some Mercurial commands can produce a lot of output, and Mercurial will
3344 3346 attempt to use a pager to make those commands more pleasant.
3345 3347 </p>
3346 3348 <p>
3347 3349 To set the pager that should be used, set the application variable:
3348 3350 </p>
3349 3351 <pre>
3350 3352 [pager]
3351 3353 pager = less -FRX
3352 3354 </pre>
3353 3355 <p>
3354 3356 If no pager is set in the user or repository configuration, Mercurial uses the
3355 3357 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3356 3358 or system configuration is used. If none of these are set, a default pager will
3357 3359 be used, typically 'less' on Unix and 'more' on Windows.
3358 3360 </p>
3359 3361 <p>
3360 3362 You can disable the pager for certain commands by adding them to the
3361 3363 pager.ignore list:
3362 3364 </p>
3363 3365 <pre>
3364 3366 [pager]
3365 3367 ignore = version, help, update
3366 3368 </pre>
3367 3369 <p>
3368 3370 To ignore global commands like 'hg version' or 'hg help', you have
3369 3371 to specify them in your user configuration file.
3370 3372 </p>
3371 3373 <p>
3372 3374 To control whether the pager is used at all for an individual command,
3373 3375 you can use --pager=&lt;value&gt;:
3374 3376 </p>
3375 3377 <ul>
3376 3378 <li> use as needed: 'auto'.
3377 3379 <li> require the pager: 'yes' or 'on'.
3378 3380 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3379 3381 </ul>
3380 3382 <p>
3381 3383 To globally turn off all attempts to use a pager, set:
3382 3384 </p>
3383 3385 <pre>
3384 3386 [ui]
3385 3387 paginate = never
3386 3388 </pre>
3387 3389 <p>
3388 3390 which will prevent the pager from running.
3389 3391 </p>
3390 3392
3391 3393 </div>
3392 3394 </div>
3393 3395 </div>
3394 3396
3395 3397
3396 3398
3397 3399 </body>
3398 3400 </html>
3399 3401
3400 3402
3401 3403 Sub-topic indexes rendered properly
3402 3404
3403 3405 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3404 3406 200 Script output follows
3405 3407
3406 3408 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3407 3409 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3408 3410 <head>
3409 3411 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3410 3412 <meta name="robots" content="index, nofollow" />
3411 3413 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3412 3414 <script type="text/javascript" src="/static/mercurial.js"></script>
3413 3415
3414 3416 <title>Help: internals</title>
3415 3417 </head>
3416 3418 <body>
3417 3419
3418 3420 <div class="container">
3419 3421 <div class="menu">
3420 3422 <div class="logo">
3421 3423 <a href="https://mercurial-scm.org/">
3422 3424 <img src="/static/hglogo.png" alt="mercurial" /></a>
3423 3425 </div>
3424 3426 <ul>
3425 3427 <li><a href="/shortlog">log</a></li>
3426 3428 <li><a href="/graph">graph</a></li>
3427 3429 <li><a href="/tags">tags</a></li>
3428 3430 <li><a href="/bookmarks">bookmarks</a></li>
3429 3431 <li><a href="/branches">branches</a></li>
3430 3432 </ul>
3431 3433 <ul>
3432 3434 <li><a href="/help">help</a></li>
3433 3435 </ul>
3434 3436 </div>
3435 3437
3436 3438 <div class="main">
3437 3439 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3438 3440
3439 3441 <form class="search" action="/log">
3440 3442
3441 3443 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3442 3444 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3443 3445 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3444 3446 </form>
3445 3447 <table class="bigtable">
3446 3448 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3447 3449
3448 3450 <tr><td>
3449 3451 <a href="/help/internals.bid-merge">
3450 3452 bid-merge
3451 3453 </a>
3452 3454 </td><td>
3453 3455 Bid Merge Algorithm
3454 3456 </td></tr>
3455 3457 <tr><td>
3456 3458 <a href="/help/internals.bundle2">
3457 3459 bundle2
3458 3460 </a>
3459 3461 </td><td>
3460 3462 Bundle2
3461 3463 </td></tr>
3462 3464 <tr><td>
3463 3465 <a href="/help/internals.bundles">
3464 3466 bundles
3465 3467 </a>
3466 3468 </td><td>
3467 3469 Bundles
3468 3470 </td></tr>
3469 3471 <tr><td>
3470 3472 <a href="/help/internals.cbor">
3471 3473 cbor
3472 3474 </a>
3473 3475 </td><td>
3474 3476 CBOR
3475 3477 </td></tr>
3476 3478 <tr><td>
3477 3479 <a href="/help/internals.censor">
3478 3480 censor
3479 3481 </a>
3480 3482 </td><td>
3481 3483 Censor
3482 3484 </td></tr>
3483 3485 <tr><td>
3484 3486 <a href="/help/internals.changegroups">
3485 3487 changegroups
3486 3488 </a>
3487 3489 </td><td>
3488 3490 Changegroups
3489 3491 </td></tr>
3490 3492 <tr><td>
3491 3493 <a href="/help/internals.config">
3492 3494 config
3493 3495 </a>
3494 3496 </td><td>
3495 3497 Config Registrar
3496 3498 </td></tr>
3497 3499 <tr><td>
3498 3500 <a href="/help/internals.extensions">
3499 3501 extensions
3500 3502 </a>
3501 3503 </td><td>
3502 3504 Extension API
3503 3505 </td></tr>
3504 3506 <tr><td>
3505 3507 <a href="/help/internals.mergestate">
3506 3508 mergestate
3507 3509 </a>
3508 3510 </td><td>
3509 3511 Mergestate
3510 3512 </td></tr>
3511 3513 <tr><td>
3512 3514 <a href="/help/internals.requirements">
3513 3515 requirements
3514 3516 </a>
3515 3517 </td><td>
3516 3518 Repository Requirements
3517 3519 </td></tr>
3518 3520 <tr><td>
3519 3521 <a href="/help/internals.revlogs">
3520 3522 revlogs
3521 3523 </a>
3522 3524 </td><td>
3523 3525 Revision Logs
3524 3526 </td></tr>
3525 3527 <tr><td>
3526 3528 <a href="/help/internals.wireprotocol">
3527 3529 wireprotocol
3528 3530 </a>
3529 3531 </td><td>
3530 3532 Wire Protocol
3531 3533 </td></tr>
3532 3534 <tr><td>
3533 3535 <a href="/help/internals.wireprotocolrpc">
3534 3536 wireprotocolrpc
3535 3537 </a>
3536 3538 </td><td>
3537 3539 Wire Protocol RPC
3538 3540 </td></tr>
3539 3541 <tr><td>
3540 3542 <a href="/help/internals.wireprotocolv2">
3541 3543 wireprotocolv2
3542 3544 </a>
3543 3545 </td><td>
3544 3546 Wire Protocol Version 2
3545 3547 </td></tr>
3546 3548
3547 3549
3548 3550
3549 3551
3550 3552
3551 3553 </table>
3552 3554 </div>
3553 3555 </div>
3554 3556
3555 3557
3556 3558
3557 3559 </body>
3558 3560 </html>
3559 3561
3560 3562
3561 3563 Sub-topic topics rendered properly
3562 3564
3563 3565 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3564 3566 200 Script output follows
3565 3567
3566 3568 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3567 3569 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3568 3570 <head>
3569 3571 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3570 3572 <meta name="robots" content="index, nofollow" />
3571 3573 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3572 3574 <script type="text/javascript" src="/static/mercurial.js"></script>
3573 3575
3574 3576 <title>Help: internals.changegroups</title>
3575 3577 </head>
3576 3578 <body>
3577 3579
3578 3580 <div class="container">
3579 3581 <div class="menu">
3580 3582 <div class="logo">
3581 3583 <a href="https://mercurial-scm.org/">
3582 3584 <img src="/static/hglogo.png" alt="mercurial" /></a>
3583 3585 </div>
3584 3586 <ul>
3585 3587 <li><a href="/shortlog">log</a></li>
3586 3588 <li><a href="/graph">graph</a></li>
3587 3589 <li><a href="/tags">tags</a></li>
3588 3590 <li><a href="/bookmarks">bookmarks</a></li>
3589 3591 <li><a href="/branches">branches</a></li>
3590 3592 </ul>
3591 3593 <ul>
3592 3594 <li class="active"><a href="/help">help</a></li>
3593 3595 </ul>
3594 3596 </div>
3595 3597
3596 3598 <div class="main">
3597 3599 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3598 3600 <h3>Help: internals.changegroups</h3>
3599 3601
3600 3602 <form class="search" action="/log">
3601 3603
3602 3604 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3603 3605 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3604 3606 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3605 3607 </form>
3606 3608 <div id="doc">
3607 3609 <h1>Changegroups</h1>
3608 3610 <p>
3609 3611 Changegroups are representations of repository revlog data, specifically
3610 3612 the changelog data, root/flat manifest data, treemanifest data, and
3611 3613 filelogs.
3612 3614 </p>
3613 3615 <p>
3614 3616 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3615 3617 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3616 3618 only difference being an additional item in the *delta header*. Version
3617 3619 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3618 3620 exchanging treemanifests (enabled by setting an option on the
3619 3621 &quot;changegroup&quot; part in the bundle2).
3620 3622 </p>
3621 3623 <p>
3622 3624 Changegroups when not exchanging treemanifests consist of 3 logical
3623 3625 segments:
3624 3626 </p>
3625 3627 <pre>
3626 3628 +---------------------------------+
3627 3629 | | | |
3628 3630 | changeset | manifest | filelogs |
3629 3631 | | | |
3630 3632 | | | |
3631 3633 +---------------------------------+
3632 3634 </pre>
3633 3635 <p>
3634 3636 When exchanging treemanifests, there are 4 logical segments:
3635 3637 </p>
3636 3638 <pre>
3637 3639 +-------------------------------------------------+
3638 3640 | | | | |
3639 3641 | changeset | root | treemanifests | filelogs |
3640 3642 | | manifest | | |
3641 3643 | | | | |
3642 3644 +-------------------------------------------------+
3643 3645 </pre>
3644 3646 <p>
3645 3647 The principle building block of each segment is a *chunk*. A *chunk*
3646 3648 is a framed piece of data:
3647 3649 </p>
3648 3650 <pre>
3649 3651 +---------------------------------------+
3650 3652 | | |
3651 3653 | length | data |
3652 3654 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3653 3655 | | |
3654 3656 +---------------------------------------+
3655 3657 </pre>
3656 3658 <p>
3657 3659 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3658 3660 integer indicating the length of the entire chunk (including the length field
3659 3661 itself).
3660 3662 </p>
3661 3663 <p>
3662 3664 There is a special case chunk that has a value of 0 for the length
3663 3665 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3664 3666 </p>
3665 3667 <h2>Delta Groups</h2>
3666 3668 <p>
3667 3669 A *delta group* expresses the content of a revlog as a series of deltas,
3668 3670 or patches against previous revisions.
3669 3671 </p>
3670 3672 <p>
3671 3673 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3672 3674 to signal the end of the delta group:
3673 3675 </p>
3674 3676 <pre>
3675 3677 +------------------------------------------------------------------------+
3676 3678 | | | | | |
3677 3679 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3678 3680 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3679 3681 | | | | | |
3680 3682 +------------------------------------------------------------------------+
3681 3683 </pre>
3682 3684 <p>
3683 3685 Each *chunk*'s data consists of the following:
3684 3686 </p>
3685 3687 <pre>
3686 3688 +---------------------------------------+
3687 3689 | | |
3688 3690 | delta header | delta data |
3689 3691 | (various by version) | (various) |
3690 3692 | | |
3691 3693 +---------------------------------------+
3692 3694 </pre>
3693 3695 <p>
3694 3696 The *delta data* is a series of *delta*s that describe a diff from an existing
3695 3697 entry (either that the recipient already has, or previously specified in the
3696 3698 bundle/changegroup).
3697 3699 </p>
3698 3700 <p>
3699 3701 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3700 3702 &quot;3&quot; of the changegroup format.
3701 3703 </p>
3702 3704 <p>
3703 3705 Version 1 (headerlen=80):
3704 3706 </p>
3705 3707 <pre>
3706 3708 +------------------------------------------------------+
3707 3709 | | | | |
3708 3710 | node | p1 node | p2 node | link node |
3709 3711 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3710 3712 | | | | |
3711 3713 +------------------------------------------------------+
3712 3714 </pre>
3713 3715 <p>
3714 3716 Version 2 (headerlen=100):
3715 3717 </p>
3716 3718 <pre>
3717 3719 +------------------------------------------------------------------+
3718 3720 | | | | | |
3719 3721 | node | p1 node | p2 node | base node | link node |
3720 3722 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3721 3723 | | | | | |
3722 3724 +------------------------------------------------------------------+
3723 3725 </pre>
3724 3726 <p>
3725 3727 Version 3 (headerlen=102):
3726 3728 </p>
3727 3729 <pre>
3728 3730 +------------------------------------------------------------------------------+
3729 3731 | | | | | | |
3730 3732 | node | p1 node | p2 node | base node | link node | flags |
3731 3733 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3732 3734 | | | | | | |
3733 3735 +------------------------------------------------------------------------------+
3734 3736 </pre>
3735 3737 <p>
3736 3738 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3737 3739 series of *delta*s, densely packed (no separators). These deltas describe a diff
3738 3740 from an existing entry (either that the recipient already has, or previously
3739 3741 specified in the bundle/changegroup). The format is described more fully in
3740 3742 &quot;hg help internals.bdiff&quot;, but briefly:
3741 3743 </p>
3742 3744 <pre>
3743 3745 +---------------------------------------------------------------+
3744 3746 | | | | |
3745 3747 | start offset | end offset | new length | content |
3746 3748 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3747 3749 | | | | |
3748 3750 +---------------------------------------------------------------+
3749 3751 </pre>
3750 3752 <p>
3751 3753 Please note that the length field in the delta data does *not* include itself.
3752 3754 </p>
3753 3755 <p>
3754 3756 In version 1, the delta is always applied against the previous node from
3755 3757 the changegroup or the first parent if this is the first entry in the
3756 3758 changegroup.
3757 3759 </p>
3758 3760 <p>
3759 3761 In version 2 and up, the delta base node is encoded in the entry in the
3760 3762 changegroup. This allows the delta to be expressed against any parent,
3761 3763 which can result in smaller deltas and more efficient encoding of data.
3762 3764 </p>
3763 3765 <p>
3764 3766 The *flags* field holds bitwise flags affecting the processing of revision
3765 3767 data. The following flags are defined:
3766 3768 </p>
3767 3769 <dl>
3768 3770 <dt>32768
3769 3771 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3770 3772 <dt>16384
3771 3773 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3772 3774 <dt>8192
3773 3775 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3774 3776 </dl>
3775 3777 <p>
3776 3778 For historical reasons, the integer values are identical to revlog version 1
3777 3779 per-revision storage flags and correspond to bits being set in this 2-byte
3778 3780 field. Bits were allocated starting from the most-significant bit, hence the
3779 3781 reverse ordering and allocation of these flags.
3780 3782 </p>
3781 3783 <h2>Changeset Segment</h2>
3782 3784 <p>
3783 3785 The *changeset segment* consists of a single *delta group* holding
3784 3786 changelog data. The *empty chunk* at the end of the *delta group* denotes
3785 3787 the boundary to the *manifest segment*.
3786 3788 </p>
3787 3789 <h2>Manifest Segment</h2>
3788 3790 <p>
3789 3791 The *manifest segment* consists of a single *delta group* holding manifest
3790 3792 data. If treemanifests are in use, it contains only the manifest for the
3791 3793 root directory of the repository. Otherwise, it contains the entire
3792 3794 manifest data. The *empty chunk* at the end of the *delta group* denotes
3793 3795 the boundary to the next segment (either the *treemanifests segment* or the
3794 3796 *filelogs segment*, depending on version and the request options).
3795 3797 </p>
3796 3798 <h3>Treemanifests Segment</h3>
3797 3799 <p>
3798 3800 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3799 3801 only if the 'treemanifest' param is part of the bundle2 changegroup part
3800 3802 (it is not possible to use changegroup version 3 outside of bundle2).
3801 3803 Aside from the filenames in the *treemanifests segment* containing a
3802 3804 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3803 3805 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3804 3806 a sub-segment with filename size 0). This denotes the boundary to the
3805 3807 *filelogs segment*.
3806 3808 </p>
3807 3809 <h2>Filelogs Segment</h2>
3808 3810 <p>
3809 3811 The *filelogs segment* consists of multiple sub-segments, each
3810 3812 corresponding to an individual file whose data is being described:
3811 3813 </p>
3812 3814 <pre>
3813 3815 +--------------------------------------------------+
3814 3816 | | | | | |
3815 3817 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3816 3818 | | | | | (4 bytes) |
3817 3819 | | | | | |
3818 3820 +--------------------------------------------------+
3819 3821 </pre>
3820 3822 <p>
3821 3823 The final filelog sub-segment is followed by an *empty chunk* (logically,
3822 3824 a sub-segment with filename size 0). This denotes the end of the segment
3823 3825 and of the overall changegroup.
3824 3826 </p>
3825 3827 <p>
3826 3828 Each filelog sub-segment consists of the following:
3827 3829 </p>
3828 3830 <pre>
3829 3831 +------------------------------------------------------+
3830 3832 | | | |
3831 3833 | filename length | filename | delta group |
3832 3834 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3833 3835 | | | |
3834 3836 +------------------------------------------------------+
3835 3837 </pre>
3836 3838 <p>
3837 3839 That is, a *chunk* consisting of the filename (not terminated or padded)
3838 3840 followed by N chunks constituting the *delta group* for this file. The
3839 3841 *empty chunk* at the end of each *delta group* denotes the boundary to the
3840 3842 next filelog sub-segment.
3841 3843 </p>
3842 3844
3843 3845 </div>
3844 3846 </div>
3845 3847 </div>
3846 3848
3847 3849
3848 3850
3849 3851 </body>
3850 3852 </html>
3851 3853
3852 3854
3853 3855 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3854 3856 404 Not Found
3855 3857
3856 3858 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3857 3859 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3858 3860 <head>
3859 3861 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3860 3862 <meta name="robots" content="index, nofollow" />
3861 3863 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3862 3864 <script type="text/javascript" src="/static/mercurial.js"></script>
3863 3865
3864 3866 <title>test: error</title>
3865 3867 </head>
3866 3868 <body>
3867 3869
3868 3870 <div class="container">
3869 3871 <div class="menu">
3870 3872 <div class="logo">
3871 3873 <a href="https://mercurial-scm.org/">
3872 3874 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3873 3875 </div>
3874 3876 <ul>
3875 3877 <li><a href="/shortlog">log</a></li>
3876 3878 <li><a href="/graph">graph</a></li>
3877 3879 <li><a href="/tags">tags</a></li>
3878 3880 <li><a href="/bookmarks">bookmarks</a></li>
3879 3881 <li><a href="/branches">branches</a></li>
3880 3882 </ul>
3881 3883 <ul>
3882 3884 <li><a href="/help">help</a></li>
3883 3885 </ul>
3884 3886 </div>
3885 3887
3886 3888 <div class="main">
3887 3889
3888 3890 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3889 3891 <h3>error</h3>
3890 3892
3891 3893
3892 3894 <form class="search" action="/log">
3893 3895
3894 3896 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3895 3897 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3896 3898 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3897 3899 </form>
3898 3900
3899 3901 <div class="description">
3900 3902 <p>
3901 3903 An error occurred while processing your request:
3902 3904 </p>
3903 3905 <p>
3904 3906 Not Found
3905 3907 </p>
3906 3908 </div>
3907 3909 </div>
3908 3910 </div>
3909 3911
3910 3912
3911 3913
3912 3914 </body>
3913 3915 </html>
3914 3916
3915 3917 [1]
3916 3918
3917 3919 $ killdaemons.py
3918 3920
3919 3921 #endif
General Comments 0
You need to be logged in to leave comments. Login now