##// END OF EJS Templates
debugancestor: make the index argument optional, defaulting to 00changelog.i
Bryan O'Sullivan -
r6178:81afdd01 default
parent child Browse files
Show More
@@ -1,3152 +1,3161
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
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 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import os, re, sys, urllib
10 import os, re, sys, urllib
11 import hg, util, revlog, bundlerepo, extensions
11 import hg, util, revlog, bundlerepo, extensions
12 import difflib, patch, time, help, mdiff, tempfile
12 import difflib, patch, time, help, mdiff, tempfile
13 import errno, version, socket
13 import errno, version, socket
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
15
15
16 # Commands start here, listed alphabetically
16 # Commands start here, listed alphabetically
17
17
18 def add(ui, repo, *pats, **opts):
18 def add(ui, repo, *pats, **opts):
19 """add the specified files on the next commit
19 """add the specified files on the next commit
20
20
21 Schedule files to be version controlled and added to the repository.
21 Schedule files to be version controlled and added to the repository.
22
22
23 The files will be added to the repository at the next commit. To
23 The files will be added to the repository at the next commit. To
24 undo an add before that, see hg revert.
24 undo an add before that, see hg revert.
25
25
26 If no names are given, add all files in the repository.
26 If no names are given, add all files in the repository.
27 """
27 """
28
28
29 rejected = None
29 rejected = None
30 exacts = {}
30 exacts = {}
31 names = []
31 names = []
32 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):
33 badmatch=util.always):
34 if exact:
34 if exact:
35 if ui.verbose:
35 if ui.verbose:
36 ui.status(_('adding %s\n') % rel)
36 ui.status(_('adding %s\n') % rel)
37 names.append(abs)
37 names.append(abs)
38 exacts[abs] = 1
38 exacts[abs] = 1
39 elif abs not in repo.dirstate:
39 elif abs not in repo.dirstate:
40 ui.status(_('adding %s\n') % rel)
40 ui.status(_('adding %s\n') % rel)
41 names.append(abs)
41 names.append(abs)
42 if not opts.get('dry_run'):
42 if not opts.get('dry_run'):
43 rejected = repo.add(names)
43 rejected = repo.add(names)
44 rejected = [p for p in rejected if p in exacts]
44 rejected = [p for p in rejected if p in exacts]
45 return rejected and 1 or 0
45 return rejected and 1 or 0
46
46
47 def addremove(ui, repo, *pats, **opts):
47 def addremove(ui, repo, *pats, **opts):
48 """add all new files, delete all missing files
48 """add all new files, delete all missing files
49
49
50 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.
51
51
52 New files are ignored if they match any of the patterns in .hgignore. As
52 New files are ignored if they match any of the patterns in .hgignore. As
53 with add, these changes take effect at the next commit.
53 with add, these changes take effect at the next commit.
54
54
55 Use the -s option to detect renamed files. With a parameter > 0,
55 Use the -s option to detect renamed files. With a parameter > 0,
56 this compares every removed file with every added file and records
56 this compares every removed file with every added file and records
57 those similar enough as renames. This option takes a percentage
57 those similar enough as renames. This option takes a percentage
58 between 0 (disabled) and 100 (files must be identical) as its
58 between 0 (disabled) and 100 (files must be identical) as its
59 parameter. Detecting renamed files this way can be expensive.
59 parameter. Detecting renamed files this way can be expensive.
60 """
60 """
61 try:
61 try:
62 sim = float(opts.get('similarity') or 0)
62 sim = float(opts.get('similarity') or 0)
63 except ValueError:
63 except ValueError:
64 raise util.Abort(_('similarity must be a number'))
64 raise util.Abort(_('similarity must be a number'))
65 if sim < 0 or sim > 100:
65 if sim < 0 or sim > 100:
66 raise util.Abort(_('similarity must be between 0 and 100'))
66 raise util.Abort(_('similarity must be between 0 and 100'))
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
68
68
69 def annotate(ui, repo, *pats, **opts):
69 def annotate(ui, repo, *pats, **opts):
70 """show changeset information per file line
70 """show changeset information per file line
71
71
72 List changes in files, showing the revision id responsible for each line
72 List changes in files, showing the revision id responsible for each line
73
73
74 This command is useful to discover who did a change or when a change took
74 This command is useful to discover who did a change or when a change took
75 place.
75 place.
76
76
77 Without the -a option, annotate will avoid processing files it
77 Without the -a option, annotate will avoid processing files it
78 detects as binary. With -a, annotate will generate an annotation
78 detects as binary. With -a, annotate will generate an annotation
79 anyway, probably with undesirable results.
79 anyway, probably with undesirable results.
80 """
80 """
81 datefunc = ui.quiet and util.shortdate or util.datestr
81 datefunc = ui.quiet and util.shortdate or util.datestr
82 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
82 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
83
83
84 if not pats:
84 if not pats:
85 raise util.Abort(_('at least one file name or pattern required'))
85 raise util.Abort(_('at least one file name or pattern required'))
86
86
87 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
87 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
88 ('number', lambda x: str(x[0].rev())),
88 ('number', lambda x: str(x[0].rev())),
89 ('changeset', lambda x: short(x[0].node())),
89 ('changeset', lambda x: short(x[0].node())),
90 ('date', getdate),
90 ('date', getdate),
91 ('follow', lambda x: x[0].path()),
91 ('follow', lambda x: x[0].path()),
92 ]
92 ]
93
93
94 if (not opts['user'] and not opts['changeset'] and not opts['date']
94 if (not opts['user'] and not opts['changeset'] and not opts['date']
95 and not opts['follow']):
95 and not opts['follow']):
96 opts['number'] = 1
96 opts['number'] = 1
97
97
98 linenumber = opts.get('line_number') is not None
98 linenumber = opts.get('line_number') is not None
99 if (linenumber and (not opts['changeset']) and (not opts['number'])):
99 if (linenumber and (not opts['changeset']) and (not opts['number'])):
100 raise util.Abort(_('at least one of -n/-c is required for -l'))
100 raise util.Abort(_('at least one of -n/-c is required for -l'))
101
101
102 funcmap = [func for op, func in opmap if opts.get(op)]
102 funcmap = [func for op, func in opmap if opts.get(op)]
103 if linenumber:
103 if linenumber:
104 lastfunc = funcmap[-1]
104 lastfunc = funcmap[-1]
105 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
105 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
106
106
107 ctx = repo.changectx(opts['rev'])
107 ctx = repo.changectx(opts['rev'])
108
108
109 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
109 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
110 node=ctx.node()):
110 node=ctx.node()):
111 fctx = ctx.filectx(abs)
111 fctx = ctx.filectx(abs)
112 if not opts['text'] and util.binary(fctx.data()):
112 if not opts['text'] and util.binary(fctx.data()):
113 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
113 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
114 continue
114 continue
115
115
116 lines = fctx.annotate(follow=opts.get('follow'),
116 lines = fctx.annotate(follow=opts.get('follow'),
117 linenumber=linenumber)
117 linenumber=linenumber)
118 pieces = []
118 pieces = []
119
119
120 for f in funcmap:
120 for f in funcmap:
121 l = [f(n) for n, dummy in lines]
121 l = [f(n) for n, dummy in lines]
122 if l:
122 if l:
123 m = max(map(len, l))
123 m = max(map(len, l))
124 pieces.append(["%*s" % (m, x) for x in l])
124 pieces.append(["%*s" % (m, x) for x in l])
125
125
126 if pieces:
126 if pieces:
127 for p, l in zip(zip(*pieces), lines):
127 for p, l in zip(zip(*pieces), lines):
128 ui.write("%s: %s" % (" ".join(p), l[1]))
128 ui.write("%s: %s" % (" ".join(p), l[1]))
129
129
130 def archive(ui, repo, dest, **opts):
130 def archive(ui, repo, dest, **opts):
131 '''create unversioned archive of a repository revision
131 '''create unversioned archive of a repository revision
132
132
133 By default, the revision used is the parent of the working
133 By default, the revision used is the parent of the working
134 directory; use "-r" to specify a different revision.
134 directory; use "-r" to specify a different revision.
135
135
136 To specify the type of archive to create, use "-t". Valid
136 To specify the type of archive to create, use "-t". Valid
137 types are:
137 types are:
138
138
139 "files" (default): a directory full of files
139 "files" (default): a directory full of files
140 "tar": tar archive, uncompressed
140 "tar": tar archive, uncompressed
141 "tbz2": tar archive, compressed using bzip2
141 "tbz2": tar archive, compressed using bzip2
142 "tgz": tar archive, compressed using gzip
142 "tgz": tar archive, compressed using gzip
143 "uzip": zip archive, uncompressed
143 "uzip": zip archive, uncompressed
144 "zip": zip archive, compressed using deflate
144 "zip": zip archive, compressed using deflate
145
145
146 The exact name of the destination archive or directory is given
146 The exact name of the destination archive or directory is given
147 using a format string; see "hg help export" for details.
147 using a format string; see "hg help export" for details.
148
148
149 Each member added to an archive file has a directory prefix
149 Each member added to an archive file has a directory prefix
150 prepended. Use "-p" to specify a format string for the prefix.
150 prepended. Use "-p" to specify a format string for the prefix.
151 The default is the basename of the archive, with suffixes removed.
151 The default is the basename of the archive, with suffixes removed.
152 '''
152 '''
153
153
154 ctx = repo.changectx(opts['rev'])
154 ctx = repo.changectx(opts['rev'])
155 if not ctx:
155 if not ctx:
156 raise util.Abort(_('repository has no revisions'))
156 raise util.Abort(_('repository has no revisions'))
157 node = ctx.node()
157 node = ctx.node()
158 dest = cmdutil.make_filename(repo, dest, node)
158 dest = cmdutil.make_filename(repo, dest, node)
159 if os.path.realpath(dest) == repo.root:
159 if os.path.realpath(dest) == repo.root:
160 raise util.Abort(_('repository root cannot be destination'))
160 raise util.Abort(_('repository root cannot be destination'))
161 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
161 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
162 kind = opts.get('type') or 'files'
162 kind = opts.get('type') or 'files'
163 prefix = opts['prefix']
163 prefix = opts['prefix']
164 if dest == '-':
164 if dest == '-':
165 if kind == 'files':
165 if kind == 'files':
166 raise util.Abort(_('cannot archive plain files to stdout'))
166 raise util.Abort(_('cannot archive plain files to stdout'))
167 dest = sys.stdout
167 dest = sys.stdout
168 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
168 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
169 prefix = cmdutil.make_filename(repo, prefix, node)
169 prefix = cmdutil.make_filename(repo, prefix, node)
170 archival.archive(repo, dest, node, kind, not opts['no_decode'],
170 archival.archive(repo, dest, node, kind, not opts['no_decode'],
171 matchfn, prefix)
171 matchfn, prefix)
172
172
173 def backout(ui, repo, node=None, rev=None, **opts):
173 def backout(ui, repo, node=None, rev=None, **opts):
174 '''reverse effect of earlier changeset
174 '''reverse effect of earlier changeset
175
175
176 Commit the backed out changes as a new changeset. The new
176 Commit the backed out changes as a new changeset. The new
177 changeset is a child of the backed out changeset.
177 changeset is a child of the backed out changeset.
178
178
179 If you back out a changeset other than the tip, a new head is
179 If you back out a changeset other than the tip, a new head is
180 created. This head will be the new tip and you should merge this
180 created. This head will be the new tip and you should merge this
181 backout changeset with another head (current one by default).
181 backout changeset with another head (current one by default).
182
182
183 The --merge option remembers the parent of the working directory
183 The --merge option remembers the parent of the working directory
184 before starting the backout, then merges the new head with that
184 before starting the backout, then merges the new head with that
185 changeset afterwards. This saves you from doing the merge by
185 changeset afterwards. This saves you from doing the merge by
186 hand. The result of this merge is not committed, as for a normal
186 hand. The result of this merge is not committed, as for a normal
187 merge.
187 merge.
188
188
189 See 'hg help dates' for a list of formats valid for -d/--date.
189 See 'hg help dates' for a list of formats valid for -d/--date.
190 '''
190 '''
191 if rev and node:
191 if rev and node:
192 raise util.Abort(_("please specify just one revision"))
192 raise util.Abort(_("please specify just one revision"))
193
193
194 if not rev:
194 if not rev:
195 rev = node
195 rev = node
196
196
197 if not rev:
197 if not rev:
198 raise util.Abort(_("please specify a revision to backout"))
198 raise util.Abort(_("please specify a revision to backout"))
199
199
200 date = opts.get('date')
200 date = opts.get('date')
201 if date:
201 if date:
202 opts['date'] = util.parsedate(date)
202 opts['date'] = util.parsedate(date)
203
203
204 cmdutil.bail_if_changed(repo)
204 cmdutil.bail_if_changed(repo)
205 node = repo.lookup(rev)
205 node = repo.lookup(rev)
206
206
207 op1, op2 = repo.dirstate.parents()
207 op1, op2 = repo.dirstate.parents()
208 a = repo.changelog.ancestor(op1, node)
208 a = repo.changelog.ancestor(op1, node)
209 if a != node:
209 if a != node:
210 raise util.Abort(_('cannot back out change on a different branch'))
210 raise util.Abort(_('cannot back out change on a different branch'))
211
211
212 p1, p2 = repo.changelog.parents(node)
212 p1, p2 = repo.changelog.parents(node)
213 if p1 == nullid:
213 if p1 == nullid:
214 raise util.Abort(_('cannot back out a change with no parents'))
214 raise util.Abort(_('cannot back out a change with no parents'))
215 if p2 != nullid:
215 if p2 != nullid:
216 if not opts['parent']:
216 if not opts['parent']:
217 raise util.Abort(_('cannot back out a merge changeset without '
217 raise util.Abort(_('cannot back out a merge changeset without '
218 '--parent'))
218 '--parent'))
219 p = repo.lookup(opts['parent'])
219 p = repo.lookup(opts['parent'])
220 if p not in (p1, p2):
220 if p not in (p1, p2):
221 raise util.Abort(_('%s is not a parent of %s') %
221 raise util.Abort(_('%s is not a parent of %s') %
222 (short(p), short(node)))
222 (short(p), short(node)))
223 parent = p
223 parent = p
224 else:
224 else:
225 if opts['parent']:
225 if opts['parent']:
226 raise util.Abort(_('cannot use --parent on non-merge changeset'))
226 raise util.Abort(_('cannot use --parent on non-merge changeset'))
227 parent = p1
227 parent = p1
228
228
229 hg.clean(repo, node, show_stats=False)
229 hg.clean(repo, node, show_stats=False)
230 revert_opts = opts.copy()
230 revert_opts = opts.copy()
231 revert_opts['date'] = None
231 revert_opts['date'] = None
232 revert_opts['all'] = True
232 revert_opts['all'] = True
233 revert_opts['rev'] = hex(parent)
233 revert_opts['rev'] = hex(parent)
234 revert_opts['no_backup'] = None
234 revert_opts['no_backup'] = None
235 revert(ui, repo, **revert_opts)
235 revert(ui, repo, **revert_opts)
236 commit_opts = opts.copy()
236 commit_opts = opts.copy()
237 commit_opts['addremove'] = False
237 commit_opts['addremove'] = False
238 if not commit_opts['message'] and not commit_opts['logfile']:
238 if not commit_opts['message'] and not commit_opts['logfile']:
239 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
239 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
240 commit_opts['force_editor'] = True
240 commit_opts['force_editor'] = True
241 commit(ui, repo, **commit_opts)
241 commit(ui, repo, **commit_opts)
242 def nice(node):
242 def nice(node):
243 return '%d:%s' % (repo.changelog.rev(node), short(node))
243 return '%d:%s' % (repo.changelog.rev(node), short(node))
244 ui.status(_('changeset %s backs out changeset %s\n') %
244 ui.status(_('changeset %s backs out changeset %s\n') %
245 (nice(repo.changelog.tip()), nice(node)))
245 (nice(repo.changelog.tip()), nice(node)))
246 if op1 != node:
246 if op1 != node:
247 hg.clean(repo, op1, show_stats=False)
247 hg.clean(repo, op1, show_stats=False)
248 if opts['merge']:
248 if opts['merge']:
249 ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
249 ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
250 hg.merge(repo, hex(repo.changelog.tip()))
250 hg.merge(repo, hex(repo.changelog.tip()))
251 else:
251 else:
252 ui.status(_('the backout changeset is a new head - '
252 ui.status(_('the backout changeset is a new head - '
253 'do not forget to merge\n'))
253 'do not forget to merge\n'))
254 ui.status(_('(use "backout --merge" '
254 ui.status(_('(use "backout --merge" '
255 'if you want to auto-merge)\n'))
255 'if you want to auto-merge)\n'))
256
256
257 def bisect(ui, repo, rev=None, extra=None,
257 def bisect(ui, repo, rev=None, extra=None,
258 reset=None, good=None, bad=None, skip=None, noupdate=None):
258 reset=None, good=None, bad=None, skip=None, noupdate=None):
259 """subdivision search of changesets
259 """subdivision search of changesets
260
260
261 This command helps to find changesets which introduce problems.
261 This command helps to find changesets which introduce problems.
262 To use, mark the earliest changeset you know exhibits the problem
262 To use, mark the earliest changeset you know exhibits the problem
263 as bad, then mark the latest changeset which is free from the
263 as bad, then mark the latest changeset which is free from the
264 problem as good. Bisect will update your working directory to a
264 problem as good. Bisect will update your working directory to a
265 revision for testing. Once you have performed tests, mark the
265 revision for testing. Once you have performed tests, mark the
266 working directory as bad or good and bisect will either update to
266 working directory as bad or good and bisect will either update to
267 another candidate changeset or announce that it has found the bad
267 another candidate changeset or announce that it has found the bad
268 revision.
268 revision.
269 """
269 """
270 # backward compatibility
270 # backward compatibility
271 if rev in "good bad reset init".split():
271 if rev in "good bad reset init".split():
272 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
272 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
273 cmd, rev, extra = rev, extra, None
273 cmd, rev, extra = rev, extra, None
274 if cmd == "good":
274 if cmd == "good":
275 good = True
275 good = True
276 elif cmd == "bad":
276 elif cmd == "bad":
277 bad = True
277 bad = True
278 else:
278 else:
279 reset = True
279 reset = True
280 elif extra or good + bad + skip + reset > 1:
280 elif extra or good + bad + skip + reset > 1:
281 raise util.Abort("Incompatible arguments")
281 raise util.Abort("Incompatible arguments")
282
282
283 if reset:
283 if reset:
284 p = repo.join("bisect.state")
284 p = repo.join("bisect.state")
285 if os.path.exists(p):
285 if os.path.exists(p):
286 os.unlink(p)
286 os.unlink(p)
287 return
287 return
288
288
289 # load state
289 # load state
290 state = {'good': [], 'bad': [], 'skip': []}
290 state = {'good': [], 'bad': [], 'skip': []}
291 if os.path.exists(repo.join("bisect.state")):
291 if os.path.exists(repo.join("bisect.state")):
292 for l in repo.opener("bisect.state"):
292 for l in repo.opener("bisect.state"):
293 kind, node = l[:-1].split()
293 kind, node = l[:-1].split()
294 node = repo.lookup(node)
294 node = repo.lookup(node)
295 if kind not in state:
295 if kind not in state:
296 raise util.Abort(_("unknown bisect kind %s") % kind)
296 raise util.Abort(_("unknown bisect kind %s") % kind)
297 state[kind].append(node)
297 state[kind].append(node)
298
298
299 # update state
299 # update state
300 node = repo.lookup(rev or '.')
300 node = repo.lookup(rev or '.')
301 if good:
301 if good:
302 state['good'].append(node)
302 state['good'].append(node)
303 elif bad:
303 elif bad:
304 state['bad'].append(node)
304 state['bad'].append(node)
305 elif skip:
305 elif skip:
306 state['skip'].append(node)
306 state['skip'].append(node)
307
307
308 # save state
308 # save state
309 f = repo.opener("bisect.state", "w", atomictemp=True)
309 f = repo.opener("bisect.state", "w", atomictemp=True)
310 wlock = repo.wlock()
310 wlock = repo.wlock()
311 try:
311 try:
312 for kind in state:
312 for kind in state:
313 for node in state[kind]:
313 for node in state[kind]:
314 f.write("%s %s\n" % (kind, hg.hex(node)))
314 f.write("%s %s\n" % (kind, hg.hex(node)))
315 f.rename()
315 f.rename()
316 finally:
316 finally:
317 del wlock
317 del wlock
318
318
319 if not state['good'] or not state['bad']:
319 if not state['good'] or not state['bad']:
320 return
320 return
321
321
322 # actually bisect
322 # actually bisect
323 node, changesets, good = hbisect.bisect(repo.changelog, state)
323 node, changesets, good = hbisect.bisect(repo.changelog, state)
324 if changesets == 0:
324 if changesets == 0:
325 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
325 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
326 displayer = cmdutil.show_changeset(ui, repo, {})
326 displayer = cmdutil.show_changeset(ui, repo, {})
327 displayer.show(changenode=node)
327 displayer.show(changenode=node)
328 elif node is not None:
328 elif node is not None:
329 # compute the approximate number of remaining tests
329 # compute the approximate number of remaining tests
330 tests, size = 0, 2
330 tests, size = 0, 2
331 while size <= changesets:
331 while size <= changesets:
332 tests, size = tests + 1, size * 2
332 tests, size = tests + 1, size * 2
333 rev = repo.changelog.rev(node)
333 rev = repo.changelog.rev(node)
334 ui.write(_("Testing changeset %s:%s "
334 ui.write(_("Testing changeset %s:%s "
335 "(%s changesets remaining, ~%s tests)\n")
335 "(%s changesets remaining, ~%s tests)\n")
336 % (rev, hg.short(node), changesets, tests))
336 % (rev, hg.short(node), changesets, tests))
337 if not noupdate:
337 if not noupdate:
338 cmdutil.bail_if_changed(repo)
338 cmdutil.bail_if_changed(repo)
339 return hg.clean(repo, node)
339 return hg.clean(repo, node)
340
340
341 def branch(ui, repo, label=None, **opts):
341 def branch(ui, repo, label=None, **opts):
342 """set or show the current branch name
342 """set or show the current branch name
343
343
344 With no argument, show the current branch name. With one argument,
344 With no argument, show the current branch name. With one argument,
345 set the working directory branch name (the branch does not exist in
345 set the working directory branch name (the branch does not exist in
346 the repository until the next commit).
346 the repository until the next commit).
347
347
348 Unless --force is specified, branch will not let you set a
348 Unless --force is specified, branch will not let you set a
349 branch name that shadows an existing branch.
349 branch name that shadows an existing branch.
350
350
351 Use the command 'hg update' to switch to an existing branch.
351 Use the command 'hg update' to switch to an existing branch.
352 """
352 """
353
353
354 if label:
354 if label:
355 if not opts.get('force') and label in repo.branchtags():
355 if not opts.get('force') and label in repo.branchtags():
356 if label not in [p.branch() for p in repo.workingctx().parents()]:
356 if label not in [p.branch() for p in repo.workingctx().parents()]:
357 raise util.Abort(_('a branch of the same name already exists'
357 raise util.Abort(_('a branch of the same name already exists'
358 ' (use --force to override)'))
358 ' (use --force to override)'))
359 repo.dirstate.setbranch(util.fromlocal(label))
359 repo.dirstate.setbranch(util.fromlocal(label))
360 ui.status(_('marked working directory as branch %s\n') % label)
360 ui.status(_('marked working directory as branch %s\n') % label)
361 else:
361 else:
362 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
362 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
363
363
364 def branches(ui, repo, active=False):
364 def branches(ui, repo, active=False):
365 """list repository named branches
365 """list repository named branches
366
366
367 List the repository's named branches, indicating which ones are
367 List the repository's named branches, indicating which ones are
368 inactive. If active is specified, only show active branches.
368 inactive. If active is specified, only show active branches.
369
369
370 A branch is considered active if it contains unmerged heads.
370 A branch is considered active if it contains unmerged heads.
371
371
372 Use the command 'hg update' to switch to an existing branch.
372 Use the command 'hg update' to switch to an existing branch.
373 """
373 """
374 b = repo.branchtags()
374 b = repo.branchtags()
375 heads = dict.fromkeys(repo.heads(), 1)
375 heads = dict.fromkeys(repo.heads(), 1)
376 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
376 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
377 l.sort()
377 l.sort()
378 l.reverse()
378 l.reverse()
379 for ishead, r, n, t in l:
379 for ishead, r, n, t in l:
380 if active and not ishead:
380 if active and not ishead:
381 # If we're only displaying active branches, abort the loop on
381 # If we're only displaying active branches, abort the loop on
382 # encountering the first inactive head
382 # encountering the first inactive head
383 break
383 break
384 else:
384 else:
385 hexfunc = ui.debugflag and hex or short
385 hexfunc = ui.debugflag and hex or short
386 if ui.quiet:
386 if ui.quiet:
387 ui.write("%s\n" % t)
387 ui.write("%s\n" % t)
388 else:
388 else:
389 spaces = " " * (30 - util.locallen(t))
389 spaces = " " * (30 - util.locallen(t))
390 # The code only gets here if inactive branches are being
390 # The code only gets here if inactive branches are being
391 # displayed or the branch is active.
391 # displayed or the branch is active.
392 isinactive = ((not ishead) and " (inactive)") or ''
392 isinactive = ((not ishead) and " (inactive)") or ''
393 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
393 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
394
394
395 def bundle(ui, repo, fname, dest=None, **opts):
395 def bundle(ui, repo, fname, dest=None, **opts):
396 """create a changegroup file
396 """create a changegroup file
397
397
398 Generate a compressed changegroup file collecting changesets not
398 Generate a compressed changegroup file collecting changesets not
399 found in the other repository.
399 found in the other repository.
400
400
401 If no destination repository is specified the destination is
401 If no destination repository is specified the destination is
402 assumed to have all the nodes specified by one or more --base
402 assumed to have all the nodes specified by one or more --base
403 parameters. To create a bundle containing all changesets, use
403 parameters. To create a bundle containing all changesets, use
404 --all (or --base null).
404 --all (or --base null).
405
405
406 The bundle file can then be transferred using conventional means and
406 The bundle file can then be transferred using conventional means and
407 applied to another repository with the unbundle or pull command.
407 applied to another repository with the unbundle or pull command.
408 This is useful when direct push and pull are not available or when
408 This is useful when direct push and pull are not available or when
409 exporting an entire repository is undesirable.
409 exporting an entire repository is undesirable.
410
410
411 Applying bundles preserves all changeset contents including
411 Applying bundles preserves all changeset contents including
412 permissions, copy/rename information, and revision history.
412 permissions, copy/rename information, and revision history.
413 """
413 """
414 revs = opts.get('rev') or None
414 revs = opts.get('rev') or None
415 if revs:
415 if revs:
416 revs = [repo.lookup(rev) for rev in revs]
416 revs = [repo.lookup(rev) for rev in revs]
417 if opts.get('all'):
417 if opts.get('all'):
418 base = ['null']
418 base = ['null']
419 else:
419 else:
420 base = opts.get('base')
420 base = opts.get('base')
421 if base:
421 if base:
422 if dest:
422 if dest:
423 raise util.Abort(_("--base is incompatible with specifiying "
423 raise util.Abort(_("--base is incompatible with specifiying "
424 "a destination"))
424 "a destination"))
425 base = [repo.lookup(rev) for rev in base]
425 base = [repo.lookup(rev) for rev in base]
426 # create the right base
426 # create the right base
427 # XXX: nodesbetween / changegroup* should be "fixed" instead
427 # XXX: nodesbetween / changegroup* should be "fixed" instead
428 o = []
428 o = []
429 has = {nullid: None}
429 has = {nullid: None}
430 for n in base:
430 for n in base:
431 has.update(repo.changelog.reachable(n))
431 has.update(repo.changelog.reachable(n))
432 if revs:
432 if revs:
433 visit = list(revs)
433 visit = list(revs)
434 else:
434 else:
435 visit = repo.changelog.heads()
435 visit = repo.changelog.heads()
436 seen = {}
436 seen = {}
437 while visit:
437 while visit:
438 n = visit.pop(0)
438 n = visit.pop(0)
439 parents = [p for p in repo.changelog.parents(n) if p not in has]
439 parents = [p for p in repo.changelog.parents(n) if p not in has]
440 if len(parents) == 0:
440 if len(parents) == 0:
441 o.insert(0, n)
441 o.insert(0, n)
442 else:
442 else:
443 for p in parents:
443 for p in parents:
444 if p not in seen:
444 if p not in seen:
445 seen[p] = 1
445 seen[p] = 1
446 visit.append(p)
446 visit.append(p)
447 else:
447 else:
448 cmdutil.setremoteconfig(ui, opts)
448 cmdutil.setremoteconfig(ui, opts)
449 dest, revs, checkout = hg.parseurl(
449 dest, revs, checkout = hg.parseurl(
450 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
450 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
451 other = hg.repository(ui, dest)
451 other = hg.repository(ui, dest)
452 o = repo.findoutgoing(other, force=opts['force'])
452 o = repo.findoutgoing(other, force=opts['force'])
453
453
454 if revs:
454 if revs:
455 cg = repo.changegroupsubset(o, revs, 'bundle')
455 cg = repo.changegroupsubset(o, revs, 'bundle')
456 else:
456 else:
457 cg = repo.changegroup(o, 'bundle')
457 cg = repo.changegroup(o, 'bundle')
458 changegroup.writebundle(cg, fname, "HG10BZ")
458 changegroup.writebundle(cg, fname, "HG10BZ")
459
459
460 def cat(ui, repo, file1, *pats, **opts):
460 def cat(ui, repo, file1, *pats, **opts):
461 """output the current or given revision of files
461 """output the current or given revision of files
462
462
463 Print the specified files as they were at the given revision.
463 Print the specified files as they were at the given revision.
464 If no revision is given, the parent of the working directory is used,
464 If no revision is given, the parent of the working directory is used,
465 or tip if no revision is checked out.
465 or tip if no revision is checked out.
466
466
467 Output may be to a file, in which case the name of the file is
467 Output may be to a file, in which case the name of the file is
468 given using a format string. The formatting rules are the same as
468 given using a format string. The formatting rules are the same as
469 for the export command, with the following additions:
469 for the export command, with the following additions:
470
470
471 %s basename of file being printed
471 %s basename of file being printed
472 %d dirname of file being printed, or '.' if in repo root
472 %d dirname of file being printed, or '.' if in repo root
473 %p root-relative path name of file being printed
473 %p root-relative path name of file being printed
474 """
474 """
475 ctx = repo.changectx(opts['rev'])
475 ctx = repo.changectx(opts['rev'])
476 err = 1
476 err = 1
477 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
477 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
478 ctx.node()):
478 ctx.node()):
479 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
479 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
480 data = ctx.filectx(abs).data()
480 data = ctx.filectx(abs).data()
481 if opts.get('decode'):
481 if opts.get('decode'):
482 data = repo.wwritedata(abs, data)
482 data = repo.wwritedata(abs, data)
483 fp.write(data)
483 fp.write(data)
484 err = 0
484 err = 0
485 return err
485 return err
486
486
487 def clone(ui, source, dest=None, **opts):
487 def clone(ui, source, dest=None, **opts):
488 """make a copy of an existing repository
488 """make a copy of an existing repository
489
489
490 Create a copy of an existing repository in a new directory.
490 Create a copy of an existing repository in a new directory.
491
491
492 If no destination directory name is specified, it defaults to the
492 If no destination directory name is specified, it defaults to the
493 basename of the source.
493 basename of the source.
494
494
495 The location of the source is added to the new repository's
495 The location of the source is added to the new repository's
496 .hg/hgrc file, as the default to be used for future pulls.
496 .hg/hgrc file, as the default to be used for future pulls.
497
497
498 For efficiency, hardlinks are used for cloning whenever the source
498 For efficiency, hardlinks are used for cloning whenever the source
499 and destination are on the same filesystem (note this applies only
499 and destination are on the same filesystem (note this applies only
500 to the repository data, not to the checked out files). Some
500 to the repository data, not to the checked out files). Some
501 filesystems, such as AFS, implement hardlinking incorrectly, but
501 filesystems, such as AFS, implement hardlinking incorrectly, but
502 do not report errors. In these cases, use the --pull option to
502 do not report errors. In these cases, use the --pull option to
503 avoid hardlinking.
503 avoid hardlinking.
504
504
505 You can safely clone repositories and checked out files using full
505 You can safely clone repositories and checked out files using full
506 hardlinks with
506 hardlinks with
507
507
508 $ cp -al REPO REPOCLONE
508 $ cp -al REPO REPOCLONE
509
509
510 which is the fastest way to clone. However, the operation is not
510 which is the fastest way to clone. However, the operation is not
511 atomic (making sure REPO is not modified during the operation is
511 atomic (making sure REPO is not modified during the operation is
512 up to you) and you have to make sure your editor breaks hardlinks
512 up to you) and you have to make sure your editor breaks hardlinks
513 (Emacs and most Linux Kernel tools do so).
513 (Emacs and most Linux Kernel tools do so).
514
514
515 If you use the -r option to clone up to a specific revision, no
515 If you use the -r option to clone up to a specific revision, no
516 subsequent revisions will be present in the cloned repository.
516 subsequent revisions will be present in the cloned repository.
517 This option implies --pull, even on local repositories.
517 This option implies --pull, even on local repositories.
518
518
519 See pull for valid source format details.
519 See pull for valid source format details.
520
520
521 It is possible to specify an ssh:// URL as the destination, but no
521 It is possible to specify an ssh:// URL as the destination, but no
522 .hg/hgrc and working directory will be created on the remote side.
522 .hg/hgrc and working directory will be created on the remote side.
523 Look at the help text for the pull command for important details
523 Look at the help text for the pull command for important details
524 about ssh:// URLs.
524 about ssh:// URLs.
525 """
525 """
526 cmdutil.setremoteconfig(ui, opts)
526 cmdutil.setremoteconfig(ui, opts)
527 hg.clone(ui, source, dest,
527 hg.clone(ui, source, dest,
528 pull=opts['pull'],
528 pull=opts['pull'],
529 stream=opts['uncompressed'],
529 stream=opts['uncompressed'],
530 rev=opts['rev'],
530 rev=opts['rev'],
531 update=not opts['noupdate'])
531 update=not opts['noupdate'])
532
532
533 def commit(ui, repo, *pats, **opts):
533 def commit(ui, repo, *pats, **opts):
534 """commit the specified files or all outstanding changes
534 """commit the specified files or all outstanding changes
535
535
536 Commit changes to the given files into the repository.
536 Commit changes to the given files into the repository.
537
537
538 If a list of files is omitted, all changes reported by "hg status"
538 If a list of files is omitted, all changes reported by "hg status"
539 will be committed.
539 will be committed.
540
540
541 If no commit message is specified, the configured editor is started to
541 If no commit message is specified, the configured editor is started to
542 enter a message.
542 enter a message.
543
543
544 See 'hg help dates' for a list of formats valid for -d/--date.
544 See 'hg help dates' for a list of formats valid for -d/--date.
545 """
545 """
546 def commitfunc(ui, repo, files, message, match, opts):
546 def commitfunc(ui, repo, files, message, match, opts):
547 return repo.commit(files, message, opts['user'], opts['date'], match,
547 return repo.commit(files, message, opts['user'], opts['date'], match,
548 force_editor=opts.get('force_editor'))
548 force_editor=opts.get('force_editor'))
549 cmdutil.commit(ui, repo, commitfunc, pats, opts)
549 cmdutil.commit(ui, repo, commitfunc, pats, opts)
550
550
551 def copy(ui, repo, *pats, **opts):
551 def copy(ui, repo, *pats, **opts):
552 """mark files as copied for the next commit
552 """mark files as copied for the next commit
553
553
554 Mark dest as having copies of source files. If dest is a
554 Mark dest as having copies of source files. If dest is a
555 directory, copies are put in that directory. If dest is a file,
555 directory, copies are put in that directory. If dest is a file,
556 there can only be one source.
556 there can only be one source.
557
557
558 By default, this command copies the contents of files as they
558 By default, this command copies the contents of files as they
559 stand in the working directory. If invoked with --after, the
559 stand in the working directory. If invoked with --after, the
560 operation is recorded, but no copying is performed.
560 operation is recorded, but no copying is performed.
561
561
562 This command takes effect in the next commit. To undo a copy
562 This command takes effect in the next commit. To undo a copy
563 before that, see hg revert.
563 before that, see hg revert.
564 """
564 """
565 wlock = repo.wlock(False)
565 wlock = repo.wlock(False)
566 try:
566 try:
567 return cmdutil.copy(ui, repo, pats, opts)
567 return cmdutil.copy(ui, repo, pats, opts)
568 finally:
568 finally:
569 del wlock
569 del wlock
570
570
571 def debugancestor(ui, index, rev1, rev2):
571 def debugancestor(ui, *opts):
572 """find the ancestor revision of two revisions in a given index"""
572 """find the ancestor revision of two revisions in a given index"""
573 if len(opts) == 3:
574 index, rev1, rev2 = opts
573 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
575 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
576 elif len(opts) == 2:
577 rev1, rev2 = opts
578 repo = hg.repository(ui)
579 r = repo.changelog
580 else:
581 raise util.Abort(_('either two or three arguments required'))
574 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
582 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
575 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
583 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
576
584
577 def debugcomplete(ui, cmd='', **opts):
585 def debugcomplete(ui, cmd='', **opts):
578 """returns the completion list associated with the given command"""
586 """returns the completion list associated with the given command"""
579
587
580 if opts['options']:
588 if opts['options']:
581 options = []
589 options = []
582 otables = [globalopts]
590 otables = [globalopts]
583 if cmd:
591 if cmd:
584 aliases, entry = cmdutil.findcmd(ui, cmd, table)
592 aliases, entry = cmdutil.findcmd(ui, cmd, table)
585 otables.append(entry[1])
593 otables.append(entry[1])
586 for t in otables:
594 for t in otables:
587 for o in t:
595 for o in t:
588 if o[0]:
596 if o[0]:
589 options.append('-%s' % o[0])
597 options.append('-%s' % o[0])
590 options.append('--%s' % o[1])
598 options.append('--%s' % o[1])
591 ui.write("%s\n" % "\n".join(options))
599 ui.write("%s\n" % "\n".join(options))
592 return
600 return
593
601
594 clist = cmdutil.findpossible(ui, cmd, table).keys()
602 clist = cmdutil.findpossible(ui, cmd, table).keys()
595 clist.sort()
603 clist.sort()
596 ui.write("%s\n" % "\n".join(clist))
604 ui.write("%s\n" % "\n".join(clist))
597
605
598 def debugfsinfo(ui, path = "."):
606 def debugfsinfo(ui, path = "."):
599 file('.debugfsinfo', 'w').write('')
607 file('.debugfsinfo', 'w').write('')
600 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
608 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
601 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
609 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
602 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
610 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
603 and 'yes' or 'no'))
611 and 'yes' or 'no'))
604 os.unlink('.debugfsinfo')
612 os.unlink('.debugfsinfo')
605
613
606 def debugrebuildstate(ui, repo, rev=""):
614 def debugrebuildstate(ui, repo, rev=""):
607 """rebuild the dirstate as it would look like for the given revision"""
615 """rebuild the dirstate as it would look like for the given revision"""
608 if rev == "":
616 if rev == "":
609 rev = repo.changelog.tip()
617 rev = repo.changelog.tip()
610 ctx = repo.changectx(rev)
618 ctx = repo.changectx(rev)
611 files = ctx.manifest()
619 files = ctx.manifest()
612 wlock = repo.wlock()
620 wlock = repo.wlock()
613 try:
621 try:
614 repo.dirstate.rebuild(rev, files)
622 repo.dirstate.rebuild(rev, files)
615 finally:
623 finally:
616 del wlock
624 del wlock
617
625
618 def debugcheckstate(ui, repo):
626 def debugcheckstate(ui, repo):
619 """validate the correctness of the current dirstate"""
627 """validate the correctness of the current dirstate"""
620 parent1, parent2 = repo.dirstate.parents()
628 parent1, parent2 = repo.dirstate.parents()
621 m1 = repo.changectx(parent1).manifest()
629 m1 = repo.changectx(parent1).manifest()
622 m2 = repo.changectx(parent2).manifest()
630 m2 = repo.changectx(parent2).manifest()
623 errors = 0
631 errors = 0
624 for f in repo.dirstate:
632 for f in repo.dirstate:
625 state = repo.dirstate[f]
633 state = repo.dirstate[f]
626 if state in "nr" and f not in m1:
634 if state in "nr" and f not in m1:
627 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
635 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
628 errors += 1
636 errors += 1
629 if state in "a" and f in m1:
637 if state in "a" and f in m1:
630 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
638 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
631 errors += 1
639 errors += 1
632 if state in "m" and f not in m1 and f not in m2:
640 if state in "m" and f not in m1 and f not in m2:
633 ui.warn(_("%s in state %s, but not in either manifest\n") %
641 ui.warn(_("%s in state %s, but not in either manifest\n") %
634 (f, state))
642 (f, state))
635 errors += 1
643 errors += 1
636 for f in m1:
644 for f in m1:
637 state = repo.dirstate[f]
645 state = repo.dirstate[f]
638 if state not in "nrm":
646 if state not in "nrm":
639 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
647 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
640 errors += 1
648 errors += 1
641 if errors:
649 if errors:
642 error = _(".hg/dirstate inconsistent with current parent's manifest")
650 error = _(".hg/dirstate inconsistent with current parent's manifest")
643 raise util.Abort(error)
651 raise util.Abort(error)
644
652
645 def showconfig(ui, repo, *values, **opts):
653 def showconfig(ui, repo, *values, **opts):
646 """show combined config settings from all hgrc files
654 """show combined config settings from all hgrc files
647
655
648 With no args, print names and values of all config items.
656 With no args, print names and values of all config items.
649
657
650 With one arg of the form section.name, print just the value of
658 With one arg of the form section.name, print just the value of
651 that config item.
659 that config item.
652
660
653 With multiple args, print names and values of all config items
661 With multiple args, print names and values of all config items
654 with matching section names."""
662 with matching section names."""
655
663
656 untrusted = bool(opts.get('untrusted'))
664 untrusted = bool(opts.get('untrusted'))
657 if values:
665 if values:
658 if len([v for v in values if '.' in v]) > 1:
666 if len([v for v in values if '.' in v]) > 1:
659 raise util.Abort(_('only one config item permitted'))
667 raise util.Abort(_('only one config item permitted'))
660 for section, name, value in ui.walkconfig(untrusted=untrusted):
668 for section, name, value in ui.walkconfig(untrusted=untrusted):
661 sectname = section + '.' + name
669 sectname = section + '.' + name
662 if values:
670 if values:
663 for v in values:
671 for v in values:
664 if v == section:
672 if v == section:
665 ui.write('%s=%s\n' % (sectname, value))
673 ui.write('%s=%s\n' % (sectname, value))
666 elif v == sectname:
674 elif v == sectname:
667 ui.write(value, '\n')
675 ui.write(value, '\n')
668 else:
676 else:
669 ui.write('%s=%s\n' % (sectname, value))
677 ui.write('%s=%s\n' % (sectname, value))
670
678
671 def debugsetparents(ui, repo, rev1, rev2=None):
679 def debugsetparents(ui, repo, rev1, rev2=None):
672 """manually set the parents of the current working directory
680 """manually set the parents of the current working directory
673
681
674 This is useful for writing repository conversion tools, but should
682 This is useful for writing repository conversion tools, but should
675 be used with care.
683 be used with care.
676 """
684 """
677
685
678 if not rev2:
686 if not rev2:
679 rev2 = hex(nullid)
687 rev2 = hex(nullid)
680
688
681 wlock = repo.wlock()
689 wlock = repo.wlock()
682 try:
690 try:
683 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
691 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
684 finally:
692 finally:
685 del wlock
693 del wlock
686
694
687 def debugstate(ui, repo):
695 def debugstate(ui, repo):
688 """show the contents of the current dirstate"""
696 """show the contents of the current dirstate"""
689 k = repo.dirstate._map.items()
697 k = repo.dirstate._map.items()
690 k.sort()
698 k.sort()
691 for file_, ent in k:
699 for file_, ent in k:
692 if ent[3] == -1:
700 if ent[3] == -1:
693 # Pad or slice to locale representation
701 # Pad or slice to locale representation
694 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
702 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
695 timestr = 'unset'
703 timestr = 'unset'
696 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
704 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
697 else:
705 else:
698 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
706 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
699 if ent[1] & 020000:
707 if ent[1] & 020000:
700 mode = 'lnk'
708 mode = 'lnk'
701 else:
709 else:
702 mode = '%3o' % (ent[1] & 0777)
710 mode = '%3o' % (ent[1] & 0777)
703 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
711 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
704 for f in repo.dirstate.copies():
712 for f in repo.dirstate.copies():
705 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
713 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
706
714
707 def debugdata(ui, file_, rev):
715 def debugdata(ui, file_, rev):
708 """dump the contents of a data file revision"""
716 """dump the contents of a data file revision"""
709 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
717 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
710 try:
718 try:
711 ui.write(r.revision(r.lookup(rev)))
719 ui.write(r.revision(r.lookup(rev)))
712 except KeyError:
720 except KeyError:
713 raise util.Abort(_('invalid revision identifier %s') % rev)
721 raise util.Abort(_('invalid revision identifier %s') % rev)
714
722
715 def debugdate(ui, date, range=None, **opts):
723 def debugdate(ui, date, range=None, **opts):
716 """parse and display a date"""
724 """parse and display a date"""
717 if opts["extended"]:
725 if opts["extended"]:
718 d = util.parsedate(date, util.extendeddateformats)
726 d = util.parsedate(date, util.extendeddateformats)
719 else:
727 else:
720 d = util.parsedate(date)
728 d = util.parsedate(date)
721 ui.write("internal: %s %s\n" % d)
729 ui.write("internal: %s %s\n" % d)
722 ui.write("standard: %s\n" % util.datestr(d))
730 ui.write("standard: %s\n" % util.datestr(d))
723 if range:
731 if range:
724 m = util.matchdate(range)
732 m = util.matchdate(range)
725 ui.write("match: %s\n" % m(d[0]))
733 ui.write("match: %s\n" % m(d[0]))
726
734
727 def debugindex(ui, file_):
735 def debugindex(ui, file_):
728 """dump the contents of an index file"""
736 """dump the contents of an index file"""
729 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
737 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
730 ui.write(" rev offset length base linkrev" +
738 ui.write(" rev offset length base linkrev" +
731 " nodeid p1 p2\n")
739 " nodeid p1 p2\n")
732 for i in xrange(r.count()):
740 for i in xrange(r.count()):
733 node = r.node(i)
741 node = r.node(i)
734 try:
742 try:
735 pp = r.parents(node)
743 pp = r.parents(node)
736 except:
744 except:
737 pp = [nullid, nullid]
745 pp = [nullid, nullid]
738 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
746 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
739 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
747 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
740 short(node), short(pp[0]), short(pp[1])))
748 short(node), short(pp[0]), short(pp[1])))
741
749
742 def debugindexdot(ui, file_):
750 def debugindexdot(ui, file_):
743 """dump an index DAG as a .dot file"""
751 """dump an index DAG as a .dot file"""
744 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
752 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
745 ui.write("digraph G {\n")
753 ui.write("digraph G {\n")
746 for i in xrange(r.count()):
754 for i in xrange(r.count()):
747 node = r.node(i)
755 node = r.node(i)
748 pp = r.parents(node)
756 pp = r.parents(node)
749 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
757 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
750 if pp[1] != nullid:
758 if pp[1] != nullid:
751 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
759 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
752 ui.write("}\n")
760 ui.write("}\n")
753
761
754 def debuginstall(ui):
762 def debuginstall(ui):
755 '''test Mercurial installation'''
763 '''test Mercurial installation'''
756
764
757 def writetemp(contents):
765 def writetemp(contents):
758 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
766 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
759 f = os.fdopen(fd, "wb")
767 f = os.fdopen(fd, "wb")
760 f.write(contents)
768 f.write(contents)
761 f.close()
769 f.close()
762 return name
770 return name
763
771
764 problems = 0
772 problems = 0
765
773
766 # encoding
774 # encoding
767 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
775 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
768 try:
776 try:
769 util.fromlocal("test")
777 util.fromlocal("test")
770 except util.Abort, inst:
778 except util.Abort, inst:
771 ui.write(" %s\n" % inst)
779 ui.write(" %s\n" % inst)
772 ui.write(_(" (check that your locale is properly set)\n"))
780 ui.write(_(" (check that your locale is properly set)\n"))
773 problems += 1
781 problems += 1
774
782
775 # compiled modules
783 # compiled modules
776 ui.status(_("Checking extensions...\n"))
784 ui.status(_("Checking extensions...\n"))
777 try:
785 try:
778 import bdiff, mpatch, base85
786 import bdiff, mpatch, base85
779 except Exception, inst:
787 except Exception, inst:
780 ui.write(" %s\n" % inst)
788 ui.write(" %s\n" % inst)
781 ui.write(_(" One or more extensions could not be found"))
789 ui.write(_(" One or more extensions could not be found"))
782 ui.write(_(" (check that you compiled the extensions)\n"))
790 ui.write(_(" (check that you compiled the extensions)\n"))
783 problems += 1
791 problems += 1
784
792
785 # templates
793 # templates
786 ui.status(_("Checking templates...\n"))
794 ui.status(_("Checking templates...\n"))
787 try:
795 try:
788 import templater
796 import templater
789 t = templater.templater(templater.templatepath("map-cmdline.default"))
797 t = templater.templater(templater.templatepath("map-cmdline.default"))
790 except Exception, inst:
798 except Exception, inst:
791 ui.write(" %s\n" % inst)
799 ui.write(" %s\n" % inst)
792 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
800 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
793 problems += 1
801 problems += 1
794
802
795 # patch
803 # patch
796 ui.status(_("Checking patch...\n"))
804 ui.status(_("Checking patch...\n"))
797 patchproblems = 0
805 patchproblems = 0
798 a = "1\n2\n3\n4\n"
806 a = "1\n2\n3\n4\n"
799 b = "1\n2\n3\ninsert\n4\n"
807 b = "1\n2\n3\ninsert\n4\n"
800 fa = writetemp(a)
808 fa = writetemp(a)
801 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
809 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
802 os.path.basename(fa))
810 os.path.basename(fa))
803 fd = writetemp(d)
811 fd = writetemp(d)
804
812
805 files = {}
813 files = {}
806 try:
814 try:
807 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
815 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
808 except util.Abort, e:
816 except util.Abort, e:
809 ui.write(_(" patch call failed:\n"))
817 ui.write(_(" patch call failed:\n"))
810 ui.write(" " + str(e) + "\n")
818 ui.write(" " + str(e) + "\n")
811 patchproblems += 1
819 patchproblems += 1
812 else:
820 else:
813 if list(files) != [os.path.basename(fa)]:
821 if list(files) != [os.path.basename(fa)]:
814 ui.write(_(" unexpected patch output!\n"))
822 ui.write(_(" unexpected patch output!\n"))
815 patchproblems += 1
823 patchproblems += 1
816 a = file(fa).read()
824 a = file(fa).read()
817 if a != b:
825 if a != b:
818 ui.write(_(" patch test failed!\n"))
826 ui.write(_(" patch test failed!\n"))
819 patchproblems += 1
827 patchproblems += 1
820
828
821 if patchproblems:
829 if patchproblems:
822 if ui.config('ui', 'patch'):
830 if ui.config('ui', 'patch'):
823 ui.write(_(" (Current patch tool may be incompatible with patch,"
831 ui.write(_(" (Current patch tool may be incompatible with patch,"
824 " or misconfigured. Please check your .hgrc file)\n"))
832 " or misconfigured. Please check your .hgrc file)\n"))
825 else:
833 else:
826 ui.write(_(" Internal patcher failure, please report this error"
834 ui.write(_(" Internal patcher failure, please report this error"
827 " to http://www.selenic.com/mercurial/bts\n"))
835 " to http://www.selenic.com/mercurial/bts\n"))
828 problems += patchproblems
836 problems += patchproblems
829
837
830 os.unlink(fa)
838 os.unlink(fa)
831 os.unlink(fd)
839 os.unlink(fd)
832
840
833 # editor
841 # editor
834 ui.status(_("Checking commit editor...\n"))
842 ui.status(_("Checking commit editor...\n"))
835 editor = ui.geteditor()
843 editor = ui.geteditor()
836 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
844 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
837 if not cmdpath:
845 if not cmdpath:
838 if editor == 'vi':
846 if editor == 'vi':
839 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
847 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
840 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
848 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
841 else:
849 else:
842 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
850 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
843 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
851 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
844 problems += 1
852 problems += 1
845
853
846 # check username
854 # check username
847 ui.status(_("Checking username...\n"))
855 ui.status(_("Checking username...\n"))
848 user = os.environ.get("HGUSER")
856 user = os.environ.get("HGUSER")
849 if user is None:
857 if user is None:
850 user = ui.config("ui", "username")
858 user = ui.config("ui", "username")
851 if user is None:
859 if user is None:
852 user = os.environ.get("EMAIL")
860 user = os.environ.get("EMAIL")
853 if not user:
861 if not user:
854 ui.warn(" ")
862 ui.warn(" ")
855 ui.username()
863 ui.username()
856 ui.write(_(" (specify a username in your .hgrc file)\n"))
864 ui.write(_(" (specify a username in your .hgrc file)\n"))
857
865
858 if not problems:
866 if not problems:
859 ui.status(_("No problems detected\n"))
867 ui.status(_("No problems detected\n"))
860 else:
868 else:
861 ui.write(_("%s problems detected,"
869 ui.write(_("%s problems detected,"
862 " please check your install!\n") % problems)
870 " please check your install!\n") % problems)
863
871
864 return problems
872 return problems
865
873
866 def debugrename(ui, repo, file1, *pats, **opts):
874 def debugrename(ui, repo, file1, *pats, **opts):
867 """dump rename information"""
875 """dump rename information"""
868
876
869 ctx = repo.changectx(opts.get('rev', 'tip'))
877 ctx = repo.changectx(opts.get('rev', 'tip'))
870 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
878 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
871 ctx.node()):
879 ctx.node()):
872 fctx = ctx.filectx(abs)
880 fctx = ctx.filectx(abs)
873 m = fctx.filelog().renamed(fctx.filenode())
881 m = fctx.filelog().renamed(fctx.filenode())
874 if m:
882 if m:
875 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
883 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
876 else:
884 else:
877 ui.write(_("%s not renamed\n") % rel)
885 ui.write(_("%s not renamed\n") % rel)
878
886
879 def debugwalk(ui, repo, *pats, **opts):
887 def debugwalk(ui, repo, *pats, **opts):
880 """show how files match on given patterns"""
888 """show how files match on given patterns"""
881 items = list(cmdutil.walk(repo, pats, opts))
889 items = list(cmdutil.walk(repo, pats, opts))
882 if not items:
890 if not items:
883 return
891 return
884 fmt = '%%s %%-%ds %%-%ds %%s' % (
892 fmt = '%%s %%-%ds %%-%ds %%s' % (
885 max([len(abs) for (src, abs, rel, exact) in items]),
893 max([len(abs) for (src, abs, rel, exact) in items]),
886 max([len(rel) for (src, abs, rel, exact) in items]))
894 max([len(rel) for (src, abs, rel, exact) in items]))
887 for src, abs, rel, exact in items:
895 for src, abs, rel, exact in items:
888 line = fmt % (src, abs, rel, exact and 'exact' or '')
896 line = fmt % (src, abs, rel, exact and 'exact' or '')
889 ui.write("%s\n" % line.rstrip())
897 ui.write("%s\n" % line.rstrip())
890
898
891 def diff(ui, repo, *pats, **opts):
899 def diff(ui, repo, *pats, **opts):
892 """diff repository (or selected files)
900 """diff repository (or selected files)
893
901
894 Show differences between revisions for the specified files.
902 Show differences between revisions for the specified files.
895
903
896 Differences between files are shown using the unified diff format.
904 Differences between files are shown using the unified diff format.
897
905
898 NOTE: diff may generate unexpected results for merges, as it will
906 NOTE: diff may generate unexpected results for merges, as it will
899 default to comparing against the working directory's first parent
907 default to comparing against the working directory's first parent
900 changeset if no revisions are specified.
908 changeset if no revisions are specified.
901
909
902 When two revision arguments are given, then changes are shown
910 When two revision arguments are given, then changes are shown
903 between those revisions. If only one revision is specified then
911 between those revisions. If only one revision is specified then
904 that revision is compared to the working directory, and, when no
912 that revision is compared to the working directory, and, when no
905 revisions are specified, the working directory files are compared
913 revisions are specified, the working directory files are compared
906 to its parent.
914 to its parent.
907
915
908 Without the -a option, diff will avoid generating diffs of files
916 Without the -a option, diff will avoid generating diffs of files
909 it detects as binary. With -a, diff will generate a diff anyway,
917 it detects as binary. With -a, diff will generate a diff anyway,
910 probably with undesirable results.
918 probably with undesirable results.
911 """
919 """
912 node1, node2 = cmdutil.revpair(repo, opts['rev'])
920 node1, node2 = cmdutil.revpair(repo, opts['rev'])
913
921
914 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
922 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
915
923
916 patch.diff(repo, node1, node2, fns, match=matchfn,
924 patch.diff(repo, node1, node2, fns, match=matchfn,
917 opts=patch.diffopts(ui, opts))
925 opts=patch.diffopts(ui, opts))
918
926
919 def export(ui, repo, *changesets, **opts):
927 def export(ui, repo, *changesets, **opts):
920 """dump the header and diffs for one or more changesets
928 """dump the header and diffs for one or more changesets
921
929
922 Print the changeset header and diffs for one or more revisions.
930 Print the changeset header and diffs for one or more revisions.
923
931
924 The information shown in the changeset header is: author,
932 The information shown in the changeset header is: author,
925 changeset hash, parent(s) and commit comment.
933 changeset hash, parent(s) and commit comment.
926
934
927 NOTE: export may generate unexpected diff output for merge changesets,
935 NOTE: export may generate unexpected diff output for merge changesets,
928 as it will compare the merge changeset against its first parent only.
936 as it will compare the merge changeset against its first parent only.
929
937
930 Output may be to a file, in which case the name of the file is
938 Output may be to a file, in which case the name of the file is
931 given using a format string. The formatting rules are as follows:
939 given using a format string. The formatting rules are as follows:
932
940
933 %% literal "%" character
941 %% literal "%" character
934 %H changeset hash (40 bytes of hexadecimal)
942 %H changeset hash (40 bytes of hexadecimal)
935 %N number of patches being generated
943 %N number of patches being generated
936 %R changeset revision number
944 %R changeset revision number
937 %b basename of the exporting repository
945 %b basename of the exporting repository
938 %h short-form changeset hash (12 bytes of hexadecimal)
946 %h short-form changeset hash (12 bytes of hexadecimal)
939 %n zero-padded sequence number, starting at 1
947 %n zero-padded sequence number, starting at 1
940 %r zero-padded changeset revision number
948 %r zero-padded changeset revision number
941
949
942 Without the -a option, export will avoid generating diffs of files
950 Without the -a option, export will avoid generating diffs of files
943 it detects as binary. With -a, export will generate a diff anyway,
951 it detects as binary. With -a, export will generate a diff anyway,
944 probably with undesirable results.
952 probably with undesirable results.
945
953
946 With the --switch-parent option, the diff will be against the second
954 With the --switch-parent option, the diff will be against the second
947 parent. It can be useful to review a merge.
955 parent. It can be useful to review a merge.
948 """
956 """
949 if not changesets:
957 if not changesets:
950 raise util.Abort(_("export requires at least one changeset"))
958 raise util.Abort(_("export requires at least one changeset"))
951 revs = cmdutil.revrange(repo, changesets)
959 revs = cmdutil.revrange(repo, changesets)
952 if len(revs) > 1:
960 if len(revs) > 1:
953 ui.note(_('exporting patches:\n'))
961 ui.note(_('exporting patches:\n'))
954 else:
962 else:
955 ui.note(_('exporting patch:\n'))
963 ui.note(_('exporting patch:\n'))
956 patch.export(repo, revs, template=opts['output'],
964 patch.export(repo, revs, template=opts['output'],
957 switch_parent=opts['switch_parent'],
965 switch_parent=opts['switch_parent'],
958 opts=patch.diffopts(ui, opts))
966 opts=patch.diffopts(ui, opts))
959
967
960 def grep(ui, repo, pattern, *pats, **opts):
968 def grep(ui, repo, pattern, *pats, **opts):
961 """search for a pattern in specified files and revisions
969 """search for a pattern in specified files and revisions
962
970
963 Search revisions of files for a regular expression.
971 Search revisions of files for a regular expression.
964
972
965 This command behaves differently than Unix grep. It only accepts
973 This command behaves differently than Unix grep. It only accepts
966 Python/Perl regexps. It searches repository history, not the
974 Python/Perl regexps. It searches repository history, not the
967 working directory. It always prints the revision number in which
975 working directory. It always prints the revision number in which
968 a match appears.
976 a match appears.
969
977
970 By default, grep only prints output for the first revision of a
978 By default, grep only prints output for the first revision of a
971 file in which it finds a match. To get it to print every revision
979 file in which it finds a match. To get it to print every revision
972 that contains a change in match status ("-" for a match that
980 that contains a change in match status ("-" for a match that
973 becomes a non-match, or "+" for a non-match that becomes a match),
981 becomes a non-match, or "+" for a non-match that becomes a match),
974 use the --all flag.
982 use the --all flag.
975 """
983 """
976 reflags = 0
984 reflags = 0
977 if opts['ignore_case']:
985 if opts['ignore_case']:
978 reflags |= re.I
986 reflags |= re.I
979 try:
987 try:
980 regexp = re.compile(pattern, reflags)
988 regexp = re.compile(pattern, reflags)
981 except Exception, inst:
989 except Exception, inst:
982 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
990 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
983 return None
991 return None
984 sep, eol = ':', '\n'
992 sep, eol = ':', '\n'
985 if opts['print0']:
993 if opts['print0']:
986 sep = eol = '\0'
994 sep = eol = '\0'
987
995
988 fcache = {}
996 fcache = {}
989 def getfile(fn):
997 def getfile(fn):
990 if fn not in fcache:
998 if fn not in fcache:
991 fcache[fn] = repo.file(fn)
999 fcache[fn] = repo.file(fn)
992 return fcache[fn]
1000 return fcache[fn]
993
1001
994 def matchlines(body):
1002 def matchlines(body):
995 begin = 0
1003 begin = 0
996 linenum = 0
1004 linenum = 0
997 while True:
1005 while True:
998 match = regexp.search(body, begin)
1006 match = regexp.search(body, begin)
999 if not match:
1007 if not match:
1000 break
1008 break
1001 mstart, mend = match.span()
1009 mstart, mend = match.span()
1002 linenum += body.count('\n', begin, mstart) + 1
1010 linenum += body.count('\n', begin, mstart) + 1
1003 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1011 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1004 lend = body.find('\n', mend)
1012 lend = body.find('\n', mend)
1005 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1013 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1006 begin = lend + 1
1014 begin = lend + 1
1007
1015
1008 class linestate(object):
1016 class linestate(object):
1009 def __init__(self, line, linenum, colstart, colend):
1017 def __init__(self, line, linenum, colstart, colend):
1010 self.line = line
1018 self.line = line
1011 self.linenum = linenum
1019 self.linenum = linenum
1012 self.colstart = colstart
1020 self.colstart = colstart
1013 self.colend = colend
1021 self.colend = colend
1014
1022
1015 def __eq__(self, other):
1023 def __eq__(self, other):
1016 return self.line == other.line
1024 return self.line == other.line
1017
1025
1018 matches = {}
1026 matches = {}
1019 copies = {}
1027 copies = {}
1020 def grepbody(fn, rev, body):
1028 def grepbody(fn, rev, body):
1021 matches[rev].setdefault(fn, [])
1029 matches[rev].setdefault(fn, [])
1022 m = matches[rev][fn]
1030 m = matches[rev][fn]
1023 for lnum, cstart, cend, line in matchlines(body):
1031 for lnum, cstart, cend, line in matchlines(body):
1024 s = linestate(line, lnum, cstart, cend)
1032 s = linestate(line, lnum, cstart, cend)
1025 m.append(s)
1033 m.append(s)
1026
1034
1027 def difflinestates(a, b):
1035 def difflinestates(a, b):
1028 sm = difflib.SequenceMatcher(None, a, b)
1036 sm = difflib.SequenceMatcher(None, a, b)
1029 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1037 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1030 if tag == 'insert':
1038 if tag == 'insert':
1031 for i in xrange(blo, bhi):
1039 for i in xrange(blo, bhi):
1032 yield ('+', b[i])
1040 yield ('+', b[i])
1033 elif tag == 'delete':
1041 elif tag == 'delete':
1034 for i in xrange(alo, ahi):
1042 for i in xrange(alo, ahi):
1035 yield ('-', a[i])
1043 yield ('-', a[i])
1036 elif tag == 'replace':
1044 elif tag == 'replace':
1037 for i in xrange(alo, ahi):
1045 for i in xrange(alo, ahi):
1038 yield ('-', a[i])
1046 yield ('-', a[i])
1039 for i in xrange(blo, bhi):
1047 for i in xrange(blo, bhi):
1040 yield ('+', b[i])
1048 yield ('+', b[i])
1041
1049
1042 prev = {}
1050 prev = {}
1043 def display(fn, rev, states, prevstates):
1051 def display(fn, rev, states, prevstates):
1044 datefunc = ui.quiet and util.shortdate or util.datestr
1052 datefunc = ui.quiet and util.shortdate or util.datestr
1045 found = False
1053 found = False
1046 filerevmatches = {}
1054 filerevmatches = {}
1047 r = prev.get(fn, -1)
1055 r = prev.get(fn, -1)
1048 if opts['all']:
1056 if opts['all']:
1049 iter = difflinestates(states, prevstates)
1057 iter = difflinestates(states, prevstates)
1050 else:
1058 else:
1051 iter = [('', l) for l in prevstates]
1059 iter = [('', l) for l in prevstates]
1052 for change, l in iter:
1060 for change, l in iter:
1053 cols = [fn, str(r)]
1061 cols = [fn, str(r)]
1054 if opts['line_number']:
1062 if opts['line_number']:
1055 cols.append(str(l.linenum))
1063 cols.append(str(l.linenum))
1056 if opts['all']:
1064 if opts['all']:
1057 cols.append(change)
1065 cols.append(change)
1058 if opts['user']:
1066 if opts['user']:
1059 cols.append(ui.shortuser(get(r)[1]))
1067 cols.append(ui.shortuser(get(r)[1]))
1060 if opts.get('date'):
1068 if opts.get('date'):
1061 cols.append(datefunc(get(r)[2]))
1069 cols.append(datefunc(get(r)[2]))
1062 if opts['files_with_matches']:
1070 if opts['files_with_matches']:
1063 c = (fn, r)
1071 c = (fn, r)
1064 if c in filerevmatches:
1072 if c in filerevmatches:
1065 continue
1073 continue
1066 filerevmatches[c] = 1
1074 filerevmatches[c] = 1
1067 else:
1075 else:
1068 cols.append(l.line)
1076 cols.append(l.line)
1069 ui.write(sep.join(cols), eol)
1077 ui.write(sep.join(cols), eol)
1070 found = True
1078 found = True
1071 return found
1079 return found
1072
1080
1073 fstate = {}
1081 fstate = {}
1074 skip = {}
1082 skip = {}
1075 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1083 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1076 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1084 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1077 found = False
1085 found = False
1078 follow = opts.get('follow')
1086 follow = opts.get('follow')
1079 for st, rev, fns in changeiter:
1087 for st, rev, fns in changeiter:
1080 if st == 'window':
1088 if st == 'window':
1081 matches.clear()
1089 matches.clear()
1082 elif st == 'add':
1090 elif st == 'add':
1083 ctx = repo.changectx(rev)
1091 ctx = repo.changectx(rev)
1084 matches[rev] = {}
1092 matches[rev] = {}
1085 for fn in fns:
1093 for fn in fns:
1086 if fn in skip:
1094 if fn in skip:
1087 continue
1095 continue
1088 try:
1096 try:
1089 grepbody(fn, rev, getfile(fn).read(ctx.filenode(fn)))
1097 grepbody(fn, rev, getfile(fn).read(ctx.filenode(fn)))
1090 fstate.setdefault(fn, [])
1098 fstate.setdefault(fn, [])
1091 if follow:
1099 if follow:
1092 copied = getfile(fn).renamed(ctx.filenode(fn))
1100 copied = getfile(fn).renamed(ctx.filenode(fn))
1093 if copied:
1101 if copied:
1094 copies.setdefault(rev, {})[fn] = copied[0]
1102 copies.setdefault(rev, {})[fn] = copied[0]
1095 except revlog.LookupError:
1103 except revlog.LookupError:
1096 pass
1104 pass
1097 elif st == 'iter':
1105 elif st == 'iter':
1098 states = matches[rev].items()
1106 states = matches[rev].items()
1099 states.sort()
1107 states.sort()
1100 for fn, m in states:
1108 for fn, m in states:
1101 copy = copies.get(rev, {}).get(fn)
1109 copy = copies.get(rev, {}).get(fn)
1102 if fn in skip:
1110 if fn in skip:
1103 if copy:
1111 if copy:
1104 skip[copy] = True
1112 skip[copy] = True
1105 continue
1113 continue
1106 if fn in prev or fstate[fn]:
1114 if fn in prev or fstate[fn]:
1107 r = display(fn, rev, m, fstate[fn])
1115 r = display(fn, rev, m, fstate[fn])
1108 found = found or r
1116 found = found or r
1109 if r and not opts['all']:
1117 if r and not opts['all']:
1110 skip[fn] = True
1118 skip[fn] = True
1111 if copy:
1119 if copy:
1112 skip[copy] = True
1120 skip[copy] = True
1113 fstate[fn] = m
1121 fstate[fn] = m
1114 if copy:
1122 if copy:
1115 fstate[copy] = m
1123 fstate[copy] = m
1116 prev[fn] = rev
1124 prev[fn] = rev
1117
1125
1118 fstate = fstate.items()
1126 fstate = fstate.items()
1119 fstate.sort()
1127 fstate.sort()
1120 for fn, state in fstate:
1128 for fn, state in fstate:
1121 if fn in skip:
1129 if fn in skip:
1122 continue
1130 continue
1123 if fn not in copies.get(prev[fn], {}):
1131 if fn not in copies.get(prev[fn], {}):
1124 found = display(fn, rev, {}, state) or found
1132 found = display(fn, rev, {}, state) or found
1125 return (not found and 1) or 0
1133 return (not found and 1) or 0
1126
1134
1127 def heads(ui, repo, *branchrevs, **opts):
1135 def heads(ui, repo, *branchrevs, **opts):
1128 """show current repository heads or show branch heads
1136 """show current repository heads or show branch heads
1129
1137
1130 With no arguments, show all repository head changesets.
1138 With no arguments, show all repository head changesets.
1131
1139
1132 If branch or revisions names are given this will show the heads of
1140 If branch or revisions names are given this will show the heads of
1133 the specified branches or the branches those revisions are tagged
1141 the specified branches or the branches those revisions are tagged
1134 with.
1142 with.
1135
1143
1136 Repository "heads" are changesets that don't have child
1144 Repository "heads" are changesets that don't have child
1137 changesets. They are where development generally takes place and
1145 changesets. They are where development generally takes place and
1138 are the usual targets for update and merge operations.
1146 are the usual targets for update and merge operations.
1139
1147
1140 Branch heads are changesets that have a given branch tag, but have
1148 Branch heads are changesets that have a given branch tag, but have
1141 no child changesets with that tag. They are usually where
1149 no child changesets with that tag. They are usually where
1142 development on the given branch takes place.
1150 development on the given branch takes place.
1143 """
1151 """
1144 if opts['rev']:
1152 if opts['rev']:
1145 start = repo.lookup(opts['rev'])
1153 start = repo.lookup(opts['rev'])
1146 else:
1154 else:
1147 start = None
1155 start = None
1148 if not branchrevs:
1156 if not branchrevs:
1149 # Assume we're looking repo-wide heads if no revs were specified.
1157 # Assume we're looking repo-wide heads if no revs were specified.
1150 heads = repo.heads(start)
1158 heads = repo.heads(start)
1151 else:
1159 else:
1152 heads = []
1160 heads = []
1153 visitedset = util.set()
1161 visitedset = util.set()
1154 for branchrev in branchrevs:
1162 for branchrev in branchrevs:
1155 branch = repo.changectx(branchrev).branch()
1163 branch = repo.changectx(branchrev).branch()
1156 if branch in visitedset:
1164 if branch in visitedset:
1157 continue
1165 continue
1158 visitedset.add(branch)
1166 visitedset.add(branch)
1159 bheads = repo.branchheads(branch, start)
1167 bheads = repo.branchheads(branch, start)
1160 if not bheads:
1168 if not bheads:
1161 if branch != branchrev:
1169 if branch != branchrev:
1162 ui.warn(_("no changes on branch %s containing %s are "
1170 ui.warn(_("no changes on branch %s containing %s are "
1163 "reachable from %s\n")
1171 "reachable from %s\n")
1164 % (branch, branchrev, opts['rev']))
1172 % (branch, branchrev, opts['rev']))
1165 else:
1173 else:
1166 ui.warn(_("no changes on branch %s are reachable from %s\n")
1174 ui.warn(_("no changes on branch %s are reachable from %s\n")
1167 % (branch, opts['rev']))
1175 % (branch, opts['rev']))
1168 heads.extend(bheads)
1176 heads.extend(bheads)
1169 if not heads:
1177 if not heads:
1170 return 1
1178 return 1
1171 displayer = cmdutil.show_changeset(ui, repo, opts)
1179 displayer = cmdutil.show_changeset(ui, repo, opts)
1172 for n in heads:
1180 for n in heads:
1173 displayer.show(changenode=n)
1181 displayer.show(changenode=n)
1174
1182
1175 def help_(ui, name=None, with_version=False):
1183 def help_(ui, name=None, with_version=False):
1176 """show help for a command, extension, or list of commands
1184 """show help for a command, extension, or list of commands
1177
1185
1178 With no arguments, print a list of commands and short help.
1186 With no arguments, print a list of commands and short help.
1179
1187
1180 Given a command name, print help for that command.
1188 Given a command name, print help for that command.
1181
1189
1182 Given an extension name, print help for that extension, and the
1190 Given an extension name, print help for that extension, and the
1183 commands it provides."""
1191 commands it provides."""
1184 option_lists = []
1192 option_lists = []
1185
1193
1186 def addglobalopts(aliases):
1194 def addglobalopts(aliases):
1187 if ui.verbose:
1195 if ui.verbose:
1188 option_lists.append((_("global options:"), globalopts))
1196 option_lists.append((_("global options:"), globalopts))
1189 if name == 'shortlist':
1197 if name == 'shortlist':
1190 option_lists.append((_('use "hg help" for the full list '
1198 option_lists.append((_('use "hg help" for the full list '
1191 'of commands'), ()))
1199 'of commands'), ()))
1192 else:
1200 else:
1193 if name == 'shortlist':
1201 if name == 'shortlist':
1194 msg = _('use "hg help" for the full list of commands '
1202 msg = _('use "hg help" for the full list of commands '
1195 'or "hg -v" for details')
1203 'or "hg -v" for details')
1196 elif aliases:
1204 elif aliases:
1197 msg = _('use "hg -v help%s" to show aliases and '
1205 msg = _('use "hg -v help%s" to show aliases and '
1198 'global options') % (name and " " + name or "")
1206 'global options') % (name and " " + name or "")
1199 else:
1207 else:
1200 msg = _('use "hg -v help %s" to show global options') % name
1208 msg = _('use "hg -v help %s" to show global options') % name
1201 option_lists.append((msg, ()))
1209 option_lists.append((msg, ()))
1202
1210
1203 def helpcmd(name):
1211 def helpcmd(name):
1204 if with_version:
1212 if with_version:
1205 version_(ui)
1213 version_(ui)
1206 ui.write('\n')
1214 ui.write('\n')
1207 aliases, i = cmdutil.findcmd(ui, name, table)
1215 aliases, i = cmdutil.findcmd(ui, name, table)
1208 # synopsis
1216 # synopsis
1209 ui.write("%s\n" % i[2])
1217 ui.write("%s\n" % i[2])
1210
1218
1211 # aliases
1219 # aliases
1212 if not ui.quiet and len(aliases) > 1:
1220 if not ui.quiet and len(aliases) > 1:
1213 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1221 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1214
1222
1215 # description
1223 # description
1216 doc = i[0].__doc__
1224 doc = i[0].__doc__
1217 if not doc:
1225 if not doc:
1218 doc = _("(No help text available)")
1226 doc = _("(No help text available)")
1219 if ui.quiet:
1227 if ui.quiet:
1220 doc = doc.splitlines(0)[0]
1228 doc = doc.splitlines(0)[0]
1221 ui.write("\n%s\n" % doc.rstrip())
1229 ui.write("\n%s\n" % doc.rstrip())
1222
1230
1223 if not ui.quiet:
1231 if not ui.quiet:
1224 # options
1232 # options
1225 if i[1]:
1233 if i[1]:
1226 option_lists.append((_("options:\n"), i[1]))
1234 option_lists.append((_("options:\n"), i[1]))
1227
1235
1228 addglobalopts(False)
1236 addglobalopts(False)
1229
1237
1230 def helplist(header, select=None):
1238 def helplist(header, select=None):
1231 h = {}
1239 h = {}
1232 cmds = {}
1240 cmds = {}
1233 for c, e in table.items():
1241 for c, e in table.items():
1234 f = c.split("|", 1)[0]
1242 f = c.split("|", 1)[0]
1235 if select and not select(f):
1243 if select and not select(f):
1236 continue
1244 continue
1237 if name == "shortlist" and not f.startswith("^"):
1245 if name == "shortlist" and not f.startswith("^"):
1238 continue
1246 continue
1239 f = f.lstrip("^")
1247 f = f.lstrip("^")
1240 if not ui.debugflag and f.startswith("debug"):
1248 if not ui.debugflag and f.startswith("debug"):
1241 continue
1249 continue
1242 doc = e[0].__doc__
1250 doc = e[0].__doc__
1243 if not doc:
1251 if not doc:
1244 doc = _("(No help text available)")
1252 doc = _("(No help text available)")
1245 h[f] = doc.splitlines(0)[0].rstrip()
1253 h[f] = doc.splitlines(0)[0].rstrip()
1246 cmds[f] = c.lstrip("^")
1254 cmds[f] = c.lstrip("^")
1247
1255
1248 if not h:
1256 if not h:
1249 ui.status(_('no commands defined\n'))
1257 ui.status(_('no commands defined\n'))
1250 return
1258 return
1251
1259
1252 ui.status(header)
1260 ui.status(header)
1253 fns = h.keys()
1261 fns = h.keys()
1254 fns.sort()
1262 fns.sort()
1255 m = max(map(len, fns))
1263 m = max(map(len, fns))
1256 for f in fns:
1264 for f in fns:
1257 if ui.verbose:
1265 if ui.verbose:
1258 commands = cmds[f].replace("|",", ")
1266 commands = cmds[f].replace("|",", ")
1259 ui.write(" %s:\n %s\n"%(commands, h[f]))
1267 ui.write(" %s:\n %s\n"%(commands, h[f]))
1260 else:
1268 else:
1261 ui.write(' %-*s %s\n' % (m, f, h[f]))
1269 ui.write(' %-*s %s\n' % (m, f, h[f]))
1262
1270
1263 if not ui.quiet:
1271 if not ui.quiet:
1264 addglobalopts(True)
1272 addglobalopts(True)
1265
1273
1266 def helptopic(name):
1274 def helptopic(name):
1267 v = None
1275 v = None
1268 for i in help.helptable:
1276 for i in help.helptable:
1269 l = i.split('|')
1277 l = i.split('|')
1270 if name in l:
1278 if name in l:
1271 v = i
1279 v = i
1272 header = l[-1]
1280 header = l[-1]
1273 if not v:
1281 if not v:
1274 raise cmdutil.UnknownCommand(name)
1282 raise cmdutil.UnknownCommand(name)
1275
1283
1276 # description
1284 # description
1277 doc = help.helptable[v]
1285 doc = help.helptable[v]
1278 if not doc:
1286 if not doc:
1279 doc = _("(No help text available)")
1287 doc = _("(No help text available)")
1280 if callable(doc):
1288 if callable(doc):
1281 doc = doc()
1289 doc = doc()
1282
1290
1283 ui.write("%s\n" % header)
1291 ui.write("%s\n" % header)
1284 ui.write("%s\n" % doc.rstrip())
1292 ui.write("%s\n" % doc.rstrip())
1285
1293
1286 def helpext(name):
1294 def helpext(name):
1287 try:
1295 try:
1288 mod = extensions.find(name)
1296 mod = extensions.find(name)
1289 except KeyError:
1297 except KeyError:
1290 raise cmdutil.UnknownCommand(name)
1298 raise cmdutil.UnknownCommand(name)
1291
1299
1292 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1300 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1293 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1301 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1294 for d in doc[1:]:
1302 for d in doc[1:]:
1295 ui.write(d, '\n')
1303 ui.write(d, '\n')
1296
1304
1297 ui.status('\n')
1305 ui.status('\n')
1298
1306
1299 try:
1307 try:
1300 ct = mod.cmdtable
1308 ct = mod.cmdtable
1301 except AttributeError:
1309 except AttributeError:
1302 ct = {}
1310 ct = {}
1303
1311
1304 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1312 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1305 helplist(_('list of commands:\n\n'), modcmds.has_key)
1313 helplist(_('list of commands:\n\n'), modcmds.has_key)
1306
1314
1307 if name and name != 'shortlist':
1315 if name and name != 'shortlist':
1308 i = None
1316 i = None
1309 for f in (helpcmd, helptopic, helpext):
1317 for f in (helpcmd, helptopic, helpext):
1310 try:
1318 try:
1311 f(name)
1319 f(name)
1312 i = None
1320 i = None
1313 break
1321 break
1314 except cmdutil.UnknownCommand, inst:
1322 except cmdutil.UnknownCommand, inst:
1315 i = inst
1323 i = inst
1316 if i:
1324 if i:
1317 raise i
1325 raise i
1318
1326
1319 else:
1327 else:
1320 # program name
1328 # program name
1321 if ui.verbose or with_version:
1329 if ui.verbose or with_version:
1322 version_(ui)
1330 version_(ui)
1323 else:
1331 else:
1324 ui.status(_("Mercurial Distributed SCM\n"))
1332 ui.status(_("Mercurial Distributed SCM\n"))
1325 ui.status('\n')
1333 ui.status('\n')
1326
1334
1327 # list of commands
1335 # list of commands
1328 if name == "shortlist":
1336 if name == "shortlist":
1329 header = _('basic commands:\n\n')
1337 header = _('basic commands:\n\n')
1330 else:
1338 else:
1331 header = _('list of commands:\n\n')
1339 header = _('list of commands:\n\n')
1332
1340
1333 helplist(header)
1341 helplist(header)
1334
1342
1335 # list all option lists
1343 # list all option lists
1336 opt_output = []
1344 opt_output = []
1337 for title, options in option_lists:
1345 for title, options in option_lists:
1338 opt_output.append(("\n%s" % title, None))
1346 opt_output.append(("\n%s" % title, None))
1339 for shortopt, longopt, default, desc in options:
1347 for shortopt, longopt, default, desc in options:
1340 if "DEPRECATED" in desc and not ui.verbose: continue
1348 if "DEPRECATED" in desc and not ui.verbose: continue
1341 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1349 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1342 longopt and " --%s" % longopt),
1350 longopt and " --%s" % longopt),
1343 "%s%s" % (desc,
1351 "%s%s" % (desc,
1344 default
1352 default
1345 and _(" (default: %s)") % default
1353 and _(" (default: %s)") % default
1346 or "")))
1354 or "")))
1347
1355
1348 if opt_output:
1356 if opt_output:
1349 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1357 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1350 for first, second in opt_output:
1358 for first, second in opt_output:
1351 if second:
1359 if second:
1352 ui.write(" %-*s %s\n" % (opts_len, first, second))
1360 ui.write(" %-*s %s\n" % (opts_len, first, second))
1353 else:
1361 else:
1354 ui.write("%s\n" % first)
1362 ui.write("%s\n" % first)
1355
1363
1356 def identify(ui, repo, source=None,
1364 def identify(ui, repo, source=None,
1357 rev=None, num=None, id=None, branch=None, tags=None):
1365 rev=None, num=None, id=None, branch=None, tags=None):
1358 """identify the working copy or specified revision
1366 """identify the working copy or specified revision
1359
1367
1360 With no revision, print a summary of the current state of the repo.
1368 With no revision, print a summary of the current state of the repo.
1361
1369
1362 With a path, do a lookup in another repository.
1370 With a path, do a lookup in another repository.
1363
1371
1364 This summary identifies the repository state using one or two parent
1372 This summary identifies the repository state using one or two parent
1365 hash identifiers, followed by a "+" if there are uncommitted changes
1373 hash identifiers, followed by a "+" if there are uncommitted changes
1366 in the working directory, a list of tags for this revision and a branch
1374 in the working directory, a list of tags for this revision and a branch
1367 name for non-default branches.
1375 name for non-default branches.
1368 """
1376 """
1369
1377
1370 if not repo and not source:
1378 if not repo and not source:
1371 raise util.Abort(_("There is no Mercurial repository here "
1379 raise util.Abort(_("There is no Mercurial repository here "
1372 "(.hg not found)"))
1380 "(.hg not found)"))
1373
1381
1374 hexfunc = ui.debugflag and hex or short
1382 hexfunc = ui.debugflag and hex or short
1375 default = not (num or id or branch or tags)
1383 default = not (num or id or branch or tags)
1376 output = []
1384 output = []
1377
1385
1378 if source:
1386 if source:
1379 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1387 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1380 srepo = hg.repository(ui, source)
1388 srepo = hg.repository(ui, source)
1381 if not rev and revs:
1389 if not rev and revs:
1382 rev = revs[0]
1390 rev = revs[0]
1383 if not rev:
1391 if not rev:
1384 rev = "tip"
1392 rev = "tip"
1385 if num or branch or tags:
1393 if num or branch or tags:
1386 raise util.Abort(
1394 raise util.Abort(
1387 "can't query remote revision number, branch, or tags")
1395 "can't query remote revision number, branch, or tags")
1388 output = [hexfunc(srepo.lookup(rev))]
1396 output = [hexfunc(srepo.lookup(rev))]
1389 elif not rev:
1397 elif not rev:
1390 ctx = repo.workingctx()
1398 ctx = repo.workingctx()
1391 parents = ctx.parents()
1399 parents = ctx.parents()
1392 changed = False
1400 changed = False
1393 if default or id or num:
1401 if default or id or num:
1394 changed = ctx.files() + ctx.deleted()
1402 changed = ctx.files() + ctx.deleted()
1395 if default or id:
1403 if default or id:
1396 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1404 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1397 (changed) and "+" or "")]
1405 (changed) and "+" or "")]
1398 if num:
1406 if num:
1399 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1407 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1400 (changed) and "+" or ""))
1408 (changed) and "+" or ""))
1401 else:
1409 else:
1402 ctx = repo.changectx(rev)
1410 ctx = repo.changectx(rev)
1403 if default or id:
1411 if default or id:
1404 output = [hexfunc(ctx.node())]
1412 output = [hexfunc(ctx.node())]
1405 if num:
1413 if num:
1406 output.append(str(ctx.rev()))
1414 output.append(str(ctx.rev()))
1407
1415
1408 if not source and default and not ui.quiet:
1416 if not source and default and not ui.quiet:
1409 b = util.tolocal(ctx.branch())
1417 b = util.tolocal(ctx.branch())
1410 if b != 'default':
1418 if b != 'default':
1411 output.append("(%s)" % b)
1419 output.append("(%s)" % b)
1412
1420
1413 # multiple tags for a single parent separated by '/'
1421 # multiple tags for a single parent separated by '/'
1414 t = "/".join(ctx.tags())
1422 t = "/".join(ctx.tags())
1415 if t:
1423 if t:
1416 output.append(t)
1424 output.append(t)
1417
1425
1418 if branch:
1426 if branch:
1419 output.append(util.tolocal(ctx.branch()))
1427 output.append(util.tolocal(ctx.branch()))
1420
1428
1421 if tags:
1429 if tags:
1422 output.extend(ctx.tags())
1430 output.extend(ctx.tags())
1423
1431
1424 ui.write("%s\n" % ' '.join(output))
1432 ui.write("%s\n" % ' '.join(output))
1425
1433
1426 def import_(ui, repo, patch1, *patches, **opts):
1434 def import_(ui, repo, patch1, *patches, **opts):
1427 """import an ordered set of patches
1435 """import an ordered set of patches
1428
1436
1429 Import a list of patches and commit them individually.
1437 Import a list of patches and commit them individually.
1430
1438
1431 If there are outstanding changes in the working directory, import
1439 If there are outstanding changes in the working directory, import
1432 will abort unless given the -f flag.
1440 will abort unless given the -f flag.
1433
1441
1434 You can import a patch straight from a mail message. Even patches
1442 You can import a patch straight from a mail message. Even patches
1435 as attachments work (body part must be type text/plain or
1443 as attachments work (body part must be type text/plain or
1436 text/x-patch to be used). From and Subject headers of email
1444 text/x-patch to be used). From and Subject headers of email
1437 message are used as default committer and commit message. All
1445 message are used as default committer and commit message. All
1438 text/plain body parts before first diff are added to commit
1446 text/plain body parts before first diff are added to commit
1439 message.
1447 message.
1440
1448
1441 If the imported patch was generated by hg export, user and description
1449 If the imported patch was generated by hg export, user and description
1442 from patch override values from message headers and body. Values
1450 from patch override values from message headers and body. Values
1443 given on command line with -m and -u override these.
1451 given on command line with -m and -u override these.
1444
1452
1445 If --exact is specified, import will set the working directory
1453 If --exact is specified, import will set the working directory
1446 to the parent of each patch before applying it, and will abort
1454 to the parent of each patch before applying it, and will abort
1447 if the resulting changeset has a different ID than the one
1455 if the resulting changeset has a different ID than the one
1448 recorded in the patch. This may happen due to character set
1456 recorded in the patch. This may happen due to character set
1449 problems or other deficiencies in the text patch format.
1457 problems or other deficiencies in the text patch format.
1450
1458
1451 To read a patch from standard input, use patch name "-".
1459 To read a patch from standard input, use patch name "-".
1452 See 'hg help dates' for a list of formats valid for -d/--date.
1460 See 'hg help dates' for a list of formats valid for -d/--date.
1453 """
1461 """
1454 patches = (patch1,) + patches
1462 patches = (patch1,) + patches
1455
1463
1456 date = opts.get('date')
1464 date = opts.get('date')
1457 if date:
1465 if date:
1458 opts['date'] = util.parsedate(date)
1466 opts['date'] = util.parsedate(date)
1459
1467
1460 if opts.get('exact') or not opts['force']:
1468 if opts.get('exact') or not opts['force']:
1461 cmdutil.bail_if_changed(repo)
1469 cmdutil.bail_if_changed(repo)
1462
1470
1463 d = opts["base"]
1471 d = opts["base"]
1464 strip = opts["strip"]
1472 strip = opts["strip"]
1465 wlock = lock = None
1473 wlock = lock = None
1466 try:
1474 try:
1467 wlock = repo.wlock()
1475 wlock = repo.wlock()
1468 lock = repo.lock()
1476 lock = repo.lock()
1469 for p in patches:
1477 for p in patches:
1470 pf = os.path.join(d, p)
1478 pf = os.path.join(d, p)
1471
1479
1472 if pf == '-':
1480 if pf == '-':
1473 ui.status(_("applying patch from stdin\n"))
1481 ui.status(_("applying patch from stdin\n"))
1474 data = patch.extract(ui, sys.stdin)
1482 data = patch.extract(ui, sys.stdin)
1475 else:
1483 else:
1476 ui.status(_("applying %s\n") % p)
1484 ui.status(_("applying %s\n") % p)
1477 if os.path.exists(pf):
1485 if os.path.exists(pf):
1478 data = patch.extract(ui, file(pf, 'rb'))
1486 data = patch.extract(ui, file(pf, 'rb'))
1479 else:
1487 else:
1480 data = patch.extract(ui, urllib.urlopen(pf))
1488 data = patch.extract(ui, urllib.urlopen(pf))
1481 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1489 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1482
1490
1483 if tmpname is None:
1491 if tmpname is None:
1484 raise util.Abort(_('no diffs found'))
1492 raise util.Abort(_('no diffs found'))
1485
1493
1486 try:
1494 try:
1487 cmdline_message = cmdutil.logmessage(opts)
1495 cmdline_message = cmdutil.logmessage(opts)
1488 if cmdline_message:
1496 if cmdline_message:
1489 # pickup the cmdline msg
1497 # pickup the cmdline msg
1490 message = cmdline_message
1498 message = cmdline_message
1491 elif message:
1499 elif message:
1492 # pickup the patch msg
1500 # pickup the patch msg
1493 message = message.strip()
1501 message = message.strip()
1494 else:
1502 else:
1495 # launch the editor
1503 # launch the editor
1496 message = None
1504 message = None
1497 ui.debug(_('message:\n%s\n') % message)
1505 ui.debug(_('message:\n%s\n') % message)
1498
1506
1499 wp = repo.workingctx().parents()
1507 wp = repo.workingctx().parents()
1500 if opts.get('exact'):
1508 if opts.get('exact'):
1501 if not nodeid or not p1:
1509 if not nodeid or not p1:
1502 raise util.Abort(_('not a mercurial patch'))
1510 raise util.Abort(_('not a mercurial patch'))
1503 p1 = repo.lookup(p1)
1511 p1 = repo.lookup(p1)
1504 p2 = repo.lookup(p2 or hex(nullid))
1512 p2 = repo.lookup(p2 or hex(nullid))
1505
1513
1506 if p1 != wp[0].node():
1514 if p1 != wp[0].node():
1507 hg.clean(repo, p1)
1515 hg.clean(repo, p1)
1508 repo.dirstate.setparents(p1, p2)
1516 repo.dirstate.setparents(p1, p2)
1509 elif p2:
1517 elif p2:
1510 try:
1518 try:
1511 p1 = repo.lookup(p1)
1519 p1 = repo.lookup(p1)
1512 p2 = repo.lookup(p2)
1520 p2 = repo.lookup(p2)
1513 if p1 == wp[0].node():
1521 if p1 == wp[0].node():
1514 repo.dirstate.setparents(p1, p2)
1522 repo.dirstate.setparents(p1, p2)
1515 except hg.RepoError:
1523 except hg.RepoError:
1516 pass
1524 pass
1517 if opts.get('exact') or opts.get('import_branch'):
1525 if opts.get('exact') or opts.get('import_branch'):
1518 repo.dirstate.setbranch(branch or 'default')
1526 repo.dirstate.setbranch(branch or 'default')
1519
1527
1520 files = {}
1528 files = {}
1521 try:
1529 try:
1522 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1530 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1523 files=files)
1531 files=files)
1524 finally:
1532 finally:
1525 files = patch.updatedir(ui, repo, files)
1533 files = patch.updatedir(ui, repo, files)
1526 if not opts.get('no_commit'):
1534 if not opts.get('no_commit'):
1527 n = repo.commit(files, message, opts.get('user') or user,
1535 n = repo.commit(files, message, opts.get('user') or user,
1528 opts.get('date') or date)
1536 opts.get('date') or date)
1529 if opts.get('exact'):
1537 if opts.get('exact'):
1530 if hex(n) != nodeid:
1538 if hex(n) != nodeid:
1531 repo.rollback()
1539 repo.rollback()
1532 raise util.Abort(_('patch is damaged'
1540 raise util.Abort(_('patch is damaged'
1533 ' or loses information'))
1541 ' or loses information'))
1534 # Force a dirstate write so that the next transaction
1542 # Force a dirstate write so that the next transaction
1535 # backups an up-do-date file.
1543 # backups an up-do-date file.
1536 repo.dirstate.write()
1544 repo.dirstate.write()
1537 finally:
1545 finally:
1538 os.unlink(tmpname)
1546 os.unlink(tmpname)
1539 finally:
1547 finally:
1540 del lock, wlock
1548 del lock, wlock
1541
1549
1542 def incoming(ui, repo, source="default", **opts):
1550 def incoming(ui, repo, source="default", **opts):
1543 """show new changesets found in source
1551 """show new changesets found in source
1544
1552
1545 Show new changesets found in the specified path/URL or the default
1553 Show new changesets found in the specified path/URL or the default
1546 pull location. These are the changesets that would be pulled if a pull
1554 pull location. These are the changesets that would be pulled if a pull
1547 was requested.
1555 was requested.
1548
1556
1549 For remote repository, using --bundle avoids downloading the changesets
1557 For remote repository, using --bundle avoids downloading the changesets
1550 twice if the incoming is followed by a pull.
1558 twice if the incoming is followed by a pull.
1551
1559
1552 See pull for valid source format details.
1560 See pull for valid source format details.
1553 """
1561 """
1554 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1562 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1555 cmdutil.setremoteconfig(ui, opts)
1563 cmdutil.setremoteconfig(ui, opts)
1556
1564
1557 other = hg.repository(ui, source)
1565 other = hg.repository(ui, source)
1558 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1566 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1559 if revs:
1567 if revs:
1560 revs = [other.lookup(rev) for rev in revs]
1568 revs = [other.lookup(rev) for rev in revs]
1561 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1569 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1562 if not incoming:
1570 if not incoming:
1563 try:
1571 try:
1564 os.unlink(opts["bundle"])
1572 os.unlink(opts["bundle"])
1565 except:
1573 except:
1566 pass
1574 pass
1567 ui.status(_("no changes found\n"))
1575 ui.status(_("no changes found\n"))
1568 return 1
1576 return 1
1569
1577
1570 cleanup = None
1578 cleanup = None
1571 try:
1579 try:
1572 fname = opts["bundle"]
1580 fname = opts["bundle"]
1573 if fname or not other.local():
1581 if fname or not other.local():
1574 # create a bundle (uncompressed if other repo is not local)
1582 # create a bundle (uncompressed if other repo is not local)
1575 if revs is None:
1583 if revs is None:
1576 cg = other.changegroup(incoming, "incoming")
1584 cg = other.changegroup(incoming, "incoming")
1577 else:
1585 else:
1578 cg = other.changegroupsubset(incoming, revs, 'incoming')
1586 cg = other.changegroupsubset(incoming, revs, 'incoming')
1579 bundletype = other.local() and "HG10BZ" or "HG10UN"
1587 bundletype = other.local() and "HG10BZ" or "HG10UN"
1580 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1588 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1581 # keep written bundle?
1589 # keep written bundle?
1582 if opts["bundle"]:
1590 if opts["bundle"]:
1583 cleanup = None
1591 cleanup = None
1584 if not other.local():
1592 if not other.local():
1585 # use the created uncompressed bundlerepo
1593 # use the created uncompressed bundlerepo
1586 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1594 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1587
1595
1588 o = other.changelog.nodesbetween(incoming, revs)[0]
1596 o = other.changelog.nodesbetween(incoming, revs)[0]
1589 if opts['newest_first']:
1597 if opts['newest_first']:
1590 o.reverse()
1598 o.reverse()
1591 displayer = cmdutil.show_changeset(ui, other, opts)
1599 displayer = cmdutil.show_changeset(ui, other, opts)
1592 for n in o:
1600 for n in o:
1593 parents = [p for p in other.changelog.parents(n) if p != nullid]
1601 parents = [p for p in other.changelog.parents(n) if p != nullid]
1594 if opts['no_merges'] and len(parents) == 2:
1602 if opts['no_merges'] and len(parents) == 2:
1595 continue
1603 continue
1596 displayer.show(changenode=n)
1604 displayer.show(changenode=n)
1597 finally:
1605 finally:
1598 if hasattr(other, 'close'):
1606 if hasattr(other, 'close'):
1599 other.close()
1607 other.close()
1600 if cleanup:
1608 if cleanup:
1601 os.unlink(cleanup)
1609 os.unlink(cleanup)
1602
1610
1603 def init(ui, dest=".", **opts):
1611 def init(ui, dest=".", **opts):
1604 """create a new repository in the given directory
1612 """create a new repository in the given directory
1605
1613
1606 Initialize a new repository in the given directory. If the given
1614 Initialize a new repository in the given directory. If the given
1607 directory does not exist, it is created.
1615 directory does not exist, it is created.
1608
1616
1609 If no directory is given, the current directory is used.
1617 If no directory is given, the current directory is used.
1610
1618
1611 It is possible to specify an ssh:// URL as the destination.
1619 It is possible to specify an ssh:// URL as the destination.
1612 Look at the help text for the pull command for important details
1620 Look at the help text for the pull command for important details
1613 about ssh:// URLs.
1621 about ssh:// URLs.
1614 """
1622 """
1615 cmdutil.setremoteconfig(ui, opts)
1623 cmdutil.setremoteconfig(ui, opts)
1616 hg.repository(ui, dest, create=1)
1624 hg.repository(ui, dest, create=1)
1617
1625
1618 def locate(ui, repo, *pats, **opts):
1626 def locate(ui, repo, *pats, **opts):
1619 """locate files matching specific patterns
1627 """locate files matching specific patterns
1620
1628
1621 Print all files under Mercurial control whose names match the
1629 Print all files under Mercurial control whose names match the
1622 given patterns.
1630 given patterns.
1623
1631
1624 This command searches the entire repository by default. To search
1632 This command searches the entire repository by default. To search
1625 just the current directory and its subdirectories, use
1633 just the current directory and its subdirectories, use
1626 "--include .".
1634 "--include .".
1627
1635
1628 If no patterns are given to match, this command prints all file
1636 If no patterns are given to match, this command prints all file
1629 names.
1637 names.
1630
1638
1631 If you want to feed the output of this command into the "xargs"
1639 If you want to feed the output of this command into the "xargs"
1632 command, use the "-0" option to both this command and "xargs".
1640 command, use the "-0" option to both this command and "xargs".
1633 This will avoid the problem of "xargs" treating single filenames
1641 This will avoid the problem of "xargs" treating single filenames
1634 that contain white space as multiple filenames.
1642 that contain white space as multiple filenames.
1635 """
1643 """
1636 end = opts['print0'] and '\0' or '\n'
1644 end = opts['print0'] and '\0' or '\n'
1637 rev = opts['rev']
1645 rev = opts['rev']
1638 if rev:
1646 if rev:
1639 node = repo.lookup(rev)
1647 node = repo.lookup(rev)
1640 else:
1648 else:
1641 node = None
1649 node = None
1642
1650
1643 ret = 1
1651 ret = 1
1644 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1652 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1645 badmatch=util.always,
1653 badmatch=util.always,
1646 default='relglob'):
1654 default='relglob'):
1647 if src == 'b':
1655 if src == 'b':
1648 continue
1656 continue
1649 if not node and abs not in repo.dirstate:
1657 if not node and abs not in repo.dirstate:
1650 continue
1658 continue
1651 if opts['fullpath']:
1659 if opts['fullpath']:
1652 ui.write(os.path.join(repo.root, abs), end)
1660 ui.write(os.path.join(repo.root, abs), end)
1653 else:
1661 else:
1654 ui.write(((pats and rel) or abs), end)
1662 ui.write(((pats and rel) or abs), end)
1655 ret = 0
1663 ret = 0
1656
1664
1657 return ret
1665 return ret
1658
1666
1659 def log(ui, repo, *pats, **opts):
1667 def log(ui, repo, *pats, **opts):
1660 """show revision history of entire repository or files
1668 """show revision history of entire repository or files
1661
1669
1662 Print the revision history of the specified files or the entire
1670 Print the revision history of the specified files or the entire
1663 project.
1671 project.
1664
1672
1665 File history is shown without following rename or copy history of
1673 File history is shown without following rename or copy history of
1666 files. Use -f/--follow with a file name to follow history across
1674 files. Use -f/--follow with a file name to follow history across
1667 renames and copies. --follow without a file name will only show
1675 renames and copies. --follow without a file name will only show
1668 ancestors or descendants of the starting revision. --follow-first
1676 ancestors or descendants of the starting revision. --follow-first
1669 only follows the first parent of merge revisions.
1677 only follows the first parent of merge revisions.
1670
1678
1671 If no revision range is specified, the default is tip:0 unless
1679 If no revision range is specified, the default is tip:0 unless
1672 --follow is set, in which case the working directory parent is
1680 --follow is set, in which case the working directory parent is
1673 used as the starting revision.
1681 used as the starting revision.
1674
1682
1675 See 'hg help dates' for a list of formats valid for -d/--date.
1683 See 'hg help dates' for a list of formats valid for -d/--date.
1676
1684
1677 By default this command outputs: changeset id and hash, tags,
1685 By default this command outputs: changeset id and hash, tags,
1678 non-trivial parents, user, date and time, and a summary for each
1686 non-trivial parents, user, date and time, and a summary for each
1679 commit. When the -v/--verbose switch is used, the list of changed
1687 commit. When the -v/--verbose switch is used, the list of changed
1680 files and full commit message is shown.
1688 files and full commit message is shown.
1681
1689
1682 NOTE: log -p may generate unexpected diff output for merge
1690 NOTE: log -p may generate unexpected diff output for merge
1683 changesets, as it will compare the merge changeset against its
1691 changesets, as it will compare the merge changeset against its
1684 first parent only. Also, the files: list will only reflect files
1692 first parent only. Also, the files: list will only reflect files
1685 that are different from BOTH parents.
1693 that are different from BOTH parents.
1686
1694
1687 """
1695 """
1688
1696
1689 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1697 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1690 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1698 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1691
1699
1692 if opts['limit']:
1700 if opts['limit']:
1693 try:
1701 try:
1694 limit = int(opts['limit'])
1702 limit = int(opts['limit'])
1695 except ValueError:
1703 except ValueError:
1696 raise util.Abort(_('limit must be a positive integer'))
1704 raise util.Abort(_('limit must be a positive integer'))
1697 if limit <= 0: raise util.Abort(_('limit must be positive'))
1705 if limit <= 0: raise util.Abort(_('limit must be positive'))
1698 else:
1706 else:
1699 limit = sys.maxint
1707 limit = sys.maxint
1700 count = 0
1708 count = 0
1701
1709
1702 if opts['copies'] and opts['rev']:
1710 if opts['copies'] and opts['rev']:
1703 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1711 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1704 else:
1712 else:
1705 endrev = repo.changelog.count()
1713 endrev = repo.changelog.count()
1706 rcache = {}
1714 rcache = {}
1707 ncache = {}
1715 ncache = {}
1708 def getrenamed(fn, rev):
1716 def getrenamed(fn, rev):
1709 '''looks up all renames for a file (up to endrev) the first
1717 '''looks up all renames for a file (up to endrev) the first
1710 time the file is given. It indexes on the changerev and only
1718 time the file is given. It indexes on the changerev and only
1711 parses the manifest if linkrev != changerev.
1719 parses the manifest if linkrev != changerev.
1712 Returns rename info for fn at changerev rev.'''
1720 Returns rename info for fn at changerev rev.'''
1713 if fn not in rcache:
1721 if fn not in rcache:
1714 rcache[fn] = {}
1722 rcache[fn] = {}
1715 ncache[fn] = {}
1723 ncache[fn] = {}
1716 fl = repo.file(fn)
1724 fl = repo.file(fn)
1717 for i in xrange(fl.count()):
1725 for i in xrange(fl.count()):
1718 node = fl.node(i)
1726 node = fl.node(i)
1719 lr = fl.linkrev(node)
1727 lr = fl.linkrev(node)
1720 renamed = fl.renamed(node)
1728 renamed = fl.renamed(node)
1721 rcache[fn][lr] = renamed
1729 rcache[fn][lr] = renamed
1722 if renamed:
1730 if renamed:
1723 ncache[fn][node] = renamed
1731 ncache[fn][node] = renamed
1724 if lr >= endrev:
1732 if lr >= endrev:
1725 break
1733 break
1726 if rev in rcache[fn]:
1734 if rev in rcache[fn]:
1727 return rcache[fn][rev]
1735 return rcache[fn][rev]
1728
1736
1729 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1737 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1730 # filectx logic.
1738 # filectx logic.
1731
1739
1732 try:
1740 try:
1733 return repo.changectx(rev).filectx(fn).renamed()
1741 return repo.changectx(rev).filectx(fn).renamed()
1734 except revlog.LookupError:
1742 except revlog.LookupError:
1735 pass
1743 pass
1736 return None
1744 return None
1737
1745
1738 df = False
1746 df = False
1739 if opts["date"]:
1747 if opts["date"]:
1740 df = util.matchdate(opts["date"])
1748 df = util.matchdate(opts["date"])
1741
1749
1742 only_branches = opts['only_branch']
1750 only_branches = opts['only_branch']
1743
1751
1744 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1752 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1745 for st, rev, fns in changeiter:
1753 for st, rev, fns in changeiter:
1746 if st == 'add':
1754 if st == 'add':
1747 changenode = repo.changelog.node(rev)
1755 changenode = repo.changelog.node(rev)
1748 parents = [p for p in repo.changelog.parentrevs(rev)
1756 parents = [p for p in repo.changelog.parentrevs(rev)
1749 if p != nullrev]
1757 if p != nullrev]
1750 if opts['no_merges'] and len(parents) == 2:
1758 if opts['no_merges'] and len(parents) == 2:
1751 continue
1759 continue
1752 if opts['only_merges'] and len(parents) != 2:
1760 if opts['only_merges'] and len(parents) != 2:
1753 continue
1761 continue
1754
1762
1755 if only_branches:
1763 if only_branches:
1756 revbranch = get(rev)[5]['branch']
1764 revbranch = get(rev)[5]['branch']
1757 if revbranch not in only_branches:
1765 if revbranch not in only_branches:
1758 continue
1766 continue
1759
1767
1760 if df:
1768 if df:
1761 changes = get(rev)
1769 changes = get(rev)
1762 if not df(changes[2][0]):
1770 if not df(changes[2][0]):
1763 continue
1771 continue
1764
1772
1765 if opts['keyword']:
1773 if opts['keyword']:
1766 changes = get(rev)
1774 changes = get(rev)
1767 miss = 0
1775 miss = 0
1768 for k in [kw.lower() for kw in opts['keyword']]:
1776 for k in [kw.lower() for kw in opts['keyword']]:
1769 if not (k in changes[1].lower() or
1777 if not (k in changes[1].lower() or
1770 k in changes[4].lower() or
1778 k in changes[4].lower() or
1771 k in " ".join(changes[3]).lower()):
1779 k in " ".join(changes[3]).lower()):
1772 miss = 1
1780 miss = 1
1773 break
1781 break
1774 if miss:
1782 if miss:
1775 continue
1783 continue
1776
1784
1777 copies = []
1785 copies = []
1778 if opts.get('copies') and rev:
1786 if opts.get('copies') and rev:
1779 for fn in get(rev)[3]:
1787 for fn in get(rev)[3]:
1780 rename = getrenamed(fn, rev)
1788 rename = getrenamed(fn, rev)
1781 if rename:
1789 if rename:
1782 copies.append((fn, rename[0]))
1790 copies.append((fn, rename[0]))
1783 displayer.show(rev, changenode, copies=copies)
1791 displayer.show(rev, changenode, copies=copies)
1784 elif st == 'iter':
1792 elif st == 'iter':
1785 if count == limit: break
1793 if count == limit: break
1786 if displayer.flush(rev):
1794 if displayer.flush(rev):
1787 count += 1
1795 count += 1
1788
1796
1789 def manifest(ui, repo, node=None, rev=None):
1797 def manifest(ui, repo, node=None, rev=None):
1790 """output the current or given revision of the project manifest
1798 """output the current or given revision of the project manifest
1791
1799
1792 Print a list of version controlled files for the given revision.
1800 Print a list of version controlled files for the given revision.
1793 If no revision is given, the parent of the working directory is used,
1801 If no revision is given, the parent of the working directory is used,
1794 or tip if no revision is checked out.
1802 or tip if no revision is checked out.
1795
1803
1796 The manifest is the list of files being version controlled. If no revision
1804 The manifest is the list of files being version controlled. If no revision
1797 is given then the first parent of the working directory is used.
1805 is given then the first parent of the working directory is used.
1798
1806
1799 With -v flag, print file permissions, symlink and executable bits. With
1807 With -v flag, print file permissions, symlink and executable bits. With
1800 --debug flag, print file revision hashes.
1808 --debug flag, print file revision hashes.
1801 """
1809 """
1802
1810
1803 if rev and node:
1811 if rev and node:
1804 raise util.Abort(_("please specify just one revision"))
1812 raise util.Abort(_("please specify just one revision"))
1805
1813
1806 if not node:
1814 if not node:
1807 node = rev
1815 node = rev
1808
1816
1809 m = repo.changectx(node).manifest()
1817 m = repo.changectx(node).manifest()
1810 files = m.keys()
1818 files = m.keys()
1811 files.sort()
1819 files.sort()
1812
1820
1813 for f in files:
1821 for f in files:
1814 if ui.debugflag:
1822 if ui.debugflag:
1815 ui.write("%40s " % hex(m[f]))
1823 ui.write("%40s " % hex(m[f]))
1816 if ui.verbose:
1824 if ui.verbose:
1817 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1825 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1818 perm = m.execf(f) and "755" or "644"
1826 perm = m.execf(f) and "755" or "644"
1819 ui.write("%3s %1s " % (perm, type))
1827 ui.write("%3s %1s " % (perm, type))
1820 ui.write("%s\n" % f)
1828 ui.write("%s\n" % f)
1821
1829
1822 def merge(ui, repo, node=None, force=None, rev=None):
1830 def merge(ui, repo, node=None, force=None, rev=None):
1823 """merge working directory with another revision
1831 """merge working directory with another revision
1824
1832
1825 Merge the contents of the current working directory and the
1833 Merge the contents of the current working directory and the
1826 requested revision. Files that changed between either parent are
1834 requested revision. Files that changed between either parent are
1827 marked as changed for the next commit and a commit must be
1835 marked as changed for the next commit and a commit must be
1828 performed before any further updates are allowed.
1836 performed before any further updates are allowed.
1829
1837
1830 If no revision is specified, the working directory's parent is a
1838 If no revision is specified, the working directory's parent is a
1831 head revision, and the repository contains exactly one other head,
1839 head revision, and the repository contains exactly one other head,
1832 the other head is merged with by default. Otherwise, an explicit
1840 the other head is merged with by default. Otherwise, an explicit
1833 revision to merge with must be provided.
1841 revision to merge with must be provided.
1834 """
1842 """
1835
1843
1836 if rev and node:
1844 if rev and node:
1837 raise util.Abort(_("please specify just one revision"))
1845 raise util.Abort(_("please specify just one revision"))
1838 if not node:
1846 if not node:
1839 node = rev
1847 node = rev
1840
1848
1841 if not node:
1849 if not node:
1842 heads = repo.heads()
1850 heads = repo.heads()
1843 if len(heads) > 2:
1851 if len(heads) > 2:
1844 raise util.Abort(_('repo has %d heads - '
1852 raise util.Abort(_('repo has %d heads - '
1845 'please merge with an explicit rev') %
1853 'please merge with an explicit rev') %
1846 len(heads))
1854 len(heads))
1847 parent = repo.dirstate.parents()[0]
1855 parent = repo.dirstate.parents()[0]
1848 if len(heads) == 1:
1856 if len(heads) == 1:
1849 msg = _('there is nothing to merge')
1857 msg = _('there is nothing to merge')
1850 if parent != repo.lookup(repo.workingctx().branch()):
1858 if parent != repo.lookup(repo.workingctx().branch()):
1851 msg = _('%s - use "hg update" instead') % msg
1859 msg = _('%s - use "hg update" instead') % msg
1852 raise util.Abort(msg)
1860 raise util.Abort(msg)
1853
1861
1854 if parent not in heads:
1862 if parent not in heads:
1855 raise util.Abort(_('working dir not at a head rev - '
1863 raise util.Abort(_('working dir not at a head rev - '
1856 'use "hg update" or merge with an explicit rev'))
1864 'use "hg update" or merge with an explicit rev'))
1857 node = parent == heads[0] and heads[-1] or heads[0]
1865 node = parent == heads[0] and heads[-1] or heads[0]
1858 return hg.merge(repo, node, force=force)
1866 return hg.merge(repo, node, force=force)
1859
1867
1860 def outgoing(ui, repo, dest=None, **opts):
1868 def outgoing(ui, repo, dest=None, **opts):
1861 """show changesets not found in destination
1869 """show changesets not found in destination
1862
1870
1863 Show changesets not found in the specified destination repository or
1871 Show changesets not found in the specified destination repository or
1864 the default push location. These are the changesets that would be pushed
1872 the default push location. These are the changesets that would be pushed
1865 if a push was requested.
1873 if a push was requested.
1866
1874
1867 See pull for valid destination format details.
1875 See pull for valid destination format details.
1868 """
1876 """
1869 dest, revs, checkout = hg.parseurl(
1877 dest, revs, checkout = hg.parseurl(
1870 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1878 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1871 cmdutil.setremoteconfig(ui, opts)
1879 cmdutil.setremoteconfig(ui, opts)
1872 if revs:
1880 if revs:
1873 revs = [repo.lookup(rev) for rev in revs]
1881 revs = [repo.lookup(rev) for rev in revs]
1874
1882
1875 other = hg.repository(ui, dest)
1883 other = hg.repository(ui, dest)
1876 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1884 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1877 o = repo.findoutgoing(other, force=opts['force'])
1885 o = repo.findoutgoing(other, force=opts['force'])
1878 if not o:
1886 if not o:
1879 ui.status(_("no changes found\n"))
1887 ui.status(_("no changes found\n"))
1880 return 1
1888 return 1
1881 o = repo.changelog.nodesbetween(o, revs)[0]
1889 o = repo.changelog.nodesbetween(o, revs)[0]
1882 if opts['newest_first']:
1890 if opts['newest_first']:
1883 o.reverse()
1891 o.reverse()
1884 displayer = cmdutil.show_changeset(ui, repo, opts)
1892 displayer = cmdutil.show_changeset(ui, repo, opts)
1885 for n in o:
1893 for n in o:
1886 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1894 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1887 if opts['no_merges'] and len(parents) == 2:
1895 if opts['no_merges'] and len(parents) == 2:
1888 continue
1896 continue
1889 displayer.show(changenode=n)
1897 displayer.show(changenode=n)
1890
1898
1891 def parents(ui, repo, file_=None, **opts):
1899 def parents(ui, repo, file_=None, **opts):
1892 """show the parents of the working dir or revision
1900 """show the parents of the working dir or revision
1893
1901
1894 Print the working directory's parent revisions. If a
1902 Print the working directory's parent revisions. If a
1895 revision is given via --rev, the parent of that revision
1903 revision is given via --rev, the parent of that revision
1896 will be printed. If a file argument is given, revision in
1904 will be printed. If a file argument is given, revision in
1897 which the file was last changed (before the working directory
1905 which the file was last changed (before the working directory
1898 revision or the argument to --rev if given) is printed.
1906 revision or the argument to --rev if given) is printed.
1899 """
1907 """
1900 rev = opts.get('rev')
1908 rev = opts.get('rev')
1901 if rev:
1909 if rev:
1902 ctx = repo.changectx(rev)
1910 ctx = repo.changectx(rev)
1903 else:
1911 else:
1904 ctx = repo.workingctx()
1912 ctx = repo.workingctx()
1905
1913
1906 if file_:
1914 if file_:
1907 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1915 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1908 if anypats or len(files) != 1:
1916 if anypats or len(files) != 1:
1909 raise util.Abort(_('can only specify an explicit file name'))
1917 raise util.Abort(_('can only specify an explicit file name'))
1910 file_ = files[0]
1918 file_ = files[0]
1911 filenodes = []
1919 filenodes = []
1912 for cp in ctx.parents():
1920 for cp in ctx.parents():
1913 if not cp:
1921 if not cp:
1914 continue
1922 continue
1915 try:
1923 try:
1916 filenodes.append(cp.filenode(file_))
1924 filenodes.append(cp.filenode(file_))
1917 except revlog.LookupError:
1925 except revlog.LookupError:
1918 pass
1926 pass
1919 if not filenodes:
1927 if not filenodes:
1920 raise util.Abort(_("'%s' not found in manifest!") % file_)
1928 raise util.Abort(_("'%s' not found in manifest!") % file_)
1921 fl = repo.file(file_)
1929 fl = repo.file(file_)
1922 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1930 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1923 else:
1931 else:
1924 p = [cp.node() for cp in ctx.parents()]
1932 p = [cp.node() for cp in ctx.parents()]
1925
1933
1926 displayer = cmdutil.show_changeset(ui, repo, opts)
1934 displayer = cmdutil.show_changeset(ui, repo, opts)
1927 for n in p:
1935 for n in p:
1928 if n != nullid:
1936 if n != nullid:
1929 displayer.show(changenode=n)
1937 displayer.show(changenode=n)
1930
1938
1931 def paths(ui, repo, search=None):
1939 def paths(ui, repo, search=None):
1932 """show definition of symbolic path names
1940 """show definition of symbolic path names
1933
1941
1934 Show definition of symbolic path name NAME. If no name is given, show
1942 Show definition of symbolic path name NAME. If no name is given, show
1935 definition of available names.
1943 definition of available names.
1936
1944
1937 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1945 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1938 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1946 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1939 """
1947 """
1940 if search:
1948 if search:
1941 for name, path in ui.configitems("paths"):
1949 for name, path in ui.configitems("paths"):
1942 if name == search:
1950 if name == search:
1943 ui.write("%s\n" % path)
1951 ui.write("%s\n" % path)
1944 return
1952 return
1945 ui.warn(_("not found!\n"))
1953 ui.warn(_("not found!\n"))
1946 return 1
1954 return 1
1947 else:
1955 else:
1948 for name, path in ui.configitems("paths"):
1956 for name, path in ui.configitems("paths"):
1949 ui.write("%s = %s\n" % (name, path))
1957 ui.write("%s = %s\n" % (name, path))
1950
1958
1951 def postincoming(ui, repo, modheads, optupdate, checkout):
1959 def postincoming(ui, repo, modheads, optupdate, checkout):
1952 if modheads == 0:
1960 if modheads == 0:
1953 return
1961 return
1954 if optupdate:
1962 if optupdate:
1955 if modheads <= 1 or checkout:
1963 if modheads <= 1 or checkout:
1956 return hg.update(repo, checkout)
1964 return hg.update(repo, checkout)
1957 else:
1965 else:
1958 ui.status(_("not updating, since new heads added\n"))
1966 ui.status(_("not updating, since new heads added\n"))
1959 if modheads > 1:
1967 if modheads > 1:
1960 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1968 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1961 else:
1969 else:
1962 ui.status(_("(run 'hg update' to get a working copy)\n"))
1970 ui.status(_("(run 'hg update' to get a working copy)\n"))
1963
1971
1964 def pull(ui, repo, source="default", **opts):
1972 def pull(ui, repo, source="default", **opts):
1965 """pull changes from the specified source
1973 """pull changes from the specified source
1966
1974
1967 Pull changes from a remote repository to a local one.
1975 Pull changes from a remote repository to a local one.
1968
1976
1969 This finds all changes from the repository at the specified path
1977 This finds all changes from the repository at the specified path
1970 or URL and adds them to the local repository. By default, this
1978 or URL and adds them to the local repository. By default, this
1971 does not update the copy of the project in the working directory.
1979 does not update the copy of the project in the working directory.
1972
1980
1973 Valid URLs are of the form:
1981 Valid URLs are of the form:
1974
1982
1975 local/filesystem/path (or file://local/filesystem/path)
1983 local/filesystem/path (or file://local/filesystem/path)
1976 http://[user@]host[:port]/[path]
1984 http://[user@]host[:port]/[path]
1977 https://[user@]host[:port]/[path]
1985 https://[user@]host[:port]/[path]
1978 ssh://[user@]host[:port]/[path]
1986 ssh://[user@]host[:port]/[path]
1979 static-http://host[:port]/[path]
1987 static-http://host[:port]/[path]
1980
1988
1981 Paths in the local filesystem can either point to Mercurial
1989 Paths in the local filesystem can either point to Mercurial
1982 repositories or to bundle files (as created by 'hg bundle' or
1990 repositories or to bundle files (as created by 'hg bundle' or
1983 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1991 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1984 allows access to a Mercurial repository where you simply use a web
1992 allows access to a Mercurial repository where you simply use a web
1985 server to publish the .hg directory as static content.
1993 server to publish the .hg directory as static content.
1986
1994
1987 An optional identifier after # indicates a particular branch, tag,
1995 An optional identifier after # indicates a particular branch, tag,
1988 or changeset to pull.
1996 or changeset to pull.
1989
1997
1990 Some notes about using SSH with Mercurial:
1998 Some notes about using SSH with Mercurial:
1991 - SSH requires an accessible shell account on the destination machine
1999 - SSH requires an accessible shell account on the destination machine
1992 and a copy of hg in the remote path or specified with as remotecmd.
2000 and a copy of hg in the remote path or specified with as remotecmd.
1993 - path is relative to the remote user's home directory by default.
2001 - path is relative to the remote user's home directory by default.
1994 Use an extra slash at the start of a path to specify an absolute path:
2002 Use an extra slash at the start of a path to specify an absolute path:
1995 ssh://example.com//tmp/repository
2003 ssh://example.com//tmp/repository
1996 - Mercurial doesn't use its own compression via SSH; the right thing
2004 - Mercurial doesn't use its own compression via SSH; the right thing
1997 to do is to configure it in your ~/.ssh/config, e.g.:
2005 to do is to configure it in your ~/.ssh/config, e.g.:
1998 Host *.mylocalnetwork.example.com
2006 Host *.mylocalnetwork.example.com
1999 Compression no
2007 Compression no
2000 Host *
2008 Host *
2001 Compression yes
2009 Compression yes
2002 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2010 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2003 with the --ssh command line option.
2011 with the --ssh command line option.
2004 """
2012 """
2005 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
2013 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
2006 cmdutil.setremoteconfig(ui, opts)
2014 cmdutil.setremoteconfig(ui, opts)
2007
2015
2008 other = hg.repository(ui, source)
2016 other = hg.repository(ui, source)
2009 ui.status(_('pulling from %s\n') % util.hidepassword(source))
2017 ui.status(_('pulling from %s\n') % util.hidepassword(source))
2010 if revs:
2018 if revs:
2011 try:
2019 try:
2012 revs = [other.lookup(rev) for rev in revs]
2020 revs = [other.lookup(rev) for rev in revs]
2013 except repo.NoCapability:
2021 except repo.NoCapability:
2014 error = _("Other repository doesn't support revision lookup, "
2022 error = _("Other repository doesn't support revision lookup, "
2015 "so a rev cannot be specified.")
2023 "so a rev cannot be specified.")
2016 raise util.Abort(error)
2024 raise util.Abort(error)
2017
2025
2018 modheads = repo.pull(other, heads=revs, force=opts['force'])
2026 modheads = repo.pull(other, heads=revs, force=opts['force'])
2019 return postincoming(ui, repo, modheads, opts['update'], checkout)
2027 return postincoming(ui, repo, modheads, opts['update'], checkout)
2020
2028
2021 def push(ui, repo, dest=None, **opts):
2029 def push(ui, repo, dest=None, **opts):
2022 """push changes to the specified destination
2030 """push changes to the specified destination
2023
2031
2024 Push changes from the local repository to the given destination.
2032 Push changes from the local repository to the given destination.
2025
2033
2026 This is the symmetrical operation for pull. It helps to move
2034 This is the symmetrical operation for pull. It helps to move
2027 changes from the current repository to a different one. If the
2035 changes from the current repository to a different one. If the
2028 destination is local this is identical to a pull in that directory
2036 destination is local this is identical to a pull in that directory
2029 from the current one.
2037 from the current one.
2030
2038
2031 By default, push will refuse to run if it detects the result would
2039 By default, push will refuse to run if it detects the result would
2032 increase the number of remote heads. This generally indicates the
2040 increase the number of remote heads. This generally indicates the
2033 the client has forgotten to sync and merge before pushing.
2041 the client has forgotten to sync and merge before pushing.
2034
2042
2035 Valid URLs are of the form:
2043 Valid URLs are of the form:
2036
2044
2037 local/filesystem/path (or file://local/filesystem/path)
2045 local/filesystem/path (or file://local/filesystem/path)
2038 ssh://[user@]host[:port]/[path]
2046 ssh://[user@]host[:port]/[path]
2039 http://[user@]host[:port]/[path]
2047 http://[user@]host[:port]/[path]
2040 https://[user@]host[:port]/[path]
2048 https://[user@]host[:port]/[path]
2041
2049
2042 An optional identifier after # indicates a particular branch, tag,
2050 An optional identifier after # indicates a particular branch, tag,
2043 or changeset to push.
2051 or changeset to push.
2044
2052
2045 Look at the help text for the pull command for important details
2053 Look at the help text for the pull command for important details
2046 about ssh:// URLs.
2054 about ssh:// URLs.
2047
2055
2048 Pushing to http:// and https:// URLs is only possible, if this
2056 Pushing to http:// and https:// URLs is only possible, if this
2049 feature is explicitly enabled on the remote Mercurial server.
2057 feature is explicitly enabled on the remote Mercurial server.
2050 """
2058 """
2051 dest, revs, checkout = hg.parseurl(
2059 dest, revs, checkout = hg.parseurl(
2052 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2060 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2053 cmdutil.setremoteconfig(ui, opts)
2061 cmdutil.setremoteconfig(ui, opts)
2054
2062
2055 other = hg.repository(ui, dest)
2063 other = hg.repository(ui, dest)
2056 ui.status('pushing to %s\n' % util.hidepassword(dest))
2064 ui.status('pushing to %s\n' % util.hidepassword(dest))
2057 if revs:
2065 if revs:
2058 revs = [repo.lookup(rev) for rev in revs]
2066 revs = [repo.lookup(rev) for rev in revs]
2059 r = repo.push(other, opts['force'], revs=revs)
2067 r = repo.push(other, opts['force'], revs=revs)
2060 return r == 0
2068 return r == 0
2061
2069
2062 def rawcommit(ui, repo, *pats, **opts):
2070 def rawcommit(ui, repo, *pats, **opts):
2063 """raw commit interface (DEPRECATED)
2071 """raw commit interface (DEPRECATED)
2064
2072
2065 (DEPRECATED)
2073 (DEPRECATED)
2066 Lowlevel commit, for use in helper scripts.
2074 Lowlevel commit, for use in helper scripts.
2067
2075
2068 This command is not intended to be used by normal users, as it is
2076 This command is not intended to be used by normal users, as it is
2069 primarily useful for importing from other SCMs.
2077 primarily useful for importing from other SCMs.
2070
2078
2071 This command is now deprecated and will be removed in a future
2079 This command is now deprecated and will be removed in a future
2072 release, please use debugsetparents and commit instead.
2080 release, please use debugsetparents and commit instead.
2073 """
2081 """
2074
2082
2075 ui.warn(_("(the rawcommit command is deprecated)\n"))
2083 ui.warn(_("(the rawcommit command is deprecated)\n"))
2076
2084
2077 message = cmdutil.logmessage(opts)
2085 message = cmdutil.logmessage(opts)
2078
2086
2079 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2087 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2080 if opts['files']:
2088 if opts['files']:
2081 files += open(opts['files']).read().splitlines()
2089 files += open(opts['files']).read().splitlines()
2082
2090
2083 parents = [repo.lookup(p) for p in opts['parent']]
2091 parents = [repo.lookup(p) for p in opts['parent']]
2084
2092
2085 try:
2093 try:
2086 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2094 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2087 except ValueError, inst:
2095 except ValueError, inst:
2088 raise util.Abort(str(inst))
2096 raise util.Abort(str(inst))
2089
2097
2090 def recover(ui, repo):
2098 def recover(ui, repo):
2091 """roll back an interrupted transaction
2099 """roll back an interrupted transaction
2092
2100
2093 Recover from an interrupted commit or pull.
2101 Recover from an interrupted commit or pull.
2094
2102
2095 This command tries to fix the repository status after an interrupted
2103 This command tries to fix the repository status after an interrupted
2096 operation. It should only be necessary when Mercurial suggests it.
2104 operation. It should only be necessary when Mercurial suggests it.
2097 """
2105 """
2098 if repo.recover():
2106 if repo.recover():
2099 return hg.verify(repo)
2107 return hg.verify(repo)
2100 return 1
2108 return 1
2101
2109
2102 def remove(ui, repo, *pats, **opts):
2110 def remove(ui, repo, *pats, **opts):
2103 """remove the specified files on the next commit
2111 """remove the specified files on the next commit
2104
2112
2105 Schedule the indicated files for removal from the repository.
2113 Schedule the indicated files for removal from the repository.
2106
2114
2107 This only removes files from the current branch, not from the
2115 This only removes files from the current branch, not from the
2108 entire project history. If the files still exist in the working
2116 entire project history. If the files still exist in the working
2109 directory, they will be deleted from it. If invoked with --after,
2117 directory, they will be deleted from it. If invoked with --after,
2110 files are marked as removed, but not actually unlinked unless --force
2118 files are marked as removed, but not actually unlinked unless --force
2111 is also given. Without exact file names, --after will only mark
2119 is also given. Without exact file names, --after will only mark
2112 files as removed if they are no longer in the working directory.
2120 files as removed if they are no longer in the working directory.
2113
2121
2114 This command schedules the files to be removed at the next commit.
2122 This command schedules the files to be removed at the next commit.
2115 To undo a remove before that, see hg revert.
2123 To undo a remove before that, see hg revert.
2116
2124
2117 Modified files and added files are not removed by default. To
2125 Modified files and added files are not removed by default. To
2118 remove them, use the -f/--force option.
2126 remove them, use the -f/--force option.
2119 """
2127 """
2120 if not opts['after'] and not pats:
2128 if not opts['after'] and not pats:
2121 raise util.Abort(_('no files specified'))
2129 raise util.Abort(_('no files specified'))
2122 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2130 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2123 exact = dict.fromkeys(files)
2131 exact = dict.fromkeys(files)
2124 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2132 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2125 modified, added, removed, deleted, unknown = mardu
2133 modified, added, removed, deleted, unknown = mardu
2126 remove, forget = [], []
2134 remove, forget = [], []
2127 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2135 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2128 reason = None
2136 reason = None
2129 if abs in modified and not opts['force']:
2137 if abs in modified and not opts['force']:
2130 reason = _('is modified (use -f to force removal)')
2138 reason = _('is modified (use -f to force removal)')
2131 elif abs in added:
2139 elif abs in added:
2132 if opts['force']:
2140 if opts['force']:
2133 forget.append(abs)
2141 forget.append(abs)
2134 continue
2142 continue
2135 reason = _('has been marked for add (use -f to force removal)')
2143 reason = _('has been marked for add (use -f to force removal)')
2136 exact = 1 # force the message
2144 exact = 1 # force the message
2137 elif abs not in repo.dirstate:
2145 elif abs not in repo.dirstate:
2138 reason = _('is not managed')
2146 reason = _('is not managed')
2139 elif opts['after'] and not exact and abs not in deleted:
2147 elif opts['after'] and not exact and abs not in deleted:
2140 continue
2148 continue
2141 elif abs in removed:
2149 elif abs in removed:
2142 continue
2150 continue
2143 if reason:
2151 if reason:
2144 if exact:
2152 if exact:
2145 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2153 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2146 else:
2154 else:
2147 if ui.verbose or not exact:
2155 if ui.verbose or not exact:
2148 ui.status(_('removing %s\n') % rel)
2156 ui.status(_('removing %s\n') % rel)
2149 remove.append(abs)
2157 remove.append(abs)
2150 repo.forget(forget)
2158 repo.forget(forget)
2151 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2159 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2152
2160
2153 def rename(ui, repo, *pats, **opts):
2161 def rename(ui, repo, *pats, **opts):
2154 """rename files; equivalent of copy + remove
2162 """rename files; equivalent of copy + remove
2155
2163
2156 Mark dest as copies of sources; mark sources for deletion. If
2164 Mark dest as copies of sources; mark sources for deletion. If
2157 dest is a directory, copies are put in that directory. If dest is
2165 dest is a directory, copies are put in that directory. If dest is
2158 a file, there can only be one source.
2166 a file, there can only be one source.
2159
2167
2160 By default, this command copies the contents of files as they
2168 By default, this command copies the contents of files as they
2161 stand in the working directory. If invoked with --after, the
2169 stand in the working directory. If invoked with --after, the
2162 operation is recorded, but no copying is performed.
2170 operation is recorded, but no copying is performed.
2163
2171
2164 This command takes effect in the next commit. To undo a rename
2172 This command takes effect in the next commit. To undo a rename
2165 before that, see hg revert.
2173 before that, see hg revert.
2166 """
2174 """
2167 wlock = repo.wlock(False)
2175 wlock = repo.wlock(False)
2168 try:
2176 try:
2169 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2177 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2170 finally:
2178 finally:
2171 del wlock
2179 del wlock
2172
2180
2173 def revert(ui, repo, *pats, **opts):
2181 def revert(ui, repo, *pats, **opts):
2174 """restore individual files or dirs to an earlier state
2182 """restore individual files or dirs to an earlier state
2175
2183
2176 (use update -r to check out earlier revisions, revert does not
2184 (use update -r to check out earlier revisions, revert does not
2177 change the working dir parents)
2185 change the working dir parents)
2178
2186
2179 With no revision specified, revert the named files or directories
2187 With no revision specified, revert the named files or directories
2180 to the contents they had in the parent of the working directory.
2188 to the contents they had in the parent of the working directory.
2181 This restores the contents of the affected files to an unmodified
2189 This restores the contents of the affected files to an unmodified
2182 state and unschedules adds, removes, copies, and renames. If the
2190 state and unschedules adds, removes, copies, and renames. If the
2183 working directory has two parents, you must explicitly specify the
2191 working directory has two parents, you must explicitly specify the
2184 revision to revert to.
2192 revision to revert to.
2185
2193
2186 Using the -r option, revert the given files or directories to their
2194 Using the -r option, revert the given files or directories to their
2187 contents as of a specific revision. This can be helpful to "roll
2195 contents as of a specific revision. This can be helpful to "roll
2188 back" some or all of an earlier change.
2196 back" some or all of an earlier change.
2189 See 'hg help dates' for a list of formats valid for -d/--date.
2197 See 'hg help dates' for a list of formats valid for -d/--date.
2190
2198
2191 Revert modifies the working directory. It does not commit any
2199 Revert modifies the working directory. It does not commit any
2192 changes, or change the parent of the working directory. If you
2200 changes, or change the parent of the working directory. If you
2193 revert to a revision other than the parent of the working
2201 revert to a revision other than the parent of the working
2194 directory, the reverted files will thus appear modified
2202 directory, the reverted files will thus appear modified
2195 afterwards.
2203 afterwards.
2196
2204
2197 If a file has been deleted, it is restored. If the executable
2205 If a file has been deleted, it is restored. If the executable
2198 mode of a file was changed, it is reset.
2206 mode of a file was changed, it is reset.
2199
2207
2200 If names are given, all files matching the names are reverted.
2208 If names are given, all files matching the names are reverted.
2201 If no arguments are given, no files are reverted.
2209 If no arguments are given, no files are reverted.
2202
2210
2203 Modified files are saved with a .orig suffix before reverting.
2211 Modified files are saved with a .orig suffix before reverting.
2204 To disable these backups, use --no-backup.
2212 To disable these backups, use --no-backup.
2205 """
2213 """
2206
2214
2207 if opts["date"]:
2215 if opts["date"]:
2208 if opts["rev"]:
2216 if opts["rev"]:
2209 raise util.Abort(_("you can't specify a revision and a date"))
2217 raise util.Abort(_("you can't specify a revision and a date"))
2210 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2218 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2211
2219
2212 if not pats and not opts['all']:
2220 if not pats and not opts['all']:
2213 raise util.Abort(_('no files or directories specified; '
2221 raise util.Abort(_('no files or directories specified; '
2214 'use --all to revert the whole repo'))
2222 'use --all to revert the whole repo'))
2215
2223
2216 parent, p2 = repo.dirstate.parents()
2224 parent, p2 = repo.dirstate.parents()
2217 if not opts['rev'] and p2 != nullid:
2225 if not opts['rev'] and p2 != nullid:
2218 raise util.Abort(_('uncommitted merge - please provide a '
2226 raise util.Abort(_('uncommitted merge - please provide a '
2219 'specific revision'))
2227 'specific revision'))
2220 ctx = repo.changectx(opts['rev'])
2228 ctx = repo.changectx(opts['rev'])
2221 node = ctx.node()
2229 node = ctx.node()
2222 mf = ctx.manifest()
2230 mf = ctx.manifest()
2223 if node == parent:
2231 if node == parent:
2224 pmf = mf
2232 pmf = mf
2225 else:
2233 else:
2226 pmf = None
2234 pmf = None
2227
2235
2228 # need all matching names in dirstate and manifest of target rev,
2236 # need all matching names in dirstate and manifest of target rev,
2229 # so have to walk both. do not print errors if files exist in one
2237 # so have to walk both. do not print errors if files exist in one
2230 # but not other.
2238 # but not other.
2231
2239
2232 names = {}
2240 names = {}
2233
2241
2234 wlock = repo.wlock()
2242 wlock = repo.wlock()
2235 try:
2243 try:
2236 # walk dirstate.
2244 # walk dirstate.
2237 files = []
2245 files = []
2238 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2246 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2239 badmatch=mf.has_key):
2247 badmatch=mf.has_key):
2240 names[abs] = (rel, exact)
2248 names[abs] = (rel, exact)
2241 if src != 'b':
2249 if src != 'b':
2242 files.append(abs)
2250 files.append(abs)
2243
2251
2244 # walk target manifest.
2252 # walk target manifest.
2245
2253
2246 def badmatch(path):
2254 def badmatch(path):
2247 if path in names:
2255 if path in names:
2248 return True
2256 return True
2249 path_ = path + '/'
2257 path_ = path + '/'
2250 for f in names:
2258 for f in names:
2251 if f.startswith(path_):
2259 if f.startswith(path_):
2252 return True
2260 return True
2253 return False
2261 return False
2254
2262
2255 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2263 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2256 badmatch=badmatch):
2264 badmatch=badmatch):
2257 if abs in names or src == 'b':
2265 if abs in names or src == 'b':
2258 continue
2266 continue
2259 names[abs] = (rel, exact)
2267 names[abs] = (rel, exact)
2260
2268
2261 changes = repo.status(files=files, match=names.has_key)[:4]
2269 changes = repo.status(files=files, match=names.has_key)[:4]
2262 modified, added, removed, deleted = map(dict.fromkeys, changes)
2270 modified, added, removed, deleted = map(dict.fromkeys, changes)
2263
2271
2264 # if f is a rename, also revert the source
2272 # if f is a rename, also revert the source
2265 cwd = repo.getcwd()
2273 cwd = repo.getcwd()
2266 for f in added:
2274 for f in added:
2267 src = repo.dirstate.copied(f)
2275 src = repo.dirstate.copied(f)
2268 if src and src not in names and repo.dirstate[src] == 'r':
2276 if src and src not in names and repo.dirstate[src] == 'r':
2269 removed[src] = None
2277 removed[src] = None
2270 names[src] = (repo.pathto(src, cwd), True)
2278 names[src] = (repo.pathto(src, cwd), True)
2271
2279
2272 def removeforget(abs):
2280 def removeforget(abs):
2273 if repo.dirstate[abs] == 'a':
2281 if repo.dirstate[abs] == 'a':
2274 return _('forgetting %s\n')
2282 return _('forgetting %s\n')
2275 return _('removing %s\n')
2283 return _('removing %s\n')
2276
2284
2277 revert = ([], _('reverting %s\n'))
2285 revert = ([], _('reverting %s\n'))
2278 add = ([], _('adding %s\n'))
2286 add = ([], _('adding %s\n'))
2279 remove = ([], removeforget)
2287 remove = ([], removeforget)
2280 undelete = ([], _('undeleting %s\n'))
2288 undelete = ([], _('undeleting %s\n'))
2281
2289
2282 disptable = (
2290 disptable = (
2283 # dispatch table:
2291 # dispatch table:
2284 # file state
2292 # file state
2285 # action if in target manifest
2293 # action if in target manifest
2286 # action if not in target manifest
2294 # action if not in target manifest
2287 # make backup if in target manifest
2295 # make backup if in target manifest
2288 # make backup if not in target manifest
2296 # make backup if not in target manifest
2289 (modified, revert, remove, True, True),
2297 (modified, revert, remove, True, True),
2290 (added, revert, remove, True, False),
2298 (added, revert, remove, True, False),
2291 (removed, undelete, None, False, False),
2299 (removed, undelete, None, False, False),
2292 (deleted, revert, remove, False, False),
2300 (deleted, revert, remove, False, False),
2293 )
2301 )
2294
2302
2295 entries = names.items()
2303 entries = names.items()
2296 entries.sort()
2304 entries.sort()
2297
2305
2298 for abs, (rel, exact) in entries:
2306 for abs, (rel, exact) in entries:
2299 mfentry = mf.get(abs)
2307 mfentry = mf.get(abs)
2300 target = repo.wjoin(abs)
2308 target = repo.wjoin(abs)
2301 def handle(xlist, dobackup):
2309 def handle(xlist, dobackup):
2302 xlist[0].append(abs)
2310 xlist[0].append(abs)
2303 if dobackup and not opts['no_backup'] and util.lexists(target):
2311 if dobackup and not opts['no_backup'] and util.lexists(target):
2304 bakname = "%s.orig" % rel
2312 bakname = "%s.orig" % rel
2305 ui.note(_('saving current version of %s as %s\n') %
2313 ui.note(_('saving current version of %s as %s\n') %
2306 (rel, bakname))
2314 (rel, bakname))
2307 if not opts.get('dry_run'):
2315 if not opts.get('dry_run'):
2308 util.copyfile(target, bakname)
2316 util.copyfile(target, bakname)
2309 if ui.verbose or not exact:
2317 if ui.verbose or not exact:
2310 msg = xlist[1]
2318 msg = xlist[1]
2311 if not isinstance(msg, basestring):
2319 if not isinstance(msg, basestring):
2312 msg = msg(abs)
2320 msg = msg(abs)
2313 ui.status(msg % rel)
2321 ui.status(msg % rel)
2314 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2322 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2315 if abs not in table: continue
2323 if abs not in table: continue
2316 # file has changed in dirstate
2324 # file has changed in dirstate
2317 if mfentry:
2325 if mfentry:
2318 handle(hitlist, backuphit)
2326 handle(hitlist, backuphit)
2319 elif misslist is not None:
2327 elif misslist is not None:
2320 handle(misslist, backupmiss)
2328 handle(misslist, backupmiss)
2321 break
2329 break
2322 else:
2330 else:
2323 if abs not in repo.dirstate:
2331 if abs not in repo.dirstate:
2324 if mfentry:
2332 if mfentry:
2325 handle(add, True)
2333 handle(add, True)
2326 elif exact:
2334 elif exact:
2327 ui.warn(_('file not managed: %s\n') % rel)
2335 ui.warn(_('file not managed: %s\n') % rel)
2328 continue
2336 continue
2329 # file has not changed in dirstate
2337 # file has not changed in dirstate
2330 if node == parent:
2338 if node == parent:
2331 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2339 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2332 continue
2340 continue
2333 if pmf is None:
2341 if pmf is None:
2334 # only need parent manifest in this unlikely case,
2342 # only need parent manifest in this unlikely case,
2335 # so do not read by default
2343 # so do not read by default
2336 pmf = repo.changectx(parent).manifest()
2344 pmf = repo.changectx(parent).manifest()
2337 if abs in pmf:
2345 if abs in pmf:
2338 if mfentry:
2346 if mfentry:
2339 # if version of file is same in parent and target
2347 # if version of file is same in parent and target
2340 # manifests, do nothing
2348 # manifests, do nothing
2341 if (pmf[abs] != mfentry or
2349 if (pmf[abs] != mfentry or
2342 pmf.flags(abs) != mf.flags(abs)):
2350 pmf.flags(abs) != mf.flags(abs)):
2343 handle(revert, False)
2351 handle(revert, False)
2344 else:
2352 else:
2345 handle(remove, False)
2353 handle(remove, False)
2346
2354
2347 if not opts.get('dry_run'):
2355 if not opts.get('dry_run'):
2348 def checkout(f):
2356 def checkout(f):
2349 fc = ctx[f]
2357 fc = ctx[f]
2350 repo.wwrite(f, fc.data(), fc.fileflags())
2358 repo.wwrite(f, fc.data(), fc.fileflags())
2351
2359
2352 audit_path = util.path_auditor(repo.root)
2360 audit_path = util.path_auditor(repo.root)
2353 for f in remove[0]:
2361 for f in remove[0]:
2354 if repo.dirstate[f] == 'a':
2362 if repo.dirstate[f] == 'a':
2355 repo.dirstate.forget(f)
2363 repo.dirstate.forget(f)
2356 continue
2364 continue
2357 audit_path(f)
2365 audit_path(f)
2358 try:
2366 try:
2359 util.unlink(repo.wjoin(f))
2367 util.unlink(repo.wjoin(f))
2360 except OSError:
2368 except OSError:
2361 pass
2369 pass
2362 repo.dirstate.remove(f)
2370 repo.dirstate.remove(f)
2363
2371
2364 for f in revert[0]:
2372 for f in revert[0]:
2365 checkout(f)
2373 checkout(f)
2366
2374
2367 for f in add[0]:
2375 for f in add[0]:
2368 checkout(f)
2376 checkout(f)
2369 repo.dirstate.add(f)
2377 repo.dirstate.add(f)
2370
2378
2371 normal = repo.dirstate.normallookup
2379 normal = repo.dirstate.normallookup
2372 if node == parent and p2 == nullid:
2380 if node == parent and p2 == nullid:
2373 normal = repo.dirstate.normal
2381 normal = repo.dirstate.normal
2374 for f in undelete[0]:
2382 for f in undelete[0]:
2375 checkout(f)
2383 checkout(f)
2376 normal(f)
2384 normal(f)
2377
2385
2378 finally:
2386 finally:
2379 del wlock
2387 del wlock
2380
2388
2381 def rollback(ui, repo):
2389 def rollback(ui, repo):
2382 """roll back the last transaction
2390 """roll back the last transaction
2383
2391
2384 This command should be used with care. There is only one level of
2392 This command should be used with care. There is only one level of
2385 rollback, and there is no way to undo a rollback. It will also
2393 rollback, and there is no way to undo a rollback. It will also
2386 restore the dirstate at the time of the last transaction, losing
2394 restore the dirstate at the time of the last transaction, losing
2387 any dirstate changes since that time.
2395 any dirstate changes since that time.
2388
2396
2389 Transactions are used to encapsulate the effects of all commands
2397 Transactions are used to encapsulate the effects of all commands
2390 that create new changesets or propagate existing changesets into a
2398 that create new changesets or propagate existing changesets into a
2391 repository. For example, the following commands are transactional,
2399 repository. For example, the following commands are transactional,
2392 and their effects can be rolled back:
2400 and their effects can be rolled back:
2393
2401
2394 commit
2402 commit
2395 import
2403 import
2396 pull
2404 pull
2397 push (with this repository as destination)
2405 push (with this repository as destination)
2398 unbundle
2406 unbundle
2399
2407
2400 This command is not intended for use on public repositories. Once
2408 This command is not intended for use on public repositories. Once
2401 changes are visible for pull by other users, rolling a transaction
2409 changes are visible for pull by other users, rolling a transaction
2402 back locally is ineffective (someone else may already have pulled
2410 back locally is ineffective (someone else may already have pulled
2403 the changes). Furthermore, a race is possible with readers of the
2411 the changes). Furthermore, a race is possible with readers of the
2404 repository; for example an in-progress pull from the repository
2412 repository; for example an in-progress pull from the repository
2405 may fail if a rollback is performed.
2413 may fail if a rollback is performed.
2406 """
2414 """
2407 repo.rollback()
2415 repo.rollback()
2408
2416
2409 def root(ui, repo):
2417 def root(ui, repo):
2410 """print the root (top) of the current working dir
2418 """print the root (top) of the current working dir
2411
2419
2412 Print the root directory of the current repository.
2420 Print the root directory of the current repository.
2413 """
2421 """
2414 ui.write(repo.root + "\n")
2422 ui.write(repo.root + "\n")
2415
2423
2416 def serve(ui, repo, **opts):
2424 def serve(ui, repo, **opts):
2417 """export the repository via HTTP
2425 """export the repository via HTTP
2418
2426
2419 Start a local HTTP repository browser and pull server.
2427 Start a local HTTP repository browser and pull server.
2420
2428
2421 By default, the server logs accesses to stdout and errors to
2429 By default, the server logs accesses to stdout and errors to
2422 stderr. Use the "-A" and "-E" options to log to files.
2430 stderr. Use the "-A" and "-E" options to log to files.
2423 """
2431 """
2424
2432
2425 if opts["stdio"]:
2433 if opts["stdio"]:
2426 if repo is None:
2434 if repo is None:
2427 raise hg.RepoError(_("There is no Mercurial repository here"
2435 raise hg.RepoError(_("There is no Mercurial repository here"
2428 " (.hg not found)"))
2436 " (.hg not found)"))
2429 s = sshserver.sshserver(ui, repo)
2437 s = sshserver.sshserver(ui, repo)
2430 s.serve_forever()
2438 s.serve_forever()
2431
2439
2432 parentui = ui.parentui or ui
2440 parentui = ui.parentui or ui
2433 optlist = ("name templates style address port prefix ipv6"
2441 optlist = ("name templates style address port prefix ipv6"
2434 " accesslog errorlog webdir_conf certificate")
2442 " accesslog errorlog webdir_conf certificate")
2435 for o in optlist.split():
2443 for o in optlist.split():
2436 if opts[o]:
2444 if opts[o]:
2437 parentui.setconfig("web", o, str(opts[o]))
2445 parentui.setconfig("web", o, str(opts[o]))
2438 if (repo is not None) and (repo.ui != parentui):
2446 if (repo is not None) and (repo.ui != parentui):
2439 repo.ui.setconfig("web", o, str(opts[o]))
2447 repo.ui.setconfig("web", o, str(opts[o]))
2440
2448
2441 if repo is None and not ui.config("web", "webdir_conf"):
2449 if repo is None and not ui.config("web", "webdir_conf"):
2442 raise hg.RepoError(_("There is no Mercurial repository here"
2450 raise hg.RepoError(_("There is no Mercurial repository here"
2443 " (.hg not found)"))
2451 " (.hg not found)"))
2444
2452
2445 class service:
2453 class service:
2446 def init(self):
2454 def init(self):
2447 util.set_signal_handler()
2455 util.set_signal_handler()
2448 try:
2456 try:
2449 self.httpd = hgweb.server.create_server(parentui, repo)
2457 self.httpd = hgweb.server.create_server(parentui, repo)
2450 except socket.error, inst:
2458 except socket.error, inst:
2451 raise util.Abort(_('cannot start server: ') + inst.args[1])
2459 raise util.Abort(_('cannot start server: ') + inst.args[1])
2452
2460
2453 if not ui.verbose: return
2461 if not ui.verbose: return
2454
2462
2455 if self.httpd.prefix:
2463 if self.httpd.prefix:
2456 prefix = self.httpd.prefix.strip('/') + '/'
2464 prefix = self.httpd.prefix.strip('/') + '/'
2457 else:
2465 else:
2458 prefix = ''
2466 prefix = ''
2459
2467
2460 if self.httpd.port != 80:
2468 if self.httpd.port != 80:
2461 ui.status(_('listening at http://%s:%d/%s\n') %
2469 ui.status(_('listening at http://%s:%d/%s\n') %
2462 (self.httpd.addr, self.httpd.port, prefix))
2470 (self.httpd.addr, self.httpd.port, prefix))
2463 else:
2471 else:
2464 ui.status(_('listening at http://%s/%s\n') %
2472 ui.status(_('listening at http://%s/%s\n') %
2465 (self.httpd.addr, prefix))
2473 (self.httpd.addr, prefix))
2466
2474
2467 def run(self):
2475 def run(self):
2468 self.httpd.serve_forever()
2476 self.httpd.serve_forever()
2469
2477
2470 service = service()
2478 service = service()
2471
2479
2472 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2480 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2473
2481
2474 def status(ui, repo, *pats, **opts):
2482 def status(ui, repo, *pats, **opts):
2475 """show changed files in the working directory
2483 """show changed files in the working directory
2476
2484
2477 Show status of files in the repository. If names are given, only
2485 Show status of files in the repository. If names are given, only
2478 files that match are shown. Files that are clean or ignored or
2486 files that match are shown. Files that are clean or ignored or
2479 source of a copy/move operation, are not listed unless -c (clean),
2487 source of a copy/move operation, are not listed unless -c (clean),
2480 -i (ignored), -C (copies) or -A is given. Unless options described
2488 -i (ignored), -C (copies) or -A is given. Unless options described
2481 with "show only ..." are given, the options -mardu are used.
2489 with "show only ..." are given, the options -mardu are used.
2482
2490
2483 NOTE: status may appear to disagree with diff if permissions have
2491 NOTE: status may appear to disagree with diff if permissions have
2484 changed or a merge has occurred. The standard diff format does not
2492 changed or a merge has occurred. The standard diff format does not
2485 report permission changes and diff only reports changes relative
2493 report permission changes and diff only reports changes relative
2486 to one merge parent.
2494 to one merge parent.
2487
2495
2488 If one revision is given, it is used as the base revision.
2496 If one revision is given, it is used as the base revision.
2489 If two revisions are given, the difference between them is shown.
2497 If two revisions are given, the difference between them is shown.
2490
2498
2491 The codes used to show the status of files are:
2499 The codes used to show the status of files are:
2492 M = modified
2500 M = modified
2493 A = added
2501 A = added
2494 R = removed
2502 R = removed
2495 C = clean
2503 C = clean
2496 ! = deleted, but still tracked
2504 ! = deleted, but still tracked
2497 ? = not tracked
2505 ? = not tracked
2498 I = ignored
2506 I = ignored
2499 = the previous added file was copied from here
2507 = the previous added file was copied from here
2500 """
2508 """
2501
2509
2502 all = opts['all']
2510 all = opts['all']
2503 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2511 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2504
2512
2505 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2513 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2506 cwd = (pats and repo.getcwd()) or ''
2514 cwd = (pats and repo.getcwd()) or ''
2507 modified, added, removed, deleted, unknown, ignored, clean = [
2515 modified, added, removed, deleted, unknown, ignored, clean = [
2508 n for n in repo.status(node1=node1, node2=node2, files=files,
2516 n for n in repo.status(node1=node1, node2=node2, files=files,
2509 match=matchfn,
2517 match=matchfn,
2510 list_ignored=all or opts['ignored'],
2518 list_ignored=all or opts['ignored'],
2511 list_clean=all or opts['clean'])]
2519 list_clean=all or opts['clean'])]
2512
2520
2513 changetypes = (('modified', 'M', modified),
2521 changetypes = (('modified', 'M', modified),
2514 ('added', 'A', added),
2522 ('added', 'A', added),
2515 ('removed', 'R', removed),
2523 ('removed', 'R', removed),
2516 ('deleted', '!', deleted),
2524 ('deleted', '!', deleted),
2517 ('unknown', '?', unknown),
2525 ('unknown', '?', unknown),
2518 ('ignored', 'I', ignored))
2526 ('ignored', 'I', ignored))
2519
2527
2520 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2528 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2521
2529
2522 end = opts['print0'] and '\0' or '\n'
2530 end = opts['print0'] and '\0' or '\n'
2523
2531
2524 for opt, char, changes in ([ct for ct in explicit_changetypes
2532 for opt, char, changes in ([ct for ct in explicit_changetypes
2525 if all or opts[ct[0]]]
2533 if all or opts[ct[0]]]
2526 or changetypes):
2534 or changetypes):
2527 if opts['no_status']:
2535 if opts['no_status']:
2528 format = "%%s%s" % end
2536 format = "%%s%s" % end
2529 else:
2537 else:
2530 format = "%s %%s%s" % (char, end)
2538 format = "%s %%s%s" % (char, end)
2531
2539
2532 for f in changes:
2540 for f in changes:
2533 ui.write(format % repo.pathto(f, cwd))
2541 ui.write(format % repo.pathto(f, cwd))
2534 if ((all or opts.get('copies')) and not opts.get('no_status')):
2542 if ((all or opts.get('copies')) and not opts.get('no_status')):
2535 copied = repo.dirstate.copied(f)
2543 copied = repo.dirstate.copied(f)
2536 if copied:
2544 if copied:
2537 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2545 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2538
2546
2539 def tag(ui, repo, name, rev_=None, **opts):
2547 def tag(ui, repo, name, rev_=None, **opts):
2540 """add a tag for the current or given revision
2548 """add a tag for the current or given revision
2541
2549
2542 Name a particular revision using <name>.
2550 Name a particular revision using <name>.
2543
2551
2544 Tags are used to name particular revisions of the repository and are
2552 Tags are used to name particular revisions of the repository and are
2545 very useful to compare different revision, to go back to significant
2553 very useful to compare different revision, to go back to significant
2546 earlier versions or to mark branch points as releases, etc.
2554 earlier versions or to mark branch points as releases, etc.
2547
2555
2548 If no revision is given, the parent of the working directory is used,
2556 If no revision is given, the parent of the working directory is used,
2549 or tip if no revision is checked out.
2557 or tip if no revision is checked out.
2550
2558
2551 To facilitate version control, distribution, and merging of tags,
2559 To facilitate version control, distribution, and merging of tags,
2552 they are stored as a file named ".hgtags" which is managed
2560 they are stored as a file named ".hgtags" which is managed
2553 similarly to other project files and can be hand-edited if
2561 similarly to other project files and can be hand-edited if
2554 necessary. The file '.hg/localtags' is used for local tags (not
2562 necessary. The file '.hg/localtags' is used for local tags (not
2555 shared among repositories).
2563 shared among repositories).
2556
2564
2557 See 'hg help dates' for a list of formats valid for -d/--date.
2565 See 'hg help dates' for a list of formats valid for -d/--date.
2558 """
2566 """
2559 if name in ['tip', '.', 'null']:
2567 if name in ['tip', '.', 'null']:
2560 raise util.Abort(_("the name '%s' is reserved") % name)
2568 raise util.Abort(_("the name '%s' is reserved") % name)
2561 if rev_ is not None:
2569 if rev_ is not None:
2562 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2570 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2563 "please use 'hg tag [-r REV] NAME' instead\n"))
2571 "please use 'hg tag [-r REV] NAME' instead\n"))
2564 if opts['rev']:
2572 if opts['rev']:
2565 raise util.Abort(_("use only one form to specify the revision"))
2573 raise util.Abort(_("use only one form to specify the revision"))
2566 if opts['rev'] and opts['remove']:
2574 if opts['rev'] and opts['remove']:
2567 raise util.Abort(_("--rev and --remove are incompatible"))
2575 raise util.Abort(_("--rev and --remove are incompatible"))
2568 if opts['rev']:
2576 if opts['rev']:
2569 rev_ = opts['rev']
2577 rev_ = opts['rev']
2570 message = opts['message']
2578 message = opts['message']
2571 if opts['remove']:
2579 if opts['remove']:
2572 tagtype = repo.tagtype(name)
2580 tagtype = repo.tagtype(name)
2573
2581
2574 if not tagtype:
2582 if not tagtype:
2575 raise util.Abort(_('tag %s does not exist') % name)
2583 raise util.Abort(_('tag %s does not exist') % name)
2576 if opts['local'] and tagtype == 'global':
2584 if opts['local'] and tagtype == 'global':
2577 raise util.Abort(_('%s tag is global') % name)
2585 raise util.Abort(_('%s tag is global') % name)
2578 if not opts['local'] and tagtype == 'local':
2586 if not opts['local'] and tagtype == 'local':
2579 raise util.Abort(_('%s tag is local') % name)
2587 raise util.Abort(_('%s tag is local') % name)
2580
2588
2581 rev_ = nullid
2589 rev_ = nullid
2582 if not message:
2590 if not message:
2583 message = _('Removed tag %s') % name
2591 message = _('Removed tag %s') % name
2584 elif name in repo.tags() and not opts['force']:
2592 elif name in repo.tags() and not opts['force']:
2585 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2593 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2586 % name)
2594 % name)
2587 if not rev_ and repo.dirstate.parents()[1] != nullid:
2595 if not rev_ and repo.dirstate.parents()[1] != nullid:
2588 raise util.Abort(_('uncommitted merge - please provide a '
2596 raise util.Abort(_('uncommitted merge - please provide a '
2589 'specific revision'))
2597 'specific revision'))
2590 r = repo.changectx(rev_).node()
2598 r = repo.changectx(rev_).node()
2591
2599
2592 if not message:
2600 if not message:
2593 message = _('Added tag %s for changeset %s') % (name, short(r))
2601 message = _('Added tag %s for changeset %s') % (name, short(r))
2594
2602
2595 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2603 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2596
2604
2597 def tags(ui, repo):
2605 def tags(ui, repo):
2598 """list repository tags
2606 """list repository tags
2599
2607
2600 List the repository tags.
2608 List the repository tags.
2601
2609
2602 This lists both regular and local tags. When the -v/--verbose switch
2610 This lists both regular and local tags. When the -v/--verbose switch
2603 is used, a third column "local" is printed for local tags.
2611 is used, a third column "local" is printed for local tags.
2604 """
2612 """
2605
2613
2606 l = repo.tagslist()
2614 l = repo.tagslist()
2607 l.reverse()
2615 l.reverse()
2608 hexfunc = ui.debugflag and hex or short
2616 hexfunc = ui.debugflag and hex or short
2609 tagtype = ""
2617 tagtype = ""
2610
2618
2611 for t, n in l:
2619 for t, n in l:
2612 if ui.quiet:
2620 if ui.quiet:
2613 ui.write("%s\n" % t)
2621 ui.write("%s\n" % t)
2614 continue
2622 continue
2615
2623
2616 try:
2624 try:
2617 hn = hexfunc(n)
2625 hn = hexfunc(n)
2618 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2626 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2619 except revlog.LookupError:
2627 except revlog.LookupError:
2620 r = " ?:%s" % hn
2628 r = " ?:%s" % hn
2621 else:
2629 else:
2622 spaces = " " * (30 - util.locallen(t))
2630 spaces = " " * (30 - util.locallen(t))
2623 if ui.verbose:
2631 if ui.verbose:
2624 if repo.tagtype(t) == 'local':
2632 if repo.tagtype(t) == 'local':
2625 tagtype = " local"
2633 tagtype = " local"
2626 else:
2634 else:
2627 tagtype = ""
2635 tagtype = ""
2628 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2636 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2629
2637
2630 def tip(ui, repo, **opts):
2638 def tip(ui, repo, **opts):
2631 """show the tip revision
2639 """show the tip revision
2632
2640
2633 Show the tip revision.
2641 Show the tip revision.
2634 """
2642 """
2635 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2643 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2636
2644
2637 def unbundle(ui, repo, fname1, *fnames, **opts):
2645 def unbundle(ui, repo, fname1, *fnames, **opts):
2638 """apply one or more changegroup files
2646 """apply one or more changegroup files
2639
2647
2640 Apply one or more compressed changegroup files generated by the
2648 Apply one or more compressed changegroup files generated by the
2641 bundle command.
2649 bundle command.
2642 """
2650 """
2643 fnames = (fname1,) + fnames
2651 fnames = (fname1,) + fnames
2644 for fname in fnames:
2652 for fname in fnames:
2645 if os.path.exists(fname):
2653 if os.path.exists(fname):
2646 f = open(fname, "rb")
2654 f = open(fname, "rb")
2647 else:
2655 else:
2648 f = urllib.urlopen(fname)
2656 f = urllib.urlopen(fname)
2649 gen = changegroup.readbundle(f, fname)
2657 gen = changegroup.readbundle(f, fname)
2650 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2658 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2651
2659
2652 return postincoming(ui, repo, modheads, opts['update'], None)
2660 return postincoming(ui, repo, modheads, opts['update'], None)
2653
2661
2654 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2662 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2655 """update working directory
2663 """update working directory
2656
2664
2657 Update the working directory to the specified revision, or the
2665 Update the working directory to the specified revision, or the
2658 tip of the current branch if none is specified.
2666 tip of the current branch if none is specified.
2659 See 'hg help dates' for a list of formats valid for -d/--date.
2667 See 'hg help dates' for a list of formats valid for -d/--date.
2660
2668
2661 If there are no outstanding changes in the working directory and
2669 If there are no outstanding changes in the working directory and
2662 there is a linear relationship between the current version and the
2670 there is a linear relationship between the current version and the
2663 requested version, the result is the requested version.
2671 requested version, the result is the requested version.
2664
2672
2665 To merge the working directory with another revision, use the
2673 To merge the working directory with another revision, use the
2666 merge command.
2674 merge command.
2667
2675
2668 By default, update will refuse to run if doing so would require
2676 By default, update will refuse to run if doing so would require
2669 discarding local changes.
2677 discarding local changes.
2670 """
2678 """
2671 if rev and node:
2679 if rev and node:
2672 raise util.Abort(_("please specify just one revision"))
2680 raise util.Abort(_("please specify just one revision"))
2673
2681
2674 if not rev:
2682 if not rev:
2675 rev = node
2683 rev = node
2676
2684
2677 if date:
2685 if date:
2678 if rev:
2686 if rev:
2679 raise util.Abort(_("you can't specify a revision and a date"))
2687 raise util.Abort(_("you can't specify a revision and a date"))
2680 rev = cmdutil.finddate(ui, repo, date)
2688 rev = cmdutil.finddate(ui, repo, date)
2681
2689
2682 if clean:
2690 if clean:
2683 return hg.clean(repo, rev)
2691 return hg.clean(repo, rev)
2684 else:
2692 else:
2685 return hg.update(repo, rev)
2693 return hg.update(repo, rev)
2686
2694
2687 def verify(ui, repo):
2695 def verify(ui, repo):
2688 """verify the integrity of the repository
2696 """verify the integrity of the repository
2689
2697
2690 Verify the integrity of the current repository.
2698 Verify the integrity of the current repository.
2691
2699
2692 This will perform an extensive check of the repository's
2700 This will perform an extensive check of the repository's
2693 integrity, validating the hashes and checksums of each entry in
2701 integrity, validating the hashes and checksums of each entry in
2694 the changelog, manifest, and tracked files, as well as the
2702 the changelog, manifest, and tracked files, as well as the
2695 integrity of their crosslinks and indices.
2703 integrity of their crosslinks and indices.
2696 """
2704 """
2697 return hg.verify(repo)
2705 return hg.verify(repo)
2698
2706
2699 def version_(ui):
2707 def version_(ui):
2700 """output version and copyright information"""
2708 """output version and copyright information"""
2701 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2709 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2702 % version.get_version())
2710 % version.get_version())
2703 ui.status(_(
2711 ui.status(_(
2704 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2712 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2705 "This is free software; see the source for copying conditions. "
2713 "This is free software; see the source for copying conditions. "
2706 "There is NO\nwarranty; "
2714 "There is NO\nwarranty; "
2707 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2715 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2708 ))
2716 ))
2709
2717
2710 # Command options and aliases are listed here, alphabetically
2718 # Command options and aliases are listed here, alphabetically
2711
2719
2712 globalopts = [
2720 globalopts = [
2713 ('R', 'repository', '',
2721 ('R', 'repository', '',
2714 _('repository root directory or symbolic path name')),
2722 _('repository root directory or symbolic path name')),
2715 ('', 'cwd', '', _('change working directory')),
2723 ('', 'cwd', '', _('change working directory')),
2716 ('y', 'noninteractive', None,
2724 ('y', 'noninteractive', None,
2717 _('do not prompt, assume \'yes\' for any required answers')),
2725 _('do not prompt, assume \'yes\' for any required answers')),
2718 ('q', 'quiet', None, _('suppress output')),
2726 ('q', 'quiet', None, _('suppress output')),
2719 ('v', 'verbose', None, _('enable additional output')),
2727 ('v', 'verbose', None, _('enable additional output')),
2720 ('', 'config', [], _('set/override config option')),
2728 ('', 'config', [], _('set/override config option')),
2721 ('', 'debug', None, _('enable debugging output')),
2729 ('', 'debug', None, _('enable debugging output')),
2722 ('', 'debugger', None, _('start debugger')),
2730 ('', 'debugger', None, _('start debugger')),
2723 ('', 'encoding', util._encoding, _('set the charset encoding')),
2731 ('', 'encoding', util._encoding, _('set the charset encoding')),
2724 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2732 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2725 ('', 'lsprof', None, _('print improved command execution profile')),
2733 ('', 'lsprof', None, _('print improved command execution profile')),
2726 ('', 'traceback', None, _('print traceback on exception')),
2734 ('', 'traceback', None, _('print traceback on exception')),
2727 ('', 'time', None, _('time how long the command takes')),
2735 ('', 'time', None, _('time how long the command takes')),
2728 ('', 'profile', None, _('print command execution profile')),
2736 ('', 'profile', None, _('print command execution profile')),
2729 ('', 'version', None, _('output version information and exit')),
2737 ('', 'version', None, _('output version information and exit')),
2730 ('h', 'help', None, _('display help and exit')),
2738 ('h', 'help', None, _('display help and exit')),
2731 ]
2739 ]
2732
2740
2733 dryrunopts = [('n', 'dry-run', None,
2741 dryrunopts = [('n', 'dry-run', None,
2734 _('do not perform actions, just print output'))]
2742 _('do not perform actions, just print output'))]
2735
2743
2736 remoteopts = [
2744 remoteopts = [
2737 ('e', 'ssh', '', _('specify ssh command to use')),
2745 ('e', 'ssh', '', _('specify ssh command to use')),
2738 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2746 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2739 ]
2747 ]
2740
2748
2741 walkopts = [
2749 walkopts = [
2742 ('I', 'include', [], _('include names matching the given patterns')),
2750 ('I', 'include', [], _('include names matching the given patterns')),
2743 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2751 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2744 ]
2752 ]
2745
2753
2746 commitopts = [
2754 commitopts = [
2747 ('m', 'message', '', _('use <text> as commit message')),
2755 ('m', 'message', '', _('use <text> as commit message')),
2748 ('l', 'logfile', '', _('read commit message from <file>')),
2756 ('l', 'logfile', '', _('read commit message from <file>')),
2749 ]
2757 ]
2750
2758
2751 commitopts2 = [
2759 commitopts2 = [
2752 ('d', 'date', '', _('record datecode as commit date')),
2760 ('d', 'date', '', _('record datecode as commit date')),
2753 ('u', 'user', '', _('record user as committer')),
2761 ('u', 'user', '', _('record user as committer')),
2754 ]
2762 ]
2755
2763
2756 table = {
2764 table = {
2757 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2765 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2758 "addremove":
2766 "addremove":
2759 (addremove,
2767 (addremove,
2760 [('s', 'similarity', '',
2768 [('s', 'similarity', '',
2761 _('guess renamed files by similarity (0<=s<=100)')),
2769 _('guess renamed files by similarity (0<=s<=100)')),
2762 ] + walkopts + dryrunopts,
2770 ] + walkopts + dryrunopts,
2763 _('hg addremove [OPTION]... [FILE]...')),
2771 _('hg addremove [OPTION]... [FILE]...')),
2764 "^annotate":
2772 "^annotate":
2765 (annotate,
2773 (annotate,
2766 [('r', 'rev', '', _('annotate the specified revision')),
2774 [('r', 'rev', '', _('annotate the specified revision')),
2767 ('f', 'follow', None, _('follow file copies and renames')),
2775 ('f', 'follow', None, _('follow file copies and renames')),
2768 ('a', 'text', None, _('treat all files as text')),
2776 ('a', 'text', None, _('treat all files as text')),
2769 ('u', 'user', None, _('list the author (long with -v)')),
2777 ('u', 'user', None, _('list the author (long with -v)')),
2770 ('d', 'date', None, _('list the date (short with -q)')),
2778 ('d', 'date', None, _('list the date (short with -q)')),
2771 ('n', 'number', None, _('list the revision number (default)')),
2779 ('n', 'number', None, _('list the revision number (default)')),
2772 ('c', 'changeset', None, _('list the changeset')),
2780 ('c', 'changeset', None, _('list the changeset')),
2773 ('l', 'line-number', None,
2781 ('l', 'line-number', None,
2774 _('show line number at the first appearance'))
2782 _('show line number at the first appearance'))
2775 ] + walkopts,
2783 ] + walkopts,
2776 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2784 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2777 "archive":
2785 "archive":
2778 (archive,
2786 (archive,
2779 [('', 'no-decode', None, _('do not pass files through decoders')),
2787 [('', 'no-decode', None, _('do not pass files through decoders')),
2780 ('p', 'prefix', '', _('directory prefix for files in archive')),
2788 ('p', 'prefix', '', _('directory prefix for files in archive')),
2781 ('r', 'rev', '', _('revision to distribute')),
2789 ('r', 'rev', '', _('revision to distribute')),
2782 ('t', 'type', '', _('type of distribution to create')),
2790 ('t', 'type', '', _('type of distribution to create')),
2783 ] + walkopts,
2791 ] + walkopts,
2784 _('hg archive [OPTION]... DEST')),
2792 _('hg archive [OPTION]... DEST')),
2785 "backout":
2793 "backout":
2786 (backout,
2794 (backout,
2787 [('', 'merge', None,
2795 [('', 'merge', None,
2788 _('merge with old dirstate parent after backout')),
2796 _('merge with old dirstate parent after backout')),
2789 ('', 'parent', '', _('parent to choose when backing out merge')),
2797 ('', 'parent', '', _('parent to choose when backing out merge')),
2790 ('r', 'rev', '', _('revision to backout')),
2798 ('r', 'rev', '', _('revision to backout')),
2791 ] + walkopts + commitopts + commitopts2,
2799 ] + walkopts + commitopts + commitopts2,
2792 _('hg backout [OPTION]... [-r] REV')),
2800 _('hg backout [OPTION]... [-r] REV')),
2793 "bisect":
2801 "bisect":
2794 (bisect,
2802 (bisect,
2795 [('r', 'reset', False, _('reset bisect state')),
2803 [('r', 'reset', False, _('reset bisect state')),
2796 ('g', 'good', False, _('mark changeset good')),
2804 ('g', 'good', False, _('mark changeset good')),
2797 ('b', 'bad', False, _('mark changeset bad')),
2805 ('b', 'bad', False, _('mark changeset bad')),
2798 ('s', 'skip', False, _('skip testing changeset')),
2806 ('s', 'skip', False, _('skip testing changeset')),
2799 ('U', 'noupdate', False, _('do not update to target'))],
2807 ('U', 'noupdate', False, _('do not update to target'))],
2800 _("hg bisect [-gbsr] [REV]")),
2808 _("hg bisect [-gbsr] [REV]")),
2801 "branch":
2809 "branch":
2802 (branch,
2810 (branch,
2803 [('f', 'force', None,
2811 [('f', 'force', None,
2804 _('set branch name even if it shadows an existing branch'))],
2812 _('set branch name even if it shadows an existing branch'))],
2805 _('hg branch [-f] [NAME]')),
2813 _('hg branch [-f] [NAME]')),
2806 "branches":
2814 "branches":
2807 (branches,
2815 (branches,
2808 [('a', 'active', False,
2816 [('a', 'active', False,
2809 _('show only branches that have unmerged heads'))],
2817 _('show only branches that have unmerged heads'))],
2810 _('hg branches [-a]')),
2818 _('hg branches [-a]')),
2811 "bundle":
2819 "bundle":
2812 (bundle,
2820 (bundle,
2813 [('f', 'force', None,
2821 [('f', 'force', None,
2814 _('run even when remote repository is unrelated')),
2822 _('run even when remote repository is unrelated')),
2815 ('r', 'rev', [],
2823 ('r', 'rev', [],
2816 _('a changeset you would like to bundle')),
2824 _('a changeset you would like to bundle')),
2817 ('', 'base', [],
2825 ('', 'base', [],
2818 _('a base changeset to specify instead of a destination')),
2826 _('a base changeset to specify instead of a destination')),
2819 ('a', 'all', None,
2827 ('a', 'all', None,
2820 _('bundle all changesets in the repository')),
2828 _('bundle all changesets in the repository')),
2821 ] + remoteopts,
2829 ] + remoteopts,
2822 _('hg bundle [-f] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
2830 _('hg bundle [-f] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
2823 "cat":
2831 "cat":
2824 (cat,
2832 (cat,
2825 [('o', 'output', '', _('print output to file with formatted name')),
2833 [('o', 'output', '', _('print output to file with formatted name')),
2826 ('r', 'rev', '', _('print the given revision')),
2834 ('r', 'rev', '', _('print the given revision')),
2827 ('', 'decode', None, _('apply any matching decode filter')),
2835 ('', 'decode', None, _('apply any matching decode filter')),
2828 ] + walkopts,
2836 ] + walkopts,
2829 _('hg cat [OPTION]... FILE...')),
2837 _('hg cat [OPTION]... FILE...')),
2830 "^clone":
2838 "^clone":
2831 (clone,
2839 (clone,
2832 [('U', 'noupdate', None, _('do not update the new working directory')),
2840 [('U', 'noupdate', None, _('do not update the new working directory')),
2833 ('r', 'rev', [],
2841 ('r', 'rev', [],
2834 _('a changeset you would like to have after cloning')),
2842 _('a changeset you would like to have after cloning')),
2835 ('', 'pull', None, _('use pull protocol to copy metadata')),
2843 ('', 'pull', None, _('use pull protocol to copy metadata')),
2836 ('', 'uncompressed', None,
2844 ('', 'uncompressed', None,
2837 _('use uncompressed transfer (fast over LAN)')),
2845 _('use uncompressed transfer (fast over LAN)')),
2838 ] + remoteopts,
2846 ] + remoteopts,
2839 _('hg clone [OPTION]... SOURCE [DEST]')),
2847 _('hg clone [OPTION]... SOURCE [DEST]')),
2840 "^commit|ci":
2848 "^commit|ci":
2841 (commit,
2849 (commit,
2842 [('A', 'addremove', None,
2850 [('A', 'addremove', None,
2843 _('mark new/missing files as added/removed before committing')),
2851 _('mark new/missing files as added/removed before committing')),
2844 ] + walkopts + commitopts + commitopts2,
2852 ] + walkopts + commitopts + commitopts2,
2845 _('hg commit [OPTION]... [FILE]...')),
2853 _('hg commit [OPTION]... [FILE]...')),
2846 "copy|cp":
2854 "copy|cp":
2847 (copy,
2855 (copy,
2848 [('A', 'after', None, _('record a copy that has already occurred')),
2856 [('A', 'after', None, _('record a copy that has already occurred')),
2849 ('f', 'force', None,
2857 ('f', 'force', None,
2850 _('forcibly copy over an existing managed file')),
2858 _('forcibly copy over an existing managed file')),
2851 ] + walkopts + dryrunopts,
2859 ] + walkopts + dryrunopts,
2852 _('hg copy [OPTION]... [SOURCE]... DEST')),
2860 _('hg copy [OPTION]... [SOURCE]... DEST')),
2853 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2861 "debugancestor": (debugancestor, [],
2862 _('hg debugancestor [INDEX] REV1 REV2')),
2854 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2863 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2855 "debugcomplete":
2864 "debugcomplete":
2856 (debugcomplete,
2865 (debugcomplete,
2857 [('o', 'options', None, _('show the command options'))],
2866 [('o', 'options', None, _('show the command options'))],
2858 _('hg debugcomplete [-o] CMD')),
2867 _('hg debugcomplete [-o] CMD')),
2859 "debugdate":
2868 "debugdate":
2860 (debugdate,
2869 (debugdate,
2861 [('e', 'extended', None, _('try extended date formats'))],
2870 [('e', 'extended', None, _('try extended date formats'))],
2862 _('hg debugdate [-e] DATE [RANGE]')),
2871 _('hg debugdate [-e] DATE [RANGE]')),
2863 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2872 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2864 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2873 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2865 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2874 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2866 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2875 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2867 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2876 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2868 "debugrawcommit|rawcommit":
2877 "debugrawcommit|rawcommit":
2869 (rawcommit,
2878 (rawcommit,
2870 [('p', 'parent', [], _('parent')),
2879 [('p', 'parent', [], _('parent')),
2871 ('F', 'files', '', _('file list'))
2880 ('F', 'files', '', _('file list'))
2872 ] + commitopts + commitopts2,
2881 ] + commitopts + commitopts2,
2873 _('hg debugrawcommit [OPTION]... [FILE]...')),
2882 _('hg debugrawcommit [OPTION]... [FILE]...')),
2874 "debugrebuildstate":
2883 "debugrebuildstate":
2875 (debugrebuildstate,
2884 (debugrebuildstate,
2876 [('r', 'rev', '', _('revision to rebuild to'))],
2885 [('r', 'rev', '', _('revision to rebuild to'))],
2877 _('hg debugrebuildstate [-r REV] [REV]')),
2886 _('hg debugrebuildstate [-r REV] [REV]')),
2878 "debugrename":
2887 "debugrename":
2879 (debugrename,
2888 (debugrename,
2880 [('r', 'rev', '', _('revision to debug'))],
2889 [('r', 'rev', '', _('revision to debug'))],
2881 _('hg debugrename [-r REV] FILE')),
2890 _('hg debugrename [-r REV] FILE')),
2882 "debugsetparents":
2891 "debugsetparents":
2883 (debugsetparents,
2892 (debugsetparents,
2884 [],
2893 [],
2885 _('hg debugsetparents REV1 [REV2]')),
2894 _('hg debugsetparents REV1 [REV2]')),
2886 "debugstate": (debugstate, [], _('hg debugstate')),
2895 "debugstate": (debugstate, [], _('hg debugstate')),
2887 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2896 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2888 "^diff":
2897 "^diff":
2889 (diff,
2898 (diff,
2890 [('r', 'rev', [], _('revision')),
2899 [('r', 'rev', [], _('revision')),
2891 ('a', 'text', None, _('treat all files as text')),
2900 ('a', 'text', None, _('treat all files as text')),
2892 ('p', 'show-function', None,
2901 ('p', 'show-function', None,
2893 _('show which function each change is in')),
2902 _('show which function each change is in')),
2894 ('g', 'git', None, _('use git extended diff format')),
2903 ('g', 'git', None, _('use git extended diff format')),
2895 ('', 'nodates', None, _("don't include dates in diff headers")),
2904 ('', 'nodates', None, _("don't include dates in diff headers")),
2896 ('w', 'ignore-all-space', None,
2905 ('w', 'ignore-all-space', None,
2897 _('ignore white space when comparing lines')),
2906 _('ignore white space when comparing lines')),
2898 ('b', 'ignore-space-change', None,
2907 ('b', 'ignore-space-change', None,
2899 _('ignore changes in the amount of white space')),
2908 _('ignore changes in the amount of white space')),
2900 ('B', 'ignore-blank-lines', None,
2909 ('B', 'ignore-blank-lines', None,
2901 _('ignore changes whose lines are all blank')),
2910 _('ignore changes whose lines are all blank')),
2902 ('U', 'unified', 3,
2911 ('U', 'unified', 3,
2903 _('number of lines of context to show'))
2912 _('number of lines of context to show'))
2904 ] + walkopts,
2913 ] + walkopts,
2905 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2914 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2906 "^export":
2915 "^export":
2907 (export,
2916 (export,
2908 [('o', 'output', '', _('print output to file with formatted name')),
2917 [('o', 'output', '', _('print output to file with formatted name')),
2909 ('a', 'text', None, _('treat all files as text')),
2918 ('a', 'text', None, _('treat all files as text')),
2910 ('g', 'git', None, _('use git extended diff format')),
2919 ('g', 'git', None, _('use git extended diff format')),
2911 ('', 'nodates', None, _("don't include dates in diff headers")),
2920 ('', 'nodates', None, _("don't include dates in diff headers")),
2912 ('', 'switch-parent', None, _('diff against the second parent'))],
2921 ('', 'switch-parent', None, _('diff against the second parent'))],
2913 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2922 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2914 "grep":
2923 "grep":
2915 (grep,
2924 (grep,
2916 [('0', 'print0', None, _('end fields with NUL')),
2925 [('0', 'print0', None, _('end fields with NUL')),
2917 ('', 'all', None, _('print all revisions that match')),
2926 ('', 'all', None, _('print all revisions that match')),
2918 ('f', 'follow', None,
2927 ('f', 'follow', None,
2919 _('follow changeset history, or file history across copies and renames')),
2928 _('follow changeset history, or file history across copies and renames')),
2920 ('i', 'ignore-case', None, _('ignore case when matching')),
2929 ('i', 'ignore-case', None, _('ignore case when matching')),
2921 ('l', 'files-with-matches', None,
2930 ('l', 'files-with-matches', None,
2922 _('print only filenames and revs that match')),
2931 _('print only filenames and revs that match')),
2923 ('n', 'line-number', None, _('print matching line numbers')),
2932 ('n', 'line-number', None, _('print matching line numbers')),
2924 ('r', 'rev', [], _('search in given revision range')),
2933 ('r', 'rev', [], _('search in given revision range')),
2925 ('u', 'user', None, _('list the author (long with -v)')),
2934 ('u', 'user', None, _('list the author (long with -v)')),
2926 ('d', 'date', None, _('list the date (short with -q)')),
2935 ('d', 'date', None, _('list the date (short with -q)')),
2927 ] + walkopts,
2936 ] + walkopts,
2928 _('hg grep [OPTION]... PATTERN [FILE]...')),
2937 _('hg grep [OPTION]... PATTERN [FILE]...')),
2929 "heads":
2938 "heads":
2930 (heads,
2939 (heads,
2931 [('', 'style', '', _('display using template map file')),
2940 [('', 'style', '', _('display using template map file')),
2932 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2941 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2933 ('', 'template', '', _('display with template'))],
2942 ('', 'template', '', _('display with template'))],
2934 _('hg heads [-r REV] [REV]...')),
2943 _('hg heads [-r REV] [REV]...')),
2935 "help": (help_, [], _('hg help [COMMAND]')),
2944 "help": (help_, [], _('hg help [COMMAND]')),
2936 "identify|id":
2945 "identify|id":
2937 (identify,
2946 (identify,
2938 [('r', 'rev', '', _('identify the specified rev')),
2947 [('r', 'rev', '', _('identify the specified rev')),
2939 ('n', 'num', None, _('show local revision number')),
2948 ('n', 'num', None, _('show local revision number')),
2940 ('i', 'id', None, _('show global revision id')),
2949 ('i', 'id', None, _('show global revision id')),
2941 ('b', 'branch', None, _('show branch')),
2950 ('b', 'branch', None, _('show branch')),
2942 ('t', 'tags', None, _('show tags'))],
2951 ('t', 'tags', None, _('show tags'))],
2943 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2952 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2944 "import|patch":
2953 "import|patch":
2945 (import_,
2954 (import_,
2946 [('p', 'strip', 1,
2955 [('p', 'strip', 1,
2947 _('directory strip option for patch. This has the same\n'
2956 _('directory strip option for patch. This has the same\n'
2948 'meaning as the corresponding patch option')),
2957 'meaning as the corresponding patch option')),
2949 ('b', 'base', '', _('base path')),
2958 ('b', 'base', '', _('base path')),
2950 ('f', 'force', None,
2959 ('f', 'force', None,
2951 _('skip check for outstanding uncommitted changes')),
2960 _('skip check for outstanding uncommitted changes')),
2952 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2961 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2953 ('', 'exact', None,
2962 ('', 'exact', None,
2954 _('apply patch to the nodes from which it was generated')),
2963 _('apply patch to the nodes from which it was generated')),
2955 ('', 'import-branch', None,
2964 ('', 'import-branch', None,
2956 _('Use any branch information in patch (implied by --exact)'))] +
2965 _('Use any branch information in patch (implied by --exact)'))] +
2957 commitopts + commitopts2,
2966 commitopts + commitopts2,
2958 _('hg import [OPTION]... PATCH...')),
2967 _('hg import [OPTION]... PATCH...')),
2959 "incoming|in":
2968 "incoming|in":
2960 (incoming,
2969 (incoming,
2961 [('M', 'no-merges', None, _('do not show merges')),
2970 [('M', 'no-merges', None, _('do not show merges')),
2962 ('f', 'force', None,
2971 ('f', 'force', None,
2963 _('run even when remote repository is unrelated')),
2972 _('run even when remote repository is unrelated')),
2964 ('', 'style', '', _('display using template map file')),
2973 ('', 'style', '', _('display using template map file')),
2965 ('n', 'newest-first', None, _('show newest record first')),
2974 ('n', 'newest-first', None, _('show newest record first')),
2966 ('', 'bundle', '', _('file to store the bundles into')),
2975 ('', 'bundle', '', _('file to store the bundles into')),
2967 ('p', 'patch', None, _('show patch')),
2976 ('p', 'patch', None, _('show patch')),
2968 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2977 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2969 ('', 'template', '', _('display with template')),
2978 ('', 'template', '', _('display with template')),
2970 ] + remoteopts,
2979 ] + remoteopts,
2971 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2980 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2972 ' [--bundle FILENAME] [SOURCE]')),
2981 ' [--bundle FILENAME] [SOURCE]')),
2973 "^init":
2982 "^init":
2974 (init,
2983 (init,
2975 remoteopts,
2984 remoteopts,
2976 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2985 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2977 "locate":
2986 "locate":
2978 (locate,
2987 (locate,
2979 [('r', 'rev', '', _('search the repository as it stood at rev')),
2988 [('r', 'rev', '', _('search the repository as it stood at rev')),
2980 ('0', 'print0', None,
2989 ('0', 'print0', None,
2981 _('end filenames with NUL, for use with xargs')),
2990 _('end filenames with NUL, for use with xargs')),
2982 ('f', 'fullpath', None,
2991 ('f', 'fullpath', None,
2983 _('print complete paths from the filesystem root')),
2992 _('print complete paths from the filesystem root')),
2984 ] + walkopts,
2993 ] + walkopts,
2985 _('hg locate [OPTION]... [PATTERN]...')),
2994 _('hg locate [OPTION]... [PATTERN]...')),
2986 "^log|history":
2995 "^log|history":
2987 (log,
2996 (log,
2988 [('f', 'follow', None,
2997 [('f', 'follow', None,
2989 _('follow changeset history, or file history across copies and renames')),
2998 _('follow changeset history, or file history across copies and renames')),
2990 ('', 'follow-first', None,
2999 ('', 'follow-first', None,
2991 _('only follow the first parent of merge changesets')),
3000 _('only follow the first parent of merge changesets')),
2992 ('d', 'date', '', _('show revs matching date spec')),
3001 ('d', 'date', '', _('show revs matching date spec')),
2993 ('C', 'copies', None, _('show copied files')),
3002 ('C', 'copies', None, _('show copied files')),
2994 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
3003 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2995 ('l', 'limit', '', _('limit number of changes displayed')),
3004 ('l', 'limit', '', _('limit number of changes displayed')),
2996 ('r', 'rev', [], _('show the specified revision or range')),
3005 ('r', 'rev', [], _('show the specified revision or range')),
2997 ('', 'removed', None, _('include revs where files were removed')),
3006 ('', 'removed', None, _('include revs where files were removed')),
2998 ('M', 'no-merges', None, _('do not show merges')),
3007 ('M', 'no-merges', None, _('do not show merges')),
2999 ('', 'style', '', _('display using template map file')),
3008 ('', 'style', '', _('display using template map file')),
3000 ('m', 'only-merges', None, _('show only merges')),
3009 ('m', 'only-merges', None, _('show only merges')),
3001 ('b', 'only-branch', [],
3010 ('b', 'only-branch', [],
3002 _('show only changesets within the given named branch')),
3011 _('show only changesets within the given named branch')),
3003 ('p', 'patch', None, _('show patch')),
3012 ('p', 'patch', None, _('show patch')),
3004 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
3013 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
3005 ('', 'template', '', _('display with template')),
3014 ('', 'template', '', _('display with template')),
3006 ] + walkopts,
3015 ] + walkopts,
3007 _('hg log [OPTION]... [FILE]')),
3016 _('hg log [OPTION]... [FILE]')),
3008 "manifest":
3017 "manifest":
3009 (manifest,
3018 (manifest,
3010 [('r', 'rev', '', _('revision to display'))],
3019 [('r', 'rev', '', _('revision to display'))],
3011 _('hg manifest [-r REV]')),
3020 _('hg manifest [-r REV]')),
3012 "^merge":
3021 "^merge":
3013 (merge,
3022 (merge,
3014 [('f', 'force', None, _('force a merge with outstanding changes')),
3023 [('f', 'force', None, _('force a merge with outstanding changes')),
3015 ('r', 'rev', '', _('revision to merge')),
3024 ('r', 'rev', '', _('revision to merge')),
3016 ],
3025 ],
3017 _('hg merge [-f] [[-r] REV]')),
3026 _('hg merge [-f] [[-r] REV]')),
3018 "outgoing|out":
3027 "outgoing|out":
3019 (outgoing,
3028 (outgoing,
3020 [('M', 'no-merges', None, _('do not show merges')),
3029 [('M', 'no-merges', None, _('do not show merges')),
3021 ('f', 'force', None,
3030 ('f', 'force', None,
3022 _('run even when remote repository is unrelated')),
3031 _('run even when remote repository is unrelated')),
3023 ('p', 'patch', None, _('show patch')),
3032 ('p', 'patch', None, _('show patch')),
3024 ('', 'style', '', _('display using template map file')),
3033 ('', 'style', '', _('display using template map file')),
3025 ('r', 'rev', [], _('a specific revision you would like to push')),
3034 ('r', 'rev', [], _('a specific revision you would like to push')),
3026 ('n', 'newest-first', None, _('show newest record first')),
3035 ('n', 'newest-first', None, _('show newest record first')),
3027 ('', 'template', '', _('display with template')),
3036 ('', 'template', '', _('display with template')),
3028 ] + remoteopts,
3037 ] + remoteopts,
3029 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
3038 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
3030 "^parents":
3039 "^parents":
3031 (parents,
3040 (parents,
3032 [('r', 'rev', '', _('show parents from the specified rev')),
3041 [('r', 'rev', '', _('show parents from the specified rev')),
3033 ('', 'style', '', _('display using template map file')),
3042 ('', 'style', '', _('display using template map file')),
3034 ('', 'template', '', _('display with template'))],
3043 ('', 'template', '', _('display with template'))],
3035 _('hg parents [-r REV] [FILE]')),
3044 _('hg parents [-r REV] [FILE]')),
3036 "paths": (paths, [], _('hg paths [NAME]')),
3045 "paths": (paths, [], _('hg paths [NAME]')),
3037 "^pull":
3046 "^pull":
3038 (pull,
3047 (pull,
3039 [('u', 'update', None,
3048 [('u', 'update', None,
3040 _('update to new tip if changesets were pulled')),
3049 _('update to new tip if changesets were pulled')),
3041 ('f', 'force', None,
3050 ('f', 'force', None,
3042 _('run even when remote repository is unrelated')),
3051 _('run even when remote repository is unrelated')),
3043 ('r', 'rev', [],
3052 ('r', 'rev', [],
3044 _('a specific revision up to which you would like to pull')),
3053 _('a specific revision up to which you would like to pull')),
3045 ] + remoteopts,
3054 ] + remoteopts,
3046 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3055 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3047 "^push":
3056 "^push":
3048 (push,
3057 (push,
3049 [('f', 'force', None, _('force push')),
3058 [('f', 'force', None, _('force push')),
3050 ('r', 'rev', [], _('a specific revision you would like to push')),
3059 ('r', 'rev', [], _('a specific revision you would like to push')),
3051 ] + remoteopts,
3060 ] + remoteopts,
3052 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3061 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3053 "recover": (recover, [], _('hg recover')),
3062 "recover": (recover, [], _('hg recover')),
3054 "^remove|rm":
3063 "^remove|rm":
3055 (remove,
3064 (remove,
3056 [('A', 'after', None, _('record remove without deleting')),
3065 [('A', 'after', None, _('record remove without deleting')),
3057 ('f', 'force', None, _('remove file even if modified')),
3066 ('f', 'force', None, _('remove file even if modified')),
3058 ] + walkopts,
3067 ] + walkopts,
3059 _('hg remove [OPTION]... FILE...')),
3068 _('hg remove [OPTION]... FILE...')),
3060 "rename|mv":
3069 "rename|mv":
3061 (rename,
3070 (rename,
3062 [('A', 'after', None, _('record a rename that has already occurred')),
3071 [('A', 'after', None, _('record a rename that has already occurred')),
3063 ('f', 'force', None,
3072 ('f', 'force', None,
3064 _('forcibly copy over an existing managed file')),
3073 _('forcibly copy over an existing managed file')),
3065 ] + walkopts + dryrunopts,
3074 ] + walkopts + dryrunopts,
3066 _('hg rename [OPTION]... SOURCE... DEST')),
3075 _('hg rename [OPTION]... SOURCE... DEST')),
3067 "revert":
3076 "revert":
3068 (revert,
3077 (revert,
3069 [('a', 'all', None, _('revert all changes when no arguments given')),
3078 [('a', 'all', None, _('revert all changes when no arguments given')),
3070 ('d', 'date', '', _('tipmost revision matching date')),
3079 ('d', 'date', '', _('tipmost revision matching date')),
3071 ('r', 'rev', '', _('revision to revert to')),
3080 ('r', 'rev', '', _('revision to revert to')),
3072 ('', 'no-backup', None, _('do not save backup copies of files')),
3081 ('', 'no-backup', None, _('do not save backup copies of files')),
3073 ] + walkopts + dryrunopts,
3082 ] + walkopts + dryrunopts,
3074 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3083 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3075 "rollback": (rollback, [], _('hg rollback')),
3084 "rollback": (rollback, [], _('hg rollback')),
3076 "root": (root, [], _('hg root')),
3085 "root": (root, [], _('hg root')),
3077 "^serve":
3086 "^serve":
3078 (serve,
3087 (serve,
3079 [('A', 'accesslog', '', _('name of access log file to write to')),
3088 [('A', 'accesslog', '', _('name of access log file to write to')),
3080 ('d', 'daemon', None, _('run server in background')),
3089 ('d', 'daemon', None, _('run server in background')),
3081 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3090 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3082 ('E', 'errorlog', '', _('name of error log file to write to')),
3091 ('E', 'errorlog', '', _('name of error log file to write to')),
3083 ('p', 'port', 0, _('port to use (default: 8000)')),
3092 ('p', 'port', 0, _('port to use (default: 8000)')),
3084 ('a', 'address', '', _('address to use')),
3093 ('a', 'address', '', _('address to use')),
3085 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3094 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3086 ('n', 'name', '',
3095 ('n', 'name', '',
3087 _('name to show in web pages (default: working dir)')),
3096 _('name to show in web pages (default: working dir)')),
3088 ('', 'webdir-conf', '', _('name of the webdir config file'
3097 ('', 'webdir-conf', '', _('name of the webdir config file'
3089 ' (serve more than one repo)')),
3098 ' (serve more than one repo)')),
3090 ('', 'pid-file', '', _('name of file to write process ID to')),
3099 ('', 'pid-file', '', _('name of file to write process ID to')),
3091 ('', 'stdio', None, _('for remote clients')),
3100 ('', 'stdio', None, _('for remote clients')),
3092 ('t', 'templates', '', _('web templates to use')),
3101 ('t', 'templates', '', _('web templates to use')),
3093 ('', 'style', '', _('template style to use')),
3102 ('', 'style', '', _('template style to use')),
3094 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3103 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3095 ('', 'certificate', '', _('SSL certificate file'))],
3104 ('', 'certificate', '', _('SSL certificate file'))],
3096 _('hg serve [OPTION]...')),
3105 _('hg serve [OPTION]...')),
3097 "showconfig|debugconfig":
3106 "showconfig|debugconfig":
3098 (showconfig,
3107 (showconfig,
3099 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3108 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3100 _('hg showconfig [-u] [NAME]...')),
3109 _('hg showconfig [-u] [NAME]...')),
3101 "^status|st":
3110 "^status|st":
3102 (status,
3111 (status,
3103 [('A', 'all', None, _('show status of all files')),
3112 [('A', 'all', None, _('show status of all files')),
3104 ('m', 'modified', None, _('show only modified files')),
3113 ('m', 'modified', None, _('show only modified files')),
3105 ('a', 'added', None, _('show only added files')),
3114 ('a', 'added', None, _('show only added files')),
3106 ('r', 'removed', None, _('show only removed files')),
3115 ('r', 'removed', None, _('show only removed files')),
3107 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3116 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3108 ('c', 'clean', None, _('show only files without changes')),
3117 ('c', 'clean', None, _('show only files without changes')),
3109 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3118 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3110 ('i', 'ignored', None, _('show only ignored files')),
3119 ('i', 'ignored', None, _('show only ignored files')),
3111 ('n', 'no-status', None, _('hide status prefix')),
3120 ('n', 'no-status', None, _('hide status prefix')),
3112 ('C', 'copies', None, _('show source of copied files')),
3121 ('C', 'copies', None, _('show source of copied files')),
3113 ('0', 'print0', None,
3122 ('0', 'print0', None,
3114 _('end filenames with NUL, for use with xargs')),
3123 _('end filenames with NUL, for use with xargs')),
3115 ('', 'rev', [], _('show difference from revision')),
3124 ('', 'rev', [], _('show difference from revision')),
3116 ] + walkopts,
3125 ] + walkopts,
3117 _('hg status [OPTION]... [FILE]...')),
3126 _('hg status [OPTION]... [FILE]...')),
3118 "tag":
3127 "tag":
3119 (tag,
3128 (tag,
3120 [('f', 'force', None, _('replace existing tag')),
3129 [('f', 'force', None, _('replace existing tag')),
3121 ('l', 'local', None, _('make the tag local')),
3130 ('l', 'local', None, _('make the tag local')),
3122 ('r', 'rev', '', _('revision to tag')),
3131 ('r', 'rev', '', _('revision to tag')),
3123 ('', 'remove', None, _('remove a tag')),
3132 ('', 'remove', None, _('remove a tag')),
3124 # -l/--local is already there, commitopts cannot be used
3133 # -l/--local is already there, commitopts cannot be used
3125 ('m', 'message', '', _('use <text> as commit message')),
3134 ('m', 'message', '', _('use <text> as commit message')),
3126 ] + commitopts2,
3135 ] + commitopts2,
3127 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3136 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3128 "tags": (tags, [], _('hg tags')),
3137 "tags": (tags, [], _('hg tags')),
3129 "tip":
3138 "tip":
3130 (tip,
3139 (tip,
3131 [('', 'style', '', _('display using template map file')),
3140 [('', 'style', '', _('display using template map file')),
3132 ('p', 'patch', None, _('show patch')),
3141 ('p', 'patch', None, _('show patch')),
3133 ('', 'template', '', _('display with template'))],
3142 ('', 'template', '', _('display with template'))],
3134 _('hg tip [-p]')),
3143 _('hg tip [-p]')),
3135 "unbundle":
3144 "unbundle":
3136 (unbundle,
3145 (unbundle,
3137 [('u', 'update', None,
3146 [('u', 'update', None,
3138 _('update to new tip if changesets were unbundled'))],
3147 _('update to new tip if changesets were unbundled'))],
3139 _('hg unbundle [-u] FILE...')),
3148 _('hg unbundle [-u] FILE...')),
3140 "^update|up|checkout|co":
3149 "^update|up|checkout|co":
3141 (update,
3150 (update,
3142 [('C', 'clean', None, _('overwrite locally modified files')),
3151 [('C', 'clean', None, _('overwrite locally modified files')),
3143 ('d', 'date', '', _('tipmost revision matching date')),
3152 ('d', 'date', '', _('tipmost revision matching date')),
3144 ('r', 'rev', '', _('revision'))],
3153 ('r', 'rev', '', _('revision'))],
3145 _('hg update [-C] [-d DATE] [[-r] REV]')),
3154 _('hg update [-C] [-d DATE] [[-r] REV]')),
3146 "verify": (verify, [], _('hg verify')),
3155 "verify": (verify, [], _('hg verify')),
3147 "version": (version_, [], _('hg version')),
3156 "version": (version_, [], _('hg version')),
3148 }
3157 }
3149
3158
3150 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3159 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3151 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3160 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3152 optionalrepo = ("identify paths serve showconfig")
3161 optionalrepo = ("identify paths serve showconfig")
General Comments 0
You need to be logged in to leave comments. Login now