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