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