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