##// END OF EJS Templates
Add rename/mv command....
Bryan O'Sullivan -
r1253:a45e717c default
parent child Browse files
Show More
@@ -1,758 +1,778 b''
1 1 HG(1)
2 2 =====
3 3 Matt Mackall <mpm@selenic.com>
4 4
5 5 NAME
6 6 ----
7 7 hg - Mercurial source code management system
8 8
9 9 SYNOPSIS
10 10 --------
11 11 'hg' [-v -d -q -y] <command> [command options] [files]
12 12
13 13 DESCRIPTION
14 14 -----------
15 15 The hg(1) command provides a command line interface to the Mercurial system.
16 16
17 17 OPTIONS
18 18 -------
19 19
20 20 -R, --repository::
21 21 repository root directory
22 22
23 23 --cwd::
24 24 change working directory
25 25
26 26 -y, --noninteractive::
27 27 do not prompt, assume 'yes' for any required answers
28 28
29 29 -q, --quiet::
30 30 suppress output
31 31
32 32 -v, --verbose::
33 33 enable additional output
34 34
35 35 --debug::
36 36 enable debugging output
37 37
38 38 --traceback::
39 39 print traceback on exception
40 40
41 41 --time::
42 42 time how long the command takes
43 43
44 44 --profile::
45 45 print command execution profile
46 46
47 47 --version::
48 48 output version information and exit
49 49
50 50 -h, --help::
51 51 display help and exit
52 52
53 53 COMMAND ELEMENTS
54 54 ----------------
55 55
56 56 files ...::
57 57 indicates one or more filename or relative path filenames; see
58 58 "FILE NAME PATTERNS" for information on pattern matching
59 59
60 60 path::
61 61 indicates a path on the local machine
62 62
63 63 revision::
64 64 indicates a changeset which can be specified as a changeset revision
65 65 number, a tag, or a unique substring of the changeset hash value
66 66
67 67 repository path::
68 68 either the pathname of a local repository or the URI of a remote
69 69 repository. There are two available URI protocols, http:// which is
70 70 fast and the old-http:// protocol which is much slower but does not
71 71 require a special server on the web host.
72 72
73 73 COMMANDS
74 74 --------
75 75
76 76 add [options] [files ...]::
77 77 Schedule files to be version controlled and added to the repository.
78 78
79 79 The files will be added to the repository at the next commit.
80 80
81 81 If no names are given, add all files in the current directory and
82 82 its subdirectories.
83 83
84 84 addremove [options] [files ...]::
85 85 Add all new files and remove all missing files from the repository.
86 86
87 87 New files are ignored if they match any of the patterns in .hgignore. As
88 88 with add, these changes take effect at the next commit.
89 89
90 90 annotate [-r <rev> -u -n -c] [files ...]::
91 91 List changes in files, showing the revision id responsible for each line
92 92
93 93 This command is useful to discover who did a change or when a change took
94 94 place.
95 95
96 96 Without the -a option, annotate will avoid processing files it
97 97 detects as binary. With -a, annotate will generate an annotation
98 98 anyway, probably with undesirable results.
99 99
100 100 options:
101 101 -a, --text treat all files as text
102 102 -I, --include <pat> include names matching the given patterns
103 103 -X, --exclude <pat> exclude names matching the given patterns
104 104 -r, --revision <rev> annotate the specified revision
105 105 -u, --user list the author
106 106 -c, --changeset list the changeset
107 107 -n, --number list the revision number (default)
108 108
109 109 bundle <file> <other>::
110 110 (EXPERIMENTAL)
111 111
112 112 Generate a compressed changegroup file collecting all changesets
113 113 not found in the other repository.
114 114
115 115 This file can then be transferred using conventional means and
116 116 applied to another repository with the unbundle command. This is
117 117 useful when native push and pull are not available or when
118 118 exporting an entire repository is undesirable. The standard file
119 119 extension is ".hg".
120 120
121 121 Unlike import/export, this exactly preserves all changeset
122 122 contents including permissions, rename data, and revision history.
123 123
124 124 cat <file> [revision]::
125 125 Output to stdout the given revision for the specified file.
126 126
127 127 If no revision is given then the tip is used.
128 128
129 129 clone [-U] <source> [dest]::
130 130 Create a copy of an existing repository in a new directory.
131 131
132 132 If no destination directory name is specified, it defaults to the
133 133 basename of the source.
134 134
135 135 The source is added to the new repository's .hg/hgrc file to be used in
136 136 future pulls.
137 137
138 138 For efficiency, hardlinks are used for cloning whenever the
139 139 source and destination are on the same filesystem.
140 140
141 141 options:
142 142 -U, --noupdate do not update the new working directory
143 143 -e, --ssh specify ssh command to use
144 144 --remotecmd specify hg command to run on the remote side
145 145
146 146 commit [options] [files...]::
147 147 Commit changes to the given files into the repository.
148 148
149 149 If a list of files is omitted, all changes reported by "hg status"
150 150 from the root of the repository will be commited.
151 151
152 152 The HGEDITOR or EDITOR environment variables are used to start an
153 153 editor to add a commit comment.
154 154
155 155 Options:
156 156
157 157 -A, --addremove run addremove during commit
158 158 -I, --include <pat> include names matching the given patterns
159 159 -X, --exclude <pat> exclude names matching the given patterns
160 160 -m, --message <text> use <text> as commit message
161 161 -l, --logfile <file> read the commit message from <file>
162 162 -d, --date <datecode> record datecode as commit date
163 163 -u, --user <user> record user as commiter
164 164
165 165 aliases: ci
166 166
167 167 copy <source ...> <dest>::
168 168 Mark dest as having copies of source files. If dest is a
169 169 directory, copies are put in that directory. If dest is a file,
170 170 there can only be one source.
171 171
172 172 By default, this command copies the contents of files as they
173 173 stand in the working directory. If invoked with --after, the
174 174 operation is recorded, but no copying is performed.
175 175
176 This command takes effect for the next commit.
176 This command takes effect in the next commit.
177 177
178 178 Options:
179 179 -A, --after record a copy that has already occurred
180 180 -f, --force forcibly copy over an existing managed file
181 181 -p, --parents append source path to dest
182 182
183 aliases: cp
184
183 185 diff [-a] [-r revision] [-r revision] [files ...]::
184 186 Show differences between revisions for the specified files.
185 187
186 188 Differences between files are shown using the unified diff format.
187 189
188 190 When two revision arguments are given, then changes are shown
189 191 between those revisions. If only one revision is specified then
190 192 that revision is compared to the working directory, and, when no
191 193 revisions are specified, the working directory files are compared
192 194 to its parent.
193 195
194 196 Without the -a option, diff will avoid generating diffs of files
195 197 it detects as binary. With -a, diff will generate a diff anyway,
196 198 probably with undesirable results.
197 199
198 200 options:
199 201 -a, --text treat all files as text
200 202 -I, --include <pat> include names matching the given patterns
201 203 -X, --exclude <pat> exclude names matching the given patterns
202 204
203 205 export [-o filespec] [revision] ...::
204 206 Print the changeset header and diffs for one or more revisions.
205 207
206 208 The information shown in the changeset header is: author,
207 209 changeset hash, parent and commit comment.
208 210
209 211 Output may be to a file, in which case the name of the file is
210 212 given using a format string. The formatting rules are as follows:
211 213
212 214 %% literal "%" character
213 215 %H changeset hash (40 bytes of hexadecimal)
214 216 %N number of patches being generated
215 217 %R changeset revision number
216 218 %b basename of the exporting repository
217 219 %h short-form changeset hash (12 bytes of hexadecimal)
218 220 %n zero-padded sequence number, starting at 1
219 221 %r zero-padded changeset revision number
220 222
221 223 Without the -a option, export will avoid generating diffs of files
222 224 it detects as binary. With -a, export will generate a diff anyway,
223 225 probably with undesirable results.
224 226
225 227 options:
226 228 -a, --text treat all files as text
227 229 -o, --output <filespec> print output to file with formatted named
228 230
229 231 forget [options] [files]::
230 232 Undo an 'hg add' scheduled for the next commit.
231 233
232 234 options:
233 235 -I, --include <pat> include names matching the given patterns
234 236 -X, --exclude <pat> exclude names matching the given patterns
235 237
236 238 grep [options] pattern [files]::
237 239 Search revisions of files for a regular expression.
238 240
239 241 This command behaves differently than Unix grep. It only accepts
240 242 Python/Perl regexps. It searches repository history, not the
241 243 working directory. It always prints the revision number in which
242 244 a match appears.
243 245
244 246 By default, grep only prints output for the first revision of a
245 247 file in which it finds a match. To get it to print every revision
246 248 that contains a change in match status ("-" for a match that
247 249 becomes a non-match, or "+" for a non-match that becomes a match),
248 250 use the --all flag.
249 251
250 252 options:
251 253 -0, --print0 end fields with NUL
252 254 -I, --include <pat> include names matching the given patterns
253 255 -X, --exclude <pat> exclude names matching the given patterns
254 256 --all print all revisions that match
255 257 -i, --ignore-case ignore case when matching
256 258 -l, --files-with-matches print only file names and revs that match
257 259 -n, --line-number print matching line numbers
258 260 -r <rev>, --rev <rev> search in given revision range
259 261 -u, --user print user who committed change
260 262
261 263 heads::
262 264 Show all repository head changesets.
263 265
264 266 Repository "heads" are changesets that don't have children
265 267 changesets. They are where development generally takes place and
266 268 are the usual targets for update and merge operations.
267 269
268 270 identify::
269 271 Print a short summary of the current state of the repo.
270 272
271 273 This summary identifies the repository state using one or two parent
272 274 hash identifiers, followed by a "+" if there are uncommitted changes
273 275 in the working directory, followed by a list of tags for this revision.
274 276
275 277 aliases: id
276 278
277 279 import [-p <n> -b <base> -f] <patches>::
278 280 Import a list of patches and commit them individually.
279 281
280 282 If there are outstanding changes in the working directory, import
281 283 will abort unless given the -f flag.
282 284
283 285 If a patch looks like a mail message (its first line starts with
284 286 "From " or looks like an RFC822 header), it will not be applied
285 287 unless the -f option is used. The importer neither parses nor
286 288 discards mail headers, so use -f only to override the "mailness"
287 289 safety check, not to import a real mail message.
288 290
289 291 options:
290 292 -p, --strip <n> directory strip option for patch. This has the same
291 293 meaning as the corresponding patch option
292 294 -b <path> base directory to read patches from
293 295 -f, --force skip check for outstanding uncommitted changes
294 296
295 297 aliases: patch
296 298
297 299 incoming [-p] [source]::
298 300 Show new changesets found in the specified repo or the default
299 301 pull repo. These are the changesets that would be pulled if a pull
300 302 was requested.
301 303
302 304 Currently only local repositories are supported.
303 305
304 306 options:
305 307 -p, --patch show patch
306 308
307 309 aliases: in
308 310
309 311 init [dest]::
310 312 Initialize a new repository in the given directory. If the given
311 313 directory does not exist, it is created.
312 314
313 315 If no directory is given, the current directory is used.
314 316
315 317 locate [options] [files]::
316 318 Print all files under Mercurial control whose names match the
317 319 given patterns.
318 320
319 321 This command searches the current directory and its
320 322 subdirectories. To search an entire repository, move to the root
321 323 of the repository.
322 324
323 325 If no patterns are given to match, this command prints all file
324 326 names.
325 327
326 328 If you want to feed the output of this command into the "xargs"
327 329 command, use the "-0" option to both this command and "xargs".
328 330 This will avoid the problem of "xargs" treating single filenames
329 331 that contain white space as multiple file names.
330 332
331 333 options:
332 334
333 335 -0, --print0 end filenames with NUL, for use with xargs
334 336 -f, --fullpath print complete paths from the filesystem root
335 337 -I, --include <pat> include names matching the given patterns
336 338 -r, --rev <rev> search the repository as it stood at rev
337 339 -X, --exclude <pat> exclude names matching the given patterns
338 340
339 341 log [-r revision ...] [-p] [files]::
340 342 Print the revision history of the specified files or the entire project.
341 343
342 344 By default this command outputs: changeset id and hash, tags,
343 345 parents, user, date and time, and a summary for each commit. The
344 346 -v switch adds some more detail, such as changed files, manifest
345 347 hashes or message signatures.
346 348
347 349 options:
348 350 -I, --include <pat> include names matching the given patterns
349 351 -X, --exclude <pat> exclude names matching the given patterns
350 352 -r, --rev <A> show the specified revision or range
351 353 -p, --patch show patch
352 354
353 355 aliases: history
354 356
355 357 manifest [revision]::
356 358 Print a list of version controlled files for the given revision.
357 359
358 360 The manifest is the list of files being version controlled. If no revision
359 361 is given then the tip is used.
360 362
361 363 outgoing [-p] [dest]::
362 364 Show changesets not found in the specified destination repo or the
363 365 default push repo. These are the changesets that would be pushed
364 366 if a push was requested.
365 367
366 368 options:
367 369 -p, --patch show patch
368 370
369 371 aliases: out
370 372
371 373 parents::
372 374 Print the working directory's parent revisions.
373 375
374 376 paths [NAME]::
375 377 Show definition of symbolic path name NAME. If no name is given, show
376 378 definition of available names.
377 379
378 380 Path names are defined in the [paths] section of /etc/mercurial/hgrc
379 381 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
380 382
381 383 pull <repository path>::
382 384 Pull changes from a remote repository to a local one.
383 385
384 386 This finds all changes from the repository at the specified path
385 387 or URL and adds them to the local repository. By default, this
386 388 does not update the copy of the project in the working directory.
387 389
388 390 Valid URLs are of the form:
389 391
390 392 local/filesystem/path
391 393 http://[user@]host[:port][/path]
392 394 https://[user@]host[:port][/path]
393 395 ssh://[user@]host[:port][/path]
394 396
395 397 SSH requires an accessible shell account on the destination
396 398 machine and a copy of hg in the remote path.
397 399
398 400 options:
399 401 -u, --update update the working directory to tip after pull
400 402 -e, --ssh specify ssh command to use
401 403 --remotecmd specify hg command to run on the remote side
402 404
403 405 push <destination>::
404 406 Push changes from the local repository to the given destination.
405 407
406 408 This is the symmetrical operation for pull. It helps to move
407 409 changes from the current repository to a different one. If the
408 410 destination is local this is identical to a pull in that directory
409 411 from the current one.
410 412
411 413 By default, push will refuse to run if it detects the result would
412 414 increase the number of remote heads. This generally indicates the
413 415 the client has forgotten to sync and merge before pushing.
414 416
415 417 Valid URLs are of the form:
416 418
417 419 local/filesystem/path
418 420 ssh://[user@]host[:port][/path]
419 421
420 422 SSH requires an accessible shell account on the destination
421 423 machine and a copy of hg in the remote path.
422 424
423 425 options:
424 426
425 427 -f, --force force update
426 428 -e, --ssh specify ssh command to use
427 429 --remotecmd specify hg command to run on the remote side
428 430
429 431 rawcommit [-p -d -u -F -m -l]::
430 432 Lowlevel commit, for use in helper scripts.
431 433
432 434 This command is not intended to be used by normal users, as it is
433 435 primarily useful for importing from other SCMs.
434 436
435 437 recover::
436 438 Recover from an interrupted commit or pull.
437 439
438 440 This command tries to fix the repository status after an interrupted
439 441 operation. It should only be necessary when Mercurial suggests it.
440 442
441 443 remove [options] [files ...]::
442 444 Schedule the indicated files for removal from the repository.
443 445
444 446 This command schedules the files to be removed at the next commit.
445 447 This only removes files from the current branch, not from the
446 448 entire project history. If the files still exist in the working
447 449 directory, they will be deleted from it.
448 450
449 451 aliases: rm
450 452
453 rename <source ...> <dest>::
454 Mark dest as copies of sources; mark sources for deletion. If
455 dest is a directory, copies are put in that directory. If dest is
456 a file, there can only be one source.
457
458 By default, this command copies the contents of files as they
459 stand in the working directory. If invoked with --after, the
460 operation is recorded, but no copying is performed.
461
462 This command takes effect in the next commit.
463
464 Options:
465 -A, --after record a rename that has already occurred
466 -f, --force forcibly copy over an existing managed file
467 -p, --parents append source path to dest
468
469 aliases: mv
470
451 471 revert [names ...]::
452 472 Revert any uncommitted modifications made to the named files or
453 473 directories. This restores the contents of the affected files to
454 474 an unmodified state.
455 475
456 476 If a file has been deleted, it is recreated. If the executable
457 477 mode of a file was changed, it is reset.
458 478
459 479 If a directory is given, all files in that directory and its
460 480 subdirectories are reverted.
461 481
462 482 If no arguments are given, all files in the current directory and
463 483 its subdirectories are reverted.
464 484
465 485 options:
466 486 -r, --rev <rev> revision to revert to
467 487 -n, --nonrecursive do not recurse into subdirectories
468 488
469 489 root::
470 490 Print the root directory of the current repository.
471 491
472 492 serve [options]::
473 493 Start a local HTTP repository browser and pull server.
474 494
475 495 By default, the server logs accesses to stdout and errors to
476 496 stderr. Use the "-A" and "-E" options to log to files.
477 497
478 498 options:
479 499 -A, --accesslog <file> name of access log file to write to
480 500 -E, --errorlog <file> name of error log file to write to
481 501 -a, --address <addr> address to use
482 502 -p, --port <n> port to use (default: 8000)
483 503 -n, --name <name> name to show in web pages (default: working dir)
484 504 -t, --templatedir <path> web templates to use
485 505 -6, --ipv6 use IPv6 in addition to IPv4
486 506
487 507 status [options] [files]::
488 508 Show changed files in the working directory. If no names are
489 509 given, all files are shown. Otherwise, only files matching the
490 510 given names are shown.
491 511
492 512 The codes used to show the status of files are:
493 513
494 514 M = changed
495 515 A = added
496 516 R = removed
497 517 ? = not tracked
498 518
499 519 options:
500 520
501 521 -m, --modified show only modified files
502 522 -a, --added show only added files
503 523 -r, --removed show only removed files
504 524 -u, --unknown show only unknown (not tracked) files
505 525 -n, --no-status hide status prefix
506 526 -0, --print0 end filenames with NUL, for use with xargs
507 527 -I, --include <pat> include names matching the given patterns
508 528 -X, --exclude <pat> exclude names matching the given patterns
509 529
510 530 tag [-l -m <text> -d <datecode> -u <user>] <name> [revision]::
511 531 Name a particular revision using <name>.
512 532
513 533 Tags are used to name particular revisions of the repository and are
514 534 very useful to compare different revision, to go back to significant
515 535 earlier versions or to mark branch points as releases, etc.
516 536
517 537 If no revision is given, the tip is used.
518 538
519 539 To facilitate version control, distribution, and merging of tags,
520 540 they are stored as a file named ".hgtags" which is managed
521 541 similarly to other project files and can be hand-edited if
522 542 necessary.
523 543
524 544 options:
525 545 -l, --local make the tag local
526 546 -m, --message <text> message for tag commit log entry
527 547 -d, --date <datecode> datecode for commit
528 548 -u, --user <user> user for commit
529 549
530 550 Note: Local tags are not version-controlled or distributed and are
531 551 stored in the .hg/localtags file. If there exists a local tag and
532 552 a public tag with the same name, local tag is used.
533 553
534 554 tags::
535 555 List the repository tags.
536 556
537 557 This lists both regular and local tags.
538 558
539 559 tip::
540 560 Show the tip revision.
541 561
542 562 unbundle <file>::
543 563 (EXPERIMENTAL)
544 564
545 565 Apply a compressed changegroup file generated by the bundle
546 566 command.
547 567
548 568 undo::
549 569 Undo the last commit or pull transaction.
550 570
551 571 Roll back the last pull or commit transaction on the
552 572 repository, restoring the project to its earlier state.
553 573
554 574 This command should be used with care. There is only one level of
555 575 undo and there is no redo.
556 576
557 577 This command is not intended for use on public repositories. Once
558 578 a change is visible for pull by other users, undoing it locally is
559 579 ineffective.
560 580
561 581 update [-m -C] [revision]::
562 582 Update the working directory to the specified revision.
563 583
564 584 By default, update will refuse to run if doing so would require
565 585 merging or discarding local changes.
566 586
567 587 With the -m option, a merge will be performed.
568 588
569 589 With the -C option, local changes will be lost.
570 590
571 591 options:
572 592 -m, --merge allow merging of branches
573 593 -C, --clean overwrite locally modified files
574 594
575 595 aliases: up checkout co
576 596
577 597 verify::
578 598 Verify the integrity of the current repository.
579 599
580 600 This will perform an extensive check of the repository's
581 601 integrity, validating the hashes and checksums of each entry in
582 602 the changelog, manifest, and tracked files, as well as the
583 603 integrity of their crosslinks and indices.
584 604
585 605 FILE NAME PATTERNS
586 606 ------------------
587 607
588 608 Mercurial accepts several notations for identifying one or more
589 609 file at a time.
590 610
591 611 By default, Mercurial treats file names as shell-style extended
592 612 glob patterns.
593 613
594 614 Alternate pattern notations must be specified explicitly.
595 615
596 616 To use a plain path name without any pattern matching, start a
597 617 name with "path:". These path names must match completely, from
598 618 the root of the current repository.
599 619
600 620 To use an extended glob, start a name with "glob:". Globs are
601 621 rooted at the current directory; a glob such as "*.c" will match
602 622 files ending in ".c" in the current directory only.
603 623
604 624 The supported glob syntax extensions are "**" to match any string
605 625 across path separators, and "{a,b}" to mean "a or b".
606 626
607 627 To use a Perl/Python regular expression, start a name with "re:".
608 628 Regexp pattern matching is anchored at the root of the repository.
609 629
610 630 Plain examples:
611 631
612 632 path:foo/bar a name bar in a directory named foo in the root of
613 633 the repository
614 634 path:path:name a file or directory named "path:name"
615 635
616 636 Glob examples:
617 637
618 638 glob:*.c any name ending in ".c" in the current directory
619 639 *.c any name ending in ".c" in the current directory
620 640 **.c any name ending in ".c" in the current directory, or
621 641 any subdirectory
622 642 foo/*.c any name ending in ".c" in the directory foo
623 643 foo/**.c any name ending in ".c" in the directory foo, or any
624 644 subdirectory
625 645
626 646 Regexp examples:
627 647
628 648 re:.*\.c$ any name ending in ".c", anywhere in the repository
629 649
630 650
631 651 SPECIFYING SINGLE REVISIONS
632 652 ---------------------------
633 653
634 654 Mercurial accepts several notations for identifying individual
635 655 revisions.
636 656
637 657 A plain integer is treated as a revision number. Negative
638 658 integers are treated as offsets from the tip, with -1 denoting the
639 659 tip.
640 660
641 661 A 40-digit hexadecimal string is treated as a unique revision
642 662 identifier.
643 663
644 664 A hexadecimal string less than 40 characters long is treated as a
645 665 unique revision identifier, and referred to as a short-form
646 666 identifier. A short-form identifier is only valid if it is the
647 667 prefix of one full-length identifier.
648 668
649 669 Any other string is treated as a tag name, which is a symbolic
650 670 name associated with a revision identifier. Tag names may not
651 671 contain the ":" character.
652 672
653 673 The reserved name "tip" is a special tag that always identifies
654 674 the most recent revision.
655 675
656 676 SPECIFYING MULTIPLE REVISIONS
657 677 -----------------------------
658 678
659 679 When Mercurial accepts more than one revision, they may be
660 680 specified individually, or provided as a continuous range,
661 681 separated by the ":" character.
662 682
663 683 The syntax of range notation is [BEGIN]:[END], where BEGIN and END
664 684 are revision identifiers. Both BEGIN and END are optional. If
665 685 BEGIN is not specified, it defaults to revision number 0. If END
666 686 is not specified, it defaults to the tip. The range ":" thus
667 687 means "all revisions".
668 688
669 689 If BEGIN is greater than END, revisions are treated in reverse
670 690 order.
671 691
672 692 A range acts as a closed interval. This means that a range of 3:5
673 693 gives 3, 4 and 5. Similarly, a range of 4:2 gives 4, 3, and 2.
674 694
675 695 ENVIRONMENT VARIABLES
676 696 ---------------------
677 697
678 698 HGEDITOR::
679 699 This is the name of the editor to use when committing. Defaults to the
680 700 value of EDITOR.
681 701
682 702 (deprecated, use .hgrc)
683 703
684 704 HGMERGE::
685 705 An executable to use for resolving merge conflicts. The program
686 706 will be executed with three arguments: local file, remote file,
687 707 ancestor file.
688 708
689 709 The default program is "hgmerge", which is a shell script provided
690 710 by Mercurial with some sensible defaults.
691 711
692 712 (deprecated, use .hgrc)
693 713
694 714 HGUSER::
695 715 This is the string used for the author of a commit.
696 716
697 717 (deprecated, use .hgrc)
698 718
699 719 EMAIL::
700 720 If HGUSER is not set, this will be used as the author for a commit.
701 721
702 722 LOGNAME::
703 723 If neither HGUSER nor EMAIL is set, LOGNAME will be used (with
704 724 '@hostname' appended) as the author value for a commit.
705 725
706 726 EDITOR::
707 727 This is the name of the editor used in the hgmerge script. It will be
708 728 used for commit messages if HGEDITOR isn't set. Defaults to 'vi'.
709 729
710 730 PYTHONPATH::
711 731 This is used by Python to find imported modules and may need to be set
712 732 appropriately if Mercurial is not installed system-wide.
713 733
714 734 FILES
715 735 -----
716 736 .hgignore::
717 737 This file contains regular expressions (one per line) that describe file
718 738 names that should be ignored by hg.
719 739
720 740 .hgtags::
721 741 This file contains changeset hash values and text tag names (one of each
722 742 separated by spaces) that correspond to tagged versions of the repository
723 743 contents.
724 744
725 745 /etc/mercurial/hgrc, $HOME/.hgrc, .hg/hgrc::
726 746 This file contains defaults and configuration. Values in .hg/hgrc
727 747 override those in $HOME/.hgrc, and these override settings made in the
728 748 global /etc/mercurial/hgrc configuration. See hgrc(5) for details of
729 749 the contents and format of these files.
730 750
731 751 BUGS
732 752 ----
733 753 Probably lots, please post them to the mailing list (See Resources below)
734 754 when you find them.
735 755
736 756 SEE ALSO
737 757 --------
738 758 hgrc(5)
739 759
740 760 AUTHOR
741 761 ------
742 762 Written by Matt Mackall <mpm@selenic.com>
743 763
744 764 RESOURCES
745 765 ---------
746 766 http://selenic.com/mercurial[Main Web Site]
747 767
748 768 http://www.serpentine.com/mercurial[Wiki site]
749 769
750 770 http://selenic.com/hg[Source code repository]
751 771
752 772 http://selenic.com/mailman/listinfo/mercurial[Mailing list]
753 773
754 774 COPYING
755 775 -------
756 776 Copyright (C) 2005 Matt Mackall.
757 777 Free use of this software is granted under the terms of the GNU General
758 778 Public License (GPL).
@@ -1,2165 +1,2193 b''
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from demandload import demandload
9 9 from node import *
10 10 demandload(globals(), "os re sys signal shutil imp urllib pdb")
11 11 demandload(globals(), "fancyopts ui hg util lock revlog")
12 12 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback")
13 13 demandload(globals(), "errno socket version struct atexit sets bz2")
14 14
15 15 class UnknownCommand(Exception):
16 16 """Exception raised if command is not in the command table."""
17 17
18 18 def filterfiles(filters, files):
19 19 l = [x for x in files if x in filters]
20 20
21 21 for t in filters:
22 22 if t and t[-1] != "/":
23 23 t += "/"
24 24 l += [x for x in files if x.startswith(t)]
25 25 return l
26 26
27 27 def relpath(repo, args):
28 28 cwd = repo.getcwd()
29 29 if cwd:
30 30 return [util.normpath(os.path.join(cwd, x)) for x in args]
31 31 return args
32 32
33 33 def matchpats(repo, cwd, pats=[], opts={}, head=''):
34 34 return util.matcher(repo.root, cwd, pats or ['.'], opts.get('include'),
35 35 opts.get('exclude'), head)
36 36
37 37 def makewalk(repo, pats, opts, head=''):
38 38 cwd = repo.getcwd()
39 39 files, matchfn, anypats = matchpats(repo, cwd, pats, opts, head)
40 40 exact = dict(zip(files, files))
41 41 def walk():
42 42 for src, fn in repo.walk(files=files, match=matchfn):
43 43 yield src, fn, util.pathto(cwd, fn), fn in exact
44 44 return files, matchfn, walk()
45 45
46 46 def walk(repo, pats, opts, head=''):
47 47 files, matchfn, results = makewalk(repo, pats, opts, head)
48 48 for r in results:
49 49 yield r
50 50
51 51 def walkchangerevs(ui, repo, cwd, pats, opts):
52 52 '''Iterate over files and the revs they changed in.
53 53
54 54 Callers most commonly need to iterate backwards over the history
55 55 it is interested in. Doing so has awful (quadratic-looking)
56 56 performance, so we use iterators in a "windowed" way.
57 57
58 58 We walk a window of revisions in the desired order. Within the
59 59 window, we first walk forwards to gather data, then in the desired
60 60 order (usually backwards) to display it.
61 61
62 62 This function returns an (iterator, getchange) pair. The
63 63 getchange function returns the changelog entry for a numeric
64 64 revision. The iterator yields 3-tuples. They will be of one of
65 65 the following forms:
66 66
67 67 "window", incrementing, lastrev: stepping through a window,
68 68 positive if walking forwards through revs, last rev in the
69 69 sequence iterated over - use to reset state for the current window
70 70
71 71 "add", rev, fns: out-of-order traversal of the given file names
72 72 fns, which changed during revision rev - use to gather data for
73 73 possible display
74 74
75 75 "iter", rev, None: in-order traversal of the revs earlier iterated
76 76 over with "add" - use to display data'''
77 77 cwd = repo.getcwd()
78 78 if not pats and cwd:
79 79 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
80 80 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
81 81 files, matchfn, anypats = matchpats(repo, (pats and cwd) or '',
82 82 pats, opts)
83 83 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
84 84 wanted = {}
85 85 slowpath = anypats
86 86 window = 300
87 87 fncache = {}
88 88
89 89 chcache = {}
90 90 def getchange(rev):
91 91 ch = chcache.get(rev)
92 92 if ch is None:
93 93 chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev)))
94 94 return ch
95 95
96 96 if not slowpath and not files:
97 97 # No files, no patterns. Display all revs.
98 98 wanted = dict(zip(revs, revs))
99 99 if not slowpath:
100 100 # Only files, no patterns. Check the history of each file.
101 101 def filerevgen(filelog):
102 102 for i in xrange(filelog.count() - 1, -1, -window):
103 103 revs = []
104 104 for j in xrange(max(0, i - window), i + 1):
105 105 revs.append(filelog.linkrev(filelog.node(j)))
106 106 revs.reverse()
107 107 for rev in revs:
108 108 yield rev
109 109
110 110 minrev, maxrev = min(revs), max(revs)
111 111 for file in files:
112 112 filelog = repo.file(file)
113 113 # A zero count may be a directory or deleted file, so
114 114 # try to find matching entries on the slow path.
115 115 if filelog.count() == 0:
116 116 slowpath = True
117 117 break
118 118 for rev in filerevgen(filelog):
119 119 if rev <= maxrev:
120 120 if rev < minrev:
121 121 break
122 122 fncache.setdefault(rev, [])
123 123 fncache[rev].append(file)
124 124 wanted[rev] = 1
125 125 if slowpath:
126 126 # The slow path checks files modified in every changeset.
127 127 def changerevgen():
128 128 for i in xrange(repo.changelog.count() - 1, -1, -window):
129 129 for j in xrange(max(0, i - window), i + 1):
130 130 yield j, getchange(j)[3]
131 131
132 132 for rev, changefiles in changerevgen():
133 133 matches = filter(matchfn, changefiles)
134 134 if matches:
135 135 fncache[rev] = matches
136 136 wanted[rev] = 1
137 137
138 138 def iterate():
139 139 for i in xrange(0, len(revs), window):
140 140 yield 'window', revs[0] < revs[-1], revs[-1]
141 141 nrevs = [rev for rev in revs[i:min(i+window, len(revs))]
142 142 if rev in wanted]
143 143 srevs = list(nrevs)
144 144 srevs.sort()
145 145 for rev in srevs:
146 146 fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3])
147 147 yield 'add', rev, fns
148 148 for rev in nrevs:
149 149 yield 'iter', rev, None
150 150 return iterate(), getchange
151 151
152 152 revrangesep = ':'
153 153
154 154 def revrange(ui, repo, revs, revlog=None):
155 155 """Yield revision as strings from a list of revision specifications."""
156 156 if revlog is None:
157 157 revlog = repo.changelog
158 158 revcount = revlog.count()
159 159 def fix(val, defval):
160 160 if not val:
161 161 return defval
162 162 try:
163 163 num = int(val)
164 164 if str(num) != val:
165 165 raise ValueError
166 166 if num < 0:
167 167 num += revcount
168 168 if not (0 <= num < revcount):
169 169 raise ValueError
170 170 except ValueError:
171 171 try:
172 172 num = repo.changelog.rev(repo.lookup(val))
173 173 except KeyError:
174 174 try:
175 175 num = revlog.rev(revlog.lookup(val))
176 176 except KeyError:
177 177 raise util.Abort('invalid revision identifier %s', val)
178 178 return num
179 179 seen = {}
180 180 for spec in revs:
181 181 if spec.find(revrangesep) >= 0:
182 182 start, end = spec.split(revrangesep, 1)
183 183 start = fix(start, 0)
184 184 end = fix(end, revcount - 1)
185 185 step = start > end and -1 or 1
186 186 for rev in xrange(start, end+step, step):
187 187 if rev in seen: continue
188 188 seen[rev] = 1
189 189 yield str(rev)
190 190 else:
191 191 rev = fix(spec, None)
192 192 if rev in seen: continue
193 193 seen[rev] = 1
194 194 yield str(rev)
195 195
196 196 def make_filename(repo, r, pat, node=None,
197 197 total=None, seqno=None, revwidth=None):
198 198 node_expander = {
199 199 'H': lambda: hex(node),
200 200 'R': lambda: str(r.rev(node)),
201 201 'h': lambda: short(node),
202 202 }
203 203 expander = {
204 204 '%': lambda: '%',
205 205 'b': lambda: os.path.basename(repo.root),
206 206 }
207 207
208 208 try:
209 209 if node:
210 210 expander.update(node_expander)
211 211 if node and revwidth is not None:
212 212 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
213 213 if total is not None:
214 214 expander['N'] = lambda: str(total)
215 215 if seqno is not None:
216 216 expander['n'] = lambda: str(seqno)
217 217 if total is not None and seqno is not None:
218 218 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
219 219
220 220 newname = []
221 221 patlen = len(pat)
222 222 i = 0
223 223 while i < patlen:
224 224 c = pat[i]
225 225 if c == '%':
226 226 i += 1
227 227 c = pat[i]
228 228 c = expander[c]()
229 229 newname.append(c)
230 230 i += 1
231 231 return ''.join(newname)
232 232 except KeyError, inst:
233 233 raise util.Abort("invalid format spec '%%%s' in output file name",
234 234 inst.args[0])
235 235
236 236 def make_file(repo, r, pat, node=None,
237 237 total=None, seqno=None, revwidth=None, mode='wb'):
238 238 if not pat or pat == '-':
239 239 return 'w' in mode and sys.stdout or sys.stdin
240 240 if hasattr(pat, 'write') and 'w' in mode:
241 241 return pat
242 242 if hasattr(pat, 'read') and 'r' in mode:
243 243 return pat
244 244 return open(make_filename(repo, r, pat, node, total, seqno, revwidth),
245 245 mode)
246 246
247 247 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
248 248 changes=None, text=False):
249 249 def date(c):
250 250 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
251 251
252 252 if not changes:
253 253 (c, a, d, u) = repo.changes(node1, node2, files, match=match)
254 254 else:
255 255 (c, a, d, u) = changes
256 256 if files:
257 257 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
258 258
259 259 if not c and not a and not d:
260 260 return
261 261
262 262 if node2:
263 263 change = repo.changelog.read(node2)
264 264 mmap2 = repo.manifest.read(change[0])
265 265 date2 = date(change)
266 266 def read(f):
267 267 return repo.file(f).read(mmap2[f])
268 268 else:
269 269 date2 = time.asctime()
270 270 if not node1:
271 271 node1 = repo.dirstate.parents()[0]
272 272 def read(f):
273 273 return repo.wfile(f).read()
274 274
275 275 if ui.quiet:
276 276 r = None
277 277 else:
278 278 hexfunc = ui.verbose and hex or short
279 279 r = [hexfunc(node) for node in [node1, node2] if node]
280 280
281 281 change = repo.changelog.read(node1)
282 282 mmap = repo.manifest.read(change[0])
283 283 date1 = date(change)
284 284
285 285 for f in c:
286 286 to = None
287 287 if f in mmap:
288 288 to = repo.file(f).read(mmap[f])
289 289 tn = read(f)
290 290 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
291 291 for f in a:
292 292 to = None
293 293 tn = read(f)
294 294 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
295 295 for f in d:
296 296 to = repo.file(f).read(mmap[f])
297 297 tn = None
298 298 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
299 299
300 300 def trimuser(ui, name, rev, revcache):
301 301 """trim the name of the user who committed a change"""
302 302 user = revcache.get(rev)
303 303 if user is None:
304 304 user = revcache[rev] = ui.shortuser(name)
305 305 return user
306 306
307 307 def show_changeset(ui, repo, rev=0, changenode=None, brinfo=None):
308 308 """show a single changeset or file revision"""
309 309 log = repo.changelog
310 310 if changenode is None:
311 311 changenode = log.node(rev)
312 312 elif not rev:
313 313 rev = log.rev(changenode)
314 314
315 315 if ui.quiet:
316 316 ui.write("%d:%s\n" % (rev, short(changenode)))
317 317 return
318 318
319 319 changes = log.read(changenode)
320 320
321 321 t, tz = changes[2].split(' ')
322 322 # a conversion tool was sticking non-integer offsets into repos
323 323 try:
324 324 tz = int(tz)
325 325 except ValueError:
326 326 tz = 0
327 327 date = time.asctime(time.localtime(float(t))) + " %+05d" % (int(tz)/-36)
328 328
329 329 parents = [(log.rev(p), ui.verbose and hex(p) or short(p))
330 330 for p in log.parents(changenode)
331 331 if ui.debugflag or p != nullid]
332 332 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
333 333 parents = []
334 334
335 335 if ui.verbose:
336 336 ui.write("changeset: %d:%s\n" % (rev, hex(changenode)))
337 337 else:
338 338 ui.write("changeset: %d:%s\n" % (rev, short(changenode)))
339 339
340 340 for tag in repo.nodetags(changenode):
341 341 ui.status("tag: %s\n" % tag)
342 342 for parent in parents:
343 343 ui.write("parent: %d:%s\n" % parent)
344 344
345 345 if brinfo and changenode in brinfo:
346 346 br = brinfo[changenode]
347 347 ui.write("branch: %s\n" % " ".join(br))
348 348
349 349 ui.debug("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
350 350 hex(changes[0])))
351 351 ui.status("user: %s\n" % changes[1])
352 352 ui.status("date: %s\n" % date)
353 353
354 354 if ui.debugflag:
355 355 files = repo.changes(log.parents(changenode)[0], changenode)
356 356 for key, value in zip(["files:", "files+:", "files-:"], files):
357 357 if value:
358 358 ui.note("%-12s %s\n" % (key, " ".join(value)))
359 359 else:
360 360 ui.note("files: %s\n" % " ".join(changes[3]))
361 361
362 362 description = changes[4].strip()
363 363 if description:
364 364 if ui.verbose:
365 365 ui.status("description:\n")
366 366 ui.status(description)
367 367 ui.status("\n\n")
368 368 else:
369 369 ui.status("summary: %s\n" % description.splitlines()[0])
370 370 ui.status("\n")
371 371
372 372 def show_version(ui):
373 373 """output version and copyright information"""
374 374 ui.write("Mercurial Distributed SCM (version %s)\n"
375 375 % version.get_version())
376 376 ui.status(
377 377 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
378 378 "This is free software; see the source for copying conditions. "
379 379 "There is NO\nwarranty; "
380 380 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
381 381 )
382 382
383 383 def help_(ui, cmd=None, with_version=False):
384 384 """show help for a given command or all commands"""
385 385 option_lists = []
386 386 if cmd and cmd != 'shortlist':
387 387 if with_version:
388 388 show_version(ui)
389 389 ui.write('\n')
390 390 key, i = find(cmd)
391 391 # synopsis
392 392 ui.write("%s\n\n" % i[2])
393 393
394 394 # description
395 395 doc = i[0].__doc__
396 396 if ui.quiet:
397 397 doc = doc.splitlines(0)[0]
398 398 ui.write("%s\n" % doc.rstrip())
399 399
400 400 if not ui.quiet:
401 401 # aliases
402 402 aliases = ', '.join(key.split('|')[1:])
403 403 if aliases:
404 404 ui.write("\naliases: %s\n" % aliases)
405 405
406 406 # options
407 407 if i[1]:
408 408 option_lists.append(("options", i[1]))
409 409
410 410 else:
411 411 # program name
412 412 if ui.verbose or with_version:
413 413 show_version(ui)
414 414 else:
415 415 ui.status("Mercurial Distributed SCM\n")
416 416 ui.status('\n')
417 417
418 418 # list of commands
419 419 if cmd == "shortlist":
420 420 ui.status('basic commands (use "hg help" '
421 421 'for the full list or option "-v" for details):\n\n')
422 422 elif ui.verbose:
423 423 ui.status('list of commands:\n\n')
424 424 else:
425 425 ui.status('list of commands (use "hg help -v" '
426 426 'to show aliases and global options):\n\n')
427 427
428 428 h = {}
429 429 cmds = {}
430 430 for c, e in table.items():
431 431 f = c.split("|")[0]
432 432 if cmd == "shortlist" and not f.startswith("^"):
433 433 continue
434 434 f = f.lstrip("^")
435 435 if not ui.debugflag and f.startswith("debug"):
436 436 continue
437 437 d = ""
438 438 if e[0].__doc__:
439 439 d = e[0].__doc__.splitlines(0)[0].rstrip()
440 440 h[f] = d
441 441 cmds[f]=c.lstrip("^")
442 442
443 443 fns = h.keys()
444 444 fns.sort()
445 445 m = max(map(len, fns))
446 446 for f in fns:
447 447 if ui.verbose:
448 448 commands = cmds[f].replace("|",", ")
449 449 ui.write(" %s:\n %s\n"%(commands,h[f]))
450 450 else:
451 451 ui.write(' %-*s %s\n' % (m, f, h[f]))
452 452
453 453 # global options
454 454 if ui.verbose:
455 455 option_lists.append(("global options", globalopts))
456 456
457 457 # list all option lists
458 458 opt_output = []
459 459 for title, options in option_lists:
460 460 opt_output.append(("\n%s:\n" % title, None))
461 461 for shortopt, longopt, default, desc in options:
462 462 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
463 463 longopt and " --%s" % longopt),
464 464 "%s%s" % (desc,
465 465 default and " (default: %s)" % default
466 466 or "")))
467 467
468 468 if opt_output:
469 469 opts_len = max([len(line[0]) for line in opt_output if line[1]])
470 470 for first, second in opt_output:
471 471 if second:
472 472 ui.write(" %-*s %s\n" % (opts_len, first, second))
473 473 else:
474 474 ui.write("%s\n" % first)
475 475
476 476 # Commands start here, listed alphabetically
477 477
478 478 def add(ui, repo, *pats, **opts):
479 479 '''add the specified files on the next commit'''
480 480 names = []
481 481 for src, abs, rel, exact in walk(repo, pats, opts):
482 482 if exact:
483 483 names.append(abs)
484 484 elif repo.dirstate.state(abs) == '?':
485 485 ui.status('adding %s\n' % rel)
486 486 names.append(abs)
487 487 repo.add(names)
488 488
489 489 def addremove(ui, repo, *pats, **opts):
490 490 """add all new files, delete all missing files"""
491 491 add, remove = [], []
492 492 for src, abs, rel, exact in walk(repo, pats, opts):
493 493 if src == 'f' and repo.dirstate.state(abs) == '?':
494 494 add.append(abs)
495 495 if not exact:
496 496 ui.status('adding ', rel, '\n')
497 497 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
498 498 remove.append(abs)
499 499 if not exact:
500 500 ui.status('removing ', rel, '\n')
501 501 repo.add(add)
502 502 repo.remove(remove)
503 503
504 504 def annotate(ui, repo, *pats, **opts):
505 505 """show changeset information per file line"""
506 506 def getnode(rev):
507 507 return short(repo.changelog.node(rev))
508 508
509 509 ucache = {}
510 510 def getname(rev):
511 511 cl = repo.changelog.read(repo.changelog.node(rev))
512 512 return trimuser(ui, cl[1], rev, ucache)
513 513
514 514 if not pats:
515 515 raise util.Abort('at least one file name or pattern required')
516 516
517 517 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
518 518 if not opts['user'] and not opts['changeset']:
519 519 opts['number'] = 1
520 520
521 521 if opts['rev']:
522 522 node = repo.changelog.lookup(opts['rev'])
523 523 else:
524 524 node = repo.dirstate.parents()[0]
525 525 change = repo.changelog.read(node)
526 526 mmap = repo.manifest.read(change[0])
527 527
528 528 for src, abs, rel, exact in walk(repo, pats, opts):
529 529 if abs not in mmap:
530 530 ui.warn("warning: %s is not in the repository!\n" % rel)
531 531 continue
532 532
533 533 f = repo.file(abs)
534 534 if not opts['text'] and util.binary(f.read(mmap[abs])):
535 535 ui.write("%s: binary file\n" % rel)
536 536 continue
537 537
538 538 lines = f.annotate(mmap[abs])
539 539 pieces = []
540 540
541 541 for o, f in opmap:
542 542 if opts[o]:
543 543 l = [f(n) for n, dummy in lines]
544 544 if l:
545 545 m = max(map(len, l))
546 546 pieces.append(["%*s" % (m, x) for x in l])
547 547
548 548 if pieces:
549 549 for p, l in zip(zip(*pieces), lines):
550 550 ui.write("%s: %s" % (" ".join(p), l[1]))
551 551
552 552 def bundle(ui, repo, fname, dest="default-push", **opts):
553 553 """create a changegroup file"""
554 554 f = open(fname, "wb")
555 555 dest = ui.expandpath(dest)
556 556 other = hg.repository(ui, dest)
557 557 o = repo.findoutgoing(other)
558 558 cg = repo.changegroup(o)
559 559
560 560 try:
561 561 f.write("HG10")
562 562 z = bz2.BZ2Compressor(9)
563 563 while 1:
564 564 chunk = cg.read(4096)
565 565 if not chunk:
566 566 break
567 567 f.write(z.compress(chunk))
568 568 f.write(z.flush())
569 569 except:
570 570 os.unlink(fname)
571 571
572 572 def cat(ui, repo, file1, rev=None, **opts):
573 573 """output the latest or given revision of a file"""
574 574 r = repo.file(relpath(repo, [file1])[0])
575 575 if rev:
576 576 try:
577 577 # assume all revision numbers are for changesets
578 578 n = repo.lookup(rev)
579 579 change = repo.changelog.read(n)
580 580 m = repo.manifest.read(change[0])
581 581 n = m[relpath(repo, [file1])[0]]
582 582 except (hg.RepoError, KeyError):
583 583 try:
584 584 n = r.lookup(rev)
585 585 except KeyError, inst:
586 586 raise util.Abort('cannot find file %s in rev %s', file1, rev)
587 587 else:
588 588 n = r.tip()
589 589 fp = make_file(repo, r, opts['output'], node=n)
590 590 fp.write(r.read(n))
591 591
592 592 def clone(ui, source, dest=None, **opts):
593 593 """make a copy of an existing repository"""
594 594 if dest is None:
595 595 dest = os.path.basename(os.path.normpath(source))
596 596
597 597 if os.path.exists(dest):
598 598 raise util.Abort("destination '%s' already exists", dest)
599 599
600 600 dest = os.path.realpath(dest)
601 601
602 602 class Dircleanup:
603 603 def __init__(self, dir_):
604 604 self.rmtree = shutil.rmtree
605 605 self.dir_ = dir_
606 606 os.mkdir(dir_)
607 607 def close(self):
608 608 self.dir_ = None
609 609 def __del__(self):
610 610 if self.dir_:
611 611 self.rmtree(self.dir_, True)
612 612
613 613 if opts['ssh']:
614 614 ui.setconfig("ui", "ssh", opts['ssh'])
615 615 if opts['remotecmd']:
616 616 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
617 617
618 618 d = Dircleanup(dest)
619 619 if not os.path.exists(source):
620 620 source = ui.expandpath(source)
621 621 abspath = source
622 622 other = hg.repository(ui, source)
623 623
624 624 copy = False
625 625 if other.dev() != -1:
626 626 abspath = os.path.abspath(source)
627 627 copy = True
628 628
629 629 if copy:
630 630 try:
631 631 # we use a lock here because if we race with commit, we
632 632 # can end up with extra data in the cloned revlogs that's
633 633 # not pointed to by changesets, thus causing verify to
634 634 # fail
635 635 l1 = lock.lock(os.path.join(source, ".hg", "lock"))
636 636 except OSError:
637 637 copy = False
638 638
639 639 if copy:
640 640 # we lock here to avoid premature writing to the target
641 641 os.mkdir(os.path.join(dest, ".hg"))
642 642 l2 = lock.lock(os.path.join(dest, ".hg", "lock"))
643 643
644 644 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
645 645 for f in files.split():
646 646 src = os.path.join(source, ".hg", f)
647 647 dst = os.path.join(dest, ".hg", f)
648 648 util.copyfiles(src, dst)
649 649
650 650 repo = hg.repository(ui, dest)
651 651
652 652 else:
653 653 repo = hg.repository(ui, dest, create=1)
654 654 repo.pull(other)
655 655
656 656 f = repo.opener("hgrc", "w")
657 657 f.write("[paths]\n")
658 658 f.write("default = %s\n" % abspath)
659 659
660 660 if not opts['noupdate']:
661 661 update(ui, repo)
662 662
663 663 d.close()
664 664
665 665 def commit(ui, repo, *pats, **opts):
666 666 """commit the specified files or all outstanding changes"""
667 667 if opts['text']:
668 668 ui.warn("Warning: -t and --text is deprecated,"
669 669 " please use -m or --message instead.\n")
670 670 message = opts['message'] or opts['text']
671 671 logfile = opts['logfile']
672 672 if not message and logfile:
673 673 try:
674 674 if logfile == '-':
675 675 message = sys.stdin.read()
676 676 else:
677 677 message = open(logfile).read()
678 678 except IOError, why:
679 679 ui.warn("Can't read commit message %s: %s\n" % (logfile, why))
680 680
681 681 if opts['addremove']:
682 682 addremove(ui, repo, *pats, **opts)
683 683 cwd = repo.getcwd()
684 684 if not pats and cwd:
685 685 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
686 686 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
687 687 fns, match, anypats = matchpats(repo, (pats and repo.getcwd()) or '',
688 688 pats, opts)
689 689 if pats:
690 690 c, a, d, u = repo.changes(files=fns, match=match)
691 691 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
692 692 else:
693 693 files = []
694 694 try:
695 695 repo.commit(files, message, opts['user'], opts['date'], match)
696 696 except ValueError, inst:
697 697 raise util.Abort(str(inst))
698 698
699 def copy(ui, repo, *pats, **opts):
700 """mark files as copied for the next commit"""
699 def docopy(ui, repo, pats, opts):
701 700 if not pats:
702 701 raise util.Abort('no source or destination specified')
703 702 elif len(pats) == 1:
704 703 raise util.Abort('no destination specified')
705 704 pats = list(pats)
706 705 dest = pats.pop()
707 706 sources = []
708 707
709 708 def okaytocopy(abs, rel, exact):
710 709 reasons = {'?': 'is not managed',
711 710 'a': 'has been marked for add'}
712 711 reason = reasons.get(repo.dirstate.state(abs))
713 712 if reason:
714 713 if exact: ui.warn('%s: not copying - file %s\n' % (rel, reason))
715 714 else:
716 715 return True
717 716
718 717 for src, abs, rel, exact in walk(repo, pats, opts):
719 718 if okaytocopy(abs, rel, exact):
720 719 sources.append((abs, rel, exact))
721 720 if not sources:
722 721 raise util.Abort('no files to copy')
723 722
724 723 cwd = repo.getcwd()
725 724 absdest = util.canonpath(repo.root, cwd, dest)
726 725 reldest = util.pathto(cwd, absdest)
727 726 if os.path.exists(reldest):
728 727 destisfile = not os.path.isdir(reldest)
729 728 else:
730 729 destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?'
731 730
732 731 if destisfile:
733 732 if opts['parents']:
734 733 raise util.Abort('with --parents, destination must be a directory')
735 734 elif len(sources) > 1:
736 735 raise util.Abort('with multiple sources, destination must be a '
737 736 'directory')
738 errs = 0
737 errs, copied = 0, []
739 738 for abs, rel, exact in sources:
740 739 if opts['parents']:
741 740 mydest = os.path.join(dest, rel)
742 741 elif destisfile:
743 742 mydest = reldest
744 743 else:
745 744 mydest = os.path.join(dest, os.path.basename(rel))
746 745 myabsdest = util.canonpath(repo.root, cwd, mydest)
747 746 myreldest = util.pathto(cwd, myabsdest)
748 747 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?':
749 748 ui.warn('%s: not overwriting - file already managed\n' % myreldest)
750 749 continue
751 750 mydestdir = os.path.dirname(myreldest) or '.'
752 751 if not opts['after']:
753 752 try:
754 753 if opts['parents']: os.makedirs(mydestdir)
755 754 elif not destisfile: os.mkdir(mydestdir)
756 755 except OSError, inst:
757 756 if inst.errno != errno.EEXIST: raise
758 757 if ui.verbose or not exact:
759 758 ui.status('copying %s to %s\n' % (rel, myreldest))
760 759 if not opts['after']:
761 760 try:
762 761 shutil.copyfile(rel, myreldest)
763 762 n = repo.manifest.tip()
764 763 mf = repo.manifest.readflags(n)
765 764 util.set_exec(myreldest, util.is_exec(rel, mf[abs]))
765 except shutil.Error, inst:
766 raise util.Abort(str(inst))
766 767 except IOError, inst:
767 768 if inst.errno == errno.ENOENT:
768 769 ui.warn('%s: deleted in working copy\n' % rel)
769 770 else:
770 771 ui.warn('%s: cannot copy - %s\n' % (rel, inst.strerror))
771 772 errs += 1
772 773 continue
773 774 repo.copy(abs, myabsdest)
775 copied.append((abs, rel, exact))
774 776 if errs:
775 ui.warn('(consider using --after to record failed copies)\n')
777 ui.warn('(consider using --after)\n')
778 return errs, copied
779
780 def copy(ui, repo, *pats, **opts):
781 """mark files as copied for the next commit"""
782 errs, copied = docopy(ui, repo, pats, opts)
776 783 return errs
777 784
778 785 def debugcheckstate(ui, repo):
779 786 """validate the correctness of the current dirstate"""
780 787 parent1, parent2 = repo.dirstate.parents()
781 788 repo.dirstate.read()
782 789 dc = repo.dirstate.map
783 790 keys = dc.keys()
784 791 keys.sort()
785 792 m1n = repo.changelog.read(parent1)[0]
786 793 m2n = repo.changelog.read(parent2)[0]
787 794 m1 = repo.manifest.read(m1n)
788 795 m2 = repo.manifest.read(m2n)
789 796 errors = 0
790 797 for f in dc:
791 798 state = repo.dirstate.state(f)
792 799 if state in "nr" and f not in m1:
793 800 ui.warn("%s in state %s, but not in manifest1\n" % (f, state))
794 801 errors += 1
795 802 if state in "a" and f in m1:
796 803 ui.warn("%s in state %s, but also in manifest1\n" % (f, state))
797 804 errors += 1
798 805 if state in "m" and f not in m1 and f not in m2:
799 806 ui.warn("%s in state %s, but not in either manifest\n" %
800 807 (f, state))
801 808 errors += 1
802 809 for f in m1:
803 810 state = repo.dirstate.state(f)
804 811 if state not in "nrm":
805 812 ui.warn("%s in manifest1, but listed as state %s" % (f, state))
806 813 errors += 1
807 814 if errors:
808 815 raise util.Abort(".hg/dirstate inconsistent with current parent's manifest")
809 816
810 817 def debugconfig(ui):
811 818 """show combined config settings from all hgrc files"""
812 819 try:
813 820 repo = hg.repository(ui)
814 821 except hg.RepoError:
815 822 pass
816 823 for section, name, value in ui.walkconfig():
817 824 ui.write('%s.%s=%s\n' % (section, name, value))
818 825
819 826 def debugstate(ui, repo):
820 827 """show the contents of the current dirstate"""
821 828 repo.dirstate.read()
822 829 dc = repo.dirstate.map
823 830 keys = dc.keys()
824 831 keys.sort()
825 832 for file_ in keys:
826 833 ui.write("%c %3o %10d %s %s\n"
827 834 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
828 835 time.strftime("%x %X",
829 836 time.localtime(dc[file_][3])), file_))
830 837 for f in repo.dirstate.copies:
831 838 ui.write("copy: %s -> %s\n" % (repo.dirstate.copies[f], f))
832 839
833 840 def debugdata(ui, file_, rev):
834 841 """dump the contents of an data file revision"""
835 842 r = revlog.revlog(file, file_[:-2] + ".i", file_)
836 843 ui.write(r.revision(r.lookup(rev)))
837 844
838 845 def debugindex(ui, file_):
839 846 """dump the contents of an index file"""
840 847 r = revlog.revlog(file, file_, "")
841 848 ui.write(" rev offset length base linkrev" +
842 849 " nodeid p1 p2\n")
843 850 for i in range(r.count()):
844 851 e = r.index[i]
845 852 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
846 853 i, e[0], e[1], e[2], e[3],
847 854 short(e[6]), short(e[4]), short(e[5])))
848 855
849 856 def debugindexdot(ui, file_):
850 857 """dump an index DAG as a .dot file"""
851 858 r = revlog.revlog(file, file_, "")
852 859 ui.write("digraph G {\n")
853 860 for i in range(r.count()):
854 861 e = r.index[i]
855 862 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
856 863 if e[5] != nullid:
857 864 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
858 865 ui.write("}\n")
859 866
860 867 def debugrename(ui, repo, file, rev=None):
861 868 """dump rename information"""
862 869 r = repo.file(relpath(repo, [file])[0])
863 870 if rev:
864 871 try:
865 872 # assume all revision numbers are for changesets
866 873 n = repo.lookup(rev)
867 874 change = repo.changelog.read(n)
868 875 m = repo.manifest.read(change[0])
869 876 n = m[relpath(repo, [file])[0]]
870 877 except hg.RepoError, KeyError:
871 878 n = r.lookup(rev)
872 879 else:
873 880 n = r.tip()
874 881 m = r.renamed(n)
875 882 if m:
876 883 ui.write("renamed from %s:%s\n" % (m[0], hex(m[1])))
877 884 else:
878 885 ui.write("not renamed\n")
879 886
880 887 def debugwalk(ui, repo, *pats, **opts):
881 888 """show how files match on given patterns"""
882 889 items = list(walk(repo, pats, opts))
883 890 if not items:
884 891 return
885 892 fmt = '%%s %%-%ds %%-%ds %%s\n' % (
886 893 max([len(abs) for (src, abs, rel, exact) in items]),
887 894 max([len(rel) for (src, abs, rel, exact) in items]))
888 895 for src, abs, rel, exact in items:
889 896 ui.write(fmt % (src, abs, rel, exact and 'exact' or ''))
890 897
891 898 def diff(ui, repo, *pats, **opts):
892 899 """diff working directory (or selected files)"""
893 900 node1, node2 = None, None
894 901 revs = [repo.lookup(x) for x in opts['rev']]
895 902
896 903 if len(revs) > 0:
897 904 node1 = revs[0]
898 905 if len(revs) > 1:
899 906 node2 = revs[1]
900 907 if len(revs) > 2:
901 908 raise util.Abort("too many revisions to diff")
902 909
903 910 files = []
904 911 match = util.always
905 912 if pats:
906 913 roots, match, results = makewalk(repo, pats, opts)
907 914 for src, abs, rel, exact in results:
908 915 files.append(abs)
909 916
910 917 dodiff(sys.stdout, ui, repo, node1, node2, files, match=match,
911 918 text=opts['text'])
912 919
913 920 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
914 921 node = repo.lookup(changeset)
915 922 prev, other = repo.changelog.parents(node)
916 923 change = repo.changelog.read(node)
917 924
918 925 fp = make_file(repo, repo.changelog, opts['output'],
919 926 node=node, total=total, seqno=seqno,
920 927 revwidth=revwidth)
921 928 if fp != sys.stdout:
922 929 ui.note("%s\n" % fp.name)
923 930
924 931 fp.write("# HG changeset patch\n")
925 932 fp.write("# User %s\n" % change[1])
926 933 fp.write("# Node ID %s\n" % hex(node))
927 934 fp.write("# Parent %s\n" % hex(prev))
928 935 if other != nullid:
929 936 fp.write("# Parent %s\n" % hex(other))
930 937 fp.write(change[4].rstrip())
931 938 fp.write("\n\n")
932 939
933 940 dodiff(fp, ui, repo, prev, node, text=opts['text'])
934 941 if fp != sys.stdout:
935 942 fp.close()
936 943
937 944 def export(ui, repo, *changesets, **opts):
938 945 """dump the header and diffs for one or more changesets"""
939 946 if not changesets:
940 947 raise util.Abort("export requires at least one changeset")
941 948 seqno = 0
942 949 revs = list(revrange(ui, repo, changesets))
943 950 total = len(revs)
944 951 revwidth = max(map(len, revs))
945 952 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
946 953 for cset in revs:
947 954 seqno += 1
948 955 doexport(ui, repo, cset, seqno, total, revwidth, opts)
949 956
950 957 def forget(ui, repo, *pats, **opts):
951 958 """don't add the specified files on the next commit"""
952 959 forget = []
953 960 for src, abs, rel, exact in walk(repo, pats, opts):
954 961 if repo.dirstate.state(abs) == 'a':
955 962 forget.append(abs)
956 963 if not exact:
957 964 ui.status('forgetting ', rel, '\n')
958 965 repo.forget(forget)
959 966
960 967 def grep(ui, repo, pattern, *pats, **opts):
961 968 """search for a pattern in specified files and revisions"""
962 969 reflags = 0
963 970 if opts['ignore_case']:
964 971 reflags |= re.I
965 972 regexp = re.compile(pattern, reflags)
966 973 sep, eol = ':', '\n'
967 974 if opts['print0']:
968 975 sep = eol = '\0'
969 976
970 977 fcache = {}
971 978 def getfile(fn):
972 979 if fn not in fcache:
973 980 fcache[fn] = repo.file(fn)
974 981 return fcache[fn]
975 982
976 983 def matchlines(body):
977 984 begin = 0
978 985 linenum = 0
979 986 while True:
980 987 match = regexp.search(body, begin)
981 988 if not match:
982 989 break
983 990 mstart, mend = match.span()
984 991 linenum += body.count('\n', begin, mstart) + 1
985 992 lstart = body.rfind('\n', begin, mstart) + 1 or begin
986 993 lend = body.find('\n', mend)
987 994 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
988 995 begin = lend + 1
989 996
990 997 class linestate:
991 998 def __init__(self, line, linenum, colstart, colend):
992 999 self.line = line
993 1000 self.linenum = linenum
994 1001 self.colstart = colstart
995 1002 self.colend = colend
996 1003 def __eq__(self, other):
997 1004 return self.line == other.line
998 1005 def __hash__(self):
999 1006 return hash(self.line)
1000 1007
1001 1008 matches = {}
1002 1009 def grepbody(fn, rev, body):
1003 1010 matches[rev].setdefault(fn, {})
1004 1011 m = matches[rev][fn]
1005 1012 for lnum, cstart, cend, line in matchlines(body):
1006 1013 s = linestate(line, lnum, cstart, cend)
1007 1014 m[s] = s
1008 1015
1009 1016 prev = {}
1010 1017 ucache = {}
1011 1018 def display(fn, rev, states, prevstates):
1012 1019 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates)))
1013 1020 diff.sort(lambda x, y: cmp(x.linenum, y.linenum))
1014 1021 counts = {'-': 0, '+': 0}
1015 1022 filerevmatches = {}
1016 1023 for l in diff:
1017 1024 if incrementing or not opts['all']:
1018 1025 change = ((l in prevstates) and '-') or '+'
1019 1026 r = rev
1020 1027 else:
1021 1028 change = ((l in states) and '-') or '+'
1022 1029 r = prev[fn]
1023 1030 cols = [fn, str(rev)]
1024 1031 if opts['line_number']: cols.append(str(l.linenum))
1025 1032 if opts['all']: cols.append(change)
1026 1033 if opts['user']: cols.append(trimuser(ui, getchange(rev)[1], rev,
1027 1034 ucache))
1028 1035 if opts['files_with_matches']:
1029 1036 c = (fn, rev)
1030 1037 if c in filerevmatches: continue
1031 1038 filerevmatches[c] = 1
1032 1039 else:
1033 1040 cols.append(l.line)
1034 1041 ui.write(sep.join(cols), eol)
1035 1042 counts[change] += 1
1036 1043 return counts['+'], counts['-']
1037 1044
1038 1045 fstate = {}
1039 1046 skip = {}
1040 1047 changeiter, getchange = walkchangerevs(ui, repo, repo.getcwd(), pats, opts)
1041 1048 count = 0
1042 1049 for st, rev, fns in changeiter:
1043 1050 if st == 'window':
1044 1051 incrementing = rev
1045 1052 matches.clear()
1046 1053 elif st == 'add':
1047 1054 change = repo.changelog.read(repo.lookup(str(rev)))
1048 1055 mf = repo.manifest.read(change[0])
1049 1056 matches[rev] = {}
1050 1057 for fn in fns:
1051 1058 if fn in skip: continue
1052 1059 fstate.setdefault(fn, {})
1053 1060 try:
1054 1061 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1055 1062 except KeyError:
1056 1063 pass
1057 1064 elif st == 'iter':
1058 1065 states = matches[rev].items()
1059 1066 states.sort()
1060 1067 for fn, m in states:
1061 1068 if fn in skip: continue
1062 1069 if incrementing or not opts['all'] or fstate[fn]:
1063 1070 pos, neg = display(fn, rev, m, fstate[fn])
1064 1071 count += pos + neg
1065 1072 if pos and not opts['all']:
1066 1073 skip[fn] = True
1067 1074 fstate[fn] = m
1068 1075 prev[fn] = rev
1069 1076
1070 1077 if not incrementing:
1071 1078 fstate = fstate.items()
1072 1079 fstate.sort()
1073 1080 for fn, state in fstate:
1074 1081 if fn in skip: continue
1075 1082 display(fn, rev, {}, state)
1076 1083 return (count == 0 and 1) or 0
1077 1084
1078 1085 def heads(ui, repo, **opts):
1079 1086 """show current repository heads"""
1080 1087 heads = repo.changelog.heads()
1081 1088 br = None
1082 1089 if opts['branches']:
1083 1090 br = repo.branchlookup(heads)
1084 1091 for n in repo.changelog.heads():
1085 1092 show_changeset(ui, repo, changenode=n, brinfo=br)
1086 1093
1087 1094 def identify(ui, repo):
1088 1095 """print information about the working copy"""
1089 1096 parents = [p for p in repo.dirstate.parents() if p != nullid]
1090 1097 if not parents:
1091 1098 ui.write("unknown\n")
1092 1099 return
1093 1100
1094 1101 hexfunc = ui.verbose and hex or short
1095 1102 (c, a, d, u) = repo.changes()
1096 1103 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
1097 1104 (c or a or d) and "+" or "")]
1098 1105
1099 1106 if not ui.quiet:
1100 1107 # multiple tags for a single parent separated by '/'
1101 1108 parenttags = ['/'.join(tags)
1102 1109 for tags in map(repo.nodetags, parents) if tags]
1103 1110 # tags for multiple parents separated by ' + '
1104 1111 if parenttags:
1105 1112 output.append(' + '.join(parenttags))
1106 1113
1107 1114 ui.write("%s\n" % ' '.join(output))
1108 1115
1109 1116 def import_(ui, repo, patch1, *patches, **opts):
1110 1117 """import an ordered set of patches"""
1111 1118 patches = (patch1,) + patches
1112 1119
1113 1120 if not opts['force']:
1114 1121 (c, a, d, u) = repo.changes()
1115 1122 if c or a or d:
1116 1123 raise util.Abort("outstanding uncommitted changes")
1117 1124
1118 1125 d = opts["base"]
1119 1126 strip = opts["strip"]
1120 1127
1121 1128 mailre = re.compile(r'(?:From |[\w-]+:)')
1122 1129 diffre = re.compile(r'(?:diff -|--- .*\s+\w+ \w+ +\d+ \d+:\d+:\d+ \d+)')
1123 1130
1124 1131 for patch in patches:
1125 1132 ui.status("applying %s\n" % patch)
1126 1133 pf = os.path.join(d, patch)
1127 1134
1128 1135 message = []
1129 1136 user = None
1130 1137 hgpatch = False
1131 1138 for line in file(pf):
1132 1139 line = line.rstrip()
1133 1140 if (not message and not hgpatch and
1134 1141 mailre.match(line) and not opts['force']):
1135 1142 if len(line) > 35: line = line[:32] + '...'
1136 1143 raise util.Abort('first line looks like a '
1137 1144 'mail header: ' + line)
1138 1145 if diffre.match(line):
1139 1146 break
1140 1147 elif hgpatch:
1141 1148 # parse values when importing the result of an hg export
1142 1149 if line.startswith("# User "):
1143 1150 user = line[7:]
1144 1151 ui.debug('User: %s\n' % user)
1145 1152 elif not line.startswith("# ") and line:
1146 1153 message.append(line)
1147 1154 hgpatch = False
1148 1155 elif line == '# HG changeset patch':
1149 1156 hgpatch = True
1150 1157 message = [] # We may have collected garbage
1151 1158 else:
1152 1159 message.append(line)
1153 1160
1154 1161 # make sure message isn't empty
1155 1162 if not message:
1156 1163 message = "imported patch %s\n" % patch
1157 1164 else:
1158 1165 message = "%s\n" % '\n'.join(message)
1159 1166 ui.debug('message:\n%s\n' % message)
1160 1167
1161 1168 f = os.popen("patch -p%d < '%s'" % (strip, pf))
1162 1169 files = []
1163 1170 for l in f.read().splitlines():
1164 1171 l.rstrip('\r\n');
1165 1172 ui.status("%s\n" % l)
1166 1173 if l.startswith('patching file '):
1167 1174 pf = l[14:]
1168 1175 if pf not in files:
1169 1176 files.append(pf)
1170 1177 patcherr = f.close()
1171 1178 if patcherr:
1172 1179 raise util.Abort("patch failed")
1173 1180
1174 1181 if len(files) > 0:
1175 1182 addremove(ui, repo, *files)
1176 1183 repo.commit(files, message, user)
1177 1184
1178 1185 def incoming(ui, repo, source="default", **opts):
1179 1186 """show new changesets found in source"""
1180 1187 source = ui.expandpath(source)
1181 1188 other = hg.repository(ui, source)
1182 1189 if not other.local():
1183 1190 raise util.Abort("incoming doesn't work for remote repositories yet")
1184 1191 o = repo.findincoming(other)
1185 1192 if not o:
1186 1193 return
1187 1194 o = other.newer(o)
1188 1195 o.reverse()
1189 1196 for n in o:
1190 1197 show_changeset(ui, other, changenode=n)
1191 1198 if opts['patch']:
1192 1199 prev = other.changelog.parents(n)[0]
1193 1200 dodiff(ui, ui, other, prev, n)
1194 1201 ui.write("\n")
1195 1202
1196 1203 def init(ui, dest="."):
1197 1204 """create a new repository in the given directory"""
1198 1205 if not os.path.exists(dest):
1199 1206 os.mkdir(dest)
1200 1207 hg.repository(ui, dest, create=1)
1201 1208
1202 1209 def locate(ui, repo, *pats, **opts):
1203 1210 """locate files matching specific patterns"""
1204 1211 end = opts['print0'] and '\0' or '\n'
1205 1212
1206 1213 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
1207 1214 if repo.dirstate.state(abs) == '?':
1208 1215 continue
1209 1216 if opts['fullpath']:
1210 1217 ui.write(os.path.join(repo.root, abs), end)
1211 1218 else:
1212 1219 ui.write(rel, end)
1213 1220
1214 1221 def log(ui, repo, *pats, **opts):
1215 1222 """show revision history of entire repository or files"""
1216 1223 class dui:
1217 1224 # Implement and delegate some ui protocol. Save hunks of
1218 1225 # output for later display in the desired order.
1219 1226 def __init__(self, ui):
1220 1227 self.ui = ui
1221 1228 self.hunk = {}
1222 1229 def bump(self, rev):
1223 1230 self.rev = rev
1224 1231 self.hunk[rev] = []
1225 1232 def note(self, *args):
1226 1233 if self.verbose:
1227 1234 self.write(*args)
1228 1235 def status(self, *args):
1229 1236 if not self.quiet:
1230 1237 self.write(*args)
1231 1238 def write(self, *args):
1232 1239 self.hunk[self.rev].append(args)
1233 1240 def __getattr__(self, key):
1234 1241 return getattr(self.ui, key)
1235 1242 cwd = repo.getcwd()
1236 1243 if not pats and cwd:
1237 1244 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
1238 1245 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
1239 1246 changeiter, getchange = walkchangerevs(ui, repo, (pats and cwd) or '',
1240 1247 pats, opts)
1241 1248 for st, rev, fns in changeiter:
1242 1249 if st == 'window':
1243 1250 du = dui(ui)
1244 1251 elif st == 'add':
1245 1252 du.bump(rev)
1246 1253 br = None
1247 1254 if opts['branch']:
1248 1255 br = repo.branchlookup([repo.changelog.node(rev)])
1249 1256 show_changeset(du, repo, rev, brinfo=br)
1250 1257 if opts['patch']:
1251 1258 changenode = repo.changelog.node(rev)
1252 1259 prev, other = repo.changelog.parents(changenode)
1253 1260 dodiff(du, du, repo, prev, changenode, fns)
1254 1261 du.write("\n\n")
1255 1262 elif st == 'iter':
1256 1263 for args in du.hunk[rev]:
1257 1264 ui.write(*args)
1258 1265
1259 1266 def manifest(ui, repo, rev=None):
1260 1267 """output the latest or given revision of the project manifest"""
1261 1268 if rev:
1262 1269 try:
1263 1270 # assume all revision numbers are for changesets
1264 1271 n = repo.lookup(rev)
1265 1272 change = repo.changelog.read(n)
1266 1273 n = change[0]
1267 1274 except hg.RepoError:
1268 1275 n = repo.manifest.lookup(rev)
1269 1276 else:
1270 1277 n = repo.manifest.tip()
1271 1278 m = repo.manifest.read(n)
1272 1279 mf = repo.manifest.readflags(n)
1273 1280 files = m.keys()
1274 1281 files.sort()
1275 1282
1276 1283 for f in files:
1277 1284 ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
1278 1285
1279 1286 def outgoing(ui, repo, dest="default-push", **opts):
1280 1287 """show changesets not found in destination"""
1281 1288 dest = ui.expandpath(dest)
1282 1289 other = hg.repository(ui, dest)
1283 1290 o = repo.findoutgoing(other)
1284 1291 o = repo.newer(o)
1285 1292 o.reverse()
1286 1293 for n in o:
1287 1294 show_changeset(ui, repo, changenode=n)
1288 1295 if opts['patch']:
1289 1296 prev = repo.changelog.parents(n)[0]
1290 1297 dodiff(ui, ui, repo, prev, n)
1291 1298 ui.write("\n")
1292 1299
1293 1300 def parents(ui, repo, rev=None):
1294 1301 """show the parents of the working dir or revision"""
1295 1302 if rev:
1296 1303 p = repo.changelog.parents(repo.lookup(rev))
1297 1304 else:
1298 1305 p = repo.dirstate.parents()
1299 1306
1300 1307 for n in p:
1301 1308 if n != nullid:
1302 1309 show_changeset(ui, repo, changenode=n)
1303 1310
1304 1311 def paths(ui, search=None):
1305 1312 """show definition of symbolic path names"""
1306 1313 try:
1307 1314 repo = hg.repository(ui=ui)
1308 1315 except hg.RepoError:
1309 1316 pass
1310 1317
1311 1318 if search:
1312 1319 for name, path in ui.configitems("paths"):
1313 1320 if name == search:
1314 1321 ui.write("%s\n" % path)
1315 1322 return
1316 1323 ui.warn("not found!\n")
1317 1324 return 1
1318 1325 else:
1319 1326 for name, path in ui.configitems("paths"):
1320 1327 ui.write("%s = %s\n" % (name, path))
1321 1328
1322 1329 def pull(ui, repo, source="default", **opts):
1323 1330 """pull changes from the specified source"""
1324 1331 source = ui.expandpath(source)
1325 1332 ui.status('pulling from %s\n' % (source))
1326 1333
1327 1334 if opts['ssh']:
1328 1335 ui.setconfig("ui", "ssh", opts['ssh'])
1329 1336 if opts['remotecmd']:
1330 1337 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
1331 1338
1332 1339 other = hg.repository(ui, source)
1333 1340 r = repo.pull(other)
1334 1341 if not r:
1335 1342 if opts['update']:
1336 1343 return update(ui, repo)
1337 1344 else:
1338 1345 ui.status("(run 'hg update' to get a working copy)\n")
1339 1346
1340 1347 return r
1341 1348
1342 1349 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1343 1350 """push changes to the specified destination"""
1344 1351 dest = ui.expandpath(dest)
1345 1352 ui.status('pushing to %s\n' % (dest))
1346 1353
1347 1354 if ssh:
1348 1355 ui.setconfig("ui", "ssh", ssh)
1349 1356 if remotecmd:
1350 1357 ui.setconfig("ui", "remotecmd", remotecmd)
1351 1358
1352 1359 other = hg.repository(ui, dest)
1353 1360 r = repo.push(other, force)
1354 1361 return r
1355 1362
1356 1363 def rawcommit(ui, repo, *flist, **rc):
1357 1364 "raw commit interface"
1358 1365 if rc['text']:
1359 1366 ui.warn("Warning: -t and --text is deprecated,"
1360 1367 " please use -m or --message instead.\n")
1361 1368 message = rc['message'] or rc['text']
1362 1369 if not message and rc['logfile']:
1363 1370 try:
1364 1371 message = open(rc['logfile']).read()
1365 1372 except IOError:
1366 1373 pass
1367 1374 if not message and not rc['logfile']:
1368 1375 raise util.Abort("missing commit message")
1369 1376
1370 1377 files = relpath(repo, list(flist))
1371 1378 if rc['files']:
1372 1379 files += open(rc['files']).read().splitlines()
1373 1380
1374 1381 rc['parent'] = map(repo.lookup, rc['parent'])
1375 1382
1376 1383 try:
1377 1384 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1378 1385 except ValueError, inst:
1379 1386 raise util.Abort(str(inst))
1380 1387
1381 1388 def recover(ui, repo):
1382 1389 """roll back an interrupted transaction"""
1383 1390 repo.recover()
1384 1391
1385 1392 def remove(ui, repo, pat, *pats, **opts):
1386 1393 """remove the specified files on the next commit"""
1387 1394 names = []
1388 1395 def okaytoremove(abs, rel, exact):
1389 1396 c, a, d, u = repo.changes(files = [abs])
1390 1397 reason = None
1391 1398 if c: reason = 'is modified'
1392 1399 elif a: reason = 'has been marked for add'
1393 elif u: reason = 'not managed'
1400 elif u: reason = 'is not managed'
1394 1401 if reason and exact:
1395 1402 ui.warn('not removing %s: file %s\n' % (rel, reason))
1396 1403 else:
1397 1404 return True
1398 1405 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts):
1399 1406 if okaytoremove(abs, rel, exact):
1400 if not exact: ui.status('removing %s\n' % rel)
1407 if ui.verbose or not exact: ui.status('removing %s\n' % rel)
1401 1408 names.append(abs)
1402 1409 for name in names:
1403 1410 try:
1404 1411 os.unlink(name)
1405 1412 except OSError, inst:
1406 1413 if inst.errno != errno.ENOENT: raise
1407 1414 repo.remove(names)
1408 1415
1416 def rename(ui, repo, *pats, **opts):
1417 """rename files; equivalent of copy + remove"""
1418 errs, copied = docopy(ui, repo, pats, opts)
1419 names = []
1420 for abs, rel, exact in copied:
1421 if ui.verbose or not exact: ui.status('removing %s\n' % rel)
1422 try:
1423 os.unlink(rel)
1424 except OSError, inst:
1425 if inst.errno != errno.ENOENT: raise
1426 names.append(abs)
1427 repo.remove(names)
1428 return errs
1429
1409 1430 def revert(ui, repo, *names, **opts):
1410 1431 """revert modified files or dirs back to their unmodified states"""
1411 1432 node = opts['rev'] and repo.lookup(opts['rev']) or \
1412 1433 repo.dirstate.parents()[0]
1413 1434 root = os.path.realpath(repo.root)
1414 1435
1415 1436 def trimpath(p):
1416 1437 p = os.path.realpath(p)
1417 1438 if p.startswith(root):
1418 1439 rest = p[len(root):]
1419 1440 if not rest:
1420 1441 return rest
1421 1442 if p.startswith(os.sep):
1422 1443 return rest[1:]
1423 1444 return p
1424 1445
1425 1446 relnames = map(trimpath, names or [os.getcwd()])
1426 1447 chosen = {}
1427 1448
1428 1449 def choose(name):
1429 1450 def body(name):
1430 1451 for r in relnames:
1431 1452 if not name.startswith(r):
1432 1453 continue
1433 1454 rest = name[len(r):]
1434 1455 if not rest:
1435 1456 return r, True
1436 1457 depth = rest.count(os.sep)
1437 1458 if not r:
1438 1459 if depth == 0 or not opts['nonrecursive']:
1439 1460 return r, True
1440 1461 elif rest[0] == os.sep:
1441 1462 if depth == 1 or not opts['nonrecursive']:
1442 1463 return r, True
1443 1464 return None, False
1444 1465 relname, ret = body(name)
1445 1466 if ret:
1446 1467 chosen[relname] = 1
1447 1468 return ret
1448 1469
1449 1470 r = repo.update(node, False, True, choose, False)
1450 1471 for n in relnames:
1451 1472 if n not in chosen:
1452 1473 ui.warn('error: no matches for %s\n' % n)
1453 1474 r = 1
1454 1475 sys.stdout.flush()
1455 1476 return r
1456 1477
1457 1478 def root(ui, repo):
1458 1479 """print the root (top) of the current working dir"""
1459 1480 ui.write(repo.root + "\n")
1460 1481
1461 1482 def serve(ui, repo, **opts):
1462 1483 """export the repository via HTTP"""
1463 1484
1464 1485 if opts["stdio"]:
1465 1486 fin, fout = sys.stdin, sys.stdout
1466 1487 sys.stdout = sys.stderr
1467 1488
1468 1489 def getarg():
1469 1490 argline = fin.readline()[:-1]
1470 1491 arg, l = argline.split()
1471 1492 val = fin.read(int(l))
1472 1493 return arg, val
1473 1494 def respond(v):
1474 1495 fout.write("%d\n" % len(v))
1475 1496 fout.write(v)
1476 1497 fout.flush()
1477 1498
1478 1499 lock = None
1479 1500
1480 1501 while 1:
1481 1502 cmd = fin.readline()[:-1]
1482 1503 if cmd == '':
1483 1504 return
1484 1505 if cmd == "heads":
1485 1506 h = repo.heads()
1486 1507 respond(" ".join(map(hex, h)) + "\n")
1487 1508 if cmd == "lock":
1488 1509 lock = repo.lock()
1489 1510 respond("")
1490 1511 if cmd == "unlock":
1491 1512 if lock:
1492 1513 lock.release()
1493 1514 lock = None
1494 1515 respond("")
1495 1516 elif cmd == "branches":
1496 1517 arg, nodes = getarg()
1497 1518 nodes = map(bin, nodes.split(" "))
1498 1519 r = []
1499 1520 for b in repo.branches(nodes):
1500 1521 r.append(" ".join(map(hex, b)) + "\n")
1501 1522 respond("".join(r))
1502 1523 elif cmd == "between":
1503 1524 arg, pairs = getarg()
1504 1525 pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
1505 1526 r = []
1506 1527 for b in repo.between(pairs):
1507 1528 r.append(" ".join(map(hex, b)) + "\n")
1508 1529 respond("".join(r))
1509 1530 elif cmd == "changegroup":
1510 1531 nodes = []
1511 1532 arg, roots = getarg()
1512 1533 nodes = map(bin, roots.split(" "))
1513 1534
1514 1535 cg = repo.changegroup(nodes)
1515 1536 while 1:
1516 1537 d = cg.read(4096)
1517 1538 if not d:
1518 1539 break
1519 1540 fout.write(d)
1520 1541
1521 1542 fout.flush()
1522 1543
1523 1544 elif cmd == "addchangegroup":
1524 1545 if not lock:
1525 1546 respond("not locked")
1526 1547 continue
1527 1548 respond("")
1528 1549
1529 1550 r = repo.addchangegroup(fin)
1530 1551 respond("")
1531 1552
1532 1553 optlist = "name templates style address port ipv6 accesslog errorlog"
1533 1554 for o in optlist.split():
1534 1555 if opts[o]:
1535 1556 ui.setconfig("web", o, opts[o])
1536 1557
1537 1558 try:
1538 1559 httpd = hgweb.create_server(repo)
1539 1560 except socket.error, inst:
1540 1561 raise util.Abort('cannot start server: ' + inst.args[1])
1541 1562
1542 1563 if ui.verbose:
1543 1564 addr, port = httpd.socket.getsockname()
1544 1565 if addr == '0.0.0.0':
1545 1566 addr = socket.gethostname()
1546 1567 else:
1547 1568 try:
1548 1569 addr = socket.gethostbyaddr(addr)[0]
1549 1570 except socket.error:
1550 1571 pass
1551 1572 if port != 80:
1552 1573 ui.status('listening at http://%s:%d/\n' % (addr, port))
1553 1574 else:
1554 1575 ui.status('listening at http://%s/\n' % addr)
1555 1576 httpd.serve_forever()
1556 1577
1557 1578 def status(ui, repo, *pats, **opts):
1558 1579 '''show changed files in the working directory
1559 1580
1560 1581 M = modified
1561 1582 A = added
1562 1583 R = removed
1563 1584 ? = not tracked
1564 1585 '''
1565 1586
1566 1587 cwd = repo.getcwd()
1567 1588 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1568 1589 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1569 1590 for n in repo.changes(files=files, match=matchfn)]
1570 1591
1571 1592 changetypes = [('modified', 'M', c),
1572 1593 ('added', 'A', a),
1573 1594 ('removed', 'R', d),
1574 1595 ('unknown', '?', u)]
1575 1596
1576 1597 end = opts['print0'] and '\0' or '\n'
1577 1598
1578 1599 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1579 1600 or changetypes):
1580 1601 if opts['no_status']:
1581 1602 format = "%%s%s" % end
1582 1603 else:
1583 1604 format = "%s %%s%s" % (char, end);
1584 1605
1585 1606 for f in changes:
1586 1607 ui.write(format % f)
1587 1608
1588 1609 def tag(ui, repo, name, rev=None, **opts):
1589 1610 """add a tag for the current tip or a given revision"""
1590 1611 if opts['text']:
1591 1612 ui.warn("Warning: -t and --text is deprecated,"
1592 1613 " please use -m or --message instead.\n")
1593 1614 if name == "tip":
1594 1615 raise util.Abort("the name 'tip' is reserved")
1595 1616 if rev:
1596 1617 r = hex(repo.lookup(rev))
1597 1618 else:
1598 1619 r = hex(repo.changelog.tip())
1599 1620
1600 1621 if name.find(revrangesep) >= 0:
1601 1622 raise util.Abort("'%s' cannot be used in a tag name" % revrangesep)
1602 1623
1603 1624 if opts['local']:
1604 1625 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1605 1626 return
1606 1627
1607 1628 (c, a, d, u) = repo.changes()
1608 1629 for x in (c, a, d, u):
1609 1630 if ".hgtags" in x:
1610 1631 raise util.Abort("working copy of .hgtags is changed "
1611 1632 "(please commit .hgtags manually)")
1612 1633
1613 1634 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
1614 1635 if repo.dirstate.state(".hgtags") == '?':
1615 1636 repo.add([".hgtags"])
1616 1637
1617 1638 message = (opts['message'] or opts['text'] or
1618 1639 "Added tag %s for changeset %s" % (name, r))
1619 1640 try:
1620 1641 repo.commit([".hgtags"], message, opts['user'], opts['date'])
1621 1642 except ValueError, inst:
1622 1643 raise util.Abort(str(inst))
1623 1644
1624 1645 def tags(ui, repo):
1625 1646 """list repository tags"""
1626 1647
1627 1648 l = repo.tagslist()
1628 1649 l.reverse()
1629 1650 for t, n in l:
1630 1651 try:
1631 1652 r = "%5d:%s" % (repo.changelog.rev(n), hex(n))
1632 1653 except KeyError:
1633 1654 r = " ?:?"
1634 1655 ui.write("%-30s %s\n" % (t, r))
1635 1656
1636 1657 def tip(ui, repo):
1637 1658 """show the tip revision"""
1638 1659 n = repo.changelog.tip()
1639 1660 show_changeset(ui, repo, changenode=n)
1640 1661
1641 1662 def unbundle(ui, repo, fname):
1642 1663 """apply a changegroup file"""
1643 1664 f = urllib.urlopen(fname)
1644 1665
1645 1666 if f.read(4) != "HG10":
1646 1667 raise util.Abort("%s: not a Mercurial bundle file" % fname)
1647 1668
1648 1669 class bzread:
1649 1670 def __init__(self, f):
1650 1671 self.zd = bz2.BZ2Decompressor()
1651 1672 self.f = f
1652 1673 self.buf = ""
1653 1674 def read(self, l):
1654 1675 while l > len(self.buf):
1655 1676 r = self.f.read(4096)
1656 1677 if r:
1657 1678 self.buf += self.zd.decompress(r)
1658 1679 else:
1659 1680 break
1660 1681 d, self.buf = self.buf[:l], self.buf[l:]
1661 1682 return d
1662 1683
1663 1684 repo.addchangegroup(bzread(f))
1664 1685
1665 1686 def undo(ui, repo):
1666 1687 """undo the last commit or pull
1667 1688
1668 1689 Roll back the last pull or commit transaction on the
1669 1690 repository, restoring the project to its earlier state.
1670 1691
1671 1692 This command should be used with care. There is only one level of
1672 1693 undo and there is no redo.
1673 1694
1674 1695 This command is not intended for use on public repositories. Once
1675 1696 a change is visible for pull by other users, undoing it locally is
1676 1697 ineffective.
1677 1698 """
1678 1699 repo.undo()
1679 1700
1680 1701 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
1681 1702 '''update or merge working directory
1682 1703
1683 1704 If there are no outstanding changes in the working directory and
1684 1705 there is a linear relationship between the current version and the
1685 1706 requested version, the result is the requested version.
1686 1707
1687 1708 Otherwise the result is a merge between the contents of the
1688 1709 current working directory and the requested version. Files that
1689 1710 changed between either parent are marked as changed for the next
1690 1711 commit and a commit must be performed before any further updates
1691 1712 are allowed.
1692 1713 '''
1693 1714 if branch:
1694 1715 br = repo.branchlookup(branch=branch)
1695 1716 found = []
1696 1717 for x in br:
1697 1718 if branch in br[x]:
1698 1719 found.append(x)
1699 1720 if len(found) > 1:
1700 1721 ui.warn("Found multiple heads for %s\n" % branch)
1701 1722 for x in found:
1702 1723 show_changeset(ui, repo, changenode=x, brinfo=br)
1703 1724 return 1
1704 1725 if len(found) == 1:
1705 1726 node = found[0]
1706 1727 ui.warn("Using head %s for branch %s\n" % (short(node), branch))
1707 1728 else:
1708 1729 ui.warn("branch %s not found\n" % (branch))
1709 1730 return 1
1710 1731 else:
1711 1732 node = node and repo.lookup(node) or repo.changelog.tip()
1712 1733 return repo.update(node, allow=merge, force=clean)
1713 1734
1714 1735 def verify(ui, repo):
1715 1736 """verify the integrity of the repository"""
1716 1737 return repo.verify()
1717 1738
1718 1739 # Command options and aliases are listed here, alphabetically
1719 1740
1720 1741 table = {
1721 1742 "^add":
1722 1743 (add,
1723 1744 [('I', 'include', [], 'include path in search'),
1724 1745 ('X', 'exclude', [], 'exclude path from search')],
1725 1746 "hg add [OPTION]... [FILE]..."),
1726 1747 "addremove":
1727 1748 (addremove,
1728 1749 [('I', 'include', [], 'include path in search'),
1729 1750 ('X', 'exclude', [], 'exclude path from search')],
1730 1751 "hg addremove [OPTION]... [FILE]..."),
1731 1752 "^annotate":
1732 1753 (annotate,
1733 1754 [('r', 'rev', '', 'revision'),
1734 1755 ('a', 'text', None, 'treat all files as text'),
1735 1756 ('u', 'user', None, 'show user'),
1736 1757 ('n', 'number', None, 'show revision number'),
1737 1758 ('c', 'changeset', None, 'show changeset'),
1738 1759 ('I', 'include', [], 'include path in search'),
1739 1760 ('X', 'exclude', [], 'exclude path from search')],
1740 1761 'hg annotate [OPTION]... FILE...'),
1741 1762 "bundle":
1742 1763 (bundle,
1743 1764 [],
1744 1765 'hg bundle FILE DEST'),
1745 1766 "cat":
1746 1767 (cat,
1747 1768 [('o', 'output', "", 'output to file')],
1748 1769 'hg cat [-o OUTFILE] FILE [REV]'),
1749 1770 "^clone":
1750 1771 (clone,
1751 1772 [('U', 'noupdate', None, 'skip update after cloning'),
1752 1773 ('e', 'ssh', "", 'ssh command'),
1753 1774 ('', 'remotecmd', "", 'remote hg command')],
1754 1775 'hg clone [OPTION]... SOURCE [DEST]'),
1755 1776 "^commit|ci":
1756 1777 (commit,
1757 1778 [('A', 'addremove', None, 'run add/remove during commit'),
1758 1779 ('I', 'include', [], 'include path in search'),
1759 1780 ('X', 'exclude', [], 'exclude path from search'),
1760 1781 ('m', 'message', "", 'commit message'),
1761 1782 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1762 1783 ('l', 'logfile', "", 'commit message file'),
1763 1784 ('d', 'date', "", 'date code'),
1764 1785 ('u', 'user', "", 'user')],
1765 1786 'hg commit [OPTION]... [FILE]...'),
1766 1787 "copy|cp": (copy,
1767 1788 [('I', 'include', [], 'include path in search'),
1768 1789 ('X', 'exclude', [], 'exclude path from search'),
1769 1790 ('A', 'after', None, 'record a copy after it has happened'),
1770 1791 ('f', 'force', None, 'replace destination if it exists'),
1771 1792 ('p', 'parents', None, 'append source path to dest')],
1772 1793 'hg copy [OPTION]... [SOURCE]... DEST'),
1773 1794 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1774 1795 "debugconfig": (debugconfig, [], 'debugconfig'),
1775 1796 "debugstate": (debugstate, [], 'debugstate'),
1776 1797 "debugdata": (debugdata, [], 'debugdata FILE REV'),
1777 1798 "debugindex": (debugindex, [], 'debugindex FILE'),
1778 1799 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1779 1800 "debugrename": (debugrename, [], 'debugrename FILE [REV]'),
1780 1801 "debugwalk":
1781 1802 (debugwalk,
1782 1803 [('I', 'include', [], 'include path in search'),
1783 1804 ('X', 'exclude', [], 'exclude path from search')],
1784 1805 'debugwalk [OPTION]... [FILE]...'),
1785 1806 "^diff":
1786 1807 (diff,
1787 1808 [('r', 'rev', [], 'revision'),
1788 1809 ('a', 'text', None, 'treat all files as text'),
1789 1810 ('I', 'include', [], 'include path in search'),
1790 1811 ('X', 'exclude', [], 'exclude path from search')],
1791 1812 'hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...'),
1792 1813 "^export":
1793 1814 (export,
1794 1815 [('o', 'output', "", 'output to file'),
1795 1816 ('a', 'text', None, 'treat all files as text')],
1796 1817 "hg export [-a] [-o OUTFILE] REV..."),
1797 1818 "forget":
1798 1819 (forget,
1799 1820 [('I', 'include', [], 'include path in search'),
1800 1821 ('X', 'exclude', [], 'exclude path from search')],
1801 1822 "hg forget [OPTION]... FILE..."),
1802 1823 "grep":
1803 1824 (grep,
1804 1825 [('0', 'print0', None, 'end fields with NUL'),
1805 1826 ('I', 'include', [], 'include path in search'),
1806 1827 ('X', 'exclude', [], 'include path in search'),
1807 1828 ('', 'all', None, 'print all revisions with matches'),
1808 1829 ('i', 'ignore-case', None, 'ignore case when matching'),
1809 1830 ('l', 'files-with-matches', None, 'print names of files and revs with matches'),
1810 1831 ('n', 'line-number', None, 'print line numbers'),
1811 1832 ('r', 'rev', [], 'search in revision rev'),
1812 1833 ('u', 'user', None, 'print user who made change')],
1813 1834 "hg grep [OPTION]... PATTERN [FILE]..."),
1814 1835 "heads":
1815 1836 (heads,
1816 1837 [('b', 'branches', None, 'find branch info')],
1817 1838 'hg heads [-b]'),
1818 1839 "help": (help_, [], 'hg help [COMMAND]'),
1819 1840 "identify|id": (identify, [], 'hg identify'),
1820 1841 "import|patch":
1821 1842 (import_,
1822 1843 [('p', 'strip', 1, 'path strip'),
1823 1844 ('f', 'force', None, 'skip check for outstanding changes'),
1824 1845 ('b', 'base', "", 'base path')],
1825 1846 "hg import [-f] [-p NUM] [-b BASE] PATCH..."),
1826 "incoming|in": (incoming,
1847 "incoming|in": (incoming,
1827 1848 [('p', 'patch', None, 'show patch')],
1828 1849 'hg incoming [-p] [SOURCE]'),
1829 1850 "^init": (init, [], 'hg init [DEST]'),
1830 1851 "locate":
1831 1852 (locate,
1832 1853 [('r', 'rev', '', 'revision'),
1833 1854 ('0', 'print0', None, 'end filenames with NUL'),
1834 1855 ('f', 'fullpath', None, 'print complete paths'),
1835 1856 ('I', 'include', [], 'include path in search'),
1836 1857 ('X', 'exclude', [], 'exclude path from search')],
1837 1858 'hg locate [OPTION]... [PATTERN]...'),
1838 1859 "^log|history":
1839 1860 (log,
1840 1861 [('I', 'include', [], 'include path in search'),
1841 1862 ('X', 'exclude', [], 'exclude path from search'),
1842 1863 ('b', 'branch', None, 'show branches'),
1843 1864 ('r', 'rev', [], 'revision'),
1844 1865 ('p', 'patch', None, 'show patch')],
1845 1866 'hg log [-I] [-X] [-r REV]... [-p] [FILE]'),
1846 1867 "manifest": (manifest, [], 'hg manifest [REV]'),
1847 "outgoing|out": (outgoing,
1868 "outgoing|out": (outgoing,
1848 1869 [('p', 'patch', None, 'show patch')],
1849 1870 'hg outgoing [-p] [DEST]'),
1850 1871 "parents": (parents, [], 'hg parents [REV]'),
1851 1872 "paths": (paths, [], 'hg paths [NAME]'),
1852 1873 "^pull":
1853 1874 (pull,
1854 1875 [('u', 'update', None, 'update working directory'),
1855 1876 ('e', 'ssh', "", 'ssh command'),
1856 1877 ('', 'remotecmd', "", 'remote hg command')],
1857 1878 'hg pull [-u] [-e FILE] [--remotecmd FILE] [SOURCE]'),
1858 1879 "^push":
1859 1880 (push,
1860 1881 [('f', 'force', None, 'force push'),
1861 1882 ('e', 'ssh', "", 'ssh command'),
1862 1883 ('', 'remotecmd', "", 'remote hg command')],
1863 1884 'hg push [-f] [-e FILE] [--remotecmd FILE] [DEST]'),
1864 1885 "rawcommit":
1865 1886 (rawcommit,
1866 1887 [('p', 'parent', [], 'parent'),
1867 1888 ('d', 'date', "", 'date code'),
1868 1889 ('u', 'user', "", 'user'),
1869 1890 ('F', 'files', "", 'file list'),
1870 1891 ('m', 'message', "", 'commit message'),
1871 1892 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1872 1893 ('l', 'logfile', "", 'commit message file')],
1873 1894 'hg rawcommit [OPTION]... [FILE]...'),
1874 1895 "recover": (recover, [], "hg recover"),
1875 1896 "^remove|rm": (remove,
1876 1897 [('I', 'include', [], 'include path in search'),
1877 1898 ('X', 'exclude', [], 'exclude path from search')],
1878 1899 "hg remove [OPTION]... FILE..."),
1900 "rename|mv": (rename,
1901 [('I', 'include', [], 'include path in search'),
1902 ('X', 'exclude', [], 'exclude path from search'),
1903 ('A', 'after', None, 'record a copy after it has happened'),
1904 ('f', 'force', None, 'replace destination if it exists'),
1905 ('p', 'parents', None, 'append source path to dest')],
1906 'hg rename [OPTION]... [SOURCE]... DEST'),
1879 1907 "^revert":
1880 1908 (revert,
1881 1909 [("n", "nonrecursive", None, "don't recurse into subdirs"),
1882 1910 ("r", "rev", "", "revision")],
1883 1911 "hg revert [-n] [-r REV] [NAME]..."),
1884 1912 "root": (root, [], "hg root"),
1885 1913 "^serve":
1886 1914 (serve,
1887 1915 [('A', 'accesslog', '', 'access log file'),
1888 1916 ('E', 'errorlog', '', 'error log file'),
1889 1917 ('p', 'port', 0, 'listen port'),
1890 1918 ('a', 'address', '', 'interface address'),
1891 1919 ('n', 'name', "", 'repository name'),
1892 1920 ('', 'stdio', None, 'for remote clients'),
1893 1921 ('t', 'templates', "", 'template directory'),
1894 1922 ('', 'style', "", 'template style'),
1895 1923 ('6', 'ipv6', None, 'use IPv6 in addition to IPv4')],
1896 1924 "hg serve [OPTION]..."),
1897 1925 "^status":
1898 1926 (status,
1899 1927 [('m', 'modified', None, 'show only modified files'),
1900 1928 ('a', 'added', None, 'show only added files'),
1901 1929 ('r', 'removed', None, 'show only removed files'),
1902 1930 ('u', 'unknown', None, 'show only unknown (not tracked) files'),
1903 1931 ('n', 'no-status', None, 'hide status prefix'),
1904 1932 ('0', 'print0', None, 'end filenames with NUL'),
1905 1933 ('I', 'include', [], 'include path in search'),
1906 1934 ('X', 'exclude', [], 'exclude path from search')],
1907 1935 "hg status [OPTION]... [FILE]..."),
1908 1936 "tag":
1909 1937 (tag,
1910 1938 [('l', 'local', None, 'make the tag local'),
1911 1939 ('m', 'message', "", 'commit message'),
1912 1940 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1913 1941 ('d', 'date', "", 'date code'),
1914 1942 ('u', 'user', "", 'user')],
1915 1943 'hg tag [OPTION]... NAME [REV]'),
1916 1944 "tags": (tags, [], 'hg tags'),
1917 1945 "tip": (tip, [], 'hg tip'),
1918 1946 "unbundle":
1919 1947 (unbundle,
1920 1948 [],
1921 1949 'hg unbundle FILE'),
1922 1950 "undo": (undo, [], 'hg undo'),
1923 1951 "^update|up|checkout|co":
1924 1952 (update,
1925 1953 [('b', 'branch', "", 'checkout the head of a specific branch'),
1926 1954 ('m', 'merge', None, 'allow merging of conflicts'),
1927 1955 ('C', 'clean', None, 'overwrite locally modified files')],
1928 1956 'hg update [-b TAG] [-m] [-C] [REV]'),
1929 1957 "verify": (verify, [], 'hg verify'),
1930 1958 "version": (show_version, [], 'hg version'),
1931 1959 }
1932 1960
1933 1961 globalopts = [
1934 1962 ('R', 'repository', "", 'repository root directory'),
1935 1963 ('', 'cwd', '', 'change working directory'),
1936 1964 ('y', 'noninteractive', None, 'run non-interactively'),
1937 1965 ('q', 'quiet', None, 'quiet mode'),
1938 1966 ('v', 'verbose', None, 'verbose mode'),
1939 1967 ('', 'debug', None, 'debug mode'),
1940 1968 ('', 'debugger', None, 'start debugger'),
1941 1969 ('', 'traceback', None, 'print traceback on exception'),
1942 1970 ('', 'time', None, 'time how long the command takes'),
1943 1971 ('', 'profile', None, 'profile'),
1944 1972 ('', 'version', None, 'output version information and exit'),
1945 1973 ('h', 'help', None, 'display help and exit'),
1946 1974 ]
1947 1975
1948 1976 norepo = ("clone init version help debugconfig debugdata"
1949 1977 " debugindex debugindexdot paths")
1950 1978
1951 1979 def find(cmd):
1952 1980 for e in table.keys():
1953 1981 if re.match("(%s)$" % e, cmd):
1954 1982 return e, table[e]
1955 1983
1956 1984 raise UnknownCommand(cmd)
1957 1985
1958 1986 class SignalInterrupt(Exception):
1959 1987 """Exception raised on SIGTERM and SIGHUP."""
1960 1988
1961 1989 def catchterm(*args):
1962 1990 raise SignalInterrupt
1963 1991
1964 1992 def run():
1965 1993 sys.exit(dispatch(sys.argv[1:]))
1966 1994
1967 1995 class ParseError(Exception):
1968 1996 """Exception raised on errors in parsing the command line."""
1969 1997
1970 1998 def parse(args):
1971 1999 options = {}
1972 2000 cmdoptions = {}
1973 2001
1974 2002 try:
1975 2003 args = fancyopts.fancyopts(args, globalopts, options)
1976 2004 except fancyopts.getopt.GetoptError, inst:
1977 2005 raise ParseError(None, inst)
1978 2006
1979 2007 if args:
1980 2008 cmd, args = args[0], args[1:]
1981 2009 i = find(cmd)[1]
1982 2010 c = list(i[1])
1983 2011 else:
1984 2012 cmd = None
1985 2013 c = []
1986 2014
1987 2015 # combine global options into local
1988 2016 for o in globalopts:
1989 2017 c.append((o[0], o[1], options[o[1]], o[3]))
1990 2018
1991 2019 try:
1992 2020 args = fancyopts.fancyopts(args, c, cmdoptions)
1993 2021 except fancyopts.getopt.GetoptError, inst:
1994 2022 raise ParseError(cmd, inst)
1995 2023
1996 2024 # separate global options back out
1997 2025 for o in globalopts:
1998 2026 n = o[1]
1999 2027 options[n] = cmdoptions[n]
2000 2028 del cmdoptions[n]
2001 2029
2002 2030 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
2003 2031
2004 2032 def dispatch(args):
2005 2033 signal.signal(signal.SIGTERM, catchterm)
2006 2034 try:
2007 2035 signal.signal(signal.SIGHUP, catchterm)
2008 2036 except AttributeError:
2009 2037 pass
2010 2038
2011 2039 u = ui.ui()
2012 2040 external = []
2013 2041 for x in u.extensions():
2014 2042 if x[1]:
2015 2043 mod = imp.load_source(x[0], x[1])
2016 2044 else:
2017 2045 def importh(name):
2018 2046 mod = __import__(name)
2019 2047 components = name.split('.')
2020 2048 for comp in components[1:]:
2021 2049 mod = getattr(mod, comp)
2022 2050 return mod
2023 2051 mod = importh(x[0])
2024 2052 external.append(mod)
2025 2053 for x in external:
2026 2054 for t in x.cmdtable:
2027 2055 if t in table:
2028 2056 u.warn("module %s override %s\n" % (x.__name__, t))
2029 2057 table.update(x.cmdtable)
2030 2058
2031 2059 try:
2032 2060 cmd, func, args, options, cmdoptions = parse(args)
2033 2061 except ParseError, inst:
2034 2062 if inst.args[0]:
2035 2063 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1]))
2036 2064 help_(u, inst.args[0])
2037 2065 else:
2038 2066 u.warn("hg: %s\n" % inst.args[1])
2039 2067 help_(u, 'shortlist')
2040 2068 sys.exit(-1)
2041 2069 except UnknownCommand, inst:
2042 2070 u.warn("hg: unknown command '%s'\n" % inst.args[0])
2043 2071 help_(u, 'shortlist')
2044 2072 sys.exit(1)
2045 2073
2046 2074 if options["time"]:
2047 2075 def get_times():
2048 2076 t = os.times()
2049 2077 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
2050 2078 t = (t[0], t[1], t[2], t[3], time.clock())
2051 2079 return t
2052 2080 s = get_times()
2053 2081 def print_time():
2054 2082 t = get_times()
2055 2083 u.warn("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n" %
2056 2084 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
2057 2085 atexit.register(print_time)
2058 2086
2059 2087 u.updateopts(options["verbose"], options["debug"], options["quiet"],
2060 2088 not options["noninteractive"])
2061 2089
2062 2090 # enter the debugger before command execution
2063 2091 if options['debugger']:
2064 2092 pdb.set_trace()
2065 2093
2066 2094 try:
2067 2095 try:
2068 2096 if options['help']:
2069 2097 help_(u, cmd, options['version'])
2070 2098 sys.exit(0)
2071 2099 elif options['version']:
2072 2100 show_version(u)
2073 2101 sys.exit(0)
2074 2102 elif not cmd:
2075 2103 help_(u, 'shortlist')
2076 2104 sys.exit(0)
2077 2105
2078 2106 if options['cwd']:
2079 2107 try:
2080 2108 os.chdir(options['cwd'])
2081 2109 except OSError, inst:
2082 2110 raise util.Abort('%s: %s' %
2083 2111 (options['cwd'], inst.strerror))
2084 2112
2085 2113 if cmd not in norepo.split():
2086 2114 path = options["repository"] or ""
2087 2115 repo = hg.repository(ui=u, path=path)
2088 2116 for x in external:
2089 2117 x.reposetup(u, repo)
2090 2118 d = lambda: func(u, repo, *args, **cmdoptions)
2091 2119 else:
2092 2120 d = lambda: func(u, *args, **cmdoptions)
2093 2121
2094 2122 if options['profile']:
2095 2123 import hotshot, hotshot.stats
2096 2124 prof = hotshot.Profile("hg.prof")
2097 2125 r = prof.runcall(d)
2098 2126 prof.close()
2099 2127 stats = hotshot.stats.load("hg.prof")
2100 2128 stats.strip_dirs()
2101 2129 stats.sort_stats('time', 'calls')
2102 2130 stats.print_stats(40)
2103 2131 return r
2104 2132 else:
2105 2133 return d()
2106 2134 except:
2107 2135 # enter the debugger when we hit an exception
2108 2136 if options['debugger']:
2109 2137 pdb.post_mortem(sys.exc_info()[2])
2110 2138 if options['traceback']:
2111 2139 traceback.print_exc()
2112 2140 raise
2113 2141 except hg.RepoError, inst:
2114 2142 u.warn("abort: ", inst, "!\n")
2115 2143 except revlog.RevlogError, inst:
2116 2144 u.warn("abort: ", inst, "!\n")
2117 2145 except SignalInterrupt:
2118 2146 u.warn("killed!\n")
2119 2147 except KeyboardInterrupt:
2120 2148 try:
2121 2149 u.warn("interrupted!\n")
2122 2150 except IOError, inst:
2123 2151 if inst.errno == errno.EPIPE:
2124 2152 if u.debugflag:
2125 2153 u.warn("\nbroken pipe\n")
2126 2154 else:
2127 2155 raise
2128 2156 except IOError, inst:
2129 2157 if hasattr(inst, "code"):
2130 2158 u.warn("abort: %s\n" % inst)
2131 2159 elif hasattr(inst, "reason"):
2132 2160 u.warn("abort: error: %s\n" % inst.reason[1])
2133 2161 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
2134 2162 if u.debugflag:
2135 2163 u.warn("broken pipe\n")
2136 2164 else:
2137 2165 raise
2138 2166 except OSError, inst:
2139 2167 if hasattr(inst, "filename"):
2140 2168 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
2141 2169 else:
2142 2170 u.warn("abort: %s\n" % inst.strerror)
2143 2171 except util.Abort, inst:
2144 2172 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
2145 2173 sys.exit(1)
2146 2174 except TypeError, inst:
2147 2175 # was this an argument error?
2148 2176 tb = traceback.extract_tb(sys.exc_info()[2])
2149 2177 if len(tb) > 2: # no
2150 2178 raise
2151 2179 u.debug(inst, "\n")
2152 2180 u.warn("%s: invalid arguments\n" % cmd)
2153 2181 help_(u, cmd)
2154 2182 except UnknownCommand, inst:
2155 2183 u.warn("hg: unknown command '%s'\n" % inst.args[0])
2156 2184 help_(u, 'shortlist')
2157 2185 except SystemExit:
2158 2186 # don't catch this in the catch-all below
2159 2187 raise
2160 2188 except:
2161 2189 u.warn("** unknown exception encountered, details follow\n")
2162 2190 u.warn("** report bug details to mercurial@selenic.com\n")
2163 2191 raise
2164 2192
2165 2193 sys.exit(-1)
@@ -1,209 +1,211 b''
1 1 Mercurial Distributed SCM
2 2
3 3 basic commands (use "hg help" for the full list or option "-v" for details):
4 4
5 5 add add the specified files on the next commit
6 6 annotate show changeset information per file line
7 7 clone make a copy of an existing repository
8 8 commit commit the specified files or all outstanding changes
9 9 diff diff working directory (or selected files)
10 10 export dump the header and diffs for one or more changesets
11 11 init create a new repository in the given directory
12 12 log show revision history of entire repository or files
13 13 pull pull changes from the specified source
14 14 push push changes to the specified destination
15 15 remove remove the specified files on the next commit
16 16 revert revert modified files or dirs back to their unmodified states
17 17 serve export the repository via HTTP
18 18 status show changed files in the working directory
19 19 update update or merge working directory
20 20 add add the specified files on the next commit
21 21 annotate show changeset information per file line
22 22 clone make a copy of an existing repository
23 23 commit commit the specified files or all outstanding changes
24 24 diff diff working directory (or selected files)
25 25 export dump the header and diffs for one or more changesets
26 26 init create a new repository in the given directory
27 27 log show revision history of entire repository or files
28 28 pull pull changes from the specified source
29 29 push push changes to the specified destination
30 30 remove remove the specified files on the next commit
31 31 revert revert modified files or dirs back to their unmodified states
32 32 serve export the repository via HTTP
33 33 status show changed files in the working directory
34 34 update update or merge working directory
35 35 Mercurial Distributed SCM
36 36
37 37 list of commands (use "hg help -v" to show aliases and global options):
38 38
39 39 add add the specified files on the next commit
40 40 addremove add all new files, delete all missing files
41 41 annotate show changeset information per file line
42 42 bundle create a changegroup file
43 43 cat output the latest or given revision of a file
44 44 clone make a copy of an existing repository
45 45 commit commit the specified files or all outstanding changes
46 46 copy mark files as copied for the next commit
47 47 diff diff working directory (or selected files)
48 48 export dump the header and diffs for one or more changesets
49 49 forget don't add the specified files on the next commit
50 50 grep search for a pattern in specified files and revisions
51 51 heads show current repository heads
52 52 help show help for a given command or all commands
53 53 identify print information about the working copy
54 54 import import an ordered set of patches
55 55 incoming show new changesets found in source
56 56 init create a new repository in the given directory
57 57 locate locate files matching specific patterns
58 58 log show revision history of entire repository or files
59 59 manifest output the latest or given revision of the project manifest
60 60 outgoing show changesets not found in destination
61 61 parents show the parents of the working dir or revision
62 62 paths show definition of symbolic path names
63 63 pull pull changes from the specified source
64 64 push push changes to the specified destination
65 65 rawcommit raw commit interface
66 66 recover roll back an interrupted transaction
67 67 remove remove the specified files on the next commit
68 rename rename files; equivalent of copy + remove
68 69 revert revert modified files or dirs back to their unmodified states
69 70 root print the root (top) of the current working dir
70 71 serve export the repository via HTTP
71 72 status show changed files in the working directory
72 73 tag add a tag for the current tip or a given revision
73 74 tags list repository tags
74 75 tip show the tip revision
75 76 unbundle apply a changegroup file
76 77 undo undo the last commit or pull
77 78 update update or merge working directory
78 79 verify verify the integrity of the repository
79 80 version output version and copyright information
80 81 add add the specified files on the next commit
81 82 addremove add all new files, delete all missing files
82 83 annotate show changeset information per file line
83 84 bundle create a changegroup file
84 85 cat output the latest or given revision of a file
85 86 clone make a copy of an existing repository
86 87 commit commit the specified files or all outstanding changes
87 88 copy mark files as copied for the next commit
88 89 diff diff working directory (or selected files)
89 90 export dump the header and diffs for one or more changesets
90 91 forget don't add the specified files on the next commit
91 92 grep search for a pattern in specified files and revisions
92 93 heads show current repository heads
93 94 help show help for a given command or all commands
94 95 identify print information about the working copy
95 96 import import an ordered set of patches
96 97 incoming show new changesets found in source
97 98 init create a new repository in the given directory
98 99 locate locate files matching specific patterns
99 100 log show revision history of entire repository or files
100 101 manifest output the latest or given revision of the project manifest
101 102 outgoing show changesets not found in destination
102 103 parents show the parents of the working dir or revision
103 104 paths show definition of symbolic path names
104 105 pull pull changes from the specified source
105 106 push push changes to the specified destination
106 107 rawcommit raw commit interface
107 108 recover roll back an interrupted transaction
108 109 remove remove the specified files on the next commit
110 rename rename files; equivalent of copy + remove
109 111 revert revert modified files or dirs back to their unmodified states
110 112 root print the root (top) of the current working dir
111 113 serve export the repository via HTTP
112 114 status show changed files in the working directory
113 115 tag add a tag for the current tip or a given revision
114 116 tags list repository tags
115 117 tip show the tip revision
116 118 unbundle apply a changegroup file
117 119 undo undo the last commit or pull
118 120 update update or merge working directory
119 121 verify verify the integrity of the repository
120 122 version output version and copyright information
121 123 hg add [OPTION]... [FILE]...
122 124
123 125 add the specified files on the next commit
124 126
125 127 options:
126 128
127 129 -I --include include path in search
128 130 -X --exclude exclude path from search
129 131 hg add: option --skjdfks not recognized
130 132 hg add [OPTION]... [FILE]...
131 133
132 134 add the specified files on the next commit
133 135
134 136 options:
135 137
136 138 -I --include include path in search
137 139 -X --exclude exclude path from search
138 140 hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
139 141
140 142 diff working directory (or selected files)
141 143
142 144 options:
143 145
144 146 -r --rev revision
145 147 -a --text treat all files as text
146 148 -I --include include path in search
147 149 -X --exclude exclude path from search
148 150 hg status [OPTION]... [FILE]...
149 151
150 152 show changed files in the working directory
151 153
152 154 M = modified
153 155 A = added
154 156 R = removed
155 157 ? = not tracked
156 158
157 159 options:
158 160
159 161 -m --modified show only modified files
160 162 -a --added show only added files
161 163 -r --removed show only removed files
162 164 -u --unknown show only unknown (not tracked) files
163 165 -n --no-status hide status prefix
164 166 -0 --print0 end filenames with NUL
165 167 -I --include include path in search
166 168 -X --exclude exclude path from search
167 169 hg status [OPTION]... [FILE]...
168 170
169 171 show changed files in the working directory
170 172 hg: unknown command 'foo'
171 173 Mercurial Distributed SCM
172 174
173 175 basic commands (use "hg help" for the full list or option "-v" for details):
174 176
175 177 add add the specified files on the next commit
176 178 annotate show changeset information per file line
177 179 clone make a copy of an existing repository
178 180 commit commit the specified files or all outstanding changes
179 181 diff diff working directory (or selected files)
180 182 export dump the header and diffs for one or more changesets
181 183 init create a new repository in the given directory
182 184 log show revision history of entire repository or files
183 185 pull pull changes from the specified source
184 186 push push changes to the specified destination
185 187 remove remove the specified files on the next commit
186 188 revert revert modified files or dirs back to their unmodified states
187 189 serve export the repository via HTTP
188 190 status show changed files in the working directory
189 191 update update or merge working directory
190 192 hg: unknown command 'skjdfks'
191 193 Mercurial Distributed SCM
192 194
193 195 basic commands (use "hg help" for the full list or option "-v" for details):
194 196
195 197 add add the specified files on the next commit
196 198 annotate show changeset information per file line
197 199 clone make a copy of an existing repository
198 200 commit commit the specified files or all outstanding changes
199 201 diff diff working directory (or selected files)
200 202 export dump the header and diffs for one or more changesets
201 203 init create a new repository in the given directory
202 204 log show revision history of entire repository or files
203 205 pull pull changes from the specified source
204 206 push push changes to the specified destination
205 207 remove remove the specified files on the next commit
206 208 revert revert modified files or dirs back to their unmodified states
207 209 serve export the repository via HTTP
208 210 status show changed files in the working directory
209 211 update update or merge working directory
General Comments 0
You need to be logged in to leave comments. Login now