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