comparison mercurial/commands.py @ 3092:25857e00af8e

cat: default to working dir parent instead of tip This introduces a defaultrev function that chooses the working dir parent if a revision isn't specified, and uses it in several places.
author Brendan Cully <brendan@kublai.com>
date Thu, 14 Sep 2006 19:24:00 -0700
parents eeaf9bcdfa25
children 81da3c45aabd
comparison
equal deleted inserted replaced
3091:41e5ecfb6c24 3092:25857e00af8e
48 except IOError, inst: 48 except IOError, inst:
49 raise util.Abort(_("can't read commit message '%s': %s") % 49 raise util.Abort(_("can't read commit message '%s': %s") %
50 (logfile, inst.strerror)) 50 (logfile, inst.strerror))
51 return message 51 return message
52 52
53 def defaultrev(repo, rev=None, default='tip'):
54 """returns rev if it is specified, otherwise the working dir
55 parent if there is only one, or tip if there is no working
56 dir"""
57 if rev:
58 return rev
59
60 p1, p2 = repo.dirstate.parents()
61 if p2 != nullid:
62 raise util.Abort(_('uncommitted merge - please provide a '
63 'specific revision'))
64 if p1 != nullid:
65 return hex(p1)
66 return default
67
53 def walkchangerevs(ui, repo, pats, opts): 68 def walkchangerevs(ui, repo, pats, opts):
54 '''Iterate over files and the revs they changed in. 69 '''Iterate over files and the revs they changed in.
55 70
56 Callers most commonly need to iterate backwards over the history 71 Callers most commonly need to iterate backwards over the history
57 it is interested in. Doing so has awful (quadratic-looking) 72 it is interested in. Doing so has awful (quadratic-looking)
97 112
98 if repo.changelog.count() == 0: 113 if repo.changelog.count() == 0:
99 return [], False, matchfn 114 return [], False, matchfn
100 115
101 if follow: 116 if follow:
102 p = repo.dirstate.parents()[0] 117 defrange = '%s:0' % defaultrev(repo)
103 if p == nullid:
104 ui.warn(_('No working directory revision; defaulting to tip\n'))
105 start = 'tip'
106 else:
107 start = repo.changelog.rev(p)
108 defrange = '%s:0' % start
109 else: 118 else:
110 defrange = 'tip:0' 119 defrange = 'tip:0'
111 revs = map(int, cmdutil.revrange(ui, repo, opts['rev'] or [defrange])) 120 revs = map(int, cmdutil.revrange(ui, repo, opts['rev'] or [defrange]))
112 wanted = {} 121 wanted = {}
113 slowpath = anypats 122 slowpath = anypats
635 opmap = [['user', getname], ['number', str], ['changeset', getnode], 644 opmap = [['user', getname], ['number', str], ['changeset', getnode],
636 ['date', getdate]] 645 ['date', getdate]]
637 if not opts['user'] and not opts['changeset'] and not opts['date']: 646 if not opts['user'] and not opts['changeset'] and not opts['date']:
638 opts['number'] = 1 647 opts['number'] = 1
639 648
640 ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) 649 ctx = repo.changectx(defaultrev(repo, opts['rev']))
641 650
642 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, 651 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
643 node=ctx.node()): 652 node=ctx.node()):
644 fctx = ctx.filectx(abs) 653 fctx = ctx.filectx(abs)
645 if not opts['text'] and util.binary(fctx.data()): 654 if not opts['text'] and util.binary(fctx.data()):
682 Each member added to an archive file has a directory prefix 691 Each member added to an archive file has a directory prefix
683 prepended. Use "-p" to specify a format string for the prefix. 692 prepended. Use "-p" to specify a format string for the prefix.
684 The default is the basename of the archive, with suffixes removed. 693 The default is the basename of the archive, with suffixes removed.
685 ''' 694 '''
686 695
687 if opts['rev']: 696 node = repo.lookup(defaultrev(repo, opts['rev']))
688 node = repo.lookup(opts['rev'])
689 else:
690 node, p2 = repo.dirstate.parents()
691 if p2 != nullid:
692 raise util.Abort(_('uncommitted merge - please provide a '
693 'specific revision'))
694
695 dest = cmdutil.make_filename(repo, dest, node) 697 dest = cmdutil.make_filename(repo, dest, node)
696 if os.path.realpath(dest) == repo.root: 698 if os.path.realpath(dest) == repo.root:
697 raise util.Abort(_('repository root cannot be destination')) 699 raise util.Abort(_('repository root cannot be destination'))
698 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts) 700 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
699 kind = opts.get('type') or 'files' 701 kind = opts.get('type') or 'files'
795 797
796 def cat(ui, repo, file1, *pats, **opts): 798 def cat(ui, repo, file1, *pats, **opts):
797 """output the latest or given revisions of files 799 """output the latest or given revisions of files
798 800
799 Print the specified files as they were at the given revision. 801 Print the specified files as they were at the given revision.
800 If no revision is given then the tip is used. 802 If no revision is given then working dir parent is used, or tip
803 if no revision is checked out.
801 804
802 Output may be to a file, in which case the name of the file is 805 Output may be to a file, in which case the name of the file is
803 given using a format string. The formatting rules are the same as 806 given using a format string. The formatting rules are the same as
804 for the export command, with the following additions: 807 for the export command, with the following additions:
805 808
806 %s basename of file being printed 809 %s basename of file being printed
807 %d dirname of file being printed, or '.' if in repo root 810 %d dirname of file being printed, or '.' if in repo root
808 %p root-relative path name of file being printed 811 %p root-relative path name of file being printed
809 """ 812 """
810 ctx = repo.changectx(opts['rev'] or "-1") 813 ctx = repo.changectx(defaultrev(repo, opts['rev']))
811 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, 814 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
812 ctx.node()): 815 ctx.node()):
813 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) 816 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
814 fp.write(ctx.filectx(abs).data()) 817 fp.write(ctx.filectx(abs).data())
815 818
2223 if not pats and not opts['all']: 2226 if not pats and not opts['all']:
2224 raise util.Abort(_('no files or directories specified; ' 2227 raise util.Abort(_('no files or directories specified; '
2225 'use --all to revert the whole repo')) 2228 'use --all to revert the whole repo'))
2226 2229
2227 parent, p2 = repo.dirstate.parents() 2230 parent, p2 = repo.dirstate.parents()
2228 if opts['rev']: 2231 node = repo.lookup(defaultrev(repo, opts['rev']))
2229 node = repo.lookup(opts['rev'])
2230 elif p2 != nullid:
2231 raise util.Abort(_('working dir has two parents; '
2232 'you must specify the revision to revert to'))
2233 else:
2234 node = parent
2235 mf = repo.manifest.read(repo.changelog.read(node)[0]) 2232 mf = repo.manifest.read(repo.changelog.read(node)[0])
2236 if node == parent: 2233 if node == parent:
2237 pmf = mf 2234 pmf = mf
2238 else: 2235 else:
2239 pmf = None 2236 pmf = None
2529 "please use 'hg tag [-r REV] NAME' instead\n")) 2526 "please use 'hg tag [-r REV] NAME' instead\n"))
2530 if opts['rev']: 2527 if opts['rev']:
2531 raise util.Abort(_("use only one form to specify the revision")) 2528 raise util.Abort(_("use only one form to specify the revision"))
2532 if opts['rev']: 2529 if opts['rev']:
2533 rev_ = opts['rev'] 2530 rev_ = opts['rev']
2534 if rev_: 2531 r = defaultrev(repo, rev_, nullid)
2535 r = repo.lookup(rev_) 2532 if r == nullid:
2536 else: 2533 raise util.Abort(_('no revision to tag'))
2537 p1, p2 = repo.dirstate.parents() 2534 r = repo.lookup(r)
2538 if p1 == nullid:
2539 raise util.Abort(_('no revision to tag'))
2540 if p2 != nullid:
2541 raise util.Abort(_('outstanding uncommitted merges'))
2542 r = p1
2543 2535
2544 message = opts['message'] 2536 message = opts['message']
2545 if not message: 2537 if not message:
2546 message = _('Added tag %s for changeset %s') % (name, short(r)) 2538 message = _('Added tag %s for changeset %s') % (name, short(r))
2547 2539