##// END OF EJS Templates
cat --decode: Drop short option, use opts.get() instead of opts[]...
Thomas Arendsen Hein -
r6094:3998c1b0 default
parent child Browse files
Show More
@@ -1,3095 +1,3095 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import os, re, sys, urllib
10 import os, re, sys, urllib
11 import hg, util, revlog, bundlerepo, extensions
11 import hg, util, revlog, bundlerepo, extensions
12 import difflib, patch, time, help, mdiff, tempfile
12 import difflib, patch, time, help, mdiff, tempfile
13 import errno, version, socket
13 import errno, version, socket
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
15
15
16 # Commands start here, listed alphabetically
16 # Commands start here, listed alphabetically
17
17
18 def add(ui, repo, *pats, **opts):
18 def add(ui, repo, *pats, **opts):
19 """add the specified files on the next commit
19 """add the specified files on the next commit
20
20
21 Schedule files to be version controlled and added to the repository.
21 Schedule files to be version controlled and added to the repository.
22
22
23 The files will be added to the repository at the next commit. To
23 The files will be added to the repository at the next commit. To
24 undo an add before that, see hg revert.
24 undo an add before that, see hg revert.
25
25
26 If no names are given, add all files in the repository.
26 If no names are given, add all files in the repository.
27 """
27 """
28
28
29 rejected = None
29 rejected = None
30 exacts = {}
30 exacts = {}
31 names = []
31 names = []
32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
33 badmatch=util.always):
33 badmatch=util.always):
34 if exact:
34 if exact:
35 if ui.verbose:
35 if ui.verbose:
36 ui.status(_('adding %s\n') % rel)
36 ui.status(_('adding %s\n') % rel)
37 names.append(abs)
37 names.append(abs)
38 exacts[abs] = 1
38 exacts[abs] = 1
39 elif abs not in repo.dirstate:
39 elif abs not in repo.dirstate:
40 ui.status(_('adding %s\n') % rel)
40 ui.status(_('adding %s\n') % rel)
41 names.append(abs)
41 names.append(abs)
42 if not opts.get('dry_run'):
42 if not opts.get('dry_run'):
43 rejected = repo.add(names)
43 rejected = repo.add(names)
44 rejected = [p for p in rejected if p in exacts]
44 rejected = [p for p in rejected if p in exacts]
45 return rejected and 1 or 0
45 return rejected and 1 or 0
46
46
47 def addremove(ui, repo, *pats, **opts):
47 def addremove(ui, repo, *pats, **opts):
48 """add all new files, delete all missing files
48 """add all new files, delete all missing files
49
49
50 Add all new files and remove all missing files from the repository.
50 Add all new files and remove all missing files from the repository.
51
51
52 New files are ignored if they match any of the patterns in .hgignore. As
52 New files are ignored if they match any of the patterns in .hgignore. As
53 with add, these changes take effect at the next commit.
53 with add, these changes take effect at the next commit.
54
54
55 Use the -s option to detect renamed files. With a parameter > 0,
55 Use the -s option to detect renamed files. With a parameter > 0,
56 this compares every removed file with every added file and records
56 this compares every removed file with every added file and records
57 those similar enough as renames. This option takes a percentage
57 those similar enough as renames. This option takes a percentage
58 between 0 (disabled) and 100 (files must be identical) as its
58 between 0 (disabled) and 100 (files must be identical) as its
59 parameter. Detecting renamed files this way can be expensive.
59 parameter. Detecting renamed files this way can be expensive.
60 """
60 """
61 try:
61 try:
62 sim = float(opts.get('similarity') or 0)
62 sim = float(opts.get('similarity') or 0)
63 except ValueError:
63 except ValueError:
64 raise util.Abort(_('similarity must be a number'))
64 raise util.Abort(_('similarity must be a number'))
65 if sim < 0 or sim > 100:
65 if sim < 0 or sim > 100:
66 raise util.Abort(_('similarity must be between 0 and 100'))
66 raise util.Abort(_('similarity must be between 0 and 100'))
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
68
68
69 def annotate(ui, repo, *pats, **opts):
69 def annotate(ui, repo, *pats, **opts):
70 """show changeset information per file line
70 """show changeset information per file line
71
71
72 List changes in files, showing the revision id responsible for each line
72 List changes in files, showing the revision id responsible for each line
73
73
74 This command is useful to discover who did a change or when a change took
74 This command is useful to discover who did a change or when a change took
75 place.
75 place.
76
76
77 Without the -a option, annotate will avoid processing files it
77 Without the -a option, annotate will avoid processing files it
78 detects as binary. With -a, annotate will generate an annotation
78 detects as binary. With -a, annotate will generate an annotation
79 anyway, probably with undesirable results.
79 anyway, probably with undesirable results.
80 """
80 """
81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
82
82
83 if not pats:
83 if not pats:
84 raise util.Abort(_('at least one file name or pattern required'))
84 raise util.Abort(_('at least one file name or pattern required'))
85
85
86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
87 ('number', lambda x: str(x[0].rev())),
87 ('number', lambda x: str(x[0].rev())),
88 ('changeset', lambda x: short(x[0].node())),
88 ('changeset', lambda x: short(x[0].node())),
89 ('date', getdate),
89 ('date', getdate),
90 ('follow', lambda x: x[0].path()),
90 ('follow', lambda x: x[0].path()),
91 ]
91 ]
92
92
93 if (not opts['user'] and not opts['changeset'] and not opts['date']
93 if (not opts['user'] and not opts['changeset'] and not opts['date']
94 and not opts['follow']):
94 and not opts['follow']):
95 opts['number'] = 1
95 opts['number'] = 1
96
96
97 linenumber = opts.get('line_number') is not None
97 linenumber = opts.get('line_number') is not None
98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
99 raise util.Abort(_('at least one of -n/-c is required for -l'))
99 raise util.Abort(_('at least one of -n/-c is required for -l'))
100
100
101 funcmap = [func for op, func in opmap if opts.get(op)]
101 funcmap = [func for op, func in opmap if opts.get(op)]
102 if linenumber:
102 if linenumber:
103 lastfunc = funcmap[-1]
103 lastfunc = funcmap[-1]
104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
105
105
106 ctx = repo.changectx(opts['rev'])
106 ctx = repo.changectx(opts['rev'])
107
107
108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
109 node=ctx.node()):
109 node=ctx.node()):
110 fctx = ctx.filectx(abs)
110 fctx = ctx.filectx(abs)
111 if not opts['text'] and util.binary(fctx.data()):
111 if not opts['text'] and util.binary(fctx.data()):
112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
113 continue
113 continue
114
114
115 lines = fctx.annotate(follow=opts.get('follow'),
115 lines = fctx.annotate(follow=opts.get('follow'),
116 linenumber=linenumber)
116 linenumber=linenumber)
117 pieces = []
117 pieces = []
118
118
119 for f in funcmap:
119 for f in funcmap:
120 l = [f(n) for n, dummy in lines]
120 l = [f(n) for n, dummy in lines]
121 if l:
121 if l:
122 m = max(map(len, l))
122 m = max(map(len, l))
123 pieces.append(["%*s" % (m, x) for x in l])
123 pieces.append(["%*s" % (m, x) for x in l])
124
124
125 if pieces:
125 if pieces:
126 for p, l in zip(zip(*pieces), lines):
126 for p, l in zip(zip(*pieces), lines):
127 ui.write("%s: %s" % (" ".join(p), l[1]))
127 ui.write("%s: %s" % (" ".join(p), l[1]))
128
128
129 def archive(ui, repo, dest, **opts):
129 def archive(ui, repo, dest, **opts):
130 '''create unversioned archive of a repository revision
130 '''create unversioned archive of a repository revision
131
131
132 By default, the revision used is the parent of the working
132 By default, the revision used is the parent of the working
133 directory; use "-r" to specify a different revision.
133 directory; use "-r" to specify a different revision.
134
134
135 To specify the type of archive to create, use "-t". Valid
135 To specify the type of archive to create, use "-t". Valid
136 types are:
136 types are:
137
137
138 "files" (default): a directory full of files
138 "files" (default): a directory full of files
139 "tar": tar archive, uncompressed
139 "tar": tar archive, uncompressed
140 "tbz2": tar archive, compressed using bzip2
140 "tbz2": tar archive, compressed using bzip2
141 "tgz": tar archive, compressed using gzip
141 "tgz": tar archive, compressed using gzip
142 "uzip": zip archive, uncompressed
142 "uzip": zip archive, uncompressed
143 "zip": zip archive, compressed using deflate
143 "zip": zip archive, compressed using deflate
144
144
145 The exact name of the destination archive or directory is given
145 The exact name of the destination archive or directory is given
146 using a format string; see "hg help export" for details.
146 using a format string; see "hg help export" for details.
147
147
148 Each member added to an archive file has a directory prefix
148 Each member added to an archive file has a directory prefix
149 prepended. Use "-p" to specify a format string for the prefix.
149 prepended. Use "-p" to specify a format string for the prefix.
150 The default is the basename of the archive, with suffixes removed.
150 The default is the basename of the archive, with suffixes removed.
151 '''
151 '''
152
152
153 ctx = repo.changectx(opts['rev'])
153 ctx = repo.changectx(opts['rev'])
154 if not ctx:
154 if not ctx:
155 raise util.Abort(_('repository has no revisions'))
155 raise util.Abort(_('repository has no revisions'))
156 node = ctx.node()
156 node = ctx.node()
157 dest = cmdutil.make_filename(repo, dest, node)
157 dest = cmdutil.make_filename(repo, dest, node)
158 if os.path.realpath(dest) == repo.root:
158 if os.path.realpath(dest) == repo.root:
159 raise util.Abort(_('repository root cannot be destination'))
159 raise util.Abort(_('repository root cannot be destination'))
160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
161 kind = opts.get('type') or 'files'
161 kind = opts.get('type') or 'files'
162 prefix = opts['prefix']
162 prefix = opts['prefix']
163 if dest == '-':
163 if dest == '-':
164 if kind == 'files':
164 if kind == 'files':
165 raise util.Abort(_('cannot archive plain files to stdout'))
165 raise util.Abort(_('cannot archive plain files to stdout'))
166 dest = sys.stdout
166 dest = sys.stdout
167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
168 prefix = cmdutil.make_filename(repo, prefix, node)
168 prefix = cmdutil.make_filename(repo, prefix, node)
169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
170 matchfn, prefix)
170 matchfn, prefix)
171
171
172 def backout(ui, repo, node=None, rev=None, **opts):
172 def backout(ui, repo, node=None, rev=None, **opts):
173 '''reverse effect of earlier changeset
173 '''reverse effect of earlier changeset
174
174
175 Commit the backed out changes as a new changeset. The new
175 Commit the backed out changes as a new changeset. The new
176 changeset is a child of the backed out changeset.
176 changeset is a child of the backed out changeset.
177
177
178 If you back out a changeset other than the tip, a new head is
178 If you back out a changeset other than the tip, a new head is
179 created. This head is the parent of the working directory. If
179 created. This head is the parent of the working directory. If
180 you back out an old changeset, your working directory will appear
180 you back out an old changeset, your working directory will appear
181 old after the backout. You should merge the backout changeset
181 old after the backout. You should merge the backout changeset
182 with another head.
182 with another head.
183
183
184 The --merge option remembers the parent of the working directory
184 The --merge option remembers the parent of the working directory
185 before starting the backout, then merges the new head with that
185 before starting the backout, then merges the new head with that
186 changeset afterwards. This saves you from doing the merge by
186 changeset afterwards. This saves you from doing the merge by
187 hand. The result of this merge is not committed, as for a normal
187 hand. The result of this merge is not committed, as for a normal
188 merge.'''
188 merge.'''
189 if rev and node:
189 if rev and node:
190 raise util.Abort(_("please specify just one revision"))
190 raise util.Abort(_("please specify just one revision"))
191
191
192 if not rev:
192 if not rev:
193 rev = node
193 rev = node
194
194
195 if not rev:
195 if not rev:
196 raise util.Abort(_("please specify a revision to backout"))
196 raise util.Abort(_("please specify a revision to backout"))
197
197
198 cmdutil.bail_if_changed(repo)
198 cmdutil.bail_if_changed(repo)
199 node = repo.lookup(rev)
199 node = repo.lookup(rev)
200
200
201 op1, op2 = repo.dirstate.parents()
201 op1, op2 = repo.dirstate.parents()
202 a = repo.changelog.ancestor(op1, node)
202 a = repo.changelog.ancestor(op1, node)
203 if a != node:
203 if a != node:
204 raise util.Abort(_('cannot back out change on a different branch'))
204 raise util.Abort(_('cannot back out change on a different branch'))
205
205
206 p1, p2 = repo.changelog.parents(node)
206 p1, p2 = repo.changelog.parents(node)
207 if p1 == nullid:
207 if p1 == nullid:
208 raise util.Abort(_('cannot back out a change with no parents'))
208 raise util.Abort(_('cannot back out a change with no parents'))
209 if p2 != nullid:
209 if p2 != nullid:
210 if not opts['parent']:
210 if not opts['parent']:
211 raise util.Abort(_('cannot back out a merge changeset without '
211 raise util.Abort(_('cannot back out a merge changeset without '
212 '--parent'))
212 '--parent'))
213 p = repo.lookup(opts['parent'])
213 p = repo.lookup(opts['parent'])
214 if p not in (p1, p2):
214 if p not in (p1, p2):
215 raise util.Abort(_('%s is not a parent of %s') %
215 raise util.Abort(_('%s is not a parent of %s') %
216 (short(p), short(node)))
216 (short(p), short(node)))
217 parent = p
217 parent = p
218 else:
218 else:
219 if opts['parent']:
219 if opts['parent']:
220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
221 parent = p1
221 parent = p1
222
222
223 hg.clean(repo, node, show_stats=False)
223 hg.clean(repo, node, show_stats=False)
224 revert_opts = opts.copy()
224 revert_opts = opts.copy()
225 revert_opts['date'] = None
225 revert_opts['date'] = None
226 revert_opts['all'] = True
226 revert_opts['all'] = True
227 revert_opts['rev'] = hex(parent)
227 revert_opts['rev'] = hex(parent)
228 revert_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['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['files_with_matches']:
1046 if opts['files_with_matches']:
1047 c = (fn, r)
1047 c = (fn, r)
1048 if c in filerevmatches:
1048 if c in filerevmatches:
1049 continue
1049 continue
1050 filerevmatches[c] = 1
1050 filerevmatches[c] = 1
1051 else:
1051 else:
1052 cols.append(l.line)
1052 cols.append(l.line)
1053 ui.write(sep.join(cols), eol)
1053 ui.write(sep.join(cols), eol)
1054 found = True
1054 found = True
1055 return found
1055 return found
1056
1056
1057 fstate = {}
1057 fstate = {}
1058 skip = {}
1058 skip = {}
1059 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1059 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1060 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1060 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1061 found = False
1061 found = False
1062 follow = opts.get('follow')
1062 follow = opts.get('follow')
1063 for st, rev, fns in changeiter:
1063 for st, rev, fns in changeiter:
1064 if st == 'window':
1064 if st == 'window':
1065 matches.clear()
1065 matches.clear()
1066 elif st == 'add':
1066 elif st == 'add':
1067 mf = repo.changectx(rev).manifest()
1067 mf = repo.changectx(rev).manifest()
1068 matches[rev] = {}
1068 matches[rev] = {}
1069 for fn in fns:
1069 for fn in fns:
1070 if fn in skip:
1070 if fn in skip:
1071 continue
1071 continue
1072 try:
1072 try:
1073 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1073 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1074 fstate.setdefault(fn, [])
1074 fstate.setdefault(fn, [])
1075 if follow:
1075 if follow:
1076 copied = getfile(fn).renamed(mf[fn])
1076 copied = getfile(fn).renamed(mf[fn])
1077 if copied:
1077 if copied:
1078 copies.setdefault(rev, {})[fn] = copied[0]
1078 copies.setdefault(rev, {})[fn] = copied[0]
1079 except KeyError:
1079 except KeyError:
1080 pass
1080 pass
1081 elif st == 'iter':
1081 elif st == 'iter':
1082 states = matches[rev].items()
1082 states = matches[rev].items()
1083 states.sort()
1083 states.sort()
1084 for fn, m in states:
1084 for fn, m in states:
1085 copy = copies.get(rev, {}).get(fn)
1085 copy = copies.get(rev, {}).get(fn)
1086 if fn in skip:
1086 if fn in skip:
1087 if copy:
1087 if copy:
1088 skip[copy] = True
1088 skip[copy] = True
1089 continue
1089 continue
1090 if fn in prev or fstate[fn]:
1090 if fn in prev or fstate[fn]:
1091 r = display(fn, rev, m, fstate[fn])
1091 r = display(fn, rev, m, fstate[fn])
1092 found = found or r
1092 found = found or r
1093 if r and not opts['all']:
1093 if r and not opts['all']:
1094 skip[fn] = True
1094 skip[fn] = True
1095 if copy:
1095 if copy:
1096 skip[copy] = True
1096 skip[copy] = True
1097 fstate[fn] = m
1097 fstate[fn] = m
1098 if copy:
1098 if copy:
1099 fstate[copy] = m
1099 fstate[copy] = m
1100 prev[fn] = rev
1100 prev[fn] = rev
1101
1101
1102 fstate = fstate.items()
1102 fstate = fstate.items()
1103 fstate.sort()
1103 fstate.sort()
1104 for fn, state in fstate:
1104 for fn, state in fstate:
1105 if fn in skip:
1105 if fn in skip:
1106 continue
1106 continue
1107 if fn not in copies.get(prev[fn], {}):
1107 if fn not in copies.get(prev[fn], {}):
1108 found = display(fn, rev, {}, state) or found
1108 found = display(fn, rev, {}, state) or found
1109 return (not found and 1) or 0
1109 return (not found and 1) or 0
1110
1110
1111 def heads(ui, repo, *branchrevs, **opts):
1111 def heads(ui, repo, *branchrevs, **opts):
1112 """show current repository heads or show branch heads
1112 """show current repository heads or show branch heads
1113
1113
1114 With no arguments, show all repository head changesets.
1114 With no arguments, show all repository head changesets.
1115
1115
1116 If branch or revisions names are given this will show the heads of
1116 If branch or revisions names are given this will show the heads of
1117 the specified branches or the branches those revisions are tagged
1117 the specified branches or the branches those revisions are tagged
1118 with.
1118 with.
1119
1119
1120 Repository "heads" are changesets that don't have child
1120 Repository "heads" are changesets that don't have child
1121 changesets. They are where development generally takes place and
1121 changesets. They are where development generally takes place and
1122 are the usual targets for update and merge operations.
1122 are the usual targets for update and merge operations.
1123
1123
1124 Branch heads are changesets that have a given branch tag, but have
1124 Branch heads are changesets that have a given branch tag, but have
1125 no child changesets with that tag. They are usually where
1125 no child changesets with that tag. They are usually where
1126 development on the given branch takes place.
1126 development on the given branch takes place.
1127 """
1127 """
1128 if opts['rev']:
1128 if opts['rev']:
1129 start = repo.lookup(opts['rev'])
1129 start = repo.lookup(opts['rev'])
1130 else:
1130 else:
1131 start = None
1131 start = None
1132 if not branchrevs:
1132 if not branchrevs:
1133 # Assume we're looking repo-wide heads if no revs were specified.
1133 # Assume we're looking repo-wide heads if no revs were specified.
1134 heads = repo.heads(start)
1134 heads = repo.heads(start)
1135 else:
1135 else:
1136 heads = []
1136 heads = []
1137 visitedset = util.set()
1137 visitedset = util.set()
1138 for branchrev in branchrevs:
1138 for branchrev in branchrevs:
1139 branch = repo.changectx(branchrev).branch()
1139 branch = repo.changectx(branchrev).branch()
1140 if branch in visitedset:
1140 if branch in visitedset:
1141 continue
1141 continue
1142 visitedset.add(branch)
1142 visitedset.add(branch)
1143 bheads = repo.branchheads(branch, start)
1143 bheads = repo.branchheads(branch, start)
1144 if not bheads:
1144 if not bheads:
1145 if branch != branchrev:
1145 if branch != branchrev:
1146 ui.warn(_("no changes on branch %s containing %s are "
1146 ui.warn(_("no changes on branch %s containing %s are "
1147 "reachable from %s\n")
1147 "reachable from %s\n")
1148 % (branch, branchrev, opts['rev']))
1148 % (branch, branchrev, opts['rev']))
1149 else:
1149 else:
1150 ui.warn(_("no changes on branch %s are reachable from %s\n")
1150 ui.warn(_("no changes on branch %s are reachable from %s\n")
1151 % (branch, opts['rev']))
1151 % (branch, opts['rev']))
1152 heads.extend(bheads)
1152 heads.extend(bheads)
1153 if not heads:
1153 if not heads:
1154 return 1
1154 return 1
1155 displayer = cmdutil.show_changeset(ui, repo, opts)
1155 displayer = cmdutil.show_changeset(ui, repo, opts)
1156 for n in heads:
1156 for n in heads:
1157 displayer.show(changenode=n)
1157 displayer.show(changenode=n)
1158
1158
1159 def help_(ui, name=None, with_version=False):
1159 def help_(ui, name=None, with_version=False):
1160 """show help for a command, extension, or list of commands
1160 """show help for a command, extension, or list of commands
1161
1161
1162 With no arguments, print a list of commands and short help.
1162 With no arguments, print a list of commands and short help.
1163
1163
1164 Given a command name, print help for that command.
1164 Given a command name, print help for that command.
1165
1165
1166 Given an extension name, print help for that extension, and the
1166 Given an extension name, print help for that extension, and the
1167 commands it provides."""
1167 commands it provides."""
1168 option_lists = []
1168 option_lists = []
1169
1169
1170 def addglobalopts(aliases):
1170 def addglobalopts(aliases):
1171 if ui.verbose:
1171 if ui.verbose:
1172 option_lists.append((_("global options:"), globalopts))
1172 option_lists.append((_("global options:"), globalopts))
1173 if name == 'shortlist':
1173 if name == 'shortlist':
1174 option_lists.append((_('use "hg help" for the full list '
1174 option_lists.append((_('use "hg help" for the full list '
1175 'of commands'), ()))
1175 'of commands'), ()))
1176 else:
1176 else:
1177 if name == 'shortlist':
1177 if name == 'shortlist':
1178 msg = _('use "hg help" for the full list of commands '
1178 msg = _('use "hg help" for the full list of commands '
1179 'or "hg -v" for details')
1179 'or "hg -v" for details')
1180 elif aliases:
1180 elif aliases:
1181 msg = _('use "hg -v help%s" to show aliases and '
1181 msg = _('use "hg -v help%s" to show aliases and '
1182 'global options') % (name and " " + name or "")
1182 'global options') % (name and " " + name or "")
1183 else:
1183 else:
1184 msg = _('use "hg -v help %s" to show global options') % name
1184 msg = _('use "hg -v help %s" to show global options') % name
1185 option_lists.append((msg, ()))
1185 option_lists.append((msg, ()))
1186
1186
1187 def helpcmd(name):
1187 def helpcmd(name):
1188 if with_version:
1188 if with_version:
1189 version_(ui)
1189 version_(ui)
1190 ui.write('\n')
1190 ui.write('\n')
1191 aliases, i = cmdutil.findcmd(ui, name, table)
1191 aliases, i = cmdutil.findcmd(ui, name, table)
1192 # synopsis
1192 # synopsis
1193 ui.write("%s\n" % i[2])
1193 ui.write("%s\n" % i[2])
1194
1194
1195 # aliases
1195 # aliases
1196 if not ui.quiet and len(aliases) > 1:
1196 if not ui.quiet and len(aliases) > 1:
1197 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1197 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1198
1198
1199 # description
1199 # description
1200 doc = i[0].__doc__
1200 doc = i[0].__doc__
1201 if not doc:
1201 if not doc:
1202 doc = _("(No help text available)")
1202 doc = _("(No help text available)")
1203 if ui.quiet:
1203 if ui.quiet:
1204 doc = doc.splitlines(0)[0]
1204 doc = doc.splitlines(0)[0]
1205 ui.write("\n%s\n" % doc.rstrip())
1205 ui.write("\n%s\n" % doc.rstrip())
1206
1206
1207 if not ui.quiet:
1207 if not ui.quiet:
1208 # options
1208 # options
1209 if i[1]:
1209 if i[1]:
1210 option_lists.append((_("options:\n"), i[1]))
1210 option_lists.append((_("options:\n"), i[1]))
1211
1211
1212 addglobalopts(False)
1212 addglobalopts(False)
1213
1213
1214 def helplist(header, select=None):
1214 def helplist(header, select=None):
1215 h = {}
1215 h = {}
1216 cmds = {}
1216 cmds = {}
1217 for c, e in table.items():
1217 for c, e in table.items():
1218 f = c.split("|", 1)[0]
1218 f = c.split("|", 1)[0]
1219 if select and not select(f):
1219 if select and not select(f):
1220 continue
1220 continue
1221 if name == "shortlist" and not f.startswith("^"):
1221 if name == "shortlist" and not f.startswith("^"):
1222 continue
1222 continue
1223 f = f.lstrip("^")
1223 f = f.lstrip("^")
1224 if not ui.debugflag and f.startswith("debug"):
1224 if not ui.debugflag and f.startswith("debug"):
1225 continue
1225 continue
1226 doc = e[0].__doc__
1226 doc = e[0].__doc__
1227 if not doc:
1227 if not doc:
1228 doc = _("(No help text available)")
1228 doc = _("(No help text available)")
1229 h[f] = doc.splitlines(0)[0].rstrip()
1229 h[f] = doc.splitlines(0)[0].rstrip()
1230 cmds[f] = c.lstrip("^")
1230 cmds[f] = c.lstrip("^")
1231
1231
1232 if not h:
1232 if not h:
1233 ui.status(_('no commands defined\n'))
1233 ui.status(_('no commands defined\n'))
1234 return
1234 return
1235
1235
1236 ui.status(header)
1236 ui.status(header)
1237 fns = h.keys()
1237 fns = h.keys()
1238 fns.sort()
1238 fns.sort()
1239 m = max(map(len, fns))
1239 m = max(map(len, fns))
1240 for f in fns:
1240 for f in fns:
1241 if ui.verbose:
1241 if ui.verbose:
1242 commands = cmds[f].replace("|",", ")
1242 commands = cmds[f].replace("|",", ")
1243 ui.write(" %s:\n %s\n"%(commands, h[f]))
1243 ui.write(" %s:\n %s\n"%(commands, h[f]))
1244 else:
1244 else:
1245 ui.write(' %-*s %s\n' % (m, f, h[f]))
1245 ui.write(' %-*s %s\n' % (m, f, h[f]))
1246
1246
1247 if not ui.quiet:
1247 if not ui.quiet:
1248 addglobalopts(True)
1248 addglobalopts(True)
1249
1249
1250 def helptopic(name):
1250 def helptopic(name):
1251 v = None
1251 v = None
1252 for i in help.helptable:
1252 for i in help.helptable:
1253 l = i.split('|')
1253 l = i.split('|')
1254 if name in l:
1254 if name in l:
1255 v = i
1255 v = i
1256 header = l[-1]
1256 header = l[-1]
1257 if not v:
1257 if not v:
1258 raise cmdutil.UnknownCommand(name)
1258 raise cmdutil.UnknownCommand(name)
1259
1259
1260 # description
1260 # description
1261 doc = help.helptable[v]
1261 doc = help.helptable[v]
1262 if not doc:
1262 if not doc:
1263 doc = _("(No help text available)")
1263 doc = _("(No help text available)")
1264 if callable(doc):
1264 if callable(doc):
1265 doc = doc()
1265 doc = doc()
1266
1266
1267 ui.write("%s\n" % header)
1267 ui.write("%s\n" % header)
1268 ui.write("%s\n" % doc.rstrip())
1268 ui.write("%s\n" % doc.rstrip())
1269
1269
1270 def helpext(name):
1270 def helpext(name):
1271 try:
1271 try:
1272 mod = extensions.find(name)
1272 mod = extensions.find(name)
1273 except KeyError:
1273 except KeyError:
1274 raise cmdutil.UnknownCommand(name)
1274 raise cmdutil.UnknownCommand(name)
1275
1275
1276 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1276 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1277 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1277 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1278 for d in doc[1:]:
1278 for d in doc[1:]:
1279 ui.write(d, '\n')
1279 ui.write(d, '\n')
1280
1280
1281 ui.status('\n')
1281 ui.status('\n')
1282
1282
1283 try:
1283 try:
1284 ct = mod.cmdtable
1284 ct = mod.cmdtable
1285 except AttributeError:
1285 except AttributeError:
1286 ct = {}
1286 ct = {}
1287
1287
1288 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1288 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1289 helplist(_('list of commands:\n\n'), modcmds.has_key)
1289 helplist(_('list of commands:\n\n'), modcmds.has_key)
1290
1290
1291 if name and name != 'shortlist':
1291 if name and name != 'shortlist':
1292 i = None
1292 i = None
1293 for f in (helpcmd, helptopic, helpext):
1293 for f in (helpcmd, helptopic, helpext):
1294 try:
1294 try:
1295 f(name)
1295 f(name)
1296 i = None
1296 i = None
1297 break
1297 break
1298 except cmdutil.UnknownCommand, inst:
1298 except cmdutil.UnknownCommand, inst:
1299 i = inst
1299 i = inst
1300 if i:
1300 if i:
1301 raise i
1301 raise i
1302
1302
1303 else:
1303 else:
1304 # program name
1304 # program name
1305 if ui.verbose or with_version:
1305 if ui.verbose or with_version:
1306 version_(ui)
1306 version_(ui)
1307 else:
1307 else:
1308 ui.status(_("Mercurial Distributed SCM\n"))
1308 ui.status(_("Mercurial Distributed SCM\n"))
1309 ui.status('\n')
1309 ui.status('\n')
1310
1310
1311 # list of commands
1311 # list of commands
1312 if name == "shortlist":
1312 if name == "shortlist":
1313 header = _('basic commands:\n\n')
1313 header = _('basic commands:\n\n')
1314 else:
1314 else:
1315 header = _('list of commands:\n\n')
1315 header = _('list of commands:\n\n')
1316
1316
1317 helplist(header)
1317 helplist(header)
1318
1318
1319 # list all option lists
1319 # list all option lists
1320 opt_output = []
1320 opt_output = []
1321 for title, options in option_lists:
1321 for title, options in option_lists:
1322 opt_output.append(("\n%s" % title, None))
1322 opt_output.append(("\n%s" % title, None))
1323 for shortopt, longopt, default, desc in options:
1323 for shortopt, longopt, default, desc in options:
1324 if "DEPRECATED" in desc and not ui.verbose: continue
1324 if "DEPRECATED" in desc and not ui.verbose: continue
1325 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1325 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1326 longopt and " --%s" % longopt),
1326 longopt and " --%s" % longopt),
1327 "%s%s" % (desc,
1327 "%s%s" % (desc,
1328 default
1328 default
1329 and _(" (default: %s)") % default
1329 and _(" (default: %s)") % default
1330 or "")))
1330 or "")))
1331
1331
1332 if opt_output:
1332 if opt_output:
1333 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1333 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1334 for first, second in opt_output:
1334 for first, second in opt_output:
1335 if second:
1335 if second:
1336 ui.write(" %-*s %s\n" % (opts_len, first, second))
1336 ui.write(" %-*s %s\n" % (opts_len, first, second))
1337 else:
1337 else:
1338 ui.write("%s\n" % first)
1338 ui.write("%s\n" % first)
1339
1339
1340 def identify(ui, repo, source=None,
1340 def identify(ui, repo, source=None,
1341 rev=None, num=None, id=None, branch=None, tags=None):
1341 rev=None, num=None, id=None, branch=None, tags=None):
1342 """identify the working copy or specified revision
1342 """identify the working copy or specified revision
1343
1343
1344 With no revision, print a summary of the current state of the repo.
1344 With no revision, print a summary of the current state of the repo.
1345
1345
1346 With a path, do a lookup in another repository.
1346 With a path, do a lookup in another repository.
1347
1347
1348 This summary identifies the repository state using one or two parent
1348 This summary identifies the repository state using one or two parent
1349 hash identifiers, followed by a "+" if there are uncommitted changes
1349 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
1350 in the working directory, a list of tags for this revision and a branch
1351 name for non-default branches.
1351 name for non-default branches.
1352 """
1352 """
1353
1353
1354 if not repo and not source:
1354 if not repo and not source:
1355 raise util.Abort(_("There is no Mercurial repository here "
1355 raise util.Abort(_("There is no Mercurial repository here "
1356 "(.hg not found)"))
1356 "(.hg not found)"))
1357
1357
1358 hexfunc = ui.debugflag and hex or short
1358 hexfunc = ui.debugflag and hex or short
1359 default = not (num or id or branch or tags)
1359 default = not (num or id or branch or tags)
1360 output = []
1360 output = []
1361
1361
1362 if source:
1362 if source:
1363 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1363 source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
1364 srepo = hg.repository(ui, source)
1364 srepo = hg.repository(ui, source)
1365 if not rev and revs:
1365 if not rev and revs:
1366 rev = revs[0]
1366 rev = revs[0]
1367 if not rev:
1367 if not rev:
1368 rev = "tip"
1368 rev = "tip"
1369 if num or branch or tags:
1369 if num or branch or tags:
1370 raise util.Abort(
1370 raise util.Abort(
1371 "can't query remote revision number, branch, or tags")
1371 "can't query remote revision number, branch, or tags")
1372 output = [hexfunc(srepo.lookup(rev))]
1372 output = [hexfunc(srepo.lookup(rev))]
1373 elif not rev:
1373 elif not rev:
1374 ctx = repo.workingctx()
1374 ctx = repo.workingctx()
1375 parents = ctx.parents()
1375 parents = ctx.parents()
1376 changed = False
1376 changed = False
1377 if default or id or num:
1377 if default or id or num:
1378 changed = ctx.files() + ctx.deleted()
1378 changed = ctx.files() + ctx.deleted()
1379 if default or id:
1379 if default or id:
1380 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1380 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
1381 (changed) and "+" or "")]
1381 (changed) and "+" or "")]
1382 if num:
1382 if num:
1383 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1383 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
1384 (changed) and "+" or ""))
1384 (changed) and "+" or ""))
1385 else:
1385 else:
1386 ctx = repo.changectx(rev)
1386 ctx = repo.changectx(rev)
1387 if default or id:
1387 if default or id:
1388 output = [hexfunc(ctx.node())]
1388 output = [hexfunc(ctx.node())]
1389 if num:
1389 if num:
1390 output.append(str(ctx.rev()))
1390 output.append(str(ctx.rev()))
1391
1391
1392 if not source and default and not ui.quiet:
1392 if not source and default and not ui.quiet:
1393 b = util.tolocal(ctx.branch())
1393 b = util.tolocal(ctx.branch())
1394 if b != 'default':
1394 if b != 'default':
1395 output.append("(%s)" % b)
1395 output.append("(%s)" % b)
1396
1396
1397 # multiple tags for a single parent separated by '/'
1397 # multiple tags for a single parent separated by '/'
1398 t = "/".join(ctx.tags())
1398 t = "/".join(ctx.tags())
1399 if t:
1399 if t:
1400 output.append(t)
1400 output.append(t)
1401
1401
1402 if branch:
1402 if branch:
1403 output.append(util.tolocal(ctx.branch()))
1403 output.append(util.tolocal(ctx.branch()))
1404
1404
1405 if tags:
1405 if tags:
1406 output.extend(ctx.tags())
1406 output.extend(ctx.tags())
1407
1407
1408 ui.write("%s\n" % ' '.join(output))
1408 ui.write("%s\n" % ' '.join(output))
1409
1409
1410 def import_(ui, repo, patch1, *patches, **opts):
1410 def import_(ui, repo, patch1, *patches, **opts):
1411 """import an ordered set of patches
1411 """import an ordered set of patches
1412
1412
1413 Import a list of patches and commit them individually.
1413 Import a list of patches and commit them individually.
1414
1414
1415 If there are outstanding changes in the working directory, import
1415 If there are outstanding changes in the working directory, import
1416 will abort unless given the -f flag.
1416 will abort unless given the -f flag.
1417
1417
1418 You can import a patch straight from a mail message. Even patches
1418 You can import a patch straight from a mail message. Even patches
1419 as attachments work (body part must be type text/plain or
1419 as attachments work (body part must be type text/plain or
1420 text/x-patch to be used). From and Subject headers of email
1420 text/x-patch to be used). From and Subject headers of email
1421 message are used as default committer and commit message. All
1421 message are used as default committer and commit message. All
1422 text/plain body parts before first diff are added to commit
1422 text/plain body parts before first diff are added to commit
1423 message.
1423 message.
1424
1424
1425 If the imported patch was generated by hg export, user and description
1425 If the imported patch was generated by hg export, user and description
1426 from patch override values from message headers and body. Values
1426 from patch override values from message headers and body. Values
1427 given on command line with -m and -u override these.
1427 given on command line with -m and -u override these.
1428
1428
1429 If --exact is specified, import will set the working directory
1429 If --exact is specified, import will set the working directory
1430 to the parent of each patch before applying it, and will abort
1430 to the parent of each patch before applying it, and will abort
1431 if the resulting changeset has a different ID than the one
1431 if the resulting changeset has a different ID than the one
1432 recorded in the patch. This may happen due to character set
1432 recorded in the patch. This may happen due to character set
1433 problems or other deficiencies in the text patch format.
1433 problems or other deficiencies in the text patch format.
1434
1434
1435 To read a patch from standard input, use patch name "-".
1435 To read a patch from standard input, use patch name "-".
1436 """
1436 """
1437 patches = (patch1,) + patches
1437 patches = (patch1,) + patches
1438
1438
1439 if opts.get('exact') or not opts['force']:
1439 if opts.get('exact') or not opts['force']:
1440 cmdutil.bail_if_changed(repo)
1440 cmdutil.bail_if_changed(repo)
1441
1441
1442 d = opts["base"]
1442 d = opts["base"]
1443 strip = opts["strip"]
1443 strip = opts["strip"]
1444 wlock = lock = None
1444 wlock = lock = None
1445 try:
1445 try:
1446 wlock = repo.wlock()
1446 wlock = repo.wlock()
1447 lock = repo.lock()
1447 lock = repo.lock()
1448 for p in patches:
1448 for p in patches:
1449 pf = os.path.join(d, p)
1449 pf = os.path.join(d, p)
1450
1450
1451 if pf == '-':
1451 if pf == '-':
1452 ui.status(_("applying patch from stdin\n"))
1452 ui.status(_("applying patch from stdin\n"))
1453 data = patch.extract(ui, sys.stdin)
1453 data = patch.extract(ui, sys.stdin)
1454 else:
1454 else:
1455 ui.status(_("applying %s\n") % p)
1455 ui.status(_("applying %s\n") % p)
1456 if os.path.exists(pf):
1456 if os.path.exists(pf):
1457 data = patch.extract(ui, file(pf, 'rb'))
1457 data = patch.extract(ui, file(pf, 'rb'))
1458 else:
1458 else:
1459 data = patch.extract(ui, urllib.urlopen(pf))
1459 data = patch.extract(ui, urllib.urlopen(pf))
1460 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1460 tmpname, message, user, date, branch, nodeid, p1, p2 = data
1461
1461
1462 if tmpname is None:
1462 if tmpname is None:
1463 raise util.Abort(_('no diffs found'))
1463 raise util.Abort(_('no diffs found'))
1464
1464
1465 try:
1465 try:
1466 cmdline_message = cmdutil.logmessage(opts)
1466 cmdline_message = cmdutil.logmessage(opts)
1467 if cmdline_message:
1467 if cmdline_message:
1468 # pickup the cmdline msg
1468 # pickup the cmdline msg
1469 message = cmdline_message
1469 message = cmdline_message
1470 elif message:
1470 elif message:
1471 # pickup the patch msg
1471 # pickup the patch msg
1472 message = message.strip()
1472 message = message.strip()
1473 else:
1473 else:
1474 # launch the editor
1474 # launch the editor
1475 message = None
1475 message = None
1476 ui.debug(_('message:\n%s\n') % message)
1476 ui.debug(_('message:\n%s\n') % message)
1477
1477
1478 wp = repo.workingctx().parents()
1478 wp = repo.workingctx().parents()
1479 if opts.get('exact'):
1479 if opts.get('exact'):
1480 if not nodeid or not p1:
1480 if not nodeid or not p1:
1481 raise util.Abort(_('not a mercurial patch'))
1481 raise util.Abort(_('not a mercurial patch'))
1482 p1 = repo.lookup(p1)
1482 p1 = repo.lookup(p1)
1483 p2 = repo.lookup(p2 or hex(nullid))
1483 p2 = repo.lookup(p2 or hex(nullid))
1484
1484
1485 if p1 != wp[0].node():
1485 if p1 != wp[0].node():
1486 hg.clean(repo, p1)
1486 hg.clean(repo, p1)
1487 repo.dirstate.setparents(p1, p2)
1487 repo.dirstate.setparents(p1, p2)
1488 elif p2:
1488 elif p2:
1489 try:
1489 try:
1490 p1 = repo.lookup(p1)
1490 p1 = repo.lookup(p1)
1491 p2 = repo.lookup(p2)
1491 p2 = repo.lookup(p2)
1492 if p1 == wp[0].node():
1492 if p1 == wp[0].node():
1493 repo.dirstate.setparents(p1, p2)
1493 repo.dirstate.setparents(p1, p2)
1494 except hg.RepoError:
1494 except hg.RepoError:
1495 pass
1495 pass
1496 if opts.get('exact') or opts.get('import_branch'):
1496 if opts.get('exact') or opts.get('import_branch'):
1497 repo.dirstate.setbranch(branch or 'default')
1497 repo.dirstate.setbranch(branch or 'default')
1498
1498
1499 files = {}
1499 files = {}
1500 try:
1500 try:
1501 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1501 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1502 files=files)
1502 files=files)
1503 finally:
1503 finally:
1504 files = patch.updatedir(ui, repo, files)
1504 files = patch.updatedir(ui, repo, files)
1505 if not opts.get('no_commit'):
1505 if not opts.get('no_commit'):
1506 n = repo.commit(files, message, opts.get('user') or user,
1506 n = repo.commit(files, message, opts.get('user') or user,
1507 opts.get('date') or date)
1507 opts.get('date') or date)
1508 if opts.get('exact'):
1508 if opts.get('exact'):
1509 if hex(n) != nodeid:
1509 if hex(n) != nodeid:
1510 repo.rollback()
1510 repo.rollback()
1511 raise util.Abort(_('patch is damaged'
1511 raise util.Abort(_('patch is damaged'
1512 ' or loses information'))
1512 ' or loses information'))
1513 # Force a dirstate write so that the next transaction
1513 # Force a dirstate write so that the next transaction
1514 # backups an up-do-date file.
1514 # backups an up-do-date file.
1515 repo.dirstate.write()
1515 repo.dirstate.write()
1516 finally:
1516 finally:
1517 os.unlink(tmpname)
1517 os.unlink(tmpname)
1518 finally:
1518 finally:
1519 del lock, wlock
1519 del lock, wlock
1520
1520
1521 def incoming(ui, repo, source="default", **opts):
1521 def incoming(ui, repo, source="default", **opts):
1522 """show new changesets found in source
1522 """show new changesets found in source
1523
1523
1524 Show new changesets found in the specified path/URL or the default
1524 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
1525 pull location. These are the changesets that would be pulled if a pull
1526 was requested.
1526 was requested.
1527
1527
1528 For remote repository, using --bundle avoids downloading the changesets
1528 For remote repository, using --bundle avoids downloading the changesets
1529 twice if the incoming is followed by a pull.
1529 twice if the incoming is followed by a pull.
1530
1530
1531 See pull for valid source format details.
1531 See pull for valid source format details.
1532 """
1532 """
1533 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1533 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1534 cmdutil.setremoteconfig(ui, opts)
1534 cmdutil.setremoteconfig(ui, opts)
1535
1535
1536 other = hg.repository(ui, source)
1536 other = hg.repository(ui, source)
1537 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1537 ui.status(_('comparing with %s\n') % util.hidepassword(source))
1538 if revs:
1538 if revs:
1539 revs = [other.lookup(rev) for rev in revs]
1539 revs = [other.lookup(rev) for rev in revs]
1540 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1540 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1541 if not incoming:
1541 if not incoming:
1542 try:
1542 try:
1543 os.unlink(opts["bundle"])
1543 os.unlink(opts["bundle"])
1544 except:
1544 except:
1545 pass
1545 pass
1546 ui.status(_("no changes found\n"))
1546 ui.status(_("no changes found\n"))
1547 return 1
1547 return 1
1548
1548
1549 cleanup = None
1549 cleanup = None
1550 try:
1550 try:
1551 fname = opts["bundle"]
1551 fname = opts["bundle"]
1552 if fname or not other.local():
1552 if fname or not other.local():
1553 # create a bundle (uncompressed if other repo is not local)
1553 # create a bundle (uncompressed if other repo is not local)
1554 if revs is None:
1554 if revs is None:
1555 cg = other.changegroup(incoming, "incoming")
1555 cg = other.changegroup(incoming, "incoming")
1556 else:
1556 else:
1557 cg = other.changegroupsubset(incoming, revs, 'incoming')
1557 cg = other.changegroupsubset(incoming, revs, 'incoming')
1558 bundletype = other.local() and "HG10BZ" or "HG10UN"
1558 bundletype = other.local() and "HG10BZ" or "HG10UN"
1559 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1559 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1560 # keep written bundle?
1560 # keep written bundle?
1561 if opts["bundle"]:
1561 if opts["bundle"]:
1562 cleanup = None
1562 cleanup = None
1563 if not other.local():
1563 if not other.local():
1564 # use the created uncompressed bundlerepo
1564 # use the created uncompressed bundlerepo
1565 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1565 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1566
1566
1567 o = other.changelog.nodesbetween(incoming, revs)[0]
1567 o = other.changelog.nodesbetween(incoming, revs)[0]
1568 if opts['newest_first']:
1568 if opts['newest_first']:
1569 o.reverse()
1569 o.reverse()
1570 displayer = cmdutil.show_changeset(ui, other, opts)
1570 displayer = cmdutil.show_changeset(ui, other, opts)
1571 for n in o:
1571 for n in o:
1572 parents = [p for p in other.changelog.parents(n) if p != nullid]
1572 parents = [p for p in other.changelog.parents(n) if p != nullid]
1573 if opts['no_merges'] and len(parents) == 2:
1573 if opts['no_merges'] and len(parents) == 2:
1574 continue
1574 continue
1575 displayer.show(changenode=n)
1575 displayer.show(changenode=n)
1576 finally:
1576 finally:
1577 if hasattr(other, 'close'):
1577 if hasattr(other, 'close'):
1578 other.close()
1578 other.close()
1579 if cleanup:
1579 if cleanup:
1580 os.unlink(cleanup)
1580 os.unlink(cleanup)
1581
1581
1582 def init(ui, dest=".", **opts):
1582 def init(ui, dest=".", **opts):
1583 """create a new repository in the given directory
1583 """create a new repository in the given directory
1584
1584
1585 Initialize a new repository in the given directory. If the given
1585 Initialize a new repository in the given directory. If the given
1586 directory does not exist, it is created.
1586 directory does not exist, it is created.
1587
1587
1588 If no directory is given, the current directory is used.
1588 If no directory is given, the current directory is used.
1589
1589
1590 It is possible to specify an ssh:// URL as the destination.
1590 It is possible to specify an ssh:// URL as the destination.
1591 Look at the help text for the pull command for important details
1591 Look at the help text for the pull command for important details
1592 about ssh:// URLs.
1592 about ssh:// URLs.
1593 """
1593 """
1594 cmdutil.setremoteconfig(ui, opts)
1594 cmdutil.setremoteconfig(ui, opts)
1595 hg.repository(ui, dest, create=1)
1595 hg.repository(ui, dest, create=1)
1596
1596
1597 def locate(ui, repo, *pats, **opts):
1597 def locate(ui, repo, *pats, **opts):
1598 """locate files matching specific patterns
1598 """locate files matching specific patterns
1599
1599
1600 Print all files under Mercurial control whose names match the
1600 Print all files under Mercurial control whose names match the
1601 given patterns.
1601 given patterns.
1602
1602
1603 This command searches the entire repository by default. To search
1603 This command searches the entire repository by default. To search
1604 just the current directory and its subdirectories, use
1604 just the current directory and its subdirectories, use
1605 "--include .".
1605 "--include .".
1606
1606
1607 If no patterns are given to match, this command prints all file
1607 If no patterns are given to match, this command prints all file
1608 names.
1608 names.
1609
1609
1610 If you want to feed the output of this command into the "xargs"
1610 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".
1611 command, use the "-0" option to both this command and "xargs".
1612 This will avoid the problem of "xargs" treating single filenames
1612 This will avoid the problem of "xargs" treating single filenames
1613 that contain white space as multiple filenames.
1613 that contain white space as multiple filenames.
1614 """
1614 """
1615 end = opts['print0'] and '\0' or '\n'
1615 end = opts['print0'] and '\0' or '\n'
1616 rev = opts['rev']
1616 rev = opts['rev']
1617 if rev:
1617 if rev:
1618 node = repo.lookup(rev)
1618 node = repo.lookup(rev)
1619 else:
1619 else:
1620 node = None
1620 node = None
1621
1621
1622 ret = 1
1622 ret = 1
1623 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1623 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1624 badmatch=util.always,
1624 badmatch=util.always,
1625 default='relglob'):
1625 default='relglob'):
1626 if src == 'b':
1626 if src == 'b':
1627 continue
1627 continue
1628 if not node and abs not in repo.dirstate:
1628 if not node and abs not in repo.dirstate:
1629 continue
1629 continue
1630 if opts['fullpath']:
1630 if opts['fullpath']:
1631 ui.write(os.path.join(repo.root, abs), end)
1631 ui.write(os.path.join(repo.root, abs), end)
1632 else:
1632 else:
1633 ui.write(((pats and rel) or abs), end)
1633 ui.write(((pats and rel) or abs), end)
1634 ret = 0
1634 ret = 0
1635
1635
1636 return ret
1636 return ret
1637
1637
1638 def log(ui, repo, *pats, **opts):
1638 def log(ui, repo, *pats, **opts):
1639 """show revision history of entire repository or files
1639 """show revision history of entire repository or files
1640
1640
1641 Print the revision history of the specified files or the entire
1641 Print the revision history of the specified files or the entire
1642 project.
1642 project.
1643
1643
1644 File history is shown without following rename or copy history of
1644 File history is shown without following rename or copy history of
1645 files. Use -f/--follow with a file name to follow history across
1645 files. Use -f/--follow with a file name to follow history across
1646 renames and copies. --follow without a file name will only show
1646 renames and copies. --follow without a file name will only show
1647 ancestors or descendants of the starting revision. --follow-first
1647 ancestors or descendants of the starting revision. --follow-first
1648 only follows the first parent of merge revisions.
1648 only follows the first parent of merge revisions.
1649
1649
1650 If no revision range is specified, the default is tip:0 unless
1650 If no revision range is specified, the default is tip:0 unless
1651 --follow is set, in which case the working directory parent is
1651 --follow is set, in which case the working directory parent is
1652 used as the starting revision.
1652 used as the starting revision.
1653
1653
1654 By default this command outputs: changeset id and hash, tags,
1654 By default this command outputs: changeset id and hash, tags,
1655 non-trivial parents, user, date and time, and a summary for each
1655 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
1656 commit. When the -v/--verbose switch is used, the list of changed
1657 files and full commit message is shown.
1657 files and full commit message is shown.
1658
1658
1659 NOTE: log -p may generate unexpected diff output for merge
1659 NOTE: log -p may generate unexpected diff output for merge
1660 changesets, as it will compare the merge changeset against its
1660 changesets, as it will compare the merge changeset against its
1661 first parent only. Also, the files: list will only reflect files
1661 first parent only. Also, the files: list will only reflect files
1662 that are different from BOTH parents.
1662 that are different from BOTH parents.
1663
1663
1664 """
1664 """
1665
1665
1666 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1666 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1667 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1667 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1668
1668
1669 if opts['limit']:
1669 if opts['limit']:
1670 try:
1670 try:
1671 limit = int(opts['limit'])
1671 limit = int(opts['limit'])
1672 except ValueError:
1672 except ValueError:
1673 raise util.Abort(_('limit must be a positive integer'))
1673 raise util.Abort(_('limit must be a positive integer'))
1674 if limit <= 0: raise util.Abort(_('limit must be positive'))
1674 if limit <= 0: raise util.Abort(_('limit must be positive'))
1675 else:
1675 else:
1676 limit = sys.maxint
1676 limit = sys.maxint
1677 count = 0
1677 count = 0
1678
1678
1679 if opts['copies'] and opts['rev']:
1679 if opts['copies'] and opts['rev']:
1680 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1680 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1681 else:
1681 else:
1682 endrev = repo.changelog.count()
1682 endrev = repo.changelog.count()
1683 rcache = {}
1683 rcache = {}
1684 ncache = {}
1684 ncache = {}
1685 def getrenamed(fn, rev):
1685 def getrenamed(fn, rev):
1686 '''looks up all renames for a file (up to endrev) the first
1686 '''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
1687 time the file is given. It indexes on the changerev and only
1688 parses the manifest if linkrev != changerev.
1688 parses the manifest if linkrev != changerev.
1689 Returns rename info for fn at changerev rev.'''
1689 Returns rename info for fn at changerev rev.'''
1690 if fn not in rcache:
1690 if fn not in rcache:
1691 rcache[fn] = {}
1691 rcache[fn] = {}
1692 ncache[fn] = {}
1692 ncache[fn] = {}
1693 fl = repo.file(fn)
1693 fl = repo.file(fn)
1694 for i in xrange(fl.count()):
1694 for i in xrange(fl.count()):
1695 node = fl.node(i)
1695 node = fl.node(i)
1696 lr = fl.linkrev(node)
1696 lr = fl.linkrev(node)
1697 renamed = fl.renamed(node)
1697 renamed = fl.renamed(node)
1698 rcache[fn][lr] = renamed
1698 rcache[fn][lr] = renamed
1699 if renamed:
1699 if renamed:
1700 ncache[fn][node] = renamed
1700 ncache[fn][node] = renamed
1701 if lr >= endrev:
1701 if lr >= endrev:
1702 break
1702 break
1703 if rev in rcache[fn]:
1703 if rev in rcache[fn]:
1704 return rcache[fn][rev]
1704 return rcache[fn][rev]
1705
1705
1706 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1706 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1707 # filectx logic.
1707 # filectx logic.
1708
1708
1709 try:
1709 try:
1710 return repo.changectx(rev).filectx(fn).renamed()
1710 return repo.changectx(rev).filectx(fn).renamed()
1711 except revlog.LookupError:
1711 except revlog.LookupError:
1712 pass
1712 pass
1713 return None
1713 return None
1714
1714
1715 df = False
1715 df = False
1716 if opts["date"]:
1716 if opts["date"]:
1717 df = util.matchdate(opts["date"])
1717 df = util.matchdate(opts["date"])
1718
1718
1719 only_branches = opts['only_branch']
1719 only_branches = opts['only_branch']
1720
1720
1721 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1721 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1722 for st, rev, fns in changeiter:
1722 for st, rev, fns in changeiter:
1723 if st == 'add':
1723 if st == 'add':
1724 changenode = repo.changelog.node(rev)
1724 changenode = repo.changelog.node(rev)
1725 parents = [p for p in repo.changelog.parentrevs(rev)
1725 parents = [p for p in repo.changelog.parentrevs(rev)
1726 if p != nullrev]
1726 if p != nullrev]
1727 if opts['no_merges'] and len(parents) == 2:
1727 if opts['no_merges'] and len(parents) == 2:
1728 continue
1728 continue
1729 if opts['only_merges'] and len(parents) != 2:
1729 if opts['only_merges'] and len(parents) != 2:
1730 continue
1730 continue
1731
1731
1732 if only_branches:
1732 if only_branches:
1733 revbranch = get(rev)[5]['branch']
1733 revbranch = get(rev)[5]['branch']
1734 if revbranch not in only_branches:
1734 if revbranch not in only_branches:
1735 continue
1735 continue
1736
1736
1737 if df:
1737 if df:
1738 changes = get(rev)
1738 changes = get(rev)
1739 if not df(changes[2][0]):
1739 if not df(changes[2][0]):
1740 continue
1740 continue
1741
1741
1742 if opts['keyword']:
1742 if opts['keyword']:
1743 changes = get(rev)
1743 changes = get(rev)
1744 miss = 0
1744 miss = 0
1745 for k in [kw.lower() for kw in opts['keyword']]:
1745 for k in [kw.lower() for kw in opts['keyword']]:
1746 if not (k in changes[1].lower() or
1746 if not (k in changes[1].lower() or
1747 k in changes[4].lower() or
1747 k in changes[4].lower() or
1748 k in " ".join(changes[3]).lower()):
1748 k in " ".join(changes[3]).lower()):
1749 miss = 1
1749 miss = 1
1750 break
1750 break
1751 if miss:
1751 if miss:
1752 continue
1752 continue
1753
1753
1754 copies = []
1754 copies = []
1755 if opts.get('copies') and rev:
1755 if opts.get('copies') and rev:
1756 for fn in get(rev)[3]:
1756 for fn in get(rev)[3]:
1757 rename = getrenamed(fn, rev)
1757 rename = getrenamed(fn, rev)
1758 if rename:
1758 if rename:
1759 copies.append((fn, rename[0]))
1759 copies.append((fn, rename[0]))
1760 displayer.show(rev, changenode, copies=copies)
1760 displayer.show(rev, changenode, copies=copies)
1761 elif st == 'iter':
1761 elif st == 'iter':
1762 if count == limit: break
1762 if count == limit: break
1763 if displayer.flush(rev):
1763 if displayer.flush(rev):
1764 count += 1
1764 count += 1
1765
1765
1766 def manifest(ui, repo, node=None, rev=None):
1766 def manifest(ui, repo, node=None, rev=None):
1767 """output the current or given revision of the project manifest
1767 """output the current or given revision of the project manifest
1768
1768
1769 Print a list of version controlled files for the given revision.
1769 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,
1770 If no revision is given, the parent of the working directory is used,
1771 or tip if no revision is checked out.
1771 or tip if no revision is checked out.
1772
1772
1773 The manifest is the list of files being version controlled. If no revision
1773 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.
1774 is given then the first parent of the working directory is used.
1775
1775
1776 With -v flag, print file permissions, symlink and executable bits. With
1776 With -v flag, print file permissions, symlink and executable bits. With
1777 --debug flag, print file revision hashes.
1777 --debug flag, print file revision hashes.
1778 """
1778 """
1779
1779
1780 if rev and node:
1780 if rev and node:
1781 raise util.Abort(_("please specify just one revision"))
1781 raise util.Abort(_("please specify just one revision"))
1782
1782
1783 if not node:
1783 if not node:
1784 node = rev
1784 node = rev
1785
1785
1786 m = repo.changectx(node).manifest()
1786 m = repo.changectx(node).manifest()
1787 files = m.keys()
1787 files = m.keys()
1788 files.sort()
1788 files.sort()
1789
1789
1790 for f in files:
1790 for f in files:
1791 if ui.debugflag:
1791 if ui.debugflag:
1792 ui.write("%40s " % hex(m[f]))
1792 ui.write("%40s " % hex(m[f]))
1793 if ui.verbose:
1793 if ui.verbose:
1794 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1794 type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
1795 perm = m.execf(f) and "755" or "644"
1795 perm = m.execf(f) and "755" or "644"
1796 ui.write("%3s %1s " % (perm, type))
1796 ui.write("%3s %1s " % (perm, type))
1797 ui.write("%s\n" % f)
1797 ui.write("%s\n" % f)
1798
1798
1799 def merge(ui, repo, node=None, force=None, rev=None):
1799 def merge(ui, repo, node=None, force=None, rev=None):
1800 """merge working directory with another revision
1800 """merge working directory with another revision
1801
1801
1802 Merge the contents of the current working directory and the
1802 Merge the contents of the current working directory and the
1803 requested revision. Files that changed between either parent are
1803 requested revision. Files that changed between either parent are
1804 marked as changed for the next commit and a commit must be
1804 marked as changed for the next commit and a commit must be
1805 performed before any further updates are allowed.
1805 performed before any further updates are allowed.
1806
1806
1807 If no revision is specified, the working directory's parent is a
1807 If no revision is specified, the working directory's parent is a
1808 head revision, and the repository contains exactly one other head,
1808 head revision, and the repository contains exactly one other head,
1809 the other head is merged with by default. Otherwise, an explicit
1809 the other head is merged with by default. Otherwise, an explicit
1810 revision to merge with must be provided.
1810 revision to merge with must be provided.
1811 """
1811 """
1812
1812
1813 if rev and node:
1813 if rev and node:
1814 raise util.Abort(_("please specify just one revision"))
1814 raise util.Abort(_("please specify just one revision"))
1815 if not node:
1815 if not node:
1816 node = rev
1816 node = rev
1817
1817
1818 if not node:
1818 if not node:
1819 heads = repo.heads()
1819 heads = repo.heads()
1820 if len(heads) > 2:
1820 if len(heads) > 2:
1821 raise util.Abort(_('repo has %d heads - '
1821 raise util.Abort(_('repo has %d heads - '
1822 'please merge with an explicit rev') %
1822 'please merge with an explicit rev') %
1823 len(heads))
1823 len(heads))
1824 parent = repo.dirstate.parents()[0]
1824 parent = repo.dirstate.parents()[0]
1825 if len(heads) == 1:
1825 if len(heads) == 1:
1826 msg = _('there is nothing to merge')
1826 msg = _('there is nothing to merge')
1827 if parent != repo.lookup(repo.workingctx().branch()):
1827 if parent != repo.lookup(repo.workingctx().branch()):
1828 msg = _('%s - use "hg update" instead') % msg
1828 msg = _('%s - use "hg update" instead') % msg
1829 raise util.Abort(msg)
1829 raise util.Abort(msg)
1830
1830
1831 if parent not in heads:
1831 if parent not in heads:
1832 raise util.Abort(_('working dir not at a head rev - '
1832 raise util.Abort(_('working dir not at a head rev - '
1833 'use "hg update" or merge with an explicit rev'))
1833 'use "hg update" or merge with an explicit rev'))
1834 node = parent == heads[0] and heads[-1] or heads[0]
1834 node = parent == heads[0] and heads[-1] or heads[0]
1835 return hg.merge(repo, node, force=force)
1835 return hg.merge(repo, node, force=force)
1836
1836
1837 def outgoing(ui, repo, dest=None, **opts):
1837 def outgoing(ui, repo, dest=None, **opts):
1838 """show changesets not found in destination
1838 """show changesets not found in destination
1839
1839
1840 Show changesets not found in the specified destination repository or
1840 Show changesets not found in the specified destination repository or
1841 the default push location. These are the changesets that would be pushed
1841 the default push location. These are the changesets that would be pushed
1842 if a push was requested.
1842 if a push was requested.
1843
1843
1844 See pull for valid destination format details.
1844 See pull for valid destination format details.
1845 """
1845 """
1846 dest, revs, checkout = hg.parseurl(
1846 dest, revs, checkout = hg.parseurl(
1847 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1847 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1848 cmdutil.setremoteconfig(ui, opts)
1848 cmdutil.setremoteconfig(ui, opts)
1849 if revs:
1849 if revs:
1850 revs = [repo.lookup(rev) for rev in revs]
1850 revs = [repo.lookup(rev) for rev in revs]
1851
1851
1852 other = hg.repository(ui, dest)
1852 other = hg.repository(ui, dest)
1853 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1853 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
1854 o = repo.findoutgoing(other, force=opts['force'])
1854 o = repo.findoutgoing(other, force=opts['force'])
1855 if not o:
1855 if not o:
1856 ui.status(_("no changes found\n"))
1856 ui.status(_("no changes found\n"))
1857 return 1
1857 return 1
1858 o = repo.changelog.nodesbetween(o, revs)[0]
1858 o = repo.changelog.nodesbetween(o, revs)[0]
1859 if opts['newest_first']:
1859 if opts['newest_first']:
1860 o.reverse()
1860 o.reverse()
1861 displayer = cmdutil.show_changeset(ui, repo, opts)
1861 displayer = cmdutil.show_changeset(ui, repo, opts)
1862 for n in o:
1862 for n in o:
1863 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1863 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1864 if opts['no_merges'] and len(parents) == 2:
1864 if opts['no_merges'] and len(parents) == 2:
1865 continue
1865 continue
1866 displayer.show(changenode=n)
1866 displayer.show(changenode=n)
1867
1867
1868 def parents(ui, repo, file_=None, **opts):
1868 def parents(ui, repo, file_=None, **opts):
1869 """show the parents of the working dir or revision
1869 """show the parents of the working dir or revision
1870
1870
1871 Print the working directory's parent revisions. If a
1871 Print the working directory's parent revisions. If a
1872 revision is given via --rev, the parent of that revision
1872 revision is given via --rev, the parent of that revision
1873 will be printed. If a file argument is given, revision in
1873 will be printed. If a file argument is given, revision in
1874 which the file was last changed (before the working directory
1874 which the file was last changed (before the working directory
1875 revision or the argument to --rev if given) is printed.
1875 revision or the argument to --rev if given) is printed.
1876 """
1876 """
1877 rev = opts.get('rev')
1877 rev = opts.get('rev')
1878 if rev:
1878 if rev:
1879 ctx = repo.changectx(rev)
1879 ctx = repo.changectx(rev)
1880 else:
1880 else:
1881 ctx = repo.workingctx()
1881 ctx = repo.workingctx()
1882
1882
1883 if file_:
1883 if file_:
1884 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1884 files, match, anypats = cmdutil.matchpats(repo, (file_,), opts)
1885 if anypats or len(files) != 1:
1885 if anypats or len(files) != 1:
1886 raise util.Abort(_('can only specify an explicit file name'))
1886 raise util.Abort(_('can only specify an explicit file name'))
1887 file_ = files[0]
1887 file_ = files[0]
1888 filenodes = []
1888 filenodes = []
1889 for cp in ctx.parents():
1889 for cp in ctx.parents():
1890 if not cp:
1890 if not cp:
1891 continue
1891 continue
1892 try:
1892 try:
1893 filenodes.append(cp.filenode(file_))
1893 filenodes.append(cp.filenode(file_))
1894 except revlog.LookupError:
1894 except revlog.LookupError:
1895 pass
1895 pass
1896 if not filenodes:
1896 if not filenodes:
1897 raise util.Abort(_("'%s' not found in manifest!") % file_)
1897 raise util.Abort(_("'%s' not found in manifest!") % file_)
1898 fl = repo.file(file_)
1898 fl = repo.file(file_)
1899 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1899 p = [repo.lookup(fl.linkrev(fn)) for fn in filenodes]
1900 else:
1900 else:
1901 p = [cp.node() for cp in ctx.parents()]
1901 p = [cp.node() for cp in ctx.parents()]
1902
1902
1903 displayer = cmdutil.show_changeset(ui, repo, opts)
1903 displayer = cmdutil.show_changeset(ui, repo, opts)
1904 for n in p:
1904 for n in p:
1905 if n != nullid:
1905 if n != nullid:
1906 displayer.show(changenode=n)
1906 displayer.show(changenode=n)
1907
1907
1908 def paths(ui, repo, search=None):
1908 def paths(ui, repo, search=None):
1909 """show definition of symbolic path names
1909 """show definition of symbolic path names
1910
1910
1911 Show definition of symbolic path name NAME. If no name is given, show
1911 Show definition of symbolic path name NAME. If no name is given, show
1912 definition of available names.
1912 definition of available names.
1913
1913
1914 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1914 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.
1915 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1916 """
1916 """
1917 if search:
1917 if search:
1918 for name, path in ui.configitems("paths"):
1918 for name, path in ui.configitems("paths"):
1919 if name == search:
1919 if name == search:
1920 ui.write("%s\n" % path)
1920 ui.write("%s\n" % path)
1921 return
1921 return
1922 ui.warn(_("not found!\n"))
1922 ui.warn(_("not found!\n"))
1923 return 1
1923 return 1
1924 else:
1924 else:
1925 for name, path in ui.configitems("paths"):
1925 for name, path in ui.configitems("paths"):
1926 ui.write("%s = %s\n" % (name, path))
1926 ui.write("%s = %s\n" % (name, path))
1927
1927
1928 def postincoming(ui, repo, modheads, optupdate, checkout):
1928 def postincoming(ui, repo, modheads, optupdate, checkout):
1929 if modheads == 0:
1929 if modheads == 0:
1930 return
1930 return
1931 if optupdate:
1931 if optupdate:
1932 if modheads <= 1 or checkout:
1932 if modheads <= 1 or checkout:
1933 return hg.update(repo, checkout)
1933 return hg.update(repo, checkout)
1934 else:
1934 else:
1935 ui.status(_("not updating, since new heads added\n"))
1935 ui.status(_("not updating, since new heads added\n"))
1936 if modheads > 1:
1936 if modheads > 1:
1937 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1937 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1938 else:
1938 else:
1939 ui.status(_("(run 'hg update' to get a working copy)\n"))
1939 ui.status(_("(run 'hg update' to get a working copy)\n"))
1940
1940
1941 def pull(ui, repo, source="default", **opts):
1941 def pull(ui, repo, source="default", **opts):
1942 """pull changes from the specified source
1942 """pull changes from the specified source
1943
1943
1944 Pull changes from a remote repository to a local one.
1944 Pull changes from a remote repository to a local one.
1945
1945
1946 This finds all changes from the repository at the specified path
1946 This finds all changes from the repository at the specified path
1947 or URL and adds them to the local repository. By default, this
1947 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.
1948 does not update the copy of the project in the working directory.
1949
1949
1950 Valid URLs are of the form:
1950 Valid URLs are of the form:
1951
1951
1952 local/filesystem/path (or file://local/filesystem/path)
1952 local/filesystem/path (or file://local/filesystem/path)
1953 http://[user@]host[:port]/[path]
1953 http://[user@]host[:port]/[path]
1954 https://[user@]host[:port]/[path]
1954 https://[user@]host[:port]/[path]
1955 ssh://[user@]host[:port]/[path]
1955 ssh://[user@]host[:port]/[path]
1956 static-http://host[:port]/[path]
1956 static-http://host[:port]/[path]
1957
1957
1958 Paths in the local filesystem can either point to Mercurial
1958 Paths in the local filesystem can either point to Mercurial
1959 repositories or to bundle files (as created by 'hg bundle' or
1959 repositories or to bundle files (as created by 'hg bundle' or
1960 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1960 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1961 allows access to a Mercurial repository where you simply use a web
1961 allows access to a Mercurial repository where you simply use a web
1962 server to publish the .hg directory as static content.
1962 server to publish the .hg directory as static content.
1963
1963
1964 An optional identifier after # indicates a particular branch, tag,
1964 An optional identifier after # indicates a particular branch, tag,
1965 or changeset to pull.
1965 or changeset to pull.
1966
1966
1967 Some notes about using SSH with Mercurial:
1967 Some notes about using SSH with Mercurial:
1968 - SSH requires an accessible shell account on the destination machine
1968 - 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.
1969 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.
1970 - 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:
1971 Use an extra slash at the start of a path to specify an absolute path:
1972 ssh://example.com//tmp/repository
1972 ssh://example.com//tmp/repository
1973 - Mercurial doesn't use its own compression via SSH; the right thing
1973 - 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.:
1974 to do is to configure it in your ~/.ssh/config, e.g.:
1975 Host *.mylocalnetwork.example.com
1975 Host *.mylocalnetwork.example.com
1976 Compression no
1976 Compression no
1977 Host *
1977 Host *
1978 Compression yes
1978 Compression yes
1979 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1979 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1980 with the --ssh command line option.
1980 with the --ssh command line option.
1981 """
1981 """
1982 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1982 source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
1983 cmdutil.setremoteconfig(ui, opts)
1983 cmdutil.setremoteconfig(ui, opts)
1984
1984
1985 other = hg.repository(ui, source)
1985 other = hg.repository(ui, source)
1986 ui.status(_('pulling from %s\n') % util.hidepassword(source))
1986 ui.status(_('pulling from %s\n') % util.hidepassword(source))
1987 if revs:
1987 if revs:
1988 try:
1988 try:
1989 revs = [other.lookup(rev) for rev in revs]
1989 revs = [other.lookup(rev) for rev in revs]
1990 except repo.NoCapability:
1990 except repo.NoCapability:
1991 error = _("Other repository doesn't support revision lookup, "
1991 error = _("Other repository doesn't support revision lookup, "
1992 "so a rev cannot be specified.")
1992 "so a rev cannot be specified.")
1993 raise util.Abort(error)
1993 raise util.Abort(error)
1994
1994
1995 modheads = repo.pull(other, heads=revs, force=opts['force'])
1995 modheads = repo.pull(other, heads=revs, force=opts['force'])
1996 return postincoming(ui, repo, modheads, opts['update'], checkout)
1996 return postincoming(ui, repo, modheads, opts['update'], checkout)
1997
1997
1998 def push(ui, repo, dest=None, **opts):
1998 def push(ui, repo, dest=None, **opts):
1999 """push changes to the specified destination
1999 """push changes to the specified destination
2000
2000
2001 Push changes from the local repository to the given destination.
2001 Push changes from the local repository to the given destination.
2002
2002
2003 This is the symmetrical operation for pull. It helps to move
2003 This is the symmetrical operation for pull. It helps to move
2004 changes from the current repository to a different one. If the
2004 changes from the current repository to a different one. If the
2005 destination is local this is identical to a pull in that directory
2005 destination is local this is identical to a pull in that directory
2006 from the current one.
2006 from the current one.
2007
2007
2008 By default, push will refuse to run if it detects the result would
2008 By default, push will refuse to run if it detects the result would
2009 increase the number of remote heads. This generally indicates the
2009 increase the number of remote heads. This generally indicates the
2010 the client has forgotten to sync and merge before pushing.
2010 the client has forgotten to sync and merge before pushing.
2011
2011
2012 Valid URLs are of the form:
2012 Valid URLs are of the form:
2013
2013
2014 local/filesystem/path (or file://local/filesystem/path)
2014 local/filesystem/path (or file://local/filesystem/path)
2015 ssh://[user@]host[:port]/[path]
2015 ssh://[user@]host[:port]/[path]
2016 http://[user@]host[:port]/[path]
2016 http://[user@]host[:port]/[path]
2017 https://[user@]host[:port]/[path]
2017 https://[user@]host[:port]/[path]
2018
2018
2019 An optional identifier after # indicates a particular branch, tag,
2019 An optional identifier after # indicates a particular branch, tag,
2020 or changeset to push.
2020 or changeset to push.
2021
2021
2022 Look at the help text for the pull command for important details
2022 Look at the help text for the pull command for important details
2023 about ssh:// URLs.
2023 about ssh:// URLs.
2024
2024
2025 Pushing to http:// and https:// URLs is only possible, if this
2025 Pushing to http:// and https:// URLs is only possible, if this
2026 feature is explicitly enabled on the remote Mercurial server.
2026 feature is explicitly enabled on the remote Mercurial server.
2027 """
2027 """
2028 dest, revs, checkout = hg.parseurl(
2028 dest, revs, checkout = hg.parseurl(
2029 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2029 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2030 cmdutil.setremoteconfig(ui, opts)
2030 cmdutil.setremoteconfig(ui, opts)
2031
2031
2032 other = hg.repository(ui, dest)
2032 other = hg.repository(ui, dest)
2033 ui.status('pushing to %s\n' % util.hidepassword(dest))
2033 ui.status('pushing to %s\n' % util.hidepassword(dest))
2034 if revs:
2034 if revs:
2035 revs = [repo.lookup(rev) for rev in revs]
2035 revs = [repo.lookup(rev) for rev in revs]
2036 r = repo.push(other, opts['force'], revs=revs)
2036 r = repo.push(other, opts['force'], revs=revs)
2037 return r == 0
2037 return r == 0
2038
2038
2039 def rawcommit(ui, repo, *pats, **opts):
2039 def rawcommit(ui, repo, *pats, **opts):
2040 """raw commit interface (DEPRECATED)
2040 """raw commit interface (DEPRECATED)
2041
2041
2042 (DEPRECATED)
2042 (DEPRECATED)
2043 Lowlevel commit, for use in helper scripts.
2043 Lowlevel commit, for use in helper scripts.
2044
2044
2045 This command is not intended to be used by normal users, as it is
2045 This command is not intended to be used by normal users, as it is
2046 primarily useful for importing from other SCMs.
2046 primarily useful for importing from other SCMs.
2047
2047
2048 This command is now deprecated and will be removed in a future
2048 This command is now deprecated and will be removed in a future
2049 release, please use debugsetparents and commit instead.
2049 release, please use debugsetparents and commit instead.
2050 """
2050 """
2051
2051
2052 ui.warn(_("(the rawcommit command is deprecated)\n"))
2052 ui.warn(_("(the rawcommit command is deprecated)\n"))
2053
2053
2054 message = cmdutil.logmessage(opts)
2054 message = cmdutil.logmessage(opts)
2055
2055
2056 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2056 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2057 if opts['files']:
2057 if opts['files']:
2058 files += open(opts['files']).read().splitlines()
2058 files += open(opts['files']).read().splitlines()
2059
2059
2060 parents = [repo.lookup(p) for p in opts['parent']]
2060 parents = [repo.lookup(p) for p in opts['parent']]
2061
2061
2062 try:
2062 try:
2063 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2063 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2064 except ValueError, inst:
2064 except ValueError, inst:
2065 raise util.Abort(str(inst))
2065 raise util.Abort(str(inst))
2066
2066
2067 def recover(ui, repo):
2067 def recover(ui, repo):
2068 """roll back an interrupted transaction
2068 """roll back an interrupted transaction
2069
2069
2070 Recover from an interrupted commit or pull.
2070 Recover from an interrupted commit or pull.
2071
2071
2072 This command tries to fix the repository status after an interrupted
2072 This command tries to fix the repository status after an interrupted
2073 operation. It should only be necessary when Mercurial suggests it.
2073 operation. It should only be necessary when Mercurial suggests it.
2074 """
2074 """
2075 if repo.recover():
2075 if repo.recover():
2076 return hg.verify(repo)
2076 return hg.verify(repo)
2077 return 1
2077 return 1
2078
2078
2079 def remove(ui, repo, *pats, **opts):
2079 def remove(ui, repo, *pats, **opts):
2080 """remove the specified files on the next commit
2080 """remove the specified files on the next commit
2081
2081
2082 Schedule the indicated files for removal from the repository.
2082 Schedule the indicated files for removal from the repository.
2083
2083
2084 This only removes files from the current branch, not from the
2084 This only removes files from the current branch, not from the
2085 entire project history. If the files still exist in the working
2085 entire project history. If the files still exist in the working
2086 directory, they will be deleted from it. If invoked with --after,
2086 directory, they will be deleted from it. If invoked with --after,
2087 files are marked as removed, but not actually unlinked unless --force
2087 files are marked as removed, but not actually unlinked unless --force
2088 is also given. Without exact file names, --after will only mark
2088 is also given. Without exact file names, --after will only mark
2089 files as removed if they are no longer in the working directory.
2089 files as removed if they are no longer in the working directory.
2090
2090
2091 This command schedules the files to be removed at the next commit.
2091 This command schedules the files to be removed at the next commit.
2092 To undo a remove before that, see hg revert.
2092 To undo a remove before that, see hg revert.
2093
2093
2094 Modified files and added files are not removed by default. To
2094 Modified files and added files are not removed by default. To
2095 remove them, use the -f/--force option.
2095 remove them, use the -f/--force option.
2096 """
2096 """
2097 if not opts['after'] and not pats:
2097 if not opts['after'] and not pats:
2098 raise util.Abort(_('no files specified'))
2098 raise util.Abort(_('no files specified'))
2099 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2099 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2100 exact = dict.fromkeys(files)
2100 exact = dict.fromkeys(files)
2101 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2101 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2102 modified, added, removed, deleted, unknown = mardu
2102 modified, added, removed, deleted, unknown = mardu
2103 remove, forget = [], []
2103 remove, forget = [], []
2104 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2104 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2105 reason = None
2105 reason = None
2106 if abs in modified and not opts['force']:
2106 if abs in modified and not opts['force']:
2107 reason = _('is modified (use -f to force removal)')
2107 reason = _('is modified (use -f to force removal)')
2108 elif abs in added:
2108 elif abs in added:
2109 if opts['force']:
2109 if opts['force']:
2110 forget.append(abs)
2110 forget.append(abs)
2111 continue
2111 continue
2112 reason = _('has been marked for add (use -f to force removal)')
2112 reason = _('has been marked for add (use -f to force removal)')
2113 exact = 1 # force the message
2113 exact = 1 # force the message
2114 elif abs not in repo.dirstate:
2114 elif abs not in repo.dirstate:
2115 reason = _('is not managed')
2115 reason = _('is not managed')
2116 elif opts['after'] and not exact and abs not in deleted:
2116 elif opts['after'] and not exact and abs not in deleted:
2117 continue
2117 continue
2118 elif abs in removed:
2118 elif abs in removed:
2119 continue
2119 continue
2120 if reason:
2120 if reason:
2121 if exact:
2121 if exact:
2122 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2122 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2123 else:
2123 else:
2124 if ui.verbose or not exact:
2124 if ui.verbose or not exact:
2125 ui.status(_('removing %s\n') % rel)
2125 ui.status(_('removing %s\n') % rel)
2126 remove.append(abs)
2126 remove.append(abs)
2127 repo.forget(forget)
2127 repo.forget(forget)
2128 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2128 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2129
2129
2130 def rename(ui, repo, *pats, **opts):
2130 def rename(ui, repo, *pats, **opts):
2131 """rename files; equivalent of copy + remove
2131 """rename files; equivalent of copy + remove
2132
2132
2133 Mark dest as copies of sources; mark sources for deletion. If
2133 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
2134 dest is a directory, copies are put in that directory. If dest is
2135 a file, there can only be one source.
2135 a file, there can only be one source.
2136
2136
2137 By default, this command copies the contents of files as they
2137 By default, this command copies the contents of files as they
2138 stand in the working directory. If invoked with --after, the
2138 stand in the working directory. If invoked with --after, the
2139 operation is recorded, but no copying is performed.
2139 operation is recorded, but no copying is performed.
2140
2140
2141 This command takes effect in the next commit. To undo a rename
2141 This command takes effect in the next commit. To undo a rename
2142 before that, see hg revert.
2142 before that, see hg revert.
2143 """
2143 """
2144 wlock = repo.wlock(False)
2144 wlock = repo.wlock(False)
2145 try:
2145 try:
2146 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2146 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2147 finally:
2147 finally:
2148 del wlock
2148 del wlock
2149
2149
2150 def revert(ui, repo, *pats, **opts):
2150 def revert(ui, repo, *pats, **opts):
2151 """restore individual files or dirs to an earlier state
2151 """restore individual files or dirs to an earlier state
2152
2152
2153 (use update -r to check out earlier revisions, revert does not
2153 (use update -r to check out earlier revisions, revert does not
2154 change the working dir parents)
2154 change the working dir parents)
2155
2155
2156 With no revision specified, revert the named files or directories
2156 With no revision specified, revert the named files or directories
2157 to the contents they had in the parent of the working directory.
2157 to the contents they had in the parent of the working directory.
2158 This restores the contents of the affected files to an unmodified
2158 This restores the contents of the affected files to an unmodified
2159 state and unschedules adds, removes, copies, and renames. If the
2159 state and unschedules adds, removes, copies, and renames. If the
2160 working directory has two parents, you must explicitly specify the
2160 working directory has two parents, you must explicitly specify the
2161 revision to revert to.
2161 revision to revert to.
2162
2162
2163 Using the -r option, revert the given files or directories to their
2163 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
2164 contents as of a specific revision. This can be helpful to "roll
2165 back" some or all of an earlier change.
2165 back" some or all of an earlier change.
2166
2166
2167 Revert modifies the working directory. It does not commit any
2167 Revert modifies the working directory. It does not commit any
2168 changes, or change the parent of the working directory. If you
2168 changes, or change the parent of the working directory. If you
2169 revert to a revision other than the parent of the working
2169 revert to a revision other than the parent of the working
2170 directory, the reverted files will thus appear modified
2170 directory, the reverted files will thus appear modified
2171 afterwards.
2171 afterwards.
2172
2172
2173 If a file has been deleted, it is restored. If the executable
2173 If a file has been deleted, it is restored. If the executable
2174 mode of a file was changed, it is reset.
2174 mode of a file was changed, it is reset.
2175
2175
2176 If names are given, all files matching the names are reverted.
2176 If names are given, all files matching the names are reverted.
2177
2177
2178 If no arguments are given, no files are reverted.
2178 If no arguments are given, no files are reverted.
2179
2179
2180 Modified files are saved with a .orig suffix before reverting.
2180 Modified files are saved with a .orig suffix before reverting.
2181 To disable these backups, use --no-backup.
2181 To disable these backups, use --no-backup.
2182 """
2182 """
2183
2183
2184 if opts["date"]:
2184 if opts["date"]:
2185 if opts["rev"]:
2185 if opts["rev"]:
2186 raise util.Abort(_("you can't specify a revision and a date"))
2186 raise util.Abort(_("you can't specify a revision and a date"))
2187 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2187 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2188
2188
2189 if not pats and not opts['all']:
2189 if not pats and not opts['all']:
2190 raise util.Abort(_('no files or directories specified; '
2190 raise util.Abort(_('no files or directories specified; '
2191 'use --all to revert the whole repo'))
2191 'use --all to revert the whole repo'))
2192
2192
2193 parent, p2 = repo.dirstate.parents()
2193 parent, p2 = repo.dirstate.parents()
2194 if not opts['rev'] and p2 != nullid:
2194 if not opts['rev'] and p2 != nullid:
2195 raise util.Abort(_('uncommitted merge - please provide a '
2195 raise util.Abort(_('uncommitted merge - please provide a '
2196 'specific revision'))
2196 'specific revision'))
2197 ctx = repo.changectx(opts['rev'])
2197 ctx = repo.changectx(opts['rev'])
2198 node = ctx.node()
2198 node = ctx.node()
2199 mf = ctx.manifest()
2199 mf = ctx.manifest()
2200 if node == parent:
2200 if node == parent:
2201 pmf = mf
2201 pmf = mf
2202 else:
2202 else:
2203 pmf = None
2203 pmf = None
2204
2204
2205 # need all matching names in dirstate and manifest of target rev,
2205 # 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
2206 # so have to walk both. do not print errors if files exist in one
2207 # but not other.
2207 # but not other.
2208
2208
2209 names = {}
2209 names = {}
2210
2210
2211 wlock = repo.wlock()
2211 wlock = repo.wlock()
2212 try:
2212 try:
2213 # walk dirstate.
2213 # walk dirstate.
2214 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2214 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2215 badmatch=mf.has_key):
2215 badmatch=mf.has_key):
2216 names[abs] = (rel, exact)
2216 names[abs] = (rel, exact)
2217
2217
2218 # walk target manifest.
2218 # walk target manifest.
2219
2219
2220 def badmatch(path):
2220 def badmatch(path):
2221 if path in names:
2221 if path in names:
2222 return True
2222 return True
2223 path_ = path + '/'
2223 path_ = path + '/'
2224 for f in names:
2224 for f in names:
2225 if f.startswith(path_):
2225 if f.startswith(path_):
2226 return True
2226 return True
2227 return False
2227 return False
2228
2228
2229 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2229 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2230 badmatch=badmatch):
2230 badmatch=badmatch):
2231 if abs in names or src == 'b':
2231 if abs in names or src == 'b':
2232 continue
2232 continue
2233 names[abs] = (rel, exact)
2233 names[abs] = (rel, exact)
2234
2234
2235 changes = repo.status(match=names.has_key)[:4]
2235 changes = repo.status(match=names.has_key)[:4]
2236 modified, added, removed, deleted = map(dict.fromkeys, changes)
2236 modified, added, removed, deleted = map(dict.fromkeys, changes)
2237
2237
2238 # if f is a rename, also revert the source
2238 # if f is a rename, also revert the source
2239 cwd = repo.getcwd()
2239 cwd = repo.getcwd()
2240 for f in added:
2240 for f in added:
2241 src = repo.dirstate.copied(f)
2241 src = repo.dirstate.copied(f)
2242 if src and src not in names and repo.dirstate[src] == 'r':
2242 if src and src not in names and repo.dirstate[src] == 'r':
2243 removed[src] = None
2243 removed[src] = None
2244 names[src] = (repo.pathto(src, cwd), True)
2244 names[src] = (repo.pathto(src, cwd), True)
2245
2245
2246 revert = ([], _('reverting %s\n'))
2246 revert = ([], _('reverting %s\n'))
2247 add = ([], _('adding %s\n'))
2247 add = ([], _('adding %s\n'))
2248 remove = ([], _('removing %s\n'))
2248 remove = ([], _('removing %s\n'))
2249 forget = ([], _('forgetting %s\n'))
2249 forget = ([], _('forgetting %s\n'))
2250 undelete = ([], _('undeleting %s\n'))
2250 undelete = ([], _('undeleting %s\n'))
2251 update = {}
2251 update = {}
2252
2252
2253 disptable = (
2253 disptable = (
2254 # dispatch table:
2254 # dispatch table:
2255 # file state
2255 # file state
2256 # action if in target manifest
2256 # action if in target manifest
2257 # action if not in target manifest
2257 # action if not in target manifest
2258 # make backup if in target manifest
2258 # make backup if in target manifest
2259 # make backup if not in target manifest
2259 # make backup if not in target manifest
2260 (modified, revert, remove, True, True),
2260 (modified, revert, remove, True, True),
2261 (added, revert, forget, True, False),
2261 (added, revert, forget, True, False),
2262 (removed, undelete, None, False, False),
2262 (removed, undelete, None, False, False),
2263 (deleted, revert, remove, False, False),
2263 (deleted, revert, remove, False, False),
2264 )
2264 )
2265
2265
2266 entries = names.items()
2266 entries = names.items()
2267 entries.sort()
2267 entries.sort()
2268
2268
2269 for abs, (rel, exact) in entries:
2269 for abs, (rel, exact) in entries:
2270 mfentry = mf.get(abs)
2270 mfentry = mf.get(abs)
2271 target = repo.wjoin(abs)
2271 target = repo.wjoin(abs)
2272 def handle(xlist, dobackup):
2272 def handle(xlist, dobackup):
2273 xlist[0].append(abs)
2273 xlist[0].append(abs)
2274 update[abs] = 1
2274 update[abs] = 1
2275 if dobackup and not opts['no_backup'] and util.lexists(target):
2275 if dobackup and not opts['no_backup'] and util.lexists(target):
2276 bakname = "%s.orig" % rel
2276 bakname = "%s.orig" % rel
2277 ui.note(_('saving current version of %s as %s\n') %
2277 ui.note(_('saving current version of %s as %s\n') %
2278 (rel, bakname))
2278 (rel, bakname))
2279 if not opts.get('dry_run'):
2279 if not opts.get('dry_run'):
2280 util.copyfile(target, bakname)
2280 util.copyfile(target, bakname)
2281 if ui.verbose or not exact:
2281 if ui.verbose or not exact:
2282 ui.status(xlist[1] % rel)
2282 ui.status(xlist[1] % rel)
2283 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2283 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2284 if abs not in table: continue
2284 if abs not in table: continue
2285 # file has changed in dirstate
2285 # file has changed in dirstate
2286 if mfentry:
2286 if mfentry:
2287 handle(hitlist, backuphit)
2287 handle(hitlist, backuphit)
2288 elif misslist is not None:
2288 elif misslist is not None:
2289 handle(misslist, backupmiss)
2289 handle(misslist, backupmiss)
2290 break
2290 break
2291 else:
2291 else:
2292 if abs not in repo.dirstate:
2292 if abs not in repo.dirstate:
2293 if mfentry:
2293 if mfentry:
2294 handle(add, True)
2294 handle(add, True)
2295 elif exact:
2295 elif exact:
2296 ui.warn(_('file not managed: %s\n') % rel)
2296 ui.warn(_('file not managed: %s\n') % rel)
2297 continue
2297 continue
2298 # file has not changed in dirstate
2298 # file has not changed in dirstate
2299 if node == parent:
2299 if node == parent:
2300 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2300 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2301 continue
2301 continue
2302 if pmf is None:
2302 if pmf is None:
2303 # only need parent manifest in this unlikely case,
2303 # only need parent manifest in this unlikely case,
2304 # so do not read by default
2304 # so do not read by default
2305 pmf = repo.changectx(parent).manifest()
2305 pmf = repo.changectx(parent).manifest()
2306 if abs in pmf:
2306 if abs in pmf:
2307 if mfentry:
2307 if mfentry:
2308 # if version of file is same in parent and target
2308 # if version of file is same in parent and target
2309 # manifests, do nothing
2309 # manifests, do nothing
2310 if (pmf[abs] != mfentry or
2310 if (pmf[abs] != mfentry or
2311 pmf.flags(abs) != mf.flags(abs)):
2311 pmf.flags(abs) != mf.flags(abs)):
2312 handle(revert, False)
2312 handle(revert, False)
2313 else:
2313 else:
2314 handle(remove, False)
2314 handle(remove, False)
2315
2315
2316 if not opts.get('dry_run'):
2316 if not opts.get('dry_run'):
2317 for f in forget[0]:
2317 for f in forget[0]:
2318 repo.dirstate.forget(f)
2318 repo.dirstate.forget(f)
2319 r = hg.revert(repo, node, update.has_key)
2319 r = hg.revert(repo, node, update.has_key)
2320 for f in add[0]:
2320 for f in add[0]:
2321 repo.dirstate.add(f)
2321 repo.dirstate.add(f)
2322 for f in undelete[0]:
2322 for f in undelete[0]:
2323 repo.dirstate.normal(f)
2323 repo.dirstate.normal(f)
2324 for f in remove[0]:
2324 for f in remove[0]:
2325 repo.dirstate.remove(f)
2325 repo.dirstate.remove(f)
2326 return r
2326 return r
2327 finally:
2327 finally:
2328 del wlock
2328 del wlock
2329
2329
2330 def rollback(ui, repo):
2330 def rollback(ui, repo):
2331 """roll back the last transaction
2331 """roll back the last transaction
2332
2332
2333 This command should be used with care. There is only one level of
2333 This command should be used with care. There is only one level of
2334 rollback, and there is no way to undo a rollback. It will also
2334 rollback, and there is no way to undo a rollback. It will also
2335 restore the dirstate at the time of the last transaction, losing
2335 restore the dirstate at the time of the last transaction, losing
2336 any dirstate changes since that time.
2336 any dirstate changes since that time.
2337
2337
2338 Transactions are used to encapsulate the effects of all commands
2338 Transactions are used to encapsulate the effects of all commands
2339 that create new changesets or propagate existing changesets into a
2339 that create new changesets or propagate existing changesets into a
2340 repository. For example, the following commands are transactional,
2340 repository. For example, the following commands are transactional,
2341 and their effects can be rolled back:
2341 and their effects can be rolled back:
2342
2342
2343 commit
2343 commit
2344 import
2344 import
2345 pull
2345 pull
2346 push (with this repository as destination)
2346 push (with this repository as destination)
2347 unbundle
2347 unbundle
2348
2348
2349 This command is not intended for use on public repositories. Once
2349 This command is not intended for use on public repositories. Once
2350 changes are visible for pull by other users, rolling a transaction
2350 changes are visible for pull by other users, rolling a transaction
2351 back locally is ineffective (someone else may already have pulled
2351 back locally is ineffective (someone else may already have pulled
2352 the changes). Furthermore, a race is possible with readers of the
2352 the changes). Furthermore, a race is possible with readers of the
2353 repository; for example an in-progress pull from the repository
2353 repository; for example an in-progress pull from the repository
2354 may fail if a rollback is performed.
2354 may fail if a rollback is performed.
2355 """
2355 """
2356 repo.rollback()
2356 repo.rollback()
2357
2357
2358 def root(ui, repo):
2358 def root(ui, repo):
2359 """print the root (top) of the current working dir
2359 """print the root (top) of the current working dir
2360
2360
2361 Print the root directory of the current repository.
2361 Print the root directory of the current repository.
2362 """
2362 """
2363 ui.write(repo.root + "\n")
2363 ui.write(repo.root + "\n")
2364
2364
2365 def serve(ui, repo, **opts):
2365 def serve(ui, repo, **opts):
2366 """export the repository via HTTP
2366 """export the repository via HTTP
2367
2367
2368 Start a local HTTP repository browser and pull server.
2368 Start a local HTTP repository browser and pull server.
2369
2369
2370 By default, the server logs accesses to stdout and errors to
2370 By default, the server logs accesses to stdout and errors to
2371 stderr. Use the "-A" and "-E" options to log to files.
2371 stderr. Use the "-A" and "-E" options to log to files.
2372 """
2372 """
2373
2373
2374 if opts["stdio"]:
2374 if opts["stdio"]:
2375 if repo is None:
2375 if repo is None:
2376 raise hg.RepoError(_("There is no Mercurial repository here"
2376 raise hg.RepoError(_("There is no Mercurial repository here"
2377 " (.hg not found)"))
2377 " (.hg not found)"))
2378 s = sshserver.sshserver(ui, repo)
2378 s = sshserver.sshserver(ui, repo)
2379 s.serve_forever()
2379 s.serve_forever()
2380
2380
2381 parentui = ui.parentui or ui
2381 parentui = ui.parentui or ui
2382 optlist = ("name templates style address port prefix ipv6"
2382 optlist = ("name templates style address port prefix ipv6"
2383 " accesslog errorlog webdir_conf certificate")
2383 " accesslog errorlog webdir_conf certificate")
2384 for o in optlist.split():
2384 for o in optlist.split():
2385 if opts[o]:
2385 if opts[o]:
2386 parentui.setconfig("web", o, str(opts[o]))
2386 parentui.setconfig("web", o, str(opts[o]))
2387 if (repo is not None) and (repo.ui != parentui):
2387 if (repo is not None) and (repo.ui != parentui):
2388 repo.ui.setconfig("web", o, str(opts[o]))
2388 repo.ui.setconfig("web", o, str(opts[o]))
2389
2389
2390 if repo is None and not ui.config("web", "webdir_conf"):
2390 if repo is None and not ui.config("web", "webdir_conf"):
2391 raise hg.RepoError(_("There is no Mercurial repository here"
2391 raise hg.RepoError(_("There is no Mercurial repository here"
2392 " (.hg not found)"))
2392 " (.hg not found)"))
2393
2393
2394 class service:
2394 class service:
2395 def init(self):
2395 def init(self):
2396 util.set_signal_handler()
2396 util.set_signal_handler()
2397 try:
2397 try:
2398 self.httpd = hgweb.server.create_server(parentui, repo)
2398 self.httpd = hgweb.server.create_server(parentui, repo)
2399 except socket.error, inst:
2399 except socket.error, inst:
2400 raise util.Abort(_('cannot start server: ') + inst.args[1])
2400 raise util.Abort(_('cannot start server: ') + inst.args[1])
2401
2401
2402 if not ui.verbose: return
2402 if not ui.verbose: return
2403
2403
2404 if self.httpd.prefix:
2404 if self.httpd.prefix:
2405 prefix = self.httpd.prefix.strip('/') + '/'
2405 prefix = self.httpd.prefix.strip('/') + '/'
2406 else:
2406 else:
2407 prefix = ''
2407 prefix = ''
2408
2408
2409 if self.httpd.port != 80:
2409 if self.httpd.port != 80:
2410 ui.status(_('listening at http://%s:%d/%s\n') %
2410 ui.status(_('listening at http://%s:%d/%s\n') %
2411 (self.httpd.addr, self.httpd.port, prefix))
2411 (self.httpd.addr, self.httpd.port, prefix))
2412 else:
2412 else:
2413 ui.status(_('listening at http://%s/%s\n') %
2413 ui.status(_('listening at http://%s/%s\n') %
2414 (self.httpd.addr, prefix))
2414 (self.httpd.addr, prefix))
2415
2415
2416 def run(self):
2416 def run(self):
2417 self.httpd.serve_forever()
2417 self.httpd.serve_forever()
2418
2418
2419 service = service()
2419 service = service()
2420
2420
2421 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2421 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2422
2422
2423 def status(ui, repo, *pats, **opts):
2423 def status(ui, repo, *pats, **opts):
2424 """show changed files in the working directory
2424 """show changed files in the working directory
2425
2425
2426 Show status of files in the repository. If names are given, only
2426 Show status of files in the repository. If names are given, only
2427 files that match are shown. Files that are clean or ignored or
2427 files that match are shown. Files that are clean or ignored or
2428 source of a copy/move operation, are not listed unless -c (clean),
2428 source of a copy/move operation, are not listed unless -c (clean),
2429 -i (ignored), -C (copies) or -A is given. Unless options described
2429 -i (ignored), -C (copies) or -A is given. Unless options described
2430 with "show only ..." are given, the options -mardu are used.
2430 with "show only ..." are given, the options -mardu are used.
2431
2431
2432 NOTE: status may appear to disagree with diff if permissions have
2432 NOTE: status may appear to disagree with diff if permissions have
2433 changed or a merge has occurred. The standard diff format does not
2433 changed or a merge has occurred. The standard diff format does not
2434 report permission changes and diff only reports changes relative
2434 report permission changes and diff only reports changes relative
2435 to one merge parent.
2435 to one merge parent.
2436
2436
2437 If one revision is given, it is used as the base revision.
2437 If one revision is given, it is used as the base revision.
2438 If two revisions are given, the difference between them is shown.
2438 If two revisions are given, the difference between them is shown.
2439
2439
2440 The codes used to show the status of files are:
2440 The codes used to show the status of files are:
2441 M = modified
2441 M = modified
2442 A = added
2442 A = added
2443 R = removed
2443 R = removed
2444 C = clean
2444 C = clean
2445 ! = deleted, but still tracked
2445 ! = deleted, but still tracked
2446 ? = not tracked
2446 ? = not tracked
2447 I = ignored
2447 I = ignored
2448 = the previous added file was copied from here
2448 = the previous added file was copied from here
2449 """
2449 """
2450
2450
2451 all = opts['all']
2451 all = opts['all']
2452 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2452 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2453
2453
2454 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2454 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2455 cwd = (pats and repo.getcwd()) or ''
2455 cwd = (pats and repo.getcwd()) or ''
2456 modified, added, removed, deleted, unknown, ignored, clean = [
2456 modified, added, removed, deleted, unknown, ignored, clean = [
2457 n for n in repo.status(node1=node1, node2=node2, files=files,
2457 n for n in repo.status(node1=node1, node2=node2, files=files,
2458 match=matchfn,
2458 match=matchfn,
2459 list_ignored=all or opts['ignored'],
2459 list_ignored=all or opts['ignored'],
2460 list_clean=all or opts['clean'])]
2460 list_clean=all or opts['clean'])]
2461
2461
2462 changetypes = (('modified', 'M', modified),
2462 changetypes = (('modified', 'M', modified),
2463 ('added', 'A', added),
2463 ('added', 'A', added),
2464 ('removed', 'R', removed),
2464 ('removed', 'R', removed),
2465 ('deleted', '!', deleted),
2465 ('deleted', '!', deleted),
2466 ('unknown', '?', unknown),
2466 ('unknown', '?', unknown),
2467 ('ignored', 'I', ignored))
2467 ('ignored', 'I', ignored))
2468
2468
2469 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2469 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2470
2470
2471 end = opts['print0'] and '\0' or '\n'
2471 end = opts['print0'] and '\0' or '\n'
2472
2472
2473 for opt, char, changes in ([ct for ct in explicit_changetypes
2473 for opt, char, changes in ([ct for ct in explicit_changetypes
2474 if all or opts[ct[0]]]
2474 if all or opts[ct[0]]]
2475 or changetypes):
2475 or changetypes):
2476 if opts['no_status']:
2476 if opts['no_status']:
2477 format = "%%s%s" % end
2477 format = "%%s%s" % end
2478 else:
2478 else:
2479 format = "%s %%s%s" % (char, end)
2479 format = "%s %%s%s" % (char, end)
2480
2480
2481 for f in changes:
2481 for f in changes:
2482 ui.write(format % repo.pathto(f, cwd))
2482 ui.write(format % repo.pathto(f, cwd))
2483 if ((all or opts.get('copies')) and not opts.get('no_status')):
2483 if ((all or opts.get('copies')) and not opts.get('no_status')):
2484 copied = repo.dirstate.copied(f)
2484 copied = repo.dirstate.copied(f)
2485 if copied:
2485 if copied:
2486 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2486 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2487
2487
2488 def tag(ui, repo, name, rev_=None, **opts):
2488 def tag(ui, repo, name, rev_=None, **opts):
2489 """add a tag for the current or given revision
2489 """add a tag for the current or given revision
2490
2490
2491 Name a particular revision using <name>.
2491 Name a particular revision using <name>.
2492
2492
2493 Tags are used to name particular revisions of the repository and are
2493 Tags are used to name particular revisions of the repository and are
2494 very useful to compare different revision, to go back to significant
2494 very useful to compare different revision, to go back to significant
2495 earlier versions or to mark branch points as releases, etc.
2495 earlier versions or to mark branch points as releases, etc.
2496
2496
2497 If no revision is given, the parent of the working directory is used,
2497 If no revision is given, the parent of the working directory is used,
2498 or tip if no revision is checked out.
2498 or tip if no revision is checked out.
2499
2499
2500 To facilitate version control, distribution, and merging of tags,
2500 To facilitate version control, distribution, and merging of tags,
2501 they are stored as a file named ".hgtags" which is managed
2501 they are stored as a file named ".hgtags" which is managed
2502 similarly to other project files and can be hand-edited if
2502 similarly to other project files and can be hand-edited if
2503 necessary. The file '.hg/localtags' is used for local tags (not
2503 necessary. The file '.hg/localtags' is used for local tags (not
2504 shared among repositories).
2504 shared among repositories).
2505 """
2505 """
2506 if name in ['tip', '.', 'null']:
2506 if name in ['tip', '.', 'null']:
2507 raise util.Abort(_("the name '%s' is reserved") % name)
2507 raise util.Abort(_("the name '%s' is reserved") % name)
2508 if rev_ is not None:
2508 if rev_ is not None:
2509 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2509 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2510 "please use 'hg tag [-r REV] NAME' instead\n"))
2510 "please use 'hg tag [-r REV] NAME' instead\n"))
2511 if opts['rev']:
2511 if opts['rev']:
2512 raise util.Abort(_("use only one form to specify the revision"))
2512 raise util.Abort(_("use only one form to specify the revision"))
2513 if opts['rev'] and opts['remove']:
2513 if opts['rev'] and opts['remove']:
2514 raise util.Abort(_("--rev and --remove are incompatible"))
2514 raise util.Abort(_("--rev and --remove are incompatible"))
2515 if opts['rev']:
2515 if opts['rev']:
2516 rev_ = opts['rev']
2516 rev_ = opts['rev']
2517 message = opts['message']
2517 message = opts['message']
2518 if opts['remove']:
2518 if opts['remove']:
2519 tagtype = repo.tagtype(name)
2519 tagtype = repo.tagtype(name)
2520
2520
2521 if not tagtype:
2521 if not tagtype:
2522 raise util.Abort(_('tag %s does not exist') % name)
2522 raise util.Abort(_('tag %s does not exist') % name)
2523 if opts['local'] and tagtype == 'global':
2523 if opts['local'] and tagtype == 'global':
2524 raise util.Abort(_('%s tag is global') % name)
2524 raise util.Abort(_('%s tag is global') % name)
2525 if not opts['local'] and tagtype == 'local':
2525 if not opts['local'] and tagtype == 'local':
2526 raise util.Abort(_('%s tag is local') % name)
2526 raise util.Abort(_('%s tag is local') % name)
2527
2527
2528 rev_ = nullid
2528 rev_ = nullid
2529 if not message:
2529 if not message:
2530 message = _('Removed tag %s') % name
2530 message = _('Removed tag %s') % name
2531 elif name in repo.tags() and not opts['force']:
2531 elif name in repo.tags() and not opts['force']:
2532 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2532 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2533 % name)
2533 % name)
2534 if not rev_ and repo.dirstate.parents()[1] != nullid:
2534 if not rev_ and repo.dirstate.parents()[1] != nullid:
2535 raise util.Abort(_('uncommitted merge - please provide a '
2535 raise util.Abort(_('uncommitted merge - please provide a '
2536 'specific revision'))
2536 'specific revision'))
2537 r = repo.changectx(rev_).node()
2537 r = repo.changectx(rev_).node()
2538
2538
2539 if not message:
2539 if not message:
2540 message = _('Added tag %s for changeset %s') % (name, short(r))
2540 message = _('Added tag %s for changeset %s') % (name, short(r))
2541
2541
2542 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2542 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2543
2543
2544 def tags(ui, repo):
2544 def tags(ui, repo):
2545 """list repository tags
2545 """list repository tags
2546
2546
2547 List the repository tags.
2547 List the repository tags.
2548
2548
2549 This lists both regular and local tags. When the -v/--verbose switch
2549 This lists both regular and local tags. When the -v/--verbose switch
2550 is used, a third column "local" is printed for local tags.
2550 is used, a third column "local" is printed for local tags.
2551 """
2551 """
2552
2552
2553 l = repo.tagslist()
2553 l = repo.tagslist()
2554 l.reverse()
2554 l.reverse()
2555 hexfunc = ui.debugflag and hex or short
2555 hexfunc = ui.debugflag and hex or short
2556 tagtype = ""
2556 tagtype = ""
2557
2557
2558 for t, n in l:
2558 for t, n in l:
2559 if ui.quiet:
2559 if ui.quiet:
2560 ui.write("%s\n" % t)
2560 ui.write("%s\n" % t)
2561 continue
2561 continue
2562
2562
2563 try:
2563 try:
2564 hn = hexfunc(n)
2564 hn = hexfunc(n)
2565 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2565 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2566 except revlog.LookupError:
2566 except revlog.LookupError:
2567 r = " ?:%s" % hn
2567 r = " ?:%s" % hn
2568 else:
2568 else:
2569 spaces = " " * (30 - util.locallen(t))
2569 spaces = " " * (30 - util.locallen(t))
2570 if ui.verbose:
2570 if ui.verbose:
2571 if repo.tagtype(t) == 'local':
2571 if repo.tagtype(t) == 'local':
2572 tagtype = " local"
2572 tagtype = " local"
2573 else:
2573 else:
2574 tagtype = ""
2574 tagtype = ""
2575 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2575 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2576
2576
2577 def tip(ui, repo, **opts):
2577 def tip(ui, repo, **opts):
2578 """show the tip revision
2578 """show the tip revision
2579
2579
2580 Show the tip revision.
2580 Show the tip revision.
2581 """
2581 """
2582 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2582 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2583
2583
2584 def unbundle(ui, repo, fname1, *fnames, **opts):
2584 def unbundle(ui, repo, fname1, *fnames, **opts):
2585 """apply one or more changegroup files
2585 """apply one or more changegroup files
2586
2586
2587 Apply one or more compressed changegroup files generated by the
2587 Apply one or more compressed changegroup files generated by the
2588 bundle command.
2588 bundle command.
2589 """
2589 """
2590 fnames = (fname1,) + fnames
2590 fnames = (fname1,) + fnames
2591 for fname in fnames:
2591 for fname in fnames:
2592 if os.path.exists(fname):
2592 if os.path.exists(fname):
2593 f = open(fname, "rb")
2593 f = open(fname, "rb")
2594 else:
2594 else:
2595 f = urllib.urlopen(fname)
2595 f = urllib.urlopen(fname)
2596 gen = changegroup.readbundle(f, fname)
2596 gen = changegroup.readbundle(f, fname)
2597 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2597 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2598
2598
2599 return postincoming(ui, repo, modheads, opts['update'], None)
2599 return postincoming(ui, repo, modheads, opts['update'], None)
2600
2600
2601 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2601 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2602 """update working directory
2602 """update working directory
2603
2603
2604 Update the working directory to the specified revision, or the
2604 Update the working directory to the specified revision, or the
2605 tip of the current branch if none is specified.
2605 tip of the current branch if none is specified.
2606
2606
2607 If there are no outstanding changes in the working directory and
2607 If there are no outstanding changes in the working directory and
2608 there is a linear relationship between the current version and the
2608 there is a linear relationship between the current version and the
2609 requested version, the result is the requested version.
2609 requested version, the result is the requested version.
2610
2610
2611 To merge the working directory with another revision, use the
2611 To merge the working directory with another revision, use the
2612 merge command.
2612 merge command.
2613
2613
2614 By default, update will refuse to run if doing so would require
2614 By default, update will refuse to run if doing so would require
2615 discarding local changes.
2615 discarding local changes.
2616 """
2616 """
2617 if rev and node:
2617 if rev and node:
2618 raise util.Abort(_("please specify just one revision"))
2618 raise util.Abort(_("please specify just one revision"))
2619
2619
2620 if not rev:
2620 if not rev:
2621 rev = node
2621 rev = node
2622
2622
2623 if date:
2623 if date:
2624 if rev:
2624 if rev:
2625 raise util.Abort(_("you can't specify a revision and a date"))
2625 raise util.Abort(_("you can't specify a revision and a date"))
2626 rev = cmdutil.finddate(ui, repo, date)
2626 rev = cmdutil.finddate(ui, repo, date)
2627
2627
2628 if clean:
2628 if clean:
2629 return hg.clean(repo, rev)
2629 return hg.clean(repo, rev)
2630 else:
2630 else:
2631 return hg.update(repo, rev)
2631 return hg.update(repo, rev)
2632
2632
2633 def verify(ui, repo):
2633 def verify(ui, repo):
2634 """verify the integrity of the repository
2634 """verify the integrity of the repository
2635
2635
2636 Verify the integrity of the current repository.
2636 Verify the integrity of the current repository.
2637
2637
2638 This will perform an extensive check of the repository's
2638 This will perform an extensive check of the repository's
2639 integrity, validating the hashes and checksums of each entry in
2639 integrity, validating the hashes and checksums of each entry in
2640 the changelog, manifest, and tracked files, as well as the
2640 the changelog, manifest, and tracked files, as well as the
2641 integrity of their crosslinks and indices.
2641 integrity of their crosslinks and indices.
2642 """
2642 """
2643 return hg.verify(repo)
2643 return hg.verify(repo)
2644
2644
2645 def version_(ui):
2645 def version_(ui):
2646 """output version and copyright information"""
2646 """output version and copyright information"""
2647 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2647 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2648 % version.get_version())
2648 % version.get_version())
2649 ui.status(_(
2649 ui.status(_(
2650 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2650 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2651 "This is free software; see the source for copying conditions. "
2651 "This is free software; see the source for copying conditions. "
2652 "There is NO\nwarranty; "
2652 "There is NO\nwarranty; "
2653 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2653 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2654 ))
2654 ))
2655
2655
2656 # Command options and aliases are listed here, alphabetically
2656 # Command options and aliases are listed here, alphabetically
2657
2657
2658 globalopts = [
2658 globalopts = [
2659 ('R', 'repository', '',
2659 ('R', 'repository', '',
2660 _('repository root directory or symbolic path name')),
2660 _('repository root directory or symbolic path name')),
2661 ('', 'cwd', '', _('change working directory')),
2661 ('', 'cwd', '', _('change working directory')),
2662 ('y', 'noninteractive', None,
2662 ('y', 'noninteractive', None,
2663 _('do not prompt, assume \'yes\' for any required answers')),
2663 _('do not prompt, assume \'yes\' for any required answers')),
2664 ('q', 'quiet', None, _('suppress output')),
2664 ('q', 'quiet', None, _('suppress output')),
2665 ('v', 'verbose', None, _('enable additional output')),
2665 ('v', 'verbose', None, _('enable additional output')),
2666 ('', 'config', [], _('set/override config option')),
2666 ('', 'config', [], _('set/override config option')),
2667 ('', 'debug', None, _('enable debugging output')),
2667 ('', 'debug', None, _('enable debugging output')),
2668 ('', 'debugger', None, _('start debugger')),
2668 ('', 'debugger', None, _('start debugger')),
2669 ('', 'encoding', util._encoding, _('set the charset encoding')),
2669 ('', 'encoding', util._encoding, _('set the charset encoding')),
2670 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2670 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2671 ('', 'lsprof', None, _('print improved command execution profile')),
2671 ('', 'lsprof', None, _('print improved command execution profile')),
2672 ('', 'traceback', None, _('print traceback on exception')),
2672 ('', 'traceback', None, _('print traceback on exception')),
2673 ('', 'time', None, _('time how long the command takes')),
2673 ('', 'time', None, _('time how long the command takes')),
2674 ('', 'profile', None, _('print command execution profile')),
2674 ('', 'profile', None, _('print command execution profile')),
2675 ('', 'version', None, _('output version information and exit')),
2675 ('', 'version', None, _('output version information and exit')),
2676 ('h', 'help', None, _('display help and exit')),
2676 ('h', 'help', None, _('display help and exit')),
2677 ]
2677 ]
2678
2678
2679 dryrunopts = [('n', 'dry-run', None,
2679 dryrunopts = [('n', 'dry-run', None,
2680 _('do not perform actions, just print output'))]
2680 _('do not perform actions, just print output'))]
2681
2681
2682 remoteopts = [
2682 remoteopts = [
2683 ('e', 'ssh', '', _('specify ssh command to use')),
2683 ('e', 'ssh', '', _('specify ssh command to use')),
2684 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2684 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2685 ]
2685 ]
2686
2686
2687 walkopts = [
2687 walkopts = [
2688 ('I', 'include', [], _('include names matching the given patterns')),
2688 ('I', 'include', [], _('include names matching the given patterns')),
2689 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2689 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2690 ]
2690 ]
2691
2691
2692 commitopts = [
2692 commitopts = [
2693 ('m', 'message', '', _('use <text> as commit message')),
2693 ('m', 'message', '', _('use <text> as commit message')),
2694 ('l', 'logfile', '', _('read commit message from <file>')),
2694 ('l', 'logfile', '', _('read commit message from <file>')),
2695 ]
2695 ]
2696
2696
2697 commitopts2 = [
2697 commitopts2 = [
2698 ('d', 'date', '', _('record datecode as commit date')),
2698 ('d', 'date', '', _('record datecode as commit date')),
2699 ('u', 'user', '', _('record user as committer')),
2699 ('u', 'user', '', _('record user as committer')),
2700 ]
2700 ]
2701
2701
2702 table = {
2702 table = {
2703 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2703 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2704 "addremove":
2704 "addremove":
2705 (addremove,
2705 (addremove,
2706 [('s', 'similarity', '',
2706 [('s', 'similarity', '',
2707 _('guess renamed files by similarity (0<=s<=100)')),
2707 _('guess renamed files by similarity (0<=s<=100)')),
2708 ] + walkopts + dryrunopts,
2708 ] + walkopts + dryrunopts,
2709 _('hg addremove [OPTION]... [FILE]...')),
2709 _('hg addremove [OPTION]... [FILE]...')),
2710 "^annotate":
2710 "^annotate":
2711 (annotate,
2711 (annotate,
2712 [('r', 'rev', '', _('annotate the specified revision')),
2712 [('r', 'rev', '', _('annotate the specified revision')),
2713 ('f', 'follow', None, _('follow file copies and renames')),
2713 ('f', 'follow', None, _('follow file copies and renames')),
2714 ('a', 'text', None, _('treat all files as text')),
2714 ('a', 'text', None, _('treat all files as text')),
2715 ('u', 'user', None, _('list the author')),
2715 ('u', 'user', None, _('list the author')),
2716 ('d', 'date', None, _('list the date')),
2716 ('d', 'date', None, _('list the date')),
2717 ('n', 'number', None, _('list the revision number (default)')),
2717 ('n', 'number', None, _('list the revision number (default)')),
2718 ('c', 'changeset', None, _('list the changeset')),
2718 ('c', 'changeset', None, _('list the changeset')),
2719 ('l', 'line-number', None,
2719 ('l', 'line-number', None,
2720 _('show line number at the first appearance'))
2720 _('show line number at the first appearance'))
2721 ] + walkopts,
2721 ] + walkopts,
2722 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2722 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2723 "archive":
2723 "archive":
2724 (archive,
2724 (archive,
2725 [('', 'no-decode', None, _('do not pass files through decoders')),
2725 [('', 'no-decode', None, _('do not pass files through decoders')),
2726 ('p', 'prefix', '', _('directory prefix for files in archive')),
2726 ('p', 'prefix', '', _('directory prefix for files in archive')),
2727 ('r', 'rev', '', _('revision to distribute')),
2727 ('r', 'rev', '', _('revision to distribute')),
2728 ('t', 'type', '', _('type of distribution to create')),
2728 ('t', 'type', '', _('type of distribution to create')),
2729 ] + walkopts,
2729 ] + walkopts,
2730 _('hg archive [OPTION]... DEST')),
2730 _('hg archive [OPTION]... DEST')),
2731 "backout":
2731 "backout":
2732 (backout,
2732 (backout,
2733 [('', 'merge', None,
2733 [('', 'merge', None,
2734 _('merge with old dirstate parent after backout')),
2734 _('merge with old dirstate parent after backout')),
2735 ('', 'parent', '', _('parent to choose when backing out merge')),
2735 ('', 'parent', '', _('parent to choose when backing out merge')),
2736 ('r', 'rev', '', _('revision to backout')),
2736 ('r', 'rev', '', _('revision to backout')),
2737 ] + walkopts + commitopts + commitopts2,
2737 ] + walkopts + commitopts + commitopts2,
2738 _('hg backout [OPTION]... [-r] REV')),
2738 _('hg backout [OPTION]... [-r] REV')),
2739 "bisect":
2739 "bisect":
2740 (bisect,
2740 (bisect,
2741 [('r', 'reset', False, _('reset bisect state')),
2741 [('r', 'reset', False, _('reset bisect state')),
2742 ('g', 'good', False, _('mark changeset good')),
2742 ('g', 'good', False, _('mark changeset good')),
2743 ('b', 'bad', False, _('mark changeset bad')),
2743 ('b', 'bad', False, _('mark changeset bad')),
2744 ('s', 'skip', False, _('skip testing changeset')),
2744 ('s', 'skip', False, _('skip testing changeset')),
2745 ('U', 'noupdate', False, _('do not update to target'))],
2745 ('U', 'noupdate', False, _('do not update to target'))],
2746 _("hg bisect [-gbsr] [REV]")),
2746 _("hg bisect [-gbsr] [REV]")),
2747 "branch":
2747 "branch":
2748 (branch,
2748 (branch,
2749 [('f', 'force', None,
2749 [('f', 'force', None,
2750 _('set branch name even if it shadows an existing branch'))],
2750 _('set branch name even if it shadows an existing branch'))],
2751 _('hg branch [-f] [NAME]')),
2751 _('hg branch [-f] [NAME]')),
2752 "branches":
2752 "branches":
2753 (branches,
2753 (branches,
2754 [('a', 'active', False,
2754 [('a', 'active', False,
2755 _('show only branches that have unmerged heads'))],
2755 _('show only branches that have unmerged heads'))],
2756 _('hg branches [-a]')),
2756 _('hg branches [-a]')),
2757 "bundle":
2757 "bundle":
2758 (bundle,
2758 (bundle,
2759 [('f', 'force', None,
2759 [('f', 'force', None,
2760 _('run even when remote repository is unrelated')),
2760 _('run even when remote repository is unrelated')),
2761 ('r', 'rev', [],
2761 ('r', 'rev', [],
2762 _('a changeset you would like to bundle')),
2762 _('a changeset you would like to bundle')),
2763 ('', 'base', [],
2763 ('', 'base', [],
2764 _('a base changeset to specify instead of a destination')),
2764 _('a base changeset to specify instead of a destination')),
2765 ] + remoteopts,
2765 ] + remoteopts,
2766 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2766 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2767 "cat":
2767 "cat":
2768 (cat,
2768 (cat,
2769 [('o', 'output', '', _('print output to file with formatted name')),
2769 [('o', 'output', '', _('print output to file with formatted name')),
2770 ('r', 'rev', '', _('print the given revision')),
2770 ('r', 'rev', '', _('print the given revision')),
2771 ('d', 'decode', None, _('apply any matching decode filter')),
2771 ('', 'decode', None, _('apply any matching decode filter')),
2772 ] + walkopts,
2772 ] + walkopts,
2773 _('hg cat [OPTION]... FILE...')),
2773 _('hg cat [OPTION]... FILE...')),
2774 "^clone":
2774 "^clone":
2775 (clone,
2775 (clone,
2776 [('U', 'noupdate', None, _('do not update the new working directory')),
2776 [('U', 'noupdate', None, _('do not update the new working directory')),
2777 ('r', 'rev', [],
2777 ('r', 'rev', [],
2778 _('a changeset you would like to have after cloning')),
2778 _('a changeset you would like to have after cloning')),
2779 ('', 'pull', None, _('use pull protocol to copy metadata')),
2779 ('', 'pull', None, _('use pull protocol to copy metadata')),
2780 ('', 'uncompressed', None,
2780 ('', 'uncompressed', None,
2781 _('use uncompressed transfer (fast over LAN)')),
2781 _('use uncompressed transfer (fast over LAN)')),
2782 ] + remoteopts,
2782 ] + remoteopts,
2783 _('hg clone [OPTION]... SOURCE [DEST]')),
2783 _('hg clone [OPTION]... SOURCE [DEST]')),
2784 "^commit|ci":
2784 "^commit|ci":
2785 (commit,
2785 (commit,
2786 [('A', 'addremove', None,
2786 [('A', 'addremove', None,
2787 _('mark new/missing files as added/removed before committing')),
2787 _('mark new/missing files as added/removed before committing')),
2788 ] + walkopts + commitopts + commitopts2,
2788 ] + walkopts + commitopts + commitopts2,
2789 _('hg commit [OPTION]... [FILE]...')),
2789 _('hg commit [OPTION]... [FILE]...')),
2790 "copy|cp":
2790 "copy|cp":
2791 (copy,
2791 (copy,
2792 [('A', 'after', None, _('record a copy that has already occurred')),
2792 [('A', 'after', None, _('record a copy that has already occurred')),
2793 ('f', 'force', None,
2793 ('f', 'force', None,
2794 _('forcibly copy over an existing managed file')),
2794 _('forcibly copy over an existing managed file')),
2795 ] + walkopts + dryrunopts,
2795 ] + walkopts + dryrunopts,
2796 _('hg copy [OPTION]... [SOURCE]... DEST')),
2796 _('hg copy [OPTION]... [SOURCE]... DEST')),
2797 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2797 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2798 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2798 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2799 "debugcomplete":
2799 "debugcomplete":
2800 (debugcomplete,
2800 (debugcomplete,
2801 [('o', 'options', None, _('show the command options'))],
2801 [('o', 'options', None, _('show the command options'))],
2802 _('hg debugcomplete [-o] CMD')),
2802 _('hg debugcomplete [-o] CMD')),
2803 "debugdate":
2803 "debugdate":
2804 (debugdate,
2804 (debugdate,
2805 [('e', 'extended', None, _('try extended date formats'))],
2805 [('e', 'extended', None, _('try extended date formats'))],
2806 _('hg debugdate [-e] DATE [RANGE]')),
2806 _('hg debugdate [-e] DATE [RANGE]')),
2807 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2807 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2808 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2808 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2809 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2809 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2810 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2810 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2811 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2811 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2812 "debugrawcommit|rawcommit":
2812 "debugrawcommit|rawcommit":
2813 (rawcommit,
2813 (rawcommit,
2814 [('p', 'parent', [], _('parent')),
2814 [('p', 'parent', [], _('parent')),
2815 ('F', 'files', '', _('file list'))
2815 ('F', 'files', '', _('file list'))
2816 ] + commitopts + commitopts2,
2816 ] + commitopts + commitopts2,
2817 _('hg debugrawcommit [OPTION]... [FILE]...')),
2817 _('hg debugrawcommit [OPTION]... [FILE]...')),
2818 "debugrebuildstate":
2818 "debugrebuildstate":
2819 (debugrebuildstate,
2819 (debugrebuildstate,
2820 [('r', 'rev', '', _('revision to rebuild to'))],
2820 [('r', 'rev', '', _('revision to rebuild to'))],
2821 _('hg debugrebuildstate [-r REV] [REV]')),
2821 _('hg debugrebuildstate [-r REV] [REV]')),
2822 "debugrename":
2822 "debugrename":
2823 (debugrename,
2823 (debugrename,
2824 [('r', 'rev', '', _('revision to debug'))],
2824 [('r', 'rev', '', _('revision to debug'))],
2825 _('hg debugrename [-r REV] FILE')),
2825 _('hg debugrename [-r REV] FILE')),
2826 "debugsetparents":
2826 "debugsetparents":
2827 (debugsetparents,
2827 (debugsetparents,
2828 [],
2828 [],
2829 _('hg debugsetparents REV1 [REV2]')),
2829 _('hg debugsetparents REV1 [REV2]')),
2830 "debugstate": (debugstate, [], _('hg debugstate')),
2830 "debugstate": (debugstate, [], _('hg debugstate')),
2831 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2831 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2832 "^diff":
2832 "^diff":
2833 (diff,
2833 (diff,
2834 [('r', 'rev', [], _('revision')),
2834 [('r', 'rev', [], _('revision')),
2835 ('a', 'text', None, _('treat all files as text')),
2835 ('a', 'text', None, _('treat all files as text')),
2836 ('p', 'show-function', None,
2836 ('p', 'show-function', None,
2837 _('show which function each change is in')),
2837 _('show which function each change is in')),
2838 ('g', 'git', None, _('use git extended diff format')),
2838 ('g', 'git', None, _('use git extended diff format')),
2839 ('', 'nodates', None, _("don't include dates in diff headers")),
2839 ('', 'nodates', None, _("don't include dates in diff headers")),
2840 ('w', 'ignore-all-space', None,
2840 ('w', 'ignore-all-space', None,
2841 _('ignore white space when comparing lines')),
2841 _('ignore white space when comparing lines')),
2842 ('b', 'ignore-space-change', None,
2842 ('b', 'ignore-space-change', None,
2843 _('ignore changes in the amount of white space')),
2843 _('ignore changes in the amount of white space')),
2844 ('B', 'ignore-blank-lines', None,
2844 ('B', 'ignore-blank-lines', None,
2845 _('ignore changes whose lines are all blank')),
2845 _('ignore changes whose lines are all blank')),
2846 ('U', 'unified', 3,
2846 ('U', 'unified', 3,
2847 _('number of lines of context to show'))
2847 _('number of lines of context to show'))
2848 ] + walkopts,
2848 ] + walkopts,
2849 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2849 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2850 "^export":
2850 "^export":
2851 (export,
2851 (export,
2852 [('o', 'output', '', _('print output to file with formatted name')),
2852 [('o', 'output', '', _('print output to file with formatted name')),
2853 ('a', 'text', None, _('treat all files as text')),
2853 ('a', 'text', None, _('treat all files as text')),
2854 ('g', 'git', None, _('use git extended diff format')),
2854 ('g', 'git', None, _('use git extended diff format')),
2855 ('', 'nodates', None, _("don't include dates in diff headers")),
2855 ('', 'nodates', None, _("don't include dates in diff headers")),
2856 ('', 'switch-parent', None, _('diff against the second parent'))],
2856 ('', 'switch-parent', None, _('diff against the second parent'))],
2857 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2857 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2858 "grep":
2858 "grep":
2859 (grep,
2859 (grep,
2860 [('0', 'print0', None, _('end fields with NUL')),
2860 [('0', 'print0', None, _('end fields with NUL')),
2861 ('', 'all', None, _('print all revisions that match')),
2861 ('', 'all', None, _('print all revisions that match')),
2862 ('f', 'follow', None,
2862 ('f', 'follow', None,
2863 _('follow changeset history, or file history across copies and renames')),
2863 _('follow changeset history, or file history across copies and renames')),
2864 ('i', 'ignore-case', None, _('ignore case when matching')),
2864 ('i', 'ignore-case', None, _('ignore case when matching')),
2865 ('l', 'files-with-matches', None,
2865 ('l', 'files-with-matches', None,
2866 _('print only filenames and revs that match')),
2866 _('print only filenames and revs that match')),
2867 ('n', 'line-number', None, _('print matching line numbers')),
2867 ('n', 'line-number', None, _('print matching line numbers')),
2868 ('r', 'rev', [], _('search in given revision range')),
2868 ('r', 'rev', [], _('search in given revision range')),
2869 ('u', 'user', None, _('print user who committed change')),
2869 ('u', 'user', None, _('print user who committed change')),
2870 ] + walkopts,
2870 ] + walkopts,
2871 _('hg grep [OPTION]... PATTERN [FILE]...')),
2871 _('hg grep [OPTION]... PATTERN [FILE]...')),
2872 "heads":
2872 "heads":
2873 (heads,
2873 (heads,
2874 [('', 'style', '', _('display using template map file')),
2874 [('', 'style', '', _('display using template map file')),
2875 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2875 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2876 ('', 'template', '', _('display with template'))],
2876 ('', 'template', '', _('display with template'))],
2877 _('hg heads [-r REV] [REV]...')),
2877 _('hg heads [-r REV] [REV]...')),
2878 "help": (help_, [], _('hg help [COMMAND]')),
2878 "help": (help_, [], _('hg help [COMMAND]')),
2879 "identify|id":
2879 "identify|id":
2880 (identify,
2880 (identify,
2881 [('r', 'rev', '', _('identify the specified rev')),
2881 [('r', 'rev', '', _('identify the specified rev')),
2882 ('n', 'num', None, _('show local revision number')),
2882 ('n', 'num', None, _('show local revision number')),
2883 ('i', 'id', None, _('show global revision id')),
2883 ('i', 'id', None, _('show global revision id')),
2884 ('b', 'branch', None, _('show branch')),
2884 ('b', 'branch', None, _('show branch')),
2885 ('t', 'tags', None, _('show tags'))],
2885 ('t', 'tags', None, _('show tags'))],
2886 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2886 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2887 "import|patch":
2887 "import|patch":
2888 (import_,
2888 (import_,
2889 [('p', 'strip', 1,
2889 [('p', 'strip', 1,
2890 _('directory strip option for patch. This has the same\n'
2890 _('directory strip option for patch. This has the same\n'
2891 'meaning as the corresponding patch option')),
2891 'meaning as the corresponding patch option')),
2892 ('b', 'base', '', _('base path')),
2892 ('b', 'base', '', _('base path')),
2893 ('f', 'force', None,
2893 ('f', 'force', None,
2894 _('skip check for outstanding uncommitted changes')),
2894 _('skip check for outstanding uncommitted changes')),
2895 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2895 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2896 ('', 'exact', None,
2896 ('', 'exact', None,
2897 _('apply patch to the nodes from which it was generated')),
2897 _('apply patch to the nodes from which it was generated')),
2898 ('', 'import-branch', None,
2898 ('', 'import-branch', None,
2899 _('Use any branch information in patch (implied by --exact)'))] +
2899 _('Use any branch information in patch (implied by --exact)'))] +
2900 commitopts + commitopts2,
2900 commitopts + commitopts2,
2901 _('hg import [OPTION]... PATCH...')),
2901 _('hg import [OPTION]... PATCH...')),
2902 "incoming|in":
2902 "incoming|in":
2903 (incoming,
2903 (incoming,
2904 [('M', 'no-merges', None, _('do not show merges')),
2904 [('M', 'no-merges', None, _('do not show merges')),
2905 ('f', 'force', None,
2905 ('f', 'force', None,
2906 _('run even when remote repository is unrelated')),
2906 _('run even when remote repository is unrelated')),
2907 ('', 'style', '', _('display using template map file')),
2907 ('', 'style', '', _('display using template map file')),
2908 ('n', 'newest-first', None, _('show newest record first')),
2908 ('n', 'newest-first', None, _('show newest record first')),
2909 ('', 'bundle', '', _('file to store the bundles into')),
2909 ('', 'bundle', '', _('file to store the bundles into')),
2910 ('p', 'patch', None, _('show patch')),
2910 ('p', 'patch', None, _('show patch')),
2911 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2911 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2912 ('', 'template', '', _('display with template')),
2912 ('', 'template', '', _('display with template')),
2913 ] + remoteopts,
2913 ] + remoteopts,
2914 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2914 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2915 ' [--bundle FILENAME] [SOURCE]')),
2915 ' [--bundle FILENAME] [SOURCE]')),
2916 "^init":
2916 "^init":
2917 (init,
2917 (init,
2918 remoteopts,
2918 remoteopts,
2919 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2919 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2920 "locate":
2920 "locate":
2921 (locate,
2921 (locate,
2922 [('r', 'rev', '', _('search the repository as it stood at rev')),
2922 [('r', 'rev', '', _('search the repository as it stood at rev')),
2923 ('0', 'print0', None,
2923 ('0', 'print0', None,
2924 _('end filenames with NUL, for use with xargs')),
2924 _('end filenames with NUL, for use with xargs')),
2925 ('f', 'fullpath', None,
2925 ('f', 'fullpath', None,
2926 _('print complete paths from the filesystem root')),
2926 _('print complete paths from the filesystem root')),
2927 ] + walkopts,
2927 ] + walkopts,
2928 _('hg locate [OPTION]... [PATTERN]...')),
2928 _('hg locate [OPTION]... [PATTERN]...')),
2929 "^log|history":
2929 "^log|history":
2930 (log,
2930 (log,
2931 [('f', 'follow', None,
2931 [('f', 'follow', None,
2932 _('follow changeset history, or file history across copies and renames')),
2932 _('follow changeset history, or file history across copies and renames')),
2933 ('', 'follow-first', None,
2933 ('', 'follow-first', None,
2934 _('only follow the first parent of merge changesets')),
2934 _('only follow the first parent of merge changesets')),
2935 ('d', 'date', '', _('show revs matching date spec')),
2935 ('d', 'date', '', _('show revs matching date spec')),
2936 ('C', 'copies', None, _('show copied files')),
2936 ('C', 'copies', None, _('show copied files')),
2937 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2937 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2938 ('l', 'limit', '', _('limit number of changes displayed')),
2938 ('l', 'limit', '', _('limit number of changes displayed')),
2939 ('r', 'rev', [], _('show the specified revision or range')),
2939 ('r', 'rev', [], _('show the specified revision or range')),
2940 ('', 'removed', None, _('include revs where files were removed')),
2940 ('', 'removed', None, _('include revs where files were removed')),
2941 ('M', 'no-merges', None, _('do not show merges')),
2941 ('M', 'no-merges', None, _('do not show merges')),
2942 ('', 'style', '', _('display using template map file')),
2942 ('', 'style', '', _('display using template map file')),
2943 ('m', 'only-merges', None, _('show only merges')),
2943 ('m', 'only-merges', None, _('show only merges')),
2944 ('b', 'only-branch', [],
2944 ('b', 'only-branch', [],
2945 _('show only changesets within the given named branch')),
2945 _('show only changesets within the given named branch')),
2946 ('p', 'patch', None, _('show patch')),
2946 ('p', 'patch', None, _('show patch')),
2947 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2947 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2948 ('', 'template', '', _('display with template')),
2948 ('', 'template', '', _('display with template')),
2949 ] + walkopts,
2949 ] + walkopts,
2950 _('hg log [OPTION]... [FILE]')),
2950 _('hg log [OPTION]... [FILE]')),
2951 "manifest":
2951 "manifest":
2952 (manifest,
2952 (manifest,
2953 [('r', 'rev', '', _('revision to display'))],
2953 [('r', 'rev', '', _('revision to display'))],
2954 _('hg manifest [-r REV]')),
2954 _('hg manifest [-r REV]')),
2955 "^merge":
2955 "^merge":
2956 (merge,
2956 (merge,
2957 [('f', 'force', None, _('force a merge with outstanding changes')),
2957 [('f', 'force', None, _('force a merge with outstanding changes')),
2958 ('r', 'rev', '', _('revision to merge')),
2958 ('r', 'rev', '', _('revision to merge')),
2959 ],
2959 ],
2960 _('hg merge [-f] [[-r] REV]')),
2960 _('hg merge [-f] [[-r] REV]')),
2961 "outgoing|out":
2961 "outgoing|out":
2962 (outgoing,
2962 (outgoing,
2963 [('M', 'no-merges', None, _('do not show merges')),
2963 [('M', 'no-merges', None, _('do not show merges')),
2964 ('f', 'force', None,
2964 ('f', 'force', None,
2965 _('run even when remote repository is unrelated')),
2965 _('run even when remote repository is unrelated')),
2966 ('p', 'patch', None, _('show patch')),
2966 ('p', 'patch', None, _('show patch')),
2967 ('', 'style', '', _('display using template map file')),
2967 ('', 'style', '', _('display using template map file')),
2968 ('r', 'rev', [], _('a specific revision you would like to push')),
2968 ('r', 'rev', [], _('a specific revision you would like to push')),
2969 ('n', 'newest-first', None, _('show newest record first')),
2969 ('n', 'newest-first', None, _('show newest record first')),
2970 ('', 'template', '', _('display with template')),
2970 ('', 'template', '', _('display with template')),
2971 ] + remoteopts,
2971 ] + remoteopts,
2972 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2972 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2973 "^parents":
2973 "^parents":
2974 (parents,
2974 (parents,
2975 [('r', 'rev', '', _('show parents from the specified rev')),
2975 [('r', 'rev', '', _('show parents from the specified rev')),
2976 ('', 'style', '', _('display using template map file')),
2976 ('', 'style', '', _('display using template map file')),
2977 ('', 'template', '', _('display with template'))],
2977 ('', 'template', '', _('display with template'))],
2978 _('hg parents [-r REV] [FILE]')),
2978 _('hg parents [-r REV] [FILE]')),
2979 "paths": (paths, [], _('hg paths [NAME]')),
2979 "paths": (paths, [], _('hg paths [NAME]')),
2980 "^pull":
2980 "^pull":
2981 (pull,
2981 (pull,
2982 [('u', 'update', None,
2982 [('u', 'update', None,
2983 _('update to new tip if changesets were pulled')),
2983 _('update to new tip if changesets were pulled')),
2984 ('f', 'force', None,
2984 ('f', 'force', None,
2985 _('run even when remote repository is unrelated')),
2985 _('run even when remote repository is unrelated')),
2986 ('r', 'rev', [],
2986 ('r', 'rev', [],
2987 _('a specific revision up to which you would like to pull')),
2987 _('a specific revision up to which you would like to pull')),
2988 ] + remoteopts,
2988 ] + remoteopts,
2989 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2989 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2990 "^push":
2990 "^push":
2991 (push,
2991 (push,
2992 [('f', 'force', None, _('force push')),
2992 [('f', 'force', None, _('force push')),
2993 ('r', 'rev', [], _('a specific revision you would like to push')),
2993 ('r', 'rev', [], _('a specific revision you would like to push')),
2994 ] + remoteopts,
2994 ] + remoteopts,
2995 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2995 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2996 "recover": (recover, [], _('hg recover')),
2996 "recover": (recover, [], _('hg recover')),
2997 "^remove|rm":
2997 "^remove|rm":
2998 (remove,
2998 (remove,
2999 [('A', 'after', None, _('record remove without deleting')),
2999 [('A', 'after', None, _('record remove without deleting')),
3000 ('f', 'force', None, _('remove file even if modified')),
3000 ('f', 'force', None, _('remove file even if modified')),
3001 ] + walkopts,
3001 ] + walkopts,
3002 _('hg remove [OPTION]... FILE...')),
3002 _('hg remove [OPTION]... FILE...')),
3003 "rename|mv":
3003 "rename|mv":
3004 (rename,
3004 (rename,
3005 [('A', 'after', None, _('record a rename that has already occurred')),
3005 [('A', 'after', None, _('record a rename that has already occurred')),
3006 ('f', 'force', None,
3006 ('f', 'force', None,
3007 _('forcibly copy over an existing managed file')),
3007 _('forcibly copy over an existing managed file')),
3008 ] + walkopts + dryrunopts,
3008 ] + walkopts + dryrunopts,
3009 _('hg rename [OPTION]... SOURCE... DEST')),
3009 _('hg rename [OPTION]... SOURCE... DEST')),
3010 "revert":
3010 "revert":
3011 (revert,
3011 (revert,
3012 [('a', 'all', None, _('revert all changes when no arguments given')),
3012 [('a', 'all', None, _('revert all changes when no arguments given')),
3013 ('d', 'date', '', _('tipmost revision matching date')),
3013 ('d', 'date', '', _('tipmost revision matching date')),
3014 ('r', 'rev', '', _('revision to revert to')),
3014 ('r', 'rev', '', _('revision to revert to')),
3015 ('', 'no-backup', None, _('do not save backup copies of files')),
3015 ('', 'no-backup', None, _('do not save backup copies of files')),
3016 ] + walkopts + dryrunopts,
3016 ] + walkopts + dryrunopts,
3017 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3017 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3018 "rollback": (rollback, [], _('hg rollback')),
3018 "rollback": (rollback, [], _('hg rollback')),
3019 "root": (root, [], _('hg root')),
3019 "root": (root, [], _('hg root')),
3020 "^serve":
3020 "^serve":
3021 (serve,
3021 (serve,
3022 [('A', 'accesslog', '', _('name of access log file to write to')),
3022 [('A', 'accesslog', '', _('name of access log file to write to')),
3023 ('d', 'daemon', None, _('run server in background')),
3023 ('d', 'daemon', None, _('run server in background')),
3024 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3024 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3025 ('E', 'errorlog', '', _('name of error log file to write to')),
3025 ('E', 'errorlog', '', _('name of error log file to write to')),
3026 ('p', 'port', 0, _('port to use (default: 8000)')),
3026 ('p', 'port', 0, _('port to use (default: 8000)')),
3027 ('a', 'address', '', _('address to use')),
3027 ('a', 'address', '', _('address to use')),
3028 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3028 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3029 ('n', 'name', '',
3029 ('n', 'name', '',
3030 _('name to show in web pages (default: working dir)')),
3030 _('name to show in web pages (default: working dir)')),
3031 ('', 'webdir-conf', '', _('name of the webdir config file'
3031 ('', 'webdir-conf', '', _('name of the webdir config file'
3032 ' (serve more than one repo)')),
3032 ' (serve more than one repo)')),
3033 ('', 'pid-file', '', _('name of file to write process ID to')),
3033 ('', 'pid-file', '', _('name of file to write process ID to')),
3034 ('', 'stdio', None, _('for remote clients')),
3034 ('', 'stdio', None, _('for remote clients')),
3035 ('t', 'templates', '', _('web templates to use')),
3035 ('t', 'templates', '', _('web templates to use')),
3036 ('', 'style', '', _('template style to use')),
3036 ('', 'style', '', _('template style to use')),
3037 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3037 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3038 ('', 'certificate', '', _('SSL certificate file'))],
3038 ('', 'certificate', '', _('SSL certificate file'))],
3039 _('hg serve [OPTION]...')),
3039 _('hg serve [OPTION]...')),
3040 "showconfig|debugconfig":
3040 "showconfig|debugconfig":
3041 (showconfig,
3041 (showconfig,
3042 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3042 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3043 _('hg showconfig [-u] [NAME]...')),
3043 _('hg showconfig [-u] [NAME]...')),
3044 "^status|st":
3044 "^status|st":
3045 (status,
3045 (status,
3046 [('A', 'all', None, _('show status of all files')),
3046 [('A', 'all', None, _('show status of all files')),
3047 ('m', 'modified', None, _('show only modified files')),
3047 ('m', 'modified', None, _('show only modified files')),
3048 ('a', 'added', None, _('show only added files')),
3048 ('a', 'added', None, _('show only added files')),
3049 ('r', 'removed', None, _('show only removed files')),
3049 ('r', 'removed', None, _('show only removed files')),
3050 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3050 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3051 ('c', 'clean', None, _('show only files without changes')),
3051 ('c', 'clean', None, _('show only files without changes')),
3052 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3052 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3053 ('i', 'ignored', None, _('show only ignored files')),
3053 ('i', 'ignored', None, _('show only ignored files')),
3054 ('n', 'no-status', None, _('hide status prefix')),
3054 ('n', 'no-status', None, _('hide status prefix')),
3055 ('C', 'copies', None, _('show source of copied files')),
3055 ('C', 'copies', None, _('show source of copied files')),
3056 ('0', 'print0', None,
3056 ('0', 'print0', None,
3057 _('end filenames with NUL, for use with xargs')),
3057 _('end filenames with NUL, for use with xargs')),
3058 ('', 'rev', [], _('show difference from revision')),
3058 ('', 'rev', [], _('show difference from revision')),
3059 ] + walkopts,
3059 ] + walkopts,
3060 _('hg status [OPTION]... [FILE]...')),
3060 _('hg status [OPTION]... [FILE]...')),
3061 "tag":
3061 "tag":
3062 (tag,
3062 (tag,
3063 [('f', 'force', None, _('replace existing tag')),
3063 [('f', 'force', None, _('replace existing tag')),
3064 ('l', 'local', None, _('make the tag local')),
3064 ('l', 'local', None, _('make the tag local')),
3065 ('r', 'rev', '', _('revision to tag')),
3065 ('r', 'rev', '', _('revision to tag')),
3066 ('', 'remove', None, _('remove a tag')),
3066 ('', 'remove', None, _('remove a tag')),
3067 # -l/--local is already there, commitopts cannot be used
3067 # -l/--local is already there, commitopts cannot be used
3068 ('m', 'message', '', _('use <text> as commit message')),
3068 ('m', 'message', '', _('use <text> as commit message')),
3069 ] + commitopts2,
3069 ] + commitopts2,
3070 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3070 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3071 "tags": (tags, [], _('hg tags')),
3071 "tags": (tags, [], _('hg tags')),
3072 "tip":
3072 "tip":
3073 (tip,
3073 (tip,
3074 [('', 'style', '', _('display using template map file')),
3074 [('', 'style', '', _('display using template map file')),
3075 ('p', 'patch', None, _('show patch')),
3075 ('p', 'patch', None, _('show patch')),
3076 ('', 'template', '', _('display with template'))],
3076 ('', 'template', '', _('display with template'))],
3077 _('hg tip [-p]')),
3077 _('hg tip [-p]')),
3078 "unbundle":
3078 "unbundle":
3079 (unbundle,
3079 (unbundle,
3080 [('u', 'update', None,
3080 [('u', 'update', None,
3081 _('update to new tip if changesets were unbundled'))],
3081 _('update to new tip if changesets were unbundled'))],
3082 _('hg unbundle [-u] FILE...')),
3082 _('hg unbundle [-u] FILE...')),
3083 "^update|up|checkout|co":
3083 "^update|up|checkout|co":
3084 (update,
3084 (update,
3085 [('C', 'clean', None, _('overwrite locally modified files')),
3085 [('C', 'clean', None, _('overwrite locally modified files')),
3086 ('d', 'date', '', _('tipmost revision matching date')),
3086 ('d', 'date', '', _('tipmost revision matching date')),
3087 ('r', 'rev', '', _('revision'))],
3087 ('r', 'rev', '', _('revision'))],
3088 _('hg update [-C] [-d DATE] [[-r] REV]')),
3088 _('hg update [-C] [-d DATE] [[-r] REV]')),
3089 "verify": (verify, [], _('hg verify')),
3089 "verify": (verify, [], _('hg verify')),
3090 "version": (version_, [], _('hg version')),
3090 "version": (version_, [], _('hg version')),
3091 }
3091 }
3092
3092
3093 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3093 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3094 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3094 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3095 optionalrepo = ("identify paths serve showconfig")
3095 optionalrepo = ("identify paths serve showconfig")
@@ -1,33 +1,33 b''
1 adding a
1 adding a
2 # missing arg
2 # missing arg
3 hg cat: invalid arguments
3 hg cat: invalid arguments
4 hg cat [OPTION]... FILE...
4 hg cat [OPTION]... FILE...
5
5
6 output the current or given revision of files
6 output the current or given revision of files
7
7
8 Print the specified files as they were at the given revision.
8 Print the specified files as they were at the given revision.
9 If no revision is given, the parent of the working directory is used,
9 If no revision is given, the parent of the working directory is used,
10 or tip if no revision is checked out.
10 or tip if no revision is checked out.
11
11
12 Output may be to a file, in which case the name of the file is
12 Output may be to a file, in which case the name of the file is
13 given using a format string. The formatting rules are the same as
13 given using a format string. The formatting rules are the same as
14 for the export command, with the following additions:
14 for the export command, with the following additions:
15
15
16 %s basename of file being printed
16 %s basename of file being printed
17 %d dirname of file being printed, or '.' if in repo root
17 %d dirname of file being printed, or '.' if in repo root
18 %p root-relative path name of file being printed
18 %p root-relative path name of file being printed
19
19
20 options:
20 options:
21
21
22 -o --output print output to file with formatted name
22 -o --output print output to file with formatted name
23 -r --rev print the given revision
23 -r --rev print the given revision
24 -d --decode apply any matching decode filter
24 --decode apply any matching decode filter
25 -I --include include names matching the given patterns
25 -I --include include names matching the given patterns
26 -X --exclude exclude names matching the given patterns
26 -X --exclude exclude names matching the given patterns
27
27
28 use "hg -v help cat" to show global options
28 use "hg -v help cat" to show global options
29 % [defaults]
29 % [defaults]
30 a
30 a
31 a
31 a
32 % no repo
32 % no repo
33 abort: There is no Mercurial repository here (.hg not found)!
33 abort: There is no Mercurial repository here (.hg not found)!
@@ -1,42 +1,42 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 hg init
3 hg init
4
4
5 cat > .hg/hgrc <<EOF
5 cat > .hg/hgrc <<EOF
6 [encode]
6 [encode]
7 *.gz = gunzip
7 *.gz = gunzip
8
8
9 [decode]
9 [decode]
10 *.gz = gzip
10 *.gz = gzip
11
11
12 EOF
12 EOF
13
13
14 echo "this is a test" | gzip > a.gz
14 echo "this is a test" | gzip > a.gz
15 hg add a.gz
15 hg add a.gz
16 hg ci -m "test" -d "1000000 0"
16 hg ci -m "test" -d "1000000 0"
17 echo %% no changes
17 echo %% no changes
18 hg status
18 hg status
19 touch a.gz
19 touch a.gz
20
20
21 echo %% no changes
21 echo %% no changes
22 hg status
22 hg status
23
23
24 echo %% uncompressed contents in repo
24 echo %% uncompressed contents in repo
25 hg debugdata .hg/store/data/a.gz.d 0
25 hg debugdata .hg/store/data/a.gz.d 0
26
26
27 echo %% uncompress our working dir copy
27 echo %% uncompress our working dir copy
28 gunzip < a.gz
28 gunzip < a.gz
29
29
30 rm a.gz
30 rm a.gz
31 hg co
31 hg co
32
32
33 echo %% uncompress our new working dir copy
33 echo %% uncompress our new working dir copy
34 gunzip < a.gz
34 gunzip < a.gz
35
35
36 echo %% check hg cat operation
36 echo %% check hg cat operation
37 hg cat a.gz
37 hg cat a.gz
38 hg cat -d a.gz | gunzip
38 hg cat --decode a.gz | gunzip
39 mkdir subdir
39 mkdir subdir
40 cd subdir
40 cd subdir
41 hg -R .. cat ../a.gz
41 hg -R .. cat ../a.gz
42 hg -R .. cat -d ../a.gz | gunzip
42 hg -R .. cat --decode ../a.gz | gunzip
General Comments 0
You need to be logged in to leave comments. Login now