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