comparison mercurial/commands.py @ 6042:2da5b19a6460

Merge with crew
author Bryan O'Sullivan <bos@serpentine.com>
date Wed, 06 Feb 2008 19:57:52 -0800
parents 1d0bfa4c75c0 5af5f0f9d724
children cfb4a51da7d5
comparison
equal deleted inserted replaced
6041:dd714452c26e 6042:2da5b19a6460
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # 4 #
5 # This software may be used and distributed according to the terms 5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference. 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 import demandimport; demandimport.enable()
9 from node import * 8 from node import *
10 from i18n import _ 9 from i18n import _
11 import bisect, os, re, sys, urllib, stat 10 import os, re, sys, urllib
12 import ui, hg, util, revlog, bundlerepo, extensions 11 import hg, util, revlog, bundlerepo, extensions
13 import difflib, patch, time, help, mdiff, tempfile 12 import difflib, patch, time, help, mdiff, tempfile
14 import errno, version, socket 13 import errno, version, socket
15 import archival, changegroup, cmdutil, hgweb.server, sshserver 14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
16 15
17 # Commands start here, listed alphabetically 16 # Commands start here, listed alphabetically
18 17
19 def add(ui, repo, *pats, **opts): 18 def add(ui, repo, *pats, **opts):
20 """add the specified files on the next commit 19 """add the specified files on the next commit
25 undo an add before that, see hg revert. 24 undo an add before that, see hg revert.
26 25
27 If no names are given, add all files in the repository. 26 If no names are given, add all files in the repository.
28 """ 27 """
29 28
29 rejected = None
30 exacts = {}
30 names = [] 31 names = []
31 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): 32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
33 badmatch=util.always):
32 if exact: 34 if exact:
33 if ui.verbose: 35 if ui.verbose:
34 ui.status(_('adding %s\n') % rel) 36 ui.status(_('adding %s\n') % rel)
35 names.append(abs) 37 names.append(abs)
38 exacts[abs] = 1
36 elif abs not in repo.dirstate: 39 elif abs not in repo.dirstate:
37 ui.status(_('adding %s\n') % rel) 40 ui.status(_('adding %s\n') % rel)
38 names.append(abs) 41 names.append(abs)
39 if not opts.get('dry_run'): 42 if not opts.get('dry_run'):
40 repo.add(names) 43 rejected = repo.add(names)
44 rejected = [p for p in rejected if p in exacts]
45 return rejected and 1 or 0
41 46
42 def addremove(ui, repo, *pats, **opts): 47 def addremove(ui, repo, *pats, **opts):
43 """add all new files, delete all missing files 48 """add all new files, delete all missing files
44 49
45 Add all new files and remove all missing files from the repository. 50 Add all new files and remove all missing files from the repository.
189 194
190 if not rev: 195 if not rev:
191 raise util.Abort(_("please specify a revision to backout")) 196 raise util.Abort(_("please specify a revision to backout"))
192 197
193 cmdutil.bail_if_changed(repo) 198 cmdutil.bail_if_changed(repo)
199 node = repo.lookup(rev)
200
194 op1, op2 = repo.dirstate.parents() 201 op1, op2 = repo.dirstate.parents()
195 if op2 != nullid: 202 a = repo.changelog.ancestor(op1, node)
196 raise util.Abort(_('outstanding uncommitted merge')) 203 if a != node:
197 node = repo.lookup(rev) 204 raise util.Abort(_('cannot back out change on a different branch'))
205
198 p1, p2 = repo.changelog.parents(node) 206 p1, p2 = repo.changelog.parents(node)
199 if p1 == nullid: 207 if p1 == nullid:
200 raise util.Abort(_('cannot back out a change with no parents')) 208 raise util.Abort(_('cannot back out a change with no parents'))
201 if p2 != nullid: 209 if p2 != nullid:
202 if not opts['parent']: 210 if not opts['parent']:
209 parent = p 217 parent = p
210 else: 218 else:
211 if opts['parent']: 219 if opts['parent']:
212 raise util.Abort(_('cannot use --parent on non-merge changeset')) 220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
213 parent = p1 221 parent = p1
222
214 hg.clean(repo, node, show_stats=False) 223 hg.clean(repo, node, show_stats=False)
215 revert_opts = opts.copy() 224 revert_opts = opts.copy()
216 revert_opts['date'] = None 225 revert_opts['date'] = None
217 revert_opts['all'] = True 226 revert_opts['all'] = True
218 revert_opts['rev'] = hex(parent) 227 revert_opts['rev'] = hex(parent)
235 ui.status(_('the backout changeset is a new head - ' 244 ui.status(_('the backout changeset is a new head - '
236 'do not forget to merge\n')) 245 'do not forget to merge\n'))
237 ui.status(_('(use "backout --merge" ' 246 ui.status(_('(use "backout --merge" '
238 'if you want to auto-merge)\n')) 247 'if you want to auto-merge)\n'))
239 248
249 def bisect(ui, repo, rev=None, extra=None,
250 reset=None, good=None, bad=None, skip=None, noupdate=None):
251 """subdivision search of changesets
252
253 This command helps to find changesets which introduce problems.
254 To use, mark the earliest changeset you know exhibits the problem
255 as bad, then mark the latest changeset which is free from the
256 problem as good. Bisect will update your working directory to a
257 revision for testing. Once you have performed tests, mark the
258 working directory as bad or good and bisect will either update to
259 another candidate changeset or announce that it has found the bad
260 revision.
261 """
262 # backward compatibility
263 if rev in "good bad reset init".split():
264 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
265 cmd, rev, extra = rev, extra, None
266 if cmd == "good":
267 good = True
268 elif cmd == "bad":
269 bad = True
270 else:
271 reset = True
272 elif extra or good + bad + skip + reset > 1:
273 raise util.Abort("Incompatible arguments")
274
275 if reset:
276 p = repo.join("bisect.state")
277 if os.path.exists(p):
278 os.unlink(p)
279 return
280
281 # load state
282 state = {'good': [], 'bad': [], 'skip': []}
283 if os.path.exists(repo.join("bisect.state")):
284 for l in repo.opener("bisect.state"):
285 kind, node = l[:-1].split()
286 node = repo.lookup(node)
287 if kind not in state:
288 raise util.Abort(_("unknown bisect kind %s") % kind)
289 state[kind].append(node)
290
291 # update state
292 node = repo.lookup(rev or '.')
293 if good:
294 state['good'].append(node)
295 elif bad:
296 state['bad'].append(node)
297 elif skip:
298 state['skip'].append(node)
299
300 # save state
301 f = repo.opener("bisect.state", "w", atomictemp=True)
302 wlock = repo.wlock()
303 try:
304 for kind in state:
305 for node in state[kind]:
306 f.write("%s %s\n" % (kind, hg.hex(node)))
307 f.rename()
308 finally:
309 del wlock
310
311 if not state['good'] or not state['bad']:
312 return
313
314 # actually bisect
315 node, changesets, good = hbisect.bisect(repo.changelog, state)
316 if changesets == 0:
317 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
318 displayer = cmdutil.show_changeset(ui, repo, {})
319 displayer.show(changenode=node)
320 elif node is not None:
321 # compute the approximate number of remaining tests
322 tests, size = 0, 2
323 while size <= changesets:
324 tests, size = tests + 1, size * 2
325 rev = repo.changelog.rev(node)
326 ui.write(_("Testing changeset %s:%s "
327 "(%s changesets remaining, ~%s tests)\n")
328 % (rev, hg.short(node), changesets, tests))
329 if not noupdate:
330 cmdutil.bail_if_changed(repo)
331 return hg.clean(repo, node)
332
240 def branch(ui, repo, label=None, **opts): 333 def branch(ui, repo, label=None, **opts):
241 """set or show the current branch name 334 """set or show the current branch name
242 335
243 With no argument, show the current branch name. With one argument, 336 With no argument, show the current branch name. With one argument,
244 set the working directory branch name (the branch does not exist in 337 set the working directory branch name (the branch does not exist in
245 the repository until the next commit). 338 the repository until the next commit).
246 339
247 Unless --force is specified, branch will not let you set a 340 Unless --force is specified, branch will not let you set a
248 branch name that shadows an existing branch. 341 branch name that shadows an existing branch.
342
343 Use the command 'hg update' to switch to an existing branch.
249 """ 344 """
250 345
251 if label: 346 if label:
252 if not opts.get('force') and label in repo.branchtags(): 347 if not opts.get('force') and label in repo.branchtags():
253 if label not in [p.branch() for p in repo.workingctx().parents()]: 348 if label not in [p.branch() for p in repo.workingctx().parents()]:
263 358
264 List the repository's named branches, indicating which ones are 359 List the repository's named branches, indicating which ones are
265 inactive. If active is specified, only show active branches. 360 inactive. If active is specified, only show active branches.
266 361
267 A branch is considered active if it contains unmerged heads. 362 A branch is considered active if it contains unmerged heads.
363
364 Use the command 'hg update' to switch to an existing branch.
268 """ 365 """
269 b = repo.branchtags() 366 b = repo.branchtags()
270 heads = dict.fromkeys(repo.heads(), 1) 367 heads = dict.fromkeys(repo.heads(), 1)
271 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()] 368 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
272 l.sort() 369 l.sort()
293 Generate a compressed changegroup file collecting changesets not 390 Generate a compressed changegroup file collecting changesets not
294 found in the other repository. 391 found in the other repository.
295 392
296 If no destination repository is specified the destination is assumed 393 If no destination repository is specified the destination is assumed
297 to have all the nodes specified by one or more --base parameters. 394 to have all the nodes specified by one or more --base parameters.
395 To create a bundle containing all changesets, use --base null.
298 396
299 The bundle file can then be transferred using conventional means and 397 The bundle file can then be transferred using conventional means and
300 applied to another repository with the unbundle or pull command. 398 applied to another repository with the unbundle or pull command.
301 This is useful when direct push and pull are not available or when 399 This is useful when direct push and pull are not available or when
302 exporting an entire repository is undesirable. 400 exporting an entire repository is undesirable.
334 if p not in seen: 432 if p not in seen:
335 seen[p] = 1 433 seen[p] = 1
336 visit.append(p) 434 visit.append(p)
337 else: 435 else:
338 cmdutil.setremoteconfig(ui, opts) 436 cmdutil.setremoteconfig(ui, opts)
339 dest, revs = cmdutil.parseurl( 437 dest, revs, checkout = hg.parseurl(
340 ui.expandpath(dest or 'default-push', dest or 'default'), revs) 438 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
341 other = hg.repository(ui, dest) 439 other = hg.repository(ui, dest)
342 o = repo.findoutgoing(other, force=opts['force']) 440 o = repo.findoutgoing(other, force=opts['force'])
343 441
344 if revs: 442 if revs:
423 Commit changes to the given files into the repository. 521 Commit changes to the given files into the repository.
424 522
425 If a list of files is omitted, all changes reported by "hg status" 523 If a list of files is omitted, all changes reported by "hg status"
426 will be committed. 524 will be committed.
427 525
428 If no commit message is specified, the editor configured in your hgrc 526 If no commit message is specified, the configured editor is started to
429 or in the EDITOR environment variable is started to enter a message. 527 enter a message.
430 """ 528 """
431 message = cmdutil.logmessage(opts) 529 def commitfunc(ui, repo, files, message, match, opts):
432 530 return repo.commit(files, message, opts['user'], opts['date'], match,
433 if opts['addremove']: 531 force_editor=opts.get('force_editor'))
434 cmdutil.addremove(repo, pats, opts) 532 cmdutil.commit(ui, repo, commitfunc, pats, opts)
435 fns, match, anypats = cmdutil.matchpats(repo, pats, opts)
436 if pats:
437 status = repo.status(files=fns, match=match)
438 modified, added, removed, deleted, unknown = status[:5]
439 files = modified + added + removed
440 slist = None
441 for f in fns:
442 if f == '.':
443 continue
444 if f not in files:
445 rf = repo.wjoin(f)
446 try:
447 mode = os.lstat(rf)[stat.ST_MODE]
448 except OSError:
449 raise util.Abort(_("file %s not found!") % rf)
450 if stat.S_ISDIR(mode):
451 name = f + '/'
452 if slist is None:
453 slist = list(files)
454 slist.sort()
455 i = bisect.bisect(slist, name)
456 if i >= len(slist) or not slist[i].startswith(name):
457 raise util.Abort(_("no match under directory %s!")
458 % rf)
459 elif not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)):
460 raise util.Abort(_("can't commit %s: "
461 "unsupported file type!") % rf)
462 elif f not in repo.dirstate:
463 raise util.Abort(_("file %s not tracked!") % rf)
464 else:
465 files = []
466 try:
467 repo.commit(files, message, opts['user'], opts['date'], match,
468 force_editor=opts.get('force_editor'))
469 except ValueError, inst:
470 raise util.Abort(str(inst))
471
472 def docopy(ui, repo, pats, opts):
473 # called with the repo lock held
474 #
475 # hgsep => pathname that uses "/" to separate directories
476 # ossep => pathname that uses os.sep to separate directories
477 cwd = repo.getcwd()
478 errors = 0
479 copied = []
480 targets = {}
481
482 # abs: hgsep
483 # rel: ossep
484 # return: hgsep
485 def okaytocopy(abs, rel, exact):
486 reasons = {'?': _('is not managed'),
487 'r': _('has been marked for remove')}
488 state = repo.dirstate[abs]
489 reason = reasons.get(state)
490 if reason:
491 if exact:
492 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
493 else:
494 if state == 'a':
495 origsrc = repo.dirstate.copied(abs)
496 if origsrc is not None:
497 return origsrc
498 return abs
499
500 # origsrc: hgsep
501 # abssrc: hgsep
502 # relsrc: ossep
503 # otarget: ossep
504 def copy(origsrc, abssrc, relsrc, otarget, exact):
505 abstarget = util.canonpath(repo.root, cwd, otarget)
506 reltarget = repo.pathto(abstarget, cwd)
507 prevsrc = targets.get(abstarget)
508 src = repo.wjoin(abssrc)
509 target = repo.wjoin(abstarget)
510 if prevsrc is not None:
511 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
512 (reltarget, repo.pathto(abssrc, cwd),
513 repo.pathto(prevsrc, cwd)))
514 return
515 if (not opts['after'] and os.path.exists(target) or
516 opts['after'] and repo.dirstate[abstarget] in 'mn'):
517 if not opts['force']:
518 ui.warn(_('%s: not overwriting - file exists\n') %
519 reltarget)
520 return
521 if not opts['after'] and not opts.get('dry_run'):
522 os.unlink(target)
523 if opts['after']:
524 if not os.path.exists(target):
525 return
526 else:
527 targetdir = os.path.dirname(target) or '.'
528 if not os.path.isdir(targetdir) and not opts.get('dry_run'):
529 os.makedirs(targetdir)
530 try:
531 restore = repo.dirstate[abstarget] == 'r'
532 if restore and not opts.get('dry_run'):
533 repo.undelete([abstarget])
534 try:
535 if not opts.get('dry_run'):
536 util.copyfile(src, target)
537 restore = False
538 finally:
539 if restore:
540 repo.remove([abstarget])
541 except IOError, inst:
542 if inst.errno == errno.ENOENT:
543 ui.warn(_('%s: deleted in working copy\n') % relsrc)
544 else:
545 ui.warn(_('%s: cannot copy - %s\n') %
546 (relsrc, inst.strerror))
547 errors += 1
548 return
549 if ui.verbose or not exact:
550 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
551 targets[abstarget] = abssrc
552 if abstarget != origsrc:
553 if repo.dirstate[origsrc] == 'a':
554 if not ui.quiet:
555 ui.warn(_("%s has not been committed yet, so no copy "
556 "data will be stored for %s.\n")
557 % (repo.pathto(origsrc, cwd), reltarget))
558 if abstarget not in repo.dirstate and not opts.get('dry_run'):
559 repo.add([abstarget])
560 elif not opts.get('dry_run'):
561 repo.copy(origsrc, abstarget)
562 copied.append((abssrc, relsrc, exact))
563
564 # pat: ossep
565 # dest ossep
566 # srcs: list of (hgsep, hgsep, ossep, bool)
567 # return: function that takes hgsep and returns ossep
568 def targetpathfn(pat, dest, srcs):
569 if os.path.isdir(pat):
570 abspfx = util.canonpath(repo.root, cwd, pat)
571 abspfx = util.localpath(abspfx)
572 if destdirexists:
573 striplen = len(os.path.split(abspfx)[0])
574 else:
575 striplen = len(abspfx)
576 if striplen:
577 striplen += len(os.sep)
578 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
579 elif destdirexists:
580 res = lambda p: os.path.join(dest,
581 os.path.basename(util.localpath(p)))
582 else:
583 res = lambda p: dest
584 return res
585
586 # pat: ossep
587 # dest ossep
588 # srcs: list of (hgsep, hgsep, ossep, bool)
589 # return: function that takes hgsep and returns ossep
590 def targetpathafterfn(pat, dest, srcs):
591 if util.patkind(pat, None)[0]:
592 # a mercurial pattern
593 res = lambda p: os.path.join(dest,
594 os.path.basename(util.localpath(p)))
595 else:
596 abspfx = util.canonpath(repo.root, cwd, pat)
597 if len(abspfx) < len(srcs[0][0]):
598 # A directory. Either the target path contains the last
599 # component of the source path or it does not.
600 def evalpath(striplen):
601 score = 0
602 for s in srcs:
603 t = os.path.join(dest, util.localpath(s[0])[striplen:])
604 if os.path.exists(t):
605 score += 1
606 return score
607
608 abspfx = util.localpath(abspfx)
609 striplen = len(abspfx)
610 if striplen:
611 striplen += len(os.sep)
612 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
613 score = evalpath(striplen)
614 striplen1 = len(os.path.split(abspfx)[0])
615 if striplen1:
616 striplen1 += len(os.sep)
617 if evalpath(striplen1) > score:
618 striplen = striplen1
619 res = lambda p: os.path.join(dest,
620 util.localpath(p)[striplen:])
621 else:
622 # a file
623 if destdirexists:
624 res = lambda p: os.path.join(dest,
625 os.path.basename(util.localpath(p)))
626 else:
627 res = lambda p: dest
628 return res
629
630
631 pats = util.expand_glob(pats)
632 if not pats:
633 raise util.Abort(_('no source or destination specified'))
634 if len(pats) == 1:
635 raise util.Abort(_('no destination specified'))
636 dest = pats.pop()
637 destdirexists = os.path.isdir(dest)
638 if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
639 raise util.Abort(_('with multiple sources, destination must be an '
640 'existing directory'))
641 if opts['after']:
642 tfn = targetpathafterfn
643 else:
644 tfn = targetpathfn
645 copylist = []
646 for pat in pats:
647 srcs = []
648 for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts,
649 globbed=True):
650 origsrc = okaytocopy(abssrc, relsrc, exact)
651 if origsrc:
652 srcs.append((origsrc, abssrc, relsrc, exact))
653 if not srcs:
654 continue
655 copylist.append((tfn(pat, dest, srcs), srcs))
656 if not copylist:
657 raise util.Abort(_('no files to copy'))
658
659 for targetpath, srcs in copylist:
660 for origsrc, abssrc, relsrc, exact in srcs:
661 copy(origsrc, abssrc, relsrc, targetpath(abssrc), exact)
662
663 if errors:
664 ui.warn(_('(consider using --after)\n'))
665 return errors, copied
666 533
667 def copy(ui, repo, *pats, **opts): 534 def copy(ui, repo, *pats, **opts):
668 """mark files as copied for the next commit 535 """mark files as copied for the next commit
669 536
670 Mark dest as having copies of source files. If dest is a 537 Mark dest as having copies of source files. If dest is a
678 This command takes effect in the next commit. To undo a copy 545 This command takes effect in the next commit. To undo a copy
679 before that, see hg revert. 546 before that, see hg revert.
680 """ 547 """
681 wlock = repo.wlock(False) 548 wlock = repo.wlock(False)
682 try: 549 try:
683 errs, copied = docopy(ui, repo, pats, opts) 550 return cmdutil.copy(ui, repo, pats, opts)
684 finally: 551 finally:
685 del wlock 552 del wlock
686 return errs
687 553
688 def debugancestor(ui, index, rev1, rev2): 554 def debugancestor(ui, index, rev1, rev2):
689 """find the ancestor revision of two revisions in a given index""" 555 """find the ancestor revision of two revisions in a given index"""
690 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index) 556 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
691 a = r.ancestor(r.lookup(rev1), r.lookup(rev2)) 557 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
696 562
697 if opts['options']: 563 if opts['options']:
698 options = [] 564 options = []
699 otables = [globalopts] 565 otables = [globalopts]
700 if cmd: 566 if cmd:
701 aliases, entry = cmdutil.findcmd(ui, cmd) 567 aliases, entry = cmdutil.findcmd(ui, cmd, table)
702 otables.append(entry[1]) 568 otables.append(entry[1])
703 for t in otables: 569 for t in otables:
704 for o in t: 570 for o in t:
705 if o[0]: 571 if o[0]:
706 options.append('-%s' % o[0]) 572 options.append('-%s' % o[0])
707 options.append('--%s' % o[1]) 573 options.append('--%s' % o[1])
708 ui.write("%s\n" % "\n".join(options)) 574 ui.write("%s\n" % "\n".join(options))
709 return 575 return
710 576
711 clist = cmdutil.findpossible(ui, cmd).keys() 577 clist = cmdutil.findpossible(ui, cmd, table).keys()
712 clist.sort() 578 clist.sort()
713 ui.write("%s\n" % "\n".join(clist)) 579 ui.write("%s\n" % "\n".join(clist))
580
581 def debugfsinfo(ui, path = "."):
582 file('.debugfsinfo', 'w').write('')
583 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
584 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
585 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
586 and 'yes' or 'no'))
587 os.unlink('.debugfsinfo')
714 588
715 def debugrebuildstate(ui, repo, rev=""): 589 def debugrebuildstate(ui, repo, rev=""):
716 """rebuild the dirstate as it would look like for the given revision""" 590 """rebuild the dirstate as it would look like for the given revision"""
717 if rev == "": 591 if rev == "":
718 rev = repo.changelog.tip() 592 rev = repo.changelog.tip()
793 finally: 667 finally:
794 del wlock 668 del wlock
795 669
796 def debugstate(ui, repo): 670 def debugstate(ui, repo):
797 """show the contents of the current dirstate""" 671 """show the contents of the current dirstate"""
798 dc = repo.dirstate._map 672 k = repo.dirstate._map.items()
799 k = dc.keys()
800 k.sort() 673 k.sort()
801 for file_ in k: 674 for file_, ent in k:
802 if dc[file_][3] == -1: 675 if ent[3] == -1:
803 # Pad or slice to locale representation 676 # Pad or slice to locale representation
804 locale_len = len(time.strftime("%x %X", time.localtime(0))) 677 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
805 timestr = 'unset' 678 timestr = 'unset'
806 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr)) 679 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
807 else: 680 else:
808 timestr = time.strftime("%x %X", time.localtime(dc[file_][3])) 681 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
809 ui.write("%c %3o %10d %s %s\n" 682 if ent[1] & 020000:
810 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2], 683 mode = 'lnk'
811 timestr, file_)) 684 else:
685 mode = '%3o' % (ent[1] & 0777)
686 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
812 for f in repo.dirstate.copies(): 687 for f in repo.dirstate.copies():
813 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f)) 688 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
814 689
815 def debugdata(ui, file_, rev): 690 def debugdata(ui, file_, rev):
816 """dump the contents of a data file revision""" 691 """dump the contents of a data file revision"""
837 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_) 712 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
838 ui.write(" rev offset length base linkrev" + 713 ui.write(" rev offset length base linkrev" +
839 " nodeid p1 p2\n") 714 " nodeid p1 p2\n")
840 for i in xrange(r.count()): 715 for i in xrange(r.count()):
841 node = r.node(i) 716 node = r.node(i)
842 pp = r.parents(node) 717 try:
718 pp = r.parents(node)
719 except:
720 pp = [nullid, nullid]
843 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % ( 721 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
844 i, r.start(i), r.length(i), r.base(i), r.linkrev(node), 722 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
845 short(node), short(pp[0]), short(pp[1]))) 723 short(node), short(pp[0]), short(pp[1])))
846 724
847 def debugindexdot(ui, file_): 725 def debugindexdot(ui, file_):
897 ui.write(_(" (templates seem to have been installed incorrectly)\n")) 775 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
898 problems += 1 776 problems += 1
899 777
900 # patch 778 # patch
901 ui.status(_("Checking patch...\n")) 779 ui.status(_("Checking patch...\n"))
902 patcher = ui.config('ui', 'patch') 780 patchproblems = 0
903 patcher = ((patcher and util.find_exe(patcher)) or 781 a = "1\n2\n3\n4\n"
904 util.find_exe('gpatch') or 782 b = "1\n2\n3\ninsert\n4\n"
905 util.find_exe('patch')) 783 fa = writetemp(a)
906 if not patcher: 784 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
907 ui.write(_(" Can't find patch or gpatch in PATH\n")) 785 os.path.basename(fa))
908 ui.write(_(" (specify a patch utility in your .hgrc file)\n")) 786 fd = writetemp(d)
909 problems += 1 787
788 files = {}
789 try:
790 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
791 except util.Abort, e:
792 ui.write(_(" patch call failed:\n"))
793 ui.write(" " + str(e) + "\n")
794 patchproblems += 1
910 else: 795 else:
911 # actually attempt a patch here 796 if list(files) != [os.path.basename(fa)]:
912 a = "1\n2\n3\n4\n" 797 ui.write(_(" unexpected patch output!\n"))
913 b = "1\n2\n3\ninsert\n4\n" 798 patchproblems += 1
914 fa = writetemp(a) 799 a = file(fa).read()
915 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa)) 800 if a != b:
916 fd = writetemp(d) 801 ui.write(_(" patch test failed!\n"))
917 802 patchproblems += 1
918 files = {} 803
919 try: 804 if patchproblems:
920 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files) 805 if ui.config('ui', 'patch'):
921 except util.Abort, e: 806 ui.write(_(" (Current patch tool may be incompatible with patch,"
922 ui.write(_(" patch call failed:\n")) 807 " or misconfigured. Please check your .hgrc file)\n"))
923 ui.write(" " + str(e) + "\n")
924 problems += 1
925 else: 808 else:
926 if list(files) != [os.path.basename(fa)]: 809 ui.write(_(" Internal patcher failure, please report this error"
927 ui.write(_(" unexpected patch output!")) 810 " to http://www.selenic.com/mercurial/bts\n"))
928 ui.write(_(" (you may have an incompatible version of patch)\n")) 811 problems += patchproblems
929 problems += 1 812
930 a = file(fa).read() 813 os.unlink(fa)
931 if a != b: 814 os.unlink(fd)
932 ui.write(_(" patch test failed!"))
933 ui.write(_(" (you may have an incompatible version of patch)\n"))
934 problems += 1
935
936 os.unlink(fa)
937 os.unlink(fd)
938
939 # merge helper
940 ui.status(_("Checking merge helper...\n"))
941 cmd = (os.environ.get("HGMERGE") or ui.config("ui", "merge")
942 or "hgmerge")
943 cmdpath = util.find_exe(cmd) or util.find_exe(cmd.split()[0])
944 if not cmdpath:
945 if cmd == 'hgmerge':
946 ui.write(_(" No merge helper set and can't find default"
947 " hgmerge script in PATH\n"))
948 ui.write(_(" (specify a merge helper in your .hgrc file)\n"))
949 else:
950 ui.write(_(" Can't find merge helper '%s' in PATH\n") % cmd)
951 ui.write(_(" (specify a merge helper in your .hgrc file)\n"))
952 problems += 1
953 else:
954 # actually attempt a patch here
955 fa = writetemp("1\n2\n3\n4\n")
956 fl = writetemp("1\n2\n3\ninsert\n4\n")
957 fr = writetemp("begin\n1\n2\n3\n4\n")
958 r = util.system('%s "%s" "%s" "%s"' % (cmd, fl, fa, fr))
959 if r:
960 ui.write(_(" Got unexpected merge error %d!\n") % r)
961 problems += 1
962 m = file(fl).read()
963 if m != "begin\n1\n2\n3\ninsert\n4\n":
964 ui.write(_(" Got unexpected merge results!\n"))
965 ui.write(_(" (your merge helper may have the"
966 " wrong argument order)\n"))
967 ui.write(_(" Result: %r\n") % m)
968 problems += 1
969 os.unlink(fa)
970 os.unlink(fl)
971 os.unlink(fr)
972 815
973 # editor 816 # editor
974 ui.status(_("Checking commit editor...\n")) 817 ui.status(_("Checking commit editor...\n"))
975 editor = (os.environ.get("HGEDITOR") or 818 editor = ui.geteditor()
976 ui.config("ui", "editor") or
977 os.environ.get("EDITOR", "vi"))
978 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0]) 819 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
979 if not cmdpath: 820 if not cmdpath:
980 if editor == 'vi': 821 if editor == 'vi':
981 ui.write(_(" No commit editor set and can't find vi in PATH\n")) 822 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
982 ui.write(_(" (specify a commit editor in your .hgrc file)\n")) 823 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1009 """dump rename information""" 850 """dump rename information"""
1010 851
1011 ctx = repo.changectx(opts.get('rev', 'tip')) 852 ctx = repo.changectx(opts.get('rev', 'tip'))
1012 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, 853 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
1013 ctx.node()): 854 ctx.node()):
1014 m = ctx.filectx(abs).renamed() 855 fctx = ctx.filectx(abs)
856 m = fctx.filelog().renamed(fctx.filenode())
1015 if m: 857 if m:
1016 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1]))) 858 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
1017 else: 859 else:
1018 ui.write(_("%s not renamed\n") % rel) 860 ui.write(_("%s not renamed\n") % rel)
1019 861
1221 mf = repo.changectx(rev).manifest() 1063 mf = repo.changectx(rev).manifest()
1222 matches[rev] = {} 1064 matches[rev] = {}
1223 for fn in fns: 1065 for fn in fns:
1224 if fn in skip: 1066 if fn in skip:
1225 continue 1067 continue
1226 fstate.setdefault(fn, {})
1227 try: 1068 try:
1228 grepbody(fn, rev, getfile(fn).read(mf[fn])) 1069 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1070 fstate.setdefault(fn, [])
1229 if follow: 1071 if follow:
1230 copied = getfile(fn).renamed(mf[fn]) 1072 copied = getfile(fn).renamed(mf[fn])
1231 if copied: 1073 if copied:
1232 copies.setdefault(rev, {})[fn] = copied[0] 1074 copies.setdefault(rev, {})[fn] = copied[0]
1233 except KeyError: 1075 except KeyError:
1340 1182
1341 def helpcmd(name): 1183 def helpcmd(name):
1342 if with_version: 1184 if with_version:
1343 version_(ui) 1185 version_(ui)
1344 ui.write('\n') 1186 ui.write('\n')
1345 aliases, i = cmdutil.findcmd(ui, name) 1187 aliases, i = cmdutil.findcmd(ui, name, table)
1346 # synopsis 1188 # synopsis
1347 ui.write("%s\n\n" % i[2]) 1189 ui.write("%s\n" % i[2])
1190
1191 # aliases
1192 if not ui.quiet and len(aliases) > 1:
1193 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1348 1194
1349 # description 1195 # description
1350 doc = i[0].__doc__ 1196 doc = i[0].__doc__
1351 if not doc: 1197 if not doc:
1352 doc = _("(No help text available)") 1198 doc = _("(No help text available)")
1353 if ui.quiet: 1199 if ui.quiet:
1354 doc = doc.splitlines(0)[0] 1200 doc = doc.splitlines(0)[0]
1355 ui.write("%s\n" % doc.rstrip()) 1201 ui.write("\n%s\n" % doc.rstrip())
1356 1202
1357 if not ui.quiet: 1203 if not ui.quiet:
1358 # aliases
1359 if len(aliases) > 1:
1360 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1361
1362 # options 1204 # options
1363 if i[1]: 1205 if i[1]:
1364 option_lists.append((_("options:\n"), i[1])) 1206 option_lists.append((_("options:\n"), i[1]))
1365 1207
1366 addglobalopts(False) 1208 addglobalopts(False)
1503 hash identifiers, followed by a "+" if there are uncommitted changes 1345 hash identifiers, followed by a "+" if there are uncommitted changes
1504 in the working directory, a list of tags for this revision and a branch 1346 in the working directory, a list of tags for this revision and a branch
1505 name for non-default branches. 1347 name for non-default branches.
1506 """ 1348 """
1507 1349
1350 if not repo and not source:
1351 raise util.Abort(_("There is no Mercurial repository here "
1352 "(.hg not found)"))
1353
1508 hexfunc = ui.debugflag and hex or short 1354 hexfunc = ui.debugflag and hex or short
1509 default = not (num or id or branch or tags) 1355 default = not (num or id or branch or tags)
1510 output = [] 1356 output = []
1511 1357
1512 if source: 1358 if source:
1513 source, revs = cmdutil.parseurl(ui.expandpath(source), []) 1359 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1514 srepo = hg.repository(ui, source) 1360 srepo = hg.repository(ui, source)
1515 if not rev and revs: 1361 if not rev and revs:
1516 rev = revs[0] 1362 rev = revs[0]
1517 if not rev: 1363 if not rev:
1518 rev = "tip" 1364 rev = "tip"
1601 if pf == '-': 1447 if pf == '-':
1602 ui.status(_("applying patch from stdin\n")) 1448 ui.status(_("applying patch from stdin\n"))
1603 data = patch.extract(ui, sys.stdin) 1449 data = patch.extract(ui, sys.stdin)
1604 else: 1450 else:
1605 ui.status(_("applying %s\n") % p) 1451 ui.status(_("applying %s\n") % p)
1606 data = patch.extract(ui, file(pf, 'rb')) 1452 if os.path.exists(pf):
1607 1453 data = patch.extract(ui, file(pf, 'rb'))
1454 else:
1455 data = patch.extract(ui, urllib.urlopen(pf))
1608 tmpname, message, user, date, branch, nodeid, p1, p2 = data 1456 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1609 1457
1610 if tmpname is None: 1458 if tmpname is None:
1611 raise util.Abort(_('no diffs found')) 1459 raise util.Abort(_('no diffs found'))
1612 1460
1648 try: 1496 try:
1649 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root, 1497 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1650 files=files) 1498 files=files)
1651 finally: 1499 finally:
1652 files = patch.updatedir(ui, repo, files) 1500 files = patch.updatedir(ui, repo, files)
1653 n = repo.commit(files, message, user, date) 1501 if not opts.get('no_commit'):
1654 if opts.get('exact'): 1502 n = repo.commit(files, message, opts.get('user') or user,
1655 if hex(n) != nodeid: 1503 opts.get('date') or date)
1656 repo.rollback() 1504 if opts.get('exact'):
1657 raise util.Abort(_('patch is damaged' + 1505 if hex(n) != nodeid:
1658 ' or loses information')) 1506 repo.rollback()
1507 raise util.Abort(_('patch is damaged'
1508 ' or loses information'))
1509 # Force a dirstate write so that the next transaction
1510 # backups an up-do-date file.
1511 repo.dirstate.write()
1659 finally: 1512 finally:
1660 os.unlink(tmpname) 1513 os.unlink(tmpname)
1661 finally: 1514 finally:
1662 del wlock, lock 1515 del lock, wlock
1663 1516
1664 def incoming(ui, repo, source="default", **opts): 1517 def incoming(ui, repo, source="default", **opts):
1665 """show new changesets found in source 1518 """show new changesets found in source
1666 1519
1667 Show new changesets found in the specified path/URL or the default 1520 Show new changesets found in the specified path/URL or the default
1671 For remote repository, using --bundle avoids downloading the changesets 1524 For remote repository, using --bundle avoids downloading the changesets
1672 twice if the incoming is followed by a pull. 1525 twice if the incoming is followed by a pull.
1673 1526
1674 See pull for valid source format details. 1527 See pull for valid source format details.
1675 """ 1528 """
1676 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev']) 1529 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1677 cmdutil.setremoteconfig(ui, opts) 1530 cmdutil.setremoteconfig(ui, opts)
1678 1531
1679 other = hg.repository(ui, source) 1532 other = hg.repository(ui, source)
1680 ui.status(_('comparing with %s\n') % source) 1533 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1681 if revs: 1534 if revs:
1682 if 'lookup' in other.capabilities: 1535 revs = [other.lookup(rev) for rev in revs]
1683 revs = [other.lookup(rev) for rev in revs]
1684 else:
1685 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1686 raise util.Abort(error)
1687 incoming = repo.findincoming(other, heads=revs, force=opts["force"]) 1536 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1688 if not incoming: 1537 if not incoming:
1689 try: 1538 try:
1690 os.unlink(opts["bundle"]) 1539 os.unlink(opts["bundle"])
1691 except: 1540 except:
1699 if fname or not other.local(): 1548 if fname or not other.local():
1700 # create a bundle (uncompressed if other repo is not local) 1549 # create a bundle (uncompressed if other repo is not local)
1701 if revs is None: 1550 if revs is None:
1702 cg = other.changegroup(incoming, "incoming") 1551 cg = other.changegroup(incoming, "incoming")
1703 else: 1552 else:
1704 if 'changegroupsubset' not in other.capabilities:
1705 raise util.Abort(_("Partial incoming cannot be done because other repository doesn't support changegroupsubset."))
1706 cg = other.changegroupsubset(incoming, revs, 'incoming') 1553 cg = other.changegroupsubset(incoming, revs, 'incoming')
1707 bundletype = other.local() and "HG10BZ" or "HG10UN" 1554 bundletype = other.local() and "HG10BZ" or "HG10UN"
1708 fname = cleanup = changegroup.writebundle(cg, fname, bundletype) 1555 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1709 # keep written bundle? 1556 # keep written bundle?
1710 if opts["bundle"]: 1557 if opts["bundle"]:
1829 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1 1676 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1830 else: 1677 else:
1831 endrev = repo.changelog.count() 1678 endrev = repo.changelog.count()
1832 rcache = {} 1679 rcache = {}
1833 ncache = {} 1680 ncache = {}
1834 dcache = [] 1681 def getrenamed(fn, rev):
1835 def getrenamed(fn, rev, man):
1836 '''looks up all renames for a file (up to endrev) the first 1682 '''looks up all renames for a file (up to endrev) the first
1837 time the file is given. It indexes on the changerev and only 1683 time the file is given. It indexes on the changerev and only
1838 parses the manifest if linkrev != changerev. 1684 parses the manifest if linkrev != changerev.
1839 Returns rename info for fn at changerev rev.''' 1685 Returns rename info for fn at changerev rev.'''
1840 if fn not in rcache: 1686 if fn not in rcache:
1850 ncache[fn][node] = renamed 1696 ncache[fn][node] = renamed
1851 if lr >= endrev: 1697 if lr >= endrev:
1852 break 1698 break
1853 if rev in rcache[fn]: 1699 if rev in rcache[fn]:
1854 return rcache[fn][rev] 1700 return rcache[fn][rev]
1855 mr = repo.manifest.rev(man) 1701
1856 if repo.manifest.parentrevs(mr) != (mr - 1, nullrev): 1702 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1857 return ncache[fn].get(repo.manifest.find(man, fn)[0]) 1703 # filectx logic.
1858 if not dcache or dcache[0] != man: 1704
1859 dcache[:] = [man, repo.manifest.readdelta(man)] 1705 try:
1860 if fn in dcache[1]: 1706 return repo.changectx(rev).filectx(fn).renamed()
1861 return ncache[fn].get(dcache[1][fn]) 1707 except revlog.LookupError:
1708 pass
1862 return None 1709 return None
1863 1710
1864 df = False 1711 df = False
1865 if opts["date"]: 1712 if opts["date"]:
1866 df = util.matchdate(opts["date"]) 1713 df = util.matchdate(opts["date"])
1893 if miss: 1740 if miss:
1894 continue 1741 continue
1895 1742
1896 copies = [] 1743 copies = []
1897 if opts.get('copies') and rev: 1744 if opts.get('copies') and rev:
1898 mf = get(rev)[0]
1899 for fn in get(rev)[3]: 1745 for fn in get(rev)[3]:
1900 rename = getrenamed(fn, rev, mf) 1746 rename = getrenamed(fn, rev)
1901 if rename: 1747 if rename:
1902 copies.append((fn, rename[0])) 1748 copies.append((fn, rename[0]))
1903 displayer.show(rev, changenode, copies=copies) 1749 displayer.show(rev, changenode, copies=copies)
1904 elif st == 'iter': 1750 elif st == 'iter':
1905 if count == limit: break 1751 if count == limit: break
1906 if displayer.flush(rev): 1752 if displayer.flush(rev):
1907 count += 1 1753 count += 1
1908 1754
1909 def manifest(ui, repo, rev=None): 1755 def manifest(ui, repo, node=None, rev=None):
1910 """output the current or given revision of the project manifest 1756 """output the current or given revision of the project manifest
1911 1757
1912 Print a list of version controlled files for the given revision. 1758 Print a list of version controlled files for the given revision.
1913 If no revision is given, the parent of the working directory is used, 1759 If no revision is given, the parent of the working directory is used,
1914 or tip if no revision is checked out. 1760 or tip if no revision is checked out.
1915 1761
1916 The manifest is the list of files being version controlled. If no revision 1762 The manifest is the list of files being version controlled. If no revision
1917 is given then the first parent of the working directory is used. 1763 is given then the first parent of the working directory is used.
1918 1764
1919 With -v flag, print file permissions. With --debug flag, print 1765 With -v flag, print file permissions, symlink and executable bits. With
1920 file revision hashes. 1766 --debug flag, print file revision hashes.
1921 """ 1767 """
1922 1768
1923 m = repo.changectx(rev).manifest() 1769 if rev and node:
1770 raise util.Abort(_("please specify just one revision"))
1771
1772 if not node:
1773 node = rev
1774
1775 m = repo.changectx(node).manifest()
1924 files = m.keys() 1776 files = m.keys()
1925 files.sort() 1777 files.sort()
1926 1778
1927 for f in files: 1779 for f in files:
1928 if ui.debugflag: 1780 if ui.debugflag:
1929 ui.write("%40s " % hex(m[f])) 1781 ui.write("%40s " % hex(m[f]))
1930 if ui.verbose: 1782 if ui.verbose:
1931 ui.write("%3s " % (m.execf(f) and "755" or "644")) 1783 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1784 perm = m.execf(f) and "755" or "644"
1785 ui.write("%3s %1s " % (perm, type))
1932 ui.write("%s\n" % f) 1786 ui.write("%s\n" % f)
1933 1787
1934 def merge(ui, repo, node=None, force=None, rev=None): 1788 def merge(ui, repo, node=None, force=None, rev=None):
1935 """merge working directory with another revision 1789 """merge working directory with another revision
1936 1790
1945 revision to merge with must be provided. 1799 revision to merge with must be provided.
1946 """ 1800 """
1947 1801
1948 if rev and node: 1802 if rev and node:
1949 raise util.Abort(_("please specify just one revision")) 1803 raise util.Abort(_("please specify just one revision"))
1950
1951 if not node: 1804 if not node:
1952 node = rev 1805 node = rev
1953 1806
1954 if not node: 1807 if not node:
1955 heads = repo.heads() 1808 heads = repo.heads()
1956 if len(heads) > 2: 1809 if len(heads) > 2:
1957 raise util.Abort(_('repo has %d heads - ' 1810 raise util.Abort(_('repo has %d heads - '
1958 'please merge with an explicit rev') % 1811 'please merge with an explicit rev') %
1959 len(heads)) 1812 len(heads))
1813 parent = repo.dirstate.parents()[0]
1960 if len(heads) == 1: 1814 if len(heads) == 1:
1961 raise util.Abort(_('there is nothing to merge - ' 1815 msg = _('there is nothing to merge')
1962 'use "hg update" instead')) 1816 if parent != repo.lookup(repo.workingctx().branch()):
1963 parent = repo.dirstate.parents()[0] 1817 msg = _('%s - use "hg update" instead') % msg
1818 raise util.Abort(msg)
1819
1964 if parent not in heads: 1820 if parent not in heads:
1965 raise util.Abort(_('working dir not at a head rev - ' 1821 raise util.Abort(_('working dir not at a head rev - '
1966 'use "hg update" or merge with an explicit rev')) 1822 'use "hg update" or merge with an explicit rev'))
1967 node = parent == heads[0] and heads[-1] or heads[0] 1823 node = parent == heads[0] and heads[-1] or heads[0]
1968 return hg.merge(repo, node, force=force) 1824 return hg.merge(repo, node, force=force)
1974 the default push location. These are the changesets that would be pushed 1830 the default push location. These are the changesets that would be pushed
1975 if a push was requested. 1831 if a push was requested.
1976 1832
1977 See pull for valid destination format details. 1833 See pull for valid destination format details.
1978 """ 1834 """
1979 dest, revs = cmdutil.parseurl( 1835 dest, revs, checkout = hg.parseurl(
1980 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) 1836 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1981 cmdutil.setremoteconfig(ui, opts) 1837 cmdutil.setremoteconfig(ui, opts)
1982 if revs: 1838 if revs:
1983 revs = [repo.lookup(rev) for rev in revs] 1839 revs = [repo.lookup(rev) for rev in revs]
1984 1840
1985 other = hg.repository(ui, dest) 1841 other = hg.repository(ui, dest)
1986 ui.status(_('comparing with %s\n') % dest) 1842 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1987 o = repo.findoutgoing(other, force=opts['force']) 1843 o = repo.findoutgoing(other, force=opts['force'])
1988 if not o: 1844 if not o:
1989 ui.status(_("no changes found\n")) 1845 ui.status(_("no changes found\n"))
1990 return 1 1846 return 1
1991 o = repo.changelog.nodesbetween(o, revs)[0] 1847 o = repo.changelog.nodesbetween(o, revs)[0]
2006 will be printed. If a file argument is given, revision in 1862 will be printed. If a file argument is given, revision in
2007 which the file was last changed (before the working directory 1863 which the file was last changed (before the working directory
2008 revision or the argument to --rev if given) is printed. 1864 revision or the argument to --rev if given) is printed.
2009 """ 1865 """
2010 rev = opts.get('rev') 1866 rev = opts.get('rev')
1867 if rev:
1868 ctx = repo.changectx(rev)
1869 else:
1870 ctx = repo.workingctx()
1871
2011 if file_: 1872 if file_:
2012 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts) 1873 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
2013 if anypats or len(files) != 1: 1874 if anypats or len(files) != 1:
2014 raise util.Abort(_('can only specify an explicit file name')) 1875 raise util.Abort(_('can only specify an explicit file name'))
2015 ctx = repo.filectx(files[0], changeid=rev) 1876 file_ = files[0]
2016 elif rev: 1877 filenodes = []
2017 ctx = repo.changectx(rev) 1878 for cp in ctx.parents():
1879 if not cp:
1880 continue
1881 try:
1882 filenodes.append(cp.filenode(file_))
1883 except revlog.LookupError:
1884 pass
1885 if not filenodes:
1886 raise util.Abort(_("'%s' not found in manifest!") % file_)
1887 fl = repo.file(file_)
1888 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
2018 else: 1889 else:
2019 ctx = repo.workingctx() 1890 p = [cp.node() for cp in ctx.parents()]
2020 p = [cp.node() for cp in ctx.parents()]
2021 1891
2022 displayer = cmdutil.show_changeset(ui, repo, opts) 1892 displayer = cmdutil.show_changeset(ui, repo, opts)
2023 for n in p: 1893 for n in p:
2024 if n != nullid: 1894 if n != nullid:
2025 displayer.show(changenode=n) 1895 displayer.show(changenode=n)
2042 return 1 1912 return 1
2043 else: 1913 else:
2044 for name, path in ui.configitems("paths"): 1914 for name, path in ui.configitems("paths"):
2045 ui.write("%s = %s\n" % (name, path)) 1915 ui.write("%s = %s\n" % (name, path))
2046 1916
2047 def postincoming(ui, repo, modheads, optupdate): 1917 def postincoming(ui, repo, modheads, optupdate, checkout):
2048 if modheads == 0: 1918 if modheads == 0:
2049 return 1919 return
2050 if optupdate: 1920 if optupdate:
2051 if modheads == 1: 1921 if modheads <= 1 or checkout:
2052 return hg.update(repo, None) 1922 return hg.update(repo, checkout)
2053 else: 1923 else:
2054 ui.status(_("not updating, since new heads added\n")) 1924 ui.status(_("not updating, since new heads added\n"))
2055 if modheads > 1: 1925 if modheads > 1:
2056 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n")) 1926 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2057 else: 1927 else:
2096 Host * 1966 Host *
2097 Compression yes 1967 Compression yes
2098 Alternatively specify "ssh -C" as your ssh command in your hgrc or 1968 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2099 with the --ssh command line option. 1969 with the --ssh command line option.
2100 """ 1970 """
2101 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev']) 1971 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
2102 cmdutil.setremoteconfig(ui, opts) 1972 cmdutil.setremoteconfig(ui, opts)
2103 1973
2104 other = hg.repository(ui, source) 1974 other = hg.repository(ui, source)
2105 ui.status(_('pulling from %s\n') % (source)) 1975 ui.status(_('pulling from %s\n') % util.hidepassword(source))
2106 if revs: 1976 if revs:
2107 if 'lookup' in other.capabilities: 1977 try:
2108 revs = [other.lookup(rev) for rev in revs] 1978 revs = [other.lookup(rev) for rev in revs]
2109 else: 1979 except repo.NoCapability:
2110 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.") 1980 error = _("Other repository doesn't support revision lookup, "
1981 "so a rev cannot be specified.")
2111 raise util.Abort(error) 1982 raise util.Abort(error)
2112 1983
2113 modheads = repo.pull(other, heads=revs, force=opts['force']) 1984 modheads = repo.pull(other, heads=revs, force=opts['force'])
2114 return postincoming(ui, repo, modheads, opts['update']) 1985 return postincoming(ui, repo, modheads, opts['update'], checkout)
2115 1986
2116 def push(ui, repo, dest=None, **opts): 1987 def push(ui, repo, dest=None, **opts):
2117 """push changes to the specified destination 1988 """push changes to the specified destination
2118 1989
2119 Push changes from the local repository to the given destination. 1990 Push changes from the local repository to the given destination.
2141 about ssh:// URLs. 2012 about ssh:// URLs.
2142 2013
2143 Pushing to http:// and https:// URLs is only possible, if this 2014 Pushing to http:// and https:// URLs is only possible, if this
2144 feature is explicitly enabled on the remote Mercurial server. 2015 feature is explicitly enabled on the remote Mercurial server.
2145 """ 2016 """
2146 dest, revs = cmdutil.parseurl( 2017 dest, revs, checkout = hg.parseurl(
2147 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) 2018 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2148 cmdutil.setremoteconfig(ui, opts) 2019 cmdutil.setremoteconfig(ui, opts)
2149 2020
2150 other = hg.repository(ui, dest) 2021 other = hg.repository(ui, dest)
2151 ui.status('pushing to %s\n' % (dest)) 2022 ui.status('pushing to %s\n' % util.hidepassword(dest))
2152 if revs: 2023 if revs:
2153 revs = [repo.lookup(rev) for rev in revs] 2024 revs = [repo.lookup(rev) for rev in revs]
2154 r = repo.push(other, opts['force'], revs=revs) 2025 r = repo.push(other, opts['force'], revs=revs)
2155 return r == 0 2026 return r == 0
2156 2027
2226 elif abs in added: 2097 elif abs in added:
2227 if opts['force']: 2098 if opts['force']:
2228 forget.append(abs) 2099 forget.append(abs)
2229 continue 2100 continue
2230 reason = _('has been marked for add (use -f to force removal)') 2101 reason = _('has been marked for add (use -f to force removal)')
2102 exact = 1 # force the message
2231 elif abs not in repo.dirstate: 2103 elif abs not in repo.dirstate:
2232 reason = _('is not managed') 2104 reason = _('is not managed')
2233 elif opts['after'] and not exact and abs not in deleted: 2105 elif opts['after'] and not exact and abs not in deleted:
2234 continue 2106 continue
2235 elif abs in removed: 2107 elif abs in removed:
2258 This command takes effect in the next commit. To undo a rename 2130 This command takes effect in the next commit. To undo a rename
2259 before that, see hg revert. 2131 before that, see hg revert.
2260 """ 2132 """
2261 wlock = repo.wlock(False) 2133 wlock = repo.wlock(False)
2262 try: 2134 try:
2263 errs, copied = docopy(ui, repo, pats, opts) 2135 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2264 names = []
2265 for abs, rel, exact in copied:
2266 if ui.verbose or not exact:
2267 ui.status(_('removing %s\n') % rel)
2268 names.append(abs)
2269 if not opts.get('dry_run'):
2270 repo.remove(names, True)
2271 return errs
2272 finally: 2136 finally:
2273 del wlock 2137 del wlock
2274 2138
2275 def revert(ui, repo, *pats, **opts): 2139 def revert(ui, repo, *pats, **opts):
2276 """revert files or dirs to their states as of some revision 2140 """restore individual files or dirs to an earlier state
2141
2142 (use update -r to check out earlier revisions, revert does not
2143 change the working dir parents)
2277 2144
2278 With no revision specified, revert the named files or directories 2145 With no revision specified, revert the named files or directories
2279 to the contents they had in the parent of the working directory. 2146 to the contents they had in the parent of the working directory.
2280 This restores the contents of the affected files to an unmodified 2147 This restores the contents of the affected files to an unmodified
2281 state and unschedules adds, removes, copies, and renames. If the 2148 state and unschedules adds, removes, copies, and renames. If the
2282 working directory has two parents, you must explicitly specify the 2149 working directory has two parents, you must explicitly specify the
2283 revision to revert to. 2150 revision to revert to.
2284 2151
2285 Modified files are saved with a .orig suffix before reverting.
2286 To disable these backups, use --no-backup.
2287
2288 Using the -r option, revert the given files or directories to their 2152 Using the -r option, revert the given files or directories to their
2289 contents as of a specific revision. This can be helpful to "roll 2153 contents as of a specific revision. This can be helpful to "roll
2290 back" some or all of a change that should not have been committed. 2154 back" some or all of an earlier change.
2291 2155
2292 Revert modifies the working directory. It does not commit any 2156 Revert modifies the working directory. It does not commit any
2293 changes, or change the parent of the working directory. If you 2157 changes, or change the parent of the working directory. If you
2294 revert to a revision other than the parent of the working 2158 revert to a revision other than the parent of the working
2295 directory, the reverted files will thus appear modified 2159 directory, the reverted files will thus appear modified
2299 mode of a file was changed, it is reset. 2163 mode of a file was changed, it is reset.
2300 2164
2301 If names are given, all files matching the names are reverted. 2165 If names are given, all files matching the names are reverted.
2302 2166
2303 If no arguments are given, no files are reverted. 2167 If no arguments are given, no files are reverted.
2168
2169 Modified files are saved with a .orig suffix before reverting.
2170 To disable these backups, use --no-backup.
2304 """ 2171 """
2305 2172
2306 if opts["date"]: 2173 if opts["date"]:
2307 if opts["rev"]: 2174 if opts["rev"]:
2308 raise util.Abort(_("you can't specify a revision and a date")) 2175 raise util.Abort(_("you can't specify a revision and a date"))
2358 names[abs] = (rel, exact) 2225 names[abs] = (rel, exact)
2359 target_only[abs] = True 2226 target_only[abs] = True
2360 2227
2361 changes = repo.status(match=names.has_key)[:5] 2228 changes = repo.status(match=names.has_key)[:5]
2362 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes) 2229 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2230
2231 # if f is a rename, also revert the source
2232 cwd = repo.getcwd()
2233 for f in added:
2234 src = repo.dirstate.copied(f)
2235 if src and src not in names and repo.dirstate[src] == 'r':
2236 removed[src] = None
2237 names[src] = (repo.pathto(src, cwd), True)
2363 2238
2364 revert = ([], _('reverting %s\n')) 2239 revert = ([], _('reverting %s\n'))
2365 add = ([], _('adding %s\n')) 2240 add = ([], _('adding %s\n'))
2366 remove = ([], _('removing %s\n')) 2241 remove = ([], _('removing %s\n'))
2367 forget = ([], _('forgetting %s\n')) 2242 forget = ([], _('forgetting %s\n'))
2441 return r 2316 return r
2442 finally: 2317 finally:
2443 del wlock 2318 del wlock
2444 2319
2445 def rollback(ui, repo): 2320 def rollback(ui, repo):
2446 """roll back the last transaction in this repository 2321 """roll back the last transaction
2447 2322
2448 Roll back the last transaction in this repository, restoring the 2323 This command should be used with care. There is only one level of
2449 project to its state prior to the transaction. 2324 rollback, and there is no way to undo a rollback. It will also
2325 restore the dirstate at the time of the last transaction, losing
2326 any dirstate changes since that time.
2450 2327
2451 Transactions are used to encapsulate the effects of all commands 2328 Transactions are used to encapsulate the effects of all commands
2452 that create new changesets or propagate existing changesets into a 2329 that create new changesets or propagate existing changesets into a
2453 repository. For example, the following commands are transactional, 2330 repository. For example, the following commands are transactional,
2454 and their effects can be rolled back: 2331 and their effects can be rolled back:
2456 commit 2333 commit
2457 import 2334 import
2458 pull 2335 pull
2459 push (with this repository as destination) 2336 push (with this repository as destination)
2460 unbundle 2337 unbundle
2461
2462 This command should be used with care. There is only one level of
2463 rollback, and there is no way to undo a rollback. It will also
2464 restore the dirstate at the time of the last transaction, which
2465 may lose subsequent dirstate changes.
2466 2338
2467 This command is not intended for use on public repositories. Once 2339 This command is not intended for use on public repositories. Once
2468 changes are visible for pull by other users, rolling a transaction 2340 changes are visible for pull by other users, rolling a transaction
2469 back locally is ineffective (someone else may already have pulled 2341 back locally is ineffective (someone else may already have pulled
2470 the changes). Furthermore, a race is possible with readers of the 2342 the changes). Furthermore, a race is possible with readers of the
2495 " (.hg not found)")) 2367 " (.hg not found)"))
2496 s = sshserver.sshserver(ui, repo) 2368 s = sshserver.sshserver(ui, repo)
2497 s.serve_forever() 2369 s.serve_forever()
2498 2370
2499 parentui = ui.parentui or ui 2371 parentui = ui.parentui or ui
2500 optlist = ("name templates style address port ipv6" 2372 optlist = ("name templates style address port prefix ipv6"
2501 " accesslog errorlog webdir_conf certificate") 2373 " accesslog errorlog webdir_conf certificate")
2502 for o in optlist.split(): 2374 for o in optlist.split():
2503 if opts[o]: 2375 if opts[o]:
2504 parentui.setconfig("web", o, str(opts[o])) 2376 parentui.setconfig("web", o, str(opts[o]))
2505 if repo.ui != parentui: 2377 if (repo is not None) and (repo.ui != parentui):
2506 repo.ui.setconfig("web", o, str(opts[o])) 2378 repo.ui.setconfig("web", o, str(opts[o]))
2507 2379
2508 if repo is None and not ui.config("web", "webdir_conf"): 2380 if repo is None and not ui.config("web", "webdir_conf"):
2509 raise hg.RepoError(_("There is no Mercurial repository here" 2381 raise hg.RepoError(_("There is no Mercurial repository here"
2510 " (.hg not found)")) 2382 " (.hg not found)"))
2517 except socket.error, inst: 2389 except socket.error, inst:
2518 raise util.Abort(_('cannot start server: ') + inst.args[1]) 2390 raise util.Abort(_('cannot start server: ') + inst.args[1])
2519 2391
2520 if not ui.verbose: return 2392 if not ui.verbose: return
2521 2393
2394 if self.httpd.prefix:
2395 prefix = self.httpd.prefix.strip('/') + '/'
2396 else:
2397 prefix = ''
2398
2522 if self.httpd.port != 80: 2399 if self.httpd.port != 80:
2523 ui.status(_('listening at http://%s:%d/\n') % 2400 ui.status(_('listening at http://%s:%d/%s\n') %
2524 (self.httpd.addr, self.httpd.port)) 2401 (self.httpd.addr, self.httpd.port, prefix))
2525 else: 2402 else:
2526 ui.status(_('listening at http://%s/\n') % self.httpd.addr) 2403 ui.status(_('listening at http://%s/%s\n') %
2404 (self.httpd.addr, prefix))
2527 2405
2528 def run(self): 2406 def run(self):
2529 self.httpd.serve_forever() 2407 self.httpd.serve_forever()
2530 2408
2531 service = service() 2409 service = service()
2534 2412
2535 def status(ui, repo, *pats, **opts): 2413 def status(ui, repo, *pats, **opts):
2536 """show changed files in the working directory 2414 """show changed files in the working directory
2537 2415
2538 Show status of files in the repository. If names are given, only 2416 Show status of files in the repository. If names are given, only
2539 files that match are shown. Files that are clean or ignored, are 2417 files that match are shown. Files that are clean or ignored or
2540 not listed unless -c (clean), -i (ignored) or -A is given. 2418 source of a copy/move operation, are not listed unless -c (clean),
2419 -i (ignored), -C (copies) or -A is given. Unless options described
2420 with "show only ..." are given, the options -mardu are used.
2541 2421
2542 NOTE: status may appear to disagree with diff if permissions have 2422 NOTE: status may appear to disagree with diff if permissions have
2543 changed or a merge has occurred. The standard diff format does not 2423 changed or a merge has occurred. The standard diff format does not
2544 report permission changes and diff only reports changes relative 2424 report permission changes and diff only reports changes relative
2545 to one merge parent. 2425 to one merge parent.
2552 A = added 2432 A = added
2553 R = removed 2433 R = removed
2554 C = clean 2434 C = clean
2555 ! = deleted, but still tracked 2435 ! = deleted, but still tracked
2556 ? = not tracked 2436 ? = not tracked
2557 I = ignored (not shown by default) 2437 I = ignored
2558 = the previous added file was copied from here 2438 = the previous added file was copied from here
2559 """ 2439 """
2560 2440
2561 all = opts['all'] 2441 all = opts['all']
2562 node1, node2 = cmdutil.revpair(repo, opts.get('rev')) 2442 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2624 raise util.Abort(_("--rev and --remove are incompatible")) 2504 raise util.Abort(_("--rev and --remove are incompatible"))
2625 if opts['rev']: 2505 if opts['rev']:
2626 rev_ = opts['rev'] 2506 rev_ = opts['rev']
2627 message = opts['message'] 2507 message = opts['message']
2628 if opts['remove']: 2508 if opts['remove']:
2629 if not name in repo.tags(): 2509 tagtype = repo.tagtype(name)
2510
2511 if not tagtype:
2630 raise util.Abort(_('tag %s does not exist') % name) 2512 raise util.Abort(_('tag %s does not exist') % name)
2513 if opts['local'] and tagtype == 'global':
2514 raise util.Abort(_('%s tag is global') % name)
2515 if not opts['local'] and tagtype == 'local':
2516 raise util.Abort(_('%s tag is local') % name)
2517
2631 rev_ = nullid 2518 rev_ = nullid
2632 if not message: 2519 if not message:
2633 message = _('Removed tag %s') % name 2520 message = _('Removed tag %s') % name
2634 elif name in repo.tags() and not opts['force']: 2521 elif name in repo.tags() and not opts['force']:
2635 raise util.Abort(_('a tag named %s already exists (use -f to force)') 2522 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2647 def tags(ui, repo): 2534 def tags(ui, repo):
2648 """list repository tags 2535 """list repository tags
2649 2536
2650 List the repository tags. 2537 List the repository tags.
2651 2538
2652 This lists both regular and local tags. 2539 This lists both regular and local tags. When the -v/--verbose switch
2540 is used, a third column "local" is printed for local tags.
2653 """ 2541 """
2654 2542
2655 l = repo.tagslist() 2543 l = repo.tagslist()
2656 l.reverse() 2544 l.reverse()
2657 hexfunc = ui.debugflag and hex or short 2545 hexfunc = ui.debugflag and hex or short
2546 tagtype = ""
2547
2658 for t, n in l: 2548 for t, n in l:
2549 if ui.quiet:
2550 ui.write("%s\n" % t)
2551 continue
2552
2659 try: 2553 try:
2660 hn = hexfunc(n) 2554 hn = hexfunc(n)
2661 r = "%5d:%s" % (repo.changelog.rev(n), hexfunc(n)) 2555 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2662 except revlog.LookupError: 2556 except revlog.LookupError:
2663 r = " ?:%s" % hn 2557 r = " ?:%s" % hn
2664 if ui.quiet:
2665 ui.write("%s\n" % t)
2666 else: 2558 else:
2667 spaces = " " * (30 - util.locallen(t)) 2559 spaces = " " * (30 - util.locallen(t))
2668 ui.write("%s%s %s\n" % (t, spaces, r)) 2560 if ui.verbose:
2561 if repo.tagtype(t) == 'local':
2562 tagtype = " local"
2563 else:
2564 tagtype = ""
2565 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2669 2566
2670 def tip(ui, repo, **opts): 2567 def tip(ui, repo, **opts):
2671 """show the tip revision 2568 """show the tip revision
2672 2569
2673 Show the tip revision. 2570 Show the tip revision.
2687 else: 2584 else:
2688 f = urllib.urlopen(fname) 2585 f = urllib.urlopen(fname)
2689 gen = changegroup.readbundle(f, fname) 2586 gen = changegroup.readbundle(f, fname)
2690 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname) 2587 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2691 2588
2692 return postincoming(ui, repo, modheads, opts['update']) 2589 return postincoming(ui, repo, modheads, opts['update'], None)
2693 2590
2694 def update(ui, repo, node=None, rev=None, clean=False, date=None): 2591 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2695 """update working directory 2592 """update working directory
2696 2593
2697 Update the working directory to the specified revision, or the 2594 Update the working directory to the specified revision, or the
2738 def version_(ui): 2635 def version_(ui):
2739 """output version and copyright information""" 2636 """output version and copyright information"""
2740 ui.write(_("Mercurial Distributed SCM (version %s)\n") 2637 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2741 % version.get_version()) 2638 % version.get_version())
2742 ui.status(_( 2639 ui.status(_(
2743 "\nCopyright (C) 2005-2007 Matt Mackall <mpm@selenic.com> and others\n" 2640 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2744 "This is free software; see the source for copying conditions. " 2641 "This is free software; see the source for copying conditions. "
2745 "There is NO\nwarranty; " 2642 "There is NO\nwarranty; "
2746 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" 2643 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2747 )) 2644 ))
2748 2645
2783 ] 2680 ]
2784 2681
2785 commitopts = [ 2682 commitopts = [
2786 ('m', 'message', '', _('use <text> as commit message')), 2683 ('m', 'message', '', _('use <text> as commit message')),
2787 ('l', 'logfile', '', _('read commit message from <file>')), 2684 ('l', 'logfile', '', _('read commit message from <file>')),
2685 ]
2686
2687 commitopts2 = [
2688 ('d', 'date', '', _('record datecode as commit date')),
2689 ('u', 'user', '', _('record user as committer')),
2788 ] 2690 ]
2789 2691
2790 table = { 2692 table = {
2791 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')), 2693 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2792 "addremove": 2694 "addremove":
2818 _('hg archive [OPTION]... DEST')), 2720 _('hg archive [OPTION]... DEST')),
2819 "backout": 2721 "backout":
2820 (backout, 2722 (backout,
2821 [('', 'merge', None, 2723 [('', 'merge', None,
2822 _('merge with old dirstate parent after backout')), 2724 _('merge with old dirstate parent after backout')),
2823 ('d', 'date', '', _('record datecode as commit date')),
2824 ('', 'parent', '', _('parent to choose when backing out merge')), 2725 ('', 'parent', '', _('parent to choose when backing out merge')),
2825 ('u', 'user', '', _('record user as committer')),
2826 ('r', 'rev', '', _('revision to backout')), 2726 ('r', 'rev', '', _('revision to backout')),
2827 ] + walkopts + commitopts, 2727 ] + walkopts + commitopts + commitopts2,
2828 _('hg backout [OPTION]... [-r] REV')), 2728 _('hg backout [OPTION]... [-r] REV')),
2729 "bisect":
2730 (bisect,
2731 [('r', 'reset', False, _('reset bisect state')),
2732 ('g', 'good', False, _('mark changeset good')),
2733 ('b', 'bad', False, _('mark changeset bad')),
2734 ('s', 'skip', False, _('skip testing changeset')),
2735 ('U', 'noupdate', False, _('do not update to target'))],
2736 _("hg bisect [-gbsr] [REV]")),
2829 "branch": 2737 "branch":
2830 (branch, 2738 (branch,
2831 [('f', 'force', None, 2739 [('f', 'force', None,
2832 _('set branch name even if it shadows an existing branch'))], 2740 _('set branch name even if it shadows an existing branch'))],
2833 _('hg branch [NAME]')), 2741 _('hg branch [-f] [NAME]')),
2834 "branches": 2742 "branches":
2835 (branches, 2743 (branches,
2836 [('a', 'active', False, 2744 [('a', 'active', False,
2837 _('show only branches that have unmerged heads'))], 2745 _('show only branches that have unmerged heads'))],
2838 _('hg branches [-a]')), 2746 _('hg branches [-a]')),
2864 _('hg clone [OPTION]... SOURCE [DEST]')), 2772 _('hg clone [OPTION]... SOURCE [DEST]')),
2865 "^commit|ci": 2773 "^commit|ci":
2866 (commit, 2774 (commit,
2867 [('A', 'addremove', None, 2775 [('A', 'addremove', None,
2868 _('mark new/missing files as added/removed before committing')), 2776 _('mark new/missing files as added/removed before committing')),
2869 ('d', 'date', '', _('record datecode as commit date')), 2777 ] + walkopts + commitopts + commitopts2,
2870 ('u', 'user', '', _('record user as commiter')),
2871 ] + walkopts + commitopts,
2872 _('hg commit [OPTION]... [FILE]...')), 2778 _('hg commit [OPTION]... [FILE]...')),
2873 "copy|cp": 2779 "copy|cp":
2874 (copy, 2780 (copy,
2875 [('A', 'after', None, _('record a copy that has already occurred')), 2781 [('A', 'after', None, _('record a copy that has already occurred')),
2876 ('f', 'force', None, 2782 ('f', 'force', None,
2877 _('forcibly copy over an existing managed file')), 2783 _('forcibly copy over an existing managed file')),
2878 ] + walkopts + dryrunopts, 2784 ] + walkopts + dryrunopts,
2879 _('hg copy [OPTION]... [SOURCE]... DEST')), 2785 _('hg copy [OPTION]... [SOURCE]... DEST')),
2880 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')), 2786 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2787 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2881 "debugcomplete": 2788 "debugcomplete":
2882 (debugcomplete, 2789 (debugcomplete,
2883 [('o', 'options', None, _('show the command options'))], 2790 [('o', 'options', None, _('show the command options'))],
2884 _('debugcomplete [-o] CMD')), 2791 _('hg debugcomplete [-o] CMD')),
2885 "debuginstall": (debuginstall, [], _('debuginstall')), 2792 "debugdate":
2793 (debugdate,
2794 [('e', 'extended', None, _('try extended date formats'))],
2795 _('hg debugdate [-e] DATE [RANGE]')),
2796 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2797 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2798 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2799 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2800 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2801 "debugrawcommit|rawcommit":
2802 (rawcommit,
2803 [('p', 'parent', [], _('parent')),
2804 ('F', 'files', '', _('file list'))
2805 ] + commitopts + commitopts2,
2806 _('hg debugrawcommit [OPTION]... [FILE]...')),
2886 "debugrebuildstate": 2807 "debugrebuildstate":
2887 (debugrebuildstate, 2808 (debugrebuildstate,
2888 [('r', 'rev', '', _('revision to rebuild to'))], 2809 [('r', 'rev', '', _('revision to rebuild to'))],
2889 _('debugrebuildstate [-r REV] [REV]')), 2810 _('hg debugrebuildstate [-r REV] [REV]')),
2890 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2891 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2892 "debugstate": (debugstate, [], _('debugstate')),
2893 "debugdate":
2894 (debugdate,
2895 [('e', 'extended', None, _('try extended date formats'))],
2896 _('debugdate [-e] DATE [RANGE]')),
2897 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2898 "debugindex": (debugindex, [], _('debugindex FILE')),
2899 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2900 "debugrename": 2811 "debugrename":
2901 (debugrename, 2812 (debugrename,
2902 [('r', 'rev', '', _('revision to debug'))], 2813 [('r', 'rev', '', _('revision to debug'))],
2903 _('debugrename [-r REV] FILE')), 2814 _('hg debugrename [-r REV] FILE')),
2904 "debugwalk": (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')), 2815 "debugsetparents":
2816 (debugsetparents,
2817 [],
2818 _('hg debugsetparents REV1 [REV2]')),
2819 "debugstate": (debugstate, [], _('hg debugstate')),
2820 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2905 "^diff": 2821 "^diff":
2906 (diff, 2822 (diff,
2907 [('r', 'rev', [], _('revision')), 2823 [('r', 'rev', [], _('revision')),
2908 ('a', 'text', None, _('treat all files as text')), 2824 ('a', 'text', None, _('treat all files as text')),
2909 ('p', 'show-function', None, 2825 ('p', 'show-function', None,
2963 _('directory strip option for patch. This has the same\n' 2879 _('directory strip option for patch. This has the same\n'
2964 'meaning as the corresponding patch option')), 2880 'meaning as the corresponding patch option')),
2965 ('b', 'base', '', _('base path')), 2881 ('b', 'base', '', _('base path')),
2966 ('f', 'force', None, 2882 ('f', 'force', None,
2967 _('skip check for outstanding uncommitted changes')), 2883 _('skip check for outstanding uncommitted changes')),
2884 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2968 ('', 'exact', None, 2885 ('', 'exact', None,
2969 _('apply patch to the nodes from which it was generated')), 2886 _('apply patch to the nodes from which it was generated')),
2970 ('', 'import-branch', None, 2887 ('', 'import-branch', None,
2971 _('Use any branch information in patch (implied by --exact)'))] + commitopts, 2888 _('Use any branch information in patch (implied by --exact)'))] +
2972 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')), 2889 commitopts + commitopts2,
2973 "incoming|in": (incoming, 2890 _('hg import [OPTION]... PATCH...')),
2891 "incoming|in":
2892 (incoming,
2974 [('M', 'no-merges', None, _('do not show merges')), 2893 [('M', 'no-merges', None, _('do not show merges')),
2975 ('f', 'force', None, 2894 ('f', 'force', None,
2976 _('run even when remote repository is unrelated')), 2895 _('run even when remote repository is unrelated')),
2977 ('', 'style', '', _('display using template map file')), 2896 ('', 'style', '', _('display using template map file')),
2978 ('n', 'newest-first', None, _('show newest record first')), 2897 ('n', 'newest-first', None, _('show newest record first')),
3014 ('p', 'patch', None, _('show patch')), 2933 ('p', 'patch', None, _('show patch')),
3015 ('P', 'prune', [], _('do not display revision or any of its ancestors')), 2934 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
3016 ('', 'template', '', _('display with template')), 2935 ('', 'template', '', _('display with template')),
3017 ] + walkopts, 2936 ] + walkopts,
3018 _('hg log [OPTION]... [FILE]')), 2937 _('hg log [OPTION]... [FILE]')),
3019 "manifest": (manifest, [], _('hg manifest [REV]')), 2938 "manifest":
2939 (manifest,
2940 [('r', 'rev', '', _('revision to display'))],
2941 _('hg manifest [-r REV]')),
3020 "^merge": 2942 "^merge":
3021 (merge, 2943 (merge,
3022 [('f', 'force', None, _('force a merge with outstanding changes')), 2944 [('f', 'force', None, _('force a merge with outstanding changes')),
3023 ('r', 'rev', '', _('revision to merge')), 2945 ('r', 'rev', '', _('revision to merge')),
3024 ], 2946 ],
3025 _('hg merge [-f] [[-r] REV]')), 2947 _('hg merge [-f] [[-r] REV]')),
3026 "outgoing|out": (outgoing, 2948 "outgoing|out":
2949 (outgoing,
3027 [('M', 'no-merges', None, _('do not show merges')), 2950 [('M', 'no-merges', None, _('do not show merges')),
3028 ('f', 'force', None, 2951 ('f', 'force', None,
3029 _('run even when remote repository is unrelated')), 2952 _('run even when remote repository is unrelated')),
3030 ('p', 'patch', None, _('show patch')), 2953 ('p', 'patch', None, _('show patch')),
3031 ('', 'style', '', _('display using template map file')), 2954 ('', 'style', '', _('display using template map file')),
3055 (push, 2978 (push,
3056 [('f', 'force', None, _('force push')), 2979 [('f', 'force', None, _('force push')),
3057 ('r', 'rev', [], _('a specific revision you would like to push')), 2980 ('r', 'rev', [], _('a specific revision you would like to push')),
3058 ] + remoteopts, 2981 ] + remoteopts,
3059 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')), 2982 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3060 "debugrawcommit|rawcommit":
3061 (rawcommit,
3062 [('p', 'parent', [], _('parent')),
3063 ('d', 'date', '', _('date code')),
3064 ('u', 'user', '', _('user')),
3065 ('F', 'files', '', _('file list'))
3066 ] + commitopts,
3067 _('hg debugrawcommit [OPTION]... [FILE]...')),
3068 "recover": (recover, [], _('hg recover')), 2983 "recover": (recover, [], _('hg recover')),
3069 "^remove|rm": 2984 "^remove|rm":
3070 (remove, 2985 (remove,
3071 [('A', 'after', None, _('record remove that has already occurred')), 2986 [('A', 'after', None, _('record remove without deleting')),
3072 ('f', 'force', None, _('remove file even if modified')), 2987 ('f', 'force', None, _('remove file even if modified')),
3073 ] + walkopts, 2988 ] + walkopts,
3074 _('hg remove [OPTION]... FILE...')), 2989 _('hg remove [OPTION]... FILE...')),
3075 "rename|mv": 2990 "rename|mv":
3076 (rename, 2991 (rename,
3077 [('A', 'after', None, _('record a rename that has already occurred')), 2992 [('A', 'after', None, _('record a rename that has already occurred')),
3078 ('f', 'force', None, 2993 ('f', 'force', None,
3079 _('forcibly copy over an existing managed file')), 2994 _('forcibly copy over an existing managed file')),
3080 ] + walkopts + dryrunopts, 2995 ] + walkopts + dryrunopts,
3081 _('hg rename [OPTION]... SOURCE... DEST')), 2996 _('hg rename [OPTION]... SOURCE... DEST')),
3082 "^revert": 2997 "revert":
3083 (revert, 2998 (revert,
3084 [('a', 'all', None, _('revert all changes when no arguments given')), 2999 [('a', 'all', None, _('revert all changes when no arguments given')),
3085 ('d', 'date', '', _('tipmost revision matching date')), 3000 ('d', 'date', '', _('tipmost revision matching date')),
3086 ('r', 'rev', '', _('revision to revert to')), 3001 ('r', 'rev', '', _('revision to revert to')),
3087 ('', 'no-backup', None, _('do not save backup copies of files')), 3002 ('', 'no-backup', None, _('do not save backup copies of files')),
3088 ] + walkopts + dryrunopts, 3003 ] + walkopts + dryrunopts,
3089 _('hg revert [OPTION]... [-r REV] [NAME]...')), 3004 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3090 "rollback": (rollback, [], _('hg rollback')), 3005 "rollback": (rollback, [], _('hg rollback')),
3091 "root": (root, [], _('hg root')), 3006 "root": (root, [], _('hg root')),
3092 "showconfig|debugconfig":
3093 (showconfig,
3094 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3095 _('showconfig [-u] [NAME]...')),
3096 "^serve": 3007 "^serve":
3097 (serve, 3008 (serve,
3098 [('A', 'accesslog', '', _('name of access log file to write to')), 3009 [('A', 'accesslog', '', _('name of access log file to write to')),
3099 ('d', 'daemon', None, _('run server in background')), 3010 ('d', 'daemon', None, _('run server in background')),
3100 ('', 'daemon-pipefds', '', _('used internally by daemon mode')), 3011 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3101 ('E', 'errorlog', '', _('name of error log file to write to')), 3012 ('E', 'errorlog', '', _('name of error log file to write to')),
3102 ('p', 'port', 0, _('port to use (default: 8000)')), 3013 ('p', 'port', 0, _('port to use (default: 8000)')),
3103 ('a', 'address', '', _('address to use')), 3014 ('a', 'address', '', _('address to use')),
3015 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3104 ('n', 'name', '', 3016 ('n', 'name', '',
3105 _('name to show in web pages (default: working dir)')), 3017 _('name to show in web pages (default: working dir)')),
3106 ('', 'webdir-conf', '', _('name of the webdir config file' 3018 ('', 'webdir-conf', '', _('name of the webdir config file'
3107 ' (serve more than one repo)')), 3019 ' (serve more than one repo)')),
3108 ('', 'pid-file', '', _('name of file to write process ID to')), 3020 ('', 'pid-file', '', _('name of file to write process ID to')),
3110 ('t', 'templates', '', _('web templates to use')), 3022 ('t', 'templates', '', _('web templates to use')),
3111 ('', 'style', '', _('template style to use')), 3023 ('', 'style', '', _('template style to use')),
3112 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), 3024 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3113 ('', 'certificate', '', _('SSL certificate file'))], 3025 ('', 'certificate', '', _('SSL certificate file'))],
3114 _('hg serve [OPTION]...')), 3026 _('hg serve [OPTION]...')),
3027 "showconfig|debugconfig":
3028 (showconfig,
3029 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3030 _('hg showconfig [-u] [NAME]...')),
3115 "^status|st": 3031 "^status|st":
3116 (status, 3032 (status,
3117 [('A', 'all', None, _('show status of all files')), 3033 [('A', 'all', None, _('show status of all files')),
3118 ('m', 'modified', None, _('show only modified files')), 3034 ('m', 'modified', None, _('show only modified files')),
3119 ('a', 'added', None, _('show only added files')), 3035 ('a', 'added', None, _('show only added files')),
3131 _('hg status [OPTION]... [FILE]...')), 3047 _('hg status [OPTION]... [FILE]...')),
3132 "tag": 3048 "tag":
3133 (tag, 3049 (tag,
3134 [('f', 'force', None, _('replace existing tag')), 3050 [('f', 'force', None, _('replace existing tag')),
3135 ('l', 'local', None, _('make the tag local')), 3051 ('l', 'local', None, _('make the tag local')),
3136 ('m', 'message', '', _('message for tag commit log entry')),
3137 ('d', 'date', '', _('record datecode as commit date')),
3138 ('u', 'user', '', _('record user as commiter')),
3139 ('r', 'rev', '', _('revision to tag')), 3052 ('r', 'rev', '', _('revision to tag')),
3140 ('', 'remove', None, _('remove a tag'))], 3053 ('', 'remove', None, _('remove a tag')),
3054 # -l/--local is already there, commitopts cannot be used
3055 ('m', 'message', '', _('use <text> as commit message')),
3056 ] + commitopts2,
3141 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')), 3057 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3142 "tags": (tags, [], _('hg tags')), 3058 "tags": (tags, [], _('hg tags')),
3143 "tip": 3059 "tip":
3144 (tip, 3060 (tip,
3145 [('', 'style', '', _('display using template map file')), 3061 [('', 'style', '', _('display using template map file')),
3159 _('hg update [-C] [-d DATE] [[-r] REV]')), 3075 _('hg update [-C] [-d DATE] [[-r] REV]')),
3160 "verify": (verify, [], _('hg verify')), 3076 "verify": (verify, [], _('hg verify')),
3161 "version": (version_, [], _('hg version')), 3077 "version": (version_, [], _('hg version')),
3162 } 3078 }
3163 3079
3164 extensions.commandtable = table
3165
3166 norepo = ("clone init version help debugancestor debugcomplete debugdata" 3080 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3167 " debugindex debugindexdot debugdate debuginstall") 3081 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3168 optionalrepo = ("paths serve showconfig") 3082 optionalrepo = ("identify paths serve showconfig")
3169
3170 def dispatch(args, argv0=None):
3171 try:
3172 u = ui.ui(traceback='--traceback' in args)
3173 except util.Abort, inst:
3174 sys.stderr.write(_("abort: %s\n") % inst)
3175 return -1
3176 return cmdutil.runcatch(u, args, argv0=argv0)
3177
3178 def run():
3179 sys.exit(dispatch(sys.argv[1:], argv0=sys.argv[0]))