##// END OF EJS Templates
diff: describe behavior by using --from/--to instead of varying revision count...
Martin von Zweigbergk -
r46721:ed5a0b5d default
parent child Browse files
Show More
@@ -1,7744 +1,7747 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 2459 (b'', b'from', b'', _(b'revision to diff from'), _(b'REV')),
2460 2460 (b'', b'to', b'', _(b'revision to diff to'), _(b'REV')),
2461 2461 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2462 2462 ]
2463 2463 + diffopts
2464 2464 + diffopts2
2465 2465 + walkopts
2466 2466 + subrepoopts,
2467 2467 _(b'[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
2468 2468 helpcategory=command.CATEGORY_FILE_CONTENTS,
2469 2469 helpbasic=True,
2470 2470 inferrepo=True,
2471 2471 intents={INTENT_READONLY},
2472 2472 )
2473 2473 def diff(ui, repo, *pats, **opts):
2474 2474 """diff repository (or selected files)
2475 2475
2476 2476 Show differences between revisions for the specified files.
2477 2477
2478 2478 Differences between files are shown using the unified diff format.
2479 2479
2480 2480 .. note::
2481 2481
2482 2482 :hg:`diff` may generate unexpected results for merges, as it will
2483 2483 default to comparing against the working directory's first
2484 2484 parent changeset if no revisions are specified.
2485 2485
2486 When two revision arguments are given, then changes are shown
2487 between those revisions. If only one revision is specified then
2488 that revision is compared to the working directory, and, when no
2489 revisions are specified, the working directory files are compared
2490 to its first parent.
2491
2492 Alternatively you can specify -c/--change with a revision to see
2493 the changes in that changeset relative to its first parent.
2486 By default, the working directory files are compared to its first parent. To
2487 see the differences from another revision, use --from. To see the difference
2488 to another revision, use --to. For example, :hg:`diff --from .^` will show
2489 the differences from the working copy's grandparent to the working copy,
2490 :hg:`diff --to .` will show the diff from the working copy to its parent
2491 (i.e. the reverse of the default), and :hg:`diff --from 1.0 --to 1.2` will
2492 show the diff between those two revisions.
2493
2494 Alternatively you can specify -c/--change with a revision to see the changes
2495 in that changeset relative to its first parent (i.e. :hg:`diff -c 42` is
2496 equivalent to :hg:`diff --from 42^ --to 42`)
2494 2497
2495 2498 Without the -a/--text option, diff will avoid generating diffs of
2496 2499 files it detects as binary. With -a, diff will generate a diff
2497 2500 anyway, probably with undesirable results.
2498 2501
2499 2502 Use the -g/--git option to generate diffs in the git extended diff
2500 2503 format. For more information, read :hg:`help diffs`.
2501 2504
2502 2505 .. container:: verbose
2503 2506
2504 2507 Examples:
2505 2508
2506 2509 - compare a file in the current working directory to its parent::
2507 2510
2508 2511 hg diff foo.c
2509 2512
2510 2513 - compare two historical versions of a directory, with rename info::
2511 2514
2512 2515 hg diff --git --from 1.0 --to 1.2 lib/
2513 2516
2514 2517 - get change stats relative to the last change on some date::
2515 2518
2516 2519 hg diff --stat --from "date('may 2')"
2517 2520
2518 2521 - diff all newly-added files that contain a keyword::
2519 2522
2520 2523 hg diff "set:added() and grep(GNU)"
2521 2524
2522 2525 - compare a revision and its parents::
2523 2526
2524 2527 hg diff -c 9353 # compare against first parent
2525 2528 hg diff --from 9353^ --to 9353 # same using revset syntax
2526 2529 hg diff --from 9353^2 --to 9353 # compare against the second parent
2527 2530
2528 2531 Returns 0 on success.
2529 2532 """
2530 2533
2531 2534 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
2532 2535 opts = pycompat.byteskwargs(opts)
2533 2536 revs = opts.get(b'rev')
2534 2537 change = opts.get(b'change')
2535 2538 from_rev = opts.get(b'from')
2536 2539 to_rev = opts.get(b'to')
2537 2540 stat = opts.get(b'stat')
2538 2541 reverse = opts.get(b'reverse')
2539 2542
2540 2543 cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
2541 2544 cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
2542 2545 if change:
2543 2546 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2544 2547 ctx2 = scmutil.revsingle(repo, change, None)
2545 2548 ctx1 = ctx2.p1()
2546 2549 elif from_rev or to_rev:
2547 2550 repo = scmutil.unhidehashlikerevs(
2548 2551 repo, [from_rev] + [to_rev], b'nowarn'
2549 2552 )
2550 2553 ctx1 = scmutil.revsingle(repo, from_rev, None)
2551 2554 ctx2 = scmutil.revsingle(repo, to_rev, None)
2552 2555 else:
2553 2556 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2554 2557 ctx1, ctx2 = scmutil.revpair(repo, revs)
2555 2558
2556 2559 if reverse:
2557 2560 ctxleft = ctx2
2558 2561 ctxright = ctx1
2559 2562 else:
2560 2563 ctxleft = ctx1
2561 2564 ctxright = ctx2
2562 2565
2563 2566 diffopts = patch.diffallopts(ui, opts)
2564 2567 m = scmutil.match(ctx2, pats, opts)
2565 2568 m = repo.narrowmatch(m)
2566 2569 ui.pager(b'diff')
2567 2570 logcmdutil.diffordiffstat(
2568 2571 ui,
2569 2572 repo,
2570 2573 diffopts,
2571 2574 ctxleft,
2572 2575 ctxright,
2573 2576 m,
2574 2577 stat=stat,
2575 2578 listsubrepos=opts.get(b'subrepos'),
2576 2579 root=opts.get(b'root'),
2577 2580 )
2578 2581
2579 2582
2580 2583 @command(
2581 2584 b'export',
2582 2585 [
2583 2586 (
2584 2587 b'B',
2585 2588 b'bookmark',
2586 2589 b'',
2587 2590 _(b'export changes only reachable by given bookmark'),
2588 2591 _(b'BOOKMARK'),
2589 2592 ),
2590 2593 (
2591 2594 b'o',
2592 2595 b'output',
2593 2596 b'',
2594 2597 _(b'print output to file with formatted name'),
2595 2598 _(b'FORMAT'),
2596 2599 ),
2597 2600 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2598 2601 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2599 2602 ]
2600 2603 + diffopts
2601 2604 + formatteropts,
2602 2605 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2603 2606 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2604 2607 helpbasic=True,
2605 2608 intents={INTENT_READONLY},
2606 2609 )
2607 2610 def export(ui, repo, *changesets, **opts):
2608 2611 """dump the header and diffs for one or more changesets
2609 2612
2610 2613 Print the changeset header and diffs for one or more revisions.
2611 2614 If no revision is given, the parent of the working directory is used.
2612 2615
2613 2616 The information shown in the changeset header is: author, date,
2614 2617 branch name (if non-default), changeset hash, parent(s) and commit
2615 2618 comment.
2616 2619
2617 2620 .. note::
2618 2621
2619 2622 :hg:`export` may generate unexpected diff output for merge
2620 2623 changesets, as it will compare the merge changeset against its
2621 2624 first parent only.
2622 2625
2623 2626 Output may be to a file, in which case the name of the file is
2624 2627 given using a template string. See :hg:`help templates`. In addition
2625 2628 to the common template keywords, the following formatting rules are
2626 2629 supported:
2627 2630
2628 2631 :``%%``: literal "%" character
2629 2632 :``%H``: changeset hash (40 hexadecimal digits)
2630 2633 :``%N``: number of patches being generated
2631 2634 :``%R``: changeset revision number
2632 2635 :``%b``: basename of the exporting repository
2633 2636 :``%h``: short-form changeset hash (12 hexadecimal digits)
2634 2637 :``%m``: first line of the commit message (only alphanumeric characters)
2635 2638 :``%n``: zero-padded sequence number, starting at 1
2636 2639 :``%r``: zero-padded changeset revision number
2637 2640 :``\\``: literal "\\" character
2638 2641
2639 2642 Without the -a/--text option, export will avoid generating diffs
2640 2643 of files it detects as binary. With -a, export will generate a
2641 2644 diff anyway, probably with undesirable results.
2642 2645
2643 2646 With -B/--bookmark changesets reachable by the given bookmark are
2644 2647 selected.
2645 2648
2646 2649 Use the -g/--git option to generate diffs in the git extended diff
2647 2650 format. See :hg:`help diffs` for more information.
2648 2651
2649 2652 With the --switch-parent option, the diff will be against the
2650 2653 second parent. It can be useful to review a merge.
2651 2654
2652 2655 .. container:: verbose
2653 2656
2654 2657 Template:
2655 2658
2656 2659 The following keywords are supported in addition to the common template
2657 2660 keywords and functions. See also :hg:`help templates`.
2658 2661
2659 2662 :diff: String. Diff content.
2660 2663 :parents: List of strings. Parent nodes of the changeset.
2661 2664
2662 2665 Examples:
2663 2666
2664 2667 - use export and import to transplant a bugfix to the current
2665 2668 branch::
2666 2669
2667 2670 hg export -r 9353 | hg import -
2668 2671
2669 2672 - export all the changesets between two revisions to a file with
2670 2673 rename information::
2671 2674
2672 2675 hg export --git -r 123:150 > changes.txt
2673 2676
2674 2677 - split outgoing changes into a series of patches with
2675 2678 descriptive names::
2676 2679
2677 2680 hg export -r "outgoing()" -o "%n-%m.patch"
2678 2681
2679 2682 Returns 0 on success.
2680 2683 """
2681 2684 opts = pycompat.byteskwargs(opts)
2682 2685 bookmark = opts.get(b'bookmark')
2683 2686 changesets += tuple(opts.get(b'rev', []))
2684 2687
2685 2688 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2686 2689
2687 2690 if bookmark:
2688 2691 if bookmark not in repo._bookmarks:
2689 2692 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2690 2693
2691 2694 revs = scmutil.bookmarkrevs(repo, bookmark)
2692 2695 else:
2693 2696 if not changesets:
2694 2697 changesets = [b'.']
2695 2698
2696 2699 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2697 2700 revs = scmutil.revrange(repo, changesets)
2698 2701
2699 2702 if not revs:
2700 2703 raise error.InputError(_(b"export requires at least one changeset"))
2701 2704 if len(revs) > 1:
2702 2705 ui.note(_(b'exporting patches:\n'))
2703 2706 else:
2704 2707 ui.note(_(b'exporting patch:\n'))
2705 2708
2706 2709 fntemplate = opts.get(b'output')
2707 2710 if cmdutil.isstdiofilename(fntemplate):
2708 2711 fntemplate = b''
2709 2712
2710 2713 if fntemplate:
2711 2714 fm = formatter.nullformatter(ui, b'export', opts)
2712 2715 else:
2713 2716 ui.pager(b'export')
2714 2717 fm = ui.formatter(b'export', opts)
2715 2718 with fm:
2716 2719 cmdutil.export(
2717 2720 repo,
2718 2721 revs,
2719 2722 fm,
2720 2723 fntemplate=fntemplate,
2721 2724 switch_parent=opts.get(b'switch_parent'),
2722 2725 opts=patch.diffallopts(ui, opts),
2723 2726 )
2724 2727
2725 2728
2726 2729 @command(
2727 2730 b'files',
2728 2731 [
2729 2732 (
2730 2733 b'r',
2731 2734 b'rev',
2732 2735 b'',
2733 2736 _(b'search the repository as it is in REV'),
2734 2737 _(b'REV'),
2735 2738 ),
2736 2739 (
2737 2740 b'0',
2738 2741 b'print0',
2739 2742 None,
2740 2743 _(b'end filenames with NUL, for use with xargs'),
2741 2744 ),
2742 2745 ]
2743 2746 + walkopts
2744 2747 + formatteropts
2745 2748 + subrepoopts,
2746 2749 _(b'[OPTION]... [FILE]...'),
2747 2750 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2748 2751 intents={INTENT_READONLY},
2749 2752 )
2750 2753 def files(ui, repo, *pats, **opts):
2751 2754 """list tracked files
2752 2755
2753 2756 Print files under Mercurial control in the working directory or
2754 2757 specified revision for given files (excluding removed files).
2755 2758 Files can be specified as filenames or filesets.
2756 2759
2757 2760 If no files are given to match, this command prints the names
2758 2761 of all files under Mercurial control.
2759 2762
2760 2763 .. container:: verbose
2761 2764
2762 2765 Template:
2763 2766
2764 2767 The following keywords are supported in addition to the common template
2765 2768 keywords and functions. See also :hg:`help templates`.
2766 2769
2767 2770 :flags: String. Character denoting file's symlink and executable bits.
2768 2771 :path: String. Repository-absolute path of the file.
2769 2772 :size: Integer. Size of the file in bytes.
2770 2773
2771 2774 Examples:
2772 2775
2773 2776 - list all files under the current directory::
2774 2777
2775 2778 hg files .
2776 2779
2777 2780 - shows sizes and flags for current revision::
2778 2781
2779 2782 hg files -vr .
2780 2783
2781 2784 - list all files named README::
2782 2785
2783 2786 hg files -I "**/README"
2784 2787
2785 2788 - list all binary files::
2786 2789
2787 2790 hg files "set:binary()"
2788 2791
2789 2792 - find files containing a regular expression::
2790 2793
2791 2794 hg files "set:grep('bob')"
2792 2795
2793 2796 - search tracked file contents with xargs and grep::
2794 2797
2795 2798 hg files -0 | xargs -0 grep foo
2796 2799
2797 2800 See :hg:`help patterns` and :hg:`help filesets` for more information
2798 2801 on specifying file patterns.
2799 2802
2800 2803 Returns 0 if a match is found, 1 otherwise.
2801 2804
2802 2805 """
2803 2806
2804 2807 opts = pycompat.byteskwargs(opts)
2805 2808 rev = opts.get(b'rev')
2806 2809 if rev:
2807 2810 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2808 2811 ctx = scmutil.revsingle(repo, rev, None)
2809 2812
2810 2813 end = b'\n'
2811 2814 if opts.get(b'print0'):
2812 2815 end = b'\0'
2813 2816 fmt = b'%s' + end
2814 2817
2815 2818 m = scmutil.match(ctx, pats, opts)
2816 2819 ui.pager(b'files')
2817 2820 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2818 2821 with ui.formatter(b'files', opts) as fm:
2819 2822 return cmdutil.files(
2820 2823 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2821 2824 )
2822 2825
2823 2826
2824 2827 @command(
2825 2828 b'forget',
2826 2829 [
2827 2830 (b'i', b'interactive', None, _(b'use interactive mode')),
2828 2831 ]
2829 2832 + walkopts
2830 2833 + dryrunopts,
2831 2834 _(b'[OPTION]... FILE...'),
2832 2835 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2833 2836 helpbasic=True,
2834 2837 inferrepo=True,
2835 2838 )
2836 2839 def forget(ui, repo, *pats, **opts):
2837 2840 """forget the specified files on the next commit
2838 2841
2839 2842 Mark the specified files so they will no longer be tracked
2840 2843 after the next commit.
2841 2844
2842 2845 This only removes files from the current branch, not from the
2843 2846 entire project history, and it does not delete them from the
2844 2847 working directory.
2845 2848
2846 2849 To delete the file from the working directory, see :hg:`remove`.
2847 2850
2848 2851 To undo a forget before the next commit, see :hg:`add`.
2849 2852
2850 2853 .. container:: verbose
2851 2854
2852 2855 Examples:
2853 2856
2854 2857 - forget newly-added binary files::
2855 2858
2856 2859 hg forget "set:added() and binary()"
2857 2860
2858 2861 - forget files that would be excluded by .hgignore::
2859 2862
2860 2863 hg forget "set:hgignore()"
2861 2864
2862 2865 Returns 0 on success.
2863 2866 """
2864 2867
2865 2868 opts = pycompat.byteskwargs(opts)
2866 2869 if not pats:
2867 2870 raise error.InputError(_(b'no files specified'))
2868 2871
2869 2872 m = scmutil.match(repo[None], pats, opts)
2870 2873 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2871 2874 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2872 2875 rejected = cmdutil.forget(
2873 2876 ui,
2874 2877 repo,
2875 2878 m,
2876 2879 prefix=b"",
2877 2880 uipathfn=uipathfn,
2878 2881 explicitonly=False,
2879 2882 dryrun=dryrun,
2880 2883 interactive=interactive,
2881 2884 )[0]
2882 2885 return rejected and 1 or 0
2883 2886
2884 2887
2885 2888 @command(
2886 2889 b'graft',
2887 2890 [
2888 2891 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
2889 2892 (
2890 2893 b'',
2891 2894 b'base',
2892 2895 b'',
2893 2896 _(b'base revision when doing the graft merge (ADVANCED)'),
2894 2897 _(b'REV'),
2895 2898 ),
2896 2899 (b'c', b'continue', False, _(b'resume interrupted graft')),
2897 2900 (b'', b'stop', False, _(b'stop interrupted graft')),
2898 2901 (b'', b'abort', False, _(b'abort interrupted graft')),
2899 2902 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
2900 2903 (b'', b'log', None, _(b'append graft info to log message')),
2901 2904 (
2902 2905 b'',
2903 2906 b'no-commit',
2904 2907 None,
2905 2908 _(b"don't commit, just apply the changes in working directory"),
2906 2909 ),
2907 2910 (b'f', b'force', False, _(b'force graft')),
2908 2911 (
2909 2912 b'D',
2910 2913 b'currentdate',
2911 2914 False,
2912 2915 _(b'record the current date as commit date'),
2913 2916 ),
2914 2917 (
2915 2918 b'U',
2916 2919 b'currentuser',
2917 2920 False,
2918 2921 _(b'record the current user as committer'),
2919 2922 ),
2920 2923 ]
2921 2924 + commitopts2
2922 2925 + mergetoolopts
2923 2926 + dryrunopts,
2924 2927 _(b'[OPTION]... [-r REV]... REV...'),
2925 2928 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2926 2929 )
2927 2930 def graft(ui, repo, *revs, **opts):
2928 2931 """copy changes from other branches onto the current branch
2929 2932
2930 2933 This command uses Mercurial's merge logic to copy individual
2931 2934 changes from other branches without merging branches in the
2932 2935 history graph. This is sometimes known as 'backporting' or
2933 2936 'cherry-picking'. By default, graft will copy user, date, and
2934 2937 description from the source changesets.
2935 2938
2936 2939 Changesets that are ancestors of the current revision, that have
2937 2940 already been grafted, or that are merges will be skipped.
2938 2941
2939 2942 If --log is specified, log messages will have a comment appended
2940 2943 of the form::
2941 2944
2942 2945 (grafted from CHANGESETHASH)
2943 2946
2944 2947 If --force is specified, revisions will be grafted even if they
2945 2948 are already ancestors of, or have been grafted to, the destination.
2946 2949 This is useful when the revisions have since been backed out.
2947 2950
2948 2951 If a graft merge results in conflicts, the graft process is
2949 2952 interrupted so that the current merge can be manually resolved.
2950 2953 Once all conflicts are addressed, the graft process can be
2951 2954 continued with the -c/--continue option.
2952 2955
2953 2956 The -c/--continue option reapplies all the earlier options.
2954 2957
2955 2958 .. container:: verbose
2956 2959
2957 2960 The --base option exposes more of how graft internally uses merge with a
2958 2961 custom base revision. --base can be used to specify another ancestor than
2959 2962 the first and only parent.
2960 2963
2961 2964 The command::
2962 2965
2963 2966 hg graft -r 345 --base 234
2964 2967
2965 2968 is thus pretty much the same as::
2966 2969
2967 2970 hg diff --from 234 --to 345 | hg import
2968 2971
2969 2972 but using merge to resolve conflicts and track moved files.
2970 2973
2971 2974 The result of a merge can thus be backported as a single commit by
2972 2975 specifying one of the merge parents as base, and thus effectively
2973 2976 grafting the changes from the other side.
2974 2977
2975 2978 It is also possible to collapse multiple changesets and clean up history
2976 2979 by specifying another ancestor as base, much like rebase --collapse
2977 2980 --keep.
2978 2981
2979 2982 The commit message can be tweaked after the fact using commit --amend .
2980 2983
2981 2984 For using non-ancestors as the base to backout changes, see the backout
2982 2985 command and the hidden --parent option.
2983 2986
2984 2987 .. container:: verbose
2985 2988
2986 2989 Examples:
2987 2990
2988 2991 - copy a single change to the stable branch and edit its description::
2989 2992
2990 2993 hg update stable
2991 2994 hg graft --edit 9393
2992 2995
2993 2996 - graft a range of changesets with one exception, updating dates::
2994 2997
2995 2998 hg graft -D "2085::2093 and not 2091"
2996 2999
2997 3000 - continue a graft after resolving conflicts::
2998 3001
2999 3002 hg graft -c
3000 3003
3001 3004 - show the source of a grafted changeset::
3002 3005
3003 3006 hg log --debug -r .
3004 3007
3005 3008 - show revisions sorted by date::
3006 3009
3007 3010 hg log -r "sort(all(), date)"
3008 3011
3009 3012 - backport the result of a merge as a single commit::
3010 3013
3011 3014 hg graft -r 123 --base 123^
3012 3015
3013 3016 - land a feature branch as one changeset::
3014 3017
3015 3018 hg up -cr default
3016 3019 hg graft -r featureX --base "ancestor('featureX', 'default')"
3017 3020
3018 3021 See :hg:`help revisions` for more about specifying revisions.
3019 3022
3020 3023 Returns 0 on successful completion, 1 if there are unresolved files.
3021 3024 """
3022 3025 with repo.wlock():
3023 3026 return _dograft(ui, repo, *revs, **opts)
3024 3027
3025 3028
3026 3029 def _dograft(ui, repo, *revs, **opts):
3027 3030 opts = pycompat.byteskwargs(opts)
3028 3031 if revs and opts.get(b'rev'):
3029 3032 ui.warn(
3030 3033 _(
3031 3034 b'warning: inconsistent use of --rev might give unexpected '
3032 3035 b'revision ordering!\n'
3033 3036 )
3034 3037 )
3035 3038
3036 3039 revs = list(revs)
3037 3040 revs.extend(opts.get(b'rev'))
3038 3041 # a dict of data to be stored in state file
3039 3042 statedata = {}
3040 3043 # list of new nodes created by ongoing graft
3041 3044 statedata[b'newnodes'] = []
3042 3045
3043 3046 cmdutil.resolvecommitoptions(ui, opts)
3044 3047
3045 3048 editor = cmdutil.getcommiteditor(
3046 3049 editform=b'graft', **pycompat.strkwargs(opts)
3047 3050 )
3048 3051
3049 3052 cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue')
3050 3053
3051 3054 cont = False
3052 3055 if opts.get(b'no_commit'):
3053 3056 cmdutil.check_incompatible_arguments(
3054 3057 opts,
3055 3058 b'no_commit',
3056 3059 [b'edit', b'currentuser', b'currentdate', b'log'],
3057 3060 )
3058 3061
3059 3062 graftstate = statemod.cmdstate(repo, b'graftstate')
3060 3063
3061 3064 if opts.get(b'stop'):
3062 3065 cmdutil.check_incompatible_arguments(
3063 3066 opts,
3064 3067 b'stop',
3065 3068 [
3066 3069 b'edit',
3067 3070 b'log',
3068 3071 b'user',
3069 3072 b'date',
3070 3073 b'currentdate',
3071 3074 b'currentuser',
3072 3075 b'rev',
3073 3076 ],
3074 3077 )
3075 3078 return _stopgraft(ui, repo, graftstate)
3076 3079 elif opts.get(b'abort'):
3077 3080 cmdutil.check_incompatible_arguments(
3078 3081 opts,
3079 3082 b'abort',
3080 3083 [
3081 3084 b'edit',
3082 3085 b'log',
3083 3086 b'user',
3084 3087 b'date',
3085 3088 b'currentdate',
3086 3089 b'currentuser',
3087 3090 b'rev',
3088 3091 ],
3089 3092 )
3090 3093 return cmdutil.abortgraft(ui, repo, graftstate)
3091 3094 elif opts.get(b'continue'):
3092 3095 cont = True
3093 3096 if revs:
3094 3097 raise error.InputError(_(b"can't specify --continue and revisions"))
3095 3098 # read in unfinished revisions
3096 3099 if graftstate.exists():
3097 3100 statedata = cmdutil.readgraftstate(repo, graftstate)
3098 3101 if statedata.get(b'date'):
3099 3102 opts[b'date'] = statedata[b'date']
3100 3103 if statedata.get(b'user'):
3101 3104 opts[b'user'] = statedata[b'user']
3102 3105 if statedata.get(b'log'):
3103 3106 opts[b'log'] = True
3104 3107 if statedata.get(b'no_commit'):
3105 3108 opts[b'no_commit'] = statedata.get(b'no_commit')
3106 3109 if statedata.get(b'base'):
3107 3110 opts[b'base'] = statedata.get(b'base')
3108 3111 nodes = statedata[b'nodes']
3109 3112 revs = [repo[node].rev() for node in nodes]
3110 3113 else:
3111 3114 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3112 3115 else:
3113 3116 if not revs:
3114 3117 raise error.InputError(_(b'no revisions specified'))
3115 3118 cmdutil.checkunfinished(repo)
3116 3119 cmdutil.bailifchanged(repo)
3117 3120 revs = scmutil.revrange(repo, revs)
3118 3121
3119 3122 skipped = set()
3120 3123 basectx = None
3121 3124 if opts.get(b'base'):
3122 3125 basectx = scmutil.revsingle(repo, opts[b'base'], None)
3123 3126 if basectx is None:
3124 3127 # check for merges
3125 3128 for rev in repo.revs(b'%ld and merge()', revs):
3126 3129 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3127 3130 skipped.add(rev)
3128 3131 revs = [r for r in revs if r not in skipped]
3129 3132 if not revs:
3130 3133 return -1
3131 3134 if basectx is not None and len(revs) != 1:
3132 3135 raise error.InputError(_(b'only one revision allowed with --base '))
3133 3136
3134 3137 # Don't check in the --continue case, in effect retaining --force across
3135 3138 # --continues. That's because without --force, any revisions we decided to
3136 3139 # skip would have been filtered out here, so they wouldn't have made their
3137 3140 # way to the graftstate. With --force, any revisions we would have otherwise
3138 3141 # skipped would not have been filtered out, and if they hadn't been applied
3139 3142 # already, they'd have been in the graftstate.
3140 3143 if not (cont or opts.get(b'force')) and basectx is None:
3141 3144 # check for ancestors of dest branch
3142 3145 ancestors = repo.revs(b'%ld & (::.)', revs)
3143 3146 for rev in ancestors:
3144 3147 ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev]))
3145 3148
3146 3149 revs = [r for r in revs if r not in ancestors]
3147 3150
3148 3151 if not revs:
3149 3152 return -1
3150 3153
3151 3154 # analyze revs for earlier grafts
3152 3155 ids = {}
3153 3156 for ctx in repo.set(b"%ld", revs):
3154 3157 ids[ctx.hex()] = ctx.rev()
3155 3158 n = ctx.extra().get(b'source')
3156 3159 if n:
3157 3160 ids[n] = ctx.rev()
3158 3161
3159 3162 # check ancestors for earlier grafts
3160 3163 ui.debug(b'scanning for duplicate grafts\n')
3161 3164
3162 3165 # The only changesets we can be sure doesn't contain grafts of any
3163 3166 # revs, are the ones that are common ancestors of *all* revs:
3164 3167 for rev in repo.revs(b'only(%d,ancestor(%ld))', repo[b'.'].rev(), revs):
3165 3168 ctx = repo[rev]
3166 3169 n = ctx.extra().get(b'source')
3167 3170 if n in ids:
3168 3171 try:
3169 3172 r = repo[n].rev()
3170 3173 except error.RepoLookupError:
3171 3174 r = None
3172 3175 if r in revs:
3173 3176 ui.warn(
3174 3177 _(
3175 3178 b'skipping revision %d:%s '
3176 3179 b'(already grafted to %d:%s)\n'
3177 3180 )
3178 3181 % (r, repo[r], rev, ctx)
3179 3182 )
3180 3183 revs.remove(r)
3181 3184 elif ids[n] in revs:
3182 3185 if r is None:
3183 3186 ui.warn(
3184 3187 _(
3185 3188 b'skipping already grafted revision %d:%s '
3186 3189 b'(%d:%s also has unknown origin %s)\n'
3187 3190 )
3188 3191 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3189 3192 )
3190 3193 else:
3191 3194 ui.warn(
3192 3195 _(
3193 3196 b'skipping already grafted revision %d:%s '
3194 3197 b'(%d:%s also has origin %d:%s)\n'
3195 3198 )
3196 3199 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3197 3200 )
3198 3201 revs.remove(ids[n])
3199 3202 elif ctx.hex() in ids:
3200 3203 r = ids[ctx.hex()]
3201 3204 if r in revs:
3202 3205 ui.warn(
3203 3206 _(
3204 3207 b'skipping already grafted revision %d:%s '
3205 3208 b'(was grafted from %d:%s)\n'
3206 3209 )
3207 3210 % (r, repo[r], rev, ctx)
3208 3211 )
3209 3212 revs.remove(r)
3210 3213 if not revs:
3211 3214 return -1
3212 3215
3213 3216 if opts.get(b'no_commit'):
3214 3217 statedata[b'no_commit'] = True
3215 3218 if opts.get(b'base'):
3216 3219 statedata[b'base'] = opts[b'base']
3217 3220 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3218 3221 desc = b'%d:%s "%s"' % (
3219 3222 ctx.rev(),
3220 3223 ctx,
3221 3224 ctx.description().split(b'\n', 1)[0],
3222 3225 )
3223 3226 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3224 3227 if names:
3225 3228 desc += b' (%s)' % b' '.join(names)
3226 3229 ui.status(_(b'grafting %s\n') % desc)
3227 3230 if opts.get(b'dry_run'):
3228 3231 continue
3229 3232
3230 3233 source = ctx.extra().get(b'source')
3231 3234 extra = {}
3232 3235 if source:
3233 3236 extra[b'source'] = source
3234 3237 extra[b'intermediate-source'] = ctx.hex()
3235 3238 else:
3236 3239 extra[b'source'] = ctx.hex()
3237 3240 user = ctx.user()
3238 3241 if opts.get(b'user'):
3239 3242 user = opts[b'user']
3240 3243 statedata[b'user'] = user
3241 3244 date = ctx.date()
3242 3245 if opts.get(b'date'):
3243 3246 date = opts[b'date']
3244 3247 statedata[b'date'] = date
3245 3248 message = ctx.description()
3246 3249 if opts.get(b'log'):
3247 3250 message += b'\n(grafted from %s)' % ctx.hex()
3248 3251 statedata[b'log'] = True
3249 3252
3250 3253 # we don't merge the first commit when continuing
3251 3254 if not cont:
3252 3255 # perform the graft merge with p1(rev) as 'ancestor'
3253 3256 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
3254 3257 base = ctx.p1() if basectx is None else basectx
3255 3258 with ui.configoverride(overrides, b'graft'):
3256 3259 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
3257 3260 # report any conflicts
3258 3261 if stats.unresolvedcount > 0:
3259 3262 # write out state for --continue
3260 3263 nodes = [repo[rev].hex() for rev in revs[pos:]]
3261 3264 statedata[b'nodes'] = nodes
3262 3265 stateversion = 1
3263 3266 graftstate.save(stateversion, statedata)
3264 3267 ui.error(_(b"abort: unresolved conflicts, can't continue\n"))
3265 3268 ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n"))
3266 3269 return 1
3267 3270 else:
3268 3271 cont = False
3269 3272
3270 3273 # commit if --no-commit is false
3271 3274 if not opts.get(b'no_commit'):
3272 3275 node = repo.commit(
3273 3276 text=message, user=user, date=date, extra=extra, editor=editor
3274 3277 )
3275 3278 if node is None:
3276 3279 ui.warn(
3277 3280 _(b'note: graft of %d:%s created no changes to commit\n')
3278 3281 % (ctx.rev(), ctx)
3279 3282 )
3280 3283 # checking that newnodes exist because old state files won't have it
3281 3284 elif statedata.get(b'newnodes') is not None:
3282 3285 statedata[b'newnodes'].append(node)
3283 3286
3284 3287 # remove state when we complete successfully
3285 3288 if not opts.get(b'dry_run'):
3286 3289 graftstate.delete()
3287 3290
3288 3291 return 0
3289 3292
3290 3293
3291 3294 def _stopgraft(ui, repo, graftstate):
3292 3295 """stop the interrupted graft"""
3293 3296 if not graftstate.exists():
3294 3297 raise error.StateError(_(b"no interrupted graft found"))
3295 3298 pctx = repo[b'.']
3296 3299 mergemod.clean_update(pctx)
3297 3300 graftstate.delete()
3298 3301 ui.status(_(b"stopped the interrupted graft\n"))
3299 3302 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3300 3303 return 0
3301 3304
3302 3305
3303 3306 statemod.addunfinished(
3304 3307 b'graft',
3305 3308 fname=b'graftstate',
3306 3309 clearable=True,
3307 3310 stopflag=True,
3308 3311 continueflag=True,
3309 3312 abortfunc=cmdutil.hgabortgraft,
3310 3313 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3311 3314 )
3312 3315
3313 3316
3314 3317 @command(
3315 3318 b'grep',
3316 3319 [
3317 3320 (b'0', b'print0', None, _(b'end fields with NUL')),
3318 3321 (b'', b'all', None, _(b'an alias to --diff (DEPRECATED)')),
3319 3322 (
3320 3323 b'',
3321 3324 b'diff',
3322 3325 None,
3323 3326 _(
3324 3327 b'search revision differences for when the pattern was added '
3325 3328 b'or removed'
3326 3329 ),
3327 3330 ),
3328 3331 (b'a', b'text', None, _(b'treat all files as text')),
3329 3332 (
3330 3333 b'f',
3331 3334 b'follow',
3332 3335 None,
3333 3336 _(
3334 3337 b'follow changeset history,'
3335 3338 b' or file history across copies and renames'
3336 3339 ),
3337 3340 ),
3338 3341 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3339 3342 (
3340 3343 b'l',
3341 3344 b'files-with-matches',
3342 3345 None,
3343 3346 _(b'print only filenames and revisions that match'),
3344 3347 ),
3345 3348 (b'n', b'line-number', None, _(b'print matching line numbers')),
3346 3349 (
3347 3350 b'r',
3348 3351 b'rev',
3349 3352 [],
3350 3353 _(b'search files changed within revision range'),
3351 3354 _(b'REV'),
3352 3355 ),
3353 3356 (
3354 3357 b'',
3355 3358 b'all-files',
3356 3359 None,
3357 3360 _(
3358 3361 b'include all files in the changeset while grepping (DEPRECATED)'
3359 3362 ),
3360 3363 ),
3361 3364 (b'u', b'user', None, _(b'list the author (long with -v)')),
3362 3365 (b'd', b'date', None, _(b'list the date (short with -q)')),
3363 3366 ]
3364 3367 + formatteropts
3365 3368 + walkopts,
3366 3369 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3367 3370 helpcategory=command.CATEGORY_FILE_CONTENTS,
3368 3371 inferrepo=True,
3369 3372 intents={INTENT_READONLY},
3370 3373 )
3371 3374 def grep(ui, repo, pattern, *pats, **opts):
3372 3375 """search for a pattern in specified files
3373 3376
3374 3377 Search the working directory or revision history for a regular
3375 3378 expression in the specified files for the entire repository.
3376 3379
3377 3380 By default, grep searches the repository files in the working
3378 3381 directory and prints the files where it finds a match. To specify
3379 3382 historical revisions instead of the working directory, use the
3380 3383 --rev flag.
3381 3384
3382 3385 To search instead historical revision differences that contains a
3383 3386 change in match status ("-" for a match that becomes a non-match,
3384 3387 or "+" for a non-match that becomes a match), use the --diff flag.
3385 3388
3386 3389 PATTERN can be any Python (roughly Perl-compatible) regular
3387 3390 expression.
3388 3391
3389 3392 If no FILEs are specified and the --rev flag isn't supplied, all
3390 3393 files in the working directory are searched. When using the --rev
3391 3394 flag and specifying FILEs, use the --follow argument to also
3392 3395 follow the specified FILEs across renames and copies.
3393 3396
3394 3397 .. container:: verbose
3395 3398
3396 3399 Template:
3397 3400
3398 3401 The following keywords are supported in addition to the common template
3399 3402 keywords and functions. See also :hg:`help templates`.
3400 3403
3401 3404 :change: String. Character denoting insertion ``+`` or removal ``-``.
3402 3405 Available if ``--diff`` is specified.
3403 3406 :lineno: Integer. Line number of the match.
3404 3407 :path: String. Repository-absolute path of the file.
3405 3408 :texts: List of text chunks.
3406 3409
3407 3410 And each entry of ``{texts}`` provides the following sub-keywords.
3408 3411
3409 3412 :matched: Boolean. True if the chunk matches the specified pattern.
3410 3413 :text: String. Chunk content.
3411 3414
3412 3415 See :hg:`help templates.operators` for the list expansion syntax.
3413 3416
3414 3417 Returns 0 if a match is found, 1 otherwise.
3415 3418
3416 3419 """
3417 3420 cmdutil.check_incompatible_arguments(opts, 'all_files', ['all', 'diff'])
3418 3421 opts = pycompat.byteskwargs(opts)
3419 3422 diff = opts.get(b'all') or opts.get(b'diff')
3420 3423 follow = opts.get(b'follow')
3421 3424 if opts.get(b'all_files') is None and not diff:
3422 3425 opts[b'all_files'] = True
3423 3426 plaingrep = (
3424 3427 opts.get(b'all_files')
3425 3428 and not opts.get(b'rev')
3426 3429 and not opts.get(b'follow')
3427 3430 )
3428 3431 all_files = opts.get(b'all_files')
3429 3432 if plaingrep:
3430 3433 opts[b'rev'] = [b'wdir()']
3431 3434
3432 3435 reflags = re.M
3433 3436 if opts.get(b'ignore_case'):
3434 3437 reflags |= re.I
3435 3438 try:
3436 3439 regexp = util.re.compile(pattern, reflags)
3437 3440 except re.error as inst:
3438 3441 ui.warn(
3439 3442 _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
3440 3443 )
3441 3444 return 1
3442 3445 sep, eol = b':', b'\n'
3443 3446 if opts.get(b'print0'):
3444 3447 sep = eol = b'\0'
3445 3448
3446 3449 searcher = grepmod.grepsearcher(
3447 3450 ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
3448 3451 )
3449 3452
3450 3453 getfile = searcher._getfile
3451 3454
3452 3455 uipathfn = scmutil.getuipathfn(repo)
3453 3456
3454 3457 def display(fm, fn, ctx, pstates, states):
3455 3458 rev = scmutil.intrev(ctx)
3456 3459 if fm.isplain():
3457 3460 formatuser = ui.shortuser
3458 3461 else:
3459 3462 formatuser = pycompat.bytestr
3460 3463 if ui.quiet:
3461 3464 datefmt = b'%Y-%m-%d'
3462 3465 else:
3463 3466 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3464 3467 found = False
3465 3468
3466 3469 @util.cachefunc
3467 3470 def binary():
3468 3471 flog = getfile(fn)
3469 3472 try:
3470 3473 return stringutil.binary(flog.read(ctx.filenode(fn)))
3471 3474 except error.WdirUnsupported:
3472 3475 return ctx[fn].isbinary()
3473 3476
3474 3477 fieldnamemap = {b'linenumber': b'lineno'}
3475 3478 if diff:
3476 3479 iter = grepmod.difflinestates(pstates, states)
3477 3480 else:
3478 3481 iter = [(b'', l) for l in states]
3479 3482 for change, l in iter:
3480 3483 fm.startitem()
3481 3484 fm.context(ctx=ctx)
3482 3485 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3483 3486 fm.plain(uipathfn(fn), label=b'grep.filename')
3484 3487
3485 3488 cols = [
3486 3489 (b'rev', b'%d', rev, not plaingrep, b''),
3487 3490 (
3488 3491 b'linenumber',
3489 3492 b'%d',
3490 3493 l.linenum,
3491 3494 opts.get(b'line_number'),
3492 3495 b'',
3493 3496 ),
3494 3497 ]
3495 3498 if diff:
3496 3499 cols.append(
3497 3500 (
3498 3501 b'change',
3499 3502 b'%s',
3500 3503 change,
3501 3504 True,
3502 3505 b'grep.inserted '
3503 3506 if change == b'+'
3504 3507 else b'grep.deleted ',
3505 3508 )
3506 3509 )
3507 3510 cols.extend(
3508 3511 [
3509 3512 (
3510 3513 b'user',
3511 3514 b'%s',
3512 3515 formatuser(ctx.user()),
3513 3516 opts.get(b'user'),
3514 3517 b'',
3515 3518 ),
3516 3519 (
3517 3520 b'date',
3518 3521 b'%s',
3519 3522 fm.formatdate(ctx.date(), datefmt),
3520 3523 opts.get(b'date'),
3521 3524 b'',
3522 3525 ),
3523 3526 ]
3524 3527 )
3525 3528 for name, fmt, data, cond, extra_label in cols:
3526 3529 if cond:
3527 3530 fm.plain(sep, label=b'grep.sep')
3528 3531 field = fieldnamemap.get(name, name)
3529 3532 label = extra_label + (b'grep.%s' % name)
3530 3533 fm.condwrite(cond, field, fmt, data, label=label)
3531 3534 if not opts.get(b'files_with_matches'):
3532 3535 fm.plain(sep, label=b'grep.sep')
3533 3536 if not opts.get(b'text') and binary():
3534 3537 fm.plain(_(b" Binary file matches"))
3535 3538 else:
3536 3539 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3537 3540 fm.plain(eol)
3538 3541 found = True
3539 3542 if opts.get(b'files_with_matches'):
3540 3543 break
3541 3544 return found
3542 3545
3543 3546 def displaymatches(fm, l):
3544 3547 p = 0
3545 3548 for s, e in l.findpos(regexp):
3546 3549 if p < s:
3547 3550 fm.startitem()
3548 3551 fm.write(b'text', b'%s', l.line[p:s])
3549 3552 fm.data(matched=False)
3550 3553 fm.startitem()
3551 3554 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3552 3555 fm.data(matched=True)
3553 3556 p = e
3554 3557 if p < len(l.line):
3555 3558 fm.startitem()
3556 3559 fm.write(b'text', b'%s', l.line[p:])
3557 3560 fm.data(matched=False)
3558 3561 fm.end()
3559 3562
3560 3563 found = False
3561 3564
3562 3565 wopts = logcmdutil.walkopts(
3563 3566 pats=pats,
3564 3567 opts=opts,
3565 3568 revspec=opts[b'rev'],
3566 3569 include_pats=opts[b'include'],
3567 3570 exclude_pats=opts[b'exclude'],
3568 3571 follow=follow,
3569 3572 force_changelog_traversal=all_files,
3570 3573 filter_revisions_by_pats=not all_files,
3571 3574 )
3572 3575 revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
3573 3576
3574 3577 ui.pager(b'grep')
3575 3578 fm = ui.formatter(b'grep', opts)
3576 3579 for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
3577 3580 r = display(fm, fn, ctx, pstates, states)
3578 3581 found = found or r
3579 3582 if r and not diff and not all_files:
3580 3583 searcher.skipfile(fn, ctx.rev())
3581 3584 fm.end()
3582 3585
3583 3586 return not found
3584 3587
3585 3588
3586 3589 @command(
3587 3590 b'heads',
3588 3591 [
3589 3592 (
3590 3593 b'r',
3591 3594 b'rev',
3592 3595 b'',
3593 3596 _(b'show only heads which are descendants of STARTREV'),
3594 3597 _(b'STARTREV'),
3595 3598 ),
3596 3599 (b't', b'topo', False, _(b'show topological heads only')),
3597 3600 (
3598 3601 b'a',
3599 3602 b'active',
3600 3603 False,
3601 3604 _(b'show active branchheads only (DEPRECATED)'),
3602 3605 ),
3603 3606 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3604 3607 ]
3605 3608 + templateopts,
3606 3609 _(b'[-ct] [-r STARTREV] [REV]...'),
3607 3610 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3608 3611 intents={INTENT_READONLY},
3609 3612 )
3610 3613 def heads(ui, repo, *branchrevs, **opts):
3611 3614 """show branch heads
3612 3615
3613 3616 With no arguments, show all open branch heads in the repository.
3614 3617 Branch heads are changesets that have no descendants on the
3615 3618 same branch. They are where development generally takes place and
3616 3619 are the usual targets for update and merge operations.
3617 3620
3618 3621 If one or more REVs are given, only open branch heads on the
3619 3622 branches associated with the specified changesets are shown. This
3620 3623 means that you can use :hg:`heads .` to see the heads on the
3621 3624 currently checked-out branch.
3622 3625
3623 3626 If -c/--closed is specified, also show branch heads marked closed
3624 3627 (see :hg:`commit --close-branch`).
3625 3628
3626 3629 If STARTREV is specified, only those heads that are descendants of
3627 3630 STARTREV will be displayed.
3628 3631
3629 3632 If -t/--topo is specified, named branch mechanics will be ignored and only
3630 3633 topological heads (changesets with no children) will be shown.
3631 3634
3632 3635 Returns 0 if matching heads are found, 1 if not.
3633 3636 """
3634 3637
3635 3638 opts = pycompat.byteskwargs(opts)
3636 3639 start = None
3637 3640 rev = opts.get(b'rev')
3638 3641 if rev:
3639 3642 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3640 3643 start = scmutil.revsingle(repo, rev, None).node()
3641 3644
3642 3645 if opts.get(b'topo'):
3643 3646 heads = [repo[h] for h in repo.heads(start)]
3644 3647 else:
3645 3648 heads = []
3646 3649 for branch in repo.branchmap():
3647 3650 heads += repo.branchheads(branch, start, opts.get(b'closed'))
3648 3651 heads = [repo[h] for h in heads]
3649 3652
3650 3653 if branchrevs:
3651 3654 branches = {
3652 3655 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3653 3656 }
3654 3657 heads = [h for h in heads if h.branch() in branches]
3655 3658
3656 3659 if opts.get(b'active') and branchrevs:
3657 3660 dagheads = repo.heads(start)
3658 3661 heads = [h for h in heads if h.node() in dagheads]
3659 3662
3660 3663 if branchrevs:
3661 3664 haveheads = {h.branch() for h in heads}
3662 3665 if branches - haveheads:
3663 3666 headless = b', '.join(b for b in branches - haveheads)
3664 3667 msg = _(b'no open branch heads found on branches %s')
3665 3668 if opts.get(b'rev'):
3666 3669 msg += _(b' (started at %s)') % opts[b'rev']
3667 3670 ui.warn((msg + b'\n') % headless)
3668 3671
3669 3672 if not heads:
3670 3673 return 1
3671 3674
3672 3675 ui.pager(b'heads')
3673 3676 heads = sorted(heads, key=lambda x: -(x.rev()))
3674 3677 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3675 3678 for ctx in heads:
3676 3679 displayer.show(ctx)
3677 3680 displayer.close()
3678 3681
3679 3682
3680 3683 @command(
3681 3684 b'help',
3682 3685 [
3683 3686 (b'e', b'extension', None, _(b'show only help for extensions')),
3684 3687 (b'c', b'command', None, _(b'show only help for commands')),
3685 3688 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3686 3689 (
3687 3690 b's',
3688 3691 b'system',
3689 3692 [],
3690 3693 _(b'show help for specific platform(s)'),
3691 3694 _(b'PLATFORM'),
3692 3695 ),
3693 3696 ],
3694 3697 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3695 3698 helpcategory=command.CATEGORY_HELP,
3696 3699 norepo=True,
3697 3700 intents={INTENT_READONLY},
3698 3701 )
3699 3702 def help_(ui, name=None, **opts):
3700 3703 """show help for a given topic or a help overview
3701 3704
3702 3705 With no arguments, print a list of commands with short help messages.
3703 3706
3704 3707 Given a topic, extension, or command name, print help for that
3705 3708 topic.
3706 3709
3707 3710 Returns 0 if successful.
3708 3711 """
3709 3712
3710 3713 keep = opts.get('system') or []
3711 3714 if len(keep) == 0:
3712 3715 if pycompat.sysplatform.startswith(b'win'):
3713 3716 keep.append(b'windows')
3714 3717 elif pycompat.sysplatform == b'OpenVMS':
3715 3718 keep.append(b'vms')
3716 3719 elif pycompat.sysplatform == b'plan9':
3717 3720 keep.append(b'plan9')
3718 3721 else:
3719 3722 keep.append(b'unix')
3720 3723 keep.append(pycompat.sysplatform.lower())
3721 3724 if ui.verbose:
3722 3725 keep.append(b'verbose')
3723 3726
3724 3727 commands = sys.modules[__name__]
3725 3728 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3726 3729 ui.pager(b'help')
3727 3730 ui.write(formatted)
3728 3731
3729 3732
3730 3733 @command(
3731 3734 b'identify|id',
3732 3735 [
3733 3736 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3734 3737 (b'n', b'num', None, _(b'show local revision number')),
3735 3738 (b'i', b'id', None, _(b'show global revision id')),
3736 3739 (b'b', b'branch', None, _(b'show branch')),
3737 3740 (b't', b'tags', None, _(b'show tags')),
3738 3741 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3739 3742 ]
3740 3743 + remoteopts
3741 3744 + formatteropts,
3742 3745 _(b'[-nibtB] [-r REV] [SOURCE]'),
3743 3746 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3744 3747 optionalrepo=True,
3745 3748 intents={INTENT_READONLY},
3746 3749 )
3747 3750 def identify(
3748 3751 ui,
3749 3752 repo,
3750 3753 source=None,
3751 3754 rev=None,
3752 3755 num=None,
3753 3756 id=None,
3754 3757 branch=None,
3755 3758 tags=None,
3756 3759 bookmarks=None,
3757 3760 **opts
3758 3761 ):
3759 3762 """identify the working directory or specified revision
3760 3763
3761 3764 Print a summary identifying the repository state at REV using one or
3762 3765 two parent hash identifiers, followed by a "+" if the working
3763 3766 directory has uncommitted changes, the branch name (if not default),
3764 3767 a list of tags, and a list of bookmarks.
3765 3768
3766 3769 When REV is not given, print a summary of the current state of the
3767 3770 repository including the working directory. Specify -r. to get information
3768 3771 of the working directory parent without scanning uncommitted changes.
3769 3772
3770 3773 Specifying a path to a repository root or Mercurial bundle will
3771 3774 cause lookup to operate on that repository/bundle.
3772 3775
3773 3776 .. container:: verbose
3774 3777
3775 3778 Template:
3776 3779
3777 3780 The following keywords are supported in addition to the common template
3778 3781 keywords and functions. See also :hg:`help templates`.
3779 3782
3780 3783 :dirty: String. Character ``+`` denoting if the working directory has
3781 3784 uncommitted changes.
3782 3785 :id: String. One or two nodes, optionally followed by ``+``.
3783 3786 :parents: List of strings. Parent nodes of the changeset.
3784 3787
3785 3788 Examples:
3786 3789
3787 3790 - generate a build identifier for the working directory::
3788 3791
3789 3792 hg id --id > build-id.dat
3790 3793
3791 3794 - find the revision corresponding to a tag::
3792 3795
3793 3796 hg id -n -r 1.3
3794 3797
3795 3798 - check the most recent revision of a remote repository::
3796 3799
3797 3800 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3798 3801
3799 3802 See :hg:`log` for generating more information about specific revisions,
3800 3803 including full hash identifiers.
3801 3804
3802 3805 Returns 0 if successful.
3803 3806 """
3804 3807
3805 3808 opts = pycompat.byteskwargs(opts)
3806 3809 if not repo and not source:
3807 3810 raise error.InputError(
3808 3811 _(b"there is no Mercurial repository here (.hg not found)")
3809 3812 )
3810 3813
3811 3814 default = not (num or id or branch or tags or bookmarks)
3812 3815 output = []
3813 3816 revs = []
3814 3817
3815 3818 if source:
3816 3819 source, branches = hg.parseurl(ui.expandpath(source))
3817 3820 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3818 3821 repo = peer.local()
3819 3822 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3820 3823
3821 3824 fm = ui.formatter(b'identify', opts)
3822 3825 fm.startitem()
3823 3826
3824 3827 if not repo:
3825 3828 if num or branch or tags:
3826 3829 raise error.InputError(
3827 3830 _(b"can't query remote revision number, branch, or tags")
3828 3831 )
3829 3832 if not rev and revs:
3830 3833 rev = revs[0]
3831 3834 if not rev:
3832 3835 rev = b"tip"
3833 3836
3834 3837 remoterev = peer.lookup(rev)
3835 3838 hexrev = fm.hexfunc(remoterev)
3836 3839 if default or id:
3837 3840 output = [hexrev]
3838 3841 fm.data(id=hexrev)
3839 3842
3840 3843 @util.cachefunc
3841 3844 def getbms():
3842 3845 bms = []
3843 3846
3844 3847 if b'bookmarks' in peer.listkeys(b'namespaces'):
3845 3848 hexremoterev = hex(remoterev)
3846 3849 bms = [
3847 3850 bm
3848 3851 for bm, bmr in pycompat.iteritems(
3849 3852 peer.listkeys(b'bookmarks')
3850 3853 )
3851 3854 if bmr == hexremoterev
3852 3855 ]
3853 3856
3854 3857 return sorted(bms)
3855 3858
3856 3859 if fm.isplain():
3857 3860 if bookmarks:
3858 3861 output.extend(getbms())
3859 3862 elif default and not ui.quiet:
3860 3863 # multiple bookmarks for a single parent separated by '/'
3861 3864 bm = b'/'.join(getbms())
3862 3865 if bm:
3863 3866 output.append(bm)
3864 3867 else:
3865 3868 fm.data(node=hex(remoterev))
3866 3869 if bookmarks or b'bookmarks' in fm.datahint():
3867 3870 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3868 3871 else:
3869 3872 if rev:
3870 3873 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3871 3874 ctx = scmutil.revsingle(repo, rev, None)
3872 3875
3873 3876 if ctx.rev() is None:
3874 3877 ctx = repo[None]
3875 3878 parents = ctx.parents()
3876 3879 taglist = []
3877 3880 for p in parents:
3878 3881 taglist.extend(p.tags())
3879 3882
3880 3883 dirty = b""
3881 3884 if ctx.dirty(missing=True, merge=False, branch=False):
3882 3885 dirty = b'+'
3883 3886 fm.data(dirty=dirty)
3884 3887
3885 3888 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3886 3889 if default or id:
3887 3890 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
3888 3891 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
3889 3892
3890 3893 if num:
3891 3894 numoutput = [b"%d" % p.rev() for p in parents]
3892 3895 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
3893 3896
3894 3897 fm.data(
3895 3898 parents=fm.formatlist(
3896 3899 [fm.hexfunc(p.node()) for p in parents], name=b'node'
3897 3900 )
3898 3901 )
3899 3902 else:
3900 3903 hexoutput = fm.hexfunc(ctx.node())
3901 3904 if default or id:
3902 3905 output = [hexoutput]
3903 3906 fm.data(id=hexoutput)
3904 3907
3905 3908 if num:
3906 3909 output.append(pycompat.bytestr(ctx.rev()))
3907 3910 taglist = ctx.tags()
3908 3911
3909 3912 if default and not ui.quiet:
3910 3913 b = ctx.branch()
3911 3914 if b != b'default':
3912 3915 output.append(b"(%s)" % b)
3913 3916
3914 3917 # multiple tags for a single parent separated by '/'
3915 3918 t = b'/'.join(taglist)
3916 3919 if t:
3917 3920 output.append(t)
3918 3921
3919 3922 # multiple bookmarks for a single parent separated by '/'
3920 3923 bm = b'/'.join(ctx.bookmarks())
3921 3924 if bm:
3922 3925 output.append(bm)
3923 3926 else:
3924 3927 if branch:
3925 3928 output.append(ctx.branch())
3926 3929
3927 3930 if tags:
3928 3931 output.extend(taglist)
3929 3932
3930 3933 if bookmarks:
3931 3934 output.extend(ctx.bookmarks())
3932 3935
3933 3936 fm.data(node=ctx.hex())
3934 3937 fm.data(branch=ctx.branch())
3935 3938 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
3936 3939 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
3937 3940 fm.context(ctx=ctx)
3938 3941
3939 3942 fm.plain(b"%s\n" % b' '.join(output))
3940 3943 fm.end()
3941 3944
3942 3945
3943 3946 @command(
3944 3947 b'import|patch',
3945 3948 [
3946 3949 (
3947 3950 b'p',
3948 3951 b'strip',
3949 3952 1,
3950 3953 _(
3951 3954 b'directory strip option for patch. This has the same '
3952 3955 b'meaning as the corresponding patch option'
3953 3956 ),
3954 3957 _(b'NUM'),
3955 3958 ),
3956 3959 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
3957 3960 (b'', b'secret', None, _(b'use the secret phase for committing')),
3958 3961 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
3959 3962 (
3960 3963 b'f',
3961 3964 b'force',
3962 3965 None,
3963 3966 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
3964 3967 ),
3965 3968 (
3966 3969 b'',
3967 3970 b'no-commit',
3968 3971 None,
3969 3972 _(b"don't commit, just update the working directory"),
3970 3973 ),
3971 3974 (
3972 3975 b'',
3973 3976 b'bypass',
3974 3977 None,
3975 3978 _(b"apply patch without touching the working directory"),
3976 3979 ),
3977 3980 (b'', b'partial', None, _(b'commit even if some hunks fail')),
3978 3981 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
3979 3982 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
3980 3983 (
3981 3984 b'',
3982 3985 b'import-branch',
3983 3986 None,
3984 3987 _(b'use any branch information in patch (implied by --exact)'),
3985 3988 ),
3986 3989 ]
3987 3990 + commitopts
3988 3991 + commitopts2
3989 3992 + similarityopts,
3990 3993 _(b'[OPTION]... PATCH...'),
3991 3994 helpcategory=command.CATEGORY_IMPORT_EXPORT,
3992 3995 )
3993 3996 def import_(ui, repo, patch1=None, *patches, **opts):
3994 3997 """import an ordered set of patches
3995 3998
3996 3999 Import a list of patches and commit them individually (unless
3997 4000 --no-commit is specified).
3998 4001
3999 4002 To read a patch from standard input (stdin), use "-" as the patch
4000 4003 name. If a URL is specified, the patch will be downloaded from
4001 4004 there.
4002 4005
4003 4006 Import first applies changes to the working directory (unless
4004 4007 --bypass is specified), import will abort if there are outstanding
4005 4008 changes.
4006 4009
4007 4010 Use --bypass to apply and commit patches directly to the
4008 4011 repository, without affecting the working directory. Without
4009 4012 --exact, patches will be applied on top of the working directory
4010 4013 parent revision.
4011 4014
4012 4015 You can import a patch straight from a mail message. Even patches
4013 4016 as attachments work (to use the body part, it must have type
4014 4017 text/plain or text/x-patch). From and Subject headers of email
4015 4018 message are used as default committer and commit message. All
4016 4019 text/plain body parts before first diff are added to the commit
4017 4020 message.
4018 4021
4019 4022 If the imported patch was generated by :hg:`export`, user and
4020 4023 description from patch override values from message headers and
4021 4024 body. Values given on command line with -m/--message and -u/--user
4022 4025 override these.
4023 4026
4024 4027 If --exact is specified, import will set the working directory to
4025 4028 the parent of each patch before applying it, and will abort if the
4026 4029 resulting changeset has a different ID than the one recorded in
4027 4030 the patch. This will guard against various ways that portable
4028 4031 patch formats and mail systems might fail to transfer Mercurial
4029 4032 data or metadata. See :hg:`bundle` for lossless transmission.
4030 4033
4031 4034 Use --partial to ensure a changeset will be created from the patch
4032 4035 even if some hunks fail to apply. Hunks that fail to apply will be
4033 4036 written to a <target-file>.rej file. Conflicts can then be resolved
4034 4037 by hand before :hg:`commit --amend` is run to update the created
4035 4038 changeset. This flag exists to let people import patches that
4036 4039 partially apply without losing the associated metadata (author,
4037 4040 date, description, ...).
4038 4041
4039 4042 .. note::
4040 4043
4041 4044 When no hunks apply cleanly, :hg:`import --partial` will create
4042 4045 an empty changeset, importing only the patch metadata.
4043 4046
4044 4047 With -s/--similarity, hg will attempt to discover renames and
4045 4048 copies in the patch in the same way as :hg:`addremove`.
4046 4049
4047 4050 It is possible to use external patch programs to perform the patch
4048 4051 by setting the ``ui.patch`` configuration option. For the default
4049 4052 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4050 4053 See :hg:`help config` for more information about configuration
4051 4054 files and how to use these options.
4052 4055
4053 4056 See :hg:`help dates` for a list of formats valid for -d/--date.
4054 4057
4055 4058 .. container:: verbose
4056 4059
4057 4060 Examples:
4058 4061
4059 4062 - import a traditional patch from a website and detect renames::
4060 4063
4061 4064 hg import -s 80 http://example.com/bugfix.patch
4062 4065
4063 4066 - import a changeset from an hgweb server::
4064 4067
4065 4068 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4066 4069
4067 4070 - import all the patches in an Unix-style mbox::
4068 4071
4069 4072 hg import incoming-patches.mbox
4070 4073
4071 4074 - import patches from stdin::
4072 4075
4073 4076 hg import -
4074 4077
4075 4078 - attempt to exactly restore an exported changeset (not always
4076 4079 possible)::
4077 4080
4078 4081 hg import --exact proposed-fix.patch
4079 4082
4080 4083 - use an external tool to apply a patch which is too fuzzy for
4081 4084 the default internal tool.
4082 4085
4083 4086 hg import --config ui.patch="patch --merge" fuzzy.patch
4084 4087
4085 4088 - change the default fuzzing from 2 to a less strict 7
4086 4089
4087 4090 hg import --config ui.fuzz=7 fuzz.patch
4088 4091
4089 4092 Returns 0 on success, 1 on partial success (see --partial).
4090 4093 """
4091 4094
4092 4095 cmdutil.check_incompatible_arguments(
4093 4096 opts, 'no_commit', ['bypass', 'secret']
4094 4097 )
4095 4098 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4096 4099 opts = pycompat.byteskwargs(opts)
4097 4100 if not patch1:
4098 4101 raise error.InputError(_(b'need at least one patch to import'))
4099 4102
4100 4103 patches = (patch1,) + patches
4101 4104
4102 4105 date = opts.get(b'date')
4103 4106 if date:
4104 4107 opts[b'date'] = dateutil.parsedate(date)
4105 4108
4106 4109 exact = opts.get(b'exact')
4107 4110 update = not opts.get(b'bypass')
4108 4111 try:
4109 4112 sim = float(opts.get(b'similarity') or 0)
4110 4113 except ValueError:
4111 4114 raise error.InputError(_(b'similarity must be a number'))
4112 4115 if sim < 0 or sim > 100:
4113 4116 raise error.InputError(_(b'similarity must be between 0 and 100'))
4114 4117 if sim and not update:
4115 4118 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4116 4119
4117 4120 base = opts[b"base"]
4118 4121 msgs = []
4119 4122 ret = 0
4120 4123
4121 4124 with repo.wlock():
4122 4125 if update:
4123 4126 cmdutil.checkunfinished(repo)
4124 4127 if exact or not opts.get(b'force'):
4125 4128 cmdutil.bailifchanged(repo)
4126 4129
4127 4130 if not opts.get(b'no_commit'):
4128 4131 lock = repo.lock
4129 4132 tr = lambda: repo.transaction(b'import')
4130 4133 dsguard = util.nullcontextmanager
4131 4134 else:
4132 4135 lock = util.nullcontextmanager
4133 4136 tr = util.nullcontextmanager
4134 4137 dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
4135 4138 with lock(), tr(), dsguard():
4136 4139 parents = repo[None].parents()
4137 4140 for patchurl in patches:
4138 4141 if patchurl == b'-':
4139 4142 ui.status(_(b'applying patch from stdin\n'))
4140 4143 patchfile = ui.fin
4141 4144 patchurl = b'stdin' # for error message
4142 4145 else:
4143 4146 patchurl = os.path.join(base, patchurl)
4144 4147 ui.status(_(b'applying %s\n') % patchurl)
4145 4148 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4146 4149
4147 4150 haspatch = False
4148 4151 for hunk in patch.split(patchfile):
4149 4152 with patch.extract(ui, hunk) as patchdata:
4150 4153 msg, node, rej = cmdutil.tryimportone(
4151 4154 ui, repo, patchdata, parents, opts, msgs, hg.clean
4152 4155 )
4153 4156 if msg:
4154 4157 haspatch = True
4155 4158 ui.note(msg + b'\n')
4156 4159 if update or exact:
4157 4160 parents = repo[None].parents()
4158 4161 else:
4159 4162 parents = [repo[node]]
4160 4163 if rej:
4161 4164 ui.write_err(_(b"patch applied partially\n"))
4162 4165 ui.write_err(
4163 4166 _(
4164 4167 b"(fix the .rej files and run "
4165 4168 b"`hg commit --amend`)\n"
4166 4169 )
4167 4170 )
4168 4171 ret = 1
4169 4172 break
4170 4173
4171 4174 if not haspatch:
4172 4175 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4173 4176
4174 4177 if msgs:
4175 4178 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4176 4179 return ret
4177 4180
4178 4181
4179 4182 @command(
4180 4183 b'incoming|in',
4181 4184 [
4182 4185 (
4183 4186 b'f',
4184 4187 b'force',
4185 4188 None,
4186 4189 _(b'run even if remote repository is unrelated'),
4187 4190 ),
4188 4191 (b'n', b'newest-first', None, _(b'show newest record first')),
4189 4192 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4190 4193 (
4191 4194 b'r',
4192 4195 b'rev',
4193 4196 [],
4194 4197 _(b'a remote changeset intended to be added'),
4195 4198 _(b'REV'),
4196 4199 ),
4197 4200 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4198 4201 (
4199 4202 b'b',
4200 4203 b'branch',
4201 4204 [],
4202 4205 _(b'a specific branch you would like to pull'),
4203 4206 _(b'BRANCH'),
4204 4207 ),
4205 4208 ]
4206 4209 + logopts
4207 4210 + remoteopts
4208 4211 + subrepoopts,
4209 4212 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4210 4213 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4211 4214 )
4212 4215 def incoming(ui, repo, source=b"default", **opts):
4213 4216 """show new changesets found in source
4214 4217
4215 4218 Show new changesets found in the specified path/URL or the default
4216 4219 pull location. These are the changesets that would have been pulled
4217 4220 by :hg:`pull` at the time you issued this command.
4218 4221
4219 4222 See pull for valid source format details.
4220 4223
4221 4224 .. container:: verbose
4222 4225
4223 4226 With -B/--bookmarks, the result of bookmark comparison between
4224 4227 local and remote repositories is displayed. With -v/--verbose,
4225 4228 status is also displayed for each bookmark like below::
4226 4229
4227 4230 BM1 01234567890a added
4228 4231 BM2 1234567890ab advanced
4229 4232 BM3 234567890abc diverged
4230 4233 BM4 34567890abcd changed
4231 4234
4232 4235 The action taken locally when pulling depends on the
4233 4236 status of each bookmark:
4234 4237
4235 4238 :``added``: pull will create it
4236 4239 :``advanced``: pull will update it
4237 4240 :``diverged``: pull will create a divergent bookmark
4238 4241 :``changed``: result depends on remote changesets
4239 4242
4240 4243 From the point of view of pulling behavior, bookmark
4241 4244 existing only in the remote repository are treated as ``added``,
4242 4245 even if it is in fact locally deleted.
4243 4246
4244 4247 .. container:: verbose
4245 4248
4246 4249 For remote repository, using --bundle avoids downloading the
4247 4250 changesets twice if the incoming is followed by a pull.
4248 4251
4249 4252 Examples:
4250 4253
4251 4254 - show incoming changes with patches and full description::
4252 4255
4253 4256 hg incoming -vp
4254 4257
4255 4258 - show incoming changes excluding merges, store a bundle::
4256 4259
4257 4260 hg in -vpM --bundle incoming.hg
4258 4261 hg pull incoming.hg
4259 4262
4260 4263 - briefly list changes inside a bundle::
4261 4264
4262 4265 hg in changes.hg -T "{desc|firstline}\\n"
4263 4266
4264 4267 Returns 0 if there are incoming changes, 1 otherwise.
4265 4268 """
4266 4269 opts = pycompat.byteskwargs(opts)
4267 4270 if opts.get(b'graph'):
4268 4271 logcmdutil.checkunsupportedgraphflags([], opts)
4269 4272
4270 4273 def display(other, chlist, displayer):
4271 4274 revdag = logcmdutil.graphrevs(other, chlist, opts)
4272 4275 logcmdutil.displaygraph(
4273 4276 ui, repo, revdag, displayer, graphmod.asciiedges
4274 4277 )
4275 4278
4276 4279 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4277 4280 return 0
4278 4281
4279 4282 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'bundle'])
4280 4283
4281 4284 if opts.get(b'bookmarks'):
4282 4285 source, branches = hg.parseurl(
4283 4286 ui.expandpath(source), opts.get(b'branch')
4284 4287 )
4285 4288 other = hg.peer(repo, opts, source)
4286 4289 if b'bookmarks' not in other.listkeys(b'namespaces'):
4287 4290 ui.warn(_(b"remote doesn't support bookmarks\n"))
4288 4291 return 0
4289 4292 ui.pager(b'incoming')
4290 4293 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
4291 4294 return bookmarks.incoming(ui, repo, other)
4292 4295
4293 4296 repo._subtoppath = ui.expandpath(source)
4294 4297 try:
4295 4298 return hg.incoming(ui, repo, source, opts)
4296 4299 finally:
4297 4300 del repo._subtoppath
4298 4301
4299 4302
4300 4303 @command(
4301 4304 b'init',
4302 4305 remoteopts,
4303 4306 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4304 4307 helpcategory=command.CATEGORY_REPO_CREATION,
4305 4308 helpbasic=True,
4306 4309 norepo=True,
4307 4310 )
4308 4311 def init(ui, dest=b".", **opts):
4309 4312 """create a new repository in the given directory
4310 4313
4311 4314 Initialize a new repository in the given directory. If the given
4312 4315 directory does not exist, it will be created.
4313 4316
4314 4317 If no directory is given, the current directory is used.
4315 4318
4316 4319 It is possible to specify an ``ssh://`` URL as the destination.
4317 4320 See :hg:`help urls` for more information.
4318 4321
4319 4322 Returns 0 on success.
4320 4323 """
4321 4324 opts = pycompat.byteskwargs(opts)
4322 4325 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4323 4326
4324 4327
4325 4328 @command(
4326 4329 b'locate',
4327 4330 [
4328 4331 (
4329 4332 b'r',
4330 4333 b'rev',
4331 4334 b'',
4332 4335 _(b'search the repository as it is in REV'),
4333 4336 _(b'REV'),
4334 4337 ),
4335 4338 (
4336 4339 b'0',
4337 4340 b'print0',
4338 4341 None,
4339 4342 _(b'end filenames with NUL, for use with xargs'),
4340 4343 ),
4341 4344 (
4342 4345 b'f',
4343 4346 b'fullpath',
4344 4347 None,
4345 4348 _(b'print complete paths from the filesystem root'),
4346 4349 ),
4347 4350 ]
4348 4351 + walkopts,
4349 4352 _(b'[OPTION]... [PATTERN]...'),
4350 4353 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4351 4354 )
4352 4355 def locate(ui, repo, *pats, **opts):
4353 4356 """locate files matching specific patterns (DEPRECATED)
4354 4357
4355 4358 Print files under Mercurial control in the working directory whose
4356 4359 names match the given patterns.
4357 4360
4358 4361 By default, this command searches all directories in the working
4359 4362 directory. To search just the current directory and its
4360 4363 subdirectories, use "--include .".
4361 4364
4362 4365 If no patterns are given to match, this command prints the names
4363 4366 of all files under Mercurial control in the working directory.
4364 4367
4365 4368 If you want to feed the output of this command into the "xargs"
4366 4369 command, use the -0 option to both this command and "xargs". This
4367 4370 will avoid the problem of "xargs" treating single filenames that
4368 4371 contain whitespace as multiple filenames.
4369 4372
4370 4373 See :hg:`help files` for a more versatile command.
4371 4374
4372 4375 Returns 0 if a match is found, 1 otherwise.
4373 4376 """
4374 4377 opts = pycompat.byteskwargs(opts)
4375 4378 if opts.get(b'print0'):
4376 4379 end = b'\0'
4377 4380 else:
4378 4381 end = b'\n'
4379 4382 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
4380 4383
4381 4384 ret = 1
4382 4385 m = scmutil.match(
4383 4386 ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
4384 4387 )
4385 4388
4386 4389 ui.pager(b'locate')
4387 4390 if ctx.rev() is None:
4388 4391 # When run on the working copy, "locate" includes removed files, so
4389 4392 # we get the list of files from the dirstate.
4390 4393 filesgen = sorted(repo.dirstate.matches(m))
4391 4394 else:
4392 4395 filesgen = ctx.matches(m)
4393 4396 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4394 4397 for abs in filesgen:
4395 4398 if opts.get(b'fullpath'):
4396 4399 ui.write(repo.wjoin(abs), end)
4397 4400 else:
4398 4401 ui.write(uipathfn(abs), end)
4399 4402 ret = 0
4400 4403
4401 4404 return ret
4402 4405
4403 4406
4404 4407 @command(
4405 4408 b'log|history',
4406 4409 [
4407 4410 (
4408 4411 b'f',
4409 4412 b'follow',
4410 4413 None,
4411 4414 _(
4412 4415 b'follow changeset history, or file history across copies and renames'
4413 4416 ),
4414 4417 ),
4415 4418 (
4416 4419 b'',
4417 4420 b'follow-first',
4418 4421 None,
4419 4422 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4420 4423 ),
4421 4424 (
4422 4425 b'd',
4423 4426 b'date',
4424 4427 b'',
4425 4428 _(b'show revisions matching date spec'),
4426 4429 _(b'DATE'),
4427 4430 ),
4428 4431 (b'C', b'copies', None, _(b'show copied files')),
4429 4432 (
4430 4433 b'k',
4431 4434 b'keyword',
4432 4435 [],
4433 4436 _(b'do case-insensitive search for a given text'),
4434 4437 _(b'TEXT'),
4435 4438 ),
4436 4439 (
4437 4440 b'r',
4438 4441 b'rev',
4439 4442 [],
4440 4443 _(b'show the specified revision or revset'),
4441 4444 _(b'REV'),
4442 4445 ),
4443 4446 (
4444 4447 b'L',
4445 4448 b'line-range',
4446 4449 [],
4447 4450 _(b'follow line range of specified file (EXPERIMENTAL)'),
4448 4451 _(b'FILE,RANGE'),
4449 4452 ),
4450 4453 (
4451 4454 b'',
4452 4455 b'removed',
4453 4456 None,
4454 4457 _(b'include revisions where files were removed'),
4455 4458 ),
4456 4459 (
4457 4460 b'm',
4458 4461 b'only-merges',
4459 4462 None,
4460 4463 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4461 4464 ),
4462 4465 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4463 4466 (
4464 4467 b'',
4465 4468 b'only-branch',
4466 4469 [],
4467 4470 _(
4468 4471 b'show only changesets within the given named branch (DEPRECATED)'
4469 4472 ),
4470 4473 _(b'BRANCH'),
4471 4474 ),
4472 4475 (
4473 4476 b'b',
4474 4477 b'branch',
4475 4478 [],
4476 4479 _(b'show changesets within the given named branch'),
4477 4480 _(b'BRANCH'),
4478 4481 ),
4479 4482 (
4480 4483 b'B',
4481 4484 b'bookmark',
4482 4485 [],
4483 4486 _(b"show changesets within the given bookmark"),
4484 4487 _(b'BOOKMARK'),
4485 4488 ),
4486 4489 (
4487 4490 b'P',
4488 4491 b'prune',
4489 4492 [],
4490 4493 _(b'do not display revision or any of its ancestors'),
4491 4494 _(b'REV'),
4492 4495 ),
4493 4496 ]
4494 4497 + logopts
4495 4498 + walkopts,
4496 4499 _(b'[OPTION]... [FILE]'),
4497 4500 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4498 4501 helpbasic=True,
4499 4502 inferrepo=True,
4500 4503 intents={INTENT_READONLY},
4501 4504 )
4502 4505 def log(ui, repo, *pats, **opts):
4503 4506 """show revision history of entire repository or files
4504 4507
4505 4508 Print the revision history of the specified files or the entire
4506 4509 project.
4507 4510
4508 4511 If no revision range is specified, the default is ``tip:0`` unless
4509 4512 --follow is set, in which case the working directory parent is
4510 4513 used as the starting revision.
4511 4514
4512 4515 File history is shown without following rename or copy history of
4513 4516 files. Use -f/--follow with a filename to follow history across
4514 4517 renames and copies. --follow without a filename will only show
4515 4518 ancestors of the starting revision.
4516 4519
4517 4520 By default this command prints revision number and changeset id,
4518 4521 tags, non-trivial parents, user, date and time, and a summary for
4519 4522 each commit. When the -v/--verbose switch is used, the list of
4520 4523 changed files and full commit message are shown.
4521 4524
4522 4525 With --graph the revisions are shown as an ASCII art DAG with the most
4523 4526 recent changeset at the top.
4524 4527 'o' is a changeset, '@' is a working directory parent, '%' is a changeset
4525 4528 involved in an unresolved merge conflict, '_' closes a branch,
4526 4529 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4527 4530 changeset from the lines below is a parent of the 'o' merge on the same
4528 4531 line.
4529 4532 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4530 4533 of a '|' indicates one or more revisions in a path are omitted.
4531 4534
4532 4535 .. container:: verbose
4533 4536
4534 4537 Use -L/--line-range FILE,M:N options to follow the history of lines
4535 4538 from M to N in FILE. With -p/--patch only diff hunks affecting
4536 4539 specified line range will be shown. This option requires --follow;
4537 4540 it can be specified multiple times. Currently, this option is not
4538 4541 compatible with --graph. This option is experimental.
4539 4542
4540 4543 .. note::
4541 4544
4542 4545 :hg:`log --patch` may generate unexpected diff output for merge
4543 4546 changesets, as it will only compare the merge changeset against
4544 4547 its first parent. Also, only files different from BOTH parents
4545 4548 will appear in files:.
4546 4549
4547 4550 .. note::
4548 4551
4549 4552 For performance reasons, :hg:`log FILE` may omit duplicate changes
4550 4553 made on branches and will not show removals or mode changes. To
4551 4554 see all such changes, use the --removed switch.
4552 4555
4553 4556 .. container:: verbose
4554 4557
4555 4558 .. note::
4556 4559
4557 4560 The history resulting from -L/--line-range options depends on diff
4558 4561 options; for instance if white-spaces are ignored, respective changes
4559 4562 with only white-spaces in specified line range will not be listed.
4560 4563
4561 4564 .. container:: verbose
4562 4565
4563 4566 Some examples:
4564 4567
4565 4568 - changesets with full descriptions and file lists::
4566 4569
4567 4570 hg log -v
4568 4571
4569 4572 - changesets ancestral to the working directory::
4570 4573
4571 4574 hg log -f
4572 4575
4573 4576 - last 10 commits on the current branch::
4574 4577
4575 4578 hg log -l 10 -b .
4576 4579
4577 4580 - changesets showing all modifications of a file, including removals::
4578 4581
4579 4582 hg log --removed file.c
4580 4583
4581 4584 - all changesets that touch a directory, with diffs, excluding merges::
4582 4585
4583 4586 hg log -Mp lib/
4584 4587
4585 4588 - all revision numbers that match a keyword::
4586 4589
4587 4590 hg log -k bug --template "{rev}\\n"
4588 4591
4589 4592 - the full hash identifier of the working directory parent::
4590 4593
4591 4594 hg log -r . --template "{node}\\n"
4592 4595
4593 4596 - list available log templates::
4594 4597
4595 4598 hg log -T list
4596 4599
4597 4600 - check if a given changeset is included in a tagged release::
4598 4601
4599 4602 hg log -r "a21ccf and ancestor(1.9)"
4600 4603
4601 4604 - find all changesets by some user in a date range::
4602 4605
4603 4606 hg log -k alice -d "may 2008 to jul 2008"
4604 4607
4605 4608 - summary of all changesets after the last tag::
4606 4609
4607 4610 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4608 4611
4609 4612 - changesets touching lines 13 to 23 for file.c::
4610 4613
4611 4614 hg log -L file.c,13:23
4612 4615
4613 4616 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4614 4617 main.c with patch::
4615 4618
4616 4619 hg log -L file.c,13:23 -L main.c,2:6 -p
4617 4620
4618 4621 See :hg:`help dates` for a list of formats valid for -d/--date.
4619 4622
4620 4623 See :hg:`help revisions` for more about specifying and ordering
4621 4624 revisions.
4622 4625
4623 4626 See :hg:`help templates` for more about pre-packaged styles and
4624 4627 specifying custom templates. The default template used by the log
4625 4628 command can be customized via the ``command-templates.log`` configuration
4626 4629 setting.
4627 4630
4628 4631 Returns 0 on success.
4629 4632
4630 4633 """
4631 4634 opts = pycompat.byteskwargs(opts)
4632 4635 linerange = opts.get(b'line_range')
4633 4636
4634 4637 if linerange and not opts.get(b'follow'):
4635 4638 raise error.InputError(_(b'--line-range requires --follow'))
4636 4639
4637 4640 if linerange and pats:
4638 4641 # TODO: take pats as patterns with no line-range filter
4639 4642 raise error.InputError(
4640 4643 _(b'FILE arguments are not compatible with --line-range option')
4641 4644 )
4642 4645
4643 4646 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4644 4647 walk_opts = logcmdutil.parseopts(ui, pats, opts)
4645 4648 revs, differ = logcmdutil.getrevs(repo, walk_opts)
4646 4649 if linerange:
4647 4650 # TODO: should follow file history from logcmdutil._initialrevs(),
4648 4651 # then filter the result by logcmdutil._makerevset() and --limit
4649 4652 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4650 4653
4651 4654 getcopies = None
4652 4655 if opts.get(b'copies'):
4653 4656 endrev = None
4654 4657 if revs:
4655 4658 endrev = revs.max() + 1
4656 4659 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4657 4660
4658 4661 ui.pager(b'log')
4659 4662 displayer = logcmdutil.changesetdisplayer(
4660 4663 ui, repo, opts, differ, buffered=True
4661 4664 )
4662 4665 if opts.get(b'graph'):
4663 4666 displayfn = logcmdutil.displaygraphrevs
4664 4667 else:
4665 4668 displayfn = logcmdutil.displayrevs
4666 4669 displayfn(ui, repo, revs, displayer, getcopies)
4667 4670
4668 4671
4669 4672 @command(
4670 4673 b'manifest',
4671 4674 [
4672 4675 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4673 4676 (b'', b'all', False, _(b"list files from all revisions")),
4674 4677 ]
4675 4678 + formatteropts,
4676 4679 _(b'[-r REV]'),
4677 4680 helpcategory=command.CATEGORY_MAINTENANCE,
4678 4681 intents={INTENT_READONLY},
4679 4682 )
4680 4683 def manifest(ui, repo, node=None, rev=None, **opts):
4681 4684 """output the current or given revision of the project manifest
4682 4685
4683 4686 Print a list of version controlled files for the given revision.
4684 4687 If no revision is given, the first parent of the working directory
4685 4688 is used, or the null revision if no revision is checked out.
4686 4689
4687 4690 With -v, print file permissions, symlink and executable bits.
4688 4691 With --debug, print file revision hashes.
4689 4692
4690 4693 If option --all is specified, the list of all files from all revisions
4691 4694 is printed. This includes deleted and renamed files.
4692 4695
4693 4696 Returns 0 on success.
4694 4697 """
4695 4698 opts = pycompat.byteskwargs(opts)
4696 4699 fm = ui.formatter(b'manifest', opts)
4697 4700
4698 4701 if opts.get(b'all'):
4699 4702 if rev or node:
4700 4703 raise error.InputError(_(b"can't specify a revision with --all"))
4701 4704
4702 4705 res = set()
4703 4706 for rev in repo:
4704 4707 ctx = repo[rev]
4705 4708 res |= set(ctx.files())
4706 4709
4707 4710 ui.pager(b'manifest')
4708 4711 for f in sorted(res):
4709 4712 fm.startitem()
4710 4713 fm.write(b"path", b'%s\n', f)
4711 4714 fm.end()
4712 4715 return
4713 4716
4714 4717 if rev and node:
4715 4718 raise error.InputError(_(b"please specify just one revision"))
4716 4719
4717 4720 if not node:
4718 4721 node = rev
4719 4722
4720 4723 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4721 4724 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4722 4725 if node:
4723 4726 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4724 4727 ctx = scmutil.revsingle(repo, node)
4725 4728 mf = ctx.manifest()
4726 4729 ui.pager(b'manifest')
4727 4730 for f in ctx:
4728 4731 fm.startitem()
4729 4732 fm.context(ctx=ctx)
4730 4733 fl = ctx[f].flags()
4731 4734 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4732 4735 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4733 4736 fm.write(b'path', b'%s\n', f)
4734 4737 fm.end()
4735 4738
4736 4739
4737 4740 @command(
4738 4741 b'merge',
4739 4742 [
4740 4743 (
4741 4744 b'f',
4742 4745 b'force',
4743 4746 None,
4744 4747 _(b'force a merge including outstanding changes (DEPRECATED)'),
4745 4748 ),
4746 4749 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4747 4750 (
4748 4751 b'P',
4749 4752 b'preview',
4750 4753 None,
4751 4754 _(b'review revisions to merge (no merge is performed)'),
4752 4755 ),
4753 4756 (b'', b'abort', None, _(b'abort the ongoing merge')),
4754 4757 ]
4755 4758 + mergetoolopts,
4756 4759 _(b'[-P] [[-r] REV]'),
4757 4760 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4758 4761 helpbasic=True,
4759 4762 )
4760 4763 def merge(ui, repo, node=None, **opts):
4761 4764 """merge another revision into working directory
4762 4765
4763 4766 The current working directory is updated with all changes made in
4764 4767 the requested revision since the last common predecessor revision.
4765 4768
4766 4769 Files that changed between either parent are marked as changed for
4767 4770 the next commit and a commit must be performed before any further
4768 4771 updates to the repository are allowed. The next commit will have
4769 4772 two parents.
4770 4773
4771 4774 ``--tool`` can be used to specify the merge tool used for file
4772 4775 merges. It overrides the HGMERGE environment variable and your
4773 4776 configuration files. See :hg:`help merge-tools` for options.
4774 4777
4775 4778 If no revision is specified, the working directory's parent is a
4776 4779 head revision, and the current branch contains exactly one other
4777 4780 head, the other head is merged with by default. Otherwise, an
4778 4781 explicit revision with which to merge must be provided.
4779 4782
4780 4783 See :hg:`help resolve` for information on handling file conflicts.
4781 4784
4782 4785 To undo an uncommitted merge, use :hg:`merge --abort` which
4783 4786 will check out a clean copy of the original merge parent, losing
4784 4787 all changes.
4785 4788
4786 4789 Returns 0 on success, 1 if there are unresolved files.
4787 4790 """
4788 4791
4789 4792 opts = pycompat.byteskwargs(opts)
4790 4793 abort = opts.get(b'abort')
4791 4794 if abort and repo.dirstate.p2() == nullid:
4792 4795 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4793 4796 cmdutil.check_incompatible_arguments(opts, b'abort', [b'rev', b'preview'])
4794 4797 if abort:
4795 4798 state = cmdutil.getunfinishedstate(repo)
4796 4799 if state and state._opname != b'merge':
4797 4800 raise error.StateError(
4798 4801 _(b'cannot abort merge with %s in progress') % (state._opname),
4799 4802 hint=state.hint(),
4800 4803 )
4801 4804 if node:
4802 4805 raise error.InputError(_(b"cannot specify a node with --abort"))
4803 4806 return hg.abortmerge(repo.ui, repo)
4804 4807
4805 4808 if opts.get(b'rev') and node:
4806 4809 raise error.InputError(_(b"please specify just one revision"))
4807 4810 if not node:
4808 4811 node = opts.get(b'rev')
4809 4812
4810 4813 if node:
4811 4814 ctx = scmutil.revsingle(repo, node)
4812 4815 else:
4813 4816 if ui.configbool(b'commands', b'merge.require-rev'):
4814 4817 raise error.InputError(
4815 4818 _(
4816 4819 b'configuration requires specifying revision to merge '
4817 4820 b'with'
4818 4821 )
4819 4822 )
4820 4823 ctx = repo[destutil.destmerge(repo)]
4821 4824
4822 4825 if ctx.node() is None:
4823 4826 raise error.InputError(
4824 4827 _(b'merging with the working copy has no effect')
4825 4828 )
4826 4829
4827 4830 if opts.get(b'preview'):
4828 4831 # find nodes that are ancestors of p2 but not of p1
4829 4832 p1 = repo[b'.'].node()
4830 4833 p2 = ctx.node()
4831 4834 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4832 4835
4833 4836 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4834 4837 for node in nodes:
4835 4838 displayer.show(repo[node])
4836 4839 displayer.close()
4837 4840 return 0
4838 4841
4839 4842 # ui.forcemerge is an internal variable, do not document
4840 4843 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
4841 4844 with ui.configoverride(overrides, b'merge'):
4842 4845 force = opts.get(b'force')
4843 4846 labels = [b'working copy', b'merge rev']
4844 4847 return hg.merge(ctx, force=force, labels=labels)
4845 4848
4846 4849
4847 4850 statemod.addunfinished(
4848 4851 b'merge',
4849 4852 fname=None,
4850 4853 clearable=True,
4851 4854 allowcommit=True,
4852 4855 cmdmsg=_(b'outstanding uncommitted merge'),
4853 4856 abortfunc=hg.abortmerge,
4854 4857 statushint=_(
4855 4858 b'To continue: hg commit\nTo abort: hg merge --abort'
4856 4859 ),
4857 4860 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4858 4861 )
4859 4862
4860 4863
4861 4864 @command(
4862 4865 b'outgoing|out',
4863 4866 [
4864 4867 (
4865 4868 b'f',
4866 4869 b'force',
4867 4870 None,
4868 4871 _(b'run even when the destination is unrelated'),
4869 4872 ),
4870 4873 (
4871 4874 b'r',
4872 4875 b'rev',
4873 4876 [],
4874 4877 _(b'a changeset intended to be included in the destination'),
4875 4878 _(b'REV'),
4876 4879 ),
4877 4880 (b'n', b'newest-first', None, _(b'show newest record first')),
4878 4881 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
4879 4882 (
4880 4883 b'b',
4881 4884 b'branch',
4882 4885 [],
4883 4886 _(b'a specific branch you would like to push'),
4884 4887 _(b'BRANCH'),
4885 4888 ),
4886 4889 ]
4887 4890 + logopts
4888 4891 + remoteopts
4889 4892 + subrepoopts,
4890 4893 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4891 4894 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4892 4895 )
4893 4896 def outgoing(ui, repo, dest=None, **opts):
4894 4897 """show changesets not found in the destination
4895 4898
4896 4899 Show changesets not found in the specified destination repository
4897 4900 or the default push location. These are the changesets that would
4898 4901 be pushed if a push was requested.
4899 4902
4900 4903 See pull for details of valid destination formats.
4901 4904
4902 4905 .. container:: verbose
4903 4906
4904 4907 With -B/--bookmarks, the result of bookmark comparison between
4905 4908 local and remote repositories is displayed. With -v/--verbose,
4906 4909 status is also displayed for each bookmark like below::
4907 4910
4908 4911 BM1 01234567890a added
4909 4912 BM2 deleted
4910 4913 BM3 234567890abc advanced
4911 4914 BM4 34567890abcd diverged
4912 4915 BM5 4567890abcde changed
4913 4916
4914 4917 The action taken when pushing depends on the
4915 4918 status of each bookmark:
4916 4919
4917 4920 :``added``: push with ``-B`` will create it
4918 4921 :``deleted``: push with ``-B`` will delete it
4919 4922 :``advanced``: push will update it
4920 4923 :``diverged``: push with ``-B`` will update it
4921 4924 :``changed``: push with ``-B`` will update it
4922 4925
4923 4926 From the point of view of pushing behavior, bookmarks
4924 4927 existing only in the remote repository are treated as
4925 4928 ``deleted``, even if it is in fact added remotely.
4926 4929
4927 4930 Returns 0 if there are outgoing changes, 1 otherwise.
4928 4931 """
4929 4932 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4930 4933 # style URLs, so don't overwrite dest.
4931 4934 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
4932 4935 if not path:
4933 4936 raise error.ConfigError(
4934 4937 _(b'default repository not configured!'),
4935 4938 hint=_(b"see 'hg help config.paths'"),
4936 4939 )
4937 4940
4938 4941 opts = pycompat.byteskwargs(opts)
4939 4942 if opts.get(b'graph'):
4940 4943 logcmdutil.checkunsupportedgraphflags([], opts)
4941 4944 o, other = hg._outgoing(ui, repo, dest, opts)
4942 4945 if not o:
4943 4946 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4944 4947 return
4945 4948
4946 4949 revdag = logcmdutil.graphrevs(repo, o, opts)
4947 4950 ui.pager(b'outgoing')
4948 4951 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4949 4952 logcmdutil.displaygraph(
4950 4953 ui, repo, revdag, displayer, graphmod.asciiedges
4951 4954 )
4952 4955 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4953 4956 return 0
4954 4957
4955 4958 if opts.get(b'bookmarks'):
4956 4959 dest = path.pushloc or path.loc
4957 4960 other = hg.peer(repo, opts, dest)
4958 4961 if b'bookmarks' not in other.listkeys(b'namespaces'):
4959 4962 ui.warn(_(b"remote doesn't support bookmarks\n"))
4960 4963 return 0
4961 4964 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
4962 4965 ui.pager(b'outgoing')
4963 4966 return bookmarks.outgoing(ui, repo, other)
4964 4967
4965 4968 repo._subtoppath = path.pushloc or path.loc
4966 4969 try:
4967 4970 return hg.outgoing(ui, repo, dest, opts)
4968 4971 finally:
4969 4972 del repo._subtoppath
4970 4973
4971 4974
4972 4975 @command(
4973 4976 b'parents',
4974 4977 [
4975 4978 (
4976 4979 b'r',
4977 4980 b'rev',
4978 4981 b'',
4979 4982 _(b'show parents of the specified revision'),
4980 4983 _(b'REV'),
4981 4984 ),
4982 4985 ]
4983 4986 + templateopts,
4984 4987 _(b'[-r REV] [FILE]'),
4985 4988 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4986 4989 inferrepo=True,
4987 4990 )
4988 4991 def parents(ui, repo, file_=None, **opts):
4989 4992 """show the parents of the working directory or revision (DEPRECATED)
4990 4993
4991 4994 Print the working directory's parent revisions. If a revision is
4992 4995 given via -r/--rev, the parent of that revision will be printed.
4993 4996 If a file argument is given, the revision in which the file was
4994 4997 last changed (before the working directory revision or the
4995 4998 argument to --rev if given) is printed.
4996 4999
4997 5000 This command is equivalent to::
4998 5001
4999 5002 hg log -r "p1()+p2()" or
5000 5003 hg log -r "p1(REV)+p2(REV)" or
5001 5004 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5002 5005 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5003 5006
5004 5007 See :hg:`summary` and :hg:`help revsets` for related information.
5005 5008
5006 5009 Returns 0 on success.
5007 5010 """
5008 5011
5009 5012 opts = pycompat.byteskwargs(opts)
5010 5013 rev = opts.get(b'rev')
5011 5014 if rev:
5012 5015 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5013 5016 ctx = scmutil.revsingle(repo, rev, None)
5014 5017
5015 5018 if file_:
5016 5019 m = scmutil.match(ctx, (file_,), opts)
5017 5020 if m.anypats() or len(m.files()) != 1:
5018 5021 raise error.InputError(_(b'can only specify an explicit filename'))
5019 5022 file_ = m.files()[0]
5020 5023 filenodes = []
5021 5024 for cp in ctx.parents():
5022 5025 if not cp:
5023 5026 continue
5024 5027 try:
5025 5028 filenodes.append(cp.filenode(file_))
5026 5029 except error.LookupError:
5027 5030 pass
5028 5031 if not filenodes:
5029 5032 raise error.InputError(_(b"'%s' not found in manifest") % file_)
5030 5033 p = []
5031 5034 for fn in filenodes:
5032 5035 fctx = repo.filectx(file_, fileid=fn)
5033 5036 p.append(fctx.node())
5034 5037 else:
5035 5038 p = [cp.node() for cp in ctx.parents()]
5036 5039
5037 5040 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5038 5041 for n in p:
5039 5042 if n != nullid:
5040 5043 displayer.show(repo[n])
5041 5044 displayer.close()
5042 5045
5043 5046
5044 5047 @command(
5045 5048 b'paths',
5046 5049 formatteropts,
5047 5050 _(b'[NAME]'),
5048 5051 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5049 5052 optionalrepo=True,
5050 5053 intents={INTENT_READONLY},
5051 5054 )
5052 5055 def paths(ui, repo, search=None, **opts):
5053 5056 """show aliases for remote repositories
5054 5057
5055 5058 Show definition of symbolic path name NAME. If no name is given,
5056 5059 show definition of all available names.
5057 5060
5058 5061 Option -q/--quiet suppresses all output when searching for NAME
5059 5062 and shows only the path names when listing all definitions.
5060 5063
5061 5064 Path names are defined in the [paths] section of your
5062 5065 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5063 5066 repository, ``.hg/hgrc`` is used, too.
5064 5067
5065 5068 The path names ``default`` and ``default-push`` have a special
5066 5069 meaning. When performing a push or pull operation, they are used
5067 5070 as fallbacks if no location is specified on the command-line.
5068 5071 When ``default-push`` is set, it will be used for push and
5069 5072 ``default`` will be used for pull; otherwise ``default`` is used
5070 5073 as the fallback for both. When cloning a repository, the clone
5071 5074 source is written as ``default`` in ``.hg/hgrc``.
5072 5075
5073 5076 .. note::
5074 5077
5075 5078 ``default`` and ``default-push`` apply to all inbound (e.g.
5076 5079 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5077 5080 and :hg:`bundle`) operations.
5078 5081
5079 5082 See :hg:`help urls` for more information.
5080 5083
5081 5084 .. container:: verbose
5082 5085
5083 5086 Template:
5084 5087
5085 5088 The following keywords are supported. See also :hg:`help templates`.
5086 5089
5087 5090 :name: String. Symbolic name of the path alias.
5088 5091 :pushurl: String. URL for push operations.
5089 5092 :url: String. URL or directory path for the other operations.
5090 5093
5091 5094 Returns 0 on success.
5092 5095 """
5093 5096
5094 5097 opts = pycompat.byteskwargs(opts)
5095 5098 ui.pager(b'paths')
5096 5099 if search:
5097 5100 pathitems = [
5098 5101 (name, path)
5099 5102 for name, path in pycompat.iteritems(ui.paths)
5100 5103 if name == search
5101 5104 ]
5102 5105 else:
5103 5106 pathitems = sorted(pycompat.iteritems(ui.paths))
5104 5107
5105 5108 fm = ui.formatter(b'paths', opts)
5106 5109 if fm.isplain():
5107 5110 hidepassword = util.hidepassword
5108 5111 else:
5109 5112 hidepassword = bytes
5110 5113 if ui.quiet:
5111 5114 namefmt = b'%s\n'
5112 5115 else:
5113 5116 namefmt = b'%s = '
5114 5117 showsubopts = not search and not ui.quiet
5115 5118
5116 5119 for name, path in pathitems:
5117 5120 fm.startitem()
5118 5121 fm.condwrite(not search, b'name', namefmt, name)
5119 5122 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5120 5123 for subopt, value in sorted(path.suboptions.items()):
5121 5124 assert subopt not in (b'name', b'url')
5122 5125 if showsubopts:
5123 5126 fm.plain(b'%s:%s = ' % (name, subopt))
5124 5127 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5125 5128
5126 5129 fm.end()
5127 5130
5128 5131 if search and not pathitems:
5129 5132 if not ui.quiet:
5130 5133 ui.warn(_(b"not found!\n"))
5131 5134 return 1
5132 5135 else:
5133 5136 return 0
5134 5137
5135 5138
5136 5139 @command(
5137 5140 b'phase',
5138 5141 [
5139 5142 (b'p', b'public', False, _(b'set changeset phase to public')),
5140 5143 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5141 5144 (b's', b'secret', False, _(b'set changeset phase to secret')),
5142 5145 (b'f', b'force', False, _(b'allow to move boundary backward')),
5143 5146 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5144 5147 ],
5145 5148 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5146 5149 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5147 5150 )
5148 5151 def phase(ui, repo, *revs, **opts):
5149 5152 """set or show the current phase name
5150 5153
5151 5154 With no argument, show the phase name of the current revision(s).
5152 5155
5153 5156 With one of -p/--public, -d/--draft or -s/--secret, change the
5154 5157 phase value of the specified revisions.
5155 5158
5156 5159 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5157 5160 lower phase to a higher phase. Phases are ordered as follows::
5158 5161
5159 5162 public < draft < secret
5160 5163
5161 5164 Returns 0 on success, 1 if some phases could not be changed.
5162 5165
5163 5166 (For more information about the phases concept, see :hg:`help phases`.)
5164 5167 """
5165 5168 opts = pycompat.byteskwargs(opts)
5166 5169 # search for a unique phase argument
5167 5170 targetphase = None
5168 5171 for idx, name in enumerate(phases.cmdphasenames):
5169 5172 if opts[name]:
5170 5173 if targetphase is not None:
5171 5174 raise error.InputError(_(b'only one phase can be specified'))
5172 5175 targetphase = idx
5173 5176
5174 5177 # look for specified revision
5175 5178 revs = list(revs)
5176 5179 revs.extend(opts[b'rev'])
5177 5180 if not revs:
5178 5181 # display both parents as the second parent phase can influence
5179 5182 # the phase of a merge commit
5180 5183 revs = [c.rev() for c in repo[None].parents()]
5181 5184
5182 5185 revs = scmutil.revrange(repo, revs)
5183 5186
5184 5187 ret = 0
5185 5188 if targetphase is None:
5186 5189 # display
5187 5190 for r in revs:
5188 5191 ctx = repo[r]
5189 5192 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5190 5193 else:
5191 5194 with repo.lock(), repo.transaction(b"phase") as tr:
5192 5195 # set phase
5193 5196 if not revs:
5194 5197 raise error.InputError(_(b'empty revision set'))
5195 5198 nodes = [repo[r].node() for r in revs]
5196 5199 # moving revision from public to draft may hide them
5197 5200 # We have to check result on an unfiltered repository
5198 5201 unfi = repo.unfiltered()
5199 5202 getphase = unfi._phasecache.phase
5200 5203 olddata = [getphase(unfi, r) for r in unfi]
5201 5204 phases.advanceboundary(repo, tr, targetphase, nodes)
5202 5205 if opts[b'force']:
5203 5206 phases.retractboundary(repo, tr, targetphase, nodes)
5204 5207 getphase = unfi._phasecache.phase
5205 5208 newdata = [getphase(unfi, r) for r in unfi]
5206 5209 changes = sum(newdata[r] != olddata[r] for r in unfi)
5207 5210 cl = unfi.changelog
5208 5211 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5209 5212 if rejected:
5210 5213 ui.warn(
5211 5214 _(
5212 5215 b'cannot move %i changesets to a higher '
5213 5216 b'phase, use --force\n'
5214 5217 )
5215 5218 % len(rejected)
5216 5219 )
5217 5220 ret = 1
5218 5221 if changes:
5219 5222 msg = _(b'phase changed for %i changesets\n') % changes
5220 5223 if ret:
5221 5224 ui.status(msg)
5222 5225 else:
5223 5226 ui.note(msg)
5224 5227 else:
5225 5228 ui.warn(_(b'no phases changed\n'))
5226 5229 return ret
5227 5230
5228 5231
5229 5232 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5230 5233 """Run after a changegroup has been added via pull/unbundle
5231 5234
5232 5235 This takes arguments below:
5233 5236
5234 5237 :modheads: change of heads by pull/unbundle
5235 5238 :optupdate: updating working directory is needed or not
5236 5239 :checkout: update destination revision (or None to default destination)
5237 5240 :brev: a name, which might be a bookmark to be activated after updating
5238 5241 """
5239 5242 if modheads == 0:
5240 5243 return
5241 5244 if optupdate:
5242 5245 try:
5243 5246 return hg.updatetotally(ui, repo, checkout, brev)
5244 5247 except error.UpdateAbort as inst:
5245 5248 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5246 5249 hint = inst.hint
5247 5250 raise error.UpdateAbort(msg, hint=hint)
5248 5251 if modheads is not None and modheads > 1:
5249 5252 currentbranchheads = len(repo.branchheads())
5250 5253 if currentbranchheads == modheads:
5251 5254 ui.status(
5252 5255 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5253 5256 )
5254 5257 elif currentbranchheads > 1:
5255 5258 ui.status(
5256 5259 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5257 5260 )
5258 5261 else:
5259 5262 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5260 5263 elif not ui.configbool(b'commands', b'update.requiredest'):
5261 5264 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5262 5265
5263 5266
5264 5267 @command(
5265 5268 b'pull',
5266 5269 [
5267 5270 (
5268 5271 b'u',
5269 5272 b'update',
5270 5273 None,
5271 5274 _(b'update to new branch head if new descendants were pulled'),
5272 5275 ),
5273 5276 (
5274 5277 b'f',
5275 5278 b'force',
5276 5279 None,
5277 5280 _(b'run even when remote repository is unrelated'),
5278 5281 ),
5279 5282 (
5280 5283 b'',
5281 5284 b'confirm',
5282 5285 None,
5283 5286 _(b'confirm pull before applying changes'),
5284 5287 ),
5285 5288 (
5286 5289 b'r',
5287 5290 b'rev',
5288 5291 [],
5289 5292 _(b'a remote changeset intended to be added'),
5290 5293 _(b'REV'),
5291 5294 ),
5292 5295 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5293 5296 (
5294 5297 b'b',
5295 5298 b'branch',
5296 5299 [],
5297 5300 _(b'a specific branch you would like to pull'),
5298 5301 _(b'BRANCH'),
5299 5302 ),
5300 5303 ]
5301 5304 + remoteopts,
5302 5305 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
5303 5306 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5304 5307 helpbasic=True,
5305 5308 )
5306 5309 def pull(ui, repo, source=b"default", **opts):
5307 5310 """pull changes from the specified source
5308 5311
5309 5312 Pull changes from a remote repository to a local one.
5310 5313
5311 5314 This finds all changes from the repository at the specified path
5312 5315 or URL and adds them to a local repository (the current one unless
5313 5316 -R is specified). By default, this does not update the copy of the
5314 5317 project in the working directory.
5315 5318
5316 5319 When cloning from servers that support it, Mercurial may fetch
5317 5320 pre-generated data. When this is done, hooks operating on incoming
5318 5321 changesets and changegroups may fire more than once, once for each
5319 5322 pre-generated bundle and as well as for any additional remaining
5320 5323 data. See :hg:`help -e clonebundles` for more.
5321 5324
5322 5325 Use :hg:`incoming` if you want to see what would have been added
5323 5326 by a pull at the time you issued this command. If you then decide
5324 5327 to add those changes to the repository, you should use :hg:`pull
5325 5328 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5326 5329
5327 5330 If SOURCE is omitted, the 'default' path will be used.
5328 5331 See :hg:`help urls` for more information.
5329 5332
5330 5333 Specifying bookmark as ``.`` is equivalent to specifying the active
5331 5334 bookmark's name.
5332 5335
5333 5336 Returns 0 on success, 1 if an update had unresolved files.
5334 5337 """
5335 5338
5336 5339 opts = pycompat.byteskwargs(opts)
5337 5340 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5338 5341 b'update'
5339 5342 ):
5340 5343 msg = _(b'update destination required by configuration')
5341 5344 hint = _(b'use hg pull followed by hg update DEST')
5342 5345 raise error.InputError(msg, hint=hint)
5343 5346
5344 5347 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5345 5348 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5346 5349 ui.flush()
5347 5350 other = hg.peer(repo, opts, source)
5348 5351 try:
5349 5352 revs, checkout = hg.addbranchrevs(
5350 5353 repo, other, branches, opts.get(b'rev')
5351 5354 )
5352 5355
5353 5356 pullopargs = {}
5354 5357
5355 5358 nodes = None
5356 5359 if opts.get(b'bookmark') or revs:
5357 5360 # The list of bookmark used here is the same used to actually update
5358 5361 # the bookmark names, to avoid the race from issue 4689 and we do
5359 5362 # all lookup and bookmark queries in one go so they see the same
5360 5363 # version of the server state (issue 4700).
5361 5364 nodes = []
5362 5365 fnodes = []
5363 5366 revs = revs or []
5364 5367 if revs and not other.capable(b'lookup'):
5365 5368 err = _(
5366 5369 b"other repository doesn't support revision lookup, "
5367 5370 b"so a rev cannot be specified."
5368 5371 )
5369 5372 raise error.Abort(err)
5370 5373 with other.commandexecutor() as e:
5371 5374 fremotebookmarks = e.callcommand(
5372 5375 b'listkeys', {b'namespace': b'bookmarks'}
5373 5376 )
5374 5377 for r in revs:
5375 5378 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5376 5379 remotebookmarks = fremotebookmarks.result()
5377 5380 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5378 5381 pullopargs[b'remotebookmarks'] = remotebookmarks
5379 5382 for b in opts.get(b'bookmark', []):
5380 5383 b = repo._bookmarks.expandname(b)
5381 5384 if b not in remotebookmarks:
5382 5385 raise error.InputError(
5383 5386 _(b'remote bookmark %s not found!') % b
5384 5387 )
5385 5388 nodes.append(remotebookmarks[b])
5386 5389 for i, rev in enumerate(revs):
5387 5390 node = fnodes[i].result()
5388 5391 nodes.append(node)
5389 5392 if rev == checkout:
5390 5393 checkout = node
5391 5394
5392 5395 wlock = util.nullcontextmanager()
5393 5396 if opts.get(b'update'):
5394 5397 wlock = repo.wlock()
5395 5398 with wlock:
5396 5399 pullopargs.update(opts.get(b'opargs', {}))
5397 5400 modheads = exchange.pull(
5398 5401 repo,
5399 5402 other,
5400 5403 heads=nodes,
5401 5404 force=opts.get(b'force'),
5402 5405 bookmarks=opts.get(b'bookmark', ()),
5403 5406 opargs=pullopargs,
5404 5407 confirm=opts.get(b'confirm'),
5405 5408 ).cgresult
5406 5409
5407 5410 # brev is a name, which might be a bookmark to be activated at
5408 5411 # the end of the update. In other words, it is an explicit
5409 5412 # destination of the update
5410 5413 brev = None
5411 5414
5412 5415 if checkout:
5413 5416 checkout = repo.unfiltered().changelog.rev(checkout)
5414 5417
5415 5418 # order below depends on implementation of
5416 5419 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5417 5420 # because 'checkout' is determined without it.
5418 5421 if opts.get(b'rev'):
5419 5422 brev = opts[b'rev'][0]
5420 5423 elif opts.get(b'branch'):
5421 5424 brev = opts[b'branch'][0]
5422 5425 else:
5423 5426 brev = branches[0]
5424 5427 repo._subtoppath = source
5425 5428 try:
5426 5429 ret = postincoming(
5427 5430 ui, repo, modheads, opts.get(b'update'), checkout, brev
5428 5431 )
5429 5432 except error.FilteredRepoLookupError as exc:
5430 5433 msg = _(b'cannot update to target: %s') % exc.args[0]
5431 5434 exc.args = (msg,) + exc.args[1:]
5432 5435 raise
5433 5436 finally:
5434 5437 del repo._subtoppath
5435 5438
5436 5439 finally:
5437 5440 other.close()
5438 5441 return ret
5439 5442
5440 5443
5441 5444 @command(
5442 5445 b'push',
5443 5446 [
5444 5447 (b'f', b'force', None, _(b'force push')),
5445 5448 (
5446 5449 b'r',
5447 5450 b'rev',
5448 5451 [],
5449 5452 _(b'a changeset intended to be included in the destination'),
5450 5453 _(b'REV'),
5451 5454 ),
5452 5455 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5453 5456 (b'', b'all-bookmarks', None, _(b"push all bookmarks (EXPERIMENTAL)")),
5454 5457 (
5455 5458 b'b',
5456 5459 b'branch',
5457 5460 [],
5458 5461 _(b'a specific branch you would like to push'),
5459 5462 _(b'BRANCH'),
5460 5463 ),
5461 5464 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5462 5465 (
5463 5466 b'',
5464 5467 b'pushvars',
5465 5468 [],
5466 5469 _(b'variables that can be sent to server (ADVANCED)'),
5467 5470 ),
5468 5471 (
5469 5472 b'',
5470 5473 b'publish',
5471 5474 False,
5472 5475 _(b'push the changeset as public (EXPERIMENTAL)'),
5473 5476 ),
5474 5477 ]
5475 5478 + remoteopts,
5476 5479 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
5477 5480 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5478 5481 helpbasic=True,
5479 5482 )
5480 5483 def push(ui, repo, dest=None, **opts):
5481 5484 """push changes to the specified destination
5482 5485
5483 5486 Push changesets from the local repository to the specified
5484 5487 destination.
5485 5488
5486 5489 This operation is symmetrical to pull: it is identical to a pull
5487 5490 in the destination repository from the current one.
5488 5491
5489 5492 By default, push will not allow creation of new heads at the
5490 5493 destination, since multiple heads would make it unclear which head
5491 5494 to use. In this situation, it is recommended to pull and merge
5492 5495 before pushing.
5493 5496
5494 5497 Use --new-branch if you want to allow push to create a new named
5495 5498 branch that is not present at the destination. This allows you to
5496 5499 only create a new branch without forcing other changes.
5497 5500
5498 5501 .. note::
5499 5502
5500 5503 Extra care should be taken with the -f/--force option,
5501 5504 which will push all new heads on all branches, an action which will
5502 5505 almost always cause confusion for collaborators.
5503 5506
5504 5507 If -r/--rev is used, the specified revision and all its ancestors
5505 5508 will be pushed to the remote repository.
5506 5509
5507 5510 If -B/--bookmark is used, the specified bookmarked revision, its
5508 5511 ancestors, and the bookmark will be pushed to the remote
5509 5512 repository. Specifying ``.`` is equivalent to specifying the active
5510 5513 bookmark's name. Use the --all-bookmarks option for pushing all
5511 5514 current bookmarks.
5512 5515
5513 5516 Please see :hg:`help urls` for important details about ``ssh://``
5514 5517 URLs. If DESTINATION is omitted, a default path will be used.
5515 5518
5516 5519 .. container:: verbose
5517 5520
5518 5521 The --pushvars option sends strings to the server that become
5519 5522 environment variables prepended with ``HG_USERVAR_``. For example,
5520 5523 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5521 5524 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5522 5525
5523 5526 pushvars can provide for user-overridable hooks as well as set debug
5524 5527 levels. One example is having a hook that blocks commits containing
5525 5528 conflict markers, but enables the user to override the hook if the file
5526 5529 is using conflict markers for testing purposes or the file format has
5527 5530 strings that look like conflict markers.
5528 5531
5529 5532 By default, servers will ignore `--pushvars`. To enable it add the
5530 5533 following to your configuration file::
5531 5534
5532 5535 [push]
5533 5536 pushvars.server = true
5534 5537
5535 5538 Returns 0 if push was successful, 1 if nothing to push.
5536 5539 """
5537 5540
5538 5541 opts = pycompat.byteskwargs(opts)
5539 5542
5540 5543 if opts.get(b'all_bookmarks'):
5541 5544 cmdutil.check_incompatible_arguments(
5542 5545 opts,
5543 5546 b'all_bookmarks',
5544 5547 [b'bookmark', b'rev'],
5545 5548 )
5546 5549 opts[b'bookmark'] = list(repo._bookmarks)
5547 5550
5548 5551 if opts.get(b'bookmark'):
5549 5552 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5550 5553 for b in opts[b'bookmark']:
5551 5554 # translate -B options to -r so changesets get pushed
5552 5555 b = repo._bookmarks.expandname(b)
5553 5556 if b in repo._bookmarks:
5554 5557 opts.setdefault(b'rev', []).append(b)
5555 5558 else:
5556 5559 # if we try to push a deleted bookmark, translate it to null
5557 5560 # this lets simultaneous -r, -b options continue working
5558 5561 opts.setdefault(b'rev', []).append(b"null")
5559 5562
5560 5563 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
5561 5564 if not path:
5562 5565 raise error.ConfigError(
5563 5566 _(b'default repository not configured!'),
5564 5567 hint=_(b"see 'hg help config.paths'"),
5565 5568 )
5566 5569 dest = path.pushloc or path.loc
5567 5570 branches = (path.branch, opts.get(b'branch') or [])
5568 5571 ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
5569 5572 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
5570 5573 other = hg.peer(repo, opts, dest)
5571 5574
5572 5575 if revs:
5573 5576 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5574 5577 if not revs:
5575 5578 raise error.InputError(
5576 5579 _(b"specified revisions evaluate to an empty set"),
5577 5580 hint=_(b"use different revision arguments"),
5578 5581 )
5579 5582 elif path.pushrev:
5580 5583 # It doesn't make any sense to specify ancestor revisions. So limit
5581 5584 # to DAG heads to make discovery simpler.
5582 5585 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5583 5586 revs = scmutil.revrange(repo, [expr])
5584 5587 revs = [repo[rev].node() for rev in revs]
5585 5588 if not revs:
5586 5589 raise error.InputError(
5587 5590 _(b'default push revset for path evaluates to an empty set')
5588 5591 )
5589 5592 elif ui.configbool(b'commands', b'push.require-revs'):
5590 5593 raise error.InputError(
5591 5594 _(b'no revisions specified to push'),
5592 5595 hint=_(b'did you mean "hg push -r ."?'),
5593 5596 )
5594 5597
5595 5598 repo._subtoppath = dest
5596 5599 try:
5597 5600 # push subrepos depth-first for coherent ordering
5598 5601 c = repo[b'.']
5599 5602 subs = c.substate # only repos that are committed
5600 5603 for s in sorted(subs):
5601 5604 result = c.sub(s).push(opts)
5602 5605 if result == 0:
5603 5606 return not result
5604 5607 finally:
5605 5608 del repo._subtoppath
5606 5609
5607 5610 opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
5608 5611 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5609 5612
5610 5613 pushop = exchange.push(
5611 5614 repo,
5612 5615 other,
5613 5616 opts.get(b'force'),
5614 5617 revs=revs,
5615 5618 newbranch=opts.get(b'new_branch'),
5616 5619 bookmarks=opts.get(b'bookmark', ()),
5617 5620 publish=opts.get(b'publish'),
5618 5621 opargs=opargs,
5619 5622 )
5620 5623
5621 5624 result = not pushop.cgresult
5622 5625
5623 5626 if pushop.bkresult is not None:
5624 5627 if pushop.bkresult == 2:
5625 5628 result = 2
5626 5629 elif not result and pushop.bkresult:
5627 5630 result = 2
5628 5631
5629 5632 return result
5630 5633
5631 5634
5632 5635 @command(
5633 5636 b'recover',
5634 5637 [
5635 5638 (b'', b'verify', False, b"run `hg verify` after successful recover"),
5636 5639 ],
5637 5640 helpcategory=command.CATEGORY_MAINTENANCE,
5638 5641 )
5639 5642 def recover(ui, repo, **opts):
5640 5643 """roll back an interrupted transaction
5641 5644
5642 5645 Recover from an interrupted commit or pull.
5643 5646
5644 5647 This command tries to fix the repository status after an
5645 5648 interrupted operation. It should only be necessary when Mercurial
5646 5649 suggests it.
5647 5650
5648 5651 Returns 0 if successful, 1 if nothing to recover or verify fails.
5649 5652 """
5650 5653 ret = repo.recover()
5651 5654 if ret:
5652 5655 if opts['verify']:
5653 5656 return hg.verify(repo)
5654 5657 else:
5655 5658 msg = _(
5656 5659 b"(verify step skipped, run `hg verify` to check your "
5657 5660 b"repository content)\n"
5658 5661 )
5659 5662 ui.warn(msg)
5660 5663 return 0
5661 5664 return 1
5662 5665
5663 5666
5664 5667 @command(
5665 5668 b'remove|rm',
5666 5669 [
5667 5670 (b'A', b'after', None, _(b'record delete for missing files')),
5668 5671 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5669 5672 ]
5670 5673 + subrepoopts
5671 5674 + walkopts
5672 5675 + dryrunopts,
5673 5676 _(b'[OPTION]... FILE...'),
5674 5677 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5675 5678 helpbasic=True,
5676 5679 inferrepo=True,
5677 5680 )
5678 5681 def remove(ui, repo, *pats, **opts):
5679 5682 """remove the specified files on the next commit
5680 5683
5681 5684 Schedule the indicated files for removal from the current branch.
5682 5685
5683 5686 This command schedules the files to be removed at the next commit.
5684 5687 To undo a remove before that, see :hg:`revert`. To undo added
5685 5688 files, see :hg:`forget`.
5686 5689
5687 5690 .. container:: verbose
5688 5691
5689 5692 -A/--after can be used to remove only files that have already
5690 5693 been deleted, -f/--force can be used to force deletion, and -Af
5691 5694 can be used to remove files from the next revision without
5692 5695 deleting them from the working directory.
5693 5696
5694 5697 The following table details the behavior of remove for different
5695 5698 file states (columns) and option combinations (rows). The file
5696 5699 states are Added [A], Clean [C], Modified [M] and Missing [!]
5697 5700 (as reported by :hg:`status`). The actions are Warn, Remove
5698 5701 (from branch) and Delete (from disk):
5699 5702
5700 5703 ========= == == == ==
5701 5704 opt/state A C M !
5702 5705 ========= == == == ==
5703 5706 none W RD W R
5704 5707 -f R RD RD R
5705 5708 -A W W W R
5706 5709 -Af R R R R
5707 5710 ========= == == == ==
5708 5711
5709 5712 .. note::
5710 5713
5711 5714 :hg:`remove` never deletes files in Added [A] state from the
5712 5715 working directory, not even if ``--force`` is specified.
5713 5716
5714 5717 Returns 0 on success, 1 if any warnings encountered.
5715 5718 """
5716 5719
5717 5720 opts = pycompat.byteskwargs(opts)
5718 5721 after, force = opts.get(b'after'), opts.get(b'force')
5719 5722 dryrun = opts.get(b'dry_run')
5720 5723 if not pats and not after:
5721 5724 raise error.InputError(_(b'no files specified'))
5722 5725
5723 5726 m = scmutil.match(repo[None], pats, opts)
5724 5727 subrepos = opts.get(b'subrepos')
5725 5728 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5726 5729 return cmdutil.remove(
5727 5730 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5728 5731 )
5729 5732
5730 5733
5731 5734 @command(
5732 5735 b'rename|move|mv',
5733 5736 [
5734 5737 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5735 5738 (
5736 5739 b'',
5737 5740 b'at-rev',
5738 5741 b'',
5739 5742 _(b'(un)mark renames in the given revision (EXPERIMENTAL)'),
5740 5743 _(b'REV'),
5741 5744 ),
5742 5745 (
5743 5746 b'f',
5744 5747 b'force',
5745 5748 None,
5746 5749 _(b'forcibly move over an existing managed file'),
5747 5750 ),
5748 5751 ]
5749 5752 + walkopts
5750 5753 + dryrunopts,
5751 5754 _(b'[OPTION]... SOURCE... DEST'),
5752 5755 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5753 5756 )
5754 5757 def rename(ui, repo, *pats, **opts):
5755 5758 """rename files; equivalent of copy + remove
5756 5759
5757 5760 Mark dest as copies of sources; mark sources for deletion. If dest
5758 5761 is a directory, copies are put in that directory. If dest is a
5759 5762 file, there can only be one source.
5760 5763
5761 5764 By default, this command copies the contents of files as they
5762 5765 exist in the working directory. If invoked with -A/--after, the
5763 5766 operation is recorded, but no copying is performed.
5764 5767
5765 5768 This command takes effect at the next commit. To undo a rename
5766 5769 before that, see :hg:`revert`.
5767 5770
5768 5771 Returns 0 on success, 1 if errors are encountered.
5769 5772 """
5770 5773 opts = pycompat.byteskwargs(opts)
5771 5774 with repo.wlock():
5772 5775 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5773 5776
5774 5777
5775 5778 @command(
5776 5779 b'resolve',
5777 5780 [
5778 5781 (b'a', b'all', None, _(b'select all unresolved files')),
5779 5782 (b'l', b'list', None, _(b'list state of files needing merge')),
5780 5783 (b'm', b'mark', None, _(b'mark files as resolved')),
5781 5784 (b'u', b'unmark', None, _(b'mark files as unresolved')),
5782 5785 (b'n', b'no-status', None, _(b'hide status prefix')),
5783 5786 (b'', b're-merge', None, _(b're-merge files')),
5784 5787 ]
5785 5788 + mergetoolopts
5786 5789 + walkopts
5787 5790 + formatteropts,
5788 5791 _(b'[OPTION]... [FILE]...'),
5789 5792 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5790 5793 inferrepo=True,
5791 5794 )
5792 5795 def resolve(ui, repo, *pats, **opts):
5793 5796 """redo merges or set/view the merge status of files
5794 5797
5795 5798 Merges with unresolved conflicts are often the result of
5796 5799 non-interactive merging using the ``internal:merge`` configuration
5797 5800 setting, or a command-line merge tool like ``diff3``. The resolve
5798 5801 command is used to manage the files involved in a merge, after
5799 5802 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5800 5803 working directory must have two parents). See :hg:`help
5801 5804 merge-tools` for information on configuring merge tools.
5802 5805
5803 5806 The resolve command can be used in the following ways:
5804 5807
5805 5808 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
5806 5809 the specified files, discarding any previous merge attempts. Re-merging
5807 5810 is not performed for files already marked as resolved. Use ``--all/-a``
5808 5811 to select all unresolved files. ``--tool`` can be used to specify
5809 5812 the merge tool used for the given files. It overrides the HGMERGE
5810 5813 environment variable and your configuration files. Previous file
5811 5814 contents are saved with a ``.orig`` suffix.
5812 5815
5813 5816 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5814 5817 (e.g. after having manually fixed-up the files). The default is
5815 5818 to mark all unresolved files.
5816 5819
5817 5820 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5818 5821 default is to mark all resolved files.
5819 5822
5820 5823 - :hg:`resolve -l`: list files which had or still have conflicts.
5821 5824 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5822 5825 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
5823 5826 the list. See :hg:`help filesets` for details.
5824 5827
5825 5828 .. note::
5826 5829
5827 5830 Mercurial will not let you commit files with unresolved merge
5828 5831 conflicts. You must use :hg:`resolve -m ...` before you can
5829 5832 commit after a conflicting merge.
5830 5833
5831 5834 .. container:: verbose
5832 5835
5833 5836 Template:
5834 5837
5835 5838 The following keywords are supported in addition to the common template
5836 5839 keywords and functions. See also :hg:`help templates`.
5837 5840
5838 5841 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
5839 5842 :path: String. Repository-absolute path of the file.
5840 5843
5841 5844 Returns 0 on success, 1 if any files fail a resolve attempt.
5842 5845 """
5843 5846
5844 5847 opts = pycompat.byteskwargs(opts)
5845 5848 confirm = ui.configbool(b'commands', b'resolve.confirm')
5846 5849 flaglist = b'all mark unmark list no_status re_merge'.split()
5847 5850 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5848 5851
5849 5852 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5850 5853 if actioncount > 1:
5851 5854 raise error.InputError(_(b"too many actions specified"))
5852 5855 elif actioncount == 0 and ui.configbool(
5853 5856 b'commands', b'resolve.explicit-re-merge'
5854 5857 ):
5855 5858 hint = _(b'use --mark, --unmark, --list or --re-merge')
5856 5859 raise error.InputError(_(b'no action specified'), hint=hint)
5857 5860 if pats and all:
5858 5861 raise error.InputError(_(b"can't specify --all and patterns"))
5859 5862 if not (all or pats or show or mark or unmark):
5860 5863 raise error.InputError(
5861 5864 _(b'no files or directories specified'),
5862 5865 hint=b'use --all to re-merge all unresolved files',
5863 5866 )
5864 5867
5865 5868 if confirm:
5866 5869 if all:
5867 5870 if ui.promptchoice(
5868 5871 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
5869 5872 ):
5870 5873 raise error.CanceledError(_(b'user quit'))
5871 5874 if mark and not pats:
5872 5875 if ui.promptchoice(
5873 5876 _(
5874 5877 b'mark all unresolved files as resolved (yn)?'
5875 5878 b'$$ &Yes $$ &No'
5876 5879 )
5877 5880 ):
5878 5881 raise error.CanceledError(_(b'user quit'))
5879 5882 if unmark and not pats:
5880 5883 if ui.promptchoice(
5881 5884 _(
5882 5885 b'mark all resolved files as unresolved (yn)?'
5883 5886 b'$$ &Yes $$ &No'
5884 5887 )
5885 5888 ):
5886 5889 raise error.CanceledError(_(b'user quit'))
5887 5890
5888 5891 uipathfn = scmutil.getuipathfn(repo)
5889 5892
5890 5893 if show:
5891 5894 ui.pager(b'resolve')
5892 5895 fm = ui.formatter(b'resolve', opts)
5893 5896 ms = mergestatemod.mergestate.read(repo)
5894 5897 wctx = repo[None]
5895 5898 m = scmutil.match(wctx, pats, opts)
5896 5899
5897 5900 # Labels and keys based on merge state. Unresolved path conflicts show
5898 5901 # as 'P'. Resolved path conflicts show as 'R', the same as normal
5899 5902 # resolved conflicts.
5900 5903 mergestateinfo = {
5901 5904 mergestatemod.MERGE_RECORD_UNRESOLVED: (
5902 5905 b'resolve.unresolved',
5903 5906 b'U',
5904 5907 ),
5905 5908 mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
5906 5909 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
5907 5910 b'resolve.unresolved',
5908 5911 b'P',
5909 5912 ),
5910 5913 mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
5911 5914 b'resolve.resolved',
5912 5915 b'R',
5913 5916 ),
5914 5917 }
5915 5918
5916 5919 for f in ms:
5917 5920 if not m(f):
5918 5921 continue
5919 5922
5920 5923 label, key = mergestateinfo[ms[f]]
5921 5924 fm.startitem()
5922 5925 fm.context(ctx=wctx)
5923 5926 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
5924 5927 fm.data(path=f)
5925 5928 fm.plain(b'%s\n' % uipathfn(f), label=label)
5926 5929 fm.end()
5927 5930 return 0
5928 5931
5929 5932 with repo.wlock():
5930 5933 ms = mergestatemod.mergestate.read(repo)
5931 5934
5932 5935 if not (ms.active() or repo.dirstate.p2() != nullid):
5933 5936 raise error.StateError(
5934 5937 _(b'resolve command not applicable when not merging')
5935 5938 )
5936 5939
5937 5940 wctx = repo[None]
5938 5941 m = scmutil.match(wctx, pats, opts)
5939 5942 ret = 0
5940 5943 didwork = False
5941 5944
5942 5945 tocomplete = []
5943 5946 hasconflictmarkers = []
5944 5947 if mark:
5945 5948 markcheck = ui.config(b'commands', b'resolve.mark-check')
5946 5949 if markcheck not in [b'warn', b'abort']:
5947 5950 # Treat all invalid / unrecognized values as 'none'.
5948 5951 markcheck = False
5949 5952 for f in ms:
5950 5953 if not m(f):
5951 5954 continue
5952 5955
5953 5956 didwork = True
5954 5957
5955 5958 # path conflicts must be resolved manually
5956 5959 if ms[f] in (
5957 5960 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
5958 5961 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
5959 5962 ):
5960 5963 if mark:
5961 5964 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
5962 5965 elif unmark:
5963 5966 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
5964 5967 elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
5965 5968 ui.warn(
5966 5969 _(b'%s: path conflict must be resolved manually\n')
5967 5970 % uipathfn(f)
5968 5971 )
5969 5972 continue
5970 5973
5971 5974 if mark:
5972 5975 if markcheck:
5973 5976 fdata = repo.wvfs.tryread(f)
5974 5977 if (
5975 5978 filemerge.hasconflictmarkers(fdata)
5976 5979 and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
5977 5980 ):
5978 5981 hasconflictmarkers.append(f)
5979 5982 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
5980 5983 elif unmark:
5981 5984 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
5982 5985 else:
5983 5986 # backup pre-resolve (merge uses .orig for its own purposes)
5984 5987 a = repo.wjoin(f)
5985 5988 try:
5986 5989 util.copyfile(a, a + b".resolve")
5987 5990 except (IOError, OSError) as inst:
5988 5991 if inst.errno != errno.ENOENT:
5989 5992 raise
5990 5993
5991 5994 try:
5992 5995 # preresolve file
5993 5996 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
5994 5997 with ui.configoverride(overrides, b'resolve'):
5995 5998 complete, r = ms.preresolve(f, wctx)
5996 5999 if not complete:
5997 6000 tocomplete.append(f)
5998 6001 elif r:
5999 6002 ret = 1
6000 6003 finally:
6001 6004 ms.commit()
6002 6005
6003 6006 # replace filemerge's .orig file with our resolve file, but only
6004 6007 # for merges that are complete
6005 6008 if complete:
6006 6009 try:
6007 6010 util.rename(
6008 6011 a + b".resolve", scmutil.backuppath(ui, repo, f)
6009 6012 )
6010 6013 except OSError as inst:
6011 6014 if inst.errno != errno.ENOENT:
6012 6015 raise
6013 6016
6014 6017 if hasconflictmarkers:
6015 6018 ui.warn(
6016 6019 _(
6017 6020 b'warning: the following files still have conflict '
6018 6021 b'markers:\n'
6019 6022 )
6020 6023 + b''.join(
6021 6024 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6022 6025 )
6023 6026 )
6024 6027 if markcheck == b'abort' and not all and not pats:
6025 6028 raise error.StateError(
6026 6029 _(b'conflict markers detected'),
6027 6030 hint=_(b'use --all to mark anyway'),
6028 6031 )
6029 6032
6030 6033 for f in tocomplete:
6031 6034 try:
6032 6035 # resolve file
6033 6036 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6034 6037 with ui.configoverride(overrides, b'resolve'):
6035 6038 r = ms.resolve(f, wctx)
6036 6039 if r:
6037 6040 ret = 1
6038 6041 finally:
6039 6042 ms.commit()
6040 6043
6041 6044 # replace filemerge's .orig file with our resolve file
6042 6045 a = repo.wjoin(f)
6043 6046 try:
6044 6047 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
6045 6048 except OSError as inst:
6046 6049 if inst.errno != errno.ENOENT:
6047 6050 raise
6048 6051
6049 6052 ms.commit()
6050 6053 branchmerge = repo.dirstate.p2() != nullid
6051 6054 mergestatemod.recordupdates(repo, ms.actions(), branchmerge, None)
6052 6055
6053 6056 if not didwork and pats:
6054 6057 hint = None
6055 6058 if not any([p for p in pats if p.find(b':') >= 0]):
6056 6059 pats = [b'path:%s' % p for p in pats]
6057 6060 m = scmutil.match(wctx, pats, opts)
6058 6061 for f in ms:
6059 6062 if not m(f):
6060 6063 continue
6061 6064
6062 6065 def flag(o):
6063 6066 if o == b're_merge':
6064 6067 return b'--re-merge '
6065 6068 return b'-%s ' % o[0:1]
6066 6069
6067 6070 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6068 6071 hint = _(b"(try: hg resolve %s%s)\n") % (
6069 6072 flags,
6070 6073 b' '.join(pats),
6071 6074 )
6072 6075 break
6073 6076 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6074 6077 if hint:
6075 6078 ui.warn(hint)
6076 6079
6077 6080 unresolvedf = list(ms.unresolved())
6078 6081 if not unresolvedf:
6079 6082 ui.status(_(b'(no more unresolved files)\n'))
6080 6083 cmdutil.checkafterresolved(repo)
6081 6084
6082 6085 return ret
6083 6086
6084 6087
6085 6088 @command(
6086 6089 b'revert',
6087 6090 [
6088 6091 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6089 6092 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6090 6093 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6091 6094 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6092 6095 (b'i', b'interactive', None, _(b'interactively select the changes')),
6093 6096 ]
6094 6097 + walkopts
6095 6098 + dryrunopts,
6096 6099 _(b'[OPTION]... [-r REV] [NAME]...'),
6097 6100 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6098 6101 )
6099 6102 def revert(ui, repo, *pats, **opts):
6100 6103 """restore files to their checkout state
6101 6104
6102 6105 .. note::
6103 6106
6104 6107 To check out earlier revisions, you should use :hg:`update REV`.
6105 6108 To cancel an uncommitted merge (and lose your changes),
6106 6109 use :hg:`merge --abort`.
6107 6110
6108 6111 With no revision specified, revert the specified files or directories
6109 6112 to the contents they had in the parent of the working directory.
6110 6113 This restores the contents of files to an unmodified
6111 6114 state and unschedules adds, removes, copies, and renames. If the
6112 6115 working directory has two parents, you must explicitly specify a
6113 6116 revision.
6114 6117
6115 6118 Using the -r/--rev or -d/--date options, revert the given files or
6116 6119 directories to their states as of a specific revision. Because
6117 6120 revert does not change the working directory parents, this will
6118 6121 cause these files to appear modified. This can be helpful to "back
6119 6122 out" some or all of an earlier change. See :hg:`backout` for a
6120 6123 related method.
6121 6124
6122 6125 Modified files are saved with a .orig suffix before reverting.
6123 6126 To disable these backups, use --no-backup. It is possible to store
6124 6127 the backup files in a custom directory relative to the root of the
6125 6128 repository by setting the ``ui.origbackuppath`` configuration
6126 6129 option.
6127 6130
6128 6131 See :hg:`help dates` for a list of formats valid for -d/--date.
6129 6132
6130 6133 See :hg:`help backout` for a way to reverse the effect of an
6131 6134 earlier changeset.
6132 6135
6133 6136 Returns 0 on success.
6134 6137 """
6135 6138
6136 6139 opts = pycompat.byteskwargs(opts)
6137 6140 if opts.get(b"date"):
6138 6141 cmdutil.check_incompatible_arguments(opts, b'date', [b'rev'])
6139 6142 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6140 6143
6141 6144 parent, p2 = repo.dirstate.parents()
6142 6145 if not opts.get(b'rev') and p2 != nullid:
6143 6146 # revert after merge is a trap for new users (issue2915)
6144 6147 raise error.InputError(
6145 6148 _(b'uncommitted merge with no revision specified'),
6146 6149 hint=_(b"use 'hg update' or see 'hg help revert'"),
6147 6150 )
6148 6151
6149 6152 rev = opts.get(b'rev')
6150 6153 if rev:
6151 6154 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6152 6155 ctx = scmutil.revsingle(repo, rev)
6153 6156
6154 6157 if not (
6155 6158 pats
6156 6159 or opts.get(b'include')
6157 6160 or opts.get(b'exclude')
6158 6161 or opts.get(b'all')
6159 6162 or opts.get(b'interactive')
6160 6163 ):
6161 6164 msg = _(b"no files or directories specified")
6162 6165 if p2 != nullid:
6163 6166 hint = _(
6164 6167 b"uncommitted merge, use --all to discard all changes,"
6165 6168 b" or 'hg update -C .' to abort the merge"
6166 6169 )
6167 6170 raise error.InputError(msg, hint=hint)
6168 6171 dirty = any(repo.status())
6169 6172 node = ctx.node()
6170 6173 if node != parent:
6171 6174 if dirty:
6172 6175 hint = (
6173 6176 _(
6174 6177 b"uncommitted changes, use --all to discard all"
6175 6178 b" changes, or 'hg update %d' to update"
6176 6179 )
6177 6180 % ctx.rev()
6178 6181 )
6179 6182 else:
6180 6183 hint = (
6181 6184 _(
6182 6185 b"use --all to revert all files,"
6183 6186 b" or 'hg update %d' to update"
6184 6187 )
6185 6188 % ctx.rev()
6186 6189 )
6187 6190 elif dirty:
6188 6191 hint = _(b"uncommitted changes, use --all to discard all changes")
6189 6192 else:
6190 6193 hint = _(b"use --all to revert all files")
6191 6194 raise error.InputError(msg, hint=hint)
6192 6195
6193 6196 return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts))
6194 6197
6195 6198
6196 6199 @command(
6197 6200 b'rollback',
6198 6201 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6199 6202 helpcategory=command.CATEGORY_MAINTENANCE,
6200 6203 )
6201 6204 def rollback(ui, repo, **opts):
6202 6205 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6203 6206
6204 6207 Please use :hg:`commit --amend` instead of rollback to correct
6205 6208 mistakes in the last commit.
6206 6209
6207 6210 This command should be used with care. There is only one level of
6208 6211 rollback, and there is no way to undo a rollback. It will also
6209 6212 restore the dirstate at the time of the last transaction, losing
6210 6213 any dirstate changes since that time. This command does not alter
6211 6214 the working directory.
6212 6215
6213 6216 Transactions are used to encapsulate the effects of all commands
6214 6217 that create new changesets or propagate existing changesets into a
6215 6218 repository.
6216 6219
6217 6220 .. container:: verbose
6218 6221
6219 6222 For example, the following commands are transactional, and their
6220 6223 effects can be rolled back:
6221 6224
6222 6225 - commit
6223 6226 - import
6224 6227 - pull
6225 6228 - push (with this repository as the destination)
6226 6229 - unbundle
6227 6230
6228 6231 To avoid permanent data loss, rollback will refuse to rollback a
6229 6232 commit transaction if it isn't checked out. Use --force to
6230 6233 override this protection.
6231 6234
6232 6235 The rollback command can be entirely disabled by setting the
6233 6236 ``ui.rollback`` configuration setting to false. If you're here
6234 6237 because you want to use rollback and it's disabled, you can
6235 6238 re-enable the command by setting ``ui.rollback`` to true.
6236 6239
6237 6240 This command is not intended for use on public repositories. Once
6238 6241 changes are visible for pull by other users, rolling a transaction
6239 6242 back locally is ineffective (someone else may already have pulled
6240 6243 the changes). Furthermore, a race is possible with readers of the
6241 6244 repository; for example an in-progress pull from the repository
6242 6245 may fail if a rollback is performed.
6243 6246
6244 6247 Returns 0 on success, 1 if no rollback data is available.
6245 6248 """
6246 6249 if not ui.configbool(b'ui', b'rollback'):
6247 6250 raise error.Abort(
6248 6251 _(b'rollback is disabled because it is unsafe'),
6249 6252 hint=b'see `hg help -v rollback` for information',
6250 6253 )
6251 6254 return repo.rollback(dryrun=opts.get('dry_run'), force=opts.get('force'))
6252 6255
6253 6256
6254 6257 @command(
6255 6258 b'root',
6256 6259 [] + formatteropts,
6257 6260 intents={INTENT_READONLY},
6258 6261 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6259 6262 )
6260 6263 def root(ui, repo, **opts):
6261 6264 """print the root (top) of the current working directory
6262 6265
6263 6266 Print the root directory of the current repository.
6264 6267
6265 6268 .. container:: verbose
6266 6269
6267 6270 Template:
6268 6271
6269 6272 The following keywords are supported in addition to the common template
6270 6273 keywords and functions. See also :hg:`help templates`.
6271 6274
6272 6275 :hgpath: String. Path to the .hg directory.
6273 6276 :storepath: String. Path to the directory holding versioned data.
6274 6277
6275 6278 Returns 0 on success.
6276 6279 """
6277 6280 opts = pycompat.byteskwargs(opts)
6278 6281 with ui.formatter(b'root', opts) as fm:
6279 6282 fm.startitem()
6280 6283 fm.write(b'reporoot', b'%s\n', repo.root)
6281 6284 fm.data(hgpath=repo.path, storepath=repo.spath)
6282 6285
6283 6286
6284 6287 @command(
6285 6288 b'serve',
6286 6289 [
6287 6290 (
6288 6291 b'A',
6289 6292 b'accesslog',
6290 6293 b'',
6291 6294 _(b'name of access log file to write to'),
6292 6295 _(b'FILE'),
6293 6296 ),
6294 6297 (b'd', b'daemon', None, _(b'run server in background')),
6295 6298 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6296 6299 (
6297 6300 b'E',
6298 6301 b'errorlog',
6299 6302 b'',
6300 6303 _(b'name of error log file to write to'),
6301 6304 _(b'FILE'),
6302 6305 ),
6303 6306 # use string type, then we can check if something was passed
6304 6307 (
6305 6308 b'p',
6306 6309 b'port',
6307 6310 b'',
6308 6311 _(b'port to listen on (default: 8000)'),
6309 6312 _(b'PORT'),
6310 6313 ),
6311 6314 (
6312 6315 b'a',
6313 6316 b'address',
6314 6317 b'',
6315 6318 _(b'address to listen on (default: all interfaces)'),
6316 6319 _(b'ADDR'),
6317 6320 ),
6318 6321 (
6319 6322 b'',
6320 6323 b'prefix',
6321 6324 b'',
6322 6325 _(b'prefix path to serve from (default: server root)'),
6323 6326 _(b'PREFIX'),
6324 6327 ),
6325 6328 (
6326 6329 b'n',
6327 6330 b'name',
6328 6331 b'',
6329 6332 _(b'name to show in web pages (default: working directory)'),
6330 6333 _(b'NAME'),
6331 6334 ),
6332 6335 (
6333 6336 b'',
6334 6337 b'web-conf',
6335 6338 b'',
6336 6339 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6337 6340 _(b'FILE'),
6338 6341 ),
6339 6342 (
6340 6343 b'',
6341 6344 b'webdir-conf',
6342 6345 b'',
6343 6346 _(b'name of the hgweb config file (DEPRECATED)'),
6344 6347 _(b'FILE'),
6345 6348 ),
6346 6349 (
6347 6350 b'',
6348 6351 b'pid-file',
6349 6352 b'',
6350 6353 _(b'name of file to write process ID to'),
6351 6354 _(b'FILE'),
6352 6355 ),
6353 6356 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6354 6357 (
6355 6358 b'',
6356 6359 b'cmdserver',
6357 6360 b'',
6358 6361 _(b'for remote clients (ADVANCED)'),
6359 6362 _(b'MODE'),
6360 6363 ),
6361 6364 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6362 6365 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6363 6366 (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
6364 6367 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6365 6368 (b'', b'print-url', None, _(b'start and print only the URL')),
6366 6369 ]
6367 6370 + subrepoopts,
6368 6371 _(b'[OPTION]...'),
6369 6372 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6370 6373 helpbasic=True,
6371 6374 optionalrepo=True,
6372 6375 )
6373 6376 def serve(ui, repo, **opts):
6374 6377 """start stand-alone webserver
6375 6378
6376 6379 Start a local HTTP repository browser and pull server. You can use
6377 6380 this for ad-hoc sharing and browsing of repositories. It is
6378 6381 recommended to use a real web server to serve a repository for
6379 6382 longer periods of time.
6380 6383
6381 6384 Please note that the server does not implement access control.
6382 6385 This means that, by default, anybody can read from the server and
6383 6386 nobody can write to it by default. Set the ``web.allow-push``
6384 6387 option to ``*`` to allow everybody to push to the server. You
6385 6388 should use a real web server if you need to authenticate users.
6386 6389
6387 6390 By default, the server logs accesses to stdout and errors to
6388 6391 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6389 6392 files.
6390 6393
6391 6394 To have the server choose a free port number to listen on, specify
6392 6395 a port number of 0; in this case, the server will print the port
6393 6396 number it uses.
6394 6397
6395 6398 Returns 0 on success.
6396 6399 """
6397 6400
6398 6401 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6399 6402 opts = pycompat.byteskwargs(opts)
6400 6403 if opts[b"print_url"] and ui.verbose:
6401 6404 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6402 6405
6403 6406 if opts[b"stdio"]:
6404 6407 if repo is None:
6405 6408 raise error.RepoError(
6406 6409 _(b"there is no Mercurial repository here (.hg not found)")
6407 6410 )
6408 6411 s = wireprotoserver.sshserver(ui, repo)
6409 6412 s.serve_forever()
6410 6413 return
6411 6414
6412 6415 service = server.createservice(ui, repo, opts)
6413 6416 return server.runservice(opts, initfn=service.init, runfn=service.run)
6414 6417
6415 6418
6416 6419 @command(
6417 6420 b'shelve',
6418 6421 [
6419 6422 (
6420 6423 b'A',
6421 6424 b'addremove',
6422 6425 None,
6423 6426 _(b'mark new/missing files as added/removed before shelving'),
6424 6427 ),
6425 6428 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6426 6429 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6427 6430 (
6428 6431 b'',
6429 6432 b'date',
6430 6433 b'',
6431 6434 _(b'shelve with the specified commit date'),
6432 6435 _(b'DATE'),
6433 6436 ),
6434 6437 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6435 6438 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6436 6439 (
6437 6440 b'k',
6438 6441 b'keep',
6439 6442 False,
6440 6443 _(b'shelve, but keep changes in the working directory'),
6441 6444 ),
6442 6445 (b'l', b'list', None, _(b'list current shelves')),
6443 6446 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6444 6447 (
6445 6448 b'n',
6446 6449 b'name',
6447 6450 b'',
6448 6451 _(b'use the given name for the shelved commit'),
6449 6452 _(b'NAME'),
6450 6453 ),
6451 6454 (
6452 6455 b'p',
6453 6456 b'patch',
6454 6457 None,
6455 6458 _(
6456 6459 b'output patches for changes (provide the names of the shelved '
6457 6460 b'changes as positional arguments)'
6458 6461 ),
6459 6462 ),
6460 6463 (b'i', b'interactive', None, _(b'interactive mode')),
6461 6464 (
6462 6465 b'',
6463 6466 b'stat',
6464 6467 None,
6465 6468 _(
6466 6469 b'output diffstat-style summary of changes (provide the names of '
6467 6470 b'the shelved changes as positional arguments)'
6468 6471 ),
6469 6472 ),
6470 6473 ]
6471 6474 + cmdutil.walkopts,
6472 6475 _(b'hg shelve [OPTION]... [FILE]...'),
6473 6476 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6474 6477 )
6475 6478 def shelve(ui, repo, *pats, **opts):
6476 6479 """save and set aside changes from the working directory
6477 6480
6478 6481 Shelving takes files that "hg status" reports as not clean, saves
6479 6482 the modifications to a bundle (a shelved change), and reverts the
6480 6483 files so that their state in the working directory becomes clean.
6481 6484
6482 6485 To restore these changes to the working directory, using "hg
6483 6486 unshelve"; this will work even if you switch to a different
6484 6487 commit.
6485 6488
6486 6489 When no files are specified, "hg shelve" saves all not-clean
6487 6490 files. If specific files or directories are named, only changes to
6488 6491 those files are shelved.
6489 6492
6490 6493 In bare shelve (when no files are specified, without interactive,
6491 6494 include and exclude option), shelving remembers information if the
6492 6495 working directory was on newly created branch, in other words working
6493 6496 directory was on different branch than its first parent. In this
6494 6497 situation unshelving restores branch information to the working directory.
6495 6498
6496 6499 Each shelved change has a name that makes it easier to find later.
6497 6500 The name of a shelved change defaults to being based on the active
6498 6501 bookmark, or if there is no active bookmark, the current named
6499 6502 branch. To specify a different name, use ``--name``.
6500 6503
6501 6504 To see a list of existing shelved changes, use the ``--list``
6502 6505 option. For each shelved change, this will print its name, age,
6503 6506 and description; use ``--patch`` or ``--stat`` for more details.
6504 6507
6505 6508 To delete specific shelved changes, use ``--delete``. To delete
6506 6509 all shelved changes, use ``--cleanup``.
6507 6510 """
6508 6511 opts = pycompat.byteskwargs(opts)
6509 6512 allowables = [
6510 6513 (b'addremove', {b'create'}), # 'create' is pseudo action
6511 6514 (b'unknown', {b'create'}),
6512 6515 (b'cleanup', {b'cleanup'}),
6513 6516 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6514 6517 (b'delete', {b'delete'}),
6515 6518 (b'edit', {b'create'}),
6516 6519 (b'keep', {b'create'}),
6517 6520 (b'list', {b'list'}),
6518 6521 (b'message', {b'create'}),
6519 6522 (b'name', {b'create'}),
6520 6523 (b'patch', {b'patch', b'list'}),
6521 6524 (b'stat', {b'stat', b'list'}),
6522 6525 ]
6523 6526
6524 6527 def checkopt(opt):
6525 6528 if opts.get(opt):
6526 6529 for i, allowable in allowables:
6527 6530 if opts[i] and opt not in allowable:
6528 6531 raise error.InputError(
6529 6532 _(
6530 6533 b"options '--%s' and '--%s' may not be "
6531 6534 b"used together"
6532 6535 )
6533 6536 % (opt, i)
6534 6537 )
6535 6538 return True
6536 6539
6537 6540 if checkopt(b'cleanup'):
6538 6541 if pats:
6539 6542 raise error.InputError(
6540 6543 _(b"cannot specify names when using '--cleanup'")
6541 6544 )
6542 6545 return shelvemod.cleanupcmd(ui, repo)
6543 6546 elif checkopt(b'delete'):
6544 6547 return shelvemod.deletecmd(ui, repo, pats)
6545 6548 elif checkopt(b'list'):
6546 6549 return shelvemod.listcmd(ui, repo, pats, opts)
6547 6550 elif checkopt(b'patch') or checkopt(b'stat'):
6548 6551 return shelvemod.patchcmds(ui, repo, pats, opts)
6549 6552 else:
6550 6553 return shelvemod.createcmd(ui, repo, pats, opts)
6551 6554
6552 6555
6553 6556 _NOTTERSE = b'nothing'
6554 6557
6555 6558
6556 6559 @command(
6557 6560 b'status|st',
6558 6561 [
6559 6562 (b'A', b'all', None, _(b'show status of all files')),
6560 6563 (b'm', b'modified', None, _(b'show only modified files')),
6561 6564 (b'a', b'added', None, _(b'show only added files')),
6562 6565 (b'r', b'removed', None, _(b'show only removed files')),
6563 6566 (b'd', b'deleted', None, _(b'show only missing files')),
6564 6567 (b'c', b'clean', None, _(b'show only files without changes')),
6565 6568 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6566 6569 (b'i', b'ignored', None, _(b'show only ignored files')),
6567 6570 (b'n', b'no-status', None, _(b'hide status prefix')),
6568 6571 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6569 6572 (
6570 6573 b'C',
6571 6574 b'copies',
6572 6575 None,
6573 6576 _(b'show source of copied files (DEFAULT: ui.statuscopies)'),
6574 6577 ),
6575 6578 (
6576 6579 b'0',
6577 6580 b'print0',
6578 6581 None,
6579 6582 _(b'end filenames with NUL, for use with xargs'),
6580 6583 ),
6581 6584 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6582 6585 (
6583 6586 b'',
6584 6587 b'change',
6585 6588 b'',
6586 6589 _(b'list the changed files of a revision'),
6587 6590 _(b'REV'),
6588 6591 ),
6589 6592 ]
6590 6593 + walkopts
6591 6594 + subrepoopts
6592 6595 + formatteropts,
6593 6596 _(b'[OPTION]... [FILE]...'),
6594 6597 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6595 6598 helpbasic=True,
6596 6599 inferrepo=True,
6597 6600 intents={INTENT_READONLY},
6598 6601 )
6599 6602 def status(ui, repo, *pats, **opts):
6600 6603 """show changed files in the working directory
6601 6604
6602 6605 Show status of files in the repository. If names are given, only
6603 6606 files that match are shown. Files that are clean or ignored or
6604 6607 the source of a copy/move operation, are not listed unless
6605 6608 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6606 6609 Unless options described with "show only ..." are given, the
6607 6610 options -mardu are used.
6608 6611
6609 6612 Option -q/--quiet hides untracked (unknown and ignored) files
6610 6613 unless explicitly requested with -u/--unknown or -i/--ignored.
6611 6614
6612 6615 .. note::
6613 6616
6614 6617 :hg:`status` may appear to disagree with diff if permissions have
6615 6618 changed or a merge has occurred. The standard diff format does
6616 6619 not report permission changes and diff only reports changes
6617 6620 relative to one merge parent.
6618 6621
6619 6622 If one revision is given, it is used as the base revision.
6620 6623 If two revisions are given, the differences between them are
6621 6624 shown. The --change option can also be used as a shortcut to list
6622 6625 the changed files of a revision from its first parent.
6623 6626
6624 6627 The codes used to show the status of files are::
6625 6628
6626 6629 M = modified
6627 6630 A = added
6628 6631 R = removed
6629 6632 C = clean
6630 6633 ! = missing (deleted by non-hg command, but still tracked)
6631 6634 ? = not tracked
6632 6635 I = ignored
6633 6636 = origin of the previous file (with --copies)
6634 6637
6635 6638 .. container:: verbose
6636 6639
6637 6640 The -t/--terse option abbreviates the output by showing only the directory
6638 6641 name if all the files in it share the same status. The option takes an
6639 6642 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6640 6643 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6641 6644 for 'ignored' and 'c' for clean.
6642 6645
6643 6646 It abbreviates only those statuses which are passed. Note that clean and
6644 6647 ignored files are not displayed with '--terse ic' unless the -c/--clean
6645 6648 and -i/--ignored options are also used.
6646 6649
6647 6650 The -v/--verbose option shows information when the repository is in an
6648 6651 unfinished merge, shelve, rebase state etc. You can have this behavior
6649 6652 turned on by default by enabling the ``commands.status.verbose`` option.
6650 6653
6651 6654 You can skip displaying some of these states by setting
6652 6655 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6653 6656 'histedit', 'merge', 'rebase', or 'unshelve'.
6654 6657
6655 6658 Template:
6656 6659
6657 6660 The following keywords are supported in addition to the common template
6658 6661 keywords and functions. See also :hg:`help templates`.
6659 6662
6660 6663 :path: String. Repository-absolute path of the file.
6661 6664 :source: String. Repository-absolute path of the file originated from.
6662 6665 Available if ``--copies`` is specified.
6663 6666 :status: String. Character denoting file's status.
6664 6667
6665 6668 Examples:
6666 6669
6667 6670 - show changes in the working directory relative to a
6668 6671 changeset::
6669 6672
6670 6673 hg status --rev 9353
6671 6674
6672 6675 - show changes in the working directory relative to the
6673 6676 current directory (see :hg:`help patterns` for more information)::
6674 6677
6675 6678 hg status re:
6676 6679
6677 6680 - show all changes including copies in an existing changeset::
6678 6681
6679 6682 hg status --copies --change 9353
6680 6683
6681 6684 - get a NUL separated list of added files, suitable for xargs::
6682 6685
6683 6686 hg status -an0
6684 6687
6685 6688 - show more information about the repository status, abbreviating
6686 6689 added, removed, modified, deleted, and untracked paths::
6687 6690
6688 6691 hg status -v -t mardu
6689 6692
6690 6693 Returns 0 on success.
6691 6694
6692 6695 """
6693 6696
6694 6697 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
6695 6698 opts = pycompat.byteskwargs(opts)
6696 6699 revs = opts.get(b'rev')
6697 6700 change = opts.get(b'change')
6698 6701 terse = opts.get(b'terse')
6699 6702 if terse is _NOTTERSE:
6700 6703 if revs:
6701 6704 terse = b''
6702 6705 else:
6703 6706 terse = ui.config(b'commands', b'status.terse')
6704 6707
6705 6708 if revs and terse:
6706 6709 msg = _(b'cannot use --terse with --rev')
6707 6710 raise error.InputError(msg)
6708 6711 elif change:
6709 6712 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6710 6713 ctx2 = scmutil.revsingle(repo, change, None)
6711 6714 ctx1 = ctx2.p1()
6712 6715 else:
6713 6716 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6714 6717 ctx1, ctx2 = scmutil.revpair(repo, revs)
6715 6718
6716 6719 forcerelativevalue = None
6717 6720 if ui.hasconfig(b'commands', b'status.relative'):
6718 6721 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
6719 6722 uipathfn = scmutil.getuipathfn(
6720 6723 repo,
6721 6724 legacyrelativevalue=bool(pats),
6722 6725 forcerelativevalue=forcerelativevalue,
6723 6726 )
6724 6727
6725 6728 if opts.get(b'print0'):
6726 6729 end = b'\0'
6727 6730 else:
6728 6731 end = b'\n'
6729 6732 states = b'modified added removed deleted unknown ignored clean'.split()
6730 6733 show = [k for k in states if opts.get(k)]
6731 6734 if opts.get(b'all'):
6732 6735 show += ui.quiet and (states[:4] + [b'clean']) or states
6733 6736
6734 6737 if not show:
6735 6738 if ui.quiet:
6736 6739 show = states[:4]
6737 6740 else:
6738 6741 show = states[:5]
6739 6742
6740 6743 m = scmutil.match(ctx2, pats, opts)
6741 6744 if terse:
6742 6745 # we need to compute clean and unknown to terse
6743 6746 stat = repo.status(
6744 6747 ctx1.node(),
6745 6748 ctx2.node(),
6746 6749 m,
6747 6750 b'ignored' in show or b'i' in terse,
6748 6751 clean=True,
6749 6752 unknown=True,
6750 6753 listsubrepos=opts.get(b'subrepos'),
6751 6754 )
6752 6755
6753 6756 stat = cmdutil.tersedir(stat, terse)
6754 6757 else:
6755 6758 stat = repo.status(
6756 6759 ctx1.node(),
6757 6760 ctx2.node(),
6758 6761 m,
6759 6762 b'ignored' in show,
6760 6763 b'clean' in show,
6761 6764 b'unknown' in show,
6762 6765 opts.get(b'subrepos'),
6763 6766 )
6764 6767
6765 6768 changestates = zip(
6766 6769 states,
6767 6770 pycompat.iterbytestr(b'MAR!?IC'),
6768 6771 [getattr(stat, s.decode('utf8')) for s in states],
6769 6772 )
6770 6773
6771 6774 copy = {}
6772 6775 if (
6773 6776 opts.get(b'all')
6774 6777 or opts.get(b'copies')
6775 6778 or ui.configbool(b'ui', b'statuscopies')
6776 6779 ) and not opts.get(b'no_status'):
6777 6780 copy = copies.pathcopies(ctx1, ctx2, m)
6778 6781
6779 6782 morestatus = None
6780 6783 if (
6781 6784 (ui.verbose or ui.configbool(b'commands', b'status.verbose'))
6782 6785 and not ui.plain()
6783 6786 and not opts.get(b'print0')
6784 6787 ):
6785 6788 morestatus = cmdutil.readmorestatus(repo)
6786 6789
6787 6790 ui.pager(b'status')
6788 6791 fm = ui.formatter(b'status', opts)
6789 6792 fmt = b'%s' + end
6790 6793 showchar = not opts.get(b'no_status')
6791 6794
6792 6795 for state, char, files in changestates:
6793 6796 if state in show:
6794 6797 label = b'status.' + state
6795 6798 for f in files:
6796 6799 fm.startitem()
6797 6800 fm.context(ctx=ctx2)
6798 6801 fm.data(itemtype=b'file', path=f)
6799 6802 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
6800 6803 fm.plain(fmt % uipathfn(f), label=label)
6801 6804 if f in copy:
6802 6805 fm.data(source=copy[f])
6803 6806 fm.plain(
6804 6807 (b' %s' + end) % uipathfn(copy[f]),
6805 6808 label=b'status.copied',
6806 6809 )
6807 6810 if morestatus:
6808 6811 morestatus.formatfile(f, fm)
6809 6812
6810 6813 if morestatus:
6811 6814 morestatus.formatfooter(fm)
6812 6815 fm.end()
6813 6816
6814 6817
6815 6818 @command(
6816 6819 b'summary|sum',
6817 6820 [(b'', b'remote', None, _(b'check for push and pull'))],
6818 6821 b'[--remote]',
6819 6822 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6820 6823 helpbasic=True,
6821 6824 intents={INTENT_READONLY},
6822 6825 )
6823 6826 def summary(ui, repo, **opts):
6824 6827 """summarize working directory state
6825 6828
6826 6829 This generates a brief summary of the working directory state,
6827 6830 including parents, branch, commit status, phase and available updates.
6828 6831
6829 6832 With the --remote option, this will check the default paths for
6830 6833 incoming and outgoing changes. This can be time-consuming.
6831 6834
6832 6835 Returns 0 on success.
6833 6836 """
6834 6837
6835 6838 opts = pycompat.byteskwargs(opts)
6836 6839 ui.pager(b'summary')
6837 6840 ctx = repo[None]
6838 6841 parents = ctx.parents()
6839 6842 pnode = parents[0].node()
6840 6843 marks = []
6841 6844
6842 6845 try:
6843 6846 ms = mergestatemod.mergestate.read(repo)
6844 6847 except error.UnsupportedMergeRecords as e:
6845 6848 s = b' '.join(e.recordtypes)
6846 6849 ui.warn(
6847 6850 _(b'warning: merge state has unsupported record types: %s\n') % s
6848 6851 )
6849 6852 unresolved = []
6850 6853 else:
6851 6854 unresolved = list(ms.unresolved())
6852 6855
6853 6856 for p in parents:
6854 6857 # label with log.changeset (instead of log.parent) since this
6855 6858 # shows a working directory parent *changeset*:
6856 6859 # i18n: column positioning for "hg summary"
6857 6860 ui.write(
6858 6861 _(b'parent: %d:%s ') % (p.rev(), p),
6859 6862 label=logcmdutil.changesetlabels(p),
6860 6863 )
6861 6864 ui.write(b' '.join(p.tags()), label=b'log.tag')
6862 6865 if p.bookmarks():
6863 6866 marks.extend(p.bookmarks())
6864 6867 if p.rev() == -1:
6865 6868 if not len(repo):
6866 6869 ui.write(_(b' (empty repository)'))
6867 6870 else:
6868 6871 ui.write(_(b' (no revision checked out)'))
6869 6872 if p.obsolete():
6870 6873 ui.write(_(b' (obsolete)'))
6871 6874 if p.isunstable():
6872 6875 instabilities = (
6873 6876 ui.label(instability, b'trouble.%s' % instability)
6874 6877 for instability in p.instabilities()
6875 6878 )
6876 6879 ui.write(b' (' + b', '.join(instabilities) + b')')
6877 6880 ui.write(b'\n')
6878 6881 if p.description():
6879 6882 ui.status(
6880 6883 b' ' + p.description().splitlines()[0].strip() + b'\n',
6881 6884 label=b'log.summary',
6882 6885 )
6883 6886
6884 6887 branch = ctx.branch()
6885 6888 bheads = repo.branchheads(branch)
6886 6889 # i18n: column positioning for "hg summary"
6887 6890 m = _(b'branch: %s\n') % branch
6888 6891 if branch != b'default':
6889 6892 ui.write(m, label=b'log.branch')
6890 6893 else:
6891 6894 ui.status(m, label=b'log.branch')
6892 6895
6893 6896 if marks:
6894 6897 active = repo._activebookmark
6895 6898 # i18n: column positioning for "hg summary"
6896 6899 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
6897 6900 if active is not None:
6898 6901 if active in marks:
6899 6902 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
6900 6903 marks.remove(active)
6901 6904 else:
6902 6905 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
6903 6906 for m in marks:
6904 6907 ui.write(b' ' + m, label=b'log.bookmark')
6905 6908 ui.write(b'\n', label=b'log.bookmark')
6906 6909
6907 6910 status = repo.status(unknown=True)
6908 6911
6909 6912 c = repo.dirstate.copies()
6910 6913 copied, renamed = [], []
6911 6914 for d, s in pycompat.iteritems(c):
6912 6915 if s in status.removed:
6913 6916 status.removed.remove(s)
6914 6917 renamed.append(d)
6915 6918 else:
6916 6919 copied.append(d)
6917 6920 if d in status.added:
6918 6921 status.added.remove(d)
6919 6922
6920 6923 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6921 6924
6922 6925 labels = [
6923 6926 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
6924 6927 (ui.label(_(b'%d added'), b'status.added'), status.added),
6925 6928 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
6926 6929 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
6927 6930 (ui.label(_(b'%d copied'), b'status.copied'), copied),
6928 6931 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
6929 6932 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
6930 6933 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
6931 6934 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
6932 6935 ]
6933 6936 t = []
6934 6937 for l, s in labels:
6935 6938 if s:
6936 6939 t.append(l % len(s))
6937 6940
6938 6941 t = b', '.join(t)
6939 6942 cleanworkdir = False
6940 6943
6941 6944 if repo.vfs.exists(b'graftstate'):
6942 6945 t += _(b' (graft in progress)')
6943 6946 if repo.vfs.exists(b'updatestate'):
6944 6947 t += _(b' (interrupted update)')
6945 6948 elif len(parents) > 1:
6946 6949 t += _(b' (merge)')
6947 6950 elif branch != parents[0].branch():
6948 6951 t += _(b' (new branch)')
6949 6952 elif parents[0].closesbranch() and pnode in repo.branchheads(
6950 6953 branch, closed=True
6951 6954 ):
6952 6955 t += _(b' (head closed)')
6953 6956 elif not (
6954 6957 status.modified
6955 6958 or status.added
6956 6959 or status.removed
6957 6960 or renamed
6958 6961 or copied
6959 6962 or subs
6960 6963 ):
6961 6964 t += _(b' (clean)')
6962 6965 cleanworkdir = True
6963 6966 elif pnode not in bheads:
6964 6967 t += _(b' (new branch head)')
6965 6968
6966 6969 if parents:
6967 6970 pendingphase = max(p.phase() for p in parents)
6968 6971 else:
6969 6972 pendingphase = phases.public
6970 6973
6971 6974 if pendingphase > phases.newcommitphase(ui):
6972 6975 t += b' (%s)' % phases.phasenames[pendingphase]
6973 6976
6974 6977 if cleanworkdir:
6975 6978 # i18n: column positioning for "hg summary"
6976 6979 ui.status(_(b'commit: %s\n') % t.strip())
6977 6980 else:
6978 6981 # i18n: column positioning for "hg summary"
6979 6982 ui.write(_(b'commit: %s\n') % t.strip())
6980 6983
6981 6984 # all ancestors of branch heads - all ancestors of parent = new csets
6982 6985 new = len(
6983 6986 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
6984 6987 )
6985 6988
6986 6989 if new == 0:
6987 6990 # i18n: column positioning for "hg summary"
6988 6991 ui.status(_(b'update: (current)\n'))
6989 6992 elif pnode not in bheads:
6990 6993 # i18n: column positioning for "hg summary"
6991 6994 ui.write(_(b'update: %d new changesets (update)\n') % new)
6992 6995 else:
6993 6996 # i18n: column positioning for "hg summary"
6994 6997 ui.write(
6995 6998 _(b'update: %d new changesets, %d branch heads (merge)\n')
6996 6999 % (new, len(bheads))
6997 7000 )
6998 7001
6999 7002 t = []
7000 7003 draft = len(repo.revs(b'draft()'))
7001 7004 if draft:
7002 7005 t.append(_(b'%d draft') % draft)
7003 7006 secret = len(repo.revs(b'secret()'))
7004 7007 if secret:
7005 7008 t.append(_(b'%d secret') % secret)
7006 7009
7007 7010 if draft or secret:
7008 7011 ui.status(_(b'phases: %s\n') % b', '.join(t))
7009 7012
7010 7013 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7011 7014 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7012 7015 numtrouble = len(repo.revs(trouble + b"()"))
7013 7016 # We write all the possibilities to ease translation
7014 7017 troublemsg = {
7015 7018 b"orphan": _(b"orphan: %d changesets"),
7016 7019 b"contentdivergent": _(b"content-divergent: %d changesets"),
7017 7020 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7018 7021 }
7019 7022 if numtrouble > 0:
7020 7023 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7021 7024
7022 7025 cmdutil.summaryhooks(ui, repo)
7023 7026
7024 7027 if opts.get(b'remote'):
7025 7028 needsincoming, needsoutgoing = True, True
7026 7029 else:
7027 7030 needsincoming, needsoutgoing = False, False
7028 7031 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
7029 7032 if i:
7030 7033 needsincoming = True
7031 7034 if o:
7032 7035 needsoutgoing = True
7033 7036 if not needsincoming and not needsoutgoing:
7034 7037 return
7035 7038
7036 7039 def getincoming():
7037 7040 source, branches = hg.parseurl(ui.expandpath(b'default'))
7038 7041 sbranch = branches[0]
7039 7042 try:
7040 7043 other = hg.peer(repo, {}, source)
7041 7044 except error.RepoError:
7042 7045 if opts.get(b'remote'):
7043 7046 raise
7044 7047 return source, sbranch, None, None, None
7045 7048 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7046 7049 if revs:
7047 7050 revs = [other.lookup(rev) for rev in revs]
7048 7051 ui.debug(b'comparing with %s\n' % util.hidepassword(source))
7049 7052 repo.ui.pushbuffer()
7050 7053 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7051 7054 repo.ui.popbuffer()
7052 7055 return source, sbranch, other, commoninc, commoninc[1]
7053 7056
7054 7057 if needsincoming:
7055 7058 source, sbranch, sother, commoninc, incoming = getincoming()
7056 7059 else:
7057 7060 source = sbranch = sother = commoninc = incoming = None
7058 7061
7059 7062 def getoutgoing():
7060 7063 dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
7061 7064 dbranch = branches[0]
7062 7065 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
7063 7066 if source != dest:
7064 7067 try:
7065 7068 dother = hg.peer(repo, {}, dest)
7066 7069 except error.RepoError:
7067 7070 if opts.get(b'remote'):
7068 7071 raise
7069 7072 return dest, dbranch, None, None
7070 7073 ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
7071 7074 elif sother is None:
7072 7075 # there is no explicit destination peer, but source one is invalid
7073 7076 return dest, dbranch, None, None
7074 7077 else:
7075 7078 dother = sother
7076 7079 if source != dest or (sbranch is not None and sbranch != dbranch):
7077 7080 common = None
7078 7081 else:
7079 7082 common = commoninc
7080 7083 if revs:
7081 7084 revs = [repo.lookup(rev) for rev in revs]
7082 7085 repo.ui.pushbuffer()
7083 7086 outgoing = discovery.findcommonoutgoing(
7084 7087 repo, dother, onlyheads=revs, commoninc=common
7085 7088 )
7086 7089 repo.ui.popbuffer()
7087 7090 return dest, dbranch, dother, outgoing
7088 7091
7089 7092 if needsoutgoing:
7090 7093 dest, dbranch, dother, outgoing = getoutgoing()
7091 7094 else:
7092 7095 dest = dbranch = dother = outgoing = None
7093 7096
7094 7097 if opts.get(b'remote'):
7095 7098 t = []
7096 7099 if incoming:
7097 7100 t.append(_(b'1 or more incoming'))
7098 7101 o = outgoing.missing
7099 7102 if o:
7100 7103 t.append(_(b'%d outgoing') % len(o))
7101 7104 other = dother or sother
7102 7105 if b'bookmarks' in other.listkeys(b'namespaces'):
7103 7106 counts = bookmarks.summary(repo, other)
7104 7107 if counts[0] > 0:
7105 7108 t.append(_(b'%d incoming bookmarks') % counts[0])
7106 7109 if counts[1] > 0:
7107 7110 t.append(_(b'%d outgoing bookmarks') % counts[1])
7108 7111
7109 7112 if t:
7110 7113 # i18n: column positioning for "hg summary"
7111 7114 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7112 7115 else:
7113 7116 # i18n: column positioning for "hg summary"
7114 7117 ui.status(_(b'remote: (synced)\n'))
7115 7118
7116 7119 cmdutil.summaryremotehooks(
7117 7120 ui,
7118 7121 repo,
7119 7122 opts,
7120 7123 (
7121 7124 (source, sbranch, sother, commoninc),
7122 7125 (dest, dbranch, dother, outgoing),
7123 7126 ),
7124 7127 )
7125 7128
7126 7129
7127 7130 @command(
7128 7131 b'tag',
7129 7132 [
7130 7133 (b'f', b'force', None, _(b'force tag')),
7131 7134 (b'l', b'local', None, _(b'make the tag local')),
7132 7135 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7133 7136 (b'', b'remove', None, _(b'remove a tag')),
7134 7137 # -l/--local is already there, commitopts cannot be used
7135 7138 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7136 7139 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7137 7140 ]
7138 7141 + commitopts2,
7139 7142 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7140 7143 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7141 7144 )
7142 7145 def tag(ui, repo, name1, *names, **opts):
7143 7146 """add one or more tags for the current or given revision
7144 7147
7145 7148 Name a particular revision using <name>.
7146 7149
7147 7150 Tags are used to name particular revisions of the repository and are
7148 7151 very useful to compare different revisions, to go back to significant
7149 7152 earlier versions or to mark branch points as releases, etc. Changing
7150 7153 an existing tag is normally disallowed; use -f/--force to override.
7151 7154
7152 7155 If no revision is given, the parent of the working directory is
7153 7156 used.
7154 7157
7155 7158 To facilitate version control, distribution, and merging of tags,
7156 7159 they are stored as a file named ".hgtags" which is managed similarly
7157 7160 to other project files and can be hand-edited if necessary. This
7158 7161 also means that tagging creates a new commit. The file
7159 7162 ".hg/localtags" is used for local tags (not shared among
7160 7163 repositories).
7161 7164
7162 7165 Tag commits are usually made at the head of a branch. If the parent
7163 7166 of the working directory is not a branch head, :hg:`tag` aborts; use
7164 7167 -f/--force to force the tag commit to be based on a non-head
7165 7168 changeset.
7166 7169
7167 7170 See :hg:`help dates` for a list of formats valid for -d/--date.
7168 7171
7169 7172 Since tag names have priority over branch names during revision
7170 7173 lookup, using an existing branch name as a tag name is discouraged.
7171 7174
7172 7175 Returns 0 on success.
7173 7176 """
7174 7177 cmdutil.check_incompatible_arguments(opts, 'remove', ['rev'])
7175 7178 opts = pycompat.byteskwargs(opts)
7176 7179 with repo.wlock(), repo.lock():
7177 7180 rev_ = b"."
7178 7181 names = [t.strip() for t in (name1,) + names]
7179 7182 if len(names) != len(set(names)):
7180 7183 raise error.InputError(_(b'tag names must be unique'))
7181 7184 for n in names:
7182 7185 scmutil.checknewlabel(repo, n, b'tag')
7183 7186 if not n:
7184 7187 raise error.InputError(
7185 7188 _(b'tag names cannot consist entirely of whitespace')
7186 7189 )
7187 7190 if opts.get(b'rev'):
7188 7191 rev_ = opts[b'rev']
7189 7192 message = opts.get(b'message')
7190 7193 if opts.get(b'remove'):
7191 7194 if opts.get(b'local'):
7192 7195 expectedtype = b'local'
7193 7196 else:
7194 7197 expectedtype = b'global'
7195 7198
7196 7199 for n in names:
7197 7200 if repo.tagtype(n) == b'global':
7198 7201 alltags = tagsmod.findglobaltags(ui, repo)
7199 7202 if alltags[n][0] == nullid:
7200 7203 raise error.InputError(
7201 7204 _(b"tag '%s' is already removed") % n
7202 7205 )
7203 7206 if not repo.tagtype(n):
7204 7207 raise error.InputError(_(b"tag '%s' does not exist") % n)
7205 7208 if repo.tagtype(n) != expectedtype:
7206 7209 if expectedtype == b'global':
7207 7210 raise error.InputError(
7208 7211 _(b"tag '%s' is not a global tag") % n
7209 7212 )
7210 7213 else:
7211 7214 raise error.InputError(
7212 7215 _(b"tag '%s' is not a local tag") % n
7213 7216 )
7214 7217 rev_ = b'null'
7215 7218 if not message:
7216 7219 # we don't translate commit messages
7217 7220 message = b'Removed tag %s' % b', '.join(names)
7218 7221 elif not opts.get(b'force'):
7219 7222 for n in names:
7220 7223 if n in repo.tags():
7221 7224 raise error.InputError(
7222 7225 _(b"tag '%s' already exists (use -f to force)") % n
7223 7226 )
7224 7227 if not opts.get(b'local'):
7225 7228 p1, p2 = repo.dirstate.parents()
7226 7229 if p2 != nullid:
7227 7230 raise error.StateError(_(b'uncommitted merge'))
7228 7231 bheads = repo.branchheads()
7229 7232 if not opts.get(b'force') and bheads and p1 not in bheads:
7230 7233 raise error.InputError(
7231 7234 _(
7232 7235 b'working directory is not at a branch head '
7233 7236 b'(use -f to force)'
7234 7237 )
7235 7238 )
7236 7239 node = scmutil.revsingle(repo, rev_).node()
7237 7240
7238 7241 if not message:
7239 7242 # we don't translate commit messages
7240 7243 message = b'Added tag %s for changeset %s' % (
7241 7244 b', '.join(names),
7242 7245 short(node),
7243 7246 )
7244 7247
7245 7248 date = opts.get(b'date')
7246 7249 if date:
7247 7250 date = dateutil.parsedate(date)
7248 7251
7249 7252 if opts.get(b'remove'):
7250 7253 editform = b'tag.remove'
7251 7254 else:
7252 7255 editform = b'tag.add'
7253 7256 editor = cmdutil.getcommiteditor(
7254 7257 editform=editform, **pycompat.strkwargs(opts)
7255 7258 )
7256 7259
7257 7260 # don't allow tagging the null rev
7258 7261 if (
7259 7262 not opts.get(b'remove')
7260 7263 and scmutil.revsingle(repo, rev_).rev() == nullrev
7261 7264 ):
7262 7265 raise error.InputError(_(b"cannot tag null revision"))
7263 7266
7264 7267 tagsmod.tag(
7265 7268 repo,
7266 7269 names,
7267 7270 node,
7268 7271 message,
7269 7272 opts.get(b'local'),
7270 7273 opts.get(b'user'),
7271 7274 date,
7272 7275 editor=editor,
7273 7276 )
7274 7277
7275 7278
7276 7279 @command(
7277 7280 b'tags',
7278 7281 formatteropts,
7279 7282 b'',
7280 7283 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7281 7284 intents={INTENT_READONLY},
7282 7285 )
7283 7286 def tags(ui, repo, **opts):
7284 7287 """list repository tags
7285 7288
7286 7289 This lists both regular and local tags. When the -v/--verbose
7287 7290 switch is used, a third column "local" is printed for local tags.
7288 7291 When the -q/--quiet switch is used, only the tag name is printed.
7289 7292
7290 7293 .. container:: verbose
7291 7294
7292 7295 Template:
7293 7296
7294 7297 The following keywords are supported in addition to the common template
7295 7298 keywords and functions such as ``{tag}``. See also
7296 7299 :hg:`help templates`.
7297 7300
7298 7301 :type: String. ``local`` for local tags.
7299 7302
7300 7303 Returns 0 on success.
7301 7304 """
7302 7305
7303 7306 opts = pycompat.byteskwargs(opts)
7304 7307 ui.pager(b'tags')
7305 7308 fm = ui.formatter(b'tags', opts)
7306 7309 hexfunc = fm.hexfunc
7307 7310
7308 7311 for t, n in reversed(repo.tagslist()):
7309 7312 hn = hexfunc(n)
7310 7313 label = b'tags.normal'
7311 7314 tagtype = b''
7312 7315 if repo.tagtype(t) == b'local':
7313 7316 label = b'tags.local'
7314 7317 tagtype = b'local'
7315 7318
7316 7319 fm.startitem()
7317 7320 fm.context(repo=repo)
7318 7321 fm.write(b'tag', b'%s', t, label=label)
7319 7322 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7320 7323 fm.condwrite(
7321 7324 not ui.quiet,
7322 7325 b'rev node',
7323 7326 fmt,
7324 7327 repo.changelog.rev(n),
7325 7328 hn,
7326 7329 label=label,
7327 7330 )
7328 7331 fm.condwrite(
7329 7332 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7330 7333 )
7331 7334 fm.plain(b'\n')
7332 7335 fm.end()
7333 7336
7334 7337
7335 7338 @command(
7336 7339 b'tip',
7337 7340 [
7338 7341 (b'p', b'patch', None, _(b'show patch')),
7339 7342 (b'g', b'git', None, _(b'use git extended diff format')),
7340 7343 ]
7341 7344 + templateopts,
7342 7345 _(b'[-p] [-g]'),
7343 7346 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7344 7347 )
7345 7348 def tip(ui, repo, **opts):
7346 7349 """show the tip revision (DEPRECATED)
7347 7350
7348 7351 The tip revision (usually just called the tip) is the changeset
7349 7352 most recently added to the repository (and therefore the most
7350 7353 recently changed head).
7351 7354
7352 7355 If you have just made a commit, that commit will be the tip. If
7353 7356 you have just pulled changes from another repository, the tip of
7354 7357 that repository becomes the current tip. The "tip" tag is special
7355 7358 and cannot be renamed or assigned to a different changeset.
7356 7359
7357 7360 This command is deprecated, please use :hg:`heads` instead.
7358 7361
7359 7362 Returns 0 on success.
7360 7363 """
7361 7364 opts = pycompat.byteskwargs(opts)
7362 7365 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7363 7366 displayer.show(repo[b'tip'])
7364 7367 displayer.close()
7365 7368
7366 7369
7367 7370 @command(
7368 7371 b'unbundle',
7369 7372 [
7370 7373 (
7371 7374 b'u',
7372 7375 b'update',
7373 7376 None,
7374 7377 _(b'update to new branch head if changesets were unbundled'),
7375 7378 )
7376 7379 ],
7377 7380 _(b'[-u] FILE...'),
7378 7381 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7379 7382 )
7380 7383 def unbundle(ui, repo, fname1, *fnames, **opts):
7381 7384 """apply one or more bundle files
7382 7385
7383 7386 Apply one or more bundle files generated by :hg:`bundle`.
7384 7387
7385 7388 Returns 0 on success, 1 if an update has unresolved files.
7386 7389 """
7387 7390 fnames = (fname1,) + fnames
7388 7391
7389 7392 with repo.lock():
7390 7393 for fname in fnames:
7391 7394 f = hg.openpath(ui, fname)
7392 7395 gen = exchange.readbundle(ui, f, fname)
7393 7396 if isinstance(gen, streamclone.streamcloneapplier):
7394 7397 raise error.InputError(
7395 7398 _(
7396 7399 b'packed bundles cannot be applied with '
7397 7400 b'"hg unbundle"'
7398 7401 ),
7399 7402 hint=_(b'use "hg debugapplystreamclonebundle"'),
7400 7403 )
7401 7404 url = b'bundle:' + fname
7402 7405 try:
7403 7406 txnname = b'unbundle'
7404 7407 if not isinstance(gen, bundle2.unbundle20):
7405 7408 txnname = b'unbundle\n%s' % util.hidepassword(url)
7406 7409 with repo.transaction(txnname) as tr:
7407 7410 op = bundle2.applybundle(
7408 7411 repo, gen, tr, source=b'unbundle', url=url
7409 7412 )
7410 7413 except error.BundleUnknownFeatureError as exc:
7411 7414 raise error.Abort(
7412 7415 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7413 7416 hint=_(
7414 7417 b"see https://mercurial-scm.org/"
7415 7418 b"wiki/BundleFeature for more "
7416 7419 b"information"
7417 7420 ),
7418 7421 )
7419 7422 modheads = bundle2.combinechangegroupresults(op)
7420 7423
7421 7424 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
7422 7425
7423 7426
7424 7427 @command(
7425 7428 b'unshelve',
7426 7429 [
7427 7430 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7428 7431 (
7429 7432 b'c',
7430 7433 b'continue',
7431 7434 None,
7432 7435 _(b'continue an incomplete unshelve operation'),
7433 7436 ),
7434 7437 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7435 7438 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7436 7439 (
7437 7440 b'n',
7438 7441 b'name',
7439 7442 b'',
7440 7443 _(b'restore shelved change with given name'),
7441 7444 _(b'NAME'),
7442 7445 ),
7443 7446 (b't', b'tool', b'', _(b'specify merge tool')),
7444 7447 (
7445 7448 b'',
7446 7449 b'date',
7447 7450 b'',
7448 7451 _(b'set date for temporary commits (DEPRECATED)'),
7449 7452 _(b'DATE'),
7450 7453 ),
7451 7454 ],
7452 7455 _(b'hg unshelve [OPTION]... [[-n] SHELVED]'),
7453 7456 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7454 7457 )
7455 7458 def unshelve(ui, repo, *shelved, **opts):
7456 7459 """restore a shelved change to the working directory
7457 7460
7458 7461 This command accepts an optional name of a shelved change to
7459 7462 restore. If none is given, the most recent shelved change is used.
7460 7463
7461 7464 If a shelved change is applied successfully, the bundle that
7462 7465 contains the shelved changes is moved to a backup location
7463 7466 (.hg/shelve-backup).
7464 7467
7465 7468 Since you can restore a shelved change on top of an arbitrary
7466 7469 commit, it is possible that unshelving will result in a conflict
7467 7470 between your changes and the commits you are unshelving onto. If
7468 7471 this occurs, you must resolve the conflict, then use
7469 7472 ``--continue`` to complete the unshelve operation. (The bundle
7470 7473 will not be moved until you successfully complete the unshelve.)
7471 7474
7472 7475 (Alternatively, you can use ``--abort`` to abandon an unshelve
7473 7476 that causes a conflict. This reverts the unshelved changes, and
7474 7477 leaves the bundle in place.)
7475 7478
7476 7479 If bare shelved change (without interactive, include and exclude
7477 7480 option) was done on newly created branch it would restore branch
7478 7481 information to the working directory.
7479 7482
7480 7483 After a successful unshelve, the shelved changes are stored in a
7481 7484 backup directory. Only the N most recent backups are kept. N
7482 7485 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7483 7486 configuration option.
7484 7487
7485 7488 .. container:: verbose
7486 7489
7487 7490 Timestamp in seconds is used to decide order of backups. More
7488 7491 than ``maxbackups`` backups are kept, if same timestamp
7489 7492 prevents from deciding exact order of them, for safety.
7490 7493
7491 7494 Selected changes can be unshelved with ``--interactive`` flag.
7492 7495 The working directory is updated with the selected changes, and
7493 7496 only the unselected changes remain shelved.
7494 7497 Note: The whole shelve is applied to working directory first before
7495 7498 running interactively. So, this will bring up all the conflicts between
7496 7499 working directory and the shelve, irrespective of which changes will be
7497 7500 unshelved.
7498 7501 """
7499 7502 with repo.wlock():
7500 7503 return shelvemod.unshelvecmd(ui, repo, *shelved, **opts)
7501 7504
7502 7505
7503 7506 statemod.addunfinished(
7504 7507 b'unshelve',
7505 7508 fname=b'shelvedstate',
7506 7509 continueflag=True,
7507 7510 abortfunc=shelvemod.hgabortunshelve,
7508 7511 continuefunc=shelvemod.hgcontinueunshelve,
7509 7512 cmdmsg=_(b'unshelve already in progress'),
7510 7513 )
7511 7514
7512 7515
7513 7516 @command(
7514 7517 b'update|up|checkout|co',
7515 7518 [
7516 7519 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7517 7520 (b'c', b'check', None, _(b'require clean working directory')),
7518 7521 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7519 7522 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7520 7523 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7521 7524 ]
7522 7525 + mergetoolopts,
7523 7526 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7524 7527 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7525 7528 helpbasic=True,
7526 7529 )
7527 7530 def update(ui, repo, node=None, **opts):
7528 7531 """update working directory (or switch revisions)
7529 7532
7530 7533 Update the repository's working directory to the specified
7531 7534 changeset. If no changeset is specified, update to the tip of the
7532 7535 current named branch and move the active bookmark (see :hg:`help
7533 7536 bookmarks`).
7534 7537
7535 7538 Update sets the working directory's parent revision to the specified
7536 7539 changeset (see :hg:`help parents`).
7537 7540
7538 7541 If the changeset is not a descendant or ancestor of the working
7539 7542 directory's parent and there are uncommitted changes, the update is
7540 7543 aborted. With the -c/--check option, the working directory is checked
7541 7544 for uncommitted changes; if none are found, the working directory is
7542 7545 updated to the specified changeset.
7543 7546
7544 7547 .. container:: verbose
7545 7548
7546 7549 The -C/--clean, -c/--check, and -m/--merge options control what
7547 7550 happens if the working directory contains uncommitted changes.
7548 7551 At most of one of them can be specified.
7549 7552
7550 7553 1. If no option is specified, and if
7551 7554 the requested changeset is an ancestor or descendant of
7552 7555 the working directory's parent, the uncommitted changes
7553 7556 are merged into the requested changeset and the merged
7554 7557 result is left uncommitted. If the requested changeset is
7555 7558 not an ancestor or descendant (that is, it is on another
7556 7559 branch), the update is aborted and the uncommitted changes
7557 7560 are preserved.
7558 7561
7559 7562 2. With the -m/--merge option, the update is allowed even if the
7560 7563 requested changeset is not an ancestor or descendant of
7561 7564 the working directory's parent.
7562 7565
7563 7566 3. With the -c/--check option, the update is aborted and the
7564 7567 uncommitted changes are preserved.
7565 7568
7566 7569 4. With the -C/--clean option, uncommitted changes are discarded and
7567 7570 the working directory is updated to the requested changeset.
7568 7571
7569 7572 To cancel an uncommitted merge (and lose your changes), use
7570 7573 :hg:`merge --abort`.
7571 7574
7572 7575 Use null as the changeset to remove the working directory (like
7573 7576 :hg:`clone -U`).
7574 7577
7575 7578 If you want to revert just one file to an older revision, use
7576 7579 :hg:`revert [-r REV] NAME`.
7577 7580
7578 7581 See :hg:`help dates` for a list of formats valid for -d/--date.
7579 7582
7580 7583 Returns 0 on success, 1 if there are unresolved files.
7581 7584 """
7582 7585 cmdutil.check_at_most_one_arg(opts, 'clean', 'check', 'merge')
7583 7586 rev = opts.get('rev')
7584 7587 date = opts.get('date')
7585 7588 clean = opts.get('clean')
7586 7589 check = opts.get('check')
7587 7590 merge = opts.get('merge')
7588 7591 if rev and node:
7589 7592 raise error.InputError(_(b"please specify just one revision"))
7590 7593
7591 7594 if ui.configbool(b'commands', b'update.requiredest'):
7592 7595 if not node and not rev and not date:
7593 7596 raise error.InputError(
7594 7597 _(b'you must specify a destination'),
7595 7598 hint=_(b'for example: hg update ".::"'),
7596 7599 )
7597 7600
7598 7601 if rev is None or rev == b'':
7599 7602 rev = node
7600 7603
7601 7604 if date and rev is not None:
7602 7605 raise error.InputError(_(b"you can't specify a revision and a date"))
7603 7606
7604 7607 updatecheck = None
7605 7608 if check:
7606 7609 updatecheck = b'abort'
7607 7610 elif merge:
7608 7611 updatecheck = b'none'
7609 7612
7610 7613 with repo.wlock():
7611 7614 cmdutil.clearunfinished(repo)
7612 7615 if date:
7613 7616 rev = cmdutil.finddate(ui, repo, date)
7614 7617
7615 7618 # if we defined a bookmark, we have to remember the original name
7616 7619 brev = rev
7617 7620 if rev:
7618 7621 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7619 7622 ctx = scmutil.revsingle(repo, rev, default=None)
7620 7623 rev = ctx.rev()
7621 7624 hidden = ctx.hidden()
7622 7625 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
7623 7626 with ui.configoverride(overrides, b'update'):
7624 7627 ret = hg.updatetotally(
7625 7628 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7626 7629 )
7627 7630 if hidden:
7628 7631 ctxstr = ctx.hex()[:12]
7629 7632 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7630 7633
7631 7634 if ctx.obsolete():
7632 7635 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7633 7636 ui.warn(b"(%s)\n" % obsfatemsg)
7634 7637 return ret
7635 7638
7636 7639
7637 7640 @command(
7638 7641 b'verify',
7639 7642 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7640 7643 helpcategory=command.CATEGORY_MAINTENANCE,
7641 7644 )
7642 7645 def verify(ui, repo, **opts):
7643 7646 """verify the integrity of the repository
7644 7647
7645 7648 Verify the integrity of the current repository.
7646 7649
7647 7650 This will perform an extensive check of the repository's
7648 7651 integrity, validating the hashes and checksums of each entry in
7649 7652 the changelog, manifest, and tracked files, as well as the
7650 7653 integrity of their crosslinks and indices.
7651 7654
7652 7655 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7653 7656 for more information about recovery from corruption of the
7654 7657 repository.
7655 7658
7656 7659 Returns 0 on success, 1 if errors are encountered.
7657 7660 """
7658 7661 opts = pycompat.byteskwargs(opts)
7659 7662
7660 7663 level = None
7661 7664 if opts[b'full']:
7662 7665 level = verifymod.VERIFY_FULL
7663 7666 return hg.verify(repo, level)
7664 7667
7665 7668
7666 7669 @command(
7667 7670 b'version',
7668 7671 [] + formatteropts,
7669 7672 helpcategory=command.CATEGORY_HELP,
7670 7673 norepo=True,
7671 7674 intents={INTENT_READONLY},
7672 7675 )
7673 7676 def version_(ui, **opts):
7674 7677 """output version and copyright information
7675 7678
7676 7679 .. container:: verbose
7677 7680
7678 7681 Template:
7679 7682
7680 7683 The following keywords are supported. See also :hg:`help templates`.
7681 7684
7682 7685 :extensions: List of extensions.
7683 7686 :ver: String. Version number.
7684 7687
7685 7688 And each entry of ``{extensions}`` provides the following sub-keywords
7686 7689 in addition to ``{ver}``.
7687 7690
7688 7691 :bundled: Boolean. True if included in the release.
7689 7692 :name: String. Extension name.
7690 7693 """
7691 7694 opts = pycompat.byteskwargs(opts)
7692 7695 if ui.verbose:
7693 7696 ui.pager(b'version')
7694 7697 fm = ui.formatter(b"version", opts)
7695 7698 fm.startitem()
7696 7699 fm.write(
7697 7700 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
7698 7701 )
7699 7702 license = _(
7700 7703 b"(see https://mercurial-scm.org for more information)\n"
7701 7704 b"\nCopyright (C) 2005-2020 Matt Mackall and others\n"
7702 7705 b"This is free software; see the source for copying conditions. "
7703 7706 b"There is NO\nwarranty; "
7704 7707 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7705 7708 )
7706 7709 if not ui.quiet:
7707 7710 fm.plain(license)
7708 7711
7709 7712 if ui.verbose:
7710 7713 fm.plain(_(b"\nEnabled extensions:\n\n"))
7711 7714 # format names and versions into columns
7712 7715 names = []
7713 7716 vers = []
7714 7717 isinternals = []
7715 7718 for name, module in sorted(extensions.extensions()):
7716 7719 names.append(name)
7717 7720 vers.append(extensions.moduleversion(module) or None)
7718 7721 isinternals.append(extensions.ismoduleinternal(module))
7719 7722 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
7720 7723 if names:
7721 7724 namefmt = b" %%-%ds " % max(len(n) for n in names)
7722 7725 places = [_(b"external"), _(b"internal")]
7723 7726 for n, v, p in zip(names, vers, isinternals):
7724 7727 fn.startitem()
7725 7728 fn.condwrite(ui.verbose, b"name", namefmt, n)
7726 7729 if ui.verbose:
7727 7730 fn.plain(b"%s " % places[p])
7728 7731 fn.data(bundled=p)
7729 7732 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
7730 7733 if ui.verbose:
7731 7734 fn.plain(b"\n")
7732 7735 fn.end()
7733 7736 fm.end()
7734 7737
7735 7738
7736 7739 def loadcmdtable(ui, name, cmdtable):
7737 7740 """Load command functions from specified cmdtable"""
7738 7741 overrides = [cmd for cmd in cmdtable if cmd in table]
7739 7742 if overrides:
7740 7743 ui.warn(
7741 7744 _(b"extension '%s' overrides commands: %s\n")
7742 7745 % (name, b" ".join(overrides))
7743 7746 )
7744 7747 table.update(cmdtable)
@@ -1,3921 +1,3925 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 When two revision arguments are given, then changes are shown between
646 those revisions. If only one revision is specified then that revision is
647 compared to the working directory, and, when no revisions are specified,
648 the working directory files are compared to its first parent.
645 By default, the working directory files are compared to its first parent.
646 To see the differences from another revision, use --from. To see the
647 difference to another revision, use --to. For example, 'hg diff --from .^'
648 will show the differences from the working copy's grandparent to the
649 working copy, 'hg diff --to .' will show the diff from the working copy to
650 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
651 1.2' will show the diff between those two revisions.
649 652
650 653 Alternatively you can specify -c/--change with a revision to see the
651 changes in that changeset relative to its first parent.
654 changes in that changeset relative to its first parent (i.e. 'hg diff -c
655 42' is equivalent to 'hg diff --from 42^ --to 42')
652 656
653 657 Without the -a/--text option, diff will avoid generating diffs of files it
654 658 detects as binary. With -a, diff will generate a diff anyway, probably
655 659 with undesirable results.
656 660
657 661 Use the -g/--git option to generate diffs in the git extended diff format.
658 662 For more information, read 'hg help diffs'.
659 663
660 664 Returns 0 on success.
661 665
662 666 options ([+] can be repeated):
663 667
664 668 -r --rev REV [+] revision
665 669 --from REV revision to diff from
666 670 --to REV revision to diff to
667 671 -c --change REV change made by revision
668 672 -a --text treat all files as text
669 673 -g --git use git extended diff format
670 674 --binary generate binary diffs in git mode (default)
671 675 --nodates omit dates from diff headers
672 676 --noprefix omit a/ and b/ prefixes from filenames
673 677 -p --show-function show which function each change is in
674 678 --reverse produce a diff that undoes the changes
675 679 -w --ignore-all-space ignore white space when comparing lines
676 680 -b --ignore-space-change ignore changes in the amount of white space
677 681 -B --ignore-blank-lines ignore changes whose lines are all blank
678 682 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
679 683 -U --unified NUM number of lines of context to show
680 684 --stat output diffstat-style summary of changes
681 685 --root DIR produce diffs relative to subdirectory
682 686 -I --include PATTERN [+] include names matching the given patterns
683 687 -X --exclude PATTERN [+] exclude names matching the given patterns
684 688 -S --subrepos recurse into subrepositories
685 689
686 690 (some details hidden, use --verbose to show complete help)
687 691
688 692 $ hg help status
689 693 hg status [OPTION]... [FILE]...
690 694
691 695 aliases: st
692 696
693 697 show changed files in the working directory
694 698
695 699 Show status of files in the repository. If names are given, only files
696 700 that match are shown. Files that are clean or ignored or the source of a
697 701 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
698 702 -C/--copies or -A/--all are given. Unless options described with "show
699 703 only ..." are given, the options -mardu are used.
700 704
701 705 Option -q/--quiet hides untracked (unknown and ignored) files unless
702 706 explicitly requested with -u/--unknown or -i/--ignored.
703 707
704 708 Note:
705 709 'hg status' may appear to disagree with diff if permissions have
706 710 changed or a merge has occurred. The standard diff format does not
707 711 report permission changes and diff only reports changes relative to one
708 712 merge parent.
709 713
710 714 If one revision is given, it is used as the base revision. If two
711 715 revisions are given, the differences between them are shown. The --change
712 716 option can also be used as a shortcut to list the changed files of a
713 717 revision from its first parent.
714 718
715 719 The codes used to show the status of files are:
716 720
717 721 M = modified
718 722 A = added
719 723 R = removed
720 724 C = clean
721 725 ! = missing (deleted by non-hg command, but still tracked)
722 726 ? = not tracked
723 727 I = ignored
724 728 = origin of the previous file (with --copies)
725 729
726 730 Returns 0 on success.
727 731
728 732 options ([+] can be repeated):
729 733
730 734 -A --all show status of all files
731 735 -m --modified show only modified files
732 736 -a --added show only added files
733 737 -r --removed show only removed files
734 738 -d --deleted show only missing files
735 739 -c --clean show only files without changes
736 740 -u --unknown show only unknown (not tracked) files
737 741 -i --ignored show only ignored files
738 742 -n --no-status hide status prefix
739 743 -C --copies show source of copied files
740 744 -0 --print0 end filenames with NUL, for use with xargs
741 745 --rev REV [+] show difference from revision
742 746 --change REV list the changed files of a revision
743 747 -I --include PATTERN [+] include names matching the given patterns
744 748 -X --exclude PATTERN [+] exclude names matching the given patterns
745 749 -S --subrepos recurse into subrepositories
746 750 -T --template TEMPLATE display with template
747 751
748 752 (some details hidden, use --verbose to show complete help)
749 753
750 754 $ hg -q help status
751 755 hg status [OPTION]... [FILE]...
752 756
753 757 show changed files in the working directory
754 758
755 759 $ hg help foo
756 760 abort: no such help topic: foo
757 761 (try 'hg help --keyword foo')
758 762 [255]
759 763
760 764 $ hg skjdfks
761 765 hg: unknown command 'skjdfks'
762 766 (use 'hg help' for a list of commands)
763 767 [255]
764 768
765 769 Typoed command gives suggestion
766 770 $ hg puls
767 771 hg: unknown command 'puls'
768 772 (did you mean one of pull, push?)
769 773 [255]
770 774
771 775 Not enabled extension gets suggested
772 776
773 777 $ hg rebase
774 778 hg: unknown command 'rebase'
775 779 'rebase' is provided by the following extension:
776 780
777 781 rebase command to move sets of revisions to a different ancestor
778 782
779 783 (use 'hg help extensions' for information on enabling extensions)
780 784 [255]
781 785
782 786 Disabled extension gets suggested
783 787 $ hg --config extensions.rebase=! rebase
784 788 hg: unknown command 'rebase'
785 789 'rebase' is provided by the following extension:
786 790
787 791 rebase command to move sets of revisions to a different ancestor
788 792
789 793 (use 'hg help extensions' for information on enabling extensions)
790 794 [255]
791 795
792 796 Checking that help adapts based on the config:
793 797
794 798 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
795 799 -g --[no-]git use git extended diff format (default: on from
796 800 config)
797 801
798 802 Make sure that we don't run afoul of the help system thinking that
799 803 this is a section and erroring out weirdly.
800 804
801 805 $ hg .log
802 806 hg: unknown command '.log'
803 807 (did you mean log?)
804 808 [255]
805 809
806 810 $ hg log.
807 811 hg: unknown command 'log.'
808 812 (did you mean log?)
809 813 [255]
810 814 $ hg pu.lh
811 815 hg: unknown command 'pu.lh'
812 816 (did you mean one of pull, push?)
813 817 [255]
814 818
815 819 $ cat > helpext.py <<EOF
816 820 > import os
817 821 > from mercurial import commands, fancyopts, registrar
818 822 >
819 823 > def func(arg):
820 824 > return '%sfoo' % arg
821 825 > class customopt(fancyopts.customopt):
822 826 > def newstate(self, oldstate, newparam, abort):
823 827 > return '%sbar' % oldstate
824 828 > cmdtable = {}
825 829 > command = registrar.command(cmdtable)
826 830 >
827 831 > @command(b'nohelp',
828 832 > [(b'', b'longdesc', 3, b'x'*67),
829 833 > (b'n', b'', None, b'normal desc'),
830 834 > (b'', b'newline', b'', b'line1\nline2'),
831 835 > (b'', b'default-off', False, b'enable X'),
832 836 > (b'', b'default-on', True, b'enable Y'),
833 837 > (b'', b'callableopt', func, b'adds foo'),
834 838 > (b'', b'customopt', customopt(''), b'adds bar'),
835 839 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
836 840 > b'hg nohelp',
837 841 > norepo=True)
838 842 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
839 843 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
840 844 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
841 845 > def nohelp(ui, *args, **kwargs):
842 846 > pass
843 847 >
844 848 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
845 849 > def hashelp(ui, *args, **kwargs):
846 850 > """Extension command's help"""
847 851 >
848 852 > def uisetup(ui):
849 853 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
850 854 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
851 855 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
852 856 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
853 857 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
854 858 >
855 859 > EOF
856 860 $ echo '[extensions]' >> $HGRCPATH
857 861 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
858 862
859 863 Test for aliases
860 864
861 865 $ hg help | grep hgalias
862 866 hgalias My doc
863 867
864 868 $ hg help hgalias
865 869 hg hgalias [--remote]
866 870
867 871 alias for: hg summary
868 872
869 873 My doc
870 874
871 875 defined by: helpext
872 876
873 877 options:
874 878
875 879 --remote check for push and pull
876 880
877 881 (some details hidden, use --verbose to show complete help)
878 882 $ hg help hgaliasnodoc
879 883 hg hgaliasnodoc [--remote]
880 884
881 885 alias for: hg summary
882 886
883 887 summarize working directory state
884 888
885 889 This generates a brief summary of the working directory state, including
886 890 parents, branch, commit status, phase and available updates.
887 891
888 892 With the --remote option, this will check the default paths for incoming
889 893 and outgoing changes. This can be time-consuming.
890 894
891 895 Returns 0 on success.
892 896
893 897 defined by: helpext
894 898
895 899 options:
896 900
897 901 --remote check for push and pull
898 902
899 903 (some details hidden, use --verbose to show complete help)
900 904
901 905 $ hg help shellalias
902 906 hg shellalias
903 907
904 908 shell alias for: echo hi
905 909
906 910 (no help text available)
907 911
908 912 defined by: helpext
909 913
910 914 (some details hidden, use --verbose to show complete help)
911 915
912 916 Test command with no help text
913 917
914 918 $ hg help nohelp
915 919 hg nohelp
916 920
917 921 (no help text available)
918 922
919 923 options:
920 924
921 925 --longdesc VALUE
922 926 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
923 927 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
924 928 -n -- normal desc
925 929 --newline VALUE line1 line2
926 930 --default-off enable X
927 931 --[no-]default-on enable Y (default: on)
928 932 --callableopt VALUE adds foo
929 933 --customopt VALUE adds bar
930 934 --customopt-withdefault VALUE adds bar (default: foo)
931 935
932 936 (some details hidden, use --verbose to show complete help)
933 937
934 938 Test that default list of commands includes extension commands that have help,
935 939 but not those that don't, except in verbose mode, when a keyword is passed, or
936 940 when help about the extension is requested.
937 941
938 942 #if no-extraextensions
939 943
940 944 $ hg help | grep hashelp
941 945 hashelp Extension command's help
942 946 $ hg help | grep nohelp
943 947 [1]
944 948 $ hg help -v | grep nohelp
945 949 nohelp (no help text available)
946 950
947 951 $ hg help -k nohelp
948 952 Commands:
949 953
950 954 nohelp hg nohelp
951 955
952 956 Extension Commands:
953 957
954 958 nohelp (no help text available)
955 959
956 960 $ hg help helpext
957 961 helpext extension - no help text available
958 962
959 963 list of commands:
960 964
961 965 hashelp Extension command's help
962 966 nohelp (no help text available)
963 967
964 968 (use 'hg help -v helpext' to show built-in aliases and global options)
965 969
966 970 #endif
967 971
968 972 Test list of internal help commands
969 973
970 974 $ hg help debug
971 975 debug commands (internal and unsupported):
972 976
973 977 debugancestor
974 978 find the ancestor revision of two revisions in a given index
975 979 debugantivirusrunning
976 980 attempt to trigger an antivirus scanner to see if one is active
977 981 debugapplystreamclonebundle
978 982 apply a stream clone bundle file
979 983 debugbackupbundle
980 984 lists the changesets available in backup bundles
981 985 debugbuilddag
982 986 builds a repo with a given DAG from scratch in the current
983 987 empty repo
984 988 debugbundle lists the contents of a bundle
985 989 debugcapabilities
986 990 lists the capabilities of a remote peer
987 991 debugchangedfiles
988 992 list the stored files changes for a revision
989 993 debugcheckstate
990 994 validate the correctness of the current dirstate
991 995 debugcolor show available color, effects or style
992 996 debugcommands
993 997 list all available commands and options
994 998 debugcomplete
995 999 returns the completion list associated with the given command
996 1000 debugcreatestreamclonebundle
997 1001 create a stream clone bundle file
998 1002 debugdag format the changelog or an index DAG as a concise textual
999 1003 description
1000 1004 debugdata dump the contents of a data file revision
1001 1005 debugdate parse and display a date
1002 1006 debugdeltachain
1003 1007 dump information about delta chains in a revlog
1004 1008 debugdirstate
1005 1009 show the contents of the current dirstate
1006 1010 debugdiscovery
1007 1011 runs the changeset discovery protocol in isolation
1008 1012 debugdownload
1009 1013 download a resource using Mercurial logic and config
1010 1014 debugextensions
1011 1015 show information about active extensions
1012 1016 debugfileset parse and apply a fileset specification
1013 1017 debugformat display format information about the current repository
1014 1018 debugfsinfo show information detected about current filesystem
1015 1019 debuggetbundle
1016 1020 retrieves a bundle from a repo
1017 1021 debugignore display the combined ignore pattern and information about
1018 1022 ignored files
1019 1023 debugindex dump index data for a storage primitive
1020 1024 debugindexdot
1021 1025 dump an index DAG as a graphviz dot file
1022 1026 debugindexstats
1023 1027 show stats related to the changelog index
1024 1028 debuginstall test Mercurial installation
1025 1029 debugknown test whether node ids are known to a repo
1026 1030 debuglocks show or modify state of locks
1027 1031 debugmanifestfulltextcache
1028 1032 show, clear or amend the contents of the manifest fulltext
1029 1033 cache
1030 1034 debugmergestate
1031 1035 print merge state
1032 1036 debugnamecomplete
1033 1037 complete "names" - tags, open branch names, bookmark names
1034 1038 debugnodemap write and inspect on disk nodemap
1035 1039 debugobsolete
1036 1040 create arbitrary obsolete marker
1037 1041 debugoptADV (no help text available)
1038 1042 debugoptDEP (no help text available)
1039 1043 debugoptEXP (no help text available)
1040 1044 debugp1copies
1041 1045 dump copy information compared to p1
1042 1046 debugp2copies
1043 1047 dump copy information compared to p2
1044 1048 debugpathcomplete
1045 1049 complete part or all of a tracked path
1046 1050 debugpathcopies
1047 1051 show copies between two revisions
1048 1052 debugpeer establish a connection to a peer repository
1049 1053 debugpickmergetool
1050 1054 examine which merge tool is chosen for specified file
1051 1055 debugpushkey access the pushkey key/value protocol
1052 1056 debugpvec (no help text available)
1053 1057 debugrebuilddirstate
1054 1058 rebuild the dirstate as it would look like for the given
1055 1059 revision
1056 1060 debugrebuildfncache
1057 1061 rebuild the fncache file
1058 1062 debugrename dump rename information
1059 1063 debugrequires
1060 1064 print the current repo requirements
1061 1065 debugrevlog show data and statistics about a revlog
1062 1066 debugrevlogindex
1063 1067 dump the contents of a revlog index
1064 1068 debugrevspec parse and apply a revision specification
1065 1069 debugserve run a server with advanced settings
1066 1070 debugsetparents
1067 1071 manually set the parents of the current working directory
1068 1072 debugsidedata
1069 1073 dump the side data for a cl/manifest/file revision
1070 1074 debugssl test a secure connection to a server
1071 1075 debugstrip strip changesets and all their descendants from the repository
1072 1076 debugsub (no help text available)
1073 1077 debugsuccessorssets
1074 1078 show set of successors for revision
1075 1079 debugtagscache
1076 1080 display the contents of .hg/cache/hgtagsfnodes1
1077 1081 debugtemplate
1078 1082 parse and apply a template
1079 1083 debuguigetpass
1080 1084 show prompt to type password
1081 1085 debuguiprompt
1082 1086 show plain prompt
1083 1087 debugupdatecaches
1084 1088 warm all known caches in the repository
1085 1089 debugupgraderepo
1086 1090 upgrade a repository to use different features
1087 1091 debugwalk show how files match on given patterns
1088 1092 debugwhyunstable
1089 1093 explain instabilities of a changeset
1090 1094 debugwireargs
1091 1095 (no help text available)
1092 1096 debugwireproto
1093 1097 send wire protocol commands to a server
1094 1098
1095 1099 (use 'hg help -v debug' to show built-in aliases and global options)
1096 1100
1097 1101 internals topic renders index of available sub-topics
1098 1102
1099 1103 $ hg help internals
1100 1104 Technical implementation topics
1101 1105 """""""""""""""""""""""""""""""
1102 1106
1103 1107 To access a subtopic, use "hg help internals.{subtopic-name}"
1104 1108
1105 1109 bid-merge Bid Merge Algorithm
1106 1110 bundle2 Bundle2
1107 1111 bundles Bundles
1108 1112 cbor CBOR
1109 1113 censor Censor
1110 1114 changegroups Changegroups
1111 1115 config Config Registrar
1112 1116 extensions Extension API
1113 1117 mergestate Mergestate
1114 1118 requirements Repository Requirements
1115 1119 revlogs Revision Logs
1116 1120 wireprotocol Wire Protocol
1117 1121 wireprotocolrpc
1118 1122 Wire Protocol RPC
1119 1123 wireprotocolv2
1120 1124 Wire Protocol Version 2
1121 1125
1122 1126 sub-topics can be accessed
1123 1127
1124 1128 $ hg help internals.changegroups
1125 1129 Changegroups
1126 1130 """"""""""""
1127 1131
1128 1132 Changegroups are representations of repository revlog data, specifically
1129 1133 the changelog data, root/flat manifest data, treemanifest data, and
1130 1134 filelogs.
1131 1135
1132 1136 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1133 1137 level, versions "1" and "2" are almost exactly the same, with the only
1134 1138 difference being an additional item in the *delta header*. Version "3"
1135 1139 adds support for storage flags in the *delta header* and optionally
1136 1140 exchanging treemanifests (enabled by setting an option on the
1137 1141 "changegroup" part in the bundle2).
1138 1142
1139 1143 Changegroups when not exchanging treemanifests consist of 3 logical
1140 1144 segments:
1141 1145
1142 1146 +---------------------------------+
1143 1147 | | | |
1144 1148 | changeset | manifest | filelogs |
1145 1149 | | | |
1146 1150 | | | |
1147 1151 +---------------------------------+
1148 1152
1149 1153 When exchanging treemanifests, there are 4 logical segments:
1150 1154
1151 1155 +-------------------------------------------------+
1152 1156 | | | | |
1153 1157 | changeset | root | treemanifests | filelogs |
1154 1158 | | manifest | | |
1155 1159 | | | | |
1156 1160 +-------------------------------------------------+
1157 1161
1158 1162 The principle building block of each segment is a *chunk*. A *chunk* is a
1159 1163 framed piece of data:
1160 1164
1161 1165 +---------------------------------------+
1162 1166 | | |
1163 1167 | length | data |
1164 1168 | (4 bytes) | (<length - 4> bytes) |
1165 1169 | | |
1166 1170 +---------------------------------------+
1167 1171
1168 1172 All integers are big-endian signed integers. Each chunk starts with a
1169 1173 32-bit integer indicating the length of the entire chunk (including the
1170 1174 length field itself).
1171 1175
1172 1176 There is a special case chunk that has a value of 0 for the length
1173 1177 ("0x00000000"). We call this an *empty chunk*.
1174 1178
1175 1179 Delta Groups
1176 1180 ============
1177 1181
1178 1182 A *delta group* expresses the content of a revlog as a series of deltas,
1179 1183 or patches against previous revisions.
1180 1184
1181 1185 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1182 1186 to signal the end of the delta group:
1183 1187
1184 1188 +------------------------------------------------------------------------+
1185 1189 | | | | | |
1186 1190 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1187 1191 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1188 1192 | | | | | |
1189 1193 +------------------------------------------------------------------------+
1190 1194
1191 1195 Each *chunk*'s data consists of the following:
1192 1196
1193 1197 +---------------------------------------+
1194 1198 | | |
1195 1199 | delta header | delta data |
1196 1200 | (various by version) | (various) |
1197 1201 | | |
1198 1202 +---------------------------------------+
1199 1203
1200 1204 The *delta data* is a series of *delta*s that describe a diff from an
1201 1205 existing entry (either that the recipient already has, or previously
1202 1206 specified in the bundle/changegroup).
1203 1207
1204 1208 The *delta header* is different between versions "1", "2", and "3" of the
1205 1209 changegroup format.
1206 1210
1207 1211 Version 1 (headerlen=80):
1208 1212
1209 1213 +------------------------------------------------------+
1210 1214 | | | | |
1211 1215 | node | p1 node | p2 node | link node |
1212 1216 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1213 1217 | | | | |
1214 1218 +------------------------------------------------------+
1215 1219
1216 1220 Version 2 (headerlen=100):
1217 1221
1218 1222 +------------------------------------------------------------------+
1219 1223 | | | | | |
1220 1224 | node | p1 node | p2 node | base node | link node |
1221 1225 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1222 1226 | | | | | |
1223 1227 +------------------------------------------------------------------+
1224 1228
1225 1229 Version 3 (headerlen=102):
1226 1230
1227 1231 +------------------------------------------------------------------------------+
1228 1232 | | | | | | |
1229 1233 | node | p1 node | p2 node | base node | link node | flags |
1230 1234 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1231 1235 | | | | | | |
1232 1236 +------------------------------------------------------------------------------+
1233 1237
1234 1238 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1235 1239 contain a series of *delta*s, densely packed (no separators). These deltas
1236 1240 describe a diff from an existing entry (either that the recipient already
1237 1241 has, or previously specified in the bundle/changegroup). The format is
1238 1242 described more fully in "hg help internals.bdiff", but briefly:
1239 1243
1240 1244 +---------------------------------------------------------------+
1241 1245 | | | | |
1242 1246 | start offset | end offset | new length | content |
1243 1247 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1244 1248 | | | | |
1245 1249 +---------------------------------------------------------------+
1246 1250
1247 1251 Please note that the length field in the delta data does *not* include
1248 1252 itself.
1249 1253
1250 1254 In version 1, the delta is always applied against the previous node from
1251 1255 the changegroup or the first parent if this is the first entry in the
1252 1256 changegroup.
1253 1257
1254 1258 In version 2 and up, the delta base node is encoded in the entry in the
1255 1259 changegroup. This allows the delta to be expressed against any parent,
1256 1260 which can result in smaller deltas and more efficient encoding of data.
1257 1261
1258 1262 The *flags* field holds bitwise flags affecting the processing of revision
1259 1263 data. The following flags are defined:
1260 1264
1261 1265 32768
1262 1266 Censored revision. The revision's fulltext has been replaced by censor
1263 1267 metadata. May only occur on file revisions.
1264 1268
1265 1269 16384
1266 1270 Ellipsis revision. Revision hash does not match data (likely due to
1267 1271 rewritten parents).
1268 1272
1269 1273 8192
1270 1274 Externally stored. The revision fulltext contains "key:value" "\n"
1271 1275 delimited metadata defining an object stored elsewhere. Used by the LFS
1272 1276 extension.
1273 1277
1274 1278 For historical reasons, the integer values are identical to revlog version
1275 1279 1 per-revision storage flags and correspond to bits being set in this
1276 1280 2-byte field. Bits were allocated starting from the most-significant bit,
1277 1281 hence the reverse ordering and allocation of these flags.
1278 1282
1279 1283 Changeset Segment
1280 1284 =================
1281 1285
1282 1286 The *changeset segment* consists of a single *delta group* holding
1283 1287 changelog data. The *empty chunk* at the end of the *delta group* denotes
1284 1288 the boundary to the *manifest segment*.
1285 1289
1286 1290 Manifest Segment
1287 1291 ================
1288 1292
1289 1293 The *manifest segment* consists of a single *delta group* holding manifest
1290 1294 data. If treemanifests are in use, it contains only the manifest for the
1291 1295 root directory of the repository. Otherwise, it contains the entire
1292 1296 manifest data. The *empty chunk* at the end of the *delta group* denotes
1293 1297 the boundary to the next segment (either the *treemanifests segment* or
1294 1298 the *filelogs segment*, depending on version and the request options).
1295 1299
1296 1300 Treemanifests Segment
1297 1301 ---------------------
1298 1302
1299 1303 The *treemanifests segment* only exists in changegroup version "3", and
1300 1304 only if the 'treemanifest' param is part of the bundle2 changegroup part
1301 1305 (it is not possible to use changegroup version 3 outside of bundle2).
1302 1306 Aside from the filenames in the *treemanifests segment* containing a
1303 1307 trailing "/" character, it behaves identically to the *filelogs segment*
1304 1308 (see below). The final sub-segment is followed by an *empty chunk*
1305 1309 (logically, a sub-segment with filename size 0). This denotes the boundary
1306 1310 to the *filelogs segment*.
1307 1311
1308 1312 Filelogs Segment
1309 1313 ================
1310 1314
1311 1315 The *filelogs segment* consists of multiple sub-segments, each
1312 1316 corresponding to an individual file whose data is being described:
1313 1317
1314 1318 +--------------------------------------------------+
1315 1319 | | | | | |
1316 1320 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1317 1321 | | | | | (4 bytes) |
1318 1322 | | | | | |
1319 1323 +--------------------------------------------------+
1320 1324
1321 1325 The final filelog sub-segment is followed by an *empty chunk* (logically,
1322 1326 a sub-segment with filename size 0). This denotes the end of the segment
1323 1327 and of the overall changegroup.
1324 1328
1325 1329 Each filelog sub-segment consists of the following:
1326 1330
1327 1331 +------------------------------------------------------+
1328 1332 | | | |
1329 1333 | filename length | filename | delta group |
1330 1334 | (4 bytes) | (<length - 4> bytes) | (various) |
1331 1335 | | | |
1332 1336 +------------------------------------------------------+
1333 1337
1334 1338 That is, a *chunk* consisting of the filename (not terminated or padded)
1335 1339 followed by N chunks constituting the *delta group* for this file. The
1336 1340 *empty chunk* at the end of each *delta group* denotes the boundary to the
1337 1341 next filelog sub-segment.
1338 1342
1339 1343 non-existent subtopics print an error
1340 1344
1341 1345 $ hg help internals.foo
1342 1346 abort: no such help topic: internals.foo
1343 1347 (try 'hg help --keyword foo')
1344 1348 [255]
1345 1349
1346 1350 test advanced, deprecated and experimental options are hidden in command help
1347 1351 $ hg help debugoptADV
1348 1352 hg debugoptADV
1349 1353
1350 1354 (no help text available)
1351 1355
1352 1356 options:
1353 1357
1354 1358 (some details hidden, use --verbose to show complete help)
1355 1359 $ hg help debugoptDEP
1356 1360 hg debugoptDEP
1357 1361
1358 1362 (no help text available)
1359 1363
1360 1364 options:
1361 1365
1362 1366 (some details hidden, use --verbose to show complete help)
1363 1367
1364 1368 $ hg help debugoptEXP
1365 1369 hg debugoptEXP
1366 1370
1367 1371 (no help text available)
1368 1372
1369 1373 options:
1370 1374
1371 1375 (some details hidden, use --verbose to show complete help)
1372 1376
1373 1377 test advanced, deprecated and experimental options are shown with -v
1374 1378 $ hg help -v debugoptADV | grep aopt
1375 1379 --aopt option is (ADVANCED)
1376 1380 $ hg help -v debugoptDEP | grep dopt
1377 1381 --dopt option is (DEPRECATED)
1378 1382 $ hg help -v debugoptEXP | grep eopt
1379 1383 --eopt option is (EXPERIMENTAL)
1380 1384
1381 1385 #if gettext
1382 1386 test deprecated option is hidden with translation with untranslated description
1383 1387 (use many globy for not failing on changed transaction)
1384 1388 $ LANGUAGE=sv hg help debugoptDEP
1385 1389 hg debugoptDEP
1386 1390
1387 1391 (*) (glob)
1388 1392
1389 1393 options:
1390 1394
1391 1395 (some details hidden, use --verbose to show complete help)
1392 1396 #endif
1393 1397
1394 1398 Test commands that collide with topics (issue4240)
1395 1399
1396 1400 $ hg config -hq
1397 1401 hg config [-u] [NAME]...
1398 1402
1399 1403 show combined config settings from all hgrc files
1400 1404 $ hg showconfig -hq
1401 1405 hg config [-u] [NAME]...
1402 1406
1403 1407 show combined config settings from all hgrc files
1404 1408
1405 1409 Test a help topic
1406 1410
1407 1411 $ hg help dates
1408 1412 Date Formats
1409 1413 """"""""""""
1410 1414
1411 1415 Some commands allow the user to specify a date, e.g.:
1412 1416
1413 1417 - backout, commit, import, tag: Specify the commit date.
1414 1418 - log, revert, update: Select revision(s) by date.
1415 1419
1416 1420 Many date formats are valid. Here are some examples:
1417 1421
1418 1422 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1419 1423 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1420 1424 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1421 1425 - "Dec 6" (midnight)
1422 1426 - "13:18" (today assumed)
1423 1427 - "3:39" (3:39AM assumed)
1424 1428 - "3:39pm" (15:39)
1425 1429 - "2006-12-06 13:18:29" (ISO 8601 format)
1426 1430 - "2006-12-6 13:18"
1427 1431 - "2006-12-6"
1428 1432 - "12-6"
1429 1433 - "12/6"
1430 1434 - "12/6/6" (Dec 6 2006)
1431 1435 - "today" (midnight)
1432 1436 - "yesterday" (midnight)
1433 1437 - "now" - right now
1434 1438
1435 1439 Lastly, there is Mercurial's internal format:
1436 1440
1437 1441 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1438 1442
1439 1443 This is the internal representation format for dates. The first number is
1440 1444 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1441 1445 is the offset of the local timezone, in seconds west of UTC (negative if
1442 1446 the timezone is east of UTC).
1443 1447
1444 1448 The log command also accepts date ranges:
1445 1449
1446 1450 - "<DATE" - at or before a given date/time
1447 1451 - ">DATE" - on or after a given date/time
1448 1452 - "DATE to DATE" - a date range, inclusive
1449 1453 - "-DAYS" - within a given number of days from today
1450 1454
1451 1455 Test repeated config section name
1452 1456
1453 1457 $ hg help config.host
1454 1458 "http_proxy.host"
1455 1459 Host name and (optional) port of the proxy server, for example
1456 1460 "myproxy:8000".
1457 1461
1458 1462 "smtp.host"
1459 1463 Host name of mail server, e.g. "mail.example.com".
1460 1464
1461 1465
1462 1466 Test section name with dot
1463 1467
1464 1468 $ hg help config.ui.username
1465 1469 "ui.username"
1466 1470 The committer of a changeset created when running "commit". Typically
1467 1471 a person's name and email address, e.g. "Fred Widget
1468 1472 <fred@example.com>". Environment variables in the username are
1469 1473 expanded.
1470 1474
1471 1475 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1472 1476 empty, e.g. if the system admin set "username =" in the system hgrc,
1473 1477 it has to be specified manually or in a different hgrc file)
1474 1478
1475 1479
1476 1480 $ hg help config.annotate.git
1477 1481 abort: help section not found: config.annotate.git
1478 1482 [255]
1479 1483
1480 1484 $ hg help config.update.check
1481 1485 "commands.update.check"
1482 1486 Determines what level of checking 'hg update' will perform before
1483 1487 moving to a destination revision. Valid values are "abort", "none",
1484 1488 "linear", and "noconflict". "abort" always fails if the working
1485 1489 directory has uncommitted changes. "none" performs no checking, and
1486 1490 may result in a merge with uncommitted changes. "linear" allows any
1487 1491 update as long as it follows a straight line in the revision history,
1488 1492 and may trigger a merge with uncommitted changes. "noconflict" will
1489 1493 allow any update which would not trigger a merge with uncommitted
1490 1494 changes, if any are present. (default: "linear")
1491 1495
1492 1496
1493 1497 $ hg help config.commands.update.check
1494 1498 "commands.update.check"
1495 1499 Determines what level of checking 'hg update' will perform before
1496 1500 moving to a destination revision. Valid values are "abort", "none",
1497 1501 "linear", and "noconflict". "abort" always fails if the working
1498 1502 directory has uncommitted changes. "none" performs no checking, and
1499 1503 may result in a merge with uncommitted changes. "linear" allows any
1500 1504 update as long as it follows a straight line in the revision history,
1501 1505 and may trigger a merge with uncommitted changes. "noconflict" will
1502 1506 allow any update which would not trigger a merge with uncommitted
1503 1507 changes, if any are present. (default: "linear")
1504 1508
1505 1509
1506 1510 $ hg help config.ommands.update.check
1507 1511 abort: help section not found: config.ommands.update.check
1508 1512 [255]
1509 1513
1510 1514 Unrelated trailing paragraphs shouldn't be included
1511 1515
1512 1516 $ hg help config.extramsg | grep '^$'
1513 1517
1514 1518
1515 1519 Test capitalized section name
1516 1520
1517 1521 $ hg help scripting.HGPLAIN > /dev/null
1518 1522
1519 1523 Help subsection:
1520 1524
1521 1525 $ hg help config.charsets |grep "Email example:" > /dev/null
1522 1526 [1]
1523 1527
1524 1528 Show nested definitions
1525 1529 ("profiling.type"[break]"ls"[break]"stat"[break])
1526 1530
1527 1531 $ hg help config.type | egrep '^$'|wc -l
1528 1532 \s*3 (re)
1529 1533
1530 1534 $ hg help config.profiling.type.ls
1531 1535 "profiling.type.ls"
1532 1536 Use Python's built-in instrumenting profiler. This profiler works on
1533 1537 all platforms, but each line number it reports is the first line of
1534 1538 a function. This restriction makes it difficult to identify the
1535 1539 expensive parts of a non-trivial function.
1536 1540
1537 1541
1538 1542 Separate sections from subsections
1539 1543
1540 1544 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1541 1545 "format"
1542 1546 --------
1543 1547
1544 1548 "usegeneraldelta"
1545 1549
1546 1550 "dotencode"
1547 1551
1548 1552 "usefncache"
1549 1553
1550 1554 "usestore"
1551 1555
1552 1556 "sparse-revlog"
1553 1557
1554 1558 "revlog-compression"
1555 1559
1556 1560 "bookmarks-in-store"
1557 1561
1558 1562 "profiling"
1559 1563 -----------
1560 1564
1561 1565 "format"
1562 1566
1563 1567 "progress"
1564 1568 ----------
1565 1569
1566 1570 "format"
1567 1571
1568 1572
1569 1573 Last item in help config.*:
1570 1574
1571 1575 $ hg help config.`hg help config|grep '^ "'| \
1572 1576 > tail -1|sed 's![ "]*!!g'`| \
1573 1577 > grep 'hg help -c config' > /dev/null
1574 1578 [1]
1575 1579
1576 1580 note to use help -c for general hg help config:
1577 1581
1578 1582 $ hg help config |grep 'hg help -c config' > /dev/null
1579 1583
1580 1584 Test templating help
1581 1585
1582 1586 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1583 1587 desc String. The text of the changeset description.
1584 1588 diffstat String. Statistics of changes with the following format:
1585 1589 firstline Any text. Returns the first line of text.
1586 1590 nonempty Any text. Returns '(none)' if the string is empty.
1587 1591
1588 1592 Test deprecated items
1589 1593
1590 1594 $ hg help -v templating | grep currentbookmark
1591 1595 currentbookmark
1592 1596 $ hg help templating | (grep currentbookmark || true)
1593 1597
1594 1598 Test help hooks
1595 1599
1596 1600 $ cat > helphook1.py <<EOF
1597 1601 > from mercurial import help
1598 1602 >
1599 1603 > def rewrite(ui, topic, doc):
1600 1604 > return doc + b'\nhelphook1\n'
1601 1605 >
1602 1606 > def extsetup(ui):
1603 1607 > help.addtopichook(b'revisions', rewrite)
1604 1608 > EOF
1605 1609 $ cat > helphook2.py <<EOF
1606 1610 > from mercurial import help
1607 1611 >
1608 1612 > def rewrite(ui, topic, doc):
1609 1613 > return doc + b'\nhelphook2\n'
1610 1614 >
1611 1615 > def extsetup(ui):
1612 1616 > help.addtopichook(b'revisions', rewrite)
1613 1617 > EOF
1614 1618 $ echo '[extensions]' >> $HGRCPATH
1615 1619 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1616 1620 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1617 1621 $ hg help revsets | grep helphook
1618 1622 helphook1
1619 1623 helphook2
1620 1624
1621 1625 help -c should only show debug --debug
1622 1626
1623 1627 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1624 1628 [1]
1625 1629
1626 1630 help -c should only show deprecated for -v
1627 1631
1628 1632 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1629 1633 [1]
1630 1634
1631 1635 Test -s / --system
1632 1636
1633 1637 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1634 1638 > wc -l | sed -e 's/ //g'
1635 1639 0
1636 1640 $ hg help config.files --system unix | grep 'USER' | \
1637 1641 > wc -l | sed -e 's/ //g'
1638 1642 0
1639 1643
1640 1644 Test -e / -c / -k combinations
1641 1645
1642 1646 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1643 1647 Commands:
1644 1648 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1645 1649 Extensions:
1646 1650 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1647 1651 Topics:
1648 1652 Commands:
1649 1653 Extensions:
1650 1654 Extension Commands:
1651 1655 $ hg help -c schemes
1652 1656 abort: no such help topic: schemes
1653 1657 (try 'hg help --keyword schemes')
1654 1658 [255]
1655 1659 $ hg help -e schemes |head -1
1656 1660 schemes extension - extend schemes with shortcuts to repository swarms
1657 1661 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1658 1662 Commands:
1659 1663 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1660 1664 Extensions:
1661 1665 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1662 1666 Extensions:
1663 1667 Commands:
1664 1668 $ hg help -c commit > /dev/null
1665 1669 $ hg help -e -c commit > /dev/null
1666 1670 $ hg help -e commit
1667 1671 abort: no such help topic: commit
1668 1672 (try 'hg help --keyword commit')
1669 1673 [255]
1670 1674
1671 1675 Test keyword search help
1672 1676
1673 1677 $ cat > prefixedname.py <<EOF
1674 1678 > '''matched against word "clone"
1675 1679 > '''
1676 1680 > EOF
1677 1681 $ echo '[extensions]' >> $HGRCPATH
1678 1682 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1679 1683 $ hg help -k clone
1680 1684 Topics:
1681 1685
1682 1686 config Configuration Files
1683 1687 extensions Using Additional Features
1684 1688 glossary Glossary
1685 1689 phases Working with Phases
1686 1690 subrepos Subrepositories
1687 1691 urls URL Paths
1688 1692
1689 1693 Commands:
1690 1694
1691 1695 bookmarks create a new bookmark or list existing bookmarks
1692 1696 clone make a copy of an existing repository
1693 1697 paths show aliases for remote repositories
1694 1698 pull pull changes from the specified source
1695 1699 update update working directory (or switch revisions)
1696 1700
1697 1701 Extensions:
1698 1702
1699 1703 clonebundles advertise pre-generated bundles to seed clones
1700 1704 narrow create clones which fetch history data for subset of files
1701 1705 (EXPERIMENTAL)
1702 1706 prefixedname matched against word "clone"
1703 1707 relink recreates hardlinks between repository clones
1704 1708
1705 1709 Extension Commands:
1706 1710
1707 1711 qclone clone main and patch repository at same time
1708 1712
1709 1713 Test unfound topic
1710 1714
1711 1715 $ hg help nonexistingtopicthatwillneverexisteverever
1712 1716 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1713 1717 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1714 1718 [255]
1715 1719
1716 1720 Test unfound keyword
1717 1721
1718 1722 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1719 1723 abort: no matches
1720 1724 (try 'hg help' for a list of topics)
1721 1725 [255]
1722 1726
1723 1727 Test omit indicating for help
1724 1728
1725 1729 $ cat > addverboseitems.py <<EOF
1726 1730 > r'''extension to test omit indicating.
1727 1731 >
1728 1732 > This paragraph is never omitted (for extension)
1729 1733 >
1730 1734 > .. container:: verbose
1731 1735 >
1732 1736 > This paragraph is omitted,
1733 1737 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1734 1738 >
1735 1739 > This paragraph is never omitted, too (for extension)
1736 1740 > '''
1737 1741 > from __future__ import absolute_import
1738 1742 > from mercurial import commands, help
1739 1743 > testtopic = br"""This paragraph is never omitted (for topic).
1740 1744 >
1741 1745 > .. container:: verbose
1742 1746 >
1743 1747 > This paragraph is omitted,
1744 1748 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1745 1749 >
1746 1750 > This paragraph is never omitted, too (for topic)
1747 1751 > """
1748 1752 > def extsetup(ui):
1749 1753 > help.helptable.append(([b"topic-containing-verbose"],
1750 1754 > b"This is the topic to test omit indicating.",
1751 1755 > lambda ui: testtopic))
1752 1756 > EOF
1753 1757 $ echo '[extensions]' >> $HGRCPATH
1754 1758 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1755 1759 $ hg help addverboseitems
1756 1760 addverboseitems extension - extension to test omit indicating.
1757 1761
1758 1762 This paragraph is never omitted (for extension)
1759 1763
1760 1764 This paragraph is never omitted, too (for extension)
1761 1765
1762 1766 (some details hidden, use --verbose to show complete help)
1763 1767
1764 1768 no commands defined
1765 1769 $ hg help -v addverboseitems
1766 1770 addverboseitems extension - extension to test omit indicating.
1767 1771
1768 1772 This paragraph is never omitted (for extension)
1769 1773
1770 1774 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1771 1775 extension)
1772 1776
1773 1777 This paragraph is never omitted, too (for extension)
1774 1778
1775 1779 no commands defined
1776 1780 $ hg help topic-containing-verbose
1777 1781 This is the topic to test omit indicating.
1778 1782 """"""""""""""""""""""""""""""""""""""""""
1779 1783
1780 1784 This paragraph is never omitted (for topic).
1781 1785
1782 1786 This paragraph is never omitted, too (for topic)
1783 1787
1784 1788 (some details hidden, use --verbose to show complete help)
1785 1789 $ hg help -v topic-containing-verbose
1786 1790 This is the topic to test omit indicating.
1787 1791 """"""""""""""""""""""""""""""""""""""""""
1788 1792
1789 1793 This paragraph is never omitted (for topic).
1790 1794
1791 1795 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1792 1796 topic)
1793 1797
1794 1798 This paragraph is never omitted, too (for topic)
1795 1799
1796 1800 Test section lookup
1797 1801
1798 1802 $ hg help revset.merge
1799 1803 "merge()"
1800 1804 Changeset is a merge changeset.
1801 1805
1802 1806 $ hg help glossary.dag
1803 1807 DAG
1804 1808 The repository of changesets of a distributed version control system
1805 1809 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1806 1810 of nodes and edges, where nodes correspond to changesets and edges
1807 1811 imply a parent -> child relation. This graph can be visualized by
1808 1812 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1809 1813 limited by the requirement for children to have at most two parents.
1810 1814
1811 1815
1812 1816 $ hg help hgrc.paths
1813 1817 "paths"
1814 1818 -------
1815 1819
1816 1820 Assigns symbolic names and behavior to repositories.
1817 1821
1818 1822 Options are symbolic names defining the URL or directory that is the
1819 1823 location of the repository. Example:
1820 1824
1821 1825 [paths]
1822 1826 my_server = https://example.com/my_repo
1823 1827 local_path = /home/me/repo
1824 1828
1825 1829 These symbolic names can be used from the command line. To pull from
1826 1830 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1827 1831 local_path'.
1828 1832
1829 1833 Options containing colons (":") denote sub-options that can influence
1830 1834 behavior for that specific path. Example:
1831 1835
1832 1836 [paths]
1833 1837 my_server = https://example.com/my_path
1834 1838 my_server:pushurl = ssh://example.com/my_path
1835 1839
1836 1840 The following sub-options can be defined:
1837 1841
1838 1842 "pushurl"
1839 1843 The URL to use for push operations. If not defined, the location
1840 1844 defined by the path's main entry is used.
1841 1845
1842 1846 "pushrev"
1843 1847 A revset defining which revisions to push by default.
1844 1848
1845 1849 When 'hg push' is executed without a "-r" argument, the revset defined
1846 1850 by this sub-option is evaluated to determine what to push.
1847 1851
1848 1852 For example, a value of "." will push the working directory's revision
1849 1853 by default.
1850 1854
1851 1855 Revsets specifying bookmarks will not result in the bookmark being
1852 1856 pushed.
1853 1857
1854 1858 The following special named paths exist:
1855 1859
1856 1860 "default"
1857 1861 The URL or directory to use when no source or remote is specified.
1858 1862
1859 1863 'hg clone' will automatically define this path to the location the
1860 1864 repository was cloned from.
1861 1865
1862 1866 "default-push"
1863 1867 (deprecated) The URL or directory for the default 'hg push' location.
1864 1868 "default:pushurl" should be used instead.
1865 1869
1866 1870 $ hg help glossary.mcguffin
1867 1871 abort: help section not found: glossary.mcguffin
1868 1872 [255]
1869 1873
1870 1874 $ hg help glossary.mc.guffin
1871 1875 abort: help section not found: glossary.mc.guffin
1872 1876 [255]
1873 1877
1874 1878 $ hg help template.files
1875 1879 files List of strings. All files modified, added, or removed by
1876 1880 this changeset.
1877 1881 files(pattern)
1878 1882 All files of the current changeset matching the pattern. See
1879 1883 'hg help patterns'.
1880 1884
1881 1885 Test section lookup by translated message
1882 1886
1883 1887 str.lower() instead of encoding.lower(str) on translated message might
1884 1888 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1885 1889 as the second or later byte of multi-byte character.
1886 1890
1887 1891 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1888 1892 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1889 1893 replacement makes message meaningless.
1890 1894
1891 1895 This tests that section lookup by translated string isn't broken by
1892 1896 such str.lower().
1893 1897
1894 1898 $ "$PYTHON" <<EOF
1895 1899 > def escape(s):
1896 1900 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1897 1901 > # translation of "record" in ja_JP.cp932
1898 1902 > upper = b"\x8bL\x98^"
1899 1903 > # str.lower()-ed section name should be treated as different one
1900 1904 > lower = b"\x8bl\x98^"
1901 1905 > with open('ambiguous.py', 'wb') as fp:
1902 1906 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1903 1907 > u'''summary of extension
1904 1908 >
1905 1909 > %s
1906 1910 > ----
1907 1911 >
1908 1912 > Upper name should show only this message
1909 1913 >
1910 1914 > %s
1911 1915 > ----
1912 1916 >
1913 1917 > Lower name should show only this message
1914 1918 >
1915 1919 > subsequent section
1916 1920 > ------------------
1917 1921 >
1918 1922 > This should be hidden at 'hg help ambiguous' with section name.
1919 1923 > '''
1920 1924 > """ % (escape(upper), escape(lower)))
1921 1925 > EOF
1922 1926
1923 1927 $ cat >> $HGRCPATH <<EOF
1924 1928 > [extensions]
1925 1929 > ambiguous = ./ambiguous.py
1926 1930 > EOF
1927 1931
1928 1932 $ "$PYTHON" <<EOF | sh
1929 1933 > from mercurial.utils import procutil
1930 1934 > upper = b"\x8bL\x98^"
1931 1935 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1932 1936 > EOF
1933 1937 \x8bL\x98^ (esc)
1934 1938 ----
1935 1939
1936 1940 Upper name should show only this message
1937 1941
1938 1942
1939 1943 $ "$PYTHON" <<EOF | sh
1940 1944 > from mercurial.utils import procutil
1941 1945 > lower = b"\x8bl\x98^"
1942 1946 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1943 1947 > EOF
1944 1948 \x8bl\x98^ (esc)
1945 1949 ----
1946 1950
1947 1951 Lower name should show only this message
1948 1952
1949 1953
1950 1954 $ cat >> $HGRCPATH <<EOF
1951 1955 > [extensions]
1952 1956 > ambiguous = !
1953 1957 > EOF
1954 1958
1955 1959 Show help content of disabled extensions
1956 1960
1957 1961 $ cat >> $HGRCPATH <<EOF
1958 1962 > [extensions]
1959 1963 > ambiguous = !./ambiguous.py
1960 1964 > EOF
1961 1965 $ hg help -e ambiguous
1962 1966 ambiguous extension - (no help text available)
1963 1967
1964 1968 (use 'hg help extensions' for information on enabling extensions)
1965 1969
1966 1970 Test dynamic list of merge tools only shows up once
1967 1971 $ hg help merge-tools
1968 1972 Merge Tools
1969 1973 """""""""""
1970 1974
1971 1975 To merge files Mercurial uses merge tools.
1972 1976
1973 1977 A merge tool combines two different versions of a file into a merged file.
1974 1978 Merge tools are given the two files and the greatest common ancestor of
1975 1979 the two file versions, so they can determine the changes made on both
1976 1980 branches.
1977 1981
1978 1982 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1979 1983 backout' and in several extensions.
1980 1984
1981 1985 Usually, the merge tool tries to automatically reconcile the files by
1982 1986 combining all non-overlapping changes that occurred separately in the two
1983 1987 different evolutions of the same initial base file. Furthermore, some
1984 1988 interactive merge programs make it easier to manually resolve conflicting
1985 1989 merges, either in a graphical way, or by inserting some conflict markers.
1986 1990 Mercurial does not include any interactive merge programs but relies on
1987 1991 external tools for that.
1988 1992
1989 1993 Available merge tools
1990 1994 =====================
1991 1995
1992 1996 External merge tools and their properties are configured in the merge-
1993 1997 tools configuration section - see hgrc(5) - but they can often just be
1994 1998 named by their executable.
1995 1999
1996 2000 A merge tool is generally usable if its executable can be found on the
1997 2001 system and if it can handle the merge. The executable is found if it is an
1998 2002 absolute or relative executable path or the name of an application in the
1999 2003 executable search path. The tool is assumed to be able to handle the merge
2000 2004 if it can handle symlinks if the file is a symlink, if it can handle
2001 2005 binary files if the file is binary, and if a GUI is available if the tool
2002 2006 requires a GUI.
2003 2007
2004 2008 There are some internal merge tools which can be used. The internal merge
2005 2009 tools are:
2006 2010
2007 2011 ":dump"
2008 2012 Creates three versions of the files to merge, containing the contents of
2009 2013 local, other and base. These files can then be used to perform a merge
2010 2014 manually. If the file to be merged is named "a.txt", these files will
2011 2015 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2012 2016 they will be placed in the same directory as "a.txt".
2013 2017
2014 2018 This implies premerge. Therefore, files aren't dumped, if premerge runs
2015 2019 successfully. Use :forcedump to forcibly write files out.
2016 2020
2017 2021 (actual capabilities: binary, symlink)
2018 2022
2019 2023 ":fail"
2020 2024 Rather than attempting to merge files that were modified on both
2021 2025 branches, it marks them as unresolved. The resolve command must be used
2022 2026 to resolve these conflicts.
2023 2027
2024 2028 (actual capabilities: binary, symlink)
2025 2029
2026 2030 ":forcedump"
2027 2031 Creates three versions of the files as same as :dump, but omits
2028 2032 premerge.
2029 2033
2030 2034 (actual capabilities: binary, symlink)
2031 2035
2032 2036 ":local"
2033 2037 Uses the local 'p1()' version of files as the merged version.
2034 2038
2035 2039 (actual capabilities: binary, symlink)
2036 2040
2037 2041 ":merge"
2038 2042 Uses the internal non-interactive simple merge algorithm for merging
2039 2043 files. It will fail if there are any conflicts and leave markers in the
2040 2044 partially merged file. Markers will have two sections, one for each side
2041 2045 of merge.
2042 2046
2043 2047 ":merge-local"
2044 2048 Like :merge, but resolve all conflicts non-interactively in favor of the
2045 2049 local 'p1()' changes.
2046 2050
2047 2051 ":merge-other"
2048 2052 Like :merge, but resolve all conflicts non-interactively in favor of the
2049 2053 other 'p2()' changes.
2050 2054
2051 2055 ":merge3"
2052 2056 Uses the internal non-interactive simple merge algorithm for merging
2053 2057 files. It will fail if there are any conflicts and leave markers in the
2054 2058 partially merged file. Marker will have three sections, one from each
2055 2059 side of the merge and one for the base content.
2056 2060
2057 2061 ":other"
2058 2062 Uses the other 'p2()' version of files as the merged version.
2059 2063
2060 2064 (actual capabilities: binary, symlink)
2061 2065
2062 2066 ":prompt"
2063 2067 Asks the user which of the local 'p1()' or the other 'p2()' version to
2064 2068 keep as the merged version.
2065 2069
2066 2070 (actual capabilities: binary, symlink)
2067 2071
2068 2072 ":tagmerge"
2069 2073 Uses the internal tag merge algorithm (experimental).
2070 2074
2071 2075 ":union"
2072 2076 Uses the internal non-interactive simple merge algorithm for merging
2073 2077 files. It will use both left and right sides for conflict regions. No
2074 2078 markers are inserted.
2075 2079
2076 2080 Internal tools are always available and do not require a GUI but will by
2077 2081 default not handle symlinks or binary files. See next section for detail
2078 2082 about "actual capabilities" described above.
2079 2083
2080 2084 Choosing a merge tool
2081 2085 =====================
2082 2086
2083 2087 Mercurial uses these rules when deciding which merge tool to use:
2084 2088
2085 2089 1. If a tool has been specified with the --tool option to merge or
2086 2090 resolve, it is used. If it is the name of a tool in the merge-tools
2087 2091 configuration, its configuration is used. Otherwise the specified tool
2088 2092 must be executable by the shell.
2089 2093 2. If the "HGMERGE" environment variable is present, its value is used and
2090 2094 must be executable by the shell.
2091 2095 3. If the filename of the file to be merged matches any of the patterns in
2092 2096 the merge-patterns configuration section, the first usable merge tool
2093 2097 corresponding to a matching pattern is used.
2094 2098 4. If ui.merge is set it will be considered next. If the value is not the
2095 2099 name of a configured tool, the specified value is used and must be
2096 2100 executable by the shell. Otherwise the named tool is used if it is
2097 2101 usable.
2098 2102 5. If any usable merge tools are present in the merge-tools configuration
2099 2103 section, the one with the highest priority is used.
2100 2104 6. If a program named "hgmerge" can be found on the system, it is used -
2101 2105 but it will by default not be used for symlinks and binary files.
2102 2106 7. If the file to be merged is not binary and is not a symlink, then
2103 2107 internal ":merge" is used.
2104 2108 8. Otherwise, ":prompt" is used.
2105 2109
2106 2110 For historical reason, Mercurial treats merge tools as below while
2107 2111 examining rules above.
2108 2112
2109 2113 step specified via binary symlink
2110 2114 ----------------------------------
2111 2115 1. --tool o/o o/o
2112 2116 2. HGMERGE o/o o/o
2113 2117 3. merge-patterns o/o(*) x/?(*)
2114 2118 4. ui.merge x/?(*) x/?(*)
2115 2119
2116 2120 Each capability column indicates Mercurial behavior for internal/external
2117 2121 merge tools at examining each rule.
2118 2122
2119 2123 - "o": "assume that a tool has capability"
2120 2124 - "x": "assume that a tool does not have capability"
2121 2125 - "?": "check actual capability of a tool"
2122 2126
2123 2127 If "merge.strict-capability-check" configuration is true, Mercurial checks
2124 2128 capabilities of merge tools strictly in (*) cases above (= each capability
2125 2129 column becomes "?/?"). It is false by default for backward compatibility.
2126 2130
2127 2131 Note:
2128 2132 After selecting a merge program, Mercurial will by default attempt to
2129 2133 merge the files using a simple merge algorithm first. Only if it
2130 2134 doesn't succeed because of conflicting changes will Mercurial actually
2131 2135 execute the merge program. Whether to use the simple merge algorithm
2132 2136 first can be controlled by the premerge setting of the merge tool.
2133 2137 Premerge is enabled by default unless the file is binary or a symlink.
2134 2138
2135 2139 See the merge-tools and ui sections of hgrc(5) for details on the
2136 2140 configuration of merge tools.
2137 2141
2138 2142 Compression engines listed in `hg help bundlespec`
2139 2143
2140 2144 $ hg help bundlespec | grep gzip
2141 2145 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2142 2146 An algorithm that produces smaller bundles than "gzip".
2143 2147 This engine will likely produce smaller bundles than "gzip" but will be
2144 2148 "gzip"
2145 2149 better compression than "gzip". It also frequently yields better (?)
2146 2150
2147 2151 Test usage of section marks in help documents
2148 2152
2149 2153 $ cd "$TESTDIR"/../doc
2150 2154 $ "$PYTHON" check-seclevel.py
2151 2155 $ cd $TESTTMP
2152 2156
2153 2157 #if serve
2154 2158
2155 2159 Test the help pages in hgweb.
2156 2160
2157 2161 Dish up an empty repo; serve it cold.
2158 2162
2159 2163 $ hg init "$TESTTMP/test"
2160 2164 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2161 2165 $ cat hg.pid >> $DAEMON_PIDS
2162 2166
2163 2167 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2164 2168 200 Script output follows
2165 2169
2166 2170 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2167 2171 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2168 2172 <head>
2169 2173 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2170 2174 <meta name="robots" content="index, nofollow" />
2171 2175 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2172 2176 <script type="text/javascript" src="/static/mercurial.js"></script>
2173 2177
2174 2178 <title>Help: Index</title>
2175 2179 </head>
2176 2180 <body>
2177 2181
2178 2182 <div class="container">
2179 2183 <div class="menu">
2180 2184 <div class="logo">
2181 2185 <a href="https://mercurial-scm.org/">
2182 2186 <img src="/static/hglogo.png" alt="mercurial" /></a>
2183 2187 </div>
2184 2188 <ul>
2185 2189 <li><a href="/shortlog">log</a></li>
2186 2190 <li><a href="/graph">graph</a></li>
2187 2191 <li><a href="/tags">tags</a></li>
2188 2192 <li><a href="/bookmarks">bookmarks</a></li>
2189 2193 <li><a href="/branches">branches</a></li>
2190 2194 </ul>
2191 2195 <ul>
2192 2196 <li class="active">help</li>
2193 2197 </ul>
2194 2198 </div>
2195 2199
2196 2200 <div class="main">
2197 2201 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2198 2202
2199 2203 <form class="search" action="/log">
2200 2204
2201 2205 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2202 2206 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2203 2207 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2204 2208 </form>
2205 2209 <table class="bigtable">
2206 2210 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2207 2211
2208 2212 <tr><td>
2209 2213 <a href="/help/bundlespec">
2210 2214 bundlespec
2211 2215 </a>
2212 2216 </td><td>
2213 2217 Bundle File Formats
2214 2218 </td></tr>
2215 2219 <tr><td>
2216 2220 <a href="/help/color">
2217 2221 color
2218 2222 </a>
2219 2223 </td><td>
2220 2224 Colorizing Outputs
2221 2225 </td></tr>
2222 2226 <tr><td>
2223 2227 <a href="/help/config">
2224 2228 config
2225 2229 </a>
2226 2230 </td><td>
2227 2231 Configuration Files
2228 2232 </td></tr>
2229 2233 <tr><td>
2230 2234 <a href="/help/dates">
2231 2235 dates
2232 2236 </a>
2233 2237 </td><td>
2234 2238 Date Formats
2235 2239 </td></tr>
2236 2240 <tr><td>
2237 2241 <a href="/help/deprecated">
2238 2242 deprecated
2239 2243 </a>
2240 2244 </td><td>
2241 2245 Deprecated Features
2242 2246 </td></tr>
2243 2247 <tr><td>
2244 2248 <a href="/help/diffs">
2245 2249 diffs
2246 2250 </a>
2247 2251 </td><td>
2248 2252 Diff Formats
2249 2253 </td></tr>
2250 2254 <tr><td>
2251 2255 <a href="/help/environment">
2252 2256 environment
2253 2257 </a>
2254 2258 </td><td>
2255 2259 Environment Variables
2256 2260 </td></tr>
2257 2261 <tr><td>
2258 2262 <a href="/help/extensions">
2259 2263 extensions
2260 2264 </a>
2261 2265 </td><td>
2262 2266 Using Additional Features
2263 2267 </td></tr>
2264 2268 <tr><td>
2265 2269 <a href="/help/filesets">
2266 2270 filesets
2267 2271 </a>
2268 2272 </td><td>
2269 2273 Specifying File Sets
2270 2274 </td></tr>
2271 2275 <tr><td>
2272 2276 <a href="/help/flags">
2273 2277 flags
2274 2278 </a>
2275 2279 </td><td>
2276 2280 Command-line flags
2277 2281 </td></tr>
2278 2282 <tr><td>
2279 2283 <a href="/help/glossary">
2280 2284 glossary
2281 2285 </a>
2282 2286 </td><td>
2283 2287 Glossary
2284 2288 </td></tr>
2285 2289 <tr><td>
2286 2290 <a href="/help/hgignore">
2287 2291 hgignore
2288 2292 </a>
2289 2293 </td><td>
2290 2294 Syntax for Mercurial Ignore Files
2291 2295 </td></tr>
2292 2296 <tr><td>
2293 2297 <a href="/help/hgweb">
2294 2298 hgweb
2295 2299 </a>
2296 2300 </td><td>
2297 2301 Configuring hgweb
2298 2302 </td></tr>
2299 2303 <tr><td>
2300 2304 <a href="/help/internals">
2301 2305 internals
2302 2306 </a>
2303 2307 </td><td>
2304 2308 Technical implementation topics
2305 2309 </td></tr>
2306 2310 <tr><td>
2307 2311 <a href="/help/merge-tools">
2308 2312 merge-tools
2309 2313 </a>
2310 2314 </td><td>
2311 2315 Merge Tools
2312 2316 </td></tr>
2313 2317 <tr><td>
2314 2318 <a href="/help/pager">
2315 2319 pager
2316 2320 </a>
2317 2321 </td><td>
2318 2322 Pager Support
2319 2323 </td></tr>
2320 2324 <tr><td>
2321 2325 <a href="/help/patterns">
2322 2326 patterns
2323 2327 </a>
2324 2328 </td><td>
2325 2329 File Name Patterns
2326 2330 </td></tr>
2327 2331 <tr><td>
2328 2332 <a href="/help/phases">
2329 2333 phases
2330 2334 </a>
2331 2335 </td><td>
2332 2336 Working with Phases
2333 2337 </td></tr>
2334 2338 <tr><td>
2335 2339 <a href="/help/revisions">
2336 2340 revisions
2337 2341 </a>
2338 2342 </td><td>
2339 2343 Specifying Revisions
2340 2344 </td></tr>
2341 2345 <tr><td>
2342 2346 <a href="/help/scripting">
2343 2347 scripting
2344 2348 </a>
2345 2349 </td><td>
2346 2350 Using Mercurial from scripts and automation
2347 2351 </td></tr>
2348 2352 <tr><td>
2349 2353 <a href="/help/subrepos">
2350 2354 subrepos
2351 2355 </a>
2352 2356 </td><td>
2353 2357 Subrepositories
2354 2358 </td></tr>
2355 2359 <tr><td>
2356 2360 <a href="/help/templating">
2357 2361 templating
2358 2362 </a>
2359 2363 </td><td>
2360 2364 Template Usage
2361 2365 </td></tr>
2362 2366 <tr><td>
2363 2367 <a href="/help/urls">
2364 2368 urls
2365 2369 </a>
2366 2370 </td><td>
2367 2371 URL Paths
2368 2372 </td></tr>
2369 2373 <tr><td>
2370 2374 <a href="/help/topic-containing-verbose">
2371 2375 topic-containing-verbose
2372 2376 </a>
2373 2377 </td><td>
2374 2378 This is the topic to test omit indicating.
2375 2379 </td></tr>
2376 2380
2377 2381
2378 2382 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2379 2383
2380 2384 <tr><td>
2381 2385 <a href="/help/abort">
2382 2386 abort
2383 2387 </a>
2384 2388 </td><td>
2385 2389 abort an unfinished operation (EXPERIMENTAL)
2386 2390 </td></tr>
2387 2391 <tr><td>
2388 2392 <a href="/help/add">
2389 2393 add
2390 2394 </a>
2391 2395 </td><td>
2392 2396 add the specified files on the next commit
2393 2397 </td></tr>
2394 2398 <tr><td>
2395 2399 <a href="/help/annotate">
2396 2400 annotate
2397 2401 </a>
2398 2402 </td><td>
2399 2403 show changeset information by line for each file
2400 2404 </td></tr>
2401 2405 <tr><td>
2402 2406 <a href="/help/clone">
2403 2407 clone
2404 2408 </a>
2405 2409 </td><td>
2406 2410 make a copy of an existing repository
2407 2411 </td></tr>
2408 2412 <tr><td>
2409 2413 <a href="/help/commit">
2410 2414 commit
2411 2415 </a>
2412 2416 </td><td>
2413 2417 commit the specified files or all outstanding changes
2414 2418 </td></tr>
2415 2419 <tr><td>
2416 2420 <a href="/help/continue">
2417 2421 continue
2418 2422 </a>
2419 2423 </td><td>
2420 2424 resumes an interrupted operation (EXPERIMENTAL)
2421 2425 </td></tr>
2422 2426 <tr><td>
2423 2427 <a href="/help/diff">
2424 2428 diff
2425 2429 </a>
2426 2430 </td><td>
2427 2431 diff repository (or selected files)
2428 2432 </td></tr>
2429 2433 <tr><td>
2430 2434 <a href="/help/export">
2431 2435 export
2432 2436 </a>
2433 2437 </td><td>
2434 2438 dump the header and diffs for one or more changesets
2435 2439 </td></tr>
2436 2440 <tr><td>
2437 2441 <a href="/help/forget">
2438 2442 forget
2439 2443 </a>
2440 2444 </td><td>
2441 2445 forget the specified files on the next commit
2442 2446 </td></tr>
2443 2447 <tr><td>
2444 2448 <a href="/help/init">
2445 2449 init
2446 2450 </a>
2447 2451 </td><td>
2448 2452 create a new repository in the given directory
2449 2453 </td></tr>
2450 2454 <tr><td>
2451 2455 <a href="/help/log">
2452 2456 log
2453 2457 </a>
2454 2458 </td><td>
2455 2459 show revision history of entire repository or files
2456 2460 </td></tr>
2457 2461 <tr><td>
2458 2462 <a href="/help/merge">
2459 2463 merge
2460 2464 </a>
2461 2465 </td><td>
2462 2466 merge another revision into working directory
2463 2467 </td></tr>
2464 2468 <tr><td>
2465 2469 <a href="/help/pull">
2466 2470 pull
2467 2471 </a>
2468 2472 </td><td>
2469 2473 pull changes from the specified source
2470 2474 </td></tr>
2471 2475 <tr><td>
2472 2476 <a href="/help/push">
2473 2477 push
2474 2478 </a>
2475 2479 </td><td>
2476 2480 push changes to the specified destination
2477 2481 </td></tr>
2478 2482 <tr><td>
2479 2483 <a href="/help/remove">
2480 2484 remove
2481 2485 </a>
2482 2486 </td><td>
2483 2487 remove the specified files on the next commit
2484 2488 </td></tr>
2485 2489 <tr><td>
2486 2490 <a href="/help/serve">
2487 2491 serve
2488 2492 </a>
2489 2493 </td><td>
2490 2494 start stand-alone webserver
2491 2495 </td></tr>
2492 2496 <tr><td>
2493 2497 <a href="/help/status">
2494 2498 status
2495 2499 </a>
2496 2500 </td><td>
2497 2501 show changed files in the working directory
2498 2502 </td></tr>
2499 2503 <tr><td>
2500 2504 <a href="/help/summary">
2501 2505 summary
2502 2506 </a>
2503 2507 </td><td>
2504 2508 summarize working directory state
2505 2509 </td></tr>
2506 2510 <tr><td>
2507 2511 <a href="/help/update">
2508 2512 update
2509 2513 </a>
2510 2514 </td><td>
2511 2515 update working directory (or switch revisions)
2512 2516 </td></tr>
2513 2517
2514 2518
2515 2519
2516 2520 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2517 2521
2518 2522 <tr><td>
2519 2523 <a href="/help/addremove">
2520 2524 addremove
2521 2525 </a>
2522 2526 </td><td>
2523 2527 add all new files, delete all missing files
2524 2528 </td></tr>
2525 2529 <tr><td>
2526 2530 <a href="/help/archive">
2527 2531 archive
2528 2532 </a>
2529 2533 </td><td>
2530 2534 create an unversioned archive of a repository revision
2531 2535 </td></tr>
2532 2536 <tr><td>
2533 2537 <a href="/help/backout">
2534 2538 backout
2535 2539 </a>
2536 2540 </td><td>
2537 2541 reverse effect of earlier changeset
2538 2542 </td></tr>
2539 2543 <tr><td>
2540 2544 <a href="/help/bisect">
2541 2545 bisect
2542 2546 </a>
2543 2547 </td><td>
2544 2548 subdivision search of changesets
2545 2549 </td></tr>
2546 2550 <tr><td>
2547 2551 <a href="/help/bookmarks">
2548 2552 bookmarks
2549 2553 </a>
2550 2554 </td><td>
2551 2555 create a new bookmark or list existing bookmarks
2552 2556 </td></tr>
2553 2557 <tr><td>
2554 2558 <a href="/help/branch">
2555 2559 branch
2556 2560 </a>
2557 2561 </td><td>
2558 2562 set or show the current branch name
2559 2563 </td></tr>
2560 2564 <tr><td>
2561 2565 <a href="/help/branches">
2562 2566 branches
2563 2567 </a>
2564 2568 </td><td>
2565 2569 list repository named branches
2566 2570 </td></tr>
2567 2571 <tr><td>
2568 2572 <a href="/help/bundle">
2569 2573 bundle
2570 2574 </a>
2571 2575 </td><td>
2572 2576 create a bundle file
2573 2577 </td></tr>
2574 2578 <tr><td>
2575 2579 <a href="/help/cat">
2576 2580 cat
2577 2581 </a>
2578 2582 </td><td>
2579 2583 output the current or given revision of files
2580 2584 </td></tr>
2581 2585 <tr><td>
2582 2586 <a href="/help/config">
2583 2587 config
2584 2588 </a>
2585 2589 </td><td>
2586 2590 show combined config settings from all hgrc files
2587 2591 </td></tr>
2588 2592 <tr><td>
2589 2593 <a href="/help/copy">
2590 2594 copy
2591 2595 </a>
2592 2596 </td><td>
2593 2597 mark files as copied for the next commit
2594 2598 </td></tr>
2595 2599 <tr><td>
2596 2600 <a href="/help/files">
2597 2601 files
2598 2602 </a>
2599 2603 </td><td>
2600 2604 list tracked files
2601 2605 </td></tr>
2602 2606 <tr><td>
2603 2607 <a href="/help/graft">
2604 2608 graft
2605 2609 </a>
2606 2610 </td><td>
2607 2611 copy changes from other branches onto the current branch
2608 2612 </td></tr>
2609 2613 <tr><td>
2610 2614 <a href="/help/grep">
2611 2615 grep
2612 2616 </a>
2613 2617 </td><td>
2614 2618 search for a pattern in specified files
2615 2619 </td></tr>
2616 2620 <tr><td>
2617 2621 <a href="/help/hashelp">
2618 2622 hashelp
2619 2623 </a>
2620 2624 </td><td>
2621 2625 Extension command's help
2622 2626 </td></tr>
2623 2627 <tr><td>
2624 2628 <a href="/help/heads">
2625 2629 heads
2626 2630 </a>
2627 2631 </td><td>
2628 2632 show branch heads
2629 2633 </td></tr>
2630 2634 <tr><td>
2631 2635 <a href="/help/help">
2632 2636 help
2633 2637 </a>
2634 2638 </td><td>
2635 2639 show help for a given topic or a help overview
2636 2640 </td></tr>
2637 2641 <tr><td>
2638 2642 <a href="/help/hgalias">
2639 2643 hgalias
2640 2644 </a>
2641 2645 </td><td>
2642 2646 My doc
2643 2647 </td></tr>
2644 2648 <tr><td>
2645 2649 <a href="/help/hgaliasnodoc">
2646 2650 hgaliasnodoc
2647 2651 </a>
2648 2652 </td><td>
2649 2653 summarize working directory state
2650 2654 </td></tr>
2651 2655 <tr><td>
2652 2656 <a href="/help/identify">
2653 2657 identify
2654 2658 </a>
2655 2659 </td><td>
2656 2660 identify the working directory or specified revision
2657 2661 </td></tr>
2658 2662 <tr><td>
2659 2663 <a href="/help/import">
2660 2664 import
2661 2665 </a>
2662 2666 </td><td>
2663 2667 import an ordered set of patches
2664 2668 </td></tr>
2665 2669 <tr><td>
2666 2670 <a href="/help/incoming">
2667 2671 incoming
2668 2672 </a>
2669 2673 </td><td>
2670 2674 show new changesets found in source
2671 2675 </td></tr>
2672 2676 <tr><td>
2673 2677 <a href="/help/manifest">
2674 2678 manifest
2675 2679 </a>
2676 2680 </td><td>
2677 2681 output the current or given revision of the project manifest
2678 2682 </td></tr>
2679 2683 <tr><td>
2680 2684 <a href="/help/nohelp">
2681 2685 nohelp
2682 2686 </a>
2683 2687 </td><td>
2684 2688 (no help text available)
2685 2689 </td></tr>
2686 2690 <tr><td>
2687 2691 <a href="/help/outgoing">
2688 2692 outgoing
2689 2693 </a>
2690 2694 </td><td>
2691 2695 show changesets not found in the destination
2692 2696 </td></tr>
2693 2697 <tr><td>
2694 2698 <a href="/help/paths">
2695 2699 paths
2696 2700 </a>
2697 2701 </td><td>
2698 2702 show aliases for remote repositories
2699 2703 </td></tr>
2700 2704 <tr><td>
2701 2705 <a href="/help/phase">
2702 2706 phase
2703 2707 </a>
2704 2708 </td><td>
2705 2709 set or show the current phase name
2706 2710 </td></tr>
2707 2711 <tr><td>
2708 2712 <a href="/help/recover">
2709 2713 recover
2710 2714 </a>
2711 2715 </td><td>
2712 2716 roll back an interrupted transaction
2713 2717 </td></tr>
2714 2718 <tr><td>
2715 2719 <a href="/help/rename">
2716 2720 rename
2717 2721 </a>
2718 2722 </td><td>
2719 2723 rename files; equivalent of copy + remove
2720 2724 </td></tr>
2721 2725 <tr><td>
2722 2726 <a href="/help/resolve">
2723 2727 resolve
2724 2728 </a>
2725 2729 </td><td>
2726 2730 redo merges or set/view the merge status of files
2727 2731 </td></tr>
2728 2732 <tr><td>
2729 2733 <a href="/help/revert">
2730 2734 revert
2731 2735 </a>
2732 2736 </td><td>
2733 2737 restore files to their checkout state
2734 2738 </td></tr>
2735 2739 <tr><td>
2736 2740 <a href="/help/root">
2737 2741 root
2738 2742 </a>
2739 2743 </td><td>
2740 2744 print the root (top) of the current working directory
2741 2745 </td></tr>
2742 2746 <tr><td>
2743 2747 <a href="/help/shellalias">
2744 2748 shellalias
2745 2749 </a>
2746 2750 </td><td>
2747 2751 (no help text available)
2748 2752 </td></tr>
2749 2753 <tr><td>
2750 2754 <a href="/help/shelve">
2751 2755 shelve
2752 2756 </a>
2753 2757 </td><td>
2754 2758 save and set aside changes from the working directory
2755 2759 </td></tr>
2756 2760 <tr><td>
2757 2761 <a href="/help/tag">
2758 2762 tag
2759 2763 </a>
2760 2764 </td><td>
2761 2765 add one or more tags for the current or given revision
2762 2766 </td></tr>
2763 2767 <tr><td>
2764 2768 <a href="/help/tags">
2765 2769 tags
2766 2770 </a>
2767 2771 </td><td>
2768 2772 list repository tags
2769 2773 </td></tr>
2770 2774 <tr><td>
2771 2775 <a href="/help/unbundle">
2772 2776 unbundle
2773 2777 </a>
2774 2778 </td><td>
2775 2779 apply one or more bundle files
2776 2780 </td></tr>
2777 2781 <tr><td>
2778 2782 <a href="/help/unshelve">
2779 2783 unshelve
2780 2784 </a>
2781 2785 </td><td>
2782 2786 restore a shelved change to the working directory
2783 2787 </td></tr>
2784 2788 <tr><td>
2785 2789 <a href="/help/verify">
2786 2790 verify
2787 2791 </a>
2788 2792 </td><td>
2789 2793 verify the integrity of the repository
2790 2794 </td></tr>
2791 2795 <tr><td>
2792 2796 <a href="/help/version">
2793 2797 version
2794 2798 </a>
2795 2799 </td><td>
2796 2800 output version and copyright information
2797 2801 </td></tr>
2798 2802
2799 2803
2800 2804 </table>
2801 2805 </div>
2802 2806 </div>
2803 2807
2804 2808
2805 2809
2806 2810 </body>
2807 2811 </html>
2808 2812
2809 2813
2810 2814 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2811 2815 200 Script output follows
2812 2816
2813 2817 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2814 2818 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2815 2819 <head>
2816 2820 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2817 2821 <meta name="robots" content="index, nofollow" />
2818 2822 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2819 2823 <script type="text/javascript" src="/static/mercurial.js"></script>
2820 2824
2821 2825 <title>Help: add</title>
2822 2826 </head>
2823 2827 <body>
2824 2828
2825 2829 <div class="container">
2826 2830 <div class="menu">
2827 2831 <div class="logo">
2828 2832 <a href="https://mercurial-scm.org/">
2829 2833 <img src="/static/hglogo.png" alt="mercurial" /></a>
2830 2834 </div>
2831 2835 <ul>
2832 2836 <li><a href="/shortlog">log</a></li>
2833 2837 <li><a href="/graph">graph</a></li>
2834 2838 <li><a href="/tags">tags</a></li>
2835 2839 <li><a href="/bookmarks">bookmarks</a></li>
2836 2840 <li><a href="/branches">branches</a></li>
2837 2841 </ul>
2838 2842 <ul>
2839 2843 <li class="active"><a href="/help">help</a></li>
2840 2844 </ul>
2841 2845 </div>
2842 2846
2843 2847 <div class="main">
2844 2848 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2845 2849 <h3>Help: add</h3>
2846 2850
2847 2851 <form class="search" action="/log">
2848 2852
2849 2853 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2850 2854 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2851 2855 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2852 2856 </form>
2853 2857 <div id="doc">
2854 2858 <p>
2855 2859 hg add [OPTION]... [FILE]...
2856 2860 </p>
2857 2861 <p>
2858 2862 add the specified files on the next commit
2859 2863 </p>
2860 2864 <p>
2861 2865 Schedule files to be version controlled and added to the
2862 2866 repository.
2863 2867 </p>
2864 2868 <p>
2865 2869 The files will be added to the repository at the next commit. To
2866 2870 undo an add before that, see 'hg forget'.
2867 2871 </p>
2868 2872 <p>
2869 2873 If no names are given, add all files to the repository (except
2870 2874 files matching &quot;.hgignore&quot;).
2871 2875 </p>
2872 2876 <p>
2873 2877 Examples:
2874 2878 </p>
2875 2879 <ul>
2876 2880 <li> New (unknown) files are added automatically by 'hg add':
2877 2881 <pre>
2878 2882 \$ ls (re)
2879 2883 foo.c
2880 2884 \$ hg status (re)
2881 2885 ? foo.c
2882 2886 \$ hg add (re)
2883 2887 adding foo.c
2884 2888 \$ hg status (re)
2885 2889 A foo.c
2886 2890 </pre>
2887 2891 <li> Specific files to be added can be specified:
2888 2892 <pre>
2889 2893 \$ ls (re)
2890 2894 bar.c foo.c
2891 2895 \$ hg status (re)
2892 2896 ? bar.c
2893 2897 ? foo.c
2894 2898 \$ hg add bar.c (re)
2895 2899 \$ hg status (re)
2896 2900 A bar.c
2897 2901 ? foo.c
2898 2902 </pre>
2899 2903 </ul>
2900 2904 <p>
2901 2905 Returns 0 if all files are successfully added.
2902 2906 </p>
2903 2907 <p>
2904 2908 options ([+] can be repeated):
2905 2909 </p>
2906 2910 <table>
2907 2911 <tr><td>-I</td>
2908 2912 <td>--include PATTERN [+]</td>
2909 2913 <td>include names matching the given patterns</td></tr>
2910 2914 <tr><td>-X</td>
2911 2915 <td>--exclude PATTERN [+]</td>
2912 2916 <td>exclude names matching the given patterns</td></tr>
2913 2917 <tr><td>-S</td>
2914 2918 <td>--subrepos</td>
2915 2919 <td>recurse into subrepositories</td></tr>
2916 2920 <tr><td>-n</td>
2917 2921 <td>--dry-run</td>
2918 2922 <td>do not perform actions, just print output</td></tr>
2919 2923 </table>
2920 2924 <p>
2921 2925 global options ([+] can be repeated):
2922 2926 </p>
2923 2927 <table>
2924 2928 <tr><td>-R</td>
2925 2929 <td>--repository REPO</td>
2926 2930 <td>repository root directory or name of overlay bundle file</td></tr>
2927 2931 <tr><td></td>
2928 2932 <td>--cwd DIR</td>
2929 2933 <td>change working directory</td></tr>
2930 2934 <tr><td>-y</td>
2931 2935 <td>--noninteractive</td>
2932 2936 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2933 2937 <tr><td>-q</td>
2934 2938 <td>--quiet</td>
2935 2939 <td>suppress output</td></tr>
2936 2940 <tr><td>-v</td>
2937 2941 <td>--verbose</td>
2938 2942 <td>enable additional output</td></tr>
2939 2943 <tr><td></td>
2940 2944 <td>--color TYPE</td>
2941 2945 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2942 2946 <tr><td></td>
2943 2947 <td>--config CONFIG [+]</td>
2944 2948 <td>set/override config option (use 'section.name=value')</td></tr>
2945 2949 <tr><td></td>
2946 2950 <td>--debug</td>
2947 2951 <td>enable debugging output</td></tr>
2948 2952 <tr><td></td>
2949 2953 <td>--debugger</td>
2950 2954 <td>start debugger</td></tr>
2951 2955 <tr><td></td>
2952 2956 <td>--encoding ENCODE</td>
2953 2957 <td>set the charset encoding (default: ascii)</td></tr>
2954 2958 <tr><td></td>
2955 2959 <td>--encodingmode MODE</td>
2956 2960 <td>set the charset encoding mode (default: strict)</td></tr>
2957 2961 <tr><td></td>
2958 2962 <td>--traceback</td>
2959 2963 <td>always print a traceback on exception</td></tr>
2960 2964 <tr><td></td>
2961 2965 <td>--time</td>
2962 2966 <td>time how long the command takes</td></tr>
2963 2967 <tr><td></td>
2964 2968 <td>--profile</td>
2965 2969 <td>print command execution profile</td></tr>
2966 2970 <tr><td></td>
2967 2971 <td>--version</td>
2968 2972 <td>output version information and exit</td></tr>
2969 2973 <tr><td>-h</td>
2970 2974 <td>--help</td>
2971 2975 <td>display help and exit</td></tr>
2972 2976 <tr><td></td>
2973 2977 <td>--hidden</td>
2974 2978 <td>consider hidden changesets</td></tr>
2975 2979 <tr><td></td>
2976 2980 <td>--pager TYPE</td>
2977 2981 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2978 2982 </table>
2979 2983
2980 2984 </div>
2981 2985 </div>
2982 2986 </div>
2983 2987
2984 2988
2985 2989
2986 2990 </body>
2987 2991 </html>
2988 2992
2989 2993
2990 2994 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2991 2995 200 Script output follows
2992 2996
2993 2997 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2994 2998 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2995 2999 <head>
2996 3000 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2997 3001 <meta name="robots" content="index, nofollow" />
2998 3002 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2999 3003 <script type="text/javascript" src="/static/mercurial.js"></script>
3000 3004
3001 3005 <title>Help: remove</title>
3002 3006 </head>
3003 3007 <body>
3004 3008
3005 3009 <div class="container">
3006 3010 <div class="menu">
3007 3011 <div class="logo">
3008 3012 <a href="https://mercurial-scm.org/">
3009 3013 <img src="/static/hglogo.png" alt="mercurial" /></a>
3010 3014 </div>
3011 3015 <ul>
3012 3016 <li><a href="/shortlog">log</a></li>
3013 3017 <li><a href="/graph">graph</a></li>
3014 3018 <li><a href="/tags">tags</a></li>
3015 3019 <li><a href="/bookmarks">bookmarks</a></li>
3016 3020 <li><a href="/branches">branches</a></li>
3017 3021 </ul>
3018 3022 <ul>
3019 3023 <li class="active"><a href="/help">help</a></li>
3020 3024 </ul>
3021 3025 </div>
3022 3026
3023 3027 <div class="main">
3024 3028 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3025 3029 <h3>Help: remove</h3>
3026 3030
3027 3031 <form class="search" action="/log">
3028 3032
3029 3033 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3030 3034 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3031 3035 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3032 3036 </form>
3033 3037 <div id="doc">
3034 3038 <p>
3035 3039 hg remove [OPTION]... FILE...
3036 3040 </p>
3037 3041 <p>
3038 3042 aliases: rm
3039 3043 </p>
3040 3044 <p>
3041 3045 remove the specified files on the next commit
3042 3046 </p>
3043 3047 <p>
3044 3048 Schedule the indicated files for removal from the current branch.
3045 3049 </p>
3046 3050 <p>
3047 3051 This command schedules the files to be removed at the next commit.
3048 3052 To undo a remove before that, see 'hg revert'. To undo added
3049 3053 files, see 'hg forget'.
3050 3054 </p>
3051 3055 <p>
3052 3056 -A/--after can be used to remove only files that have already
3053 3057 been deleted, -f/--force can be used to force deletion, and -Af
3054 3058 can be used to remove files from the next revision without
3055 3059 deleting them from the working directory.
3056 3060 </p>
3057 3061 <p>
3058 3062 The following table details the behavior of remove for different
3059 3063 file states (columns) and option combinations (rows). The file
3060 3064 states are Added [A], Clean [C], Modified [M] and Missing [!]
3061 3065 (as reported by 'hg status'). The actions are Warn, Remove
3062 3066 (from branch) and Delete (from disk):
3063 3067 </p>
3064 3068 <table>
3065 3069 <tr><td>opt/state</td>
3066 3070 <td>A</td>
3067 3071 <td>C</td>
3068 3072 <td>M</td>
3069 3073 <td>!</td></tr>
3070 3074 <tr><td>none</td>
3071 3075 <td>W</td>
3072 3076 <td>RD</td>
3073 3077 <td>W</td>
3074 3078 <td>R</td></tr>
3075 3079 <tr><td>-f</td>
3076 3080 <td>R</td>
3077 3081 <td>RD</td>
3078 3082 <td>RD</td>
3079 3083 <td>R</td></tr>
3080 3084 <tr><td>-A</td>
3081 3085 <td>W</td>
3082 3086 <td>W</td>
3083 3087 <td>W</td>
3084 3088 <td>R</td></tr>
3085 3089 <tr><td>-Af</td>
3086 3090 <td>R</td>
3087 3091 <td>R</td>
3088 3092 <td>R</td>
3089 3093 <td>R</td></tr>
3090 3094 </table>
3091 3095 <p>
3092 3096 <b>Note:</b>
3093 3097 </p>
3094 3098 <p>
3095 3099 'hg remove' never deletes files in Added [A] state from the
3096 3100 working directory, not even if &quot;--force&quot; is specified.
3097 3101 </p>
3098 3102 <p>
3099 3103 Returns 0 on success, 1 if any warnings encountered.
3100 3104 </p>
3101 3105 <p>
3102 3106 options ([+] can be repeated):
3103 3107 </p>
3104 3108 <table>
3105 3109 <tr><td>-A</td>
3106 3110 <td>--after</td>
3107 3111 <td>record delete for missing files</td></tr>
3108 3112 <tr><td>-f</td>
3109 3113 <td>--force</td>
3110 3114 <td>forget added files, delete modified files</td></tr>
3111 3115 <tr><td>-S</td>
3112 3116 <td>--subrepos</td>
3113 3117 <td>recurse into subrepositories</td></tr>
3114 3118 <tr><td>-I</td>
3115 3119 <td>--include PATTERN [+]</td>
3116 3120 <td>include names matching the given patterns</td></tr>
3117 3121 <tr><td>-X</td>
3118 3122 <td>--exclude PATTERN [+]</td>
3119 3123 <td>exclude names matching the given patterns</td></tr>
3120 3124 <tr><td>-n</td>
3121 3125 <td>--dry-run</td>
3122 3126 <td>do not perform actions, just print output</td></tr>
3123 3127 </table>
3124 3128 <p>
3125 3129 global options ([+] can be repeated):
3126 3130 </p>
3127 3131 <table>
3128 3132 <tr><td>-R</td>
3129 3133 <td>--repository REPO</td>
3130 3134 <td>repository root directory or name of overlay bundle file</td></tr>
3131 3135 <tr><td></td>
3132 3136 <td>--cwd DIR</td>
3133 3137 <td>change working directory</td></tr>
3134 3138 <tr><td>-y</td>
3135 3139 <td>--noninteractive</td>
3136 3140 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3137 3141 <tr><td>-q</td>
3138 3142 <td>--quiet</td>
3139 3143 <td>suppress output</td></tr>
3140 3144 <tr><td>-v</td>
3141 3145 <td>--verbose</td>
3142 3146 <td>enable additional output</td></tr>
3143 3147 <tr><td></td>
3144 3148 <td>--color TYPE</td>
3145 3149 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3146 3150 <tr><td></td>
3147 3151 <td>--config CONFIG [+]</td>
3148 3152 <td>set/override config option (use 'section.name=value')</td></tr>
3149 3153 <tr><td></td>
3150 3154 <td>--debug</td>
3151 3155 <td>enable debugging output</td></tr>
3152 3156 <tr><td></td>
3153 3157 <td>--debugger</td>
3154 3158 <td>start debugger</td></tr>
3155 3159 <tr><td></td>
3156 3160 <td>--encoding ENCODE</td>
3157 3161 <td>set the charset encoding (default: ascii)</td></tr>
3158 3162 <tr><td></td>
3159 3163 <td>--encodingmode MODE</td>
3160 3164 <td>set the charset encoding mode (default: strict)</td></tr>
3161 3165 <tr><td></td>
3162 3166 <td>--traceback</td>
3163 3167 <td>always print a traceback on exception</td></tr>
3164 3168 <tr><td></td>
3165 3169 <td>--time</td>
3166 3170 <td>time how long the command takes</td></tr>
3167 3171 <tr><td></td>
3168 3172 <td>--profile</td>
3169 3173 <td>print command execution profile</td></tr>
3170 3174 <tr><td></td>
3171 3175 <td>--version</td>
3172 3176 <td>output version information and exit</td></tr>
3173 3177 <tr><td>-h</td>
3174 3178 <td>--help</td>
3175 3179 <td>display help and exit</td></tr>
3176 3180 <tr><td></td>
3177 3181 <td>--hidden</td>
3178 3182 <td>consider hidden changesets</td></tr>
3179 3183 <tr><td></td>
3180 3184 <td>--pager TYPE</td>
3181 3185 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3182 3186 </table>
3183 3187
3184 3188 </div>
3185 3189 </div>
3186 3190 </div>
3187 3191
3188 3192
3189 3193
3190 3194 </body>
3191 3195 </html>
3192 3196
3193 3197
3194 3198 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3195 3199 200 Script output follows
3196 3200
3197 3201 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3198 3202 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3199 3203 <head>
3200 3204 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3201 3205 <meta name="robots" content="index, nofollow" />
3202 3206 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3203 3207 <script type="text/javascript" src="/static/mercurial.js"></script>
3204 3208
3205 3209 <title>Help: dates</title>
3206 3210 </head>
3207 3211 <body>
3208 3212
3209 3213 <div class="container">
3210 3214 <div class="menu">
3211 3215 <div class="logo">
3212 3216 <a href="https://mercurial-scm.org/">
3213 3217 <img src="/static/hglogo.png" alt="mercurial" /></a>
3214 3218 </div>
3215 3219 <ul>
3216 3220 <li><a href="/shortlog">log</a></li>
3217 3221 <li><a href="/graph">graph</a></li>
3218 3222 <li><a href="/tags">tags</a></li>
3219 3223 <li><a href="/bookmarks">bookmarks</a></li>
3220 3224 <li><a href="/branches">branches</a></li>
3221 3225 </ul>
3222 3226 <ul>
3223 3227 <li class="active"><a href="/help">help</a></li>
3224 3228 </ul>
3225 3229 </div>
3226 3230
3227 3231 <div class="main">
3228 3232 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3229 3233 <h3>Help: dates</h3>
3230 3234
3231 3235 <form class="search" action="/log">
3232 3236
3233 3237 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3234 3238 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3235 3239 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3236 3240 </form>
3237 3241 <div id="doc">
3238 3242 <h1>Date Formats</h1>
3239 3243 <p>
3240 3244 Some commands allow the user to specify a date, e.g.:
3241 3245 </p>
3242 3246 <ul>
3243 3247 <li> backout, commit, import, tag: Specify the commit date.
3244 3248 <li> log, revert, update: Select revision(s) by date.
3245 3249 </ul>
3246 3250 <p>
3247 3251 Many date formats are valid. Here are some examples:
3248 3252 </p>
3249 3253 <ul>
3250 3254 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3251 3255 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3252 3256 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3253 3257 <li> &quot;Dec 6&quot; (midnight)
3254 3258 <li> &quot;13:18&quot; (today assumed)
3255 3259 <li> &quot;3:39&quot; (3:39AM assumed)
3256 3260 <li> &quot;3:39pm&quot; (15:39)
3257 3261 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3258 3262 <li> &quot;2006-12-6 13:18&quot;
3259 3263 <li> &quot;2006-12-6&quot;
3260 3264 <li> &quot;12-6&quot;
3261 3265 <li> &quot;12/6&quot;
3262 3266 <li> &quot;12/6/6&quot; (Dec 6 2006)
3263 3267 <li> &quot;today&quot; (midnight)
3264 3268 <li> &quot;yesterday&quot; (midnight)
3265 3269 <li> &quot;now&quot; - right now
3266 3270 </ul>
3267 3271 <p>
3268 3272 Lastly, there is Mercurial's internal format:
3269 3273 </p>
3270 3274 <ul>
3271 3275 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3272 3276 </ul>
3273 3277 <p>
3274 3278 This is the internal representation format for dates. The first number
3275 3279 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3276 3280 second is the offset of the local timezone, in seconds west of UTC
3277 3281 (negative if the timezone is east of UTC).
3278 3282 </p>
3279 3283 <p>
3280 3284 The log command also accepts date ranges:
3281 3285 </p>
3282 3286 <ul>
3283 3287 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3284 3288 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3285 3289 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3286 3290 <li> &quot;-DAYS&quot; - within a given number of days from today
3287 3291 </ul>
3288 3292
3289 3293 </div>
3290 3294 </div>
3291 3295 </div>
3292 3296
3293 3297
3294 3298
3295 3299 </body>
3296 3300 </html>
3297 3301
3298 3302
3299 3303 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3300 3304 200 Script output follows
3301 3305
3302 3306 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3303 3307 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3304 3308 <head>
3305 3309 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3306 3310 <meta name="robots" content="index, nofollow" />
3307 3311 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3308 3312 <script type="text/javascript" src="/static/mercurial.js"></script>
3309 3313
3310 3314 <title>Help: pager</title>
3311 3315 </head>
3312 3316 <body>
3313 3317
3314 3318 <div class="container">
3315 3319 <div class="menu">
3316 3320 <div class="logo">
3317 3321 <a href="https://mercurial-scm.org/">
3318 3322 <img src="/static/hglogo.png" alt="mercurial" /></a>
3319 3323 </div>
3320 3324 <ul>
3321 3325 <li><a href="/shortlog">log</a></li>
3322 3326 <li><a href="/graph">graph</a></li>
3323 3327 <li><a href="/tags">tags</a></li>
3324 3328 <li><a href="/bookmarks">bookmarks</a></li>
3325 3329 <li><a href="/branches">branches</a></li>
3326 3330 </ul>
3327 3331 <ul>
3328 3332 <li class="active"><a href="/help">help</a></li>
3329 3333 </ul>
3330 3334 </div>
3331 3335
3332 3336 <div class="main">
3333 3337 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3334 3338 <h3>Help: pager</h3>
3335 3339
3336 3340 <form class="search" action="/log">
3337 3341
3338 3342 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3339 3343 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3340 3344 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3341 3345 </form>
3342 3346 <div id="doc">
3343 3347 <h1>Pager Support</h1>
3344 3348 <p>
3345 3349 Some Mercurial commands can produce a lot of output, and Mercurial will
3346 3350 attempt to use a pager to make those commands more pleasant.
3347 3351 </p>
3348 3352 <p>
3349 3353 To set the pager that should be used, set the application variable:
3350 3354 </p>
3351 3355 <pre>
3352 3356 [pager]
3353 3357 pager = less -FRX
3354 3358 </pre>
3355 3359 <p>
3356 3360 If no pager is set in the user or repository configuration, Mercurial uses the
3357 3361 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3358 3362 or system configuration is used. If none of these are set, a default pager will
3359 3363 be used, typically 'less' on Unix and 'more' on Windows.
3360 3364 </p>
3361 3365 <p>
3362 3366 You can disable the pager for certain commands by adding them to the
3363 3367 pager.ignore list:
3364 3368 </p>
3365 3369 <pre>
3366 3370 [pager]
3367 3371 ignore = version, help, update
3368 3372 </pre>
3369 3373 <p>
3370 3374 To ignore global commands like 'hg version' or 'hg help', you have
3371 3375 to specify them in your user configuration file.
3372 3376 </p>
3373 3377 <p>
3374 3378 To control whether the pager is used at all for an individual command,
3375 3379 you can use --pager=&lt;value&gt;:
3376 3380 </p>
3377 3381 <ul>
3378 3382 <li> use as needed: 'auto'.
3379 3383 <li> require the pager: 'yes' or 'on'.
3380 3384 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3381 3385 </ul>
3382 3386 <p>
3383 3387 To globally turn off all attempts to use a pager, set:
3384 3388 </p>
3385 3389 <pre>
3386 3390 [ui]
3387 3391 paginate = never
3388 3392 </pre>
3389 3393 <p>
3390 3394 which will prevent the pager from running.
3391 3395 </p>
3392 3396
3393 3397 </div>
3394 3398 </div>
3395 3399 </div>
3396 3400
3397 3401
3398 3402
3399 3403 </body>
3400 3404 </html>
3401 3405
3402 3406
3403 3407 Sub-topic indexes rendered properly
3404 3408
3405 3409 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3406 3410 200 Script output follows
3407 3411
3408 3412 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3409 3413 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3410 3414 <head>
3411 3415 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3412 3416 <meta name="robots" content="index, nofollow" />
3413 3417 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3414 3418 <script type="text/javascript" src="/static/mercurial.js"></script>
3415 3419
3416 3420 <title>Help: internals</title>
3417 3421 </head>
3418 3422 <body>
3419 3423
3420 3424 <div class="container">
3421 3425 <div class="menu">
3422 3426 <div class="logo">
3423 3427 <a href="https://mercurial-scm.org/">
3424 3428 <img src="/static/hglogo.png" alt="mercurial" /></a>
3425 3429 </div>
3426 3430 <ul>
3427 3431 <li><a href="/shortlog">log</a></li>
3428 3432 <li><a href="/graph">graph</a></li>
3429 3433 <li><a href="/tags">tags</a></li>
3430 3434 <li><a href="/bookmarks">bookmarks</a></li>
3431 3435 <li><a href="/branches">branches</a></li>
3432 3436 </ul>
3433 3437 <ul>
3434 3438 <li><a href="/help">help</a></li>
3435 3439 </ul>
3436 3440 </div>
3437 3441
3438 3442 <div class="main">
3439 3443 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3440 3444
3441 3445 <form class="search" action="/log">
3442 3446
3443 3447 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3444 3448 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3445 3449 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3446 3450 </form>
3447 3451 <table class="bigtable">
3448 3452 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3449 3453
3450 3454 <tr><td>
3451 3455 <a href="/help/internals.bid-merge">
3452 3456 bid-merge
3453 3457 </a>
3454 3458 </td><td>
3455 3459 Bid Merge Algorithm
3456 3460 </td></tr>
3457 3461 <tr><td>
3458 3462 <a href="/help/internals.bundle2">
3459 3463 bundle2
3460 3464 </a>
3461 3465 </td><td>
3462 3466 Bundle2
3463 3467 </td></tr>
3464 3468 <tr><td>
3465 3469 <a href="/help/internals.bundles">
3466 3470 bundles
3467 3471 </a>
3468 3472 </td><td>
3469 3473 Bundles
3470 3474 </td></tr>
3471 3475 <tr><td>
3472 3476 <a href="/help/internals.cbor">
3473 3477 cbor
3474 3478 </a>
3475 3479 </td><td>
3476 3480 CBOR
3477 3481 </td></tr>
3478 3482 <tr><td>
3479 3483 <a href="/help/internals.censor">
3480 3484 censor
3481 3485 </a>
3482 3486 </td><td>
3483 3487 Censor
3484 3488 </td></tr>
3485 3489 <tr><td>
3486 3490 <a href="/help/internals.changegroups">
3487 3491 changegroups
3488 3492 </a>
3489 3493 </td><td>
3490 3494 Changegroups
3491 3495 </td></tr>
3492 3496 <tr><td>
3493 3497 <a href="/help/internals.config">
3494 3498 config
3495 3499 </a>
3496 3500 </td><td>
3497 3501 Config Registrar
3498 3502 </td></tr>
3499 3503 <tr><td>
3500 3504 <a href="/help/internals.extensions">
3501 3505 extensions
3502 3506 </a>
3503 3507 </td><td>
3504 3508 Extension API
3505 3509 </td></tr>
3506 3510 <tr><td>
3507 3511 <a href="/help/internals.mergestate">
3508 3512 mergestate
3509 3513 </a>
3510 3514 </td><td>
3511 3515 Mergestate
3512 3516 </td></tr>
3513 3517 <tr><td>
3514 3518 <a href="/help/internals.requirements">
3515 3519 requirements
3516 3520 </a>
3517 3521 </td><td>
3518 3522 Repository Requirements
3519 3523 </td></tr>
3520 3524 <tr><td>
3521 3525 <a href="/help/internals.revlogs">
3522 3526 revlogs
3523 3527 </a>
3524 3528 </td><td>
3525 3529 Revision Logs
3526 3530 </td></tr>
3527 3531 <tr><td>
3528 3532 <a href="/help/internals.wireprotocol">
3529 3533 wireprotocol
3530 3534 </a>
3531 3535 </td><td>
3532 3536 Wire Protocol
3533 3537 </td></tr>
3534 3538 <tr><td>
3535 3539 <a href="/help/internals.wireprotocolrpc">
3536 3540 wireprotocolrpc
3537 3541 </a>
3538 3542 </td><td>
3539 3543 Wire Protocol RPC
3540 3544 </td></tr>
3541 3545 <tr><td>
3542 3546 <a href="/help/internals.wireprotocolv2">
3543 3547 wireprotocolv2
3544 3548 </a>
3545 3549 </td><td>
3546 3550 Wire Protocol Version 2
3547 3551 </td></tr>
3548 3552
3549 3553
3550 3554
3551 3555
3552 3556
3553 3557 </table>
3554 3558 </div>
3555 3559 </div>
3556 3560
3557 3561
3558 3562
3559 3563 </body>
3560 3564 </html>
3561 3565
3562 3566
3563 3567 Sub-topic topics rendered properly
3564 3568
3565 3569 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3566 3570 200 Script output follows
3567 3571
3568 3572 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3569 3573 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3570 3574 <head>
3571 3575 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3572 3576 <meta name="robots" content="index, nofollow" />
3573 3577 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3574 3578 <script type="text/javascript" src="/static/mercurial.js"></script>
3575 3579
3576 3580 <title>Help: internals.changegroups</title>
3577 3581 </head>
3578 3582 <body>
3579 3583
3580 3584 <div class="container">
3581 3585 <div class="menu">
3582 3586 <div class="logo">
3583 3587 <a href="https://mercurial-scm.org/">
3584 3588 <img src="/static/hglogo.png" alt="mercurial" /></a>
3585 3589 </div>
3586 3590 <ul>
3587 3591 <li><a href="/shortlog">log</a></li>
3588 3592 <li><a href="/graph">graph</a></li>
3589 3593 <li><a href="/tags">tags</a></li>
3590 3594 <li><a href="/bookmarks">bookmarks</a></li>
3591 3595 <li><a href="/branches">branches</a></li>
3592 3596 </ul>
3593 3597 <ul>
3594 3598 <li class="active"><a href="/help">help</a></li>
3595 3599 </ul>
3596 3600 </div>
3597 3601
3598 3602 <div class="main">
3599 3603 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3600 3604 <h3>Help: internals.changegroups</h3>
3601 3605
3602 3606 <form class="search" action="/log">
3603 3607
3604 3608 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3605 3609 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3606 3610 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3607 3611 </form>
3608 3612 <div id="doc">
3609 3613 <h1>Changegroups</h1>
3610 3614 <p>
3611 3615 Changegroups are representations of repository revlog data, specifically
3612 3616 the changelog data, root/flat manifest data, treemanifest data, and
3613 3617 filelogs.
3614 3618 </p>
3615 3619 <p>
3616 3620 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3617 3621 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3618 3622 only difference being an additional item in the *delta header*. Version
3619 3623 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3620 3624 exchanging treemanifests (enabled by setting an option on the
3621 3625 &quot;changegroup&quot; part in the bundle2).
3622 3626 </p>
3623 3627 <p>
3624 3628 Changegroups when not exchanging treemanifests consist of 3 logical
3625 3629 segments:
3626 3630 </p>
3627 3631 <pre>
3628 3632 +---------------------------------+
3629 3633 | | | |
3630 3634 | changeset | manifest | filelogs |
3631 3635 | | | |
3632 3636 | | | |
3633 3637 +---------------------------------+
3634 3638 </pre>
3635 3639 <p>
3636 3640 When exchanging treemanifests, there are 4 logical segments:
3637 3641 </p>
3638 3642 <pre>
3639 3643 +-------------------------------------------------+
3640 3644 | | | | |
3641 3645 | changeset | root | treemanifests | filelogs |
3642 3646 | | manifest | | |
3643 3647 | | | | |
3644 3648 +-------------------------------------------------+
3645 3649 </pre>
3646 3650 <p>
3647 3651 The principle building block of each segment is a *chunk*. A *chunk*
3648 3652 is a framed piece of data:
3649 3653 </p>
3650 3654 <pre>
3651 3655 +---------------------------------------+
3652 3656 | | |
3653 3657 | length | data |
3654 3658 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3655 3659 | | |
3656 3660 +---------------------------------------+
3657 3661 </pre>
3658 3662 <p>
3659 3663 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3660 3664 integer indicating the length of the entire chunk (including the length field
3661 3665 itself).
3662 3666 </p>
3663 3667 <p>
3664 3668 There is a special case chunk that has a value of 0 for the length
3665 3669 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3666 3670 </p>
3667 3671 <h2>Delta Groups</h2>
3668 3672 <p>
3669 3673 A *delta group* expresses the content of a revlog as a series of deltas,
3670 3674 or patches against previous revisions.
3671 3675 </p>
3672 3676 <p>
3673 3677 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3674 3678 to signal the end of the delta group:
3675 3679 </p>
3676 3680 <pre>
3677 3681 +------------------------------------------------------------------------+
3678 3682 | | | | | |
3679 3683 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3680 3684 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3681 3685 | | | | | |
3682 3686 +------------------------------------------------------------------------+
3683 3687 </pre>
3684 3688 <p>
3685 3689 Each *chunk*'s data consists of the following:
3686 3690 </p>
3687 3691 <pre>
3688 3692 +---------------------------------------+
3689 3693 | | |
3690 3694 | delta header | delta data |
3691 3695 | (various by version) | (various) |
3692 3696 | | |
3693 3697 +---------------------------------------+
3694 3698 </pre>
3695 3699 <p>
3696 3700 The *delta data* is a series of *delta*s that describe a diff from an existing
3697 3701 entry (either that the recipient already has, or previously specified in the
3698 3702 bundle/changegroup).
3699 3703 </p>
3700 3704 <p>
3701 3705 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3702 3706 &quot;3&quot; of the changegroup format.
3703 3707 </p>
3704 3708 <p>
3705 3709 Version 1 (headerlen=80):
3706 3710 </p>
3707 3711 <pre>
3708 3712 +------------------------------------------------------+
3709 3713 | | | | |
3710 3714 | node | p1 node | p2 node | link node |
3711 3715 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3712 3716 | | | | |
3713 3717 +------------------------------------------------------+
3714 3718 </pre>
3715 3719 <p>
3716 3720 Version 2 (headerlen=100):
3717 3721 </p>
3718 3722 <pre>
3719 3723 +------------------------------------------------------------------+
3720 3724 | | | | | |
3721 3725 | node | p1 node | p2 node | base node | link node |
3722 3726 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3723 3727 | | | | | |
3724 3728 +------------------------------------------------------------------+
3725 3729 </pre>
3726 3730 <p>
3727 3731 Version 3 (headerlen=102):
3728 3732 </p>
3729 3733 <pre>
3730 3734 +------------------------------------------------------------------------------+
3731 3735 | | | | | | |
3732 3736 | node | p1 node | p2 node | base node | link node | flags |
3733 3737 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3734 3738 | | | | | | |
3735 3739 +------------------------------------------------------------------------------+
3736 3740 </pre>
3737 3741 <p>
3738 3742 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3739 3743 series of *delta*s, densely packed (no separators). These deltas describe a diff
3740 3744 from an existing entry (either that the recipient already has, or previously
3741 3745 specified in the bundle/changegroup). The format is described more fully in
3742 3746 &quot;hg help internals.bdiff&quot;, but briefly:
3743 3747 </p>
3744 3748 <pre>
3745 3749 +---------------------------------------------------------------+
3746 3750 | | | | |
3747 3751 | start offset | end offset | new length | content |
3748 3752 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3749 3753 | | | | |
3750 3754 +---------------------------------------------------------------+
3751 3755 </pre>
3752 3756 <p>
3753 3757 Please note that the length field in the delta data does *not* include itself.
3754 3758 </p>
3755 3759 <p>
3756 3760 In version 1, the delta is always applied against the previous node from
3757 3761 the changegroup or the first parent if this is the first entry in the
3758 3762 changegroup.
3759 3763 </p>
3760 3764 <p>
3761 3765 In version 2 and up, the delta base node is encoded in the entry in the
3762 3766 changegroup. This allows the delta to be expressed against any parent,
3763 3767 which can result in smaller deltas and more efficient encoding of data.
3764 3768 </p>
3765 3769 <p>
3766 3770 The *flags* field holds bitwise flags affecting the processing of revision
3767 3771 data. The following flags are defined:
3768 3772 </p>
3769 3773 <dl>
3770 3774 <dt>32768
3771 3775 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3772 3776 <dt>16384
3773 3777 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3774 3778 <dt>8192
3775 3779 <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.
3776 3780 </dl>
3777 3781 <p>
3778 3782 For historical reasons, the integer values are identical to revlog version 1
3779 3783 per-revision storage flags and correspond to bits being set in this 2-byte
3780 3784 field. Bits were allocated starting from the most-significant bit, hence the
3781 3785 reverse ordering and allocation of these flags.
3782 3786 </p>
3783 3787 <h2>Changeset Segment</h2>
3784 3788 <p>
3785 3789 The *changeset segment* consists of a single *delta group* holding
3786 3790 changelog data. The *empty chunk* at the end of the *delta group* denotes
3787 3791 the boundary to the *manifest segment*.
3788 3792 </p>
3789 3793 <h2>Manifest Segment</h2>
3790 3794 <p>
3791 3795 The *manifest segment* consists of a single *delta group* holding manifest
3792 3796 data. If treemanifests are in use, it contains only the manifest for the
3793 3797 root directory of the repository. Otherwise, it contains the entire
3794 3798 manifest data. The *empty chunk* at the end of the *delta group* denotes
3795 3799 the boundary to the next segment (either the *treemanifests segment* or the
3796 3800 *filelogs segment*, depending on version and the request options).
3797 3801 </p>
3798 3802 <h3>Treemanifests Segment</h3>
3799 3803 <p>
3800 3804 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3801 3805 only if the 'treemanifest' param is part of the bundle2 changegroup part
3802 3806 (it is not possible to use changegroup version 3 outside of bundle2).
3803 3807 Aside from the filenames in the *treemanifests segment* containing a
3804 3808 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3805 3809 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3806 3810 a sub-segment with filename size 0). This denotes the boundary to the
3807 3811 *filelogs segment*.
3808 3812 </p>
3809 3813 <h2>Filelogs Segment</h2>
3810 3814 <p>
3811 3815 The *filelogs segment* consists of multiple sub-segments, each
3812 3816 corresponding to an individual file whose data is being described:
3813 3817 </p>
3814 3818 <pre>
3815 3819 +--------------------------------------------------+
3816 3820 | | | | | |
3817 3821 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3818 3822 | | | | | (4 bytes) |
3819 3823 | | | | | |
3820 3824 +--------------------------------------------------+
3821 3825 </pre>
3822 3826 <p>
3823 3827 The final filelog sub-segment is followed by an *empty chunk* (logically,
3824 3828 a sub-segment with filename size 0). This denotes the end of the segment
3825 3829 and of the overall changegroup.
3826 3830 </p>
3827 3831 <p>
3828 3832 Each filelog sub-segment consists of the following:
3829 3833 </p>
3830 3834 <pre>
3831 3835 +------------------------------------------------------+
3832 3836 | | | |
3833 3837 | filename length | filename | delta group |
3834 3838 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3835 3839 | | | |
3836 3840 +------------------------------------------------------+
3837 3841 </pre>
3838 3842 <p>
3839 3843 That is, a *chunk* consisting of the filename (not terminated or padded)
3840 3844 followed by N chunks constituting the *delta group* for this file. The
3841 3845 *empty chunk* at the end of each *delta group* denotes the boundary to the
3842 3846 next filelog sub-segment.
3843 3847 </p>
3844 3848
3845 3849 </div>
3846 3850 </div>
3847 3851 </div>
3848 3852
3849 3853
3850 3854
3851 3855 </body>
3852 3856 </html>
3853 3857
3854 3858
3855 3859 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3856 3860 404 Not Found
3857 3861
3858 3862 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3859 3863 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3860 3864 <head>
3861 3865 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3862 3866 <meta name="robots" content="index, nofollow" />
3863 3867 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3864 3868 <script type="text/javascript" src="/static/mercurial.js"></script>
3865 3869
3866 3870 <title>test: error</title>
3867 3871 </head>
3868 3872 <body>
3869 3873
3870 3874 <div class="container">
3871 3875 <div class="menu">
3872 3876 <div class="logo">
3873 3877 <a href="https://mercurial-scm.org/">
3874 3878 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3875 3879 </div>
3876 3880 <ul>
3877 3881 <li><a href="/shortlog">log</a></li>
3878 3882 <li><a href="/graph">graph</a></li>
3879 3883 <li><a href="/tags">tags</a></li>
3880 3884 <li><a href="/bookmarks">bookmarks</a></li>
3881 3885 <li><a href="/branches">branches</a></li>
3882 3886 </ul>
3883 3887 <ul>
3884 3888 <li><a href="/help">help</a></li>
3885 3889 </ul>
3886 3890 </div>
3887 3891
3888 3892 <div class="main">
3889 3893
3890 3894 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3891 3895 <h3>error</h3>
3892 3896
3893 3897
3894 3898 <form class="search" action="/log">
3895 3899
3896 3900 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3897 3901 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3898 3902 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3899 3903 </form>
3900 3904
3901 3905 <div class="description">
3902 3906 <p>
3903 3907 An error occurred while processing your request:
3904 3908 </p>
3905 3909 <p>
3906 3910 Not Found
3907 3911 </p>
3908 3912 </div>
3909 3913 </div>
3910 3914 </div>
3911 3915
3912 3916
3913 3917
3914 3918 </body>
3915 3919 </html>
3916 3920
3917 3921 [1]
3918 3922
3919 3923 $ killdaemons.py
3920 3924
3921 3925 #endif
General Comments 0
You need to be logged in to leave comments. Login now