##// END OF EJS Templates
commands: document return values of add and paths commands
Nicolas Dumazet -
r11507:35e2d453 stable
parent child Browse files
Show More
@@ -1,4459 +1,4463
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from node import hex, nullid, nullrev, short
9 9 from lock import release
10 10 from i18n import _, gettext
11 11 import os, re, sys, difflib, time, tempfile
12 12 import hg, util, revlog, bundlerepo, extensions, copies, error
13 13 import patch, help, mdiff, url, encoding, templatekw, discovery
14 14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
15 15 import merge as mergemod
16 16 import minirst, revset
17 17 import dagparser
18 18
19 19 # Commands start here, listed alphabetically
20 20
21 21 def add(ui, repo, *pats, **opts):
22 22 """add the specified files on the next commit
23 23
24 24 Schedule files to be version controlled and added to the
25 25 repository.
26 26
27 27 The files will be added to the repository at the next commit. To
28 28 undo an add before that, see :hg:`forget`.
29 29
30 30 If no names are given, add all files to the repository.
31 31
32 32 .. container:: verbose
33 33
34 34 An example showing how new (unknown) files are added
35 35 automatically by :hg:`add`::
36 36
37 37 $ ls
38 38 foo.c
39 39 $ hg status
40 40 ? foo.c
41 41 $ hg add
42 42 adding foo.c
43 43 $ hg status
44 44 A foo.c
45
46 Returns 0 if all files are successfully added.
45 47 """
46 48
47 49 bad = []
48 50 names = []
49 51 m = cmdutil.match(repo, pats, opts)
50 52 oldbad = m.bad
51 53 m.bad = lambda x, y: bad.append(x) or oldbad(x, y)
52 54
53 55 for f in repo.walk(m):
54 56 exact = m.exact(f)
55 57 if exact or f not in repo.dirstate:
56 58 names.append(f)
57 59 if ui.verbose or not exact:
58 60 ui.status(_('adding %s\n') % m.rel(f))
59 61 if not opts.get('dry_run'):
60 62 bad += [f for f in repo[None].add(names) if f in m.files()]
61 63 return bad and 1 or 0
62 64
63 65 def addremove(ui, repo, *pats, **opts):
64 66 """add all new files, delete all missing files
65 67
66 68 Add all new files and remove all missing files from the
67 69 repository.
68 70
69 71 New files are ignored if they match any of the patterns in
70 72 .hgignore. As with add, these changes take effect at the next
71 73 commit.
72 74
73 75 Use the -s/--similarity option to detect renamed files. With a
74 76 parameter greater than 0, this compares every removed file with
75 77 every added file and records those similar enough as renames. This
76 78 option takes a percentage between 0 (disabled) and 100 (files must
77 79 be identical) as its parameter. Detecting renamed files this way
78 80 can be expensive.
79 81
80 82 Returns 0 if all files are successfully added.
81 83 """
82 84 try:
83 85 sim = float(opts.get('similarity') or 0)
84 86 except ValueError:
85 87 raise util.Abort(_('similarity must be a number'))
86 88 if sim < 0 or sim > 100:
87 89 raise util.Abort(_('similarity must be between 0 and 100'))
88 90 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
89 91
90 92 def annotate(ui, repo, *pats, **opts):
91 93 """show changeset information by line for each file
92 94
93 95 List changes in files, showing the revision id responsible for
94 96 each line
95 97
96 98 This command is useful for discovering when a change was made and
97 99 by whom.
98 100
99 101 Without the -a/--text option, annotate will avoid processing files
100 102 it detects as binary. With -a, annotate will annotate the file
101 103 anyway, although the results will probably be neither useful
102 104 nor desirable.
103 105
104 106 Returns 0 on success.
105 107 """
106 108 if opts.get('follow'):
107 109 # --follow is deprecated and now just an alias for -f/--file
108 110 # to mimic the behavior of Mercurial before version 1.5
109 111 opts['file'] = 1
110 112
111 113 datefunc = ui.quiet and util.shortdate or util.datestr
112 114 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
113 115
114 116 if not pats:
115 117 raise util.Abort(_('at least one filename or pattern is required'))
116 118
117 119 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
118 120 ('number', lambda x: str(x[0].rev())),
119 121 ('changeset', lambda x: short(x[0].node())),
120 122 ('date', getdate),
121 123 ('file', lambda x: x[0].path()),
122 124 ]
123 125
124 126 if (not opts.get('user') and not opts.get('changeset')
125 127 and not opts.get('date') and not opts.get('file')):
126 128 opts['number'] = 1
127 129
128 130 linenumber = opts.get('line_number') is not None
129 131 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
130 132 raise util.Abort(_('at least one of -n/-c is required for -l'))
131 133
132 134 funcmap = [func for op, func in opmap if opts.get(op)]
133 135 if linenumber:
134 136 lastfunc = funcmap[-1]
135 137 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
136 138
137 139 ctx = repo[opts.get('rev')]
138 140 m = cmdutil.match(repo, pats, opts)
139 141 follow = not opts.get('no_follow')
140 142 for abs in ctx.walk(m):
141 143 fctx = ctx[abs]
142 144 if not opts.get('text') and util.binary(fctx.data()):
143 145 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
144 146 continue
145 147
146 148 lines = fctx.annotate(follow=follow, linenumber=linenumber)
147 149 pieces = []
148 150
149 151 for f in funcmap:
150 152 l = [f(n) for n, dummy in lines]
151 153 if l:
152 154 ml = max(map(len, l))
153 155 pieces.append(["%*s" % (ml, x) for x in l])
154 156
155 157 if pieces:
156 158 for p, l in zip(zip(*pieces), lines):
157 159 ui.write("%s: %s" % (" ".join(p), l[1]))
158 160
159 161 def archive(ui, repo, dest, **opts):
160 162 '''create an unversioned archive of a repository revision
161 163
162 164 By default, the revision used is the parent of the working
163 165 directory; use -r/--rev to specify a different revision.
164 166
165 167 The archive type is automatically detected based on file
166 168 extension (or override using -t/--type).
167 169
168 170 Valid types are:
169 171
170 172 :``files``: a directory full of files (default)
171 173 :``tar``: tar archive, uncompressed
172 174 :``tbz2``: tar archive, compressed using bzip2
173 175 :``tgz``: tar archive, compressed using gzip
174 176 :``uzip``: zip archive, uncompressed
175 177 :``zip``: zip archive, compressed using deflate
176 178
177 179 The exact name of the destination archive or directory is given
178 180 using a format string; see :hg:`help export` for details.
179 181
180 182 Each member added to an archive file has a directory prefix
181 183 prepended. Use -p/--prefix to specify a format string for the
182 184 prefix. The default is the basename of the archive, with suffixes
183 185 removed.
184 186
185 187 Returns 0 on success.
186 188 '''
187 189
188 190 ctx = repo[opts.get('rev')]
189 191 if not ctx:
190 192 raise util.Abort(_('no working directory: please specify a revision'))
191 193 node = ctx.node()
192 194 dest = cmdutil.make_filename(repo, dest, node)
193 195 if os.path.realpath(dest) == repo.root:
194 196 raise util.Abort(_('repository root cannot be destination'))
195 197
196 198 def guess_type():
197 199 exttypes = {
198 200 'tar': ['.tar'],
199 201 'tbz2': ['.tbz2', '.tar.bz2'],
200 202 'tgz': ['.tgz', '.tar.gz'],
201 203 'zip': ['.zip'],
202 204 }
203 205
204 206 for type, extensions in exttypes.items():
205 207 if util.any(dest.endswith(ext) for ext in extensions):
206 208 return type
207 209 return None
208 210
209 211 kind = opts.get('type') or guess_type() or 'files'
210 212 prefix = opts.get('prefix')
211 213
212 214 if dest == '-':
213 215 if kind == 'files':
214 216 raise util.Abort(_('cannot archive plain files to stdout'))
215 217 dest = sys.stdout
216 218 if not prefix:
217 219 prefix = os.path.basename(repo.root) + '-%h'
218 220
219 221 prefix = cmdutil.make_filename(repo, prefix, node)
220 222 matchfn = cmdutil.match(repo, [], opts)
221 223 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
222 224 matchfn, prefix)
223 225
224 226 def backout(ui, repo, node=None, rev=None, **opts):
225 227 '''reverse effect of earlier changeset
226 228
227 229 Commit the backed out changes as a new changeset. The new
228 230 changeset is a child of the backed out changeset.
229 231
230 232 If you backout a changeset other than the tip, a new head is
231 233 created. This head will be the new tip and you should merge this
232 234 backout changeset with another head.
233 235
234 236 The --merge option remembers the parent of the working directory
235 237 before starting the backout, then merges the new head with that
236 238 changeset afterwards. This saves you from doing the merge by hand.
237 239 The result of this merge is not committed, as with a normal merge.
238 240
239 241 See :hg:`help dates` for a list of formats valid for -d/--date.
240 242
241 243 Returns 0 on success.
242 244 '''
243 245 if rev and node:
244 246 raise util.Abort(_("please specify just one revision"))
245 247
246 248 if not rev:
247 249 rev = node
248 250
249 251 if not rev:
250 252 raise util.Abort(_("please specify a revision to backout"))
251 253
252 254 date = opts.get('date')
253 255 if date:
254 256 opts['date'] = util.parsedate(date)
255 257
256 258 cmdutil.bail_if_changed(repo)
257 259 node = repo.lookup(rev)
258 260
259 261 op1, op2 = repo.dirstate.parents()
260 262 a = repo.changelog.ancestor(op1, node)
261 263 if a != node:
262 264 raise util.Abort(_('cannot backout change on a different branch'))
263 265
264 266 p1, p2 = repo.changelog.parents(node)
265 267 if p1 == nullid:
266 268 raise util.Abort(_('cannot backout a change with no parents'))
267 269 if p2 != nullid:
268 270 if not opts.get('parent'):
269 271 raise util.Abort(_('cannot backout a merge changeset without '
270 272 '--parent'))
271 273 p = repo.lookup(opts['parent'])
272 274 if p not in (p1, p2):
273 275 raise util.Abort(_('%s is not a parent of %s') %
274 276 (short(p), short(node)))
275 277 parent = p
276 278 else:
277 279 if opts.get('parent'):
278 280 raise util.Abort(_('cannot use --parent on non-merge changeset'))
279 281 parent = p1
280 282
281 283 # the backout should appear on the same branch
282 284 branch = repo.dirstate.branch()
283 285 hg.clean(repo, node, show_stats=False)
284 286 repo.dirstate.setbranch(branch)
285 287 revert_opts = opts.copy()
286 288 revert_opts['date'] = None
287 289 revert_opts['all'] = True
288 290 revert_opts['rev'] = hex(parent)
289 291 revert_opts['no_backup'] = None
290 292 revert(ui, repo, **revert_opts)
291 293 commit_opts = opts.copy()
292 294 commit_opts['addremove'] = False
293 295 if not commit_opts['message'] and not commit_opts['logfile']:
294 296 # we don't translate commit messages
295 297 commit_opts['message'] = "Backed out changeset %s" % short(node)
296 298 commit_opts['force_editor'] = True
297 299 commit(ui, repo, **commit_opts)
298 300 def nice(node):
299 301 return '%d:%s' % (repo.changelog.rev(node), short(node))
300 302 ui.status(_('changeset %s backs out changeset %s\n') %
301 303 (nice(repo.changelog.tip()), nice(node)))
302 304 if op1 != node:
303 305 hg.clean(repo, op1, show_stats=False)
304 306 if opts.get('merge'):
305 307 ui.status(_('merging with changeset %s\n')
306 308 % nice(repo.changelog.tip()))
307 309 hg.merge(repo, hex(repo.changelog.tip()))
308 310 else:
309 311 ui.status(_('the backout changeset is a new head - '
310 312 'do not forget to merge\n'))
311 313 ui.status(_('(use "backout --merge" '
312 314 'if you want to auto-merge)\n'))
313 315
314 316 def bisect(ui, repo, rev=None, extra=None, command=None,
315 317 reset=None, good=None, bad=None, skip=None, noupdate=None):
316 318 """subdivision search of changesets
317 319
318 320 This command helps to find changesets which introduce problems. To
319 321 use, mark the earliest changeset you know exhibits the problem as
320 322 bad, then mark the latest changeset which is free from the problem
321 323 as good. Bisect will update your working directory to a revision
322 324 for testing (unless the -U/--noupdate option is specified). Once
323 325 you have performed tests, mark the working directory as good or
324 326 bad, and bisect will either update to another candidate changeset
325 327 or announce that it has found the bad revision.
326 328
327 329 As a shortcut, you can also use the revision argument to mark a
328 330 revision as good or bad without checking it out first.
329 331
330 332 If you supply a command, it will be used for automatic bisection.
331 333 Its exit status will be used to mark revisions as good or bad:
332 334 status 0 means good, 125 means to skip the revision, 127
333 335 (command not found) will abort the bisection, and any other
334 336 non-zero exit status means the revision is bad.
335 337
336 338 Returns 0 on success.
337 339 """
338 340 def print_result(nodes, good):
339 341 displayer = cmdutil.show_changeset(ui, repo, {})
340 342 if len(nodes) == 1:
341 343 # narrowed it down to a single revision
342 344 if good:
343 345 ui.write(_("The first good revision is:\n"))
344 346 else:
345 347 ui.write(_("The first bad revision is:\n"))
346 348 displayer.show(repo[nodes[0]])
347 349 else:
348 350 # multiple possible revisions
349 351 if good:
350 352 ui.write(_("Due to skipped revisions, the first "
351 353 "good revision could be any of:\n"))
352 354 else:
353 355 ui.write(_("Due to skipped revisions, the first "
354 356 "bad revision could be any of:\n"))
355 357 for n in nodes:
356 358 displayer.show(repo[n])
357 359 displayer.close()
358 360
359 361 def check_state(state, interactive=True):
360 362 if not state['good'] or not state['bad']:
361 363 if (good or bad or skip or reset) and interactive:
362 364 return
363 365 if not state['good']:
364 366 raise util.Abort(_('cannot bisect (no known good revisions)'))
365 367 else:
366 368 raise util.Abort(_('cannot bisect (no known bad revisions)'))
367 369 return True
368 370
369 371 # backward compatibility
370 372 if rev in "good bad reset init".split():
371 373 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
372 374 cmd, rev, extra = rev, extra, None
373 375 if cmd == "good":
374 376 good = True
375 377 elif cmd == "bad":
376 378 bad = True
377 379 else:
378 380 reset = True
379 381 elif extra or good + bad + skip + reset + bool(command) > 1:
380 382 raise util.Abort(_('incompatible arguments'))
381 383
382 384 if reset:
383 385 p = repo.join("bisect.state")
384 386 if os.path.exists(p):
385 387 os.unlink(p)
386 388 return
387 389
388 390 state = hbisect.load_state(repo)
389 391
390 392 if command:
391 393 changesets = 1
392 394 try:
393 395 while changesets:
394 396 # update state
395 397 status = util.system(command)
396 398 if status == 125:
397 399 transition = "skip"
398 400 elif status == 0:
399 401 transition = "good"
400 402 # status < 0 means process was killed
401 403 elif status == 127:
402 404 raise util.Abort(_("failed to execute %s") % command)
403 405 elif status < 0:
404 406 raise util.Abort(_("%s killed") % command)
405 407 else:
406 408 transition = "bad"
407 409 ctx = repo[rev or '.']
408 410 state[transition].append(ctx.node())
409 411 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
410 412 check_state(state, interactive=False)
411 413 # bisect
412 414 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
413 415 # update to next check
414 416 cmdutil.bail_if_changed(repo)
415 417 hg.clean(repo, nodes[0], show_stats=False)
416 418 finally:
417 419 hbisect.save_state(repo, state)
418 420 print_result(nodes, good)
419 421 return
420 422
421 423 # update state
422 424 node = repo.lookup(rev or '.')
423 425 if good or bad or skip:
424 426 if good:
425 427 state['good'].append(node)
426 428 elif bad:
427 429 state['bad'].append(node)
428 430 elif skip:
429 431 state['skip'].append(node)
430 432 hbisect.save_state(repo, state)
431 433
432 434 if not check_state(state):
433 435 return
434 436
435 437 # actually bisect
436 438 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
437 439 if changesets == 0:
438 440 print_result(nodes, good)
439 441 else:
440 442 assert len(nodes) == 1 # only a single node can be tested next
441 443 node = nodes[0]
442 444 # compute the approximate number of remaining tests
443 445 tests, size = 0, 2
444 446 while size <= changesets:
445 447 tests, size = tests + 1, size * 2
446 448 rev = repo.changelog.rev(node)
447 449 ui.write(_("Testing changeset %d:%s "
448 450 "(%d changesets remaining, ~%d tests)\n")
449 451 % (rev, short(node), changesets, tests))
450 452 if not noupdate:
451 453 cmdutil.bail_if_changed(repo)
452 454 return hg.clean(repo, node)
453 455
454 456 def branch(ui, repo, label=None, **opts):
455 457 """set or show the current branch name
456 458
457 459 With no argument, show the current branch name. With one argument,
458 460 set the working directory branch name (the branch will not exist
459 461 in the repository until the next commit). Standard practice
460 462 recommends that primary development take place on the 'default'
461 463 branch.
462 464
463 465 Unless -f/--force is specified, branch will not let you set a
464 466 branch name that already exists, even if it's inactive.
465 467
466 468 Use -C/--clean to reset the working directory branch to that of
467 469 the parent of the working directory, negating a previous branch
468 470 change.
469 471
470 472 Use the command :hg:`update` to switch to an existing branch. Use
471 473 :hg:`commit --close-branch` to mark this branch as closed.
472 474
473 475 Returns 0 on success.
474 476 """
475 477
476 478 if opts.get('clean'):
477 479 label = repo[None].parents()[0].branch()
478 480 repo.dirstate.setbranch(label)
479 481 ui.status(_('reset working directory to branch %s\n') % label)
480 482 elif label:
481 483 utflabel = encoding.fromlocal(label)
482 484 if not opts.get('force') and utflabel in repo.branchtags():
483 485 if label not in [p.branch() for p in repo.parents()]:
484 486 raise util.Abort(_('a branch of the same name already exists'
485 487 " (use 'hg update' to switch to it)"))
486 488 repo.dirstate.setbranch(utflabel)
487 489 ui.status(_('marked working directory as branch %s\n') % label)
488 490 else:
489 491 ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
490 492
491 493 def branches(ui, repo, active=False, closed=False):
492 494 """list repository named branches
493 495
494 496 List the repository's named branches, indicating which ones are
495 497 inactive. If -c/--closed is specified, also list branches which have
496 498 been marked closed (see :hg:`commit --close-branch`).
497 499
498 500 If -a/--active is specified, only show active branches. A branch
499 501 is considered active if it contains repository heads.
500 502
501 503 Use the command :hg:`update` to switch to an existing branch.
502 504
503 505 Returns 0.
504 506 """
505 507
506 508 hexfunc = ui.debugflag and hex or short
507 509 activebranches = [repo[n].branch() for n in repo.heads()]
508 510 def testactive(tag, node):
509 511 realhead = tag in activebranches
510 512 open = node in repo.branchheads(tag, closed=False)
511 513 return realhead and open
512 514 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
513 515 for tag, node in repo.branchtags().items()],
514 516 reverse=True)
515 517
516 518 for isactive, node, tag in branches:
517 519 if (not active) or isactive:
518 520 encodedtag = encoding.tolocal(tag)
519 521 if ui.quiet:
520 522 ui.write("%s\n" % encodedtag)
521 523 else:
522 524 hn = repo.lookup(node)
523 525 if isactive:
524 526 notice = ''
525 527 elif hn not in repo.branchheads(tag, closed=False):
526 528 if not closed:
527 529 continue
528 530 notice = _(' (closed)')
529 531 else:
530 532 notice = _(' (inactive)')
531 533 rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
532 534 data = encodedtag, rev, hexfunc(hn), notice
533 535 ui.write("%s %s:%s%s\n" % data)
534 536
535 537 def bundle(ui, repo, fname, dest=None, **opts):
536 538 """create a changegroup file
537 539
538 540 Generate a compressed changegroup file collecting changesets not
539 541 known to be in another repository.
540 542
541 543 If you omit the destination repository, then hg assumes the
542 544 destination will have all the nodes you specify with --base
543 545 parameters. To create a bundle containing all changesets, use
544 546 -a/--all (or --base null).
545 547
546 548 You can change compression method with the -t/--type option.
547 549 The available compression methods are: none, bzip2, and
548 550 gzip (by default, bundles are compressed using bzip2).
549 551
550 552 The bundle file can then be transferred using conventional means
551 553 and applied to another repository with the unbundle or pull
552 554 command. This is useful when direct push and pull are not
553 555 available or when exporting an entire repository is undesirable.
554 556
555 557 Applying bundles preserves all changeset contents including
556 558 permissions, copy/rename information, and revision history.
557 559
558 560 Returns 0 on success, 1 if no changes found.
559 561 """
560 562 revs = opts.get('rev') or None
561 563 if revs:
562 564 revs = [repo.lookup(rev) for rev in revs]
563 565 if opts.get('all'):
564 566 base = ['null']
565 567 else:
566 568 base = opts.get('base')
567 569 if base:
568 570 if dest:
569 571 raise util.Abort(_("--base is incompatible with specifying "
570 572 "a destination"))
571 573 base = [repo.lookup(rev) for rev in base]
572 574 # create the right base
573 575 # XXX: nodesbetween / changegroup* should be "fixed" instead
574 576 o = []
575 577 has = set((nullid,))
576 578 for n in base:
577 579 has.update(repo.changelog.reachable(n))
578 580 if revs:
579 581 visit = list(revs)
580 582 has.difference_update(revs)
581 583 else:
582 584 visit = repo.changelog.heads()
583 585 seen = {}
584 586 while visit:
585 587 n = visit.pop(0)
586 588 parents = [p for p in repo.changelog.parents(n) if p not in has]
587 589 if len(parents) == 0:
588 590 if n not in has:
589 591 o.append(n)
590 592 else:
591 593 for p in parents:
592 594 if p not in seen:
593 595 seen[p] = 1
594 596 visit.append(p)
595 597 else:
596 598 dest = ui.expandpath(dest or 'default-push', dest or 'default')
597 599 dest, branches = hg.parseurl(dest, opts.get('branch'))
598 600 other = hg.repository(hg.remoteui(repo, opts), dest)
599 601 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
600 602 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
601 603
602 604 if not o:
603 605 ui.status(_("no changes found\n"))
604 606 return 1
605 607
606 608 if revs:
607 609 cg = repo.changegroupsubset(o, revs, 'bundle')
608 610 else:
609 611 cg = repo.changegroup(o, 'bundle')
610 612
611 613 bundletype = opts.get('type', 'bzip2').lower()
612 614 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
613 615 bundletype = btypes.get(bundletype)
614 616 if bundletype not in changegroup.bundletypes:
615 617 raise util.Abort(_('unknown bundle type specified with --type'))
616 618
617 619 changegroup.writebundle(cg, fname, bundletype)
618 620
619 621 def cat(ui, repo, file1, *pats, **opts):
620 622 """output the current or given revision of files
621 623
622 624 Print the specified files as they were at the given revision. If
623 625 no revision is given, the parent of the working directory is used,
624 626 or tip if no revision is checked out.
625 627
626 628 Output may be to a file, in which case the name of the file is
627 629 given using a format string. The formatting rules are the same as
628 630 for the export command, with the following additions:
629 631
630 632 :``%s``: basename of file being printed
631 633 :``%d``: dirname of file being printed, or '.' if in repository root
632 634 :``%p``: root-relative path name of file being printed
633 635
634 636 Returns 0 on success.
635 637 """
636 638 ctx = repo[opts.get('rev')]
637 639 err = 1
638 640 m = cmdutil.match(repo, (file1,) + pats, opts)
639 641 for abs in ctx.walk(m):
640 642 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
641 643 data = ctx[abs].data()
642 644 if opts.get('decode'):
643 645 data = repo.wwritedata(abs, data)
644 646 fp.write(data)
645 647 err = 0
646 648 return err
647 649
648 650 def clone(ui, source, dest=None, **opts):
649 651 """make a copy of an existing repository
650 652
651 653 Create a copy of an existing repository in a new directory.
652 654
653 655 If no destination directory name is specified, it defaults to the
654 656 basename of the source.
655 657
656 658 The location of the source is added to the new repository's
657 659 .hg/hgrc file, as the default to be used for future pulls.
658 660
659 661 See :hg:`help urls` for valid source format details.
660 662
661 663 It is possible to specify an ``ssh://`` URL as the destination, but no
662 664 .hg/hgrc and working directory will be created on the remote side.
663 665 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
664 666
665 667 A set of changesets (tags, or branch names) to pull may be specified
666 668 by listing each changeset (tag, or branch name) with -r/--rev.
667 669 If -r/--rev is used, the cloned repository will contain only a subset
668 670 of the changesets of the source repository. Only the set of changesets
669 671 defined by all -r/--rev options (including all their ancestors)
670 672 will be pulled into the destination repository.
671 673 No subsequent changesets (including subsequent tags) will be present
672 674 in the destination.
673 675
674 676 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
675 677 local source repositories.
676 678
677 679 For efficiency, hardlinks are used for cloning whenever the source
678 680 and destination are on the same filesystem (note this applies only
679 681 to the repository data, not to the working directory). Some
680 682 filesystems, such as AFS, implement hardlinking incorrectly, but
681 683 do not report errors. In these cases, use the --pull option to
682 684 avoid hardlinking.
683 685
684 686 In some cases, you can clone repositories and the working directory
685 687 using full hardlinks with ::
686 688
687 689 $ cp -al REPO REPOCLONE
688 690
689 691 This is the fastest way to clone, but it is not always safe. The
690 692 operation is not atomic (making sure REPO is not modified during
691 693 the operation is up to you) and you have to make sure your editor
692 694 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
693 695 this is not compatible with certain extensions that place their
694 696 metadata under the .hg directory, such as mq.
695 697
696 698 Mercurial will update the working directory to the first applicable
697 699 revision from this list:
698 700
699 701 a) null if -U or the source repository has no changesets
700 702 b) if -u . and the source repository is local, the first parent of
701 703 the source repository's working directory
702 704 c) the changeset specified with -u (if a branch name, this means the
703 705 latest head of that branch)
704 706 d) the changeset specified with -r
705 707 e) the tipmost head specified with -b
706 708 f) the tipmost head specified with the url#branch source syntax
707 709 g) the tipmost head of the default branch
708 710 h) tip
709 711
710 712 Returns 0 on success.
711 713 """
712 714 if opts.get('noupdate') and opts.get('updaterev'):
713 715 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
714 716
715 717 r = hg.clone(hg.remoteui(ui, opts), source, dest,
716 718 pull=opts.get('pull'),
717 719 stream=opts.get('uncompressed'),
718 720 rev=opts.get('rev'),
719 721 update=opts.get('updaterev') or not opts.get('noupdate'),
720 722 branch=opts.get('branch'))
721 723
722 724 return r is None
723 725
724 726 def commit(ui, repo, *pats, **opts):
725 727 """commit the specified files or all outstanding changes
726 728
727 729 Commit changes to the given files into the repository. Unlike a
728 730 centralized RCS, this operation is a local operation. See
729 731 :hg:`push` for a way to actively distribute your changes.
730 732
731 733 If a list of files is omitted, all changes reported by :hg:`status`
732 734 will be committed.
733 735
734 736 If you are committing the result of a merge, do not provide any
735 737 filenames or -I/-X filters.
736 738
737 739 If no commit message is specified, the configured editor is
738 740 started to prompt you for a message.
739 741
740 742 See :hg:`help dates` for a list of formats valid for -d/--date.
741 743
742 744 Returns 0 on success, 1 if nothing changed.
743 745 """
744 746 extra = {}
745 747 if opts.get('close_branch'):
746 748 if repo['.'].node() not in repo.branchheads():
747 749 # The topo heads set is included in the branch heads set of the
748 750 # current branch, so it's sufficient to test branchheads
749 751 raise util.Abort(_('can only close branch heads'))
750 752 extra['close'] = 1
751 753 e = cmdutil.commiteditor
752 754 if opts.get('force_editor'):
753 755 e = cmdutil.commitforceeditor
754 756
755 757 def commitfunc(ui, repo, message, match, opts):
756 758 return repo.commit(message, opts.get('user'), opts.get('date'), match,
757 759 editor=e, extra=extra)
758 760
759 761 branch = repo[None].branch()
760 762 bheads = repo.branchheads(branch)
761 763
762 764 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
763 765 if not node:
764 766 ui.status(_("nothing changed\n"))
765 767 return 1
766 768
767 769 ctx = repo[node]
768 770 parents = ctx.parents()
769 771
770 772 if bheads and not [x for x in parents
771 773 if x.node() in bheads and x.branch() == branch]:
772 774 ui.status(_('created new head\n'))
773 775 # The message is not printed for initial roots. For the other
774 776 # changesets, it is printed in the following situations:
775 777 #
776 778 # Par column: for the 2 parents with ...
777 779 # N: null or no parent
778 780 # B: parent is on another named branch
779 781 # C: parent is a regular non head changeset
780 782 # H: parent was a branch head of the current branch
781 783 # Msg column: whether we print "created new head" message
782 784 # In the following, it is assumed that there already exists some
783 785 # initial branch heads of the current branch, otherwise nothing is
784 786 # printed anyway.
785 787 #
786 788 # Par Msg Comment
787 789 # NN y additional topo root
788 790 #
789 791 # BN y additional branch root
790 792 # CN y additional topo head
791 793 # HN n usual case
792 794 #
793 795 # BB y weird additional branch root
794 796 # CB y branch merge
795 797 # HB n merge with named branch
796 798 #
797 799 # CC y additional head from merge
798 800 # CH n merge with a head
799 801 #
800 802 # HH n head merge: head count decreases
801 803
802 804 if not opts.get('close_branch'):
803 805 for r in parents:
804 806 if r.extra().get('close'):
805 807 ui.status(_('reopening closed branch head %d\n') % r)
806 808
807 809 if ui.debugflag:
808 810 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
809 811 elif ui.verbose:
810 812 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
811 813
812 814 def copy(ui, repo, *pats, **opts):
813 815 """mark files as copied for the next commit
814 816
815 817 Mark dest as having copies of source files. If dest is a
816 818 directory, copies are put in that directory. If dest is a file,
817 819 the source must be a single file.
818 820
819 821 By default, this command copies the contents of files as they
820 822 exist in the working directory. If invoked with -A/--after, the
821 823 operation is recorded, but no copying is performed.
822 824
823 825 This command takes effect with the next commit. To undo a copy
824 826 before that, see :hg:`revert`.
825 827
826 828 Returns 0 on success, 1 if errors are encountered.
827 829 """
828 830 wlock = repo.wlock(False)
829 831 try:
830 832 return cmdutil.copy(ui, repo, pats, opts)
831 833 finally:
832 834 wlock.release()
833 835
834 836 def debugancestor(ui, repo, *args):
835 837 """find the ancestor revision of two revisions in a given index"""
836 838 if len(args) == 3:
837 839 index, rev1, rev2 = args
838 840 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
839 841 lookup = r.lookup
840 842 elif len(args) == 2:
841 843 if not repo:
842 844 raise util.Abort(_("There is no Mercurial repository here "
843 845 "(.hg not found)"))
844 846 rev1, rev2 = args
845 847 r = repo.changelog
846 848 lookup = repo.lookup
847 849 else:
848 850 raise util.Abort(_('either two or three arguments required'))
849 851 a = r.ancestor(lookup(rev1), lookup(rev2))
850 852 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
851 853
852 854 def debugbuilddag(ui, repo, text,
853 855 mergeable_file=False,
854 856 appended_file=False,
855 857 overwritten_file=False,
856 858 new_file=False):
857 859 """builds a repo with a given dag from scratch in the current empty repo
858 860
859 861 Elements:
860 862
861 863 - "+n" is a linear run of n nodes based on the current default parent
862 864 - "." is a single node based on the current default parent
863 865 - "$" resets the default parent to null (implied at the start);
864 866 otherwise the default parent is always the last node created
865 867 - "<p" sets the default parent to the backref p
866 868 - "*p" is a fork at parent p, which is a backref
867 869 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
868 870 - "/p2" is a merge of the preceding node and p2
869 871 - ":tag" defines a local tag for the preceding node
870 872 - "@branch" sets the named branch for subsequent nodes
871 873 - "!command" runs the command using your shell
872 874 - "!!my command\\n" is like "!", but to the end of the line
873 875 - "#...\\n" is a comment up to the end of the line
874 876
875 877 Whitespace between the above elements is ignored.
876 878
877 879 A backref is either
878 880
879 881 - a number n, which references the node curr-n, where curr is the current
880 882 node, or
881 883 - the name of a local tag you placed earlier using ":tag", or
882 884 - empty to denote the default parent.
883 885
884 886 All string valued-elements are either strictly alphanumeric, or must
885 887 be enclosed in double quotes ("..."), with "\" as escape character.
886 888
887 889 Note that the --overwritten-file and --appended-file options imply the
888 890 use of "HGMERGE=internal:local" during DAG buildup.
889 891 """
890 892
891 893 if not (mergeable_file or appended_file or overwritten_file or new_file):
892 894 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
893 895
894 896 if len(repo.changelog) > 0:
895 897 raise util.Abort(_('repository is not empty'))
896 898
897 899 if overwritten_file or appended_file:
898 900 # we don't want to fail in merges during buildup
899 901 os.environ['HGMERGE'] = 'internal:local'
900 902
901 903 def writefile(fname, text, fmode="w"):
902 904 f = open(fname, fmode)
903 905 try:
904 906 f.write(text)
905 907 finally:
906 908 f.close()
907 909
908 910 if mergeable_file:
909 911 linesperrev = 2
910 912 # determine number of revs in DAG
911 913 n = 0
912 914 for type, data in dagparser.parsedag(text):
913 915 if type == 'n':
914 916 n += 1
915 917 # make a file with k lines per rev
916 918 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
917 919 + "\n")
918 920
919 921 at = -1
920 922 atbranch = 'default'
921 923 for type, data in dagparser.parsedag(text):
922 924 if type == 'n':
923 925 ui.status('node %s\n' % str(data))
924 926 id, ps = data
925 927 p1 = ps[0]
926 928 if p1 != at:
927 929 update(ui, repo, node=p1, clean=True)
928 930 at = p1
929 931 if repo.dirstate.branch() != atbranch:
930 932 branch(ui, repo, atbranch, force=True)
931 933 if len(ps) > 1:
932 934 p2 = ps[1]
933 935 merge(ui, repo, node=p2)
934 936
935 937 if mergeable_file:
936 938 f = open("mf", "r+")
937 939 try:
938 940 lines = f.read().split("\n")
939 941 lines[id * linesperrev] += " r%i" % id
940 942 f.seek(0)
941 943 f.write("\n".join(lines))
942 944 finally:
943 945 f.close()
944 946
945 947 if appended_file:
946 948 writefile("af", "r%i\n" % id, "a")
947 949
948 950 if overwritten_file:
949 951 writefile("of", "r%i\n" % id)
950 952
951 953 if new_file:
952 954 writefile("nf%i" % id, "r%i\n" % id)
953 955
954 956 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
955 957 at = id
956 958 elif type == 'l':
957 959 id, name = data
958 960 ui.status('tag %s\n' % name)
959 961 tag(ui, repo, name, local=True)
960 962 elif type == 'a':
961 963 ui.status('branch %s\n' % data)
962 964 atbranch = data
963 965 elif type in 'cC':
964 966 r = util.system(data, cwd=repo.root)
965 967 if r:
966 968 desc, r = util.explain_exit(r)
967 969 raise util.Abort(_('%s command %s') % (data, desc))
968 970
969 971 def debugcommands(ui, cmd='', *args):
970 972 """list all available commands and options"""
971 973 for cmd, vals in sorted(table.iteritems()):
972 974 cmd = cmd.split('|')[0].strip('^')
973 975 opts = ', '.join([i[1] for i in vals[1]])
974 976 ui.write('%s: %s\n' % (cmd, opts))
975 977
976 978 def debugcomplete(ui, cmd='', **opts):
977 979 """returns the completion list associated with the given command"""
978 980
979 981 if opts.get('options'):
980 982 options = []
981 983 otables = [globalopts]
982 984 if cmd:
983 985 aliases, entry = cmdutil.findcmd(cmd, table, False)
984 986 otables.append(entry[1])
985 987 for t in otables:
986 988 for o in t:
987 989 if "(DEPRECATED)" in o[3]:
988 990 continue
989 991 if o[0]:
990 992 options.append('-%s' % o[0])
991 993 options.append('--%s' % o[1])
992 994 ui.write("%s\n" % "\n".join(options))
993 995 return
994 996
995 997 cmdlist = cmdutil.findpossible(cmd, table)
996 998 if ui.verbose:
997 999 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
998 1000 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
999 1001
1000 1002 def debugfsinfo(ui, path = "."):
1001 1003 """show information detected about current filesystem"""
1002 1004 open('.debugfsinfo', 'w').write('')
1003 1005 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1004 1006 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1005 1007 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1006 1008 and 'yes' or 'no'))
1007 1009 os.unlink('.debugfsinfo')
1008 1010
1009 1011 def debugrebuildstate(ui, repo, rev="tip"):
1010 1012 """rebuild the dirstate as it would look like for the given revision"""
1011 1013 ctx = repo[rev]
1012 1014 wlock = repo.wlock()
1013 1015 try:
1014 1016 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1015 1017 finally:
1016 1018 wlock.release()
1017 1019
1018 1020 def debugcheckstate(ui, repo):
1019 1021 """validate the correctness of the current dirstate"""
1020 1022 parent1, parent2 = repo.dirstate.parents()
1021 1023 m1 = repo[parent1].manifest()
1022 1024 m2 = repo[parent2].manifest()
1023 1025 errors = 0
1024 1026 for f in repo.dirstate:
1025 1027 state = repo.dirstate[f]
1026 1028 if state in "nr" and f not in m1:
1027 1029 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1028 1030 errors += 1
1029 1031 if state in "a" and f in m1:
1030 1032 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1031 1033 errors += 1
1032 1034 if state in "m" and f not in m1 and f not in m2:
1033 1035 ui.warn(_("%s in state %s, but not in either manifest\n") %
1034 1036 (f, state))
1035 1037 errors += 1
1036 1038 for f in m1:
1037 1039 state = repo.dirstate[f]
1038 1040 if state not in "nrm":
1039 1041 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1040 1042 errors += 1
1041 1043 if errors:
1042 1044 error = _(".hg/dirstate inconsistent with current parent's manifest")
1043 1045 raise util.Abort(error)
1044 1046
1045 1047 def showconfig(ui, repo, *values, **opts):
1046 1048 """show combined config settings from all hgrc files
1047 1049
1048 1050 With no arguments, print names and values of all config items.
1049 1051
1050 1052 With one argument of the form section.name, print just the value
1051 1053 of that config item.
1052 1054
1053 1055 With multiple arguments, print names and values of all config
1054 1056 items with matching section names.
1055 1057
1056 1058 With --debug, the source (filename and line number) is printed
1057 1059 for each config item.
1058 1060
1059 1061 Returns 0 on success.
1060 1062 """
1061 1063
1062 1064 for f in util.rcpath():
1063 1065 ui.debug(_('read config from: %s\n') % f)
1064 1066 untrusted = bool(opts.get('untrusted'))
1065 1067 if values:
1066 1068 if len([v for v in values if '.' in v]) > 1:
1067 1069 raise util.Abort(_('only one config item permitted'))
1068 1070 for section, name, value in ui.walkconfig(untrusted=untrusted):
1069 1071 sectname = section + '.' + name
1070 1072 if values:
1071 1073 for v in values:
1072 1074 if v == section:
1073 1075 ui.debug('%s: ' %
1074 1076 ui.configsource(section, name, untrusted))
1075 1077 ui.write('%s=%s\n' % (sectname, value))
1076 1078 elif v == sectname:
1077 1079 ui.debug('%s: ' %
1078 1080 ui.configsource(section, name, untrusted))
1079 1081 ui.write(value, '\n')
1080 1082 else:
1081 1083 ui.debug('%s: ' %
1082 1084 ui.configsource(section, name, untrusted))
1083 1085 ui.write('%s=%s\n' % (sectname, value))
1084 1086
1085 1087 def debugpushkey(ui, repopath, namespace, *keyinfo):
1086 1088 '''access the pushkey key/value protocol
1087 1089
1088 1090 With two args, list the keys in the given namespace.
1089 1091
1090 1092 With five args, set a key to new if it currently is set to old.
1091 1093 Reports success or failure.
1092 1094 '''
1093 1095
1094 1096 target = hg.repository(ui, repopath)
1095 1097 if keyinfo:
1096 1098 key, old, new = keyinfo
1097 1099 r = target.pushkey(namespace, key, old, new)
1098 1100 ui.status(str(r) + '\n')
1099 1101 return not(r)
1100 1102 else:
1101 1103 for k, v in target.listkeys(namespace).iteritems():
1102 1104 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1103 1105 v.encode('string-escape')))
1104 1106
1105 1107 def debugrevspec(ui, repo, expr):
1106 1108 '''parse and apply a revision specification'''
1107 1109 if ui.verbose:
1108 1110 tree = revset.parse(expr)
1109 1111 ui.note(tree, "\n")
1110 1112 func = revset.match(expr)
1111 1113 for c in func(repo, range(len(repo))):
1112 1114 ui.write("%s\n" % c)
1113 1115
1114 1116 def debugsetparents(ui, repo, rev1, rev2=None):
1115 1117 """manually set the parents of the current working directory
1116 1118
1117 1119 This is useful for writing repository conversion tools, but should
1118 1120 be used with care.
1119 1121
1120 1122 Returns 0 on success.
1121 1123 """
1122 1124
1123 1125 if not rev2:
1124 1126 rev2 = hex(nullid)
1125 1127
1126 1128 wlock = repo.wlock()
1127 1129 try:
1128 1130 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1129 1131 finally:
1130 1132 wlock.release()
1131 1133
1132 1134 def debugstate(ui, repo, nodates=None):
1133 1135 """show the contents of the current dirstate"""
1134 1136 timestr = ""
1135 1137 showdate = not nodates
1136 1138 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1137 1139 if showdate:
1138 1140 if ent[3] == -1:
1139 1141 # Pad or slice to locale representation
1140 1142 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1141 1143 time.localtime(0)))
1142 1144 timestr = 'unset'
1143 1145 timestr = (timestr[:locale_len] +
1144 1146 ' ' * (locale_len - len(timestr)))
1145 1147 else:
1146 1148 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1147 1149 time.localtime(ent[3]))
1148 1150 if ent[1] & 020000:
1149 1151 mode = 'lnk'
1150 1152 else:
1151 1153 mode = '%3o' % (ent[1] & 0777)
1152 1154 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1153 1155 for f in repo.dirstate.copies():
1154 1156 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1155 1157
1156 1158 def debugsub(ui, repo, rev=None):
1157 1159 if rev == '':
1158 1160 rev = None
1159 1161 for k, v in sorted(repo[rev].substate.items()):
1160 1162 ui.write('path %s\n' % k)
1161 1163 ui.write(' source %s\n' % v[0])
1162 1164 ui.write(' revision %s\n' % v[1])
1163 1165
1164 1166 def debugdag(ui, repo, file_=None, *revs, **opts):
1165 1167 """format the changelog or an index DAG as a concise textual description
1166 1168
1167 1169 If you pass a revlog index, the revlog's DAG is emitted. If you list
1168 1170 revision numbers, they get labelled in the output as rN.
1169 1171
1170 1172 Otherwise, the changelog DAG of the current repo is emitted.
1171 1173 """
1172 1174 spaces = opts.get('spaces')
1173 1175 dots = opts.get('dots')
1174 1176 if file_:
1175 1177 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1176 1178 revs = set((int(r) for r in revs))
1177 1179 def events():
1178 1180 for r in rlog:
1179 1181 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1180 1182 if r in revs:
1181 1183 yield 'l', (r, "r%i" % r)
1182 1184 elif repo:
1183 1185 cl = repo.changelog
1184 1186 tags = opts.get('tags')
1185 1187 branches = opts.get('branches')
1186 1188 if tags:
1187 1189 labels = {}
1188 1190 for l, n in repo.tags().items():
1189 1191 labels.setdefault(cl.rev(n), []).append(l)
1190 1192 def events():
1191 1193 b = "default"
1192 1194 for r in cl:
1193 1195 if branches:
1194 1196 newb = cl.read(cl.node(r))[5]['branch']
1195 1197 if newb != b:
1196 1198 yield 'a', newb
1197 1199 b = newb
1198 1200 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1199 1201 if tags:
1200 1202 ls = labels.get(r)
1201 1203 if ls:
1202 1204 for l in ls:
1203 1205 yield 'l', (r, l)
1204 1206 else:
1205 1207 raise util.Abort(_('need repo for changelog dag'))
1206 1208
1207 1209 for line in dagparser.dagtextlines(events(),
1208 1210 addspaces=spaces,
1209 1211 wraplabels=True,
1210 1212 wrapannotations=True,
1211 1213 wrapnonlinear=dots,
1212 1214 usedots=dots,
1213 1215 maxlinewidth=70):
1214 1216 ui.write(line)
1215 1217 ui.write("\n")
1216 1218
1217 1219 def debugdata(ui, file_, rev):
1218 1220 """dump the contents of a data file revision"""
1219 1221 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1220 1222 try:
1221 1223 ui.write(r.revision(r.lookup(rev)))
1222 1224 except KeyError:
1223 1225 raise util.Abort(_('invalid revision identifier %s') % rev)
1224 1226
1225 1227 def debugdate(ui, date, range=None, **opts):
1226 1228 """parse and display a date"""
1227 1229 if opts["extended"]:
1228 1230 d = util.parsedate(date, util.extendeddateformats)
1229 1231 else:
1230 1232 d = util.parsedate(date)
1231 1233 ui.write("internal: %s %s\n" % d)
1232 1234 ui.write("standard: %s\n" % util.datestr(d))
1233 1235 if range:
1234 1236 m = util.matchdate(range)
1235 1237 ui.write("match: %s\n" % m(d[0]))
1236 1238
1237 1239 def debugindex(ui, file_):
1238 1240 """dump the contents of an index file"""
1239 1241 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1240 1242 ui.write(" rev offset length base linkrev"
1241 1243 " nodeid p1 p2\n")
1242 1244 for i in r:
1243 1245 node = r.node(i)
1244 1246 try:
1245 1247 pp = r.parents(node)
1246 1248 except:
1247 1249 pp = [nullid, nullid]
1248 1250 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1249 1251 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1250 1252 short(node), short(pp[0]), short(pp[1])))
1251 1253
1252 1254 def debugindexdot(ui, file_):
1253 1255 """dump an index DAG as a graphviz dot file"""
1254 1256 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1255 1257 ui.write("digraph G {\n")
1256 1258 for i in r:
1257 1259 node = r.node(i)
1258 1260 pp = r.parents(node)
1259 1261 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1260 1262 if pp[1] != nullid:
1261 1263 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1262 1264 ui.write("}\n")
1263 1265
1264 1266 def debuginstall(ui):
1265 1267 '''test Mercurial installation
1266 1268
1267 1269 Returns 0 on success.
1268 1270 '''
1269 1271
1270 1272 def writetemp(contents):
1271 1273 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1272 1274 f = os.fdopen(fd, "wb")
1273 1275 f.write(contents)
1274 1276 f.close()
1275 1277 return name
1276 1278
1277 1279 problems = 0
1278 1280
1279 1281 # encoding
1280 1282 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1281 1283 try:
1282 1284 encoding.fromlocal("test")
1283 1285 except util.Abort, inst:
1284 1286 ui.write(" %s\n" % inst)
1285 1287 ui.write(_(" (check that your locale is properly set)\n"))
1286 1288 problems += 1
1287 1289
1288 1290 # compiled modules
1289 1291 ui.status(_("Checking extensions...\n"))
1290 1292 try:
1291 1293 import bdiff, mpatch, base85
1292 1294 except Exception, inst:
1293 1295 ui.write(" %s\n" % inst)
1294 1296 ui.write(_(" One or more extensions could not be found"))
1295 1297 ui.write(_(" (check that you compiled the extensions)\n"))
1296 1298 problems += 1
1297 1299
1298 1300 # templates
1299 1301 ui.status(_("Checking templates...\n"))
1300 1302 try:
1301 1303 import templater
1302 1304 templater.templater(templater.templatepath("map-cmdline.default"))
1303 1305 except Exception, inst:
1304 1306 ui.write(" %s\n" % inst)
1305 1307 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1306 1308 problems += 1
1307 1309
1308 1310 # patch
1309 1311 ui.status(_("Checking patch...\n"))
1310 1312 patchproblems = 0
1311 1313 a = "1\n2\n3\n4\n"
1312 1314 b = "1\n2\n3\ninsert\n4\n"
1313 1315 fa = writetemp(a)
1314 1316 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1315 1317 os.path.basename(fa))
1316 1318 fd = writetemp(d)
1317 1319
1318 1320 files = {}
1319 1321 try:
1320 1322 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1321 1323 except util.Abort, e:
1322 1324 ui.write(_(" patch call failed:\n"))
1323 1325 ui.write(" " + str(e) + "\n")
1324 1326 patchproblems += 1
1325 1327 else:
1326 1328 if list(files) != [os.path.basename(fa)]:
1327 1329 ui.write(_(" unexpected patch output!\n"))
1328 1330 patchproblems += 1
1329 1331 a = open(fa).read()
1330 1332 if a != b:
1331 1333 ui.write(_(" patch test failed!\n"))
1332 1334 patchproblems += 1
1333 1335
1334 1336 if patchproblems:
1335 1337 if ui.config('ui', 'patch'):
1336 1338 ui.write(_(" (Current patch tool may be incompatible with patch,"
1337 1339 " or misconfigured. Please check your .hgrc file)\n"))
1338 1340 else:
1339 1341 ui.write(_(" Internal patcher failure, please report this error"
1340 1342 " to http://mercurial.selenic.com/bts/\n"))
1341 1343 problems += patchproblems
1342 1344
1343 1345 os.unlink(fa)
1344 1346 os.unlink(fd)
1345 1347
1346 1348 # editor
1347 1349 ui.status(_("Checking commit editor...\n"))
1348 1350 editor = ui.geteditor()
1349 1351 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1350 1352 if not cmdpath:
1351 1353 if editor == 'vi':
1352 1354 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1353 1355 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1354 1356 else:
1355 1357 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1356 1358 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1357 1359 problems += 1
1358 1360
1359 1361 # check username
1360 1362 ui.status(_("Checking username...\n"))
1361 1363 try:
1362 1364 user = ui.username()
1363 1365 except util.Abort, e:
1364 1366 ui.write(" %s\n" % e)
1365 1367 ui.write(_(" (specify a username in your .hgrc file)\n"))
1366 1368 problems += 1
1367 1369
1368 1370 if not problems:
1369 1371 ui.status(_("No problems detected\n"))
1370 1372 else:
1371 1373 ui.write(_("%s problems detected,"
1372 1374 " please check your install!\n") % problems)
1373 1375
1374 1376 return problems
1375 1377
1376 1378 def debugrename(ui, repo, file1, *pats, **opts):
1377 1379 """dump rename information"""
1378 1380
1379 1381 ctx = repo[opts.get('rev')]
1380 1382 m = cmdutil.match(repo, (file1,) + pats, opts)
1381 1383 for abs in ctx.walk(m):
1382 1384 fctx = ctx[abs]
1383 1385 o = fctx.filelog().renamed(fctx.filenode())
1384 1386 rel = m.rel(abs)
1385 1387 if o:
1386 1388 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1387 1389 else:
1388 1390 ui.write(_("%s not renamed\n") % rel)
1389 1391
1390 1392 def debugwalk(ui, repo, *pats, **opts):
1391 1393 """show how files match on given patterns"""
1392 1394 m = cmdutil.match(repo, pats, opts)
1393 1395 items = list(repo.walk(m))
1394 1396 if not items:
1395 1397 return
1396 1398 fmt = 'f %%-%ds %%-%ds %%s' % (
1397 1399 max([len(abs) for abs in items]),
1398 1400 max([len(m.rel(abs)) for abs in items]))
1399 1401 for abs in items:
1400 1402 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1401 1403 ui.write("%s\n" % line.rstrip())
1402 1404
1403 1405 def diff(ui, repo, *pats, **opts):
1404 1406 """diff repository (or selected files)
1405 1407
1406 1408 Show differences between revisions for the specified files.
1407 1409
1408 1410 Differences between files are shown using the unified diff format.
1409 1411
1410 1412 NOTE: diff may generate unexpected results for merges, as it will
1411 1413 default to comparing against the working directory's first parent
1412 1414 changeset if no revisions are specified.
1413 1415
1414 1416 When two revision arguments are given, then changes are shown
1415 1417 between those revisions. If only one revision is specified then
1416 1418 that revision is compared to the working directory, and, when no
1417 1419 revisions are specified, the working directory files are compared
1418 1420 to its parent.
1419 1421
1420 1422 Alternatively you can specify -c/--change with a revision to see
1421 1423 the changes in that changeset relative to its first parent.
1422 1424
1423 1425 Without the -a/--text option, diff will avoid generating diffs of
1424 1426 files it detects as binary. With -a, diff will generate a diff
1425 1427 anyway, probably with undesirable results.
1426 1428
1427 1429 Use the -g/--git option to generate diffs in the git extended diff
1428 1430 format. For more information, read :hg:`help diffs`.
1429 1431
1430 1432 Returns 0 on success.
1431 1433 """
1432 1434
1433 1435 revs = opts.get('rev')
1434 1436 change = opts.get('change')
1435 1437 stat = opts.get('stat')
1436 1438 reverse = opts.get('reverse')
1437 1439
1438 1440 if revs and change:
1439 1441 msg = _('cannot specify --rev and --change at the same time')
1440 1442 raise util.Abort(msg)
1441 1443 elif change:
1442 1444 node2 = repo.lookup(change)
1443 1445 node1 = repo[node2].parents()[0].node()
1444 1446 else:
1445 1447 node1, node2 = cmdutil.revpair(repo, revs)
1446 1448
1447 1449 if reverse:
1448 1450 node1, node2 = node2, node1
1449 1451
1450 1452 diffopts = patch.diffopts(ui, opts)
1451 1453 m = cmdutil.match(repo, pats, opts)
1452 1454 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat)
1453 1455
1454 1456 def export(ui, repo, *changesets, **opts):
1455 1457 """dump the header and diffs for one or more changesets
1456 1458
1457 1459 Print the changeset header and diffs for one or more revisions.
1458 1460
1459 1461 The information shown in the changeset header is: author, date,
1460 1462 branch name (if non-default), changeset hash, parent(s) and commit
1461 1463 comment.
1462 1464
1463 1465 NOTE: export may generate unexpected diff output for merge
1464 1466 changesets, as it will compare the merge changeset against its
1465 1467 first parent only.
1466 1468
1467 1469 Output may be to a file, in which case the name of the file is
1468 1470 given using a format string. The formatting rules are as follows:
1469 1471
1470 1472 :``%%``: literal "%" character
1471 1473 :``%H``: changeset hash (40 bytes of hexadecimal)
1472 1474 :``%N``: number of patches being generated
1473 1475 :``%R``: changeset revision number
1474 1476 :``%b``: basename of the exporting repository
1475 1477 :``%h``: short-form changeset hash (12 bytes of hexadecimal)
1476 1478 :``%n``: zero-padded sequence number, starting at 1
1477 1479 :``%r``: zero-padded changeset revision number
1478 1480
1479 1481 Without the -a/--text option, export will avoid generating diffs
1480 1482 of files it detects as binary. With -a, export will generate a
1481 1483 diff anyway, probably with undesirable results.
1482 1484
1483 1485 Use the -g/--git option to generate diffs in the git extended diff
1484 1486 format. See :hg:`help diffs` for more information.
1485 1487
1486 1488 With the --switch-parent option, the diff will be against the
1487 1489 second parent. It can be useful to review a merge.
1488 1490
1489 1491 Returns 0 on success.
1490 1492 """
1491 1493 changesets += tuple(opts.get('rev', []))
1492 1494 if not changesets:
1493 1495 raise util.Abort(_("export requires at least one changeset"))
1494 1496 revs = cmdutil.revrange(repo, changesets)
1495 1497 if len(revs) > 1:
1496 1498 ui.note(_('exporting patches:\n'))
1497 1499 else:
1498 1500 ui.note(_('exporting patch:\n'))
1499 1501 cmdutil.export(repo, revs, template=opts.get('output'),
1500 1502 switch_parent=opts.get('switch_parent'),
1501 1503 opts=patch.diffopts(ui, opts))
1502 1504
1503 1505 def forget(ui, repo, *pats, **opts):
1504 1506 """forget the specified files on the next commit
1505 1507
1506 1508 Mark the specified files so they will no longer be tracked
1507 1509 after the next commit.
1508 1510
1509 1511 This only removes files from the current branch, not from the
1510 1512 entire project history, and it does not delete them from the
1511 1513 working directory.
1512 1514
1513 1515 To undo a forget before the next commit, see :hg:`add`.
1514 1516
1515 1517 Returns 0 on success.
1516 1518 """
1517 1519
1518 1520 if not pats:
1519 1521 raise util.Abort(_('no files specified'))
1520 1522
1521 1523 m = cmdutil.match(repo, pats, opts)
1522 1524 s = repo.status(match=m, clean=True)
1523 1525 forget = sorted(s[0] + s[1] + s[3] + s[6])
1524 1526 errs = 0
1525 1527
1526 1528 for f in m.files():
1527 1529 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1528 1530 ui.warn(_('not removing %s: file is already untracked\n')
1529 1531 % m.rel(f))
1530 1532 errs = 1
1531 1533
1532 1534 for f in forget:
1533 1535 if ui.verbose or not m.exact(f):
1534 1536 ui.status(_('removing %s\n') % m.rel(f))
1535 1537
1536 1538 repo[None].remove(forget, unlink=False)
1537 1539 return errs
1538 1540
1539 1541 def grep(ui, repo, pattern, *pats, **opts):
1540 1542 """search for a pattern in specified files and revisions
1541 1543
1542 1544 Search revisions of files for a regular expression.
1543 1545
1544 1546 This command behaves differently than Unix grep. It only accepts
1545 1547 Python/Perl regexps. It searches repository history, not the
1546 1548 working directory. It always prints the revision number in which a
1547 1549 match appears.
1548 1550
1549 1551 By default, grep only prints output for the first revision of a
1550 1552 file in which it finds a match. To get it to print every revision
1551 1553 that contains a change in match status ("-" for a match that
1552 1554 becomes a non-match, or "+" for a non-match that becomes a match),
1553 1555 use the --all flag.
1554 1556
1555 1557 Returns 0 if a match is found, 1 otherwise.
1556 1558 """
1557 1559 reflags = 0
1558 1560 if opts.get('ignore_case'):
1559 1561 reflags |= re.I
1560 1562 try:
1561 1563 regexp = re.compile(pattern, reflags)
1562 1564 except Exception, inst:
1563 1565 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1564 1566 return 1
1565 1567 sep, eol = ':', '\n'
1566 1568 if opts.get('print0'):
1567 1569 sep = eol = '\0'
1568 1570
1569 1571 getfile = util.lrucachefunc(repo.file)
1570 1572
1571 1573 def matchlines(body):
1572 1574 begin = 0
1573 1575 linenum = 0
1574 1576 while True:
1575 1577 match = regexp.search(body, begin)
1576 1578 if not match:
1577 1579 break
1578 1580 mstart, mend = match.span()
1579 1581 linenum += body.count('\n', begin, mstart) + 1
1580 1582 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1581 1583 begin = body.find('\n', mend) + 1 or len(body)
1582 1584 lend = begin - 1
1583 1585 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1584 1586
1585 1587 class linestate(object):
1586 1588 def __init__(self, line, linenum, colstart, colend):
1587 1589 self.line = line
1588 1590 self.linenum = linenum
1589 1591 self.colstart = colstart
1590 1592 self.colend = colend
1591 1593
1592 1594 def __hash__(self):
1593 1595 return hash((self.linenum, self.line))
1594 1596
1595 1597 def __eq__(self, other):
1596 1598 return self.line == other.line
1597 1599
1598 1600 matches = {}
1599 1601 copies = {}
1600 1602 def grepbody(fn, rev, body):
1601 1603 matches[rev].setdefault(fn, [])
1602 1604 m = matches[rev][fn]
1603 1605 for lnum, cstart, cend, line in matchlines(body):
1604 1606 s = linestate(line, lnum, cstart, cend)
1605 1607 m.append(s)
1606 1608
1607 1609 def difflinestates(a, b):
1608 1610 sm = difflib.SequenceMatcher(None, a, b)
1609 1611 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1610 1612 if tag == 'insert':
1611 1613 for i in xrange(blo, bhi):
1612 1614 yield ('+', b[i])
1613 1615 elif tag == 'delete':
1614 1616 for i in xrange(alo, ahi):
1615 1617 yield ('-', a[i])
1616 1618 elif tag == 'replace':
1617 1619 for i in xrange(alo, ahi):
1618 1620 yield ('-', a[i])
1619 1621 for i in xrange(blo, bhi):
1620 1622 yield ('+', b[i])
1621 1623
1622 1624 def display(fn, ctx, pstates, states):
1623 1625 rev = ctx.rev()
1624 1626 datefunc = ui.quiet and util.shortdate or util.datestr
1625 1627 found = False
1626 1628 filerevmatches = {}
1627 1629 if opts.get('all'):
1628 1630 iter = difflinestates(pstates, states)
1629 1631 else:
1630 1632 iter = [('', l) for l in states]
1631 1633 for change, l in iter:
1632 1634 cols = [fn, str(rev)]
1633 1635 before, match, after = None, None, None
1634 1636 if opts.get('line_number'):
1635 1637 cols.append(str(l.linenum))
1636 1638 if opts.get('all'):
1637 1639 cols.append(change)
1638 1640 if opts.get('user'):
1639 1641 cols.append(ui.shortuser(ctx.user()))
1640 1642 if opts.get('date'):
1641 1643 cols.append(datefunc(ctx.date()))
1642 1644 if opts.get('files_with_matches'):
1643 1645 c = (fn, rev)
1644 1646 if c in filerevmatches:
1645 1647 continue
1646 1648 filerevmatches[c] = 1
1647 1649 else:
1648 1650 before = l.line[:l.colstart]
1649 1651 match = l.line[l.colstart:l.colend]
1650 1652 after = l.line[l.colend:]
1651 1653 ui.write(sep.join(cols))
1652 1654 if before is not None:
1653 1655 ui.write(sep + before)
1654 1656 ui.write(match, label='grep.match')
1655 1657 ui.write(after)
1656 1658 ui.write(eol)
1657 1659 found = True
1658 1660 return found
1659 1661
1660 1662 skip = {}
1661 1663 revfiles = {}
1662 1664 matchfn = cmdutil.match(repo, pats, opts)
1663 1665 found = False
1664 1666 follow = opts.get('follow')
1665 1667
1666 1668 def prep(ctx, fns):
1667 1669 rev = ctx.rev()
1668 1670 pctx = ctx.parents()[0]
1669 1671 parent = pctx.rev()
1670 1672 matches.setdefault(rev, {})
1671 1673 matches.setdefault(parent, {})
1672 1674 files = revfiles.setdefault(rev, [])
1673 1675 for fn in fns:
1674 1676 flog = getfile(fn)
1675 1677 try:
1676 1678 fnode = ctx.filenode(fn)
1677 1679 except error.LookupError:
1678 1680 continue
1679 1681
1680 1682 copied = flog.renamed(fnode)
1681 1683 copy = follow and copied and copied[0]
1682 1684 if copy:
1683 1685 copies.setdefault(rev, {})[fn] = copy
1684 1686 if fn in skip:
1685 1687 if copy:
1686 1688 skip[copy] = True
1687 1689 continue
1688 1690 files.append(fn)
1689 1691
1690 1692 if fn not in matches[rev]:
1691 1693 grepbody(fn, rev, flog.read(fnode))
1692 1694
1693 1695 pfn = copy or fn
1694 1696 if pfn not in matches[parent]:
1695 1697 try:
1696 1698 fnode = pctx.filenode(pfn)
1697 1699 grepbody(pfn, parent, flog.read(fnode))
1698 1700 except error.LookupError:
1699 1701 pass
1700 1702
1701 1703 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1702 1704 rev = ctx.rev()
1703 1705 parent = ctx.parents()[0].rev()
1704 1706 for fn in sorted(revfiles.get(rev, [])):
1705 1707 states = matches[rev][fn]
1706 1708 copy = copies.get(rev, {}).get(fn)
1707 1709 if fn in skip:
1708 1710 if copy:
1709 1711 skip[copy] = True
1710 1712 continue
1711 1713 pstates = matches.get(parent, {}).get(copy or fn, [])
1712 1714 if pstates or states:
1713 1715 r = display(fn, ctx, pstates, states)
1714 1716 found = found or r
1715 1717 if r and not opts.get('all'):
1716 1718 skip[fn] = True
1717 1719 if copy:
1718 1720 skip[copy] = True
1719 1721 del matches[rev]
1720 1722 del revfiles[rev]
1721 1723
1722 1724 return not found
1723 1725
1724 1726 def heads(ui, repo, *branchrevs, **opts):
1725 1727 """show current repository heads or show branch heads
1726 1728
1727 1729 With no arguments, show all repository branch heads.
1728 1730
1729 1731 Repository "heads" are changesets with no child changesets. They are
1730 1732 where development generally takes place and are the usual targets
1731 1733 for update and merge operations. Branch heads are changesets that have
1732 1734 no child changeset on the same branch.
1733 1735
1734 1736 If one or more REVs are given, only branch heads on the branches
1735 1737 associated with the specified changesets are shown.
1736 1738
1737 1739 If -c/--closed is specified, also show branch heads marked closed
1738 1740 (see :hg:`commit --close-branch`).
1739 1741
1740 1742 If STARTREV is specified, only those heads that are descendants of
1741 1743 STARTREV will be displayed.
1742 1744
1743 1745 If -t/--topo is specified, named branch mechanics will be ignored and only
1744 1746 changesets without children will be shown.
1745 1747
1746 1748 Returns 0 if matching heads are found, 1 if not.
1747 1749 """
1748 1750
1749 1751 if opts.get('rev'):
1750 1752 start = repo.lookup(opts['rev'])
1751 1753 else:
1752 1754 start = None
1753 1755
1754 1756 if opts.get('topo'):
1755 1757 heads = [repo[h] for h in repo.heads(start)]
1756 1758 else:
1757 1759 heads = []
1758 1760 for b, ls in repo.branchmap().iteritems():
1759 1761 if start is None:
1760 1762 heads += [repo[h] for h in ls]
1761 1763 continue
1762 1764 startrev = repo.changelog.rev(start)
1763 1765 descendants = set(repo.changelog.descendants(startrev))
1764 1766 descendants.add(startrev)
1765 1767 rev = repo.changelog.rev
1766 1768 heads += [repo[h] for h in ls if rev(h) in descendants]
1767 1769
1768 1770 if branchrevs:
1769 1771 decode, encode = encoding.fromlocal, encoding.tolocal
1770 1772 branches = set(repo[decode(br)].branch() for br in branchrevs)
1771 1773 heads = [h for h in heads if h.branch() in branches]
1772 1774
1773 1775 if not opts.get('closed'):
1774 1776 heads = [h for h in heads if not h.extra().get('close')]
1775 1777
1776 1778 if opts.get('active') and branchrevs:
1777 1779 dagheads = repo.heads(start)
1778 1780 heads = [h for h in heads if h.node() in dagheads]
1779 1781
1780 1782 if branchrevs:
1781 1783 haveheads = set(h.branch() for h in heads)
1782 1784 if branches - haveheads:
1783 1785 headless = ', '.join(encode(b) for b in branches - haveheads)
1784 1786 msg = _('no open branch heads found on branches %s')
1785 1787 if opts.get('rev'):
1786 1788 msg += _(' (started at %s)' % opts['rev'])
1787 1789 ui.warn((msg + '\n') % headless)
1788 1790
1789 1791 if not heads:
1790 1792 return 1
1791 1793
1792 1794 heads = sorted(heads, key=lambda x: -x.rev())
1793 1795 displayer = cmdutil.show_changeset(ui, repo, opts)
1794 1796 for ctx in heads:
1795 1797 displayer.show(ctx)
1796 1798 displayer.close()
1797 1799
1798 1800 def help_(ui, name=None, with_version=False, unknowncmd=False):
1799 1801 """show help for a given topic or a help overview
1800 1802
1801 1803 With no arguments, print a list of commands with short help messages.
1802 1804
1803 1805 Given a topic, extension, or command name, print help for that
1804 1806 topic.
1805 1807
1806 1808 Returns 0 if successful.
1807 1809 """
1808 1810 option_lists = []
1809 1811 textwidth = util.termwidth() - 2
1810 1812
1811 1813 def addglobalopts(aliases):
1812 1814 if ui.verbose:
1813 1815 option_lists.append((_("global options:"), globalopts))
1814 1816 if name == 'shortlist':
1815 1817 option_lists.append((_('use "hg help" for the full list '
1816 1818 'of commands'), ()))
1817 1819 else:
1818 1820 if name == 'shortlist':
1819 1821 msg = _('use "hg help" for the full list of commands '
1820 1822 'or "hg -v" for details')
1821 1823 elif aliases:
1822 1824 msg = _('use "hg -v help%s" to show aliases and '
1823 1825 'global options') % (name and " " + name or "")
1824 1826 else:
1825 1827 msg = _('use "hg -v help %s" to show global options') % name
1826 1828 option_lists.append((msg, ()))
1827 1829
1828 1830 def helpcmd(name):
1829 1831 if with_version:
1830 1832 version_(ui)
1831 1833 ui.write('\n')
1832 1834
1833 1835 try:
1834 1836 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1835 1837 except error.AmbiguousCommand, inst:
1836 1838 # py3k fix: except vars can't be used outside the scope of the
1837 1839 # except block, nor can be used inside a lambda. python issue4617
1838 1840 prefix = inst.args[0]
1839 1841 select = lambda c: c.lstrip('^').startswith(prefix)
1840 1842 helplist(_('list of commands:\n\n'), select)
1841 1843 return
1842 1844
1843 1845 # check if it's an invalid alias and display its error if it is
1844 1846 if getattr(entry[0], 'badalias', False):
1845 1847 if not unknowncmd:
1846 1848 entry[0](ui)
1847 1849 return
1848 1850
1849 1851 # synopsis
1850 1852 if len(entry) > 2:
1851 1853 if entry[2].startswith('hg'):
1852 1854 ui.write("%s\n" % entry[2])
1853 1855 else:
1854 1856 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1855 1857 else:
1856 1858 ui.write('hg %s\n' % aliases[0])
1857 1859
1858 1860 # aliases
1859 1861 if not ui.quiet and len(aliases) > 1:
1860 1862 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1861 1863
1862 1864 # description
1863 1865 doc = gettext(entry[0].__doc__)
1864 1866 if not doc:
1865 1867 doc = _("(no help text available)")
1866 1868 if hasattr(entry[0], 'definition'): # aliased command
1867 1869 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1868 1870 if ui.quiet:
1869 1871 doc = doc.splitlines()[0]
1870 1872 keep = ui.verbose and ['verbose'] or []
1871 1873 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1872 1874 ui.write("\n%s\n" % formatted)
1873 1875 if pruned:
1874 1876 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1875 1877
1876 1878 if not ui.quiet:
1877 1879 # options
1878 1880 if entry[1]:
1879 1881 option_lists.append((_("options:\n"), entry[1]))
1880 1882
1881 1883 addglobalopts(False)
1882 1884
1883 1885 def helplist(header, select=None):
1884 1886 h = {}
1885 1887 cmds = {}
1886 1888 for c, e in table.iteritems():
1887 1889 f = c.split("|", 1)[0]
1888 1890 if select and not select(f):
1889 1891 continue
1890 1892 if (not select and name != 'shortlist' and
1891 1893 e[0].__module__ != __name__):
1892 1894 continue
1893 1895 if name == "shortlist" and not f.startswith("^"):
1894 1896 continue
1895 1897 f = f.lstrip("^")
1896 1898 if not ui.debugflag and f.startswith("debug"):
1897 1899 continue
1898 1900 doc = e[0].__doc__
1899 1901 if doc and 'DEPRECATED' in doc and not ui.verbose:
1900 1902 continue
1901 1903 doc = gettext(doc)
1902 1904 if not doc:
1903 1905 doc = _("(no help text available)")
1904 1906 h[f] = doc.splitlines()[0].rstrip()
1905 1907 cmds[f] = c.lstrip("^")
1906 1908
1907 1909 if not h:
1908 1910 ui.status(_('no commands defined\n'))
1909 1911 return
1910 1912
1911 1913 ui.status(header)
1912 1914 fns = sorted(h)
1913 1915 m = max(map(len, fns))
1914 1916 for f in fns:
1915 1917 if ui.verbose:
1916 1918 commands = cmds[f].replace("|",", ")
1917 1919 ui.write(" %s:\n %s\n"%(commands, h[f]))
1918 1920 else:
1919 1921 ui.write('%s\n' % (util.wrap(h[f],
1920 1922 initindent=' %-*s ' % (m, f),
1921 1923 hangindent=' ' * (m + 4))))
1922 1924
1923 1925 if not ui.quiet:
1924 1926 addglobalopts(True)
1925 1927
1926 1928 def helptopic(name):
1927 1929 for names, header, doc in help.helptable:
1928 1930 if name in names:
1929 1931 break
1930 1932 else:
1931 1933 raise error.UnknownCommand(name)
1932 1934
1933 1935 # description
1934 1936 if not doc:
1935 1937 doc = _("(no help text available)")
1936 1938 if hasattr(doc, '__call__'):
1937 1939 doc = doc()
1938 1940
1939 1941 ui.write("%s\n\n" % header)
1940 1942 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1941 1943
1942 1944 def helpext(name):
1943 1945 try:
1944 1946 mod = extensions.find(name)
1945 1947 doc = gettext(mod.__doc__) or _('no help text available')
1946 1948 except KeyError:
1947 1949 mod = None
1948 1950 doc = extensions.disabledext(name)
1949 1951 if not doc:
1950 1952 raise error.UnknownCommand(name)
1951 1953
1952 1954 if '\n' not in doc:
1953 1955 head, tail = doc, ""
1954 1956 else:
1955 1957 head, tail = doc.split('\n', 1)
1956 1958 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1957 1959 if tail:
1958 1960 ui.write(minirst.format(tail, textwidth))
1959 1961 ui.status('\n\n')
1960 1962
1961 1963 if mod:
1962 1964 try:
1963 1965 ct = mod.cmdtable
1964 1966 except AttributeError:
1965 1967 ct = {}
1966 1968 modcmds = set([c.split('|', 1)[0] for c in ct])
1967 1969 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1968 1970 else:
1969 1971 ui.write(_('use "hg help extensions" for information on enabling '
1970 1972 'extensions\n'))
1971 1973
1972 1974 def helpextcmd(name):
1973 1975 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1974 1976 doc = gettext(mod.__doc__).splitlines()[0]
1975 1977
1976 1978 msg = help.listexts(_("'%s' is provided by the following "
1977 1979 "extension:") % cmd, {ext: doc}, len(ext),
1978 1980 indent=4)
1979 1981 ui.write(minirst.format(msg, textwidth))
1980 1982 ui.write('\n\n')
1981 1983 ui.write(_('use "hg help extensions" for information on enabling '
1982 1984 'extensions\n'))
1983 1985
1984 1986 if name and name != 'shortlist':
1985 1987 i = None
1986 1988 if unknowncmd:
1987 1989 queries = (helpextcmd,)
1988 1990 else:
1989 1991 queries = (helptopic, helpcmd, helpext, helpextcmd)
1990 1992 for f in queries:
1991 1993 try:
1992 1994 f(name)
1993 1995 i = None
1994 1996 break
1995 1997 except error.UnknownCommand, inst:
1996 1998 i = inst
1997 1999 if i:
1998 2000 raise i
1999 2001
2000 2002 else:
2001 2003 # program name
2002 2004 if ui.verbose or with_version:
2003 2005 version_(ui)
2004 2006 else:
2005 2007 ui.status(_("Mercurial Distributed SCM\n"))
2006 2008 ui.status('\n')
2007 2009
2008 2010 # list of commands
2009 2011 if name == "shortlist":
2010 2012 header = _('basic commands:\n\n')
2011 2013 else:
2012 2014 header = _('list of commands:\n\n')
2013 2015
2014 2016 helplist(header)
2015 2017 if name != 'shortlist':
2016 2018 exts, maxlength = extensions.enabled()
2017 2019 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2018 2020 if text:
2019 2021 ui.write("\n%s\n" % minirst.format(text, textwidth))
2020 2022
2021 2023 # list all option lists
2022 2024 opt_output = []
2023 2025 multioccur = False
2024 2026 for title, options in option_lists:
2025 2027 opt_output.append(("\n%s" % title, None))
2026 2028 for option in options:
2027 2029 if len(option) == 5:
2028 2030 shortopt, longopt, default, desc, optlabel = option
2029 2031 else:
2030 2032 shortopt, longopt, default, desc = option
2031 2033 optlabel = _("VALUE") # default label
2032 2034
2033 2035 if _("DEPRECATED") in desc and not ui.verbose:
2034 2036 continue
2035 2037 if isinstance(default, list):
2036 2038 numqualifier = " %s [+]" % optlabel
2037 2039 multioccur = True
2038 2040 elif (default is not None) and not isinstance(default, bool):
2039 2041 numqualifier = " %s" % optlabel
2040 2042 else:
2041 2043 numqualifier = ""
2042 2044 opt_output.append(("%2s%s" %
2043 2045 (shortopt and "-%s" % shortopt,
2044 2046 longopt and " --%s%s" %
2045 2047 (longopt, numqualifier)),
2046 2048 "%s%s" % (desc,
2047 2049 default
2048 2050 and _(" (default: %s)") % default
2049 2051 or "")))
2050 2052 if multioccur:
2051 2053 msg = _("\n[+] marked option can be specified multiple times")
2052 2054 if ui.verbose and name != 'shortlist':
2053 2055 opt_output.append((msg, ()))
2054 2056 else:
2055 2057 opt_output.insert(-1, (msg, ()))
2056 2058
2057 2059 if not name:
2058 2060 ui.write(_("\nadditional help topics:\n\n"))
2059 2061 topics = []
2060 2062 for names, header, doc in help.helptable:
2061 2063 topics.append((sorted(names, key=len, reverse=True)[0], header))
2062 2064 topics_len = max([len(s[0]) for s in topics])
2063 2065 for t, desc in topics:
2064 2066 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2065 2067
2066 2068 if opt_output:
2067 2069 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
2068 2070 for first, second in opt_output:
2069 2071 if second:
2070 2072 initindent = ' %-*s ' % (opts_len, first)
2071 2073 hangindent = ' ' * (opts_len + 3)
2072 2074 ui.write('%s\n' % (util.wrap(second,
2073 2075 initindent=initindent,
2074 2076 hangindent=hangindent)))
2075 2077 else:
2076 2078 ui.write("%s\n" % first)
2077 2079
2078 2080 def identify(ui, repo, source=None,
2079 2081 rev=None, num=None, id=None, branch=None, tags=None):
2080 2082 """identify the working copy or specified revision
2081 2083
2082 2084 With no revision, print a summary of the current state of the
2083 2085 repository.
2084 2086
2085 2087 Specifying a path to a repository root or Mercurial bundle will
2086 2088 cause lookup to operate on that repository/bundle.
2087 2089
2088 2090 This summary identifies the repository state using one or two
2089 2091 parent hash identifiers, followed by a "+" if there are
2090 2092 uncommitted changes in the working directory, a list of tags for
2091 2093 this revision and a branch name for non-default branches.
2092 2094
2093 2095 Returns 0 if successful.
2094 2096 """
2095 2097
2096 2098 if not repo and not source:
2097 2099 raise util.Abort(_("There is no Mercurial repository here "
2098 2100 "(.hg not found)"))
2099 2101
2100 2102 hexfunc = ui.debugflag and hex or short
2101 2103 default = not (num or id or branch or tags)
2102 2104 output = []
2103 2105
2104 2106 revs = []
2105 2107 if source:
2106 2108 source, branches = hg.parseurl(ui.expandpath(source))
2107 2109 repo = hg.repository(ui, source)
2108 2110 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2109 2111
2110 2112 if not repo.local():
2111 2113 if not rev and revs:
2112 2114 rev = revs[0]
2113 2115 if not rev:
2114 2116 rev = "tip"
2115 2117 if num or branch or tags:
2116 2118 raise util.Abort(
2117 2119 "can't query remote revision number, branch, or tags")
2118 2120 output = [hexfunc(repo.lookup(rev))]
2119 2121 elif not rev:
2120 2122 ctx = repo[None]
2121 2123 parents = ctx.parents()
2122 2124 changed = False
2123 2125 if default or id or num:
2124 2126 changed = util.any(repo.status())
2125 2127 if default or id:
2126 2128 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2127 2129 (changed) and "+" or "")]
2128 2130 if num:
2129 2131 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2130 2132 (changed) and "+" or ""))
2131 2133 else:
2132 2134 ctx = repo[rev]
2133 2135 if default or id:
2134 2136 output = [hexfunc(ctx.node())]
2135 2137 if num:
2136 2138 output.append(str(ctx.rev()))
2137 2139
2138 2140 if repo.local() and default and not ui.quiet:
2139 2141 b = encoding.tolocal(ctx.branch())
2140 2142 if b != 'default':
2141 2143 output.append("(%s)" % b)
2142 2144
2143 2145 # multiple tags for a single parent separated by '/'
2144 2146 t = "/".join(ctx.tags())
2145 2147 if t:
2146 2148 output.append(t)
2147 2149
2148 2150 if branch:
2149 2151 output.append(encoding.tolocal(ctx.branch()))
2150 2152
2151 2153 if tags:
2152 2154 output.extend(ctx.tags())
2153 2155
2154 2156 ui.write("%s\n" % ' '.join(output))
2155 2157
2156 2158 def import_(ui, repo, patch1, *patches, **opts):
2157 2159 """import an ordered set of patches
2158 2160
2159 2161 Import a list of patches and commit them individually (unless
2160 2162 --no-commit is specified).
2161 2163
2162 2164 If there are outstanding changes in the working directory, import
2163 2165 will abort unless given the -f/--force flag.
2164 2166
2165 2167 You can import a patch straight from a mail message. Even patches
2166 2168 as attachments work (to use the body part, it must have type
2167 2169 text/plain or text/x-patch). From and Subject headers of email
2168 2170 message are used as default committer and commit message. All
2169 2171 text/plain body parts before first diff are added to commit
2170 2172 message.
2171 2173
2172 2174 If the imported patch was generated by :hg:`export`, user and
2173 2175 description from patch override values from message headers and
2174 2176 body. Values given on command line with -m/--message and -u/--user
2175 2177 override these.
2176 2178
2177 2179 If --exact is specified, import will set the working directory to
2178 2180 the parent of each patch before applying it, and will abort if the
2179 2181 resulting changeset has a different ID than the one recorded in
2180 2182 the patch. This may happen due to character set problems or other
2181 2183 deficiencies in the text patch format.
2182 2184
2183 2185 With -s/--similarity, hg will attempt to discover renames and
2184 2186 copies in the patch in the same way as 'addremove'.
2185 2187
2186 2188 To read a patch from standard input, use "-" as the patch name. If
2187 2189 a URL is specified, the patch will be downloaded from it.
2188 2190 See :hg:`help dates` for a list of formats valid for -d/--date.
2189 2191
2190 2192 Returns 0 on success.
2191 2193 """
2192 2194 patches = (patch1,) + patches
2193 2195
2194 2196 date = opts.get('date')
2195 2197 if date:
2196 2198 opts['date'] = util.parsedate(date)
2197 2199
2198 2200 try:
2199 2201 sim = float(opts.get('similarity') or 0)
2200 2202 except ValueError:
2201 2203 raise util.Abort(_('similarity must be a number'))
2202 2204 if sim < 0 or sim > 100:
2203 2205 raise util.Abort(_('similarity must be between 0 and 100'))
2204 2206
2205 2207 if opts.get('exact') or not opts.get('force'):
2206 2208 cmdutil.bail_if_changed(repo)
2207 2209
2208 2210 d = opts["base"]
2209 2211 strip = opts["strip"]
2210 2212 wlock = lock = None
2211 2213
2212 2214 def tryone(ui, hunk):
2213 2215 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2214 2216 patch.extract(ui, hunk)
2215 2217
2216 2218 if not tmpname:
2217 2219 return None
2218 2220 commitid = _('to working directory')
2219 2221
2220 2222 try:
2221 2223 cmdline_message = cmdutil.logmessage(opts)
2222 2224 if cmdline_message:
2223 2225 # pickup the cmdline msg
2224 2226 message = cmdline_message
2225 2227 elif message:
2226 2228 # pickup the patch msg
2227 2229 message = message.strip()
2228 2230 else:
2229 2231 # launch the editor
2230 2232 message = None
2231 2233 ui.debug('message:\n%s\n' % message)
2232 2234
2233 2235 wp = repo.parents()
2234 2236 if opts.get('exact'):
2235 2237 if not nodeid or not p1:
2236 2238 raise util.Abort(_('not a Mercurial patch'))
2237 2239 p1 = repo.lookup(p1)
2238 2240 p2 = repo.lookup(p2 or hex(nullid))
2239 2241
2240 2242 if p1 != wp[0].node():
2241 2243 hg.clean(repo, p1)
2242 2244 repo.dirstate.setparents(p1, p2)
2243 2245 elif p2:
2244 2246 try:
2245 2247 p1 = repo.lookup(p1)
2246 2248 p2 = repo.lookup(p2)
2247 2249 if p1 == wp[0].node():
2248 2250 repo.dirstate.setparents(p1, p2)
2249 2251 except error.RepoError:
2250 2252 pass
2251 2253 if opts.get('exact') or opts.get('import_branch'):
2252 2254 repo.dirstate.setbranch(branch or 'default')
2253 2255
2254 2256 files = {}
2255 2257 try:
2256 2258 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2257 2259 files=files, eolmode=None)
2258 2260 finally:
2259 2261 files = patch.updatedir(ui, repo, files,
2260 2262 similarity=sim / 100.0)
2261 2263 if not opts.get('no_commit'):
2262 2264 if opts.get('exact'):
2263 2265 m = None
2264 2266 else:
2265 2267 m = cmdutil.matchfiles(repo, files or [])
2266 2268 n = repo.commit(message, opts.get('user') or user,
2267 2269 opts.get('date') or date, match=m,
2268 2270 editor=cmdutil.commiteditor)
2269 2271 if opts.get('exact'):
2270 2272 if hex(n) != nodeid:
2271 2273 repo.rollback()
2272 2274 raise util.Abort(_('patch is damaged'
2273 2275 ' or loses information'))
2274 2276 # Force a dirstate write so that the next transaction
2275 2277 # backups an up-do-date file.
2276 2278 repo.dirstate.write()
2277 2279 if n:
2278 2280 commitid = short(n)
2279 2281
2280 2282 return commitid
2281 2283 finally:
2282 2284 os.unlink(tmpname)
2283 2285
2284 2286 try:
2285 2287 wlock = repo.wlock()
2286 2288 lock = repo.lock()
2287 2289 lastcommit = None
2288 2290 for p in patches:
2289 2291 pf = os.path.join(d, p)
2290 2292
2291 2293 if pf == '-':
2292 2294 ui.status(_("applying patch from stdin\n"))
2293 2295 pf = sys.stdin
2294 2296 else:
2295 2297 ui.status(_("applying %s\n") % p)
2296 2298 pf = url.open(ui, pf)
2297 2299
2298 2300 haspatch = False
2299 2301 for hunk in patch.split(pf):
2300 2302 commitid = tryone(ui, hunk)
2301 2303 if commitid:
2302 2304 haspatch = True
2303 2305 if lastcommit:
2304 2306 ui.status(_('applied %s\n') % lastcommit)
2305 2307 lastcommit = commitid
2306 2308
2307 2309 if not haspatch:
2308 2310 raise util.Abort(_('no diffs found'))
2309 2311
2310 2312 finally:
2311 2313 release(lock, wlock)
2312 2314
2313 2315 def incoming(ui, repo, source="default", **opts):
2314 2316 """show new changesets found in source
2315 2317
2316 2318 Show new changesets found in the specified path/URL or the default
2317 2319 pull location. These are the changesets that would have been pulled
2318 2320 if a pull at the time you issued this command.
2319 2321
2320 2322 For remote repository, using --bundle avoids downloading the
2321 2323 changesets twice if the incoming is followed by a pull.
2322 2324
2323 2325 See pull for valid source format details.
2324 2326
2325 2327 Returns 0 if there are incoming changes, 1 otherwise.
2326 2328 """
2327 2329 limit = cmdutil.loglimit(opts)
2328 2330 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2329 2331 other = hg.repository(hg.remoteui(repo, opts), source)
2330 2332 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2331 2333 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2332 2334 if revs:
2333 2335 revs = [other.lookup(rev) for rev in revs]
2334 2336
2335 2337 tmp = discovery.findcommonincoming(repo, other, heads=revs,
2336 2338 force=opts.get('force'))
2337 2339 common, incoming, rheads = tmp
2338 2340 if not incoming:
2339 2341 try:
2340 2342 os.unlink(opts["bundle"])
2341 2343 except:
2342 2344 pass
2343 2345 ui.status(_("no changes found\n"))
2344 2346 return 1
2345 2347
2346 2348 cleanup = None
2347 2349 try:
2348 2350 fname = opts["bundle"]
2349 2351 if fname or not other.local():
2350 2352 # create a bundle (uncompressed if other repo is not local)
2351 2353
2352 2354 if revs is None and other.capable('changegroupsubset'):
2353 2355 revs = rheads
2354 2356
2355 2357 if revs is None:
2356 2358 cg = other.changegroup(incoming, "incoming")
2357 2359 else:
2358 2360 cg = other.changegroupsubset(incoming, revs, 'incoming')
2359 2361 bundletype = other.local() and "HG10BZ" or "HG10UN"
2360 2362 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2361 2363 # keep written bundle?
2362 2364 if opts["bundle"]:
2363 2365 cleanup = None
2364 2366 if not other.local():
2365 2367 # use the created uncompressed bundlerepo
2366 2368 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2367 2369
2368 2370 o = other.changelog.nodesbetween(incoming, revs)[0]
2369 2371 if opts.get('newest_first'):
2370 2372 o.reverse()
2371 2373 displayer = cmdutil.show_changeset(ui, other, opts)
2372 2374 count = 0
2373 2375 for n in o:
2374 2376 if limit is not None and count >= limit:
2375 2377 break
2376 2378 parents = [p for p in other.changelog.parents(n) if p != nullid]
2377 2379 if opts.get('no_merges') and len(parents) == 2:
2378 2380 continue
2379 2381 count += 1
2380 2382 displayer.show(other[n])
2381 2383 displayer.close()
2382 2384 finally:
2383 2385 if hasattr(other, 'close'):
2384 2386 other.close()
2385 2387 if cleanup:
2386 2388 os.unlink(cleanup)
2387 2389
2388 2390 def init(ui, dest=".", **opts):
2389 2391 """create a new repository in the given directory
2390 2392
2391 2393 Initialize a new repository in the given directory. If the given
2392 2394 directory does not exist, it will be created.
2393 2395
2394 2396 If no directory is given, the current directory is used.
2395 2397
2396 2398 It is possible to specify an ``ssh://`` URL as the destination.
2397 2399 See :hg:`help urls` for more information.
2398 2400
2399 2401 Returns 0 on success.
2400 2402 """
2401 2403 hg.repository(hg.remoteui(ui, opts), dest, create=1)
2402 2404
2403 2405 def locate(ui, repo, *pats, **opts):
2404 2406 """locate files matching specific patterns
2405 2407
2406 2408 Print files under Mercurial control in the working directory whose
2407 2409 names match the given patterns.
2408 2410
2409 2411 By default, this command searches all directories in the working
2410 2412 directory. To search just the current directory and its
2411 2413 subdirectories, use "--include .".
2412 2414
2413 2415 If no patterns are given to match, this command prints the names
2414 2416 of all files under Mercurial control in the working directory.
2415 2417
2416 2418 If you want to feed the output of this command into the "xargs"
2417 2419 command, use the -0 option to both this command and "xargs". This
2418 2420 will avoid the problem of "xargs" treating single filenames that
2419 2421 contain whitespace as multiple filenames.
2420 2422
2421 2423 Returns 0 if a match is found, 1 otherwise.
2422 2424 """
2423 2425 end = opts.get('print0') and '\0' or '\n'
2424 2426 rev = opts.get('rev') or None
2425 2427
2426 2428 ret = 1
2427 2429 m = cmdutil.match(repo, pats, opts, default='relglob')
2428 2430 m.bad = lambda x, y: False
2429 2431 for abs in repo[rev].walk(m):
2430 2432 if not rev and abs not in repo.dirstate:
2431 2433 continue
2432 2434 if opts.get('fullpath'):
2433 2435 ui.write(repo.wjoin(abs), end)
2434 2436 else:
2435 2437 ui.write(((pats and m.rel(abs)) or abs), end)
2436 2438 ret = 0
2437 2439
2438 2440 return ret
2439 2441
2440 2442 def log(ui, repo, *pats, **opts):
2441 2443 """show revision history of entire repository or files
2442 2444
2443 2445 Print the revision history of the specified files or the entire
2444 2446 project.
2445 2447
2446 2448 File history is shown without following rename or copy history of
2447 2449 files. Use -f/--follow with a filename to follow history across
2448 2450 renames and copies. --follow without a filename will only show
2449 2451 ancestors or descendants of the starting revision. --follow-first
2450 2452 only follows the first parent of merge revisions.
2451 2453
2452 2454 If no revision range is specified, the default is tip:0 unless
2453 2455 --follow is set, in which case the working directory parent is
2454 2456 used as the starting revision. You can specify a revision set for
2455 2457 log, see :hg:`help revsets` for more information.
2456 2458
2457 2459 See :hg:`help dates` for a list of formats valid for -d/--date.
2458 2460
2459 2461 By default this command prints revision number and changeset id,
2460 2462 tags, non-trivial parents, user, date and time, and a summary for
2461 2463 each commit. When the -v/--verbose switch is used, the list of
2462 2464 changed files and full commit message are shown.
2463 2465
2464 2466 NOTE: log -p/--patch may generate unexpected diff output for merge
2465 2467 changesets, as it will only compare the merge changeset against
2466 2468 its first parent. Also, only files different from BOTH parents
2467 2469 will appear in files:.
2468 2470
2469 2471 Returns 0 on success.
2470 2472 """
2471 2473
2472 2474 matchfn = cmdutil.match(repo, pats, opts)
2473 2475 limit = cmdutil.loglimit(opts)
2474 2476 count = 0
2475 2477
2476 2478 endrev = None
2477 2479 if opts.get('copies') and opts.get('rev'):
2478 2480 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2479 2481
2480 2482 df = False
2481 2483 if opts["date"]:
2482 2484 df = util.matchdate(opts["date"])
2483 2485
2484 2486 branches = opts.get('branch', []) + opts.get('only_branch', [])
2485 2487 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2486 2488
2487 2489 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2488 2490 def prep(ctx, fns):
2489 2491 rev = ctx.rev()
2490 2492 parents = [p for p in repo.changelog.parentrevs(rev)
2491 2493 if p != nullrev]
2492 2494 if opts.get('no_merges') and len(parents) == 2:
2493 2495 return
2494 2496 if opts.get('only_merges') and len(parents) != 2:
2495 2497 return
2496 2498 if opts.get('branch') and ctx.branch() not in opts['branch']:
2497 2499 return
2498 2500 if df and not df(ctx.date()[0]):
2499 2501 return
2500 2502 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2501 2503 return
2502 2504 if opts.get('keyword'):
2503 2505 for k in [kw.lower() for kw in opts['keyword']]:
2504 2506 if (k in ctx.user().lower() or
2505 2507 k in ctx.description().lower() or
2506 2508 k in " ".join(ctx.files()).lower()):
2507 2509 break
2508 2510 else:
2509 2511 return
2510 2512
2511 2513 copies = None
2512 2514 if opts.get('copies') and rev:
2513 2515 copies = []
2514 2516 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2515 2517 for fn in ctx.files():
2516 2518 rename = getrenamed(fn, rev)
2517 2519 if rename:
2518 2520 copies.append((fn, rename[0]))
2519 2521
2520 2522 revmatchfn = None
2521 2523 if opts.get('patch') or opts.get('stat'):
2522 2524 revmatchfn = cmdutil.match(repo, fns)
2523 2525
2524 2526 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2525 2527
2526 2528 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2527 2529 if count == limit:
2528 2530 break
2529 2531 if displayer.flush(ctx.rev()):
2530 2532 count += 1
2531 2533 displayer.close()
2532 2534
2533 2535 def manifest(ui, repo, node=None, rev=None):
2534 2536 """output the current or given revision of the project manifest
2535 2537
2536 2538 Print a list of version controlled files for the given revision.
2537 2539 If no revision is given, the first parent of the working directory
2538 2540 is used, or the null revision if no revision is checked out.
2539 2541
2540 2542 With -v, print file permissions, symlink and executable bits.
2541 2543 With --debug, print file revision hashes.
2542 2544
2543 2545 Returns 0 on success.
2544 2546 """
2545 2547
2546 2548 if rev and node:
2547 2549 raise util.Abort(_("please specify just one revision"))
2548 2550
2549 2551 if not node:
2550 2552 node = rev
2551 2553
2552 2554 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2553 2555 ctx = repo[node]
2554 2556 for f in ctx:
2555 2557 if ui.debugflag:
2556 2558 ui.write("%40s " % hex(ctx.manifest()[f]))
2557 2559 if ui.verbose:
2558 2560 ui.write(decor[ctx.flags(f)])
2559 2561 ui.write("%s\n" % f)
2560 2562
2561 2563 def merge(ui, repo, node=None, **opts):
2562 2564 """merge working directory with another revision
2563 2565
2564 2566 The current working directory is updated with all changes made in
2565 2567 the requested revision since the last common predecessor revision.
2566 2568
2567 2569 Files that changed between either parent are marked as changed for
2568 2570 the next commit and a commit must be performed before any further
2569 2571 updates to the repository are allowed. The next commit will have
2570 2572 two parents.
2571 2573
2572 2574 If no revision is specified, the working directory's parent is a
2573 2575 head revision, and the current branch contains exactly one other
2574 2576 head, the other head is merged with by default. Otherwise, an
2575 2577 explicit revision with which to merge with must be provided.
2576 2578
2577 2579 To undo an uncommitted merge, use :hg:`update --clean .` which
2578 2580 will check out a clean copy of the original merge parent, losing
2579 2581 all changes.
2580 2582
2581 2583 Returns 0 on success, 1 if there are unresolved files.
2582 2584 """
2583 2585
2584 2586 if opts.get('rev') and node:
2585 2587 raise util.Abort(_("please specify just one revision"))
2586 2588 if not node:
2587 2589 node = opts.get('rev')
2588 2590
2589 2591 if not node:
2590 2592 branch = repo.changectx(None).branch()
2591 2593 bheads = repo.branchheads(branch)
2592 2594 if len(bheads) > 2:
2593 2595 raise util.Abort(_(
2594 2596 'branch \'%s\' has %d heads - '
2595 2597 'please merge with an explicit rev\n'
2596 2598 '(run \'hg heads .\' to see heads)')
2597 2599 % (branch, len(bheads)))
2598 2600
2599 2601 parent = repo.dirstate.parents()[0]
2600 2602 if len(bheads) == 1:
2601 2603 if len(repo.heads()) > 1:
2602 2604 raise util.Abort(_(
2603 2605 'branch \'%s\' has one head - '
2604 2606 'please merge with an explicit rev\n'
2605 2607 '(run \'hg heads\' to see all heads)')
2606 2608 % branch)
2607 2609 msg = _('there is nothing to merge')
2608 2610 if parent != repo.lookup(repo[None].branch()):
2609 2611 msg = _('%s - use "hg update" instead') % msg
2610 2612 raise util.Abort(msg)
2611 2613
2612 2614 if parent not in bheads:
2613 2615 raise util.Abort(_('working dir not at a head rev - '
2614 2616 'use "hg update" or merge with an explicit rev'))
2615 2617 node = parent == bheads[0] and bheads[-1] or bheads[0]
2616 2618
2617 2619 if opts.get('preview'):
2618 2620 # find nodes that are ancestors of p2 but not of p1
2619 2621 p1 = repo.lookup('.')
2620 2622 p2 = repo.lookup(node)
2621 2623 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2622 2624
2623 2625 displayer = cmdutil.show_changeset(ui, repo, opts)
2624 2626 for node in nodes:
2625 2627 displayer.show(repo[node])
2626 2628 displayer.close()
2627 2629 return 0
2628 2630
2629 2631 return hg.merge(repo, node, force=opts.get('force'))
2630 2632
2631 2633 def outgoing(ui, repo, dest=None, **opts):
2632 2634 """show changesets not found in the destination
2633 2635
2634 2636 Show changesets not found in the specified destination repository
2635 2637 or the default push location. These are the changesets that would
2636 2638 be pushed if a push was requested.
2637 2639
2638 2640 See pull for details of valid destination formats.
2639 2641
2640 2642 Returns 0 if there are outgoing changes, 1 otherwise.
2641 2643 """
2642 2644 limit = cmdutil.loglimit(opts)
2643 2645 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2644 2646 dest, branches = hg.parseurl(dest, opts.get('branch'))
2645 2647 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2646 2648 if revs:
2647 2649 revs = [repo.lookup(rev) for rev in revs]
2648 2650
2649 2651 other = hg.repository(hg.remoteui(repo, opts), dest)
2650 2652 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2651 2653 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
2652 2654 if not o:
2653 2655 ui.status(_("no changes found\n"))
2654 2656 return 1
2655 2657 o = repo.changelog.nodesbetween(o, revs)[0]
2656 2658 if opts.get('newest_first'):
2657 2659 o.reverse()
2658 2660 displayer = cmdutil.show_changeset(ui, repo, opts)
2659 2661 count = 0
2660 2662 for n in o:
2661 2663 if limit is not None and count >= limit:
2662 2664 break
2663 2665 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2664 2666 if opts.get('no_merges') and len(parents) == 2:
2665 2667 continue
2666 2668 count += 1
2667 2669 displayer.show(repo[n])
2668 2670 displayer.close()
2669 2671
2670 2672 def parents(ui, repo, file_=None, **opts):
2671 2673 """show the parents of the working directory or revision
2672 2674
2673 2675 Print the working directory's parent revisions. If a revision is
2674 2676 given via -r/--rev, the parent of that revision will be printed.
2675 2677 If a file argument is given, the revision in which the file was
2676 2678 last changed (before the working directory revision or the
2677 2679 argument to --rev if given) is printed.
2678 2680
2679 2681 Returns 0 on success.
2680 2682 """
2681 2683 rev = opts.get('rev')
2682 2684 if rev:
2683 2685 ctx = repo[rev]
2684 2686 else:
2685 2687 ctx = repo[None]
2686 2688
2687 2689 if file_:
2688 2690 m = cmdutil.match(repo, (file_,), opts)
2689 2691 if m.anypats() or len(m.files()) != 1:
2690 2692 raise util.Abort(_('can only specify an explicit filename'))
2691 2693 file_ = m.files()[0]
2692 2694 filenodes = []
2693 2695 for cp in ctx.parents():
2694 2696 if not cp:
2695 2697 continue
2696 2698 try:
2697 2699 filenodes.append(cp.filenode(file_))
2698 2700 except error.LookupError:
2699 2701 pass
2700 2702 if not filenodes:
2701 2703 raise util.Abort(_("'%s' not found in manifest!") % file_)
2702 2704 fl = repo.file(file_)
2703 2705 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2704 2706 else:
2705 2707 p = [cp.node() for cp in ctx.parents()]
2706 2708
2707 2709 displayer = cmdutil.show_changeset(ui, repo, opts)
2708 2710 for n in p:
2709 2711 if n != nullid:
2710 2712 displayer.show(repo[n])
2711 2713 displayer.close()
2712 2714
2713 2715 def paths(ui, repo, search=None):
2714 2716 """show aliases for remote repositories
2715 2717
2716 2718 Show definition of symbolic path name NAME. If no name is given,
2717 2719 show definition of all available names.
2718 2720
2719 2721 Path names are defined in the [paths] section of
2720 2722 ``/etc/mercurial/hgrc`` and ``$HOME/.hgrc``. If run inside a
2721 2723 repository, ``.hg/hgrc`` is used, too.
2722 2724
2723 2725 The path names ``default`` and ``default-push`` have a special
2724 2726 meaning. When performing a push or pull operation, they are used
2725 2727 as fallbacks if no location is specified on the command-line.
2726 2728 When ``default-push`` is set, it will be used for push and
2727 2729 ``default`` will be used for pull; otherwise ``default`` is used
2728 2730 as the fallback for both. When cloning a repository, the clone
2729 2731 source is written as ``default`` in ``.hg/hgrc``. Note that
2730 2732 ``default`` and ``default-push`` apply to all inbound (e.g.
2731 2733 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2732 2734 :hg:`bundle`) operations.
2733 2735
2734 2736 See :hg:`help urls` for more information.
2737
2738 Returns 0 on success.
2735 2739 """
2736 2740 if search:
2737 2741 for name, path in ui.configitems("paths"):
2738 2742 if name == search:
2739 2743 ui.write("%s\n" % url.hidepassword(path))
2740 2744 return
2741 2745 ui.warn(_("not found!\n"))
2742 2746 return 1
2743 2747 else:
2744 2748 for name, path in ui.configitems("paths"):
2745 2749 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2746 2750
2747 2751 def postincoming(ui, repo, modheads, optupdate, checkout):
2748 2752 if modheads == 0:
2749 2753 return
2750 2754 if optupdate:
2751 2755 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2752 2756 return hg.update(repo, checkout)
2753 2757 else:
2754 2758 ui.status(_("not updating, since new heads added\n"))
2755 2759 if modheads > 1:
2756 2760 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2757 2761 else:
2758 2762 ui.status(_("(run 'hg update' to get a working copy)\n"))
2759 2763
2760 2764 def pull(ui, repo, source="default", **opts):
2761 2765 """pull changes from the specified source
2762 2766
2763 2767 Pull changes from a remote repository to a local one.
2764 2768
2765 2769 This finds all changes from the repository at the specified path
2766 2770 or URL and adds them to a local repository (the current one unless
2767 2771 -R is specified). By default, this does not update the copy of the
2768 2772 project in the working directory.
2769 2773
2770 2774 Use :hg:`incoming` if you want to see what would have been added
2771 2775 by a pull at the time you issued this command. If you then decide
2772 2776 to add those changes to the repository, you should use :hg:`pull
2773 2777 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2774 2778
2775 2779 If SOURCE is omitted, the 'default' path will be used.
2776 2780 See :hg:`help urls` for more information.
2777 2781
2778 2782 Returns 0 on success, 1 if an update had unresolved files.
2779 2783 """
2780 2784 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2781 2785 other = hg.repository(hg.remoteui(repo, opts), source)
2782 2786 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2783 2787 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2784 2788 if revs:
2785 2789 try:
2786 2790 revs = [other.lookup(rev) for rev in revs]
2787 2791 except error.CapabilityError:
2788 2792 err = _("Other repository doesn't support revision lookup, "
2789 2793 "so a rev cannot be specified.")
2790 2794 raise util.Abort(err)
2791 2795
2792 2796 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2793 2797 if checkout:
2794 2798 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2795 2799 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2796 2800
2797 2801 def push(ui, repo, dest=None, **opts):
2798 2802 """push changes to the specified destination
2799 2803
2800 2804 Push changesets from the local repository to the specified
2801 2805 destination.
2802 2806
2803 2807 This operation is symmetrical to pull: it is identical to a pull
2804 2808 in the destination repository from the current one.
2805 2809
2806 2810 By default, push will not allow creation of new heads at the
2807 2811 destination, since multiple heads would make it unclear which head
2808 2812 to use. In this situation, it is recommended to pull and merge
2809 2813 before pushing.
2810 2814
2811 2815 Use --new-branch if you want to allow push to create a new named
2812 2816 branch that is not present at the destination. This allows you to
2813 2817 only create a new branch without forcing other changes.
2814 2818
2815 2819 Use -f/--force to override the default behavior and push all
2816 2820 changesets on all branches.
2817 2821
2818 2822 If -r/--rev is used, the specified revision and all its ancestors
2819 2823 will be pushed to the remote repository.
2820 2824
2821 2825 Please see :hg:`help urls` for important details about ``ssh://``
2822 2826 URLs. If DESTINATION is omitted, a default path will be used.
2823 2827
2824 2828 Returns 0 if push was successful, 1 if nothing to push.
2825 2829 """
2826 2830 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2827 2831 dest, branches = hg.parseurl(dest, opts.get('branch'))
2828 2832 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2829 2833 other = hg.repository(hg.remoteui(repo, opts), dest)
2830 2834 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2831 2835 if revs:
2832 2836 revs = [repo.lookup(rev) for rev in revs]
2833 2837
2834 2838 # push subrepos depth-first for coherent ordering
2835 2839 c = repo['']
2836 2840 subs = c.substate # only repos that are committed
2837 2841 for s in sorted(subs):
2838 2842 if not c.sub(s).push(opts.get('force')):
2839 2843 return False
2840 2844
2841 2845 r = repo.push(other, opts.get('force'), revs=revs,
2842 2846 newbranch=opts.get('new_branch'))
2843 2847 return r == 0
2844 2848
2845 2849 def recover(ui, repo):
2846 2850 """roll back an interrupted transaction
2847 2851
2848 2852 Recover from an interrupted commit or pull.
2849 2853
2850 2854 This command tries to fix the repository status after an
2851 2855 interrupted operation. It should only be necessary when Mercurial
2852 2856 suggests it.
2853 2857
2854 2858 Returns 0 if successful, 1 if nothing to recover or verify fails.
2855 2859 """
2856 2860 if repo.recover():
2857 2861 return hg.verify(repo)
2858 2862 return 1
2859 2863
2860 2864 def remove(ui, repo, *pats, **opts):
2861 2865 """remove the specified files on the next commit
2862 2866
2863 2867 Schedule the indicated files for removal from the repository.
2864 2868
2865 2869 This only removes files from the current branch, not from the
2866 2870 entire project history. -A/--after can be used to remove only
2867 2871 files that have already been deleted, -f/--force can be used to
2868 2872 force deletion, and -Af can be used to remove files from the next
2869 2873 revision without deleting them from the working directory.
2870 2874
2871 2875 The following table details the behavior of remove for different
2872 2876 file states (columns) and option combinations (rows). The file
2873 2877 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2874 2878 reported by :hg:`status`). The actions are Warn, Remove (from
2875 2879 branch) and Delete (from disk)::
2876 2880
2877 2881 A C M !
2878 2882 none W RD W R
2879 2883 -f R RD RD R
2880 2884 -A W W W R
2881 2885 -Af R R R R
2882 2886
2883 2887 This command schedules the files to be removed at the next commit.
2884 2888 To undo a remove before that, see :hg:`revert`.
2885 2889
2886 2890 Returns 0 on success, 1 if any warnings encountered.
2887 2891 """
2888 2892
2889 2893 ret = 0
2890 2894 after, force = opts.get('after'), opts.get('force')
2891 2895 if not pats and not after:
2892 2896 raise util.Abort(_('no files specified'))
2893 2897
2894 2898 m = cmdutil.match(repo, pats, opts)
2895 2899 s = repo.status(match=m, clean=True)
2896 2900 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2897 2901
2898 2902 for f in m.files():
2899 2903 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2900 2904 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2901 2905 ret = 1
2902 2906
2903 2907 def warn(files, reason):
2904 2908 for f in files:
2905 2909 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2906 2910 % (m.rel(f), reason))
2907 2911 ret = 1
2908 2912
2909 2913 if force:
2910 2914 remove, forget = modified + deleted + clean, added
2911 2915 elif after:
2912 2916 remove, forget = deleted, []
2913 2917 warn(modified + added + clean, _('still exists'))
2914 2918 else:
2915 2919 remove, forget = deleted + clean, []
2916 2920 warn(modified, _('is modified'))
2917 2921 warn(added, _('has been marked for add'))
2918 2922
2919 2923 for f in sorted(remove + forget):
2920 2924 if ui.verbose or not m.exact(f):
2921 2925 ui.status(_('removing %s\n') % m.rel(f))
2922 2926
2923 2927 repo[None].forget(forget)
2924 2928 repo[None].remove(remove, unlink=not after)
2925 2929 return ret
2926 2930
2927 2931 def rename(ui, repo, *pats, **opts):
2928 2932 """rename files; equivalent of copy + remove
2929 2933
2930 2934 Mark dest as copies of sources; mark sources for deletion. If dest
2931 2935 is a directory, copies are put in that directory. If dest is a
2932 2936 file, there can only be one source.
2933 2937
2934 2938 By default, this command copies the contents of files as they
2935 2939 exist in the working directory. If invoked with -A/--after, the
2936 2940 operation is recorded, but no copying is performed.
2937 2941
2938 2942 This command takes effect at the next commit. To undo a rename
2939 2943 before that, see :hg:`revert`.
2940 2944
2941 2945 Returns 0 on success, 1 if errors are encountered.
2942 2946 """
2943 2947 wlock = repo.wlock(False)
2944 2948 try:
2945 2949 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2946 2950 finally:
2947 2951 wlock.release()
2948 2952
2949 2953 def resolve(ui, repo, *pats, **opts):
2950 2954 """various operations to help finish a merge
2951 2955
2952 2956 This command includes several actions that are often useful while
2953 2957 performing a merge, after running ``merge`` but before running
2954 2958 ``commit``. (It is only meaningful if your working directory has
2955 2959 two parents.) It is most relevant for merges with unresolved
2956 2960 conflicts, which are typically a result of non-interactive merging with
2957 2961 ``internal:merge`` or a command-line merge tool like ``diff3``.
2958 2962
2959 2963 The available actions are:
2960 2964
2961 2965 1) list files that were merged with conflicts (U, for unresolved)
2962 2966 and without conflicts (R, for resolved): ``hg resolve -l``
2963 2967 (this is like ``status`` for merges)
2964 2968 2) record that you have resolved conflicts in certain files:
2965 2969 ``hg resolve -m [file ...]`` (default: mark all unresolved files)
2966 2970 3) forget that you have resolved conflicts in certain files:
2967 2971 ``hg resolve -u [file ...]`` (default: unmark all resolved files)
2968 2972 4) discard your current attempt(s) at resolving conflicts and
2969 2973 restart the merge from scratch: ``hg resolve file...``
2970 2974 (or ``-a`` for all unresolved files)
2971 2975
2972 2976 Note that Mercurial will not let you commit files with unresolved merge
2973 2977 conflicts. You must use ``hg resolve -m ...`` before you can commit
2974 2978 after a conflicting merge.
2975 2979
2976 2980 Returns 0 on success, 1 if any files fail a resolve attempt.
2977 2981 """
2978 2982
2979 2983 all, mark, unmark, show, nostatus = \
2980 2984 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2981 2985
2982 2986 if (show and (mark or unmark)) or (mark and unmark):
2983 2987 raise util.Abort(_("too many options specified"))
2984 2988 if pats and all:
2985 2989 raise util.Abort(_("can't specify --all and patterns"))
2986 2990 if not (all or pats or show or mark or unmark):
2987 2991 raise util.Abort(_('no files or directories specified; '
2988 2992 'use --all to remerge all files'))
2989 2993
2990 2994 ms = mergemod.mergestate(repo)
2991 2995 m = cmdutil.match(repo, pats, opts)
2992 2996 ret = 0
2993 2997
2994 2998 for f in ms:
2995 2999 if m(f):
2996 3000 if show:
2997 3001 if nostatus:
2998 3002 ui.write("%s\n" % f)
2999 3003 else:
3000 3004 ui.write("%s %s\n" % (ms[f].upper(), f),
3001 3005 label='resolve.' +
3002 3006 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3003 3007 elif mark:
3004 3008 ms.mark(f, "r")
3005 3009 elif unmark:
3006 3010 ms.mark(f, "u")
3007 3011 else:
3008 3012 wctx = repo[None]
3009 3013 mctx = wctx.parents()[-1]
3010 3014
3011 3015 # backup pre-resolve (merge uses .orig for its own purposes)
3012 3016 a = repo.wjoin(f)
3013 3017 util.copyfile(a, a + ".resolve")
3014 3018
3015 3019 # resolve file
3016 3020 if ms.resolve(f, wctx, mctx):
3017 3021 ret = 1
3018 3022
3019 3023 # replace filemerge's .orig file with our resolve file
3020 3024 util.rename(a + ".resolve", a + ".orig")
3021 3025 return ret
3022 3026
3023 3027 def revert(ui, repo, *pats, **opts):
3024 3028 """restore individual files or directories to an earlier state
3025 3029
3026 3030 NOTE: This command is most likely not what you are looking for. revert
3027 3031 will partially overwrite content in the working directory without changing
3028 3032 the working directory parents. Use :hg:`update -r rev` to check out earlier
3029 3033 revisions, or :hg:`update --clean .` to undo a merge which has added
3030 3034 another parent.
3031 3035
3032 3036 With no revision specified, revert the named files or directories
3033 3037 to the contents they had in the parent of the working directory.
3034 3038 This restores the contents of the affected files to an unmodified
3035 3039 state and unschedules adds, removes, copies, and renames. If the
3036 3040 working directory has two parents, you must explicitly specify a
3037 3041 revision.
3038 3042
3039 3043 Using the -r/--rev option, revert the given files or directories
3040 3044 to their contents as of a specific revision. This can be helpful
3041 3045 to "roll back" some or all of an earlier change. See :hg:`help
3042 3046 dates` for a list of formats valid for -d/--date.
3043 3047
3044 3048 Revert modifies the working directory. It does not commit any
3045 3049 changes, or change the parent of the working directory. If you
3046 3050 revert to a revision other than the parent of the working
3047 3051 directory, the reverted files will thus appear modified
3048 3052 afterwards.
3049 3053
3050 3054 If a file has been deleted, it is restored. If the executable mode
3051 3055 of a file was changed, it is reset.
3052 3056
3053 3057 If names are given, all files matching the names are reverted.
3054 3058 If no arguments are given, no files are reverted.
3055 3059
3056 3060 Modified files are saved with a .orig suffix before reverting.
3057 3061 To disable these backups, use --no-backup.
3058 3062
3059 3063 Returns 0 on success.
3060 3064 """
3061 3065
3062 3066 if opts["date"]:
3063 3067 if opts["rev"]:
3064 3068 raise util.Abort(_("you can't specify a revision and a date"))
3065 3069 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3066 3070
3067 3071 if not pats and not opts.get('all'):
3068 3072 raise util.Abort(_('no files or directories specified; '
3069 3073 'use --all to revert the whole repo'))
3070 3074
3071 3075 parent, p2 = repo.dirstate.parents()
3072 3076 if not opts.get('rev') and p2 != nullid:
3073 3077 raise util.Abort(_('uncommitted merge - please provide a '
3074 3078 'specific revision'))
3075 3079 ctx = repo[opts.get('rev')]
3076 3080 node = ctx.node()
3077 3081 mf = ctx.manifest()
3078 3082 if node == parent:
3079 3083 pmf = mf
3080 3084 else:
3081 3085 pmf = None
3082 3086
3083 3087 # need all matching names in dirstate and manifest of target rev,
3084 3088 # so have to walk both. do not print errors if files exist in one
3085 3089 # but not other.
3086 3090
3087 3091 names = {}
3088 3092
3089 3093 wlock = repo.wlock()
3090 3094 try:
3091 3095 # walk dirstate.
3092 3096
3093 3097 m = cmdutil.match(repo, pats, opts)
3094 3098 m.bad = lambda x, y: False
3095 3099 for abs in repo.walk(m):
3096 3100 names[abs] = m.rel(abs), m.exact(abs)
3097 3101
3098 3102 # walk target manifest.
3099 3103
3100 3104 def badfn(path, msg):
3101 3105 if path in names:
3102 3106 return
3103 3107 path_ = path + '/'
3104 3108 for f in names:
3105 3109 if f.startswith(path_):
3106 3110 return
3107 3111 ui.warn("%s: %s\n" % (m.rel(path), msg))
3108 3112
3109 3113 m = cmdutil.match(repo, pats, opts)
3110 3114 m.bad = badfn
3111 3115 for abs in repo[node].walk(m):
3112 3116 if abs not in names:
3113 3117 names[abs] = m.rel(abs), m.exact(abs)
3114 3118
3115 3119 m = cmdutil.matchfiles(repo, names)
3116 3120 changes = repo.status(match=m)[:4]
3117 3121 modified, added, removed, deleted = map(set, changes)
3118 3122
3119 3123 # if f is a rename, also revert the source
3120 3124 cwd = repo.getcwd()
3121 3125 for f in added:
3122 3126 src = repo.dirstate.copied(f)
3123 3127 if src and src not in names and repo.dirstate[src] == 'r':
3124 3128 removed.add(src)
3125 3129 names[src] = (repo.pathto(src, cwd), True)
3126 3130
3127 3131 def removeforget(abs):
3128 3132 if repo.dirstate[abs] == 'a':
3129 3133 return _('forgetting %s\n')
3130 3134 return _('removing %s\n')
3131 3135
3132 3136 revert = ([], _('reverting %s\n'))
3133 3137 add = ([], _('adding %s\n'))
3134 3138 remove = ([], removeforget)
3135 3139 undelete = ([], _('undeleting %s\n'))
3136 3140
3137 3141 disptable = (
3138 3142 # dispatch table:
3139 3143 # file state
3140 3144 # action if in target manifest
3141 3145 # action if not in target manifest
3142 3146 # make backup if in target manifest
3143 3147 # make backup if not in target manifest
3144 3148 (modified, revert, remove, True, True),
3145 3149 (added, revert, remove, True, False),
3146 3150 (removed, undelete, None, False, False),
3147 3151 (deleted, revert, remove, False, False),
3148 3152 )
3149 3153
3150 3154 for abs, (rel, exact) in sorted(names.items()):
3151 3155 mfentry = mf.get(abs)
3152 3156 target = repo.wjoin(abs)
3153 3157 def handle(xlist, dobackup):
3154 3158 xlist[0].append(abs)
3155 3159 if dobackup and not opts.get('no_backup') and util.lexists(target):
3156 3160 bakname = "%s.orig" % rel
3157 3161 ui.note(_('saving current version of %s as %s\n') %
3158 3162 (rel, bakname))
3159 3163 if not opts.get('dry_run'):
3160 3164 util.copyfile(target, bakname)
3161 3165 if ui.verbose or not exact:
3162 3166 msg = xlist[1]
3163 3167 if not isinstance(msg, basestring):
3164 3168 msg = msg(abs)
3165 3169 ui.status(msg % rel)
3166 3170 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3167 3171 if abs not in table:
3168 3172 continue
3169 3173 # file has changed in dirstate
3170 3174 if mfentry:
3171 3175 handle(hitlist, backuphit)
3172 3176 elif misslist is not None:
3173 3177 handle(misslist, backupmiss)
3174 3178 break
3175 3179 else:
3176 3180 if abs not in repo.dirstate:
3177 3181 if mfentry:
3178 3182 handle(add, True)
3179 3183 elif exact:
3180 3184 ui.warn(_('file not managed: %s\n') % rel)
3181 3185 continue
3182 3186 # file has not changed in dirstate
3183 3187 if node == parent:
3184 3188 if exact:
3185 3189 ui.warn(_('no changes needed to %s\n') % rel)
3186 3190 continue
3187 3191 if pmf is None:
3188 3192 # only need parent manifest in this unlikely case,
3189 3193 # so do not read by default
3190 3194 pmf = repo[parent].manifest()
3191 3195 if abs in pmf:
3192 3196 if mfentry:
3193 3197 # if version of file is same in parent and target
3194 3198 # manifests, do nothing
3195 3199 if (pmf[abs] != mfentry or
3196 3200 pmf.flags(abs) != mf.flags(abs)):
3197 3201 handle(revert, False)
3198 3202 else:
3199 3203 handle(remove, False)
3200 3204
3201 3205 if not opts.get('dry_run'):
3202 3206 def checkout(f):
3203 3207 fc = ctx[f]
3204 3208 repo.wwrite(f, fc.data(), fc.flags())
3205 3209
3206 3210 audit_path = util.path_auditor(repo.root)
3207 3211 for f in remove[0]:
3208 3212 if repo.dirstate[f] == 'a':
3209 3213 repo.dirstate.forget(f)
3210 3214 continue
3211 3215 audit_path(f)
3212 3216 try:
3213 3217 util.unlink(repo.wjoin(f))
3214 3218 except OSError:
3215 3219 pass
3216 3220 repo.dirstate.remove(f)
3217 3221
3218 3222 normal = None
3219 3223 if node == parent:
3220 3224 # We're reverting to our parent. If possible, we'd like status
3221 3225 # to report the file as clean. We have to use normallookup for
3222 3226 # merges to avoid losing information about merged/dirty files.
3223 3227 if p2 != nullid:
3224 3228 normal = repo.dirstate.normallookup
3225 3229 else:
3226 3230 normal = repo.dirstate.normal
3227 3231 for f in revert[0]:
3228 3232 checkout(f)
3229 3233 if normal:
3230 3234 normal(f)
3231 3235
3232 3236 for f in add[0]:
3233 3237 checkout(f)
3234 3238 repo.dirstate.add(f)
3235 3239
3236 3240 normal = repo.dirstate.normallookup
3237 3241 if node == parent and p2 == nullid:
3238 3242 normal = repo.dirstate.normal
3239 3243 for f in undelete[0]:
3240 3244 checkout(f)
3241 3245 normal(f)
3242 3246
3243 3247 finally:
3244 3248 wlock.release()
3245 3249
3246 3250 def rollback(ui, repo, **opts):
3247 3251 """roll back the last transaction (dangerous)
3248 3252
3249 3253 This command should be used with care. There is only one level of
3250 3254 rollback, and there is no way to undo a rollback. It will also
3251 3255 restore the dirstate at the time of the last transaction, losing
3252 3256 any dirstate changes since that time. This command does not alter
3253 3257 the working directory.
3254 3258
3255 3259 Transactions are used to encapsulate the effects of all commands
3256 3260 that create new changesets or propagate existing changesets into a
3257 3261 repository. For example, the following commands are transactional,
3258 3262 and their effects can be rolled back:
3259 3263
3260 3264 - commit
3261 3265 - import
3262 3266 - pull
3263 3267 - push (with this repository as the destination)
3264 3268 - unbundle
3265 3269
3266 3270 This command is not intended for use on public repositories. Once
3267 3271 changes are visible for pull by other users, rolling a transaction
3268 3272 back locally is ineffective (someone else may already have pulled
3269 3273 the changes). Furthermore, a race is possible with readers of the
3270 3274 repository; for example an in-progress pull from the repository
3271 3275 may fail if a rollback is performed.
3272 3276
3273 3277 Returns 0 on success, 1 if no rollback data is available.
3274 3278 """
3275 3279 return repo.rollback(opts.get('dry_run'))
3276 3280
3277 3281 def root(ui, repo):
3278 3282 """print the root (top) of the current working directory
3279 3283
3280 3284 Print the root directory of the current repository.
3281 3285
3282 3286 Returns 0 on success.
3283 3287 """
3284 3288 ui.write(repo.root + "\n")
3285 3289
3286 3290 def serve(ui, repo, **opts):
3287 3291 """start stand-alone webserver
3288 3292
3289 3293 Start a local HTTP repository browser and pull server. You can use
3290 3294 this for ad-hoc sharing and browing of repositories. It is
3291 3295 recommended to use a real web server to serve a repository for
3292 3296 longer periods of time.
3293 3297
3294 3298 Please note that the server does not implement access control.
3295 3299 This means that, by default, anybody can read from the server and
3296 3300 nobody can write to it by default. Set the ``web.allow_push``
3297 3301 option to ``*`` to allow everybody to push to the server. You
3298 3302 should use a real web server if you need to authenticate users.
3299 3303
3300 3304 By default, the server logs accesses to stdout and errors to
3301 3305 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3302 3306 files.
3303 3307
3304 3308 To have the server choose a free port number to listen on, specify
3305 3309 a port number of 0; in this case, the server will print the port
3306 3310 number it uses.
3307 3311
3308 3312 Returns 0 on success.
3309 3313 """
3310 3314
3311 3315 if opts["stdio"]:
3312 3316 if repo is None:
3313 3317 raise error.RepoError(_("There is no Mercurial repository here"
3314 3318 " (.hg not found)"))
3315 3319 s = sshserver.sshserver(ui, repo)
3316 3320 s.serve_forever()
3317 3321
3318 3322 # this way we can check if something was given in the command-line
3319 3323 if opts.get('port'):
3320 3324 opts['port'] = int(opts.get('port'))
3321 3325
3322 3326 baseui = repo and repo.baseui or ui
3323 3327 optlist = ("name templates style address port prefix ipv6"
3324 3328 " accesslog errorlog certificate encoding")
3325 3329 for o in optlist.split():
3326 3330 val = opts.get(o, '')
3327 3331 if val in (None, ''): # should check against default options instead
3328 3332 continue
3329 3333 baseui.setconfig("web", o, val)
3330 3334 if repo and repo.ui != baseui:
3331 3335 repo.ui.setconfig("web", o, val)
3332 3336
3333 3337 o = opts.get('web_conf') or opts.get('webdir_conf')
3334 3338 if not o:
3335 3339 if not repo:
3336 3340 raise error.RepoError(_("There is no Mercurial repository"
3337 3341 " here (.hg not found)"))
3338 3342 o = repo.root
3339 3343
3340 3344 app = hgweb.hgweb(o, baseui=ui)
3341 3345
3342 3346 class service(object):
3343 3347 def init(self):
3344 3348 util.set_signal_handler()
3345 3349 self.httpd = hgweb.server.create_server(ui, app)
3346 3350
3347 3351 if opts['port'] and not ui.verbose:
3348 3352 return
3349 3353
3350 3354 if self.httpd.prefix:
3351 3355 prefix = self.httpd.prefix.strip('/') + '/'
3352 3356 else:
3353 3357 prefix = ''
3354 3358
3355 3359 port = ':%d' % self.httpd.port
3356 3360 if port == ':80':
3357 3361 port = ''
3358 3362
3359 3363 bindaddr = self.httpd.addr
3360 3364 if bindaddr == '0.0.0.0':
3361 3365 bindaddr = '*'
3362 3366 elif ':' in bindaddr: # IPv6
3363 3367 bindaddr = '[%s]' % bindaddr
3364 3368
3365 3369 fqaddr = self.httpd.fqaddr
3366 3370 if ':' in fqaddr:
3367 3371 fqaddr = '[%s]' % fqaddr
3368 3372 if opts['port']:
3369 3373 write = ui.status
3370 3374 else:
3371 3375 write = ui.write
3372 3376 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3373 3377 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3374 3378
3375 3379 def run(self):
3376 3380 self.httpd.serve_forever()
3377 3381
3378 3382 service = service()
3379 3383
3380 3384 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3381 3385
3382 3386 def status(ui, repo, *pats, **opts):
3383 3387 """show changed files in the working directory
3384 3388
3385 3389 Show status of files in the repository. If names are given, only
3386 3390 files that match are shown. Files that are clean or ignored or
3387 3391 the source of a copy/move operation, are not listed unless
3388 3392 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3389 3393 Unless options described with "show only ..." are given, the
3390 3394 options -mardu are used.
3391 3395
3392 3396 Option -q/--quiet hides untracked (unknown and ignored) files
3393 3397 unless explicitly requested with -u/--unknown or -i/--ignored.
3394 3398
3395 3399 NOTE: status may appear to disagree with diff if permissions have
3396 3400 changed or a merge has occurred. The standard diff format does not
3397 3401 report permission changes and diff only reports changes relative
3398 3402 to one merge parent.
3399 3403
3400 3404 If one revision is given, it is used as the base revision.
3401 3405 If two revisions are given, the differences between them are
3402 3406 shown. The --change option can also be used as a shortcut to list
3403 3407 the changed files of a revision from its first parent.
3404 3408
3405 3409 The codes used to show the status of files are::
3406 3410
3407 3411 M = modified
3408 3412 A = added
3409 3413 R = removed
3410 3414 C = clean
3411 3415 ! = missing (deleted by non-hg command, but still tracked)
3412 3416 ? = not tracked
3413 3417 I = ignored
3414 3418 = origin of the previous file listed as A (added)
3415 3419
3416 3420 Returns 0 on success.
3417 3421 """
3418 3422
3419 3423 revs = opts.get('rev')
3420 3424 change = opts.get('change')
3421 3425
3422 3426 if revs and change:
3423 3427 msg = _('cannot specify --rev and --change at the same time')
3424 3428 raise util.Abort(msg)
3425 3429 elif change:
3426 3430 node2 = repo.lookup(change)
3427 3431 node1 = repo[node2].parents()[0].node()
3428 3432 else:
3429 3433 node1, node2 = cmdutil.revpair(repo, revs)
3430 3434
3431 3435 cwd = (pats and repo.getcwd()) or ''
3432 3436 end = opts.get('print0') and '\0' or '\n'
3433 3437 copy = {}
3434 3438 states = 'modified added removed deleted unknown ignored clean'.split()
3435 3439 show = [k for k in states if opts.get(k)]
3436 3440 if opts.get('all'):
3437 3441 show += ui.quiet and (states[:4] + ['clean']) or states
3438 3442 if not show:
3439 3443 show = ui.quiet and states[:4] or states[:5]
3440 3444
3441 3445 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3442 3446 'ignored' in show, 'clean' in show, 'unknown' in show)
3443 3447 changestates = zip(states, 'MAR!?IC', stat)
3444 3448
3445 3449 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3446 3450 ctxn = repo[nullid]
3447 3451 ctx1 = repo[node1]
3448 3452 ctx2 = repo[node2]
3449 3453 added = stat[1]
3450 3454 if node2 is None:
3451 3455 added = stat[0] + stat[1] # merged?
3452 3456
3453 3457 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3454 3458 if k in added:
3455 3459 copy[k] = v
3456 3460 elif v in added:
3457 3461 copy[v] = k
3458 3462
3459 3463 for state, char, files in changestates:
3460 3464 if state in show:
3461 3465 format = "%s %%s%s" % (char, end)
3462 3466 if opts.get('no_status'):
3463 3467 format = "%%s%s" % end
3464 3468
3465 3469 for f in files:
3466 3470 ui.write(format % repo.pathto(f, cwd),
3467 3471 label='status.' + state)
3468 3472 if f in copy:
3469 3473 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3470 3474 label='status.copied')
3471 3475
3472 3476 def summary(ui, repo, **opts):
3473 3477 """summarize working directory state
3474 3478
3475 3479 This generates a brief summary of the working directory state,
3476 3480 including parents, branch, commit status, and available updates.
3477 3481
3478 3482 With the --remote option, this will check the default paths for
3479 3483 incoming and outgoing changes. This can be time-consuming.
3480 3484
3481 3485 Returns 0 on success.
3482 3486 """
3483 3487
3484 3488 ctx = repo[None]
3485 3489 parents = ctx.parents()
3486 3490 pnode = parents[0].node()
3487 3491
3488 3492 for p in parents:
3489 3493 # label with log.changeset (instead of log.parent) since this
3490 3494 # shows a working directory parent *changeset*:
3491 3495 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3492 3496 label='log.changeset')
3493 3497 ui.write(' '.join(p.tags()), label='log.tag')
3494 3498 if p.rev() == -1:
3495 3499 if not len(repo):
3496 3500 ui.write(_(' (empty repository)'))
3497 3501 else:
3498 3502 ui.write(_(' (no revision checked out)'))
3499 3503 ui.write('\n')
3500 3504 if p.description():
3501 3505 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3502 3506 label='log.summary')
3503 3507
3504 3508 branch = ctx.branch()
3505 3509 bheads = repo.branchheads(branch)
3506 3510 m = _('branch: %s\n') % branch
3507 3511 if branch != 'default':
3508 3512 ui.write(m, label='log.branch')
3509 3513 else:
3510 3514 ui.status(m, label='log.branch')
3511 3515
3512 3516 st = list(repo.status(unknown=True))[:6]
3513 3517
3514 3518 c = repo.dirstate.copies()
3515 3519 copied, renamed = [], []
3516 3520 for d, s in c.iteritems():
3517 3521 if s in st[2]:
3518 3522 st[2].remove(s)
3519 3523 renamed.append(d)
3520 3524 else:
3521 3525 copied.append(d)
3522 3526 if d in st[1]:
3523 3527 st[1].remove(d)
3524 3528 st.insert(3, renamed)
3525 3529 st.insert(4, copied)
3526 3530
3527 3531 ms = mergemod.mergestate(repo)
3528 3532 st.append([f for f in ms if ms[f] == 'u'])
3529 3533
3530 3534 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3531 3535 st.append(subs)
3532 3536
3533 3537 labels = [ui.label(_('%d modified'), 'status.modified'),
3534 3538 ui.label(_('%d added'), 'status.added'),
3535 3539 ui.label(_('%d removed'), 'status.removed'),
3536 3540 ui.label(_('%d renamed'), 'status.copied'),
3537 3541 ui.label(_('%d copied'), 'status.copied'),
3538 3542 ui.label(_('%d deleted'), 'status.deleted'),
3539 3543 ui.label(_('%d unknown'), 'status.unknown'),
3540 3544 ui.label(_('%d ignored'), 'status.ignored'),
3541 3545 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3542 3546 ui.label(_('%d subrepos'), 'status.modified')]
3543 3547 t = []
3544 3548 for s, l in zip(st, labels):
3545 3549 if s:
3546 3550 t.append(l % len(s))
3547 3551
3548 3552 t = ', '.join(t)
3549 3553 cleanworkdir = False
3550 3554
3551 3555 if len(parents) > 1:
3552 3556 t += _(' (merge)')
3553 3557 elif branch != parents[0].branch():
3554 3558 t += _(' (new branch)')
3555 3559 elif (parents[0].extra().get('close') and
3556 3560 pnode in repo.branchheads(branch, closed=True)):
3557 3561 t += _(' (head closed)')
3558 3562 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3559 3563 t += _(' (clean)')
3560 3564 cleanworkdir = True
3561 3565 elif pnode not in bheads:
3562 3566 t += _(' (new branch head)')
3563 3567
3564 3568 if cleanworkdir:
3565 3569 ui.status(_('commit: %s\n') % t.strip())
3566 3570 else:
3567 3571 ui.write(_('commit: %s\n') % t.strip())
3568 3572
3569 3573 # all ancestors of branch heads - all ancestors of parent = new csets
3570 3574 new = [0] * len(repo)
3571 3575 cl = repo.changelog
3572 3576 for a in [cl.rev(n) for n in bheads]:
3573 3577 new[a] = 1
3574 3578 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3575 3579 new[a] = 1
3576 3580 for a in [p.rev() for p in parents]:
3577 3581 if a >= 0:
3578 3582 new[a] = 0
3579 3583 for a in cl.ancestors(*[p.rev() for p in parents]):
3580 3584 new[a] = 0
3581 3585 new = sum(new)
3582 3586
3583 3587 if new == 0:
3584 3588 ui.status(_('update: (current)\n'))
3585 3589 elif pnode not in bheads:
3586 3590 ui.write(_('update: %d new changesets (update)\n') % new)
3587 3591 else:
3588 3592 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3589 3593 (new, len(bheads)))
3590 3594
3591 3595 if opts.get('remote'):
3592 3596 t = []
3593 3597 source, branches = hg.parseurl(ui.expandpath('default'))
3594 3598 other = hg.repository(hg.remoteui(repo, {}), source)
3595 3599 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3596 3600 ui.debug('comparing with %s\n' % url.hidepassword(source))
3597 3601 repo.ui.pushbuffer()
3598 3602 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3599 3603 repo.ui.popbuffer()
3600 3604 if incoming:
3601 3605 t.append(_('1 or more incoming'))
3602 3606
3603 3607 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3604 3608 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3605 3609 other = hg.repository(hg.remoteui(repo, {}), dest)
3606 3610 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3607 3611 repo.ui.pushbuffer()
3608 3612 o = discovery.findoutgoing(repo, other)
3609 3613 repo.ui.popbuffer()
3610 3614 o = repo.changelog.nodesbetween(o, None)[0]
3611 3615 if o:
3612 3616 t.append(_('%d outgoing') % len(o))
3613 3617
3614 3618 if t:
3615 3619 ui.write(_('remote: %s\n') % (', '.join(t)))
3616 3620 else:
3617 3621 ui.status(_('remote: (synced)\n'))
3618 3622
3619 3623 def tag(ui, repo, name1, *names, **opts):
3620 3624 """add one or more tags for the current or given revision
3621 3625
3622 3626 Name a particular revision using <name>.
3623 3627
3624 3628 Tags are used to name particular revisions of the repository and are
3625 3629 very useful to compare different revisions, to go back to significant
3626 3630 earlier versions or to mark branch points as releases, etc.
3627 3631
3628 3632 If no revision is given, the parent of the working directory is
3629 3633 used, or tip if no revision is checked out.
3630 3634
3631 3635 To facilitate version control, distribution, and merging of tags,
3632 3636 they are stored as a file named ".hgtags" which is managed
3633 3637 similarly to other project files and can be hand-edited if
3634 3638 necessary. The file '.hg/localtags' is used for local tags (not
3635 3639 shared among repositories).
3636 3640
3637 3641 See :hg:`help dates` for a list of formats valid for -d/--date.
3638 3642
3639 3643 Since tag names have priority over branch names during revision
3640 3644 lookup, using an existing branch name as a tag name is discouraged.
3641 3645
3642 3646 Returns 0 on success.
3643 3647 """
3644 3648
3645 3649 rev_ = "."
3646 3650 names = [t.strip() for t in (name1,) + names]
3647 3651 if len(names) != len(set(names)):
3648 3652 raise util.Abort(_('tag names must be unique'))
3649 3653 for n in names:
3650 3654 if n in ['tip', '.', 'null']:
3651 3655 raise util.Abort(_('the name \'%s\' is reserved') % n)
3652 3656 if opts.get('rev') and opts.get('remove'):
3653 3657 raise util.Abort(_("--rev and --remove are incompatible"))
3654 3658 if opts.get('rev'):
3655 3659 rev_ = opts['rev']
3656 3660 message = opts.get('message')
3657 3661 if opts.get('remove'):
3658 3662 expectedtype = opts.get('local') and 'local' or 'global'
3659 3663 for n in names:
3660 3664 if not repo.tagtype(n):
3661 3665 raise util.Abort(_('tag \'%s\' does not exist') % n)
3662 3666 if repo.tagtype(n) != expectedtype:
3663 3667 if expectedtype == 'global':
3664 3668 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3665 3669 else:
3666 3670 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3667 3671 rev_ = nullid
3668 3672 if not message:
3669 3673 # we don't translate commit messages
3670 3674 message = 'Removed tag %s' % ', '.join(names)
3671 3675 elif not opts.get('force'):
3672 3676 for n in names:
3673 3677 if n in repo.tags():
3674 3678 raise util.Abort(_('tag \'%s\' already exists '
3675 3679 '(use -f to force)') % n)
3676 3680 if not rev_ and repo.dirstate.parents()[1] != nullid:
3677 3681 raise util.Abort(_('uncommitted merge - please provide a '
3678 3682 'specific revision'))
3679 3683 r = repo[rev_].node()
3680 3684
3681 3685 if not message:
3682 3686 # we don't translate commit messages
3683 3687 message = ('Added tag %s for changeset %s' %
3684 3688 (', '.join(names), short(r)))
3685 3689
3686 3690 date = opts.get('date')
3687 3691 if date:
3688 3692 date = util.parsedate(date)
3689 3693
3690 3694 if opts.get('edit'):
3691 3695 message = ui.edit(message, ui.username())
3692 3696
3693 3697 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3694 3698
3695 3699 def tags(ui, repo):
3696 3700 """list repository tags
3697 3701
3698 3702 This lists both regular and local tags. When the -v/--verbose
3699 3703 switch is used, a third column "local" is printed for local tags.
3700 3704
3701 3705 Returns 0 on success.
3702 3706 """
3703 3707
3704 3708 hexfunc = ui.debugflag and hex or short
3705 3709 tagtype = ""
3706 3710
3707 3711 for t, n in reversed(repo.tagslist()):
3708 3712 if ui.quiet:
3709 3713 ui.write("%s\n" % t)
3710 3714 continue
3711 3715
3712 3716 try:
3713 3717 hn = hexfunc(n)
3714 3718 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3715 3719 except error.LookupError:
3716 3720 r = " ?:%s" % hn
3717 3721 else:
3718 3722 spaces = " " * (30 - encoding.colwidth(t))
3719 3723 if ui.verbose:
3720 3724 if repo.tagtype(t) == 'local':
3721 3725 tagtype = " local"
3722 3726 else:
3723 3727 tagtype = ""
3724 3728 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3725 3729
3726 3730 def tip(ui, repo, **opts):
3727 3731 """show the tip revision
3728 3732
3729 3733 The tip revision (usually just called the tip) is the changeset
3730 3734 most recently added to the repository (and therefore the most
3731 3735 recently changed head).
3732 3736
3733 3737 If you have just made a commit, that commit will be the tip. If
3734 3738 you have just pulled changes from another repository, the tip of
3735 3739 that repository becomes the current tip. The "tip" tag is special
3736 3740 and cannot be renamed or assigned to a different changeset.
3737 3741
3738 3742 Returns 0 on success.
3739 3743 """
3740 3744 displayer = cmdutil.show_changeset(ui, repo, opts)
3741 3745 displayer.show(repo[len(repo) - 1])
3742 3746 displayer.close()
3743 3747
3744 3748 def unbundle(ui, repo, fname1, *fnames, **opts):
3745 3749 """apply one or more changegroup files
3746 3750
3747 3751 Apply one or more compressed changegroup files generated by the
3748 3752 bundle command.
3749 3753
3750 3754 Returns 0 on success, 1 if an update has unresolved files.
3751 3755 """
3752 3756 fnames = (fname1,) + fnames
3753 3757
3754 3758 lock = repo.lock()
3755 3759 try:
3756 3760 for fname in fnames:
3757 3761 f = url.open(ui, fname)
3758 3762 gen = changegroup.readbundle(f, fname)
3759 3763 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3760 3764 lock=lock)
3761 3765 finally:
3762 3766 lock.release()
3763 3767
3764 3768 return postincoming(ui, repo, modheads, opts.get('update'), None)
3765 3769
3766 3770 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3767 3771 """update working directory (or switch revisions)
3768 3772
3769 3773 Update the repository's working directory to the specified
3770 3774 changeset.
3771 3775
3772 3776 If no changeset is specified, attempt to update to the head of the
3773 3777 current branch. If this head is a descendant of the working
3774 3778 directory's parent, update to it, otherwise abort.
3775 3779
3776 3780 The following rules apply when the working directory contains
3777 3781 uncommitted changes:
3778 3782
3779 3783 1. If neither -c/--check nor -C/--clean is specified, and if
3780 3784 the requested changeset is an ancestor or descendant of
3781 3785 the working directory's parent, the uncommitted changes
3782 3786 are merged into the requested changeset and the merged
3783 3787 result is left uncommitted. If the requested changeset is
3784 3788 not an ancestor or descendant (that is, it is on another
3785 3789 branch), the update is aborted and the uncommitted changes
3786 3790 are preserved.
3787 3791
3788 3792 2. With the -c/--check option, the update is aborted and the
3789 3793 uncommitted changes are preserved.
3790 3794
3791 3795 3. With the -C/--clean option, uncommitted changes are discarded and
3792 3796 the working directory is updated to the requested changeset.
3793 3797
3794 3798 Use null as the changeset to remove the working directory (like
3795 3799 :hg:`clone -U`).
3796 3800
3797 3801 If you want to update just one file to an older changeset, use :hg:`revert`.
3798 3802
3799 3803 See :hg:`help dates` for a list of formats valid for -d/--date.
3800 3804
3801 3805 Returns 0 on success, 1 if there are unresolved files.
3802 3806 """
3803 3807 if rev and node:
3804 3808 raise util.Abort(_("please specify just one revision"))
3805 3809
3806 3810 if not rev:
3807 3811 rev = node
3808 3812
3809 3813 if check and clean:
3810 3814 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3811 3815
3812 3816 if check:
3813 3817 # we could use dirty() but we can ignore merge and branch trivia
3814 3818 c = repo[None]
3815 3819 if c.modified() or c.added() or c.removed():
3816 3820 raise util.Abort(_("uncommitted local changes"))
3817 3821
3818 3822 if date:
3819 3823 if rev:
3820 3824 raise util.Abort(_("you can't specify a revision and a date"))
3821 3825 rev = cmdutil.finddate(ui, repo, date)
3822 3826
3823 3827 if clean or check:
3824 3828 return hg.clean(repo, rev)
3825 3829 else:
3826 3830 return hg.update(repo, rev)
3827 3831
3828 3832 def verify(ui, repo):
3829 3833 """verify the integrity of the repository
3830 3834
3831 3835 Verify the integrity of the current repository.
3832 3836
3833 3837 This will perform an extensive check of the repository's
3834 3838 integrity, validating the hashes and checksums of each entry in
3835 3839 the changelog, manifest, and tracked files, as well as the
3836 3840 integrity of their crosslinks and indices.
3837 3841
3838 3842 Returns 0 on success, 1 if errors are encountered.
3839 3843 """
3840 3844 return hg.verify(repo)
3841 3845
3842 3846 def version_(ui):
3843 3847 """output version and copyright information"""
3844 3848 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3845 3849 % util.version())
3846 3850 ui.status(_(
3847 3851 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3848 3852 "This is free software; see the source for copying conditions. "
3849 3853 "There is NO\nwarranty; "
3850 3854 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3851 3855 ))
3852 3856
3853 3857 # Command options and aliases are listed here, alphabetically
3854 3858
3855 3859 globalopts = [
3856 3860 ('R', 'repository', '',
3857 3861 _('repository root directory or name of overlay bundle file'),
3858 3862 _('REPO')),
3859 3863 ('', 'cwd', '',
3860 3864 _('change working directory'), _('DIR')),
3861 3865 ('y', 'noninteractive', None,
3862 3866 _('do not prompt, assume \'yes\' for any required answers')),
3863 3867 ('q', 'quiet', None, _('suppress output')),
3864 3868 ('v', 'verbose', None, _('enable additional output')),
3865 3869 ('', 'config', [],
3866 3870 _('set/override config option (use \'section.name=value\')'),
3867 3871 _('CONFIG')),
3868 3872 ('', 'debug', None, _('enable debugging output')),
3869 3873 ('', 'debugger', None, _('start debugger')),
3870 3874 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3871 3875 _('ENCODE')),
3872 3876 ('', 'encodingmode', encoding.encodingmode,
3873 3877 _('set the charset encoding mode'), _('MODE')),
3874 3878 ('', 'traceback', None, _('always print a traceback on exception')),
3875 3879 ('', 'time', None, _('time how long the command takes')),
3876 3880 ('', 'profile', None, _('print command execution profile')),
3877 3881 ('', 'version', None, _('output version information and exit')),
3878 3882 ('h', 'help', None, _('display help and exit')),
3879 3883 ]
3880 3884
3881 3885 dryrunopts = [('n', 'dry-run', None,
3882 3886 _('do not perform actions, just print output'))]
3883 3887
3884 3888 remoteopts = [
3885 3889 ('e', 'ssh', '',
3886 3890 _('specify ssh command to use'), _('CMD')),
3887 3891 ('', 'remotecmd', '',
3888 3892 _('specify hg command to run on the remote side'), _('CMD')),
3889 3893 ]
3890 3894
3891 3895 walkopts = [
3892 3896 ('I', 'include', [],
3893 3897 _('include names matching the given patterns'), _('PATTERN')),
3894 3898 ('X', 'exclude', [],
3895 3899 _('exclude names matching the given patterns'), _('PATTERN')),
3896 3900 ]
3897 3901
3898 3902 commitopts = [
3899 3903 ('m', 'message', '',
3900 3904 _('use text as commit message'), _('TEXT')),
3901 3905 ('l', 'logfile', '',
3902 3906 _('read commit message from file'), _('FILE')),
3903 3907 ]
3904 3908
3905 3909 commitopts2 = [
3906 3910 ('d', 'date', '',
3907 3911 _('record datecode as commit date'), _('DATE')),
3908 3912 ('u', 'user', '',
3909 3913 _('record the specified user as committer'), _('USER')),
3910 3914 ]
3911 3915
3912 3916 templateopts = [
3913 3917 ('', 'style', '',
3914 3918 _('display using template map file'), _('STYLE')),
3915 3919 ('', 'template', '',
3916 3920 _('display with template'), _('TEMPLATE')),
3917 3921 ]
3918 3922
3919 3923 logopts = [
3920 3924 ('p', 'patch', None, _('show patch')),
3921 3925 ('g', 'git', None, _('use git extended diff format')),
3922 3926 ('l', 'limit', '',
3923 3927 _('limit number of changes displayed'), _('NUM')),
3924 3928 ('M', 'no-merges', None, _('do not show merges')),
3925 3929 ('', 'stat', None, _('output diffstat-style summary of changes')),
3926 3930 ] + templateopts
3927 3931
3928 3932 diffopts = [
3929 3933 ('a', 'text', None, _('treat all files as text')),
3930 3934 ('g', 'git', None, _('use git extended diff format')),
3931 3935 ('', 'nodates', None, _('omit dates from diff headers'))
3932 3936 ]
3933 3937
3934 3938 diffopts2 = [
3935 3939 ('p', 'show-function', None, _('show which function each change is in')),
3936 3940 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3937 3941 ('w', 'ignore-all-space', None,
3938 3942 _('ignore white space when comparing lines')),
3939 3943 ('b', 'ignore-space-change', None,
3940 3944 _('ignore changes in the amount of white space')),
3941 3945 ('B', 'ignore-blank-lines', None,
3942 3946 _('ignore changes whose lines are all blank')),
3943 3947 ('U', 'unified', '',
3944 3948 _('number of lines of context to show'), _('NUM')),
3945 3949 ('', 'stat', None, _('output diffstat-style summary of changes')),
3946 3950 ]
3947 3951
3948 3952 similarityopts = [
3949 3953 ('s', 'similarity', '',
3950 3954 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3951 3955 ]
3952 3956
3953 3957 table = {
3954 3958 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3955 3959 "addremove":
3956 3960 (addremove, similarityopts + walkopts + dryrunopts,
3957 3961 _('[OPTION]... [FILE]...')),
3958 3962 "^annotate|blame":
3959 3963 (annotate,
3960 3964 [('r', 'rev', '',
3961 3965 _('annotate the specified revision'), _('REV')),
3962 3966 ('', 'follow', None,
3963 3967 _('follow copies/renames and list the filename (DEPRECATED)')),
3964 3968 ('', 'no-follow', None, _("don't follow copies and renames")),
3965 3969 ('a', 'text', None, _('treat all files as text')),
3966 3970 ('u', 'user', None, _('list the author (long with -v)')),
3967 3971 ('f', 'file', None, _('list the filename')),
3968 3972 ('d', 'date', None, _('list the date (short with -q)')),
3969 3973 ('n', 'number', None, _('list the revision number (default)')),
3970 3974 ('c', 'changeset', None, _('list the changeset')),
3971 3975 ('l', 'line-number', None,
3972 3976 _('show line number at the first appearance'))
3973 3977 ] + walkopts,
3974 3978 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3975 3979 "archive":
3976 3980 (archive,
3977 3981 [('', 'no-decode', None, _('do not pass files through decoders')),
3978 3982 ('p', 'prefix', '',
3979 3983 _('directory prefix for files in archive'), _('PREFIX')),
3980 3984 ('r', 'rev', '',
3981 3985 _('revision to distribute'), _('REV')),
3982 3986 ('t', 'type', '',
3983 3987 _('type of distribution to create'), _('TYPE')),
3984 3988 ] + walkopts,
3985 3989 _('[OPTION]... DEST')),
3986 3990 "backout":
3987 3991 (backout,
3988 3992 [('', 'merge', None,
3989 3993 _('merge with old dirstate parent after backout')),
3990 3994 ('', 'parent', '',
3991 3995 _('parent to choose when backing out merge'), _('REV')),
3992 3996 ('r', 'rev', '',
3993 3997 _('revision to backout'), _('REV')),
3994 3998 ] + walkopts + commitopts + commitopts2,
3995 3999 _('[OPTION]... [-r] REV')),
3996 4000 "bisect":
3997 4001 (bisect,
3998 4002 [('r', 'reset', False, _('reset bisect state')),
3999 4003 ('g', 'good', False, _('mark changeset good')),
4000 4004 ('b', 'bad', False, _('mark changeset bad')),
4001 4005 ('s', 'skip', False, _('skip testing changeset')),
4002 4006 ('c', 'command', '',
4003 4007 _('use command to check changeset state'), _('CMD')),
4004 4008 ('U', 'noupdate', False, _('do not update to target'))],
4005 4009 _("[-gbsr] [-U] [-c CMD] [REV]")),
4006 4010 "branch":
4007 4011 (branch,
4008 4012 [('f', 'force', None,
4009 4013 _('set branch name even if it shadows an existing branch')),
4010 4014 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4011 4015 _('[-fC] [NAME]')),
4012 4016 "branches":
4013 4017 (branches,
4014 4018 [('a', 'active', False,
4015 4019 _('show only branches that have unmerged heads')),
4016 4020 ('c', 'closed', False,
4017 4021 _('show normal and closed branches'))],
4018 4022 _('[-ac]')),
4019 4023 "bundle":
4020 4024 (bundle,
4021 4025 [('f', 'force', None,
4022 4026 _('run even when the destination is unrelated')),
4023 4027 ('r', 'rev', [],
4024 4028 _('a changeset intended to be added to the destination'),
4025 4029 _('REV')),
4026 4030 ('b', 'branch', [],
4027 4031 _('a specific branch you would like to bundle'),
4028 4032 _('BRANCH')),
4029 4033 ('', 'base', [],
4030 4034 _('a base changeset assumed to be available at the destination'),
4031 4035 _('REV')),
4032 4036 ('a', 'all', None, _('bundle all changesets in the repository')),
4033 4037 ('t', 'type', 'bzip2',
4034 4038 _('bundle compression type to use'), _('TYPE')),
4035 4039 ] + remoteopts,
4036 4040 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4037 4041 "cat":
4038 4042 (cat,
4039 4043 [('o', 'output', '',
4040 4044 _('print output to file with formatted name'), _('FORMAT')),
4041 4045 ('r', 'rev', '',
4042 4046 _('print the given revision'), _('REV')),
4043 4047 ('', 'decode', None, _('apply any matching decode filter')),
4044 4048 ] + walkopts,
4045 4049 _('[OPTION]... FILE...')),
4046 4050 "^clone":
4047 4051 (clone,
4048 4052 [('U', 'noupdate', None,
4049 4053 _('the clone will include an empty working copy (only a repository)')),
4050 4054 ('u', 'updaterev', '',
4051 4055 _('revision, tag or branch to check out'), _('REV')),
4052 4056 ('r', 'rev', [],
4053 4057 _('include the specified changeset'), _('REV')),
4054 4058 ('b', 'branch', [],
4055 4059 _('clone only the specified branch'), _('BRANCH')),
4056 4060 ('', 'pull', None, _('use pull protocol to copy metadata')),
4057 4061 ('', 'uncompressed', None,
4058 4062 _('use uncompressed transfer (fast over LAN)')),
4059 4063 ] + remoteopts,
4060 4064 _('[OPTION]... SOURCE [DEST]')),
4061 4065 "^commit|ci":
4062 4066 (commit,
4063 4067 [('A', 'addremove', None,
4064 4068 _('mark new/missing files as added/removed before committing')),
4065 4069 ('', 'close-branch', None,
4066 4070 _('mark a branch as closed, hiding it from the branch list')),
4067 4071 ] + walkopts + commitopts + commitopts2,
4068 4072 _('[OPTION]... [FILE]...')),
4069 4073 "copy|cp":
4070 4074 (copy,
4071 4075 [('A', 'after', None, _('record a copy that has already occurred')),
4072 4076 ('f', 'force', None,
4073 4077 _('forcibly copy over an existing managed file')),
4074 4078 ] + walkopts + dryrunopts,
4075 4079 _('[OPTION]... [SOURCE]... DEST')),
4076 4080 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4077 4081 "debugbuilddag":
4078 4082 (debugbuilddag,
4079 4083 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4080 4084 ('a', 'appended-file', None, _('add single file all revs append to')),
4081 4085 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4082 4086 ('n', 'new-file', None, _('add new file at each rev')),
4083 4087 ],
4084 4088 _('[OPTION]... TEXT')),
4085 4089 "debugcheckstate": (debugcheckstate, [], ''),
4086 4090 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4087 4091 "debugcomplete":
4088 4092 (debugcomplete,
4089 4093 [('o', 'options', None, _('show the command options'))],
4090 4094 _('[-o] CMD')),
4091 4095 "debugdag":
4092 4096 (debugdag,
4093 4097 [('t', 'tags', None, _('use tags as labels')),
4094 4098 ('b', 'branches', None, _('annotate with branch names')),
4095 4099 ('', 'dots', None, _('use dots for runs')),
4096 4100 ('s', 'spaces', None, _('separate elements by spaces')),
4097 4101 ],
4098 4102 _('[OPTION]... [FILE [REV]...]')),
4099 4103 "debugdate":
4100 4104 (debugdate,
4101 4105 [('e', 'extended', None, _('try extended date formats'))],
4102 4106 _('[-e] DATE [RANGE]')),
4103 4107 "debugdata": (debugdata, [], _('FILE REV')),
4104 4108 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4105 4109 "debugindex": (debugindex, [], _('FILE')),
4106 4110 "debugindexdot": (debugindexdot, [], _('FILE')),
4107 4111 "debuginstall": (debuginstall, [], ''),
4108 4112 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4109 4113 "debugrebuildstate":
4110 4114 (debugrebuildstate,
4111 4115 [('r', 'rev', '',
4112 4116 _('revision to rebuild to'), _('REV'))],
4113 4117 _('[-r REV] [REV]')),
4114 4118 "debugrename":
4115 4119 (debugrename,
4116 4120 [('r', 'rev', '',
4117 4121 _('revision to debug'), _('REV'))],
4118 4122 _('[-r REV] FILE')),
4119 4123 "debugrevspec":
4120 4124 (debugrevspec, [], ('REVSPEC')),
4121 4125 "debugsetparents":
4122 4126 (debugsetparents, [], _('REV1 [REV2]')),
4123 4127 "debugstate":
4124 4128 (debugstate,
4125 4129 [('', 'nodates', None, _('do not display the saved mtime'))],
4126 4130 _('[OPTION]...')),
4127 4131 "debugsub":
4128 4132 (debugsub,
4129 4133 [('r', 'rev', '',
4130 4134 _('revision to check'), _('REV'))],
4131 4135 _('[-r REV] [REV]')),
4132 4136 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4133 4137 "^diff":
4134 4138 (diff,
4135 4139 [('r', 'rev', [],
4136 4140 _('revision'), _('REV')),
4137 4141 ('c', 'change', '',
4138 4142 _('change made by revision'), _('REV'))
4139 4143 ] + diffopts + diffopts2 + walkopts,
4140 4144 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4141 4145 "^export":
4142 4146 (export,
4143 4147 [('o', 'output', '',
4144 4148 _('print output to file with formatted name'), _('FORMAT')),
4145 4149 ('', 'switch-parent', None, _('diff against the second parent')),
4146 4150 ('r', 'rev', [],
4147 4151 _('revisions to export'), _('REV')),
4148 4152 ] + diffopts,
4149 4153 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4150 4154 "^forget":
4151 4155 (forget,
4152 4156 [] + walkopts,
4153 4157 _('[OPTION]... FILE...')),
4154 4158 "grep":
4155 4159 (grep,
4156 4160 [('0', 'print0', None, _('end fields with NUL')),
4157 4161 ('', 'all', None, _('print all revisions that match')),
4158 4162 ('f', 'follow', None,
4159 4163 _('follow changeset history,'
4160 4164 ' or file history across copies and renames')),
4161 4165 ('i', 'ignore-case', None, _('ignore case when matching')),
4162 4166 ('l', 'files-with-matches', None,
4163 4167 _('print only filenames and revisions that match')),
4164 4168 ('n', 'line-number', None, _('print matching line numbers')),
4165 4169 ('r', 'rev', [],
4166 4170 _('only search files changed within revision range'), _('REV')),
4167 4171 ('u', 'user', None, _('list the author (long with -v)')),
4168 4172 ('d', 'date', None, _('list the date (short with -q)')),
4169 4173 ] + walkopts,
4170 4174 _('[OPTION]... PATTERN [FILE]...')),
4171 4175 "heads":
4172 4176 (heads,
4173 4177 [('r', 'rev', '',
4174 4178 _('show only heads which are descendants of REV'), _('REV')),
4175 4179 ('t', 'topo', False, _('show topological heads only')),
4176 4180 ('a', 'active', False,
4177 4181 _('show active branchheads only [DEPRECATED]')),
4178 4182 ('c', 'closed', False,
4179 4183 _('show normal and closed branch heads')),
4180 4184 ] + templateopts,
4181 4185 _('[-ac] [-r REV] [REV]...')),
4182 4186 "help": (help_, [], _('[TOPIC]')),
4183 4187 "identify|id":
4184 4188 (identify,
4185 4189 [('r', 'rev', '',
4186 4190 _('identify the specified revision'), _('REV')),
4187 4191 ('n', 'num', None, _('show local revision number')),
4188 4192 ('i', 'id', None, _('show global revision id')),
4189 4193 ('b', 'branch', None, _('show branch')),
4190 4194 ('t', 'tags', None, _('show tags'))],
4191 4195 _('[-nibt] [-r REV] [SOURCE]')),
4192 4196 "import|patch":
4193 4197 (import_,
4194 4198 [('p', 'strip', 1,
4195 4199 _('directory strip option for patch. This has the same '
4196 4200 'meaning as the corresponding patch option'),
4197 4201 _('NUM')),
4198 4202 ('b', 'base', '',
4199 4203 _('base path'), _('PATH')),
4200 4204 ('f', 'force', None,
4201 4205 _('skip check for outstanding uncommitted changes')),
4202 4206 ('', 'no-commit', None,
4203 4207 _("don't commit, just update the working directory")),
4204 4208 ('', 'exact', None,
4205 4209 _('apply patch to the nodes from which it was generated')),
4206 4210 ('', 'import-branch', None,
4207 4211 _('use any branch information in patch (implied by --exact)'))] +
4208 4212 commitopts + commitopts2 + similarityopts,
4209 4213 _('[OPTION]... PATCH...')),
4210 4214 "incoming|in":
4211 4215 (incoming,
4212 4216 [('f', 'force', None,
4213 4217 _('run even if remote repository is unrelated')),
4214 4218 ('n', 'newest-first', None, _('show newest record first')),
4215 4219 ('', 'bundle', '',
4216 4220 _('file to store the bundles into'), _('FILE')),
4217 4221 ('r', 'rev', [],
4218 4222 _('a remote changeset intended to be added'), _('REV')),
4219 4223 ('b', 'branch', [],
4220 4224 _('a specific branch you would like to pull'), _('BRANCH')),
4221 4225 ] + logopts + remoteopts,
4222 4226 _('[-p] [-n] [-M] [-f] [-r REV]...'
4223 4227 ' [--bundle FILENAME] [SOURCE]')),
4224 4228 "^init":
4225 4229 (init,
4226 4230 remoteopts,
4227 4231 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4228 4232 "locate":
4229 4233 (locate,
4230 4234 [('r', 'rev', '',
4231 4235 _('search the repository as it is in REV'), _('REV')),
4232 4236 ('0', 'print0', None,
4233 4237 _('end filenames with NUL, for use with xargs')),
4234 4238 ('f', 'fullpath', None,
4235 4239 _('print complete paths from the filesystem root')),
4236 4240 ] + walkopts,
4237 4241 _('[OPTION]... [PATTERN]...')),
4238 4242 "^log|history":
4239 4243 (log,
4240 4244 [('f', 'follow', None,
4241 4245 _('follow changeset history,'
4242 4246 ' or file history across copies and renames')),
4243 4247 ('', 'follow-first', None,
4244 4248 _('only follow the first parent of merge changesets')),
4245 4249 ('d', 'date', '',
4246 4250 _('show revisions matching date spec'), _('DATE')),
4247 4251 ('C', 'copies', None, _('show copied files')),
4248 4252 ('k', 'keyword', [],
4249 4253 _('do case-insensitive search for a given text'), _('TEXT')),
4250 4254 ('r', 'rev', [],
4251 4255 _('show the specified revision or range'), _('REV')),
4252 4256 ('', 'removed', None, _('include revisions where files were removed')),
4253 4257 ('m', 'only-merges', None, _('show only merges')),
4254 4258 ('u', 'user', [],
4255 4259 _('revisions committed by user'), _('USER')),
4256 4260 ('', 'only-branch', [],
4257 4261 _('show only changesets within the given named branch (DEPRECATED)'),
4258 4262 _('BRANCH')),
4259 4263 ('b', 'branch', [],
4260 4264 _('show changesets within the given named branch'), _('BRANCH')),
4261 4265 ('P', 'prune', [],
4262 4266 _('do not display revision or any of its ancestors'), _('REV')),
4263 4267 ] + logopts + walkopts,
4264 4268 _('[OPTION]... [FILE]')),
4265 4269 "manifest":
4266 4270 (manifest,
4267 4271 [('r', 'rev', '',
4268 4272 _('revision to display'), _('REV'))],
4269 4273 _('[-r REV]')),
4270 4274 "^merge":
4271 4275 (merge,
4272 4276 [('f', 'force', None, _('force a merge with outstanding changes')),
4273 4277 ('r', 'rev', '',
4274 4278 _('revision to merge'), _('REV')),
4275 4279 ('P', 'preview', None,
4276 4280 _('review revisions to merge (no merge is performed)'))],
4277 4281 _('[-P] [-f] [[-r] REV]')),
4278 4282 "outgoing|out":
4279 4283 (outgoing,
4280 4284 [('f', 'force', None,
4281 4285 _('run even when the destination is unrelated')),
4282 4286 ('r', 'rev', [],
4283 4287 _('a changeset intended to be included in the destination'),
4284 4288 _('REV')),
4285 4289 ('n', 'newest-first', None, _('show newest record first')),
4286 4290 ('b', 'branch', [],
4287 4291 _('a specific branch you would like to push'), _('BRANCH')),
4288 4292 ] + logopts + remoteopts,
4289 4293 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4290 4294 "parents":
4291 4295 (parents,
4292 4296 [('r', 'rev', '',
4293 4297 _('show parents of the specified revision'), _('REV')),
4294 4298 ] + templateopts,
4295 4299 _('[-r REV] [FILE]')),
4296 4300 "paths": (paths, [], _('[NAME]')),
4297 4301 "^pull":
4298 4302 (pull,
4299 4303 [('u', 'update', None,
4300 4304 _('update to new branch head if changesets were pulled')),
4301 4305 ('f', 'force', None,
4302 4306 _('run even when remote repository is unrelated')),
4303 4307 ('r', 'rev', [],
4304 4308 _('a remote changeset intended to be added'), _('REV')),
4305 4309 ('b', 'branch', [],
4306 4310 _('a specific branch you would like to pull'), _('BRANCH')),
4307 4311 ] + remoteopts,
4308 4312 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4309 4313 "^push":
4310 4314 (push,
4311 4315 [('f', 'force', None, _('force push')),
4312 4316 ('r', 'rev', [],
4313 4317 _('a changeset intended to be included in the destination'),
4314 4318 _('REV')),
4315 4319 ('b', 'branch', [],
4316 4320 _('a specific branch you would like to push'), _('BRANCH')),
4317 4321 ('', 'new-branch', False, _('allow pushing a new branch')),
4318 4322 ] + remoteopts,
4319 4323 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4320 4324 "recover": (recover, []),
4321 4325 "^remove|rm":
4322 4326 (remove,
4323 4327 [('A', 'after', None, _('record delete for missing files')),
4324 4328 ('f', 'force', None,
4325 4329 _('remove (and delete) file even if added or modified')),
4326 4330 ] + walkopts,
4327 4331 _('[OPTION]... FILE...')),
4328 4332 "rename|mv":
4329 4333 (rename,
4330 4334 [('A', 'after', None, _('record a rename that has already occurred')),
4331 4335 ('f', 'force', None,
4332 4336 _('forcibly copy over an existing managed file')),
4333 4337 ] + walkopts + dryrunopts,
4334 4338 _('[OPTION]... SOURCE... DEST')),
4335 4339 "resolve":
4336 4340 (resolve,
4337 4341 [('a', 'all', None, _('select all unresolved files')),
4338 4342 ('l', 'list', None, _('list state of files needing merge')),
4339 4343 ('m', 'mark', None, _('mark files as resolved')),
4340 4344 ('u', 'unmark', None, _('unmark files as resolved')),
4341 4345 ('n', 'no-status', None, _('hide status prefix'))]
4342 4346 + walkopts,
4343 4347 _('[OPTION]... [FILE]...')),
4344 4348 "revert":
4345 4349 (revert,
4346 4350 [('a', 'all', None, _('revert all changes when no arguments given')),
4347 4351 ('d', 'date', '',
4348 4352 _('tipmost revision matching date'), _('DATE')),
4349 4353 ('r', 'rev', '',
4350 4354 _('revert to the specified revision'), _('REV')),
4351 4355 ('', 'no-backup', None, _('do not save backup copies of files')),
4352 4356 ] + walkopts + dryrunopts,
4353 4357 _('[OPTION]... [-r REV] [NAME]...')),
4354 4358 "rollback": (rollback, dryrunopts),
4355 4359 "root": (root, []),
4356 4360 "^serve":
4357 4361 (serve,
4358 4362 [('A', 'accesslog', '',
4359 4363 _('name of access log file to write to'), _('FILE')),
4360 4364 ('d', 'daemon', None, _('run server in background')),
4361 4365 ('', 'daemon-pipefds', '',
4362 4366 _('used internally by daemon mode'), _('NUM')),
4363 4367 ('E', 'errorlog', '',
4364 4368 _('name of error log file to write to'), _('FILE')),
4365 4369 # use string type, then we can check if something was passed
4366 4370 ('p', 'port', '',
4367 4371 _('port to listen on (default: 8000)'), _('PORT')),
4368 4372 ('a', 'address', '',
4369 4373 _('address to listen on (default: all interfaces)'), _('ADDR')),
4370 4374 ('', 'prefix', '',
4371 4375 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4372 4376 ('n', 'name', '',
4373 4377 _('name to show in web pages (default: working directory)'),
4374 4378 _('NAME')),
4375 4379 ('', 'web-conf', '',
4376 4380 _('name of the hgweb config file (serve more than one repository)'),
4377 4381 _('FILE')),
4378 4382 ('', 'webdir-conf', '',
4379 4383 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4380 4384 ('', 'pid-file', '',
4381 4385 _('name of file to write process ID to'), _('FILE')),
4382 4386 ('', 'stdio', None, _('for remote clients')),
4383 4387 ('t', 'templates', '',
4384 4388 _('web templates to use'), _('TEMPLATE')),
4385 4389 ('', 'style', '',
4386 4390 _('template style to use'), _('STYLE')),
4387 4391 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4388 4392 ('', 'certificate', '',
4389 4393 _('SSL certificate file'), _('FILE'))],
4390 4394 _('[OPTION]...')),
4391 4395 "showconfig|debugconfig":
4392 4396 (showconfig,
4393 4397 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4394 4398 _('[-u] [NAME]...')),
4395 4399 "^summary|sum":
4396 4400 (summary,
4397 4401 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4398 4402 "^status|st":
4399 4403 (status,
4400 4404 [('A', 'all', None, _('show status of all files')),
4401 4405 ('m', 'modified', None, _('show only modified files')),
4402 4406 ('a', 'added', None, _('show only added files')),
4403 4407 ('r', 'removed', None, _('show only removed files')),
4404 4408 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4405 4409 ('c', 'clean', None, _('show only files without changes')),
4406 4410 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4407 4411 ('i', 'ignored', None, _('show only ignored files')),
4408 4412 ('n', 'no-status', None, _('hide status prefix')),
4409 4413 ('C', 'copies', None, _('show source of copied files')),
4410 4414 ('0', 'print0', None,
4411 4415 _('end filenames with NUL, for use with xargs')),
4412 4416 ('', 'rev', [],
4413 4417 _('show difference from revision'), _('REV')),
4414 4418 ('', 'change', '',
4415 4419 _('list the changed files of a revision'), _('REV')),
4416 4420 ] + walkopts,
4417 4421 _('[OPTION]... [FILE]...')),
4418 4422 "tag":
4419 4423 (tag,
4420 4424 [('f', 'force', None, _('replace existing tag')),
4421 4425 ('l', 'local', None, _('make the tag local')),
4422 4426 ('r', 'rev', '',
4423 4427 _('revision to tag'), _('REV')),
4424 4428 ('', 'remove', None, _('remove a tag')),
4425 4429 # -l/--local is already there, commitopts cannot be used
4426 4430 ('e', 'edit', None, _('edit commit message')),
4427 4431 ('m', 'message', '',
4428 4432 _('use <text> as commit message'), _('TEXT')),
4429 4433 ] + commitopts2,
4430 4434 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4431 4435 "tags": (tags, [], ''),
4432 4436 "tip":
4433 4437 (tip,
4434 4438 [('p', 'patch', None, _('show patch')),
4435 4439 ('g', 'git', None, _('use git extended diff format')),
4436 4440 ] + templateopts,
4437 4441 _('[-p] [-g]')),
4438 4442 "unbundle":
4439 4443 (unbundle,
4440 4444 [('u', 'update', None,
4441 4445 _('update to new branch head if changesets were unbundled'))],
4442 4446 _('[-u] FILE...')),
4443 4447 "^update|up|checkout|co":
4444 4448 (update,
4445 4449 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4446 4450 ('c', 'check', None, _('check for uncommitted changes')),
4447 4451 ('d', 'date', '',
4448 4452 _('tipmost revision matching date'), _('DATE')),
4449 4453 ('r', 'rev', '',
4450 4454 _('revision'), _('REV'))],
4451 4455 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4452 4456 "verify": (verify, []),
4453 4457 "version": (version_, []),
4454 4458 }
4455 4459
4456 4460 norepo = ("clone init version help debugcommands debugcomplete debugdata"
4457 4461 " debugindex debugindexdot debugdate debuginstall debugfsinfo"
4458 4462 " debugpushkey")
4459 4463 optionalrepo = ("identify paths serve showconfig debugancestor debugdag")
@@ -1,670 +1,678
1 1 Mercurial Distributed SCM
2 2
3 3 basic commands:
4 4
5 5 add add the specified files on the next commit
6 6 annotate show changeset information by line for each file
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 repository (or selected files)
10 10 export dump the header and diffs for one or more changesets
11 11 forget forget the specified files on the next commit
12 12 init create a new repository in the given directory
13 13 log show revision history of entire repository or files
14 14 merge merge working directory with another revision
15 15 pull pull changes from the specified source
16 16 push push changes to the specified destination
17 17 remove remove the specified files on the next commit
18 18 serve start stand-alone webserver
19 19 status show changed files in the working directory
20 20 summary summarize working directory state
21 21 update update working directory (or switch revisions)
22 22
23 23 use "hg help" for the full list of commands or "hg -v" for details
24 24 add add the specified files on the next commit
25 25 annotate show changeset information by line for each file
26 26 clone make a copy of an existing repository
27 27 commit commit the specified files or all outstanding changes
28 28 diff diff repository (or selected files)
29 29 export dump the header and diffs for one or more changesets
30 30 forget forget the specified files on the next commit
31 31 init create a new repository in the given directory
32 32 log show revision history of entire repository or files
33 33 merge merge working directory with another revision
34 34 pull pull changes from the specified source
35 35 push push changes to the specified destination
36 36 remove remove the specified files on the next commit
37 37 serve start stand-alone webserver
38 38 status show changed files in the working directory
39 39 summary summarize working directory state
40 40 update update working directory (or switch revisions)
41 41 Mercurial Distributed SCM
42 42
43 43 list of commands:
44 44
45 45 add add the specified files on the next commit
46 46 addremove add all new files, delete all missing files
47 47 annotate show changeset information by line for each file
48 48 archive create an unversioned archive of a repository revision
49 49 backout reverse effect of earlier changeset
50 50 bisect subdivision search of changesets
51 51 branch set or show the current branch name
52 52 branches list repository named branches
53 53 bundle create a changegroup file
54 54 cat output the current or given revision of files
55 55 clone make a copy of an existing repository
56 56 commit commit the specified files or all outstanding changes
57 57 copy mark files as copied for the next commit
58 58 diff diff repository (or selected files)
59 59 export dump the header and diffs for one or more changesets
60 60 forget forget the specified files on the next commit
61 61 grep search for a pattern in specified files and revisions
62 62 heads show current repository heads or show branch heads
63 63 help show help for a given topic or a help overview
64 64 identify identify the working copy or specified revision
65 65 import import an ordered set of patches
66 66 incoming show new changesets found in source
67 67 init create a new repository in the given directory
68 68 locate locate files matching specific patterns
69 69 log show revision history of entire repository or files
70 70 manifest output the current or given revision of the project manifest
71 71 merge merge working directory with another revision
72 72 outgoing show changesets not found in the destination
73 73 parents show the parents of the working directory or revision
74 74 paths show aliases for remote repositories
75 75 pull pull changes from the specified source
76 76 push push changes to the specified destination
77 77 recover roll back an interrupted transaction
78 78 remove remove the specified files on the next commit
79 79 rename rename files; equivalent of copy + remove
80 80 resolve various operations to help finish a merge
81 81 revert restore individual files or directories to an earlier state
82 82 rollback roll back the last transaction (dangerous)
83 83 root print the root (top) of the current working directory
84 84 serve start stand-alone webserver
85 85 showconfig show combined config settings from all hgrc files
86 86 status show changed files in the working directory
87 87 summary summarize working directory state
88 88 tag add one or more tags for the current or given revision
89 89 tags list repository tags
90 90 tip show the tip revision
91 91 unbundle apply one or more changegroup files
92 92 update update working directory (or switch revisions)
93 93 verify verify the integrity of the repository
94 94 version output version and copyright information
95 95
96 96 additional help topics:
97 97
98 98 config Configuration Files
99 99 dates Date Formats
100 100 patterns File Name Patterns
101 101 environment Environment Variables
102 102 revisions Specifying Single Revisions
103 103 multirevs Specifying Multiple Revisions
104 104 revsets Specifying Revision Sets
105 105 diffs Diff Formats
106 106 templating Template Usage
107 107 urls URL Paths
108 108 extensions Using additional features
109 109 hgweb Configuring hgweb
110 110 glossary Glossary
111 111
112 112 use "hg -v help" to show aliases and global options
113 113 add add the specified files on the next commit
114 114 addremove add all new files, delete all missing files
115 115 annotate show changeset information by line for each file
116 116 archive create an unversioned archive of a repository revision
117 117 backout reverse effect of earlier changeset
118 118 bisect subdivision search of changesets
119 119 branch set or show the current branch name
120 120 branches list repository named branches
121 121 bundle create a changegroup file
122 122 cat output the current or given revision of files
123 123 clone make a copy of an existing repository
124 124 commit commit the specified files or all outstanding changes
125 125 copy mark files as copied for the next commit
126 126 diff diff repository (or selected files)
127 127 export dump the header and diffs for one or more changesets
128 128 forget forget the specified files on the next commit
129 129 grep search for a pattern in specified files and revisions
130 130 heads show current repository heads or show branch heads
131 131 help show help for a given topic or a help overview
132 132 identify identify the working copy or specified revision
133 133 import import an ordered set of patches
134 134 incoming show new changesets found in source
135 135 init create a new repository in the given directory
136 136 locate locate files matching specific patterns
137 137 log show revision history of entire repository or files
138 138 manifest output the current or given revision of the project manifest
139 139 merge merge working directory with another revision
140 140 outgoing show changesets not found in the destination
141 141 parents show the parents of the working directory or revision
142 142 paths show aliases for remote repositories
143 143 pull pull changes from the specified source
144 144 push push changes to the specified destination
145 145 recover roll back an interrupted transaction
146 146 remove remove the specified files on the next commit
147 147 rename rename files; equivalent of copy + remove
148 148 resolve various operations to help finish a merge
149 149 revert restore individual files or directories to an earlier state
150 150 rollback roll back the last transaction (dangerous)
151 151 root print the root (top) of the current working directory
152 152 serve start stand-alone webserver
153 153 showconfig show combined config settings from all hgrc files
154 154 status show changed files in the working directory
155 155 summary summarize working directory state
156 156 tag add one or more tags for the current or given revision
157 157 tags list repository tags
158 158 tip show the tip revision
159 159 unbundle apply one or more changegroup files
160 160 update update working directory (or switch revisions)
161 161 verify verify the integrity of the repository
162 162 version output version and copyright information
163 163
164 164 additional help topics:
165 165
166 166 config Configuration Files
167 167 dates Date Formats
168 168 patterns File Name Patterns
169 169 environment Environment Variables
170 170 revisions Specifying Single Revisions
171 171 multirevs Specifying Multiple Revisions
172 172 revsets Specifying Revision Sets
173 173 diffs Diff Formats
174 174 templating Template Usage
175 175 urls URL Paths
176 176 extensions Using additional features
177 177 hgweb Configuring hgweb
178 178 glossary Glossary
179 179 %% test short command list with verbose option
180 180 Mercurial Distributed SCM (version xxx)
181 181
182 182 Copyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others
183 183 This is free software; see the source for copying conditions. There is NO
184 184 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
185 185
186 186 basic commands:
187 187
188 188 add:
189 189 add the specified files on the next commit
190 190 annotate, blame:
191 191 show changeset information by line for each file
192 192 clone:
193 193 make a copy of an existing repository
194 194 commit, ci:
195 195 commit the specified files or all outstanding changes
196 196 diff:
197 197 diff repository (or selected files)
198 198 export:
199 199 dump the header and diffs for one or more changesets
200 200 forget:
201 201 forget the specified files on the next commit
202 202 init:
203 203 create a new repository in the given directory
204 204 log, history:
205 205 show revision history of entire repository or files
206 206 merge:
207 207 merge working directory with another revision
208 208 pull:
209 209 pull changes from the specified source
210 210 push:
211 211 push changes to the specified destination
212 212 remove, rm:
213 213 remove the specified files on the next commit
214 214 serve:
215 215 start stand-alone webserver
216 216 status, st:
217 217 show changed files in the working directory
218 218 summary, sum:
219 219 summarize working directory state
220 220 update, up, checkout, co:
221 221 update working directory (or switch revisions)
222 222
223 223 global options:
224 224 -R --repository REPO repository root directory or name of overlay bundle
225 225 file
226 226 --cwd DIR change working directory
227 227 -y --noninteractive do not prompt, assume 'yes' for any required answers
228 228 -q --quiet suppress output
229 229 -v --verbose enable additional output
230 230 --config CONFIG [+] set/override config option (use 'section.name=value')
231 231 --debug enable debugging output
232 232 --debugger start debugger
233 233 --encoding ENCODE set the charset encoding (default: ascii)
234 234 --encodingmode MODE set the charset encoding mode (default: strict)
235 235 --traceback always print a traceback on exception
236 236 --time time how long the command takes
237 237 --profile print command execution profile
238 238 --version output version information and exit
239 239 -h --help display help and exit
240 240
241 241 [+] marked option can be specified multiple times
242 242
243 243 use "hg help" for the full list of commands
244 244 hg add [OPTION]... [FILE]...
245 245
246 246 add the specified files on the next commit
247 247
248 248 Schedule files to be version controlled and added to the repository.
249 249
250 250 The files will be added to the repository at the next commit. To undo an
251 251 add before that, see "hg forget".
252 252
253 253 If no names are given, add all files to the repository.
254 254
255 Returns 0 if all files are successfully added.
256
255 257 use "hg -v help add" to show verbose help
256 258
257 259 options:
258 260
259 261 -I --include PATTERN [+] include names matching the given patterns
260 262 -X --exclude PATTERN [+] exclude names matching the given patterns
261 263 -n --dry-run do not perform actions, just print output
262 264
263 265 [+] marked option can be specified multiple times
264 266
265 267 use "hg -v help add" to show global options
266 268 %% verbose help for add
267 269 hg add [OPTION]... [FILE]...
268 270
269 271 add the specified files on the next commit
270 272
271 273 Schedule files to be version controlled and added to the repository.
272 274
273 275 The files will be added to the repository at the next commit. To undo an
274 276 add before that, see "hg forget".
275 277
276 278 If no names are given, add all files to the repository.
277 279
278 280 An example showing how new (unknown) files are added automatically by "hg
279 281 add":
280 282
281 283 $ ls
282 284 foo.c
283 285 $ hg status
284 286 ? foo.c
285 287 $ hg add
286 288 adding foo.c
287 289 $ hg status
288 290 A foo.c
289 291
292 Returns 0 if all files are successfully added.
293
290 294 options:
291 295
292 296 -I --include PATTERN [+] include names matching the given patterns
293 297 -X --exclude PATTERN [+] exclude names matching the given patterns
294 298 -n --dry-run do not perform actions, just print output
295 299
296 300 global options:
297 301 -R --repository REPO repository root directory or name of overlay bundle
298 302 file
299 303 --cwd DIR change working directory
300 304 -y --noninteractive do not prompt, assume 'yes' for any required
301 305 answers
302 306 -q --quiet suppress output
303 307 -v --verbose enable additional output
304 308 --config CONFIG [+] set/override config option (use
305 309 'section.name=value')
306 310 --debug enable debugging output
307 311 --debugger start debugger
308 312 --encoding ENCODE set the charset encoding (default: ascii)
309 313 --encodingmode MODE set the charset encoding mode (default: strict)
310 314 --traceback always print a traceback on exception
311 315 --time time how long the command takes
312 316 --profile print command execution profile
313 317 --version output version information and exit
314 318 -h --help display help and exit
315 319
316 320 [+] marked option can be specified multiple times
317 321 %% test help option with version option
318 322 Mercurial Distributed SCM (version xxx)
319 323
320 324 Copyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others
321 325 This is free software; see the source for copying conditions. There is NO
322 326 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
323 327
324 328 hg add [OPTION]... [FILE]...
325 329
326 330 add the specified files on the next commit
327 331
328 332 Schedule files to be version controlled and added to the repository.
329 333
330 334 The files will be added to the repository at the next commit. To undo an
331 335 add before that, see "hg forget".
332 336
333 337 If no names are given, add all files to the repository.
334 338
339 Returns 0 if all files are successfully added.
340
335 341 use "hg -v help add" to show verbose help
336 342
337 343 options:
338 344
339 345 -I --include PATTERN [+] include names matching the given patterns
340 346 -X --exclude PATTERN [+] exclude names matching the given patterns
341 347 -n --dry-run do not perform actions, just print output
342 348
343 349 [+] marked option can be specified multiple times
344 350
345 351 use "hg -v help add" to show global options
346 352 hg add: option --skjdfks not recognized
347 353 hg add [OPTION]... [FILE]...
348 354
349 355 add the specified files on the next commit
350 356
351 357 Schedule files to be version controlled and added to the repository.
352 358
353 359 The files will be added to the repository at the next commit. To undo an
354 360 add before that, see "hg forget".
355 361
356 362 If no names are given, add all files to the repository.
357 363
364 Returns 0 if all files are successfully added.
365
358 366 use "hg -v help add" to show verbose help
359 367
360 368 options:
361 369
362 370 -I --include PATTERN [+] include names matching the given patterns
363 371 -X --exclude PATTERN [+] exclude names matching the given patterns
364 372 -n --dry-run do not perform actions, just print output
365 373
366 374 [+] marked option can be specified multiple times
367 375
368 376 use "hg -v help add" to show global options
369 377 %% test ambiguous command help
370 378 list of commands:
371 379
372 380 add add the specified files on the next commit
373 381 addremove add all new files, delete all missing files
374 382
375 383 use "hg -v help ad" to show aliases and global options
376 384 %% test command without options
377 385 hg verify
378 386
379 387 verify the integrity of the repository
380 388
381 389 Verify the integrity of the current repository.
382 390
383 391 This will perform an extensive check of the repository's integrity,
384 392 validating the hashes and checksums of each entry in the changelog,
385 393 manifest, and tracked files, as well as the integrity of their crosslinks
386 394 and indices.
387 395
388 396 Returns 0 on success, 1 if errors are encountered.
389 397
390 398 use "hg -v help verify" to show global options
391 399 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
392 400
393 401 diff repository (or selected files)
394 402
395 403 Show differences between revisions for the specified files.
396 404
397 405 Differences between files are shown using the unified diff format.
398 406
399 407 NOTE: diff may generate unexpected results for merges, as it will default
400 408 to comparing against the working directory's first parent changeset if no
401 409 revisions are specified.
402 410
403 411 When two revision arguments are given, then changes are shown between
404 412 those revisions. If only one revision is specified then that revision is
405 413 compared to the working directory, and, when no revisions are specified,
406 414 the working directory files are compared to its parent.
407 415
408 416 Alternatively you can specify -c/--change with a revision to see the
409 417 changes in that changeset relative to its first parent.
410 418
411 419 Without the -a/--text option, diff will avoid generating diffs of files it
412 420 detects as binary. With -a, diff will generate a diff anyway, probably
413 421 with undesirable results.
414 422
415 423 Use the -g/--git option to generate diffs in the git extended diff format.
416 424 For more information, read "hg help diffs".
417 425
418 426 Returns 0 on success.
419 427
420 428 options:
421 429
422 430 -r --rev REV [+] revision
423 431 -c --change REV change made by revision
424 432 -a --text treat all files as text
425 433 -g --git use git extended diff format
426 434 --nodates omit dates from diff headers
427 435 -p --show-function show which function each change is in
428 436 --reverse produce a diff that undoes the changes
429 437 -w --ignore-all-space ignore white space when comparing lines
430 438 -b --ignore-space-change ignore changes in the amount of white space
431 439 -B --ignore-blank-lines ignore changes whose lines are all blank
432 440 -U --unified NUM number of lines of context to show
433 441 --stat output diffstat-style summary of changes
434 442 -I --include PATTERN [+] include names matching the given patterns
435 443 -X --exclude PATTERN [+] exclude names matching the given patterns
436 444
437 445 [+] marked option can be specified multiple times
438 446
439 447 use "hg -v help diff" to show global options
440 448 hg status [OPTION]... [FILE]...
441 449
442 450 aliases: st
443 451
444 452 show changed files in the working directory
445 453
446 454 Show status of files in the repository. If names are given, only files
447 455 that match are shown. Files that are clean or ignored or the source of a
448 456 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
449 457 -C/--copies or -A/--all are given. Unless options described with "show
450 458 only ..." are given, the options -mardu are used.
451 459
452 460 Option -q/--quiet hides untracked (unknown and ignored) files unless
453 461 explicitly requested with -u/--unknown or -i/--ignored.
454 462
455 463 NOTE: status may appear to disagree with diff if permissions have changed
456 464 or a merge has occurred. The standard diff format does not report
457 465 permission changes and diff only reports changes relative to one merge
458 466 parent.
459 467
460 468 If one revision is given, it is used as the base revision. If two
461 469 revisions are given, the differences between them are shown. The --change
462 470 option can also be used as a shortcut to list the changed files of a
463 471 revision from its first parent.
464 472
465 473 The codes used to show the status of files are:
466 474
467 475 M = modified
468 476 A = added
469 477 R = removed
470 478 C = clean
471 479 ! = missing (deleted by non-hg command, but still tracked)
472 480 ? = not tracked
473 481 I = ignored
474 482 = origin of the previous file listed as A (added)
475 483
476 484 Returns 0 on success.
477 485
478 486 options:
479 487
480 488 -A --all show status of all files
481 489 -m --modified show only modified files
482 490 -a --added show only added files
483 491 -r --removed show only removed files
484 492 -d --deleted show only deleted (but tracked) files
485 493 -c --clean show only files without changes
486 494 -u --unknown show only unknown (not tracked) files
487 495 -i --ignored show only ignored files
488 496 -n --no-status hide status prefix
489 497 -C --copies show source of copied files
490 498 -0 --print0 end filenames with NUL, for use with xargs
491 499 --rev REV [+] show difference from revision
492 500 --change REV list the changed files of a revision
493 501 -I --include PATTERN [+] include names matching the given patterns
494 502 -X --exclude PATTERN [+] exclude names matching the given patterns
495 503
496 504 [+] marked option can be specified multiple times
497 505
498 506 use "hg -v help status" to show global options
499 507 hg status [OPTION]... [FILE]...
500 508
501 509 show changed files in the working directory
502 510 hg: unknown command 'foo'
503 511 Mercurial Distributed SCM
504 512
505 513 basic commands:
506 514
507 515 add add the specified files on the next commit
508 516 annotate show changeset information by line for each file
509 517 clone make a copy of an existing repository
510 518 commit commit the specified files or all outstanding changes
511 519 diff diff repository (or selected files)
512 520 export dump the header and diffs for one or more changesets
513 521 forget forget the specified files on the next commit
514 522 init create a new repository in the given directory
515 523 log show revision history of entire repository or files
516 524 merge merge working directory with another revision
517 525 pull pull changes from the specified source
518 526 push push changes to the specified destination
519 527 remove remove the specified files on the next commit
520 528 serve start stand-alone webserver
521 529 status show changed files in the working directory
522 530 summary summarize working directory state
523 531 update update working directory (or switch revisions)
524 532
525 533 use "hg help" for the full list of commands or "hg -v" for details
526 534 hg: unknown command 'skjdfks'
527 535 Mercurial Distributed SCM
528 536
529 537 basic commands:
530 538
531 539 add add the specified files on the next commit
532 540 annotate show changeset information by line for each file
533 541 clone make a copy of an existing repository
534 542 commit commit the specified files or all outstanding changes
535 543 diff diff repository (or selected files)
536 544 export dump the header and diffs for one or more changesets
537 545 forget forget the specified files on the next commit
538 546 init create a new repository in the given directory
539 547 log show revision history of entire repository or files
540 548 merge merge working directory with another revision
541 549 pull pull changes from the specified source
542 550 push push changes to the specified destination
543 551 remove remove the specified files on the next commit
544 552 serve start stand-alone webserver
545 553 status show changed files in the working directory
546 554 summary summarize working directory state
547 555 update update working directory (or switch revisions)
548 556
549 557 use "hg help" for the full list of commands or "hg -v" for details
550 558 %% test command with no help text
551 559 hg nohelp
552 560
553 561 (no help text available)
554 562
555 563 use "hg -v help nohelp" to show global options
556 564 %% test that default list of commands omits extension commands
557 565 Mercurial Distributed SCM
558 566
559 567 list of commands:
560 568
561 569 add add the specified files on the next commit
562 570 addremove add all new files, delete all missing files
563 571 annotate show changeset information by line for each file
564 572 archive create an unversioned archive of a repository revision
565 573 backout reverse effect of earlier changeset
566 574 bisect subdivision search of changesets
567 575 branch set or show the current branch name
568 576 branches list repository named branches
569 577 bundle create a changegroup file
570 578 cat output the current or given revision of files
571 579 clone make a copy of an existing repository
572 580 commit commit the specified files or all outstanding changes
573 581 copy mark files as copied for the next commit
574 582 diff diff repository (or selected files)
575 583 export dump the header and diffs for one or more changesets
576 584 forget forget the specified files on the next commit
577 585 grep search for a pattern in specified files and revisions
578 586 heads show current repository heads or show branch heads
579 587 help show help for a given topic or a help overview
580 588 identify identify the working copy or specified revision
581 589 import import an ordered set of patches
582 590 incoming show new changesets found in source
583 591 init create a new repository in the given directory
584 592 locate locate files matching specific patterns
585 593 log show revision history of entire repository or files
586 594 manifest output the current or given revision of the project manifest
587 595 merge merge working directory with another revision
588 596 outgoing show changesets not found in the destination
589 597 parents show the parents of the working directory or revision
590 598 paths show aliases for remote repositories
591 599 pull pull changes from the specified source
592 600 push push changes to the specified destination
593 601 recover roll back an interrupted transaction
594 602 remove remove the specified files on the next commit
595 603 rename rename files; equivalent of copy + remove
596 604 resolve various operations to help finish a merge
597 605 revert restore individual files or directories to an earlier state
598 606 rollback roll back the last transaction (dangerous)
599 607 root print the root (top) of the current working directory
600 608 serve start stand-alone webserver
601 609 showconfig show combined config settings from all hgrc files
602 610 status show changed files in the working directory
603 611 summary summarize working directory state
604 612 tag add one or more tags for the current or given revision
605 613 tags list repository tags
606 614 tip show the tip revision
607 615 unbundle apply one or more changegroup files
608 616 update update working directory (or switch revisions)
609 617 verify verify the integrity of the repository
610 618 version output version and copyright information
611 619
612 620 enabled extensions:
613 621
614 622 helpext (no help text available)
615 623
616 624 additional help topics:
617 625
618 626 config Configuration Files
619 627 dates Date Formats
620 628 patterns File Name Patterns
621 629 environment Environment Variables
622 630 revisions Specifying Single Revisions
623 631 multirevs Specifying Multiple Revisions
624 632 revsets Specifying Revision Sets
625 633 diffs Diff Formats
626 634 templating Template Usage
627 635 urls URL Paths
628 636 extensions Using additional features
629 637 hgweb Configuring hgweb
630 638 glossary Glossary
631 639
632 640 use "hg -v help" to show aliases and global options
633 641 %% test list of commands with command with no help text
634 642 helpext extension - no help text available
635 643
636 644 list of commands:
637 645
638 646 nohelp (no help text available)
639 647
640 648 use "hg -v help helpext" to show aliases and global options
641 649 %% test a help topic
642 650 Specifying Single Revisions
643 651
644 652 Mercurial supports several ways to specify individual revisions.
645 653
646 654 A plain integer is treated as a revision number. Negative integers are
647 655 treated as sequential offsets from the tip, with -1 denoting the tip, -2
648 656 denoting the revision prior to the tip, and so forth.
649 657
650 658 A 40-digit hexadecimal string is treated as a unique revision identifier.
651 659
652 660 A hexadecimal string less than 40 characters long is treated as a unique
653 661 revision identifier and is referred to as a short-form identifier. A
654 662 short-form identifier is only valid if it is the prefix of exactly one
655 663 full-length identifier.
656 664
657 665 Any other string is treated as a tag or branch name. A tag name is a
658 666 symbolic name associated with a revision identifier. A branch name denotes
659 667 the tipmost revision of that branch. Tag and branch names must not contain
660 668 the ":" character.
661 669
662 670 The reserved name "tip" is a special tag that always identifies the most
663 671 recent revision.
664 672
665 673 The reserved name "null" indicates the null revision. This is the revision
666 674 of an empty repository, and the parent of revision 0.
667 675
668 676 The reserved name "." indicates the working directory parent. If no
669 677 working directory is checked out, it is equivalent to null. If an
670 678 uncommitted merge is in progress, "." is the revision of the first parent.
General Comments 0
You need to be logged in to leave comments. Login now