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