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