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