comparison mercurial/commands.py @ 7131:23bd7383891c

commands: optional options where possible This makes life a lot easier on API users.
author Alexander Solovyov <piranha@piranha.org.ua>
date Sat, 18 Oct 2008 18:05:56 +0200
parents 111813de4188
children 67ba74938b15
comparison
equal deleted inserted replaced
7130:204c7850c158 7131:23bd7383891c
92 ('changeset', lambda x: short(x[0].node())), 92 ('changeset', lambda x: short(x[0].node())),
93 ('date', getdate), 93 ('date', getdate),
94 ('follow', lambda x: x[0].path()), 94 ('follow', lambda x: x[0].path()),
95 ] 95 ]
96 96
97 if (not opts['user'] and not opts['changeset'] and not opts['date'] 97 if (not opts.get('user') and not opts.get('changeset') and not opts.get('date')
98 and not opts['follow']): 98 and not opts.get('follow')):
99 opts['number'] = 1 99 opts['number'] = 1
100 100
101 linenumber = opts.get('line_number') is not None 101 linenumber = opts.get('line_number') is not None
102 if (linenumber and (not opts['changeset']) and (not opts['number'])): 102 if (linenumber and (not opts.get('changeset')) and (not opts.get('number'))):
103 raise util.Abort(_('at least one of -n/-c is required for -l')) 103 raise util.Abort(_('at least one of -n/-c is required for -l'))
104 104
105 funcmap = [func for op, func in opmap if opts.get(op)] 105 funcmap = [func for op, func in opmap if opts.get(op)]
106 if linenumber: 106 if linenumber:
107 lastfunc = funcmap[-1] 107 lastfunc = funcmap[-1]
108 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1]) 108 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
109 109
110 ctx = repo[opts['rev']] 110 ctx = repo[opts.get('rev')]
111 111
112 m = cmdutil.match(repo, pats, opts) 112 m = cmdutil.match(repo, pats, opts)
113 for abs in ctx.walk(m): 113 for abs in ctx.walk(m):
114 fctx = ctx[abs] 114 fctx = ctx[abs]
115 if not opts['text'] and util.binary(fctx.data()): 115 if not opts.get('text') and util.binary(fctx.data()):
116 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs)) 116 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
117 continue 117 continue
118 118
119 lines = fctx.annotate(follow=opts.get('follow'), 119 lines = fctx.annotate(follow=opts.get('follow'),
120 linenumber=linenumber) 120 linenumber=linenumber)
152 Each member added to an archive file has a directory prefix 152 Each member added to an archive file has a directory prefix
153 prepended. Use "-p" to specify a format string for the prefix. 153 prepended. Use "-p" to specify a format string for the prefix.
154 The default is the basename of the archive, with suffixes removed. 154 The default is the basename of the archive, with suffixes removed.
155 ''' 155 '''
156 156
157 ctx = repo[opts['rev']] 157 ctx = repo[opts.get('rev')]
158 if not ctx: 158 if not ctx:
159 raise util.Abort(_('repository has no revisions')) 159 raise util.Abort(_('repository has no revisions'))
160 node = ctx.node() 160 node = ctx.node()
161 dest = cmdutil.make_filename(repo, dest, node) 161 dest = cmdutil.make_filename(repo, dest, node)
162 if os.path.realpath(dest) == repo.root: 162 if os.path.realpath(dest) == repo.root:
163 raise util.Abort(_('repository root cannot be destination')) 163 raise util.Abort(_('repository root cannot be destination'))
164 matchfn = cmdutil.match(repo, [], opts) 164 matchfn = cmdutil.match(repo, [], opts)
165 kind = opts.get('type') or 'files' 165 kind = opts.get('type') or 'files'
166 prefix = opts['prefix'] 166 prefix = opts.get('prefix')
167 if dest == '-': 167 if dest == '-':
168 if kind == 'files': 168 if kind == 'files':
169 raise util.Abort(_('cannot archive plain files to stdout')) 169 raise util.Abort(_('cannot archive plain files to stdout'))
170 dest = sys.stdout 170 dest = sys.stdout
171 if not prefix: prefix = os.path.basename(repo.root) + '-%h' 171 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
172 prefix = cmdutil.make_filename(repo, prefix, node) 172 prefix = cmdutil.make_filename(repo, prefix, node)
173 archival.archive(repo, dest, node, kind, not opts['no_decode'], 173 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
174 matchfn, prefix) 174 matchfn, prefix)
175 175
176 def backout(ui, repo, node=None, rev=None, **opts): 176 def backout(ui, repo, node=None, rev=None, **opts):
177 '''reverse effect of earlier changeset 177 '''reverse effect of earlier changeset
178 178
214 214
215 p1, p2 = repo.changelog.parents(node) 215 p1, p2 = repo.changelog.parents(node)
216 if p1 == nullid: 216 if p1 == nullid:
217 raise util.Abort(_('cannot back out a change with no parents')) 217 raise util.Abort(_('cannot back out a change with no parents'))
218 if p2 != nullid: 218 if p2 != nullid:
219 if not opts['parent']: 219 if not opts.get('parent'):
220 raise util.Abort(_('cannot back out a merge changeset without ' 220 raise util.Abort(_('cannot back out a merge changeset without '
221 '--parent')) 221 '--parent'))
222 p = repo.lookup(opts['parent']) 222 p = repo.lookup(opts['parent'])
223 if p not in (p1, p2): 223 if p not in (p1, p2):
224 raise util.Abort(_('%s is not a parent of %s') % 224 raise util.Abort(_('%s is not a parent of %s') %
225 (short(p), short(node))) 225 (short(p), short(node)))
226 parent = p 226 parent = p
227 else: 227 else:
228 if opts['parent']: 228 if opts.get('parent'):
229 raise util.Abort(_('cannot use --parent on non-merge changeset')) 229 raise util.Abort(_('cannot use --parent on non-merge changeset'))
230 parent = p1 230 parent = p1
231 231
232 # the backout should appear on the same branch 232 # the backout should appear on the same branch
233 branch = repo.dirstate.branch() 233 branch = repo.dirstate.branch()
249 return '%d:%s' % (repo.changelog.rev(node), short(node)) 249 return '%d:%s' % (repo.changelog.rev(node), short(node))
250 ui.status(_('changeset %s backs out changeset %s\n') % 250 ui.status(_('changeset %s backs out changeset %s\n') %
251 (nice(repo.changelog.tip()), nice(node))) 251 (nice(repo.changelog.tip()), nice(node)))
252 if op1 != node: 252 if op1 != node:
253 hg.clean(repo, op1, show_stats=False) 253 hg.clean(repo, op1, show_stats=False)
254 if opts['merge']: 254 if opts.get('merge'):
255 ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip())) 255 ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
256 hg.merge(repo, hex(repo.changelog.tip())) 256 hg.merge(repo, hex(repo.changelog.tip()))
257 else: 257 else:
258 ui.status(_('the backout changeset is a new head - ' 258 ui.status(_('the backout changeset is a new head - '
259 'do not forget to merge\n')) 259 'do not forget to merge\n'))
476 else: 476 else:
477 cmdutil.setremoteconfig(ui, opts) 477 cmdutil.setremoteconfig(ui, opts)
478 dest, revs, checkout = hg.parseurl( 478 dest, revs, checkout = hg.parseurl(
479 ui.expandpath(dest or 'default-push', dest or 'default'), revs) 479 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
480 other = hg.repository(ui, dest) 480 other = hg.repository(ui, dest)
481 o = repo.findoutgoing(other, force=opts['force']) 481 o = repo.findoutgoing(other, force=opts.get('force'))
482 482
483 if revs: 483 if revs:
484 cg = repo.changegroupsubset(o, revs, 'bundle') 484 cg = repo.changegroupsubset(o, revs, 'bundle')
485 else: 485 else:
486 cg = repo.changegroup(o, 'bundle') 486 cg = repo.changegroup(o, 'bundle')
506 506
507 %s basename of file being printed 507 %s basename of file being printed
508 %d dirname of file being printed, or '.' if in repo root 508 %d dirname of file being printed, or '.' if in repo root
509 %p root-relative path name of file being printed 509 %p root-relative path name of file being printed
510 """ 510 """
511 ctx = repo[opts['rev']] 511 ctx = repo[opts.get('rev')]
512 err = 1 512 err = 1
513 m = cmdutil.match(repo, (file1,) + pats, opts) 513 m = cmdutil.match(repo, (file1,) + pats, opts)
514 for abs in ctx.walk(m): 514 for abs in ctx.walk(m):
515 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) 515 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
516 data = ctx[abs].data() 516 data = ctx[abs].data()
517 if opts.get('decode'): 517 if opts.get('decode'):
518 data = repo.wwritedata(abs, data) 518 data = repo.wwritedata(abs, data)
519 fp.write(data) 519 fp.write(data)
520 err = 0 520 err = 0
564 Look at the help text for the pull command for important details 564 Look at the help text for the pull command for important details
565 about ssh:// URLs. 565 about ssh:// URLs.
566 """ 566 """
567 cmdutil.setremoteconfig(ui, opts) 567 cmdutil.setremoteconfig(ui, opts)
568 hg.clone(ui, source, dest, 568 hg.clone(ui, source, dest,
569 pull=opts['pull'], 569 pull=opts.get('pull'),
570 stream=opts['uncompressed'], 570 stream=opts.get('uncompressed'),
571 rev=opts['rev'], 571 rev=opts.get('rev'),
572 update=not opts['noupdate']) 572 update=not opts.get('noupdate'))
573 573
574 def commit(ui, repo, *pats, **opts): 574 def commit(ui, repo, *pats, **opts):
575 """commit the specified files or all outstanding changes 575 """commit the specified files or all outstanding changes
576 576
577 Commit changes to the given files into the repository. 577 Commit changes to the given files into the repository.
586 enter a message. 586 enter a message.
587 587
588 See 'hg help dates' for a list of formats valid for -d/--date. 588 See 'hg help dates' for a list of formats valid for -d/--date.
589 """ 589 """
590 def commitfunc(ui, repo, message, match, opts): 590 def commitfunc(ui, repo, message, match, opts):
591 return repo.commit(match.files(), message, opts['user'], opts['date'], 591 return repo.commit(match.files(), message, opts.get('user'), opts.get('date'),
592 match, force_editor=opts.get('force_editor')) 592 match, force_editor=opts.get('force_editor'))
593 593
594 node = cmdutil.commit(ui, repo, commitfunc, pats, opts) 594 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
595 if not node: 595 if not node:
596 return 596 return
649 ui.write("%d:%s\n" % (r.rev(a), hex(a))) 649 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
650 650
651 def debugcomplete(ui, cmd='', **opts): 651 def debugcomplete(ui, cmd='', **opts):
652 """returns the completion list associated with the given command""" 652 """returns the completion list associated with the given command"""
653 653
654 if opts['options']: 654 if opts.get('options'):
655 options = [] 655 options = []
656 otables = [globalopts] 656 otables = [globalopts]
657 if cmd: 657 if cmd:
658 aliases, entry = cmdutil.findcmd(ui, cmd, table) 658 aliases, entry = cmdutil.findcmd(ui, cmd, table)
659 otables.append(entry[1]) 659 otables.append(entry[1])
979 979
980 Without the -a option, diff will avoid generating diffs of files 980 Without the -a option, diff will avoid generating diffs of files
981 it detects as binary. With -a, diff will generate a diff anyway, 981 it detects as binary. With -a, diff will generate a diff anyway,
982 probably with undesirable results. 982 probably with undesirable results.
983 """ 983 """
984 node1, node2 = cmdutil.revpair(repo, opts['rev']) 984 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
985 985
986 m = cmdutil.match(repo, pats, opts) 986 m = cmdutil.match(repo, pats, opts)
987 patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts)) 987 patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts))
988 988
989 def export(ui, repo, *changesets, **opts): 989 def export(ui, repo, *changesets, **opts):
1021 revs = cmdutil.revrange(repo, changesets) 1021 revs = cmdutil.revrange(repo, changesets)
1022 if len(revs) > 1: 1022 if len(revs) > 1:
1023 ui.note(_('exporting patches:\n')) 1023 ui.note(_('exporting patches:\n'))
1024 else: 1024 else:
1025 ui.note(_('exporting patch:\n')) 1025 ui.note(_('exporting patch:\n'))
1026 patch.export(repo, revs, template=opts['output'], 1026 patch.export(repo, revs, template=opts.get('output'),
1027 switch_parent=opts['switch_parent'], 1027 switch_parent=opts.get('switch_parent'),
1028 opts=patch.diffopts(ui, opts)) 1028 opts=patch.diffopts(ui, opts))
1029 1029
1030 def grep(ui, repo, pattern, *pats, **opts): 1030 def grep(ui, repo, pattern, *pats, **opts):
1031 """search for a pattern in specified files and revisions 1031 """search for a pattern in specified files and revisions
1032 1032
1042 that contains a change in match status ("-" for a match that 1042 that contains a change in match status ("-" for a match that
1043 becomes a non-match, or "+" for a non-match that becomes a match), 1043 becomes a non-match, or "+" for a non-match that becomes a match),
1044 use the --all flag. 1044 use the --all flag.
1045 """ 1045 """
1046 reflags = 0 1046 reflags = 0
1047 if opts['ignore_case']: 1047 if opts.get('ignore_case'):
1048 reflags |= re.I 1048 reflags |= re.I
1049 try: 1049 try:
1050 regexp = re.compile(pattern, reflags) 1050 regexp = re.compile(pattern, reflags)
1051 except Exception, inst: 1051 except Exception, inst:
1052 ui.warn(_("grep: invalid match pattern: %s\n") % inst) 1052 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1053 return None 1053 return None
1054 sep, eol = ':', '\n' 1054 sep, eol = ':', '\n'
1055 if opts['print0']: 1055 if opts.get('print0'):
1056 sep = eol = '\0' 1056 sep = eol = '\0'
1057 1057
1058 fcache = {} 1058 fcache = {}
1059 def getfile(fn): 1059 def getfile(fn):
1060 if fn not in fcache: 1060 if fn not in fcache:
1116 def display(fn, rev, states, prevstates): 1116 def display(fn, rev, states, prevstates):
1117 datefunc = ui.quiet and util.shortdate or util.datestr 1117 datefunc = ui.quiet and util.shortdate or util.datestr
1118 found = False 1118 found = False
1119 filerevmatches = {} 1119 filerevmatches = {}
1120 r = prev.get(fn, -1) 1120 r = prev.get(fn, -1)
1121 if opts['all']: 1121 if opts.get('all'):
1122 iter = difflinestates(states, prevstates) 1122 iter = difflinestates(states, prevstates)
1123 else: 1123 else:
1124 iter = [('', l) for l in prevstates] 1124 iter = [('', l) for l in prevstates]
1125 for change, l in iter: 1125 for change, l in iter:
1126 cols = [fn, str(r)] 1126 cols = [fn, str(r)]
1127 if opts['line_number']: 1127 if opts.get('line_number'):
1128 cols.append(str(l.linenum)) 1128 cols.append(str(l.linenum))
1129 if opts['all']: 1129 if opts.get('all'):
1130 cols.append(change) 1130 cols.append(change)
1131 if opts['user']: 1131 if opts.get('user'):
1132 cols.append(ui.shortuser(get(r)[1])) 1132 cols.append(ui.shortuser(get(r)[1]))
1133 if opts.get('date'): 1133 if opts.get('date'):
1134 cols.append(datefunc(get(r)[2])) 1134 cols.append(datefunc(get(r)[2]))
1135 if opts['files_with_matches']: 1135 if opts.get('files_with_matches'):
1136 c = (fn, r) 1136 c = (fn, r)
1137 if c in filerevmatches: 1137 if c in filerevmatches:
1138 continue 1138 continue
1139 filerevmatches[c] = 1 1139 filerevmatches[c] = 1
1140 else: 1140 else:
1175 skip[copy] = True 1175 skip[copy] = True
1176 continue 1176 continue
1177 if fn in prev or fstate[fn]: 1177 if fn in prev or fstate[fn]:
1178 r = display(fn, rev, m, fstate[fn]) 1178 r = display(fn, rev, m, fstate[fn])
1179 found = found or r 1179 found = found or r
1180 if r and not opts['all']: 1180 if r and not opts.get('all'):
1181 skip[fn] = True 1181 skip[fn] = True
1182 if copy: 1182 if copy:
1183 skip[copy] = True 1183 skip[copy] = True
1184 fstate[fn] = m 1184 fstate[fn] = m
1185 if copy: 1185 if copy:
1208 1208
1209 Branch heads are changesets that have a given branch tag, but have 1209 Branch heads are changesets that have a given branch tag, but have
1210 no child changesets with that tag. They are usually where 1210 no child changesets with that tag. They are usually where
1211 development on the given branch takes place. 1211 development on the given branch takes place.
1212 """ 1212 """
1213 if opts['rev']: 1213 if opts.get('rev'):
1214 start = repo.lookup(opts['rev']) 1214 start = repo.lookup(opts['rev'])
1215 else: 1215 else:
1216 start = None 1216 start = None
1217 if not branchrevs: 1217 if not branchrevs:
1218 # Assume we're looking repo-wide heads if no revs were specified. 1218 # Assume we're looking repo-wide heads if no revs were specified.
1228 bheads = repo.branchheads(branch, start) 1228 bheads = repo.branchheads(branch, start)
1229 if not bheads: 1229 if not bheads:
1230 if branch != branchrev: 1230 if branch != branchrev:
1231 ui.warn(_("no changes on branch %s containing %s are " 1231 ui.warn(_("no changes on branch %s containing %s are "
1232 "reachable from %s\n") 1232 "reachable from %s\n")
1233 % (branch, branchrev, opts['rev'])) 1233 % (branch, branchrev, opts.get('rev')))
1234 else: 1234 else:
1235 ui.warn(_("no changes on branch %s are reachable from %s\n") 1235 ui.warn(_("no changes on branch %s are reachable from %s\n")
1236 % (branch, opts['rev'])) 1236 % (branch, opts.get('rev')))
1237 heads.extend(bheads) 1237 heads.extend(bheads)
1238 if not heads: 1238 if not heads:
1239 return 1 1239 return 1
1240 displayer = cmdutil.show_changeset(ui, repo, opts) 1240 displayer = cmdutil.show_changeset(ui, repo, opts)
1241 for n in heads: 1241 for n in heads:
1551 1551
1552 date = opts.get('date') 1552 date = opts.get('date')
1553 if date: 1553 if date:
1554 opts['date'] = util.parsedate(date) 1554 opts['date'] = util.parsedate(date)
1555 1555
1556 if opts.get('exact') or not opts['force']: 1556 if opts.get('exact') or not opts.get('force'):
1557 cmdutil.bail_if_changed(repo) 1557 cmdutil.bail_if_changed(repo)
1558 1558
1559 d = opts["base"] 1559 d = opts["base"]
1560 strip = opts["strip"] 1560 strip = opts["strip"]
1561 wlock = lock = None 1561 wlock = lock = None
1646 twice if the incoming is followed by a pull. 1646 twice if the incoming is followed by a pull.
1647 1647
1648 See pull for valid source format details. 1648 See pull for valid source format details.
1649 """ 1649 """
1650 limit = cmdutil.loglimit(opts) 1650 limit = cmdutil.loglimit(opts)
1651 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev']) 1651 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
1652 cmdutil.setremoteconfig(ui, opts) 1652 cmdutil.setremoteconfig(ui, opts)
1653 1653
1654 other = hg.repository(ui, source) 1654 other = hg.repository(ui, source)
1655 ui.status(_('comparing with %s\n') % util.hidepassword(source)) 1655 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1656 if revs: 1656 if revs:
1681 if not other.local(): 1681 if not other.local():
1682 # use the created uncompressed bundlerepo 1682 # use the created uncompressed bundlerepo
1683 other = bundlerepo.bundlerepository(ui, repo.root, fname) 1683 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1684 1684
1685 o = other.changelog.nodesbetween(incoming, revs)[0] 1685 o = other.changelog.nodesbetween(incoming, revs)[0]
1686 if opts['newest_first']: 1686 if opts.get('newest_first'):
1687 o.reverse() 1687 o.reverse()
1688 displayer = cmdutil.show_changeset(ui, other, opts) 1688 displayer = cmdutil.show_changeset(ui, other, opts)
1689 count = 0 1689 count = 0
1690 for n in o: 1690 for n in o:
1691 if count >= limit: 1691 if count >= limit:
1692 break 1692 break
1693 parents = [p for p in other.changelog.parents(n) if p != nullid] 1693 parents = [p for p in other.changelog.parents(n) if p != nullid]
1694 if opts['no_merges'] and len(parents) == 2: 1694 if opts.get('no_merges') and len(parents) == 2:
1695 continue 1695 continue
1696 count += 1 1696 count += 1
1697 displayer.show(changenode=n) 1697 displayer.show(changenode=n)
1698 finally: 1698 finally:
1699 if hasattr(other, 'close'): 1699 if hasattr(other, 'close'):
1732 If you want to feed the output of this command into the "xargs" 1732 If you want to feed the output of this command into the "xargs"
1733 command, use the "-0" option to both this command and "xargs". 1733 command, use the "-0" option to both this command and "xargs".
1734 This will avoid the problem of "xargs" treating single filenames 1734 This will avoid the problem of "xargs" treating single filenames
1735 that contain white space as multiple filenames. 1735 that contain white space as multiple filenames.
1736 """ 1736 """
1737 end = opts['print0'] and '\0' or '\n' 1737 end = opts.get('print0') and '\0' or '\n'
1738 rev = opts.get('rev') or None 1738 rev = opts.get('rev') or None
1739 1739
1740 ret = 1 1740 ret = 1
1741 m = cmdutil.match(repo, pats, opts, default='relglob') 1741 m = cmdutil.match(repo, pats, opts, default='relglob')
1742 m.bad = lambda x,y: False 1742 m.bad = lambda x,y: False
1743 for abs in repo[rev].walk(m): 1743 for abs in repo[rev].walk(m):
1744 if not rev and abs not in repo.dirstate: 1744 if not rev and abs not in repo.dirstate:
1745 continue 1745 continue
1746 if opts['fullpath']: 1746 if opts.get('fullpath'):
1747 ui.write(os.path.join(repo.root, abs), end) 1747 ui.write(os.path.join(repo.root, abs), end)
1748 else: 1748 else:
1749 ui.write(((pats and m.rel(abs)) or abs), end) 1749 ui.write(((pats and m.rel(abs)) or abs), end)
1750 ret = 0 1750 ret = 0
1751 1751
1785 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) 1785 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1786 1786
1787 limit = cmdutil.loglimit(opts) 1787 limit = cmdutil.loglimit(opts)
1788 count = 0 1788 count = 0
1789 1789
1790 if opts['copies'] and opts['rev']: 1790 if opts.get('copies') and opts.get('rev'):
1791 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1 1791 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
1792 else: 1792 else:
1793 endrev = len(repo) 1793 endrev = len(repo)
1794 rcache = {} 1794 rcache = {}
1795 ncache = {} 1795 ncache = {}
1796 def getrenamed(fn, rev): 1796 def getrenamed(fn, rev):
1825 1825
1826 df = False 1826 df = False
1827 if opts["date"]: 1827 if opts["date"]:
1828 df = util.matchdate(opts["date"]) 1828 df = util.matchdate(opts["date"])
1829 1829
1830 only_branches = opts['only_branch'] 1830 only_branches = opts.get('only_branch')
1831 1831
1832 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn) 1832 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1833 for st, rev, fns in changeiter: 1833 for st, rev, fns in changeiter:
1834 if st == 'add': 1834 if st == 'add':
1835 changenode = repo.changelog.node(rev) 1835 changenode = repo.changelog.node(rev)
1836 parents = [p for p in repo.changelog.parentrevs(rev) 1836 parents = [p for p in repo.changelog.parentrevs(rev)
1837 if p != nullrev] 1837 if p != nullrev]
1838 if opts['no_merges'] and len(parents) == 2: 1838 if opts.get('no_merges') and len(parents) == 2:
1839 continue 1839 continue
1840 if opts['only_merges'] and len(parents) != 2: 1840 if opts.get('only_merges') and len(parents) != 2:
1841 continue 1841 continue
1842 1842
1843 if only_branches: 1843 if only_branches:
1844 revbranch = get(rev)[5]['branch'] 1844 revbranch = get(rev)[5]['branch']
1845 if revbranch not in only_branches: 1845 if revbranch not in only_branches:
1848 if df: 1848 if df:
1849 changes = get(rev) 1849 changes = get(rev)
1850 if not df(changes[2][0]): 1850 if not df(changes[2][0]):
1851 continue 1851 continue
1852 1852
1853 if opts['keyword']: 1853 if opts.get('keyword'):
1854 changes = get(rev) 1854 changes = get(rev)
1855 miss = 0 1855 miss = 0
1856 for k in [kw.lower() for kw in opts['keyword']]: 1856 for k in [kw.lower() for kw in opts['keyword']]:
1857 if not (k in changes[1].lower() or 1857 if not (k in changes[1].lower() or
1858 k in changes[4].lower() or 1858 k in changes[4].lower() or
1956 1956
1957 See pull for valid destination format details. 1957 See pull for valid destination format details.
1958 """ 1958 """
1959 limit = cmdutil.loglimit(opts) 1959 limit = cmdutil.loglimit(opts)
1960 dest, revs, checkout = hg.parseurl( 1960 dest, revs, checkout = hg.parseurl(
1961 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) 1961 ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev'))
1962 cmdutil.setremoteconfig(ui, opts) 1962 cmdutil.setremoteconfig(ui, opts)
1963 if revs: 1963 if revs:
1964 revs = [repo.lookup(rev) for rev in revs] 1964 revs = [repo.lookup(rev) for rev in revs]
1965 1965
1966 other = hg.repository(ui, dest) 1966 other = hg.repository(ui, dest)
1967 ui.status(_('comparing with %s\n') % util.hidepassword(dest)) 1967 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1968 o = repo.findoutgoing(other, force=opts['force']) 1968 o = repo.findoutgoing(other, force=opts.get('force'))
1969 if not o: 1969 if not o:
1970 ui.status(_("no changes found\n")) 1970 ui.status(_("no changes found\n"))
1971 return 1 1971 return 1
1972 o = repo.changelog.nodesbetween(o, revs)[0] 1972 o = repo.changelog.nodesbetween(o, revs)[0]
1973 if opts['newest_first']: 1973 if opts.get('newest_first'):
1974 o.reverse() 1974 o.reverse()
1975 displayer = cmdutil.show_changeset(ui, repo, opts) 1975 displayer = cmdutil.show_changeset(ui, repo, opts)
1976 count = 0 1976 count = 0
1977 for n in o: 1977 for n in o:
1978 if count >= limit: 1978 if count >= limit:
1979 break 1979 break
1980 parents = [p for p in repo.changelog.parents(n) if p != nullid] 1980 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1981 if opts['no_merges'] and len(parents) == 2: 1981 if opts.get('no_merges') and len(parents) == 2:
1982 continue 1982 continue
1983 count += 1 1983 count += 1
1984 displayer.show(changenode=n) 1984 displayer.show(changenode=n)
1985 1985
1986 def parents(ui, repo, file_=None, **opts): 1986 def parents(ui, repo, file_=None, **opts):
2095 Host * 2095 Host *
2096 Compression yes 2096 Compression yes
2097 Alternatively specify "ssh -C" as your ssh command in your hgrc or 2097 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2098 with the --ssh command line option. 2098 with the --ssh command line option.
2099 """ 2099 """
2100 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev']) 2100 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
2101 cmdutil.setremoteconfig(ui, opts) 2101 cmdutil.setremoteconfig(ui, opts)
2102 2102
2103 other = hg.repository(ui, source) 2103 other = hg.repository(ui, source)
2104 ui.status(_('pulling from %s\n') % util.hidepassword(source)) 2104 ui.status(_('pulling from %s\n') % util.hidepassword(source))
2105 if revs: 2105 if revs:
2108 except NoCapability: 2108 except NoCapability:
2109 error = _("Other repository doesn't support revision lookup, " 2109 error = _("Other repository doesn't support revision lookup, "
2110 "so a rev cannot be specified.") 2110 "so a rev cannot be specified.")
2111 raise util.Abort(error) 2111 raise util.Abort(error)
2112 2112
2113 modheads = repo.pull(other, heads=revs, force=opts['force']) 2113 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2114 return postincoming(ui, repo, modheads, opts['update'], checkout) 2114 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2115 2115
2116 def push(ui, repo, dest=None, **opts): 2116 def push(ui, repo, dest=None, **opts):
2117 """push changes to the specified destination 2117 """push changes to the specified destination
2118 2118
2119 Push changes from the local repository to the given destination. 2119 Push changes from the local repository to the given destination.
2143 2143
2144 Pushing to http:// and https:// URLs is only possible, if this 2144 Pushing to http:// and https:// URLs is only possible, if this
2145 feature is explicitly enabled on the remote Mercurial server. 2145 feature is explicitly enabled on the remote Mercurial server.
2146 """ 2146 """
2147 dest, revs, checkout = hg.parseurl( 2147 dest, revs, checkout = hg.parseurl(
2148 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) 2148 ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev'))
2149 cmdutil.setremoteconfig(ui, opts) 2149 cmdutil.setremoteconfig(ui, opts)
2150 2150
2151 other = hg.repository(ui, dest) 2151 other = hg.repository(ui, dest)
2152 ui.status(_('pushing to %s\n') % util.hidepassword(dest)) 2152 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
2153 if revs: 2153 if revs:
2154 revs = [repo.lookup(rev) for rev in revs] 2154 revs = [repo.lookup(rev) for rev in revs]
2155 r = repo.push(other, opts['force'], revs=revs) 2155 r = repo.push(other, opts.get('force'), revs=revs)
2156 return r == 0 2156 return r == 0
2157 2157
2158 def rawcommit(ui, repo, *pats, **opts): 2158 def rawcommit(ui, repo, *pats, **opts):
2159 """raw commit interface (DEPRECATED) 2159 """raw commit interface (DEPRECATED)
2160 2160
2171 ui.warn(_("(the rawcommit command is deprecated)\n")) 2171 ui.warn(_("(the rawcommit command is deprecated)\n"))
2172 2172
2173 message = cmdutil.logmessage(opts) 2173 message = cmdutil.logmessage(opts)
2174 2174
2175 files = cmdutil.match(repo, pats, opts).files() 2175 files = cmdutil.match(repo, pats, opts).files()
2176 if opts['files']: 2176 if opts.get('files'):
2177 files += open(opts['files']).read().splitlines() 2177 files += open(opts['files']).read().splitlines()
2178 2178
2179 parents = [repo.lookup(p) for p in opts['parent']] 2179 parents = [repo.lookup(p) for p in opts['parent']]
2180 2180
2181 try: 2181 try:
2340 if opts["date"]: 2340 if opts["date"]:
2341 if opts["rev"]: 2341 if opts["rev"]:
2342 raise util.Abort(_("you can't specify a revision and a date")) 2342 raise util.Abort(_("you can't specify a revision and a date"))
2343 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"]) 2343 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2344 2344
2345 if not pats and not opts['all']: 2345 if not pats and not opts.get('all'):
2346 raise util.Abort(_('no files or directories specified; ' 2346 raise util.Abort(_('no files or directories specified; '
2347 'use --all to revert the whole repo')) 2347 'use --all to revert the whole repo'))
2348 2348
2349 parent, p2 = repo.dirstate.parents() 2349 parent, p2 = repo.dirstate.parents()
2350 if not opts['rev'] and p2 != nullid: 2350 if not opts.get('rev') and p2 != nullid:
2351 raise util.Abort(_('uncommitted merge - please provide a ' 2351 raise util.Abort(_('uncommitted merge - please provide a '
2352 'specific revision')) 2352 'specific revision'))
2353 ctx = repo[opts['rev']] 2353 ctx = repo[opts.get('rev')]
2354 node = ctx.node() 2354 node = ctx.node()
2355 mf = ctx.manifest() 2355 mf = ctx.manifest()
2356 if node == parent: 2356 if node == parent:
2357 pmf = mf 2357 pmf = mf
2358 else: 2358 else:
2430 for abs, (rel, exact) in util.sort(names.items()): 2430 for abs, (rel, exact) in util.sort(names.items()):
2431 mfentry = mf.get(abs) 2431 mfentry = mf.get(abs)
2432 target = repo.wjoin(abs) 2432 target = repo.wjoin(abs)
2433 def handle(xlist, dobackup): 2433 def handle(xlist, dobackup):
2434 xlist[0].append(abs) 2434 xlist[0].append(abs)
2435 if dobackup and not opts['no_backup'] and util.lexists(target): 2435 if dobackup and not opts.get('no_backup') and util.lexists(target):
2436 bakname = "%s.orig" % rel 2436 bakname = "%s.orig" % rel
2437 ui.note(_('saving current version of %s as %s\n') % 2437 ui.note(_('saving current version of %s as %s\n') %
2438 (rel, bakname)) 2438 (rel, bakname))
2439 if not opts.get('dry_run'): 2439 if not opts.get('dry_run'):
2440 util.copyfile(target, bakname) 2440 util.copyfile(target, bakname)
2651 = the previous added file was copied from here 2651 = the previous added file was copied from here
2652 """ 2652 """
2653 2653
2654 node1, node2 = cmdutil.revpair(repo, opts.get('rev')) 2654 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2655 cwd = (pats and repo.getcwd()) or '' 2655 cwd = (pats and repo.getcwd()) or ''
2656 end = opts['print0'] and '\0' or '\n' 2656 end = opts.get('print0') and '\0' or '\n'
2657 copy = {} 2657 copy = {}
2658 states = 'modified added removed deleted unknown ignored clean'.split() 2658 states = 'modified added removed deleted unknown ignored clean'.split()
2659 show = [k for k in states if opts[k]] 2659 show = [k for k in states if opts[k]]
2660 if opts['all']: 2660 if opts.get('all'):
2661 show += ui.quiet and (states[:4] + ['clean']) or states 2661 show += ui.quiet and (states[:4] + ['clean']) or states
2662 if not show: 2662 if not show:
2663 show = ui.quiet and states[:4] or states[:5] 2663 show = ui.quiet and states[:4] or states[:5]
2664 2664
2665 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts), 2665 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
2666 'ignored' in show, 'clean' in show, 'unknown' in show) 2666 'ignored' in show, 'clean' in show, 'unknown' in show)
2667 changestates = zip(states, 'MAR!?IC', stat) 2667 changestates = zip(states, 'MAR!?IC', stat)
2668 2668
2669 if (opts['all'] or opts['copies']) and not opts['no_status']: 2669 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
2670 ctxn = repo[nullid] 2670 ctxn = repo[nullid]
2671 ctx1 = repo[node1] 2671 ctx1 = repo[node1]
2672 ctx2 = repo[node2] 2672 ctx2 = repo[node2]
2673 added = stat[1] 2673 added = stat[1]
2674 if node2 is None: 2674 if node2 is None:
2681 copy[v] = k 2681 copy[v] = k
2682 2682
2683 for state, char, files in changestates: 2683 for state, char, files in changestates:
2684 if state in show: 2684 if state in show:
2685 format = "%s %%s%s" % (char, end) 2685 format = "%s %%s%s" % (char, end)
2686 if opts['no_status']: 2686 if opts.get('no_status'):
2687 format = "%%s%s" % end 2687 format = "%%s%s" % end
2688 2688
2689 for f in files: 2689 for f in files:
2690 ui.write(format % repo.pathto(f, cwd)) 2690 ui.write(format % repo.pathto(f, cwd))
2691 if f in copy: 2691 if f in copy:
2717 if len(names) != len(dict.fromkeys(names)): 2717 if len(names) != len(dict.fromkeys(names)):
2718 raise util.Abort(_('tag names must be unique')) 2718 raise util.Abort(_('tag names must be unique'))
2719 for n in names: 2719 for n in names:
2720 if n in ['tip', '.', 'null']: 2720 if n in ['tip', '.', 'null']:
2721 raise util.Abort(_('the name \'%s\' is reserved') % n) 2721 raise util.Abort(_('the name \'%s\' is reserved') % n)
2722 if opts['rev'] and opts['remove']: 2722 if opts.get('rev') and opts.get('remove'):
2723 raise util.Abort(_("--rev and --remove are incompatible")) 2723 raise util.Abort(_("--rev and --remove are incompatible"))
2724 if opts['rev']: 2724 if opts.get('rev'):
2725 rev_ = opts['rev'] 2725 rev_ = opts['rev']
2726 message = opts['message'] 2726 message = opts.get('message')
2727 if opts['remove']: 2727 if opts.get('remove'):
2728 expectedtype = opts['local'] and 'local' or 'global' 2728 expectedtype = opts.get('local') and 'local' or 'global'
2729 for n in names: 2729 for n in names:
2730 if not repo.tagtype(n): 2730 if not repo.tagtype(n):
2731 raise util.Abort(_('tag \'%s\' does not exist') % n) 2731 raise util.Abort(_('tag \'%s\' does not exist') % n)
2732 if repo.tagtype(n) != expectedtype: 2732 if repo.tagtype(n) != expectedtype:
2733 raise util.Abort(_('tag \'%s\' is not a %s tag') % 2733 raise util.Abort(_('tag \'%s\' is not a %s tag') %
2734 (n, expectedtype)) 2734 (n, expectedtype))
2735 rev_ = nullid 2735 rev_ = nullid
2736 if not message: 2736 if not message:
2737 message = _('Removed tag %s') % ', '.join(names) 2737 message = _('Removed tag %s') % ', '.join(names)
2738 elif not opts['force']: 2738 elif not opts.get('force'):
2739 for n in names: 2739 for n in names:
2740 if n in repo.tags(): 2740 if n in repo.tags():
2741 raise util.Abort(_('tag \'%s\' already exists ' 2741 raise util.Abort(_('tag \'%s\' already exists '
2742 '(use -f to force)') % n) 2742 '(use -f to force)') % n)
2743 if not rev_ and repo.dirstate.parents()[1] != nullid: 2743 if not rev_ and repo.dirstate.parents()[1] != nullid:
2751 2751
2752 date = opts.get('date') 2752 date = opts.get('date')
2753 if date: 2753 if date:
2754 date = util.parsedate(date) 2754 date = util.parsedate(date)
2755 2755
2756 repo.tag(names, r, message, opts['local'], opts['user'], date) 2756 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
2757 2757
2758 def tags(ui, repo): 2758 def tags(ui, repo):
2759 """list repository tags 2759 """list repository tags
2760 2760
2761 List the repository tags. 2761 List the repository tags.
2821 gen = changegroup.readbundle(f, fname) 2821 gen = changegroup.readbundle(f, fname)
2822 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname) 2822 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2823 finally: 2823 finally:
2824 del lock 2824 del lock
2825 2825
2826 return postincoming(ui, repo, modheads, opts['update'], None) 2826 return postincoming(ui, repo, modheads, opts.get('update'), None)
2827 2827
2828 def update(ui, repo, node=None, rev=None, clean=False, date=None): 2828 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2829 """update working directory 2829 """update working directory
2830 2830
2831 Update the repository's working directory to the specified revision, 2831 Update the repository's working directory to the specified revision,