##// END OF EJS Templates
commands.revert: don't call hg.revert...
Alexis S. L. Carvalho -
r6107:41bb88cb default
parent child Browse files
Show More
@@ -1,3098 +1,3112 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import os, re, sys, urllib
10 import os, re, sys, urllib
11 import hg, util, revlog, bundlerepo, extensions
11 import hg, util, revlog, bundlerepo, extensions
12 import difflib, patch, time, help, mdiff, tempfile
12 import difflib, patch, time, help, mdiff, tempfile
13 import errno, version, socket
13 import errno, version, socket
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
14 import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect
15
15
16 # Commands start here, listed alphabetically
16 # Commands start here, listed alphabetically
17
17
18 def add(ui, repo, *pats, **opts):
18 def add(ui, repo, *pats, **opts):
19 """add the specified files on the next commit
19 """add the specified files on the next commit
20
20
21 Schedule files to be version controlled and added to the repository.
21 Schedule files to be version controlled and added to the repository.
22
22
23 The files will be added to the repository at the next commit. To
23 The files will be added to the repository at the next commit. To
24 undo an add before that, see hg revert.
24 undo an add before that, see hg revert.
25
25
26 If no names are given, add all files in the repository.
26 If no names are given, add all files in the repository.
27 """
27 """
28
28
29 rejected = None
29 rejected = None
30 exacts = {}
30 exacts = {}
31 names = []
31 names = []
32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
32 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
33 badmatch=util.always):
33 badmatch=util.always):
34 if exact:
34 if exact:
35 if ui.verbose:
35 if ui.verbose:
36 ui.status(_('adding %s\n') % rel)
36 ui.status(_('adding %s\n') % rel)
37 names.append(abs)
37 names.append(abs)
38 exacts[abs] = 1
38 exacts[abs] = 1
39 elif abs not in repo.dirstate:
39 elif abs not in repo.dirstate:
40 ui.status(_('adding %s\n') % rel)
40 ui.status(_('adding %s\n') % rel)
41 names.append(abs)
41 names.append(abs)
42 if not opts.get('dry_run'):
42 if not opts.get('dry_run'):
43 rejected = repo.add(names)
43 rejected = repo.add(names)
44 rejected = [p for p in rejected if p in exacts]
44 rejected = [p for p in rejected if p in exacts]
45 return rejected and 1 or 0
45 return rejected and 1 or 0
46
46
47 def addremove(ui, repo, *pats, **opts):
47 def addremove(ui, repo, *pats, **opts):
48 """add all new files, delete all missing files
48 """add all new files, delete all missing files
49
49
50 Add all new files and remove all missing files from the repository.
50 Add all new files and remove all missing files from the repository.
51
51
52 New files are ignored if they match any of the patterns in .hgignore. As
52 New files are ignored if they match any of the patterns in .hgignore. As
53 with add, these changes take effect at the next commit.
53 with add, these changes take effect at the next commit.
54
54
55 Use the -s option to detect renamed files. With a parameter > 0,
55 Use the -s option to detect renamed files. With a parameter > 0,
56 this compares every removed file with every added file and records
56 this compares every removed file with every added file and records
57 those similar enough as renames. This option takes a percentage
57 those similar enough as renames. This option takes a percentage
58 between 0 (disabled) and 100 (files must be identical) as its
58 between 0 (disabled) and 100 (files must be identical) as its
59 parameter. Detecting renamed files this way can be expensive.
59 parameter. Detecting renamed files this way can be expensive.
60 """
60 """
61 try:
61 try:
62 sim = float(opts.get('similarity') or 0)
62 sim = float(opts.get('similarity') or 0)
63 except ValueError:
63 except ValueError:
64 raise util.Abort(_('similarity must be a number'))
64 raise util.Abort(_('similarity must be a number'))
65 if sim < 0 or sim > 100:
65 if sim < 0 or sim > 100:
66 raise util.Abort(_('similarity must be between 0 and 100'))
66 raise util.Abort(_('similarity must be between 0 and 100'))
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
67 return cmdutil.addremove(repo, pats, opts, similarity=sim/100.)
68
68
69 def annotate(ui, repo, *pats, **opts):
69 def annotate(ui, repo, *pats, **opts):
70 """show changeset information per file line
70 """show changeset information per file line
71
71
72 List changes in files, showing the revision id responsible for each line
72 List changes in files, showing the revision id responsible for each line
73
73
74 This command is useful to discover who did a change or when a change took
74 This command is useful to discover who did a change or when a change took
75 place.
75 place.
76
76
77 Without the -a option, annotate will avoid processing files it
77 Without the -a option, annotate will avoid processing files it
78 detects as binary. With -a, annotate will generate an annotation
78 detects as binary. With -a, annotate will generate an annotation
79 anyway, probably with undesirable results.
79 anyway, probably with undesirable results.
80 """
80 """
81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
81 getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
82
82
83 if not pats:
83 if not pats:
84 raise util.Abort(_('at least one file name or pattern required'))
84 raise util.Abort(_('at least one file name or pattern required'))
85
85
86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
86 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
87 ('number', lambda x: str(x[0].rev())),
87 ('number', lambda x: str(x[0].rev())),
88 ('changeset', lambda x: short(x[0].node())),
88 ('changeset', lambda x: short(x[0].node())),
89 ('date', getdate),
89 ('date', getdate),
90 ('follow', lambda x: x[0].path()),
90 ('follow', lambda x: x[0].path()),
91 ]
91 ]
92
92
93 if (not opts['user'] and not opts['changeset'] and not opts['date']
93 if (not opts['user'] and not opts['changeset'] and not opts['date']
94 and not opts['follow']):
94 and not opts['follow']):
95 opts['number'] = 1
95 opts['number'] = 1
96
96
97 linenumber = opts.get('line_number') is not None
97 linenumber = opts.get('line_number') is not None
98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
98 if (linenumber and (not opts['changeset']) and (not opts['number'])):
99 raise util.Abort(_('at least one of -n/-c is required for -l'))
99 raise util.Abort(_('at least one of -n/-c is required for -l'))
100
100
101 funcmap = [func for op, func in opmap if opts.get(op)]
101 funcmap = [func for op, func in opmap if opts.get(op)]
102 if linenumber:
102 if linenumber:
103 lastfunc = funcmap[-1]
103 lastfunc = funcmap[-1]
104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
104 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
105
105
106 ctx = repo.changectx(opts['rev'])
106 ctx = repo.changectx(opts['rev'])
107
107
108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
108 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
109 node=ctx.node()):
109 node=ctx.node()):
110 fctx = ctx.filectx(abs)
110 fctx = ctx.filectx(abs)
111 if not opts['text'] and util.binary(fctx.data()):
111 if not opts['text'] and util.binary(fctx.data()):
112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
112 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
113 continue
113 continue
114
114
115 lines = fctx.annotate(follow=opts.get('follow'),
115 lines = fctx.annotate(follow=opts.get('follow'),
116 linenumber=linenumber)
116 linenumber=linenumber)
117 pieces = []
117 pieces = []
118
118
119 for f in funcmap:
119 for f in funcmap:
120 l = [f(n) for n, dummy in lines]
120 l = [f(n) for n, dummy in lines]
121 if l:
121 if l:
122 m = max(map(len, l))
122 m = max(map(len, l))
123 pieces.append(["%*s" % (m, x) for x in l])
123 pieces.append(["%*s" % (m, x) for x in l])
124
124
125 if pieces:
125 if pieces:
126 for p, l in zip(zip(*pieces), lines):
126 for p, l in zip(zip(*pieces), lines):
127 ui.write("%s: %s" % (" ".join(p), l[1]))
127 ui.write("%s: %s" % (" ".join(p), l[1]))
128
128
129 def archive(ui, repo, dest, **opts):
129 def archive(ui, repo, dest, **opts):
130 '''create unversioned archive of a repository revision
130 '''create unversioned archive of a repository revision
131
131
132 By default, the revision used is the parent of the working
132 By default, the revision used is the parent of the working
133 directory; use "-r" to specify a different revision.
133 directory; use "-r" to specify a different revision.
134
134
135 To specify the type of archive to create, use "-t". Valid
135 To specify the type of archive to create, use "-t". Valid
136 types are:
136 types are:
137
137
138 "files" (default): a directory full of files
138 "files" (default): a directory full of files
139 "tar": tar archive, uncompressed
139 "tar": tar archive, uncompressed
140 "tbz2": tar archive, compressed using bzip2
140 "tbz2": tar archive, compressed using bzip2
141 "tgz": tar archive, compressed using gzip
141 "tgz": tar archive, compressed using gzip
142 "uzip": zip archive, uncompressed
142 "uzip": zip archive, uncompressed
143 "zip": zip archive, compressed using deflate
143 "zip": zip archive, compressed using deflate
144
144
145 The exact name of the destination archive or directory is given
145 The exact name of the destination archive or directory is given
146 using a format string; see "hg help export" for details.
146 using a format string; see "hg help export" for details.
147
147
148 Each member added to an archive file has a directory prefix
148 Each member added to an archive file has a directory prefix
149 prepended. Use "-p" to specify a format string for the prefix.
149 prepended. Use "-p" to specify a format string for the prefix.
150 The default is the basename of the archive, with suffixes removed.
150 The default is the basename of the archive, with suffixes removed.
151 '''
151 '''
152
152
153 ctx = repo.changectx(opts['rev'])
153 ctx = repo.changectx(opts['rev'])
154 if not ctx:
154 if not ctx:
155 raise util.Abort(_('repository has no revisions'))
155 raise util.Abort(_('repository has no revisions'))
156 node = ctx.node()
156 node = ctx.node()
157 dest = cmdutil.make_filename(repo, dest, node)
157 dest = cmdutil.make_filename(repo, dest, node)
158 if os.path.realpath(dest) == repo.root:
158 if os.path.realpath(dest) == repo.root:
159 raise util.Abort(_('repository root cannot be destination'))
159 raise util.Abort(_('repository root cannot be destination'))
160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
160 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
161 kind = opts.get('type') or 'files'
161 kind = opts.get('type') or 'files'
162 prefix = opts['prefix']
162 prefix = opts['prefix']
163 if dest == '-':
163 if dest == '-':
164 if kind == 'files':
164 if kind == 'files':
165 raise util.Abort(_('cannot archive plain files to stdout'))
165 raise util.Abort(_('cannot archive plain files to stdout'))
166 dest = sys.stdout
166 dest = sys.stdout
167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
167 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
168 prefix = cmdutil.make_filename(repo, prefix, node)
168 prefix = cmdutil.make_filename(repo, prefix, node)
169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
169 archival.archive(repo, dest, node, kind, not opts['no_decode'],
170 matchfn, prefix)
170 matchfn, prefix)
171
171
172 def backout(ui, repo, node=None, rev=None, **opts):
172 def backout(ui, repo, node=None, rev=None, **opts):
173 '''reverse effect of earlier changeset
173 '''reverse effect of earlier changeset
174
174
175 Commit the backed out changes as a new changeset. The new
175 Commit the backed out changes as a new changeset. The new
176 changeset is a child of the backed out changeset.
176 changeset is a child of the backed out changeset.
177
177
178 If you back out a changeset other than the tip, a new head is
178 If you back out a changeset other than the tip, a new head is
179 created. This head is the parent of the working directory. If
179 created. This head is the parent of the working directory. If
180 you back out an old changeset, your working directory will appear
180 you back out an old changeset, your working directory will appear
181 old after the backout. You should merge the backout changeset
181 old after the backout. You should merge the backout changeset
182 with another head.
182 with another head.
183
183
184 The --merge option remembers the parent of the working directory
184 The --merge option remembers the parent of the working directory
185 before starting the backout, then merges the new head with that
185 before starting the backout, then merges the new head with that
186 changeset afterwards. This saves you from doing the merge by
186 changeset afterwards. This saves you from doing the merge by
187 hand. The result of this merge is not committed, as for a normal
187 hand. The result of this merge is not committed, as for a normal
188 merge.'''
188 merge.'''
189 if rev and node:
189 if rev and node:
190 raise util.Abort(_("please specify just one revision"))
190 raise util.Abort(_("please specify just one revision"))
191
191
192 if not rev:
192 if not rev:
193 rev = node
193 rev = node
194
194
195 if not rev:
195 if not rev:
196 raise util.Abort(_("please specify a revision to backout"))
196 raise util.Abort(_("please specify a revision to backout"))
197
197
198 cmdutil.bail_if_changed(repo)
198 cmdutil.bail_if_changed(repo)
199 node = repo.lookup(rev)
199 node = repo.lookup(rev)
200
200
201 op1, op2 = repo.dirstate.parents()
201 op1, op2 = repo.dirstate.parents()
202 a = repo.changelog.ancestor(op1, node)
202 a = repo.changelog.ancestor(op1, node)
203 if a != node:
203 if a != node:
204 raise util.Abort(_('cannot back out change on a different branch'))
204 raise util.Abort(_('cannot back out change on a different branch'))
205
205
206 p1, p2 = repo.changelog.parents(node)
206 p1, p2 = repo.changelog.parents(node)
207 if p1 == nullid:
207 if p1 == nullid:
208 raise util.Abort(_('cannot back out a change with no parents'))
208 raise util.Abort(_('cannot back out a change with no parents'))
209 if p2 != nullid:
209 if p2 != nullid:
210 if not opts['parent']:
210 if not opts['parent']:
211 raise util.Abort(_('cannot back out a merge changeset without '
211 raise util.Abort(_('cannot back out a merge changeset without '
212 '--parent'))
212 '--parent'))
213 p = repo.lookup(opts['parent'])
213 p = repo.lookup(opts['parent'])
214 if p not in (p1, p2):
214 if p not in (p1, p2):
215 raise util.Abort(_('%s is not a parent of %s') %
215 raise util.Abort(_('%s is not a parent of %s') %
216 (short(p), short(node)))
216 (short(p), short(node)))
217 parent = p
217 parent = p
218 else:
218 else:
219 if opts['parent']:
219 if opts['parent']:
220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
220 raise util.Abort(_('cannot use --parent on non-merge changeset'))
221 parent = p1
221 parent = p1
222
222
223 hg.clean(repo, node, show_stats=False)
223 hg.clean(repo, node, show_stats=False)
224 revert_opts = opts.copy()
224 revert_opts = opts.copy()
225 revert_opts['date'] = None
225 revert_opts['date'] = None
226 revert_opts['all'] = True
226 revert_opts['all'] = True
227 revert_opts['rev'] = hex(parent)
227 revert_opts['rev'] = hex(parent)
228 revert_opts['no_backup'] = None
228 revert_opts['no_backup'] = None
229 revert(ui, repo, **revert_opts)
229 revert(ui, repo, **revert_opts)
230 commit_opts = opts.copy()
230 commit_opts = opts.copy()
231 commit_opts['addremove'] = False
231 commit_opts['addremove'] = False
232 if not commit_opts['message'] and not commit_opts['logfile']:
232 if not commit_opts['message'] and not commit_opts['logfile']:
233 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
233 commit_opts['message'] = _("Backed out changeset %s") % (short(node))
234 commit_opts['force_editor'] = True
234 commit_opts['force_editor'] = True
235 commit(ui, repo, **commit_opts)
235 commit(ui, repo, **commit_opts)
236 def nice(node):
236 def nice(node):
237 return '%d:%s' % (repo.changelog.rev(node), short(node))
237 return '%d:%s' % (repo.changelog.rev(node), short(node))
238 ui.status(_('changeset %s backs out changeset %s\n') %
238 ui.status(_('changeset %s backs out changeset %s\n') %
239 (nice(repo.changelog.tip()), nice(node)))
239 (nice(repo.changelog.tip()), nice(node)))
240 if op1 != node:
240 if op1 != node:
241 if opts['merge']:
241 if opts['merge']:
242 ui.status(_('merging with changeset %s\n') % nice(op1))
242 ui.status(_('merging with changeset %s\n') % nice(op1))
243 hg.merge(repo, hex(op1))
243 hg.merge(repo, hex(op1))
244 else:
244 else:
245 ui.status(_('the backout changeset is a new head - '
245 ui.status(_('the backout changeset is a new head - '
246 'do not forget to merge\n'))
246 'do not forget to merge\n'))
247 ui.status(_('(use "backout --merge" '
247 ui.status(_('(use "backout --merge" '
248 'if you want to auto-merge)\n'))
248 'if you want to auto-merge)\n'))
249
249
250 def bisect(ui, repo, rev=None, extra=None,
250 def bisect(ui, repo, rev=None, extra=None,
251 reset=None, good=None, bad=None, skip=None, noupdate=None):
251 reset=None, good=None, bad=None, skip=None, noupdate=None):
252 """subdivision search of changesets
252 """subdivision search of changesets
253
253
254 This command helps to find changesets which introduce problems.
254 This command helps to find changesets which introduce problems.
255 To use, mark the earliest changeset you know exhibits the problem
255 To use, mark the earliest changeset you know exhibits the problem
256 as bad, then mark the latest changeset which is free from the
256 as bad, then mark the latest changeset which is free from the
257 problem as good. Bisect will update your working directory to a
257 problem as good. Bisect will update your working directory to a
258 revision for testing. Once you have performed tests, mark the
258 revision for testing. Once you have performed tests, mark the
259 working directory as bad or good and bisect will either update to
259 working directory as bad or good and bisect will either update to
260 another candidate changeset or announce that it has found the bad
260 another candidate changeset or announce that it has found the bad
261 revision.
261 revision.
262 """
262 """
263 # backward compatibility
263 # backward compatibility
264 if rev in "good bad reset init".split():
264 if rev in "good bad reset init".split():
265 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
265 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
266 cmd, rev, extra = rev, extra, None
266 cmd, rev, extra = rev, extra, None
267 if cmd == "good":
267 if cmd == "good":
268 good = True
268 good = True
269 elif cmd == "bad":
269 elif cmd == "bad":
270 bad = True
270 bad = True
271 else:
271 else:
272 reset = True
272 reset = True
273 elif extra or good + bad + skip + reset > 1:
273 elif extra or good + bad + skip + reset > 1:
274 raise util.Abort("Incompatible arguments")
274 raise util.Abort("Incompatible arguments")
275
275
276 if reset:
276 if reset:
277 p = repo.join("bisect.state")
277 p = repo.join("bisect.state")
278 if os.path.exists(p):
278 if os.path.exists(p):
279 os.unlink(p)
279 os.unlink(p)
280 return
280 return
281
281
282 # load state
282 # load state
283 state = {'good': [], 'bad': [], 'skip': []}
283 state = {'good': [], 'bad': [], 'skip': []}
284 if os.path.exists(repo.join("bisect.state")):
284 if os.path.exists(repo.join("bisect.state")):
285 for l in repo.opener("bisect.state"):
285 for l in repo.opener("bisect.state"):
286 kind, node = l[:-1].split()
286 kind, node = l[:-1].split()
287 node = repo.lookup(node)
287 node = repo.lookup(node)
288 if kind not in state:
288 if kind not in state:
289 raise util.Abort(_("unknown bisect kind %s") % kind)
289 raise util.Abort(_("unknown bisect kind %s") % kind)
290 state[kind].append(node)
290 state[kind].append(node)
291
291
292 # update state
292 # update state
293 node = repo.lookup(rev or '.')
293 node = repo.lookup(rev or '.')
294 if good:
294 if good:
295 state['good'].append(node)
295 state['good'].append(node)
296 elif bad:
296 elif bad:
297 state['bad'].append(node)
297 state['bad'].append(node)
298 elif skip:
298 elif skip:
299 state['skip'].append(node)
299 state['skip'].append(node)
300
300
301 # save state
301 # save state
302 f = repo.opener("bisect.state", "w", atomictemp=True)
302 f = repo.opener("bisect.state", "w", atomictemp=True)
303 wlock = repo.wlock()
303 wlock = repo.wlock()
304 try:
304 try:
305 for kind in state:
305 for kind in state:
306 for node in state[kind]:
306 for node in state[kind]:
307 f.write("%s %s\n" % (kind, hg.hex(node)))
307 f.write("%s %s\n" % (kind, hg.hex(node)))
308 f.rename()
308 f.rename()
309 finally:
309 finally:
310 del wlock
310 del wlock
311
311
312 if not state['good'] or not state['bad']:
312 if not state['good'] or not state['bad']:
313 return
313 return
314
314
315 # actually bisect
315 # actually bisect
316 node, changesets, good = hbisect.bisect(repo.changelog, state)
316 node, changesets, good = hbisect.bisect(repo.changelog, state)
317 if changesets == 0:
317 if changesets == 0:
318 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
318 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
319 displayer = cmdutil.show_changeset(ui, repo, {})
319 displayer = cmdutil.show_changeset(ui, repo, {})
320 displayer.show(changenode=node)
320 displayer.show(changenode=node)
321 elif node is not None:
321 elif node is not None:
322 # compute the approximate number of remaining tests
322 # compute the approximate number of remaining tests
323 tests, size = 0, 2
323 tests, size = 0, 2
324 while size <= changesets:
324 while size <= changesets:
325 tests, size = tests + 1, size * 2
325 tests, size = tests + 1, size * 2
326 rev = repo.changelog.rev(node)
326 rev = repo.changelog.rev(node)
327 ui.write(_("Testing changeset %s:%s "
327 ui.write(_("Testing changeset %s:%s "
328 "(%s changesets remaining, ~%s tests)\n")
328 "(%s changesets remaining, ~%s tests)\n")
329 % (rev, hg.short(node), changesets, tests))
329 % (rev, hg.short(node), changesets, tests))
330 if not noupdate:
330 if not noupdate:
331 cmdutil.bail_if_changed(repo)
331 cmdutil.bail_if_changed(repo)
332 return hg.clean(repo, node)
332 return hg.clean(repo, node)
333
333
334 def branch(ui, repo, label=None, **opts):
334 def branch(ui, repo, label=None, **opts):
335 """set or show the current branch name
335 """set or show the current branch name
336
336
337 With no argument, show the current branch name. With one argument,
337 With no argument, show the current branch name. With one argument,
338 set the working directory branch name (the branch does not exist in
338 set the working directory branch name (the branch does not exist in
339 the repository until the next commit).
339 the repository until the next commit).
340
340
341 Unless --force is specified, branch will not let you set a
341 Unless --force is specified, branch will not let you set a
342 branch name that shadows an existing branch.
342 branch name that shadows an existing branch.
343
343
344 Use the command 'hg update' to switch to an existing branch.
344 Use the command 'hg update' to switch to an existing branch.
345 """
345 """
346
346
347 if label:
347 if label:
348 if not opts.get('force') and label in repo.branchtags():
348 if not opts.get('force') and label in repo.branchtags():
349 if label not in [p.branch() for p in repo.workingctx().parents()]:
349 if label not in [p.branch() for p in repo.workingctx().parents()]:
350 raise util.Abort(_('a branch of the same name already exists'
350 raise util.Abort(_('a branch of the same name already exists'
351 ' (use --force to override)'))
351 ' (use --force to override)'))
352 repo.dirstate.setbranch(util.fromlocal(label))
352 repo.dirstate.setbranch(util.fromlocal(label))
353 ui.status(_('marked working directory as branch %s\n') % label)
353 ui.status(_('marked working directory as branch %s\n') % label)
354 else:
354 else:
355 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
355 ui.write("%s\n" % util.tolocal(repo.dirstate.branch()))
356
356
357 def branches(ui, repo, active=False):
357 def branches(ui, repo, active=False):
358 """list repository named branches
358 """list repository named branches
359
359
360 List the repository's named branches, indicating which ones are
360 List the repository's named branches, indicating which ones are
361 inactive. If active is specified, only show active branches.
361 inactive. If active is specified, only show active branches.
362
362
363 A branch is considered active if it contains unmerged heads.
363 A branch is considered active if it contains unmerged heads.
364
364
365 Use the command 'hg update' to switch to an existing branch.
365 Use the command 'hg update' to switch to an existing branch.
366 """
366 """
367 b = repo.branchtags()
367 b = repo.branchtags()
368 heads = dict.fromkeys(repo.heads(), 1)
368 heads = dict.fromkeys(repo.heads(), 1)
369 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
369 l = [((n in heads), repo.changelog.rev(n), n, t) for t, n in b.items()]
370 l.sort()
370 l.sort()
371 l.reverse()
371 l.reverse()
372 for ishead, r, n, t in l:
372 for ishead, r, n, t in l:
373 if active and not ishead:
373 if active and not ishead:
374 # If we're only displaying active branches, abort the loop on
374 # If we're only displaying active branches, abort the loop on
375 # encountering the first inactive head
375 # encountering the first inactive head
376 break
376 break
377 else:
377 else:
378 hexfunc = ui.debugflag and hex or short
378 hexfunc = ui.debugflag and hex or short
379 if ui.quiet:
379 if ui.quiet:
380 ui.write("%s\n" % t)
380 ui.write("%s\n" % t)
381 else:
381 else:
382 spaces = " " * (30 - util.locallen(t))
382 spaces = " " * (30 - util.locallen(t))
383 # The code only gets here if inactive branches are being
383 # The code only gets here if inactive branches are being
384 # displayed or the branch is active.
384 # displayed or the branch is active.
385 isinactive = ((not ishead) and " (inactive)") or ''
385 isinactive = ((not ishead) and " (inactive)") or ''
386 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
386 ui.write("%s%s %s:%s%s\n" % (t, spaces, r, hexfunc(n), isinactive))
387
387
388 def bundle(ui, repo, fname, dest=None, **opts):
388 def bundle(ui, repo, fname, dest=None, **opts):
389 """create a changegroup file
389 """create a changegroup file
390
390
391 Generate a compressed changegroup file collecting changesets not
391 Generate a compressed changegroup file collecting changesets not
392 found in the other repository.
392 found in the other repository.
393
393
394 If no destination repository is specified the destination is assumed
394 If no destination repository is specified the destination is assumed
395 to have all the nodes specified by one or more --base parameters.
395 to have all the nodes specified by one or more --base parameters.
396 To create a bundle containing all changesets, use --base null.
396 To create a bundle containing all changesets, use --base null.
397
397
398 The bundle file can then be transferred using conventional means and
398 The bundle file can then be transferred using conventional means and
399 applied to another repository with the unbundle or pull command.
399 applied to another repository with the unbundle or pull command.
400 This is useful when direct push and pull are not available or when
400 This is useful when direct push and pull are not available or when
401 exporting an entire repository is undesirable.
401 exporting an entire repository is undesirable.
402
402
403 Applying bundles preserves all changeset contents including
403 Applying bundles preserves all changeset contents including
404 permissions, copy/rename information, and revision history.
404 permissions, copy/rename information, and revision history.
405 """
405 """
406 revs = opts.get('rev') or None
406 revs = opts.get('rev') or None
407 if revs:
407 if revs:
408 revs = [repo.lookup(rev) for rev in revs]
408 revs = [repo.lookup(rev) for rev in revs]
409 base = opts.get('base')
409 base = opts.get('base')
410 if base:
410 if base:
411 if dest:
411 if dest:
412 raise util.Abort(_("--base is incompatible with specifiying "
412 raise util.Abort(_("--base is incompatible with specifiying "
413 "a destination"))
413 "a destination"))
414 base = [repo.lookup(rev) for rev in base]
414 base = [repo.lookup(rev) for rev in base]
415 # create the right base
415 # create the right base
416 # XXX: nodesbetween / changegroup* should be "fixed" instead
416 # XXX: nodesbetween / changegroup* should be "fixed" instead
417 o = []
417 o = []
418 has = {nullid: None}
418 has = {nullid: None}
419 for n in base:
419 for n in base:
420 has.update(repo.changelog.reachable(n))
420 has.update(repo.changelog.reachable(n))
421 if revs:
421 if revs:
422 visit = list(revs)
422 visit = list(revs)
423 else:
423 else:
424 visit = repo.changelog.heads()
424 visit = repo.changelog.heads()
425 seen = {}
425 seen = {}
426 while visit:
426 while visit:
427 n = visit.pop(0)
427 n = visit.pop(0)
428 parents = [p for p in repo.changelog.parents(n) if p not in has]
428 parents = [p for p in repo.changelog.parents(n) if p not in has]
429 if len(parents) == 0:
429 if len(parents) == 0:
430 o.insert(0, n)
430 o.insert(0, n)
431 else:
431 else:
432 for p in parents:
432 for p in parents:
433 if p not in seen:
433 if p not in seen:
434 seen[p] = 1
434 seen[p] = 1
435 visit.append(p)
435 visit.append(p)
436 else:
436 else:
437 cmdutil.setremoteconfig(ui, opts)
437 cmdutil.setremoteconfig(ui, opts)
438 dest, revs, checkout = hg.parseurl(
438 dest, revs, checkout = hg.parseurl(
439 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
439 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
440 other = hg.repository(ui, dest)
440 other = hg.repository(ui, dest)
441 o = repo.findoutgoing(other, force=opts['force'])
441 o = repo.findoutgoing(other, force=opts['force'])
442
442
443 if revs:
443 if revs:
444 cg = repo.changegroupsubset(o, revs, 'bundle')
444 cg = repo.changegroupsubset(o, revs, 'bundle')
445 else:
445 else:
446 cg = repo.changegroup(o, 'bundle')
446 cg = repo.changegroup(o, 'bundle')
447 changegroup.writebundle(cg, fname, "HG10BZ")
447 changegroup.writebundle(cg, fname, "HG10BZ")
448
448
449 def cat(ui, repo, file1, *pats, **opts):
449 def cat(ui, repo, file1, *pats, **opts):
450 """output the current or given revision of files
450 """output the current or given revision of files
451
451
452 Print the specified files as they were at the given revision.
452 Print the specified files as they were at the given revision.
453 If no revision is given, the parent of the working directory is used,
453 If no revision is given, the parent of the working directory is used,
454 or tip if no revision is checked out.
454 or tip if no revision is checked out.
455
455
456 Output may be to a file, in which case the name of the file is
456 Output may be to a file, in which case the name of the file is
457 given using a format string. The formatting rules are the same as
457 given using a format string. The formatting rules are the same as
458 for the export command, with the following additions:
458 for the export command, with the following additions:
459
459
460 %s basename of file being printed
460 %s basename of file being printed
461 %d dirname of file being printed, or '.' if in repo root
461 %d dirname of file being printed, or '.' if in repo root
462 %p root-relative path name of file being printed
462 %p root-relative path name of file being printed
463 """
463 """
464 ctx = repo.changectx(opts['rev'])
464 ctx = repo.changectx(opts['rev'])
465 err = 1
465 err = 1
466 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
466 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
467 ctx.node()):
467 ctx.node()):
468 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
468 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
469 data = ctx.filectx(abs).data()
469 data = ctx.filectx(abs).data()
470 if opts.get('decode'):
470 if opts.get('decode'):
471 data = repo.wwritedata(abs, data)
471 data = repo.wwritedata(abs, data)
472 fp.write(data)
472 fp.write(data)
473 err = 0
473 err = 0
474 return err
474 return err
475
475
476 def clone(ui, source, dest=None, **opts):
476 def clone(ui, source, dest=None, **opts):
477 """make a copy of an existing repository
477 """make a copy of an existing repository
478
478
479 Create a copy of an existing repository in a new directory.
479 Create a copy of an existing repository in a new directory.
480
480
481 If no destination directory name is specified, it defaults to the
481 If no destination directory name is specified, it defaults to the
482 basename of the source.
482 basename of the source.
483
483
484 The location of the source is added to the new repository's
484 The location of the source is added to the new repository's
485 .hg/hgrc file, as the default to be used for future pulls.
485 .hg/hgrc file, as the default to be used for future pulls.
486
486
487 For efficiency, hardlinks are used for cloning whenever the source
487 For efficiency, hardlinks are used for cloning whenever the source
488 and destination are on the same filesystem (note this applies only
488 and destination are on the same filesystem (note this applies only
489 to the repository data, not to the checked out files). Some
489 to the repository data, not to the checked out files). Some
490 filesystems, such as AFS, implement hardlinking incorrectly, but
490 filesystems, such as AFS, implement hardlinking incorrectly, but
491 do not report errors. In these cases, use the --pull option to
491 do not report errors. In these cases, use the --pull option to
492 avoid hardlinking.
492 avoid hardlinking.
493
493
494 You can safely clone repositories and checked out files using full
494 You can safely clone repositories and checked out files using full
495 hardlinks with
495 hardlinks with
496
496
497 $ cp -al REPO REPOCLONE
497 $ cp -al REPO REPOCLONE
498
498
499 which is the fastest way to clone. However, the operation is not
499 which is the fastest way to clone. However, the operation is not
500 atomic (making sure REPO is not modified during the operation is
500 atomic (making sure REPO is not modified during the operation is
501 up to you) and you have to make sure your editor breaks hardlinks
501 up to you) and you have to make sure your editor breaks hardlinks
502 (Emacs and most Linux Kernel tools do so).
502 (Emacs and most Linux Kernel tools do so).
503
503
504 If you use the -r option to clone up to a specific revision, no
504 If you use the -r option to clone up to a specific revision, no
505 subsequent revisions will be present in the cloned repository.
505 subsequent revisions will be present in the cloned repository.
506 This option implies --pull, even on local repositories.
506 This option implies --pull, even on local repositories.
507
507
508 See pull for valid source format details.
508 See pull for valid source format details.
509
509
510 It is possible to specify an ssh:// URL as the destination, but no
510 It is possible to specify an ssh:// URL as the destination, but no
511 .hg/hgrc and working directory will be created on the remote side.
511 .hg/hgrc and working directory will be created on the remote side.
512 Look at the help text for the pull command for important details
512 Look at the help text for the pull command for important details
513 about ssh:// URLs.
513 about ssh:// URLs.
514 """
514 """
515 cmdutil.setremoteconfig(ui, opts)
515 cmdutil.setremoteconfig(ui, opts)
516 hg.clone(ui, source, dest,
516 hg.clone(ui, source, dest,
517 pull=opts['pull'],
517 pull=opts['pull'],
518 stream=opts['uncompressed'],
518 stream=opts['uncompressed'],
519 rev=opts['rev'],
519 rev=opts['rev'],
520 update=not opts['noupdate'])
520 update=not opts['noupdate'])
521
521
522 def commit(ui, repo, *pats, **opts):
522 def commit(ui, repo, *pats, **opts):
523 """commit the specified files or all outstanding changes
523 """commit the specified files or all outstanding changes
524
524
525 Commit changes to the given files into the repository.
525 Commit changes to the given files into the repository.
526
526
527 If a list of files is omitted, all changes reported by "hg status"
527 If a list of files is omitted, all changes reported by "hg status"
528 will be committed.
528 will be committed.
529
529
530 If no commit message is specified, the configured editor is started to
530 If no commit message is specified, the configured editor is started to
531 enter a message.
531 enter a message.
532 """
532 """
533 def commitfunc(ui, repo, files, message, match, opts):
533 def commitfunc(ui, repo, files, message, match, opts):
534 return repo.commit(files, message, opts['user'], opts['date'], match,
534 return repo.commit(files, message, opts['user'], opts['date'], match,
535 force_editor=opts.get('force_editor'))
535 force_editor=opts.get('force_editor'))
536 cmdutil.commit(ui, repo, commitfunc, pats, opts)
536 cmdutil.commit(ui, repo, commitfunc, pats, opts)
537
537
538 def copy(ui, repo, *pats, **opts):
538 def copy(ui, repo, *pats, **opts):
539 """mark files as copied for the next commit
539 """mark files as copied for the next commit
540
540
541 Mark dest as having copies of source files. If dest is a
541 Mark dest as having copies of source files. If dest is a
542 directory, copies are put in that directory. If dest is a file,
542 directory, copies are put in that directory. If dest is a file,
543 there can only be one source.
543 there can only be one source.
544
544
545 By default, this command copies the contents of files as they
545 By default, this command copies the contents of files as they
546 stand in the working directory. If invoked with --after, the
546 stand in the working directory. If invoked with --after, the
547 operation is recorded, but no copying is performed.
547 operation is recorded, but no copying is performed.
548
548
549 This command takes effect in the next commit. To undo a copy
549 This command takes effect in the next commit. To undo a copy
550 before that, see hg revert.
550 before that, see hg revert.
551 """
551 """
552 wlock = repo.wlock(False)
552 wlock = repo.wlock(False)
553 try:
553 try:
554 return cmdutil.copy(ui, repo, pats, opts)
554 return cmdutil.copy(ui, repo, pats, opts)
555 finally:
555 finally:
556 del wlock
556 del wlock
557
557
558 def debugancestor(ui, index, rev1, rev2):
558 def debugancestor(ui, index, rev1, rev2):
559 """find the ancestor revision of two revisions in a given index"""
559 """find the ancestor revision of two revisions in a given index"""
560 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
560 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
561 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
561 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
562 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
562 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
563
563
564 def debugcomplete(ui, cmd='', **opts):
564 def debugcomplete(ui, cmd='', **opts):
565 """returns the completion list associated with the given command"""
565 """returns the completion list associated with the given command"""
566
566
567 if opts['options']:
567 if opts['options']:
568 options = []
568 options = []
569 otables = [globalopts]
569 otables = [globalopts]
570 if cmd:
570 if cmd:
571 aliases, entry = cmdutil.findcmd(ui, cmd, table)
571 aliases, entry = cmdutil.findcmd(ui, cmd, table)
572 otables.append(entry[1])
572 otables.append(entry[1])
573 for t in otables:
573 for t in otables:
574 for o in t:
574 for o in t:
575 if o[0]:
575 if o[0]:
576 options.append('-%s' % o[0])
576 options.append('-%s' % o[0])
577 options.append('--%s' % o[1])
577 options.append('--%s' % o[1])
578 ui.write("%s\n" % "\n".join(options))
578 ui.write("%s\n" % "\n".join(options))
579 return
579 return
580
580
581 clist = cmdutil.findpossible(ui, cmd, table).keys()
581 clist = cmdutil.findpossible(ui, cmd, table).keys()
582 clist.sort()
582 clist.sort()
583 ui.write("%s\n" % "\n".join(clist))
583 ui.write("%s\n" % "\n".join(clist))
584
584
585 def debugfsinfo(ui, path = "."):
585 def debugfsinfo(ui, path = "."):
586 file('.debugfsinfo', 'w').write('')
586 file('.debugfsinfo', 'w').write('')
587 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
587 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
588 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
588 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
589 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
589 ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
590 and 'yes' or 'no'))
590 and 'yes' or 'no'))
591 os.unlink('.debugfsinfo')
591 os.unlink('.debugfsinfo')
592
592
593 def debugrebuildstate(ui, repo, rev=""):
593 def debugrebuildstate(ui, repo, rev=""):
594 """rebuild the dirstate as it would look like for the given revision"""
594 """rebuild the dirstate as it would look like for the given revision"""
595 if rev == "":
595 if rev == "":
596 rev = repo.changelog.tip()
596 rev = repo.changelog.tip()
597 ctx = repo.changectx(rev)
597 ctx = repo.changectx(rev)
598 files = ctx.manifest()
598 files = ctx.manifest()
599 wlock = repo.wlock()
599 wlock = repo.wlock()
600 try:
600 try:
601 repo.dirstate.rebuild(rev, files)
601 repo.dirstate.rebuild(rev, files)
602 finally:
602 finally:
603 del wlock
603 del wlock
604
604
605 def debugcheckstate(ui, repo):
605 def debugcheckstate(ui, repo):
606 """validate the correctness of the current dirstate"""
606 """validate the correctness of the current dirstate"""
607 parent1, parent2 = repo.dirstate.parents()
607 parent1, parent2 = repo.dirstate.parents()
608 m1 = repo.changectx(parent1).manifest()
608 m1 = repo.changectx(parent1).manifest()
609 m2 = repo.changectx(parent2).manifest()
609 m2 = repo.changectx(parent2).manifest()
610 errors = 0
610 errors = 0
611 for f in repo.dirstate:
611 for f in repo.dirstate:
612 state = repo.dirstate[f]
612 state = repo.dirstate[f]
613 if state in "nr" and f not in m1:
613 if state in "nr" and f not in m1:
614 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
614 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
615 errors += 1
615 errors += 1
616 if state in "a" and f in m1:
616 if state in "a" and f in m1:
617 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
617 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
618 errors += 1
618 errors += 1
619 if state in "m" and f not in m1 and f not in m2:
619 if state in "m" and f not in m1 and f not in m2:
620 ui.warn(_("%s in state %s, but not in either manifest\n") %
620 ui.warn(_("%s in state %s, but not in either manifest\n") %
621 (f, state))
621 (f, state))
622 errors += 1
622 errors += 1
623 for f in m1:
623 for f in m1:
624 state = repo.dirstate[f]
624 state = repo.dirstate[f]
625 if state not in "nrm":
625 if state not in "nrm":
626 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
626 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
627 errors += 1
627 errors += 1
628 if errors:
628 if errors:
629 error = _(".hg/dirstate inconsistent with current parent's manifest")
629 error = _(".hg/dirstate inconsistent with current parent's manifest")
630 raise util.Abort(error)
630 raise util.Abort(error)
631
631
632 def showconfig(ui, repo, *values, **opts):
632 def showconfig(ui, repo, *values, **opts):
633 """show combined config settings from all hgrc files
633 """show combined config settings from all hgrc files
634
634
635 With no args, print names and values of all config items.
635 With no args, print names and values of all config items.
636
636
637 With one arg of the form section.name, print just the value of
637 With one arg of the form section.name, print just the value of
638 that config item.
638 that config item.
639
639
640 With multiple args, print names and values of all config items
640 With multiple args, print names and values of all config items
641 with matching section names."""
641 with matching section names."""
642
642
643 untrusted = bool(opts.get('untrusted'))
643 untrusted = bool(opts.get('untrusted'))
644 if values:
644 if values:
645 if len([v for v in values if '.' in v]) > 1:
645 if len([v for v in values if '.' in v]) > 1:
646 raise util.Abort(_('only one config item permitted'))
646 raise util.Abort(_('only one config item permitted'))
647 for section, name, value in ui.walkconfig(untrusted=untrusted):
647 for section, name, value in ui.walkconfig(untrusted=untrusted):
648 sectname = section + '.' + name
648 sectname = section + '.' + name
649 if values:
649 if values:
650 for v in values:
650 for v in values:
651 if v == section:
651 if v == section:
652 ui.write('%s=%s\n' % (sectname, value))
652 ui.write('%s=%s\n' % (sectname, value))
653 elif v == sectname:
653 elif v == sectname:
654 ui.write(value, '\n')
654 ui.write(value, '\n')
655 else:
655 else:
656 ui.write('%s=%s\n' % (sectname, value))
656 ui.write('%s=%s\n' % (sectname, value))
657
657
658 def debugsetparents(ui, repo, rev1, rev2=None):
658 def debugsetparents(ui, repo, rev1, rev2=None):
659 """manually set the parents of the current working directory
659 """manually set the parents of the current working directory
660
660
661 This is useful for writing repository conversion tools, but should
661 This is useful for writing repository conversion tools, but should
662 be used with care.
662 be used with care.
663 """
663 """
664
664
665 if not rev2:
665 if not rev2:
666 rev2 = hex(nullid)
666 rev2 = hex(nullid)
667
667
668 wlock = repo.wlock()
668 wlock = repo.wlock()
669 try:
669 try:
670 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
670 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
671 finally:
671 finally:
672 del wlock
672 del wlock
673
673
674 def debugstate(ui, repo):
674 def debugstate(ui, repo):
675 """show the contents of the current dirstate"""
675 """show the contents of the current dirstate"""
676 k = repo.dirstate._map.items()
676 k = repo.dirstate._map.items()
677 k.sort()
677 k.sort()
678 for file_, ent in k:
678 for file_, ent in k:
679 if ent[3] == -1:
679 if ent[3] == -1:
680 # Pad or slice to locale representation
680 # Pad or slice to locale representation
681 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
681 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(0)))
682 timestr = 'unset'
682 timestr = 'unset'
683 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
683 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
684 else:
684 else:
685 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
685 timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ent[3]))
686 if ent[1] & 020000:
686 if ent[1] & 020000:
687 mode = 'lnk'
687 mode = 'lnk'
688 else:
688 else:
689 mode = '%3o' % (ent[1] & 0777)
689 mode = '%3o' % (ent[1] & 0777)
690 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
690 ui.write("%c %s %10d %s %s\n" % (ent[0], mode, ent[2], timestr, file_))
691 for f in repo.dirstate.copies():
691 for f in repo.dirstate.copies():
692 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
692 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
693
693
694 def debugdata(ui, file_, rev):
694 def debugdata(ui, file_, rev):
695 """dump the contents of a data file revision"""
695 """dump the contents of a data file revision"""
696 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
696 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
697 try:
697 try:
698 ui.write(r.revision(r.lookup(rev)))
698 ui.write(r.revision(r.lookup(rev)))
699 except KeyError:
699 except KeyError:
700 raise util.Abort(_('invalid revision identifier %s') % rev)
700 raise util.Abort(_('invalid revision identifier %s') % rev)
701
701
702 def debugdate(ui, date, range=None, **opts):
702 def debugdate(ui, date, range=None, **opts):
703 """parse and display a date"""
703 """parse and display a date"""
704 if opts["extended"]:
704 if opts["extended"]:
705 d = util.parsedate(date, util.extendeddateformats)
705 d = util.parsedate(date, util.extendeddateformats)
706 else:
706 else:
707 d = util.parsedate(date)
707 d = util.parsedate(date)
708 ui.write("internal: %s %s\n" % d)
708 ui.write("internal: %s %s\n" % d)
709 ui.write("standard: %s\n" % util.datestr(d))
709 ui.write("standard: %s\n" % util.datestr(d))
710 if range:
710 if range:
711 m = util.matchdate(range)
711 m = util.matchdate(range)
712 ui.write("match: %s\n" % m(d[0]))
712 ui.write("match: %s\n" % m(d[0]))
713
713
714 def debugindex(ui, file_):
714 def debugindex(ui, file_):
715 """dump the contents of an index file"""
715 """dump the contents of an index file"""
716 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
716 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
717 ui.write(" rev offset length base linkrev" +
717 ui.write(" rev offset length base linkrev" +
718 " nodeid p1 p2\n")
718 " nodeid p1 p2\n")
719 for i in xrange(r.count()):
719 for i in xrange(r.count()):
720 node = r.node(i)
720 node = r.node(i)
721 try:
721 try:
722 pp = r.parents(node)
722 pp = r.parents(node)
723 except:
723 except:
724 pp = [nullid, nullid]
724 pp = [nullid, nullid]
725 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
725 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
726 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
726 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
727 short(node), short(pp[0]), short(pp[1])))
727 short(node), short(pp[0]), short(pp[1])))
728
728
729 def debugindexdot(ui, file_):
729 def debugindexdot(ui, file_):
730 """dump an index DAG as a .dot file"""
730 """dump an index DAG as a .dot file"""
731 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
731 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
732 ui.write("digraph G {\n")
732 ui.write("digraph G {\n")
733 for i in xrange(r.count()):
733 for i in xrange(r.count()):
734 node = r.node(i)
734 node = r.node(i)
735 pp = r.parents(node)
735 pp = r.parents(node)
736 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
736 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
737 if pp[1] != nullid:
737 if pp[1] != nullid:
738 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
738 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
739 ui.write("}\n")
739 ui.write("}\n")
740
740
741 def debuginstall(ui):
741 def debuginstall(ui):
742 '''test Mercurial installation'''
742 '''test Mercurial installation'''
743
743
744 def writetemp(contents):
744 def writetemp(contents):
745 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
745 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
746 f = os.fdopen(fd, "wb")
746 f = os.fdopen(fd, "wb")
747 f.write(contents)
747 f.write(contents)
748 f.close()
748 f.close()
749 return name
749 return name
750
750
751 problems = 0
751 problems = 0
752
752
753 # encoding
753 # encoding
754 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
754 ui.status(_("Checking encoding (%s)...\n") % util._encoding)
755 try:
755 try:
756 util.fromlocal("test")
756 util.fromlocal("test")
757 except util.Abort, inst:
757 except util.Abort, inst:
758 ui.write(" %s\n" % inst)
758 ui.write(" %s\n" % inst)
759 ui.write(_(" (check that your locale is properly set)\n"))
759 ui.write(_(" (check that your locale is properly set)\n"))
760 problems += 1
760 problems += 1
761
761
762 # compiled modules
762 # compiled modules
763 ui.status(_("Checking extensions...\n"))
763 ui.status(_("Checking extensions...\n"))
764 try:
764 try:
765 import bdiff, mpatch, base85
765 import bdiff, mpatch, base85
766 except Exception, inst:
766 except Exception, inst:
767 ui.write(" %s\n" % inst)
767 ui.write(" %s\n" % inst)
768 ui.write(_(" One or more extensions could not be found"))
768 ui.write(_(" One or more extensions could not be found"))
769 ui.write(_(" (check that you compiled the extensions)\n"))
769 ui.write(_(" (check that you compiled the extensions)\n"))
770 problems += 1
770 problems += 1
771
771
772 # templates
772 # templates
773 ui.status(_("Checking templates...\n"))
773 ui.status(_("Checking templates...\n"))
774 try:
774 try:
775 import templater
775 import templater
776 t = templater.templater(templater.templatepath("map-cmdline.default"))
776 t = templater.templater(templater.templatepath("map-cmdline.default"))
777 except Exception, inst:
777 except Exception, inst:
778 ui.write(" %s\n" % inst)
778 ui.write(" %s\n" % inst)
779 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
779 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
780 problems += 1
780 problems += 1
781
781
782 # patch
782 # patch
783 ui.status(_("Checking patch...\n"))
783 ui.status(_("Checking patch...\n"))
784 patchproblems = 0
784 patchproblems = 0
785 a = "1\n2\n3\n4\n"
785 a = "1\n2\n3\n4\n"
786 b = "1\n2\n3\ninsert\n4\n"
786 b = "1\n2\n3\ninsert\n4\n"
787 fa = writetemp(a)
787 fa = writetemp(a)
788 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
788 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
789 os.path.basename(fa))
789 os.path.basename(fa))
790 fd = writetemp(d)
790 fd = writetemp(d)
791
791
792 files = {}
792 files = {}
793 try:
793 try:
794 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
794 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
795 except util.Abort, e:
795 except util.Abort, e:
796 ui.write(_(" patch call failed:\n"))
796 ui.write(_(" patch call failed:\n"))
797 ui.write(" " + str(e) + "\n")
797 ui.write(" " + str(e) + "\n")
798 patchproblems += 1
798 patchproblems += 1
799 else:
799 else:
800 if list(files) != [os.path.basename(fa)]:
800 if list(files) != [os.path.basename(fa)]:
801 ui.write(_(" unexpected patch output!\n"))
801 ui.write(_(" unexpected patch output!\n"))
802 patchproblems += 1
802 patchproblems += 1
803 a = file(fa).read()
803 a = file(fa).read()
804 if a != b:
804 if a != b:
805 ui.write(_(" patch test failed!\n"))
805 ui.write(_(" patch test failed!\n"))
806 patchproblems += 1
806 patchproblems += 1
807
807
808 if patchproblems:
808 if patchproblems:
809 if ui.config('ui', 'patch'):
809 if ui.config('ui', 'patch'):
810 ui.write(_(" (Current patch tool may be incompatible with patch,"
810 ui.write(_(" (Current patch tool may be incompatible with patch,"
811 " or misconfigured. Please check your .hgrc file)\n"))
811 " or misconfigured. Please check your .hgrc file)\n"))
812 else:
812 else:
813 ui.write(_(" Internal patcher failure, please report this error"
813 ui.write(_(" Internal patcher failure, please report this error"
814 " to http://www.selenic.com/mercurial/bts\n"))
814 " to http://www.selenic.com/mercurial/bts\n"))
815 problems += patchproblems
815 problems += patchproblems
816
816
817 os.unlink(fa)
817 os.unlink(fa)
818 os.unlink(fd)
818 os.unlink(fd)
819
819
820 # editor
820 # editor
821 ui.status(_("Checking commit editor...\n"))
821 ui.status(_("Checking commit editor...\n"))
822 editor = ui.geteditor()
822 editor = ui.geteditor()
823 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
823 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
824 if not cmdpath:
824 if not cmdpath:
825 if editor == 'vi':
825 if editor == 'vi':
826 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
826 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
827 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
827 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
828 else:
828 else:
829 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
829 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
830 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
830 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
831 problems += 1
831 problems += 1
832
832
833 # check username
833 # check username
834 ui.status(_("Checking username...\n"))
834 ui.status(_("Checking username...\n"))
835 user = os.environ.get("HGUSER")
835 user = os.environ.get("HGUSER")
836 if user is None:
836 if user is None:
837 user = ui.config("ui", "username")
837 user = ui.config("ui", "username")
838 if user is None:
838 if user is None:
839 user = os.environ.get("EMAIL")
839 user = os.environ.get("EMAIL")
840 if not user:
840 if not user:
841 ui.warn(" ")
841 ui.warn(" ")
842 ui.username()
842 ui.username()
843 ui.write(_(" (specify a username in your .hgrc file)\n"))
843 ui.write(_(" (specify a username in your .hgrc file)\n"))
844
844
845 if not problems:
845 if not problems:
846 ui.status(_("No problems detected\n"))
846 ui.status(_("No problems detected\n"))
847 else:
847 else:
848 ui.write(_("%s problems detected,"
848 ui.write(_("%s problems detected,"
849 " please check your install!\n") % problems)
849 " please check your install!\n") % problems)
850
850
851 return problems
851 return problems
852
852
853 def debugrename(ui, repo, file1, *pats, **opts):
853 def debugrename(ui, repo, file1, *pats, **opts):
854 """dump rename information"""
854 """dump rename information"""
855
855
856 ctx = repo.changectx(opts.get('rev', 'tip'))
856 ctx = repo.changectx(opts.get('rev', 'tip'))
857 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
857 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
858 ctx.node()):
858 ctx.node()):
859 fctx = ctx.filectx(abs)
859 fctx = ctx.filectx(abs)
860 m = fctx.filelog().renamed(fctx.filenode())
860 m = fctx.filelog().renamed(fctx.filenode())
861 if m:
861 if m:
862 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
862 ui.write(_("%s renamed from %s:%s\n") % (rel, m[0], hex(m[1])))
863 else:
863 else:
864 ui.write(_("%s not renamed\n") % rel)
864 ui.write(_("%s not renamed\n") % rel)
865
865
866 def debugwalk(ui, repo, *pats, **opts):
866 def debugwalk(ui, repo, *pats, **opts):
867 """show how files match on given patterns"""
867 """show how files match on given patterns"""
868 items = list(cmdutil.walk(repo, pats, opts))
868 items = list(cmdutil.walk(repo, pats, opts))
869 if not items:
869 if not items:
870 return
870 return
871 fmt = '%%s %%-%ds %%-%ds %%s' % (
871 fmt = '%%s %%-%ds %%-%ds %%s' % (
872 max([len(abs) for (src, abs, rel, exact) in items]),
872 max([len(abs) for (src, abs, rel, exact) in items]),
873 max([len(rel) for (src, abs, rel, exact) in items]))
873 max([len(rel) for (src, abs, rel, exact) in items]))
874 for src, abs, rel, exact in items:
874 for src, abs, rel, exact in items:
875 line = fmt % (src, abs, rel, exact and 'exact' or '')
875 line = fmt % (src, abs, rel, exact and 'exact' or '')
876 ui.write("%s\n" % line.rstrip())
876 ui.write("%s\n" % line.rstrip())
877
877
878 def diff(ui, repo, *pats, **opts):
878 def diff(ui, repo, *pats, **opts):
879 """diff repository (or selected files)
879 """diff repository (or selected files)
880
880
881 Show differences between revisions for the specified files.
881 Show differences between revisions for the specified files.
882
882
883 Differences between files are shown using the unified diff format.
883 Differences between files are shown using the unified diff format.
884
884
885 NOTE: diff may generate unexpected results for merges, as it will
885 NOTE: diff may generate unexpected results for merges, as it will
886 default to comparing against the working directory's first parent
886 default to comparing against the working directory's first parent
887 changeset if no revisions are specified.
887 changeset if no revisions are specified.
888
888
889 When two revision arguments are given, then changes are shown
889 When two revision arguments are given, then changes are shown
890 between those revisions. If only one revision is specified then
890 between those revisions. If only one revision is specified then
891 that revision is compared to the working directory, and, when no
891 that revision is compared to the working directory, and, when no
892 revisions are specified, the working directory files are compared
892 revisions are specified, the working directory files are compared
893 to its parent.
893 to its parent.
894
894
895 Without the -a option, diff will avoid generating diffs of files
895 Without the -a option, diff will avoid generating diffs of files
896 it detects as binary. With -a, diff will generate a diff anyway,
896 it detects as binary. With -a, diff will generate a diff anyway,
897 probably with undesirable results.
897 probably with undesirable results.
898 """
898 """
899 node1, node2 = cmdutil.revpair(repo, opts['rev'])
899 node1, node2 = cmdutil.revpair(repo, opts['rev'])
900
900
901 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
901 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
902
902
903 patch.diff(repo, node1, node2, fns, match=matchfn,
903 patch.diff(repo, node1, node2, fns, match=matchfn,
904 opts=patch.diffopts(ui, opts))
904 opts=patch.diffopts(ui, opts))
905
905
906 def export(ui, repo, *changesets, **opts):
906 def export(ui, repo, *changesets, **opts):
907 """dump the header and diffs for one or more changesets
907 """dump the header and diffs for one or more changesets
908
908
909 Print the changeset header and diffs for one or more revisions.
909 Print the changeset header and diffs for one or more revisions.
910
910
911 The information shown in the changeset header is: author,
911 The information shown in the changeset header is: author,
912 changeset hash, parent(s) and commit comment.
912 changeset hash, parent(s) and commit comment.
913
913
914 NOTE: export may generate unexpected diff output for merge changesets,
914 NOTE: export may generate unexpected diff output for merge changesets,
915 as it will compare the merge changeset against its first parent only.
915 as it will compare the merge changeset against its first parent only.
916
916
917 Output may be to a file, in which case the name of the file is
917 Output may be to a file, in which case the name of the file is
918 given using a format string. The formatting rules are as follows:
918 given using a format string. The formatting rules are as follows:
919
919
920 %% literal "%" character
920 %% literal "%" character
921 %H changeset hash (40 bytes of hexadecimal)
921 %H changeset hash (40 bytes of hexadecimal)
922 %N number of patches being generated
922 %N number of patches being generated
923 %R changeset revision number
923 %R changeset revision number
924 %b basename of the exporting repository
924 %b basename of the exporting repository
925 %h short-form changeset hash (12 bytes of hexadecimal)
925 %h short-form changeset hash (12 bytes of hexadecimal)
926 %n zero-padded sequence number, starting at 1
926 %n zero-padded sequence number, starting at 1
927 %r zero-padded changeset revision number
927 %r zero-padded changeset revision number
928
928
929 Without the -a option, export will avoid generating diffs of files
929 Without the -a option, export will avoid generating diffs of files
930 it detects as binary. With -a, export will generate a diff anyway,
930 it detects as binary. With -a, export will generate a diff anyway,
931 probably with undesirable results.
931 probably with undesirable results.
932
932
933 With the --switch-parent option, the diff will be against the second
933 With the --switch-parent option, the diff will be against the second
934 parent. It can be useful to review a merge.
934 parent. It can be useful to review a merge.
935 """
935 """
936 if not changesets:
936 if not changesets:
937 raise util.Abort(_("export requires at least one changeset"))
937 raise util.Abort(_("export requires at least one changeset"))
938 revs = cmdutil.revrange(repo, changesets)
938 revs = cmdutil.revrange(repo, changesets)
939 if len(revs) > 1:
939 if len(revs) > 1:
940 ui.note(_('exporting patches:\n'))
940 ui.note(_('exporting patches:\n'))
941 else:
941 else:
942 ui.note(_('exporting patch:\n'))
942 ui.note(_('exporting patch:\n'))
943 patch.export(repo, revs, template=opts['output'],
943 patch.export(repo, revs, template=opts['output'],
944 switch_parent=opts['switch_parent'],
944 switch_parent=opts['switch_parent'],
945 opts=patch.diffopts(ui, opts))
945 opts=patch.diffopts(ui, opts))
946
946
947 def grep(ui, repo, pattern, *pats, **opts):
947 def grep(ui, repo, pattern, *pats, **opts):
948 """search for a pattern in specified files and revisions
948 """search for a pattern in specified files and revisions
949
949
950 Search revisions of files for a regular expression.
950 Search revisions of files for a regular expression.
951
951
952 This command behaves differently than Unix grep. It only accepts
952 This command behaves differently than Unix grep. It only accepts
953 Python/Perl regexps. It searches repository history, not the
953 Python/Perl regexps. It searches repository history, not the
954 working directory. It always prints the revision number in which
954 working directory. It always prints the revision number in which
955 a match appears.
955 a match appears.
956
956
957 By default, grep only prints output for the first revision of a
957 By default, grep only prints output for the first revision of a
958 file in which it finds a match. To get it to print every revision
958 file in which it finds a match. To get it to print every revision
959 that contains a change in match status ("-" for a match that
959 that contains a change in match status ("-" for a match that
960 becomes a non-match, or "+" for a non-match that becomes a match),
960 becomes a non-match, or "+" for a non-match that becomes a match),
961 use the --all flag.
961 use the --all flag.
962 """
962 """
963 reflags = 0
963 reflags = 0
964 if opts['ignore_case']:
964 if opts['ignore_case']:
965 reflags |= re.I
965 reflags |= re.I
966 try:
966 try:
967 regexp = re.compile(pattern, reflags)
967 regexp = re.compile(pattern, reflags)
968 except Exception, inst:
968 except Exception, inst:
969 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
969 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
970 return None
970 return None
971 sep, eol = ':', '\n'
971 sep, eol = ':', '\n'
972 if opts['print0']:
972 if opts['print0']:
973 sep = eol = '\0'
973 sep = eol = '\0'
974
974
975 fcache = {}
975 fcache = {}
976 def getfile(fn):
976 def getfile(fn):
977 if fn not in fcache:
977 if fn not in fcache:
978 fcache[fn] = repo.file(fn)
978 fcache[fn] = repo.file(fn)
979 return fcache[fn]
979 return fcache[fn]
980
980
981 def matchlines(body):
981 def matchlines(body):
982 begin = 0
982 begin = 0
983 linenum = 0
983 linenum = 0
984 while True:
984 while True:
985 match = regexp.search(body, begin)
985 match = regexp.search(body, begin)
986 if not match:
986 if not match:
987 break
987 break
988 mstart, mend = match.span()
988 mstart, mend = match.span()
989 linenum += body.count('\n', begin, mstart) + 1
989 linenum += body.count('\n', begin, mstart) + 1
990 lstart = body.rfind('\n', begin, mstart) + 1 or begin
990 lstart = body.rfind('\n', begin, mstart) + 1 or begin
991 lend = body.find('\n', mend)
991 lend = body.find('\n', mend)
992 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
992 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
993 begin = lend + 1
993 begin = lend + 1
994
994
995 class linestate(object):
995 class linestate(object):
996 def __init__(self, line, linenum, colstart, colend):
996 def __init__(self, line, linenum, colstart, colend):
997 self.line = line
997 self.line = line
998 self.linenum = linenum
998 self.linenum = linenum
999 self.colstart = colstart
999 self.colstart = colstart
1000 self.colend = colend
1000 self.colend = colend
1001
1001
1002 def __eq__(self, other):
1002 def __eq__(self, other):
1003 return self.line == other.line
1003 return self.line == other.line
1004
1004
1005 matches = {}
1005 matches = {}
1006 copies = {}
1006 copies = {}
1007 def grepbody(fn, rev, body):
1007 def grepbody(fn, rev, body):
1008 matches[rev].setdefault(fn, [])
1008 matches[rev].setdefault(fn, [])
1009 m = matches[rev][fn]
1009 m = matches[rev][fn]
1010 for lnum, cstart, cend, line in matchlines(body):
1010 for lnum, cstart, cend, line in matchlines(body):
1011 s = linestate(line, lnum, cstart, cend)
1011 s = linestate(line, lnum, cstart, cend)
1012 m.append(s)
1012 m.append(s)
1013
1013
1014 def difflinestates(a, b):
1014 def difflinestates(a, b):
1015 sm = difflib.SequenceMatcher(None, a, b)
1015 sm = difflib.SequenceMatcher(None, a, b)
1016 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1016 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1017 if tag == 'insert':
1017 if tag == 'insert':
1018 for i in xrange(blo, bhi):
1018 for i in xrange(blo, bhi):
1019 yield ('+', b[i])
1019 yield ('+', b[i])
1020 elif tag == 'delete':
1020 elif tag == 'delete':
1021 for i in xrange(alo, ahi):
1021 for i in xrange(alo, ahi):
1022 yield ('-', a[i])
1022 yield ('-', a[i])
1023 elif tag == 'replace':
1023 elif tag == 'replace':
1024 for i in xrange(alo, ahi):
1024 for i in xrange(alo, ahi):
1025 yield ('-', a[i])
1025 yield ('-', a[i])
1026 for i in xrange(blo, bhi):
1026 for i in xrange(blo, bhi):
1027 yield ('+', b[i])
1027 yield ('+', b[i])
1028
1028
1029 prev = {}
1029 prev = {}
1030 def display(fn, rev, states, prevstates):
1030 def display(fn, rev, states, prevstates):
1031 found = False
1031 found = False
1032 filerevmatches = {}
1032 filerevmatches = {}
1033 r = prev.get(fn, -1)
1033 r = prev.get(fn, -1)
1034 if opts['all']:
1034 if opts['all']:
1035 iter = difflinestates(states, prevstates)
1035 iter = difflinestates(states, prevstates)
1036 else:
1036 else:
1037 iter = [('', l) for l in prevstates]
1037 iter = [('', l) for l in prevstates]
1038 for change, l in iter:
1038 for change, l in iter:
1039 cols = [fn, str(r)]
1039 cols = [fn, str(r)]
1040 if opts['line_number']:
1040 if opts['line_number']:
1041 cols.append(str(l.linenum))
1041 cols.append(str(l.linenum))
1042 if opts['all']:
1042 if opts['all']:
1043 cols.append(change)
1043 cols.append(change)
1044 if opts['user']:
1044 if opts['user']:
1045 cols.append(ui.shortuser(get(r)[1]))
1045 cols.append(ui.shortuser(get(r)[1]))
1046 if opts['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 files = []
2214 files = []
2215 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2215 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2216 badmatch=mf.has_key):
2216 badmatch=mf.has_key):
2217 names[abs] = (rel, exact)
2217 names[abs] = (rel, exact)
2218 if src != 'b':
2218 if src != 'b':
2219 files.append(abs)
2219 files.append(abs)
2220
2220
2221 # walk target manifest.
2221 # walk target manifest.
2222
2222
2223 def badmatch(path):
2223 def badmatch(path):
2224 if path in names:
2224 if path in names:
2225 return True
2225 return True
2226 path_ = path + '/'
2226 path_ = path + '/'
2227 for f in names:
2227 for f in names:
2228 if f.startswith(path_):
2228 if f.startswith(path_):
2229 return True
2229 return True
2230 return False
2230 return False
2231
2231
2232 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2232 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2233 badmatch=badmatch):
2233 badmatch=badmatch):
2234 if abs in names or src == 'b':
2234 if abs in names or src == 'b':
2235 continue
2235 continue
2236 names[abs] = (rel, exact)
2236 names[abs] = (rel, exact)
2237
2237
2238 changes = repo.status(files=files, match=names.has_key)[:4]
2238 changes = repo.status(files=files, match=names.has_key)[:4]
2239 modified, added, removed, deleted = map(dict.fromkeys, changes)
2239 modified, added, removed, deleted = map(dict.fromkeys, changes)
2240
2240
2241 # if f is a rename, also revert the source
2241 # if f is a rename, also revert the source
2242 cwd = repo.getcwd()
2242 cwd = repo.getcwd()
2243 for f in added:
2243 for f in added:
2244 src = repo.dirstate.copied(f)
2244 src = repo.dirstate.copied(f)
2245 if src and src not in names and repo.dirstate[src] == 'r':
2245 if src and src not in names and repo.dirstate[src] == 'r':
2246 removed[src] = None
2246 removed[src] = None
2247 names[src] = (repo.pathto(src, cwd), True)
2247 names[src] = (repo.pathto(src, cwd), True)
2248
2248
2249 revert = ([], _('reverting %s\n'))
2249 revert = ([], _('reverting %s\n'))
2250 add = ([], _('adding %s\n'))
2250 add = ([], _('adding %s\n'))
2251 remove = ([], _('removing %s\n'))
2251 remove = ([], _('removing %s\n'))
2252 forget = ([], _('forgetting %s\n'))
2252 forget = ([], _('forgetting %s\n'))
2253 undelete = ([], _('undeleting %s\n'))
2253 undelete = ([], _('undeleting %s\n'))
2254 update = {}
2255
2254
2256 disptable = (
2255 disptable = (
2257 # dispatch table:
2256 # dispatch table:
2258 # file state
2257 # file state
2259 # action if in target manifest
2258 # action if in target manifest
2260 # action if not in target manifest
2259 # action if not in target manifest
2261 # make backup if in target manifest
2260 # make backup if in target manifest
2262 # make backup if not in target manifest
2261 # make backup if not in target manifest
2263 (modified, revert, remove, True, True),
2262 (modified, revert, remove, True, True),
2264 (added, revert, forget, True, False),
2263 (added, revert, forget, True, False),
2265 (removed, undelete, None, False, False),
2264 (removed, undelete, None, False, False),
2266 (deleted, revert, remove, False, False),
2265 (deleted, revert, remove, False, False),
2267 )
2266 )
2268
2267
2269 entries = names.items()
2268 entries = names.items()
2270 entries.sort()
2269 entries.sort()
2271
2270
2272 for abs, (rel, exact) in entries:
2271 for abs, (rel, exact) in entries:
2273 mfentry = mf.get(abs)
2272 mfentry = mf.get(abs)
2274 target = repo.wjoin(abs)
2273 target = repo.wjoin(abs)
2275 def handle(xlist, dobackup):
2274 def handle(xlist, dobackup):
2276 xlist[0].append(abs)
2275 xlist[0].append(abs)
2277 update[abs] = 1
2278 if dobackup and not opts['no_backup'] and util.lexists(target):
2276 if dobackup and not opts['no_backup'] and util.lexists(target):
2279 bakname = "%s.orig" % rel
2277 bakname = "%s.orig" % rel
2280 ui.note(_('saving current version of %s as %s\n') %
2278 ui.note(_('saving current version of %s as %s\n') %
2281 (rel, bakname))
2279 (rel, bakname))
2282 if not opts.get('dry_run'):
2280 if not opts.get('dry_run'):
2283 util.copyfile(target, bakname)
2281 util.copyfile(target, bakname)
2284 if ui.verbose or not exact:
2282 if ui.verbose or not exact:
2285 ui.status(xlist[1] % rel)
2283 ui.status(xlist[1] % rel)
2286 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2284 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2287 if abs not in table: continue
2285 if abs not in table: continue
2288 # file has changed in dirstate
2286 # file has changed in dirstate
2289 if mfentry:
2287 if mfentry:
2290 handle(hitlist, backuphit)
2288 handle(hitlist, backuphit)
2291 elif misslist is not None:
2289 elif misslist is not None:
2292 handle(misslist, backupmiss)
2290 handle(misslist, backupmiss)
2293 break
2291 break
2294 else:
2292 else:
2295 if abs not in repo.dirstate:
2293 if abs not in repo.dirstate:
2296 if mfentry:
2294 if mfentry:
2297 handle(add, True)
2295 handle(add, True)
2298 elif exact:
2296 elif exact:
2299 ui.warn(_('file not managed: %s\n') % rel)
2297 ui.warn(_('file not managed: %s\n') % rel)
2300 continue
2298 continue
2301 # file has not changed in dirstate
2299 # file has not changed in dirstate
2302 if node == parent:
2300 if node == parent:
2303 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2301 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2304 continue
2302 continue
2305 if pmf is None:
2303 if pmf is None:
2306 # only need parent manifest in this unlikely case,
2304 # only need parent manifest in this unlikely case,
2307 # so do not read by default
2305 # so do not read by default
2308 pmf = repo.changectx(parent).manifest()
2306 pmf = repo.changectx(parent).manifest()
2309 if abs in pmf:
2307 if abs in pmf:
2310 if mfentry:
2308 if mfentry:
2311 # if version of file is same in parent and target
2309 # if version of file is same in parent and target
2312 # manifests, do nothing
2310 # manifests, do nothing
2313 if (pmf[abs] != mfentry or
2311 if (pmf[abs] != mfentry or
2314 pmf.flags(abs) != mf.flags(abs)):
2312 pmf.flags(abs) != mf.flags(abs)):
2315 handle(revert, False)
2313 handle(revert, False)
2316 else:
2314 else:
2317 handle(remove, False)
2315 handle(remove, False)
2318
2316
2319 if not opts.get('dry_run'):
2317 if not opts.get('dry_run'):
2318 def checkout(f):
2319 fc = ctx[f]
2320 repo.wwrite(f, fc.data(), fc.fileflags())
2321
2320 for f in forget[0]:
2322 for f in forget[0]:
2321 repo.dirstate.forget(f)
2323 repo.dirstate.forget(f)
2322 r = hg.revert(repo, node, update.has_key)
2324
2325 for f in revert[0]:
2326 checkout(f)
2327
2323 for f in add[0]:
2328 for f in add[0]:
2329 checkout(f)
2324 repo.dirstate.add(f)
2330 repo.dirstate.add(f)
2331
2325 for f in undelete[0]:
2332 for f in undelete[0]:
2333 checkout(f)
2326 repo.dirstate.normal(f)
2334 repo.dirstate.normal(f)
2335
2336 audit_path = util.path_auditor(repo.root)
2327 for f in remove[0]:
2337 for f in remove[0]:
2338 audit_path(f)
2339 try:
2340 util.unlink(repo.wjoin(f))
2341 except OSError:
2342 pass
2328 repo.dirstate.remove(f)
2343 repo.dirstate.remove(f)
2329 return r
2330 finally:
2344 finally:
2331 del wlock
2345 del wlock
2332
2346
2333 def rollback(ui, repo):
2347 def rollback(ui, repo):
2334 """roll back the last transaction
2348 """roll back the last transaction
2335
2349
2336 This command should be used with care. There is only one level of
2350 This command should be used with care. There is only one level of
2337 rollback, and there is no way to undo a rollback. It will also
2351 rollback, and there is no way to undo a rollback. It will also
2338 restore the dirstate at the time of the last transaction, losing
2352 restore the dirstate at the time of the last transaction, losing
2339 any dirstate changes since that time.
2353 any dirstate changes since that time.
2340
2354
2341 Transactions are used to encapsulate the effects of all commands
2355 Transactions are used to encapsulate the effects of all commands
2342 that create new changesets or propagate existing changesets into a
2356 that create new changesets or propagate existing changesets into a
2343 repository. For example, the following commands are transactional,
2357 repository. For example, the following commands are transactional,
2344 and their effects can be rolled back:
2358 and their effects can be rolled back:
2345
2359
2346 commit
2360 commit
2347 import
2361 import
2348 pull
2362 pull
2349 push (with this repository as destination)
2363 push (with this repository as destination)
2350 unbundle
2364 unbundle
2351
2365
2352 This command is not intended for use on public repositories. Once
2366 This command is not intended for use on public repositories. Once
2353 changes are visible for pull by other users, rolling a transaction
2367 changes are visible for pull by other users, rolling a transaction
2354 back locally is ineffective (someone else may already have pulled
2368 back locally is ineffective (someone else may already have pulled
2355 the changes). Furthermore, a race is possible with readers of the
2369 the changes). Furthermore, a race is possible with readers of the
2356 repository; for example an in-progress pull from the repository
2370 repository; for example an in-progress pull from the repository
2357 may fail if a rollback is performed.
2371 may fail if a rollback is performed.
2358 """
2372 """
2359 repo.rollback()
2373 repo.rollback()
2360
2374
2361 def root(ui, repo):
2375 def root(ui, repo):
2362 """print the root (top) of the current working dir
2376 """print the root (top) of the current working dir
2363
2377
2364 Print the root directory of the current repository.
2378 Print the root directory of the current repository.
2365 """
2379 """
2366 ui.write(repo.root + "\n")
2380 ui.write(repo.root + "\n")
2367
2381
2368 def serve(ui, repo, **opts):
2382 def serve(ui, repo, **opts):
2369 """export the repository via HTTP
2383 """export the repository via HTTP
2370
2384
2371 Start a local HTTP repository browser and pull server.
2385 Start a local HTTP repository browser and pull server.
2372
2386
2373 By default, the server logs accesses to stdout and errors to
2387 By default, the server logs accesses to stdout and errors to
2374 stderr. Use the "-A" and "-E" options to log to files.
2388 stderr. Use the "-A" and "-E" options to log to files.
2375 """
2389 """
2376
2390
2377 if opts["stdio"]:
2391 if opts["stdio"]:
2378 if repo is None:
2392 if repo is None:
2379 raise hg.RepoError(_("There is no Mercurial repository here"
2393 raise hg.RepoError(_("There is no Mercurial repository here"
2380 " (.hg not found)"))
2394 " (.hg not found)"))
2381 s = sshserver.sshserver(ui, repo)
2395 s = sshserver.sshserver(ui, repo)
2382 s.serve_forever()
2396 s.serve_forever()
2383
2397
2384 parentui = ui.parentui or ui
2398 parentui = ui.parentui or ui
2385 optlist = ("name templates style address port prefix ipv6"
2399 optlist = ("name templates style address port prefix ipv6"
2386 " accesslog errorlog webdir_conf certificate")
2400 " accesslog errorlog webdir_conf certificate")
2387 for o in optlist.split():
2401 for o in optlist.split():
2388 if opts[o]:
2402 if opts[o]:
2389 parentui.setconfig("web", o, str(opts[o]))
2403 parentui.setconfig("web", o, str(opts[o]))
2390 if (repo is not None) and (repo.ui != parentui):
2404 if (repo is not None) and (repo.ui != parentui):
2391 repo.ui.setconfig("web", o, str(opts[o]))
2405 repo.ui.setconfig("web", o, str(opts[o]))
2392
2406
2393 if repo is None and not ui.config("web", "webdir_conf"):
2407 if repo is None and not ui.config("web", "webdir_conf"):
2394 raise hg.RepoError(_("There is no Mercurial repository here"
2408 raise hg.RepoError(_("There is no Mercurial repository here"
2395 " (.hg not found)"))
2409 " (.hg not found)"))
2396
2410
2397 class service:
2411 class service:
2398 def init(self):
2412 def init(self):
2399 util.set_signal_handler()
2413 util.set_signal_handler()
2400 try:
2414 try:
2401 self.httpd = hgweb.server.create_server(parentui, repo)
2415 self.httpd = hgweb.server.create_server(parentui, repo)
2402 except socket.error, inst:
2416 except socket.error, inst:
2403 raise util.Abort(_('cannot start server: ') + inst.args[1])
2417 raise util.Abort(_('cannot start server: ') + inst.args[1])
2404
2418
2405 if not ui.verbose: return
2419 if not ui.verbose: return
2406
2420
2407 if self.httpd.prefix:
2421 if self.httpd.prefix:
2408 prefix = self.httpd.prefix.strip('/') + '/'
2422 prefix = self.httpd.prefix.strip('/') + '/'
2409 else:
2423 else:
2410 prefix = ''
2424 prefix = ''
2411
2425
2412 if self.httpd.port != 80:
2426 if self.httpd.port != 80:
2413 ui.status(_('listening at http://%s:%d/%s\n') %
2427 ui.status(_('listening at http://%s:%d/%s\n') %
2414 (self.httpd.addr, self.httpd.port, prefix))
2428 (self.httpd.addr, self.httpd.port, prefix))
2415 else:
2429 else:
2416 ui.status(_('listening at http://%s/%s\n') %
2430 ui.status(_('listening at http://%s/%s\n') %
2417 (self.httpd.addr, prefix))
2431 (self.httpd.addr, prefix))
2418
2432
2419 def run(self):
2433 def run(self):
2420 self.httpd.serve_forever()
2434 self.httpd.serve_forever()
2421
2435
2422 service = service()
2436 service = service()
2423
2437
2424 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2438 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2425
2439
2426 def status(ui, repo, *pats, **opts):
2440 def status(ui, repo, *pats, **opts):
2427 """show changed files in the working directory
2441 """show changed files in the working directory
2428
2442
2429 Show status of files in the repository. If names are given, only
2443 Show status of files in the repository. If names are given, only
2430 files that match are shown. Files that are clean or ignored or
2444 files that match are shown. Files that are clean or ignored or
2431 source of a copy/move operation, are not listed unless -c (clean),
2445 source of a copy/move operation, are not listed unless -c (clean),
2432 -i (ignored), -C (copies) or -A is given. Unless options described
2446 -i (ignored), -C (copies) or -A is given. Unless options described
2433 with "show only ..." are given, the options -mardu are used.
2447 with "show only ..." are given, the options -mardu are used.
2434
2448
2435 NOTE: status may appear to disagree with diff if permissions have
2449 NOTE: status may appear to disagree with diff if permissions have
2436 changed or a merge has occurred. The standard diff format does not
2450 changed or a merge has occurred. The standard diff format does not
2437 report permission changes and diff only reports changes relative
2451 report permission changes and diff only reports changes relative
2438 to one merge parent.
2452 to one merge parent.
2439
2453
2440 If one revision is given, it is used as the base revision.
2454 If one revision is given, it is used as the base revision.
2441 If two revisions are given, the difference between them is shown.
2455 If two revisions are given, the difference between them is shown.
2442
2456
2443 The codes used to show the status of files are:
2457 The codes used to show the status of files are:
2444 M = modified
2458 M = modified
2445 A = added
2459 A = added
2446 R = removed
2460 R = removed
2447 C = clean
2461 C = clean
2448 ! = deleted, but still tracked
2462 ! = deleted, but still tracked
2449 ? = not tracked
2463 ? = not tracked
2450 I = ignored
2464 I = ignored
2451 = the previous added file was copied from here
2465 = the previous added file was copied from here
2452 """
2466 """
2453
2467
2454 all = opts['all']
2468 all = opts['all']
2455 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2469 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2456
2470
2457 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2471 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2458 cwd = (pats and repo.getcwd()) or ''
2472 cwd = (pats and repo.getcwd()) or ''
2459 modified, added, removed, deleted, unknown, ignored, clean = [
2473 modified, added, removed, deleted, unknown, ignored, clean = [
2460 n for n in repo.status(node1=node1, node2=node2, files=files,
2474 n for n in repo.status(node1=node1, node2=node2, files=files,
2461 match=matchfn,
2475 match=matchfn,
2462 list_ignored=all or opts['ignored'],
2476 list_ignored=all or opts['ignored'],
2463 list_clean=all or opts['clean'])]
2477 list_clean=all or opts['clean'])]
2464
2478
2465 changetypes = (('modified', 'M', modified),
2479 changetypes = (('modified', 'M', modified),
2466 ('added', 'A', added),
2480 ('added', 'A', added),
2467 ('removed', 'R', removed),
2481 ('removed', 'R', removed),
2468 ('deleted', '!', deleted),
2482 ('deleted', '!', deleted),
2469 ('unknown', '?', unknown),
2483 ('unknown', '?', unknown),
2470 ('ignored', 'I', ignored))
2484 ('ignored', 'I', ignored))
2471
2485
2472 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2486 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2473
2487
2474 end = opts['print0'] and '\0' or '\n'
2488 end = opts['print0'] and '\0' or '\n'
2475
2489
2476 for opt, char, changes in ([ct for ct in explicit_changetypes
2490 for opt, char, changes in ([ct for ct in explicit_changetypes
2477 if all or opts[ct[0]]]
2491 if all or opts[ct[0]]]
2478 or changetypes):
2492 or changetypes):
2479 if opts['no_status']:
2493 if opts['no_status']:
2480 format = "%%s%s" % end
2494 format = "%%s%s" % end
2481 else:
2495 else:
2482 format = "%s %%s%s" % (char, end)
2496 format = "%s %%s%s" % (char, end)
2483
2497
2484 for f in changes:
2498 for f in changes:
2485 ui.write(format % repo.pathto(f, cwd))
2499 ui.write(format % repo.pathto(f, cwd))
2486 if ((all or opts.get('copies')) and not opts.get('no_status')):
2500 if ((all or opts.get('copies')) and not opts.get('no_status')):
2487 copied = repo.dirstate.copied(f)
2501 copied = repo.dirstate.copied(f)
2488 if copied:
2502 if copied:
2489 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2503 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2490
2504
2491 def tag(ui, repo, name, rev_=None, **opts):
2505 def tag(ui, repo, name, rev_=None, **opts):
2492 """add a tag for the current or given revision
2506 """add a tag for the current or given revision
2493
2507
2494 Name a particular revision using <name>.
2508 Name a particular revision using <name>.
2495
2509
2496 Tags are used to name particular revisions of the repository and are
2510 Tags are used to name particular revisions of the repository and are
2497 very useful to compare different revision, to go back to significant
2511 very useful to compare different revision, to go back to significant
2498 earlier versions or to mark branch points as releases, etc.
2512 earlier versions or to mark branch points as releases, etc.
2499
2513
2500 If no revision is given, the parent of the working directory is used,
2514 If no revision is given, the parent of the working directory is used,
2501 or tip if no revision is checked out.
2515 or tip if no revision is checked out.
2502
2516
2503 To facilitate version control, distribution, and merging of tags,
2517 To facilitate version control, distribution, and merging of tags,
2504 they are stored as a file named ".hgtags" which is managed
2518 they are stored as a file named ".hgtags" which is managed
2505 similarly to other project files and can be hand-edited if
2519 similarly to other project files and can be hand-edited if
2506 necessary. The file '.hg/localtags' is used for local tags (not
2520 necessary. The file '.hg/localtags' is used for local tags (not
2507 shared among repositories).
2521 shared among repositories).
2508 """
2522 """
2509 if name in ['tip', '.', 'null']:
2523 if name in ['tip', '.', 'null']:
2510 raise util.Abort(_("the name '%s' is reserved") % name)
2524 raise util.Abort(_("the name '%s' is reserved") % name)
2511 if rev_ is not None:
2525 if rev_ is not None:
2512 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2526 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2513 "please use 'hg tag [-r REV] NAME' instead\n"))
2527 "please use 'hg tag [-r REV] NAME' instead\n"))
2514 if opts['rev']:
2528 if opts['rev']:
2515 raise util.Abort(_("use only one form to specify the revision"))
2529 raise util.Abort(_("use only one form to specify the revision"))
2516 if opts['rev'] and opts['remove']:
2530 if opts['rev'] and opts['remove']:
2517 raise util.Abort(_("--rev and --remove are incompatible"))
2531 raise util.Abort(_("--rev and --remove are incompatible"))
2518 if opts['rev']:
2532 if opts['rev']:
2519 rev_ = opts['rev']
2533 rev_ = opts['rev']
2520 message = opts['message']
2534 message = opts['message']
2521 if opts['remove']:
2535 if opts['remove']:
2522 tagtype = repo.tagtype(name)
2536 tagtype = repo.tagtype(name)
2523
2537
2524 if not tagtype:
2538 if not tagtype:
2525 raise util.Abort(_('tag %s does not exist') % name)
2539 raise util.Abort(_('tag %s does not exist') % name)
2526 if opts['local'] and tagtype == 'global':
2540 if opts['local'] and tagtype == 'global':
2527 raise util.Abort(_('%s tag is global') % name)
2541 raise util.Abort(_('%s tag is global') % name)
2528 if not opts['local'] and tagtype == 'local':
2542 if not opts['local'] and tagtype == 'local':
2529 raise util.Abort(_('%s tag is local') % name)
2543 raise util.Abort(_('%s tag is local') % name)
2530
2544
2531 rev_ = nullid
2545 rev_ = nullid
2532 if not message:
2546 if not message:
2533 message = _('Removed tag %s') % name
2547 message = _('Removed tag %s') % name
2534 elif name in repo.tags() and not opts['force']:
2548 elif name in repo.tags() and not opts['force']:
2535 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2549 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2536 % name)
2550 % name)
2537 if not rev_ and repo.dirstate.parents()[1] != nullid:
2551 if not rev_ and repo.dirstate.parents()[1] != nullid:
2538 raise util.Abort(_('uncommitted merge - please provide a '
2552 raise util.Abort(_('uncommitted merge - please provide a '
2539 'specific revision'))
2553 'specific revision'))
2540 r = repo.changectx(rev_).node()
2554 r = repo.changectx(rev_).node()
2541
2555
2542 if not message:
2556 if not message:
2543 message = _('Added tag %s for changeset %s') % (name, short(r))
2557 message = _('Added tag %s for changeset %s') % (name, short(r))
2544
2558
2545 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2559 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2546
2560
2547 def tags(ui, repo):
2561 def tags(ui, repo):
2548 """list repository tags
2562 """list repository tags
2549
2563
2550 List the repository tags.
2564 List the repository tags.
2551
2565
2552 This lists both regular and local tags. When the -v/--verbose switch
2566 This lists both regular and local tags. When the -v/--verbose switch
2553 is used, a third column "local" is printed for local tags.
2567 is used, a third column "local" is printed for local tags.
2554 """
2568 """
2555
2569
2556 l = repo.tagslist()
2570 l = repo.tagslist()
2557 l.reverse()
2571 l.reverse()
2558 hexfunc = ui.debugflag and hex or short
2572 hexfunc = ui.debugflag and hex or short
2559 tagtype = ""
2573 tagtype = ""
2560
2574
2561 for t, n in l:
2575 for t, n in l:
2562 if ui.quiet:
2576 if ui.quiet:
2563 ui.write("%s\n" % t)
2577 ui.write("%s\n" % t)
2564 continue
2578 continue
2565
2579
2566 try:
2580 try:
2567 hn = hexfunc(n)
2581 hn = hexfunc(n)
2568 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2582 r = "%5d:%s" % (repo.changelog.rev(n), hn)
2569 except revlog.LookupError:
2583 except revlog.LookupError:
2570 r = " ?:%s" % hn
2584 r = " ?:%s" % hn
2571 else:
2585 else:
2572 spaces = " " * (30 - util.locallen(t))
2586 spaces = " " * (30 - util.locallen(t))
2573 if ui.verbose:
2587 if ui.verbose:
2574 if repo.tagtype(t) == 'local':
2588 if repo.tagtype(t) == 'local':
2575 tagtype = " local"
2589 tagtype = " local"
2576 else:
2590 else:
2577 tagtype = ""
2591 tagtype = ""
2578 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2592 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
2579
2593
2580 def tip(ui, repo, **opts):
2594 def tip(ui, repo, **opts):
2581 """show the tip revision
2595 """show the tip revision
2582
2596
2583 Show the tip revision.
2597 Show the tip revision.
2584 """
2598 """
2585 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2599 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2586
2600
2587 def unbundle(ui, repo, fname1, *fnames, **opts):
2601 def unbundle(ui, repo, fname1, *fnames, **opts):
2588 """apply one or more changegroup files
2602 """apply one or more changegroup files
2589
2603
2590 Apply one or more compressed changegroup files generated by the
2604 Apply one or more compressed changegroup files generated by the
2591 bundle command.
2605 bundle command.
2592 """
2606 """
2593 fnames = (fname1,) + fnames
2607 fnames = (fname1,) + fnames
2594 for fname in fnames:
2608 for fname in fnames:
2595 if os.path.exists(fname):
2609 if os.path.exists(fname):
2596 f = open(fname, "rb")
2610 f = open(fname, "rb")
2597 else:
2611 else:
2598 f = urllib.urlopen(fname)
2612 f = urllib.urlopen(fname)
2599 gen = changegroup.readbundle(f, fname)
2613 gen = changegroup.readbundle(f, fname)
2600 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2614 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2601
2615
2602 return postincoming(ui, repo, modheads, opts['update'], None)
2616 return postincoming(ui, repo, modheads, opts['update'], None)
2603
2617
2604 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2618 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2605 """update working directory
2619 """update working directory
2606
2620
2607 Update the working directory to the specified revision, or the
2621 Update the working directory to the specified revision, or the
2608 tip of the current branch if none is specified.
2622 tip of the current branch if none is specified.
2609
2623
2610 If there are no outstanding changes in the working directory and
2624 If there are no outstanding changes in the working directory and
2611 there is a linear relationship between the current version and the
2625 there is a linear relationship between the current version and the
2612 requested version, the result is the requested version.
2626 requested version, the result is the requested version.
2613
2627
2614 To merge the working directory with another revision, use the
2628 To merge the working directory with another revision, use the
2615 merge command.
2629 merge command.
2616
2630
2617 By default, update will refuse to run if doing so would require
2631 By default, update will refuse to run if doing so would require
2618 discarding local changes.
2632 discarding local changes.
2619 """
2633 """
2620 if rev and node:
2634 if rev and node:
2621 raise util.Abort(_("please specify just one revision"))
2635 raise util.Abort(_("please specify just one revision"))
2622
2636
2623 if not rev:
2637 if not rev:
2624 rev = node
2638 rev = node
2625
2639
2626 if date:
2640 if date:
2627 if rev:
2641 if rev:
2628 raise util.Abort(_("you can't specify a revision and a date"))
2642 raise util.Abort(_("you can't specify a revision and a date"))
2629 rev = cmdutil.finddate(ui, repo, date)
2643 rev = cmdutil.finddate(ui, repo, date)
2630
2644
2631 if clean:
2645 if clean:
2632 return hg.clean(repo, rev)
2646 return hg.clean(repo, rev)
2633 else:
2647 else:
2634 return hg.update(repo, rev)
2648 return hg.update(repo, rev)
2635
2649
2636 def verify(ui, repo):
2650 def verify(ui, repo):
2637 """verify the integrity of the repository
2651 """verify the integrity of the repository
2638
2652
2639 Verify the integrity of the current repository.
2653 Verify the integrity of the current repository.
2640
2654
2641 This will perform an extensive check of the repository's
2655 This will perform an extensive check of the repository's
2642 integrity, validating the hashes and checksums of each entry in
2656 integrity, validating the hashes and checksums of each entry in
2643 the changelog, manifest, and tracked files, as well as the
2657 the changelog, manifest, and tracked files, as well as the
2644 integrity of their crosslinks and indices.
2658 integrity of their crosslinks and indices.
2645 """
2659 """
2646 return hg.verify(repo)
2660 return hg.verify(repo)
2647
2661
2648 def version_(ui):
2662 def version_(ui):
2649 """output version and copyright information"""
2663 """output version and copyright information"""
2650 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2664 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2651 % version.get_version())
2665 % version.get_version())
2652 ui.status(_(
2666 ui.status(_(
2653 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2667 "\nCopyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others\n"
2654 "This is free software; see the source for copying conditions. "
2668 "This is free software; see the source for copying conditions. "
2655 "There is NO\nwarranty; "
2669 "There is NO\nwarranty; "
2656 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2670 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2657 ))
2671 ))
2658
2672
2659 # Command options and aliases are listed here, alphabetically
2673 # Command options and aliases are listed here, alphabetically
2660
2674
2661 globalopts = [
2675 globalopts = [
2662 ('R', 'repository', '',
2676 ('R', 'repository', '',
2663 _('repository root directory or symbolic path name')),
2677 _('repository root directory or symbolic path name')),
2664 ('', 'cwd', '', _('change working directory')),
2678 ('', 'cwd', '', _('change working directory')),
2665 ('y', 'noninteractive', None,
2679 ('y', 'noninteractive', None,
2666 _('do not prompt, assume \'yes\' for any required answers')),
2680 _('do not prompt, assume \'yes\' for any required answers')),
2667 ('q', 'quiet', None, _('suppress output')),
2681 ('q', 'quiet', None, _('suppress output')),
2668 ('v', 'verbose', None, _('enable additional output')),
2682 ('v', 'verbose', None, _('enable additional output')),
2669 ('', 'config', [], _('set/override config option')),
2683 ('', 'config', [], _('set/override config option')),
2670 ('', 'debug', None, _('enable debugging output')),
2684 ('', 'debug', None, _('enable debugging output')),
2671 ('', 'debugger', None, _('start debugger')),
2685 ('', 'debugger', None, _('start debugger')),
2672 ('', 'encoding', util._encoding, _('set the charset encoding')),
2686 ('', 'encoding', util._encoding, _('set the charset encoding')),
2673 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2687 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2674 ('', 'lsprof', None, _('print improved command execution profile')),
2688 ('', 'lsprof', None, _('print improved command execution profile')),
2675 ('', 'traceback', None, _('print traceback on exception')),
2689 ('', 'traceback', None, _('print traceback on exception')),
2676 ('', 'time', None, _('time how long the command takes')),
2690 ('', 'time', None, _('time how long the command takes')),
2677 ('', 'profile', None, _('print command execution profile')),
2691 ('', 'profile', None, _('print command execution profile')),
2678 ('', 'version', None, _('output version information and exit')),
2692 ('', 'version', None, _('output version information and exit')),
2679 ('h', 'help', None, _('display help and exit')),
2693 ('h', 'help', None, _('display help and exit')),
2680 ]
2694 ]
2681
2695
2682 dryrunopts = [('n', 'dry-run', None,
2696 dryrunopts = [('n', 'dry-run', None,
2683 _('do not perform actions, just print output'))]
2697 _('do not perform actions, just print output'))]
2684
2698
2685 remoteopts = [
2699 remoteopts = [
2686 ('e', 'ssh', '', _('specify ssh command to use')),
2700 ('e', 'ssh', '', _('specify ssh command to use')),
2687 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2701 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2688 ]
2702 ]
2689
2703
2690 walkopts = [
2704 walkopts = [
2691 ('I', 'include', [], _('include names matching the given patterns')),
2705 ('I', 'include', [], _('include names matching the given patterns')),
2692 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2706 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2693 ]
2707 ]
2694
2708
2695 commitopts = [
2709 commitopts = [
2696 ('m', 'message', '', _('use <text> as commit message')),
2710 ('m', 'message', '', _('use <text> as commit message')),
2697 ('l', 'logfile', '', _('read commit message from <file>')),
2711 ('l', 'logfile', '', _('read commit message from <file>')),
2698 ]
2712 ]
2699
2713
2700 commitopts2 = [
2714 commitopts2 = [
2701 ('d', 'date', '', _('record datecode as commit date')),
2715 ('d', 'date', '', _('record datecode as commit date')),
2702 ('u', 'user', '', _('record user as committer')),
2716 ('u', 'user', '', _('record user as committer')),
2703 ]
2717 ]
2704
2718
2705 table = {
2719 table = {
2706 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2720 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2707 "addremove":
2721 "addremove":
2708 (addremove,
2722 (addremove,
2709 [('s', 'similarity', '',
2723 [('s', 'similarity', '',
2710 _('guess renamed files by similarity (0<=s<=100)')),
2724 _('guess renamed files by similarity (0<=s<=100)')),
2711 ] + walkopts + dryrunopts,
2725 ] + walkopts + dryrunopts,
2712 _('hg addremove [OPTION]... [FILE]...')),
2726 _('hg addremove [OPTION]... [FILE]...')),
2713 "^annotate":
2727 "^annotate":
2714 (annotate,
2728 (annotate,
2715 [('r', 'rev', '', _('annotate the specified revision')),
2729 [('r', 'rev', '', _('annotate the specified revision')),
2716 ('f', 'follow', None, _('follow file copies and renames')),
2730 ('f', 'follow', None, _('follow file copies and renames')),
2717 ('a', 'text', None, _('treat all files as text')),
2731 ('a', 'text', None, _('treat all files as text')),
2718 ('u', 'user', None, _('list the author')),
2732 ('u', 'user', None, _('list the author')),
2719 ('d', 'date', None, _('list the date')),
2733 ('d', 'date', None, _('list the date')),
2720 ('n', 'number', None, _('list the revision number (default)')),
2734 ('n', 'number', None, _('list the revision number (default)')),
2721 ('c', 'changeset', None, _('list the changeset')),
2735 ('c', 'changeset', None, _('list the changeset')),
2722 ('l', 'line-number', None,
2736 ('l', 'line-number', None,
2723 _('show line number at the first appearance'))
2737 _('show line number at the first appearance'))
2724 ] + walkopts,
2738 ] + walkopts,
2725 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2739 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
2726 "archive":
2740 "archive":
2727 (archive,
2741 (archive,
2728 [('', 'no-decode', None, _('do not pass files through decoders')),
2742 [('', 'no-decode', None, _('do not pass files through decoders')),
2729 ('p', 'prefix', '', _('directory prefix for files in archive')),
2743 ('p', 'prefix', '', _('directory prefix for files in archive')),
2730 ('r', 'rev', '', _('revision to distribute')),
2744 ('r', 'rev', '', _('revision to distribute')),
2731 ('t', 'type', '', _('type of distribution to create')),
2745 ('t', 'type', '', _('type of distribution to create')),
2732 ] + walkopts,
2746 ] + walkopts,
2733 _('hg archive [OPTION]... DEST')),
2747 _('hg archive [OPTION]... DEST')),
2734 "backout":
2748 "backout":
2735 (backout,
2749 (backout,
2736 [('', 'merge', None,
2750 [('', 'merge', None,
2737 _('merge with old dirstate parent after backout')),
2751 _('merge with old dirstate parent after backout')),
2738 ('', 'parent', '', _('parent to choose when backing out merge')),
2752 ('', 'parent', '', _('parent to choose when backing out merge')),
2739 ('r', 'rev', '', _('revision to backout')),
2753 ('r', 'rev', '', _('revision to backout')),
2740 ] + walkopts + commitopts + commitopts2,
2754 ] + walkopts + commitopts + commitopts2,
2741 _('hg backout [OPTION]... [-r] REV')),
2755 _('hg backout [OPTION]... [-r] REV')),
2742 "bisect":
2756 "bisect":
2743 (bisect,
2757 (bisect,
2744 [('r', 'reset', False, _('reset bisect state')),
2758 [('r', 'reset', False, _('reset bisect state')),
2745 ('g', 'good', False, _('mark changeset good')),
2759 ('g', 'good', False, _('mark changeset good')),
2746 ('b', 'bad', False, _('mark changeset bad')),
2760 ('b', 'bad', False, _('mark changeset bad')),
2747 ('s', 'skip', False, _('skip testing changeset')),
2761 ('s', 'skip', False, _('skip testing changeset')),
2748 ('U', 'noupdate', False, _('do not update to target'))],
2762 ('U', 'noupdate', False, _('do not update to target'))],
2749 _("hg bisect [-gbsr] [REV]")),
2763 _("hg bisect [-gbsr] [REV]")),
2750 "branch":
2764 "branch":
2751 (branch,
2765 (branch,
2752 [('f', 'force', None,
2766 [('f', 'force', None,
2753 _('set branch name even if it shadows an existing branch'))],
2767 _('set branch name even if it shadows an existing branch'))],
2754 _('hg branch [-f] [NAME]')),
2768 _('hg branch [-f] [NAME]')),
2755 "branches":
2769 "branches":
2756 (branches,
2770 (branches,
2757 [('a', 'active', False,
2771 [('a', 'active', False,
2758 _('show only branches that have unmerged heads'))],
2772 _('show only branches that have unmerged heads'))],
2759 _('hg branches [-a]')),
2773 _('hg branches [-a]')),
2760 "bundle":
2774 "bundle":
2761 (bundle,
2775 (bundle,
2762 [('f', 'force', None,
2776 [('f', 'force', None,
2763 _('run even when remote repository is unrelated')),
2777 _('run even when remote repository is unrelated')),
2764 ('r', 'rev', [],
2778 ('r', 'rev', [],
2765 _('a changeset you would like to bundle')),
2779 _('a changeset you would like to bundle')),
2766 ('', 'base', [],
2780 ('', 'base', [],
2767 _('a base changeset to specify instead of a destination')),
2781 _('a base changeset to specify instead of a destination')),
2768 ] + remoteopts,
2782 ] + remoteopts,
2769 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2783 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2770 "cat":
2784 "cat":
2771 (cat,
2785 (cat,
2772 [('o', 'output', '', _('print output to file with formatted name')),
2786 [('o', 'output', '', _('print output to file with formatted name')),
2773 ('r', 'rev', '', _('print the given revision')),
2787 ('r', 'rev', '', _('print the given revision')),
2774 ('', 'decode', None, _('apply any matching decode filter')),
2788 ('', 'decode', None, _('apply any matching decode filter')),
2775 ] + walkopts,
2789 ] + walkopts,
2776 _('hg cat [OPTION]... FILE...')),
2790 _('hg cat [OPTION]... FILE...')),
2777 "^clone":
2791 "^clone":
2778 (clone,
2792 (clone,
2779 [('U', 'noupdate', None, _('do not update the new working directory')),
2793 [('U', 'noupdate', None, _('do not update the new working directory')),
2780 ('r', 'rev', [],
2794 ('r', 'rev', [],
2781 _('a changeset you would like to have after cloning')),
2795 _('a changeset you would like to have after cloning')),
2782 ('', 'pull', None, _('use pull protocol to copy metadata')),
2796 ('', 'pull', None, _('use pull protocol to copy metadata')),
2783 ('', 'uncompressed', None,
2797 ('', 'uncompressed', None,
2784 _('use uncompressed transfer (fast over LAN)')),
2798 _('use uncompressed transfer (fast over LAN)')),
2785 ] + remoteopts,
2799 ] + remoteopts,
2786 _('hg clone [OPTION]... SOURCE [DEST]')),
2800 _('hg clone [OPTION]... SOURCE [DEST]')),
2787 "^commit|ci":
2801 "^commit|ci":
2788 (commit,
2802 (commit,
2789 [('A', 'addremove', None,
2803 [('A', 'addremove', None,
2790 _('mark new/missing files as added/removed before committing')),
2804 _('mark new/missing files as added/removed before committing')),
2791 ] + walkopts + commitopts + commitopts2,
2805 ] + walkopts + commitopts + commitopts2,
2792 _('hg commit [OPTION]... [FILE]...')),
2806 _('hg commit [OPTION]... [FILE]...')),
2793 "copy|cp":
2807 "copy|cp":
2794 (copy,
2808 (copy,
2795 [('A', 'after', None, _('record a copy that has already occurred')),
2809 [('A', 'after', None, _('record a copy that has already occurred')),
2796 ('f', 'force', None,
2810 ('f', 'force', None,
2797 _('forcibly copy over an existing managed file')),
2811 _('forcibly copy over an existing managed file')),
2798 ] + walkopts + dryrunopts,
2812 ] + walkopts + dryrunopts,
2799 _('hg copy [OPTION]... [SOURCE]... DEST')),
2813 _('hg copy [OPTION]... [SOURCE]... DEST')),
2800 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2814 "debugancestor": (debugancestor, [], _('hg debugancestor INDEX REV1 REV2')),
2801 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2815 "debugcheckstate": (debugcheckstate, [], _('hg debugcheckstate')),
2802 "debugcomplete":
2816 "debugcomplete":
2803 (debugcomplete,
2817 (debugcomplete,
2804 [('o', 'options', None, _('show the command options'))],
2818 [('o', 'options', None, _('show the command options'))],
2805 _('hg debugcomplete [-o] CMD')),
2819 _('hg debugcomplete [-o] CMD')),
2806 "debugdate":
2820 "debugdate":
2807 (debugdate,
2821 (debugdate,
2808 [('e', 'extended', None, _('try extended date formats'))],
2822 [('e', 'extended', None, _('try extended date formats'))],
2809 _('hg debugdate [-e] DATE [RANGE]')),
2823 _('hg debugdate [-e] DATE [RANGE]')),
2810 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2824 "debugdata": (debugdata, [], _('hg debugdata FILE REV')),
2811 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2825 "debugfsinfo": (debugfsinfo, [], _('hg debugfsinfo [PATH]')),
2812 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2826 "debugindex": (debugindex, [], _('hg debugindex FILE')),
2813 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2827 "debugindexdot": (debugindexdot, [], _('hg debugindexdot FILE')),
2814 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2828 "debuginstall": (debuginstall, [], _('hg debuginstall')),
2815 "debugrawcommit|rawcommit":
2829 "debugrawcommit|rawcommit":
2816 (rawcommit,
2830 (rawcommit,
2817 [('p', 'parent', [], _('parent')),
2831 [('p', 'parent', [], _('parent')),
2818 ('F', 'files', '', _('file list'))
2832 ('F', 'files', '', _('file list'))
2819 ] + commitopts + commitopts2,
2833 ] + commitopts + commitopts2,
2820 _('hg debugrawcommit [OPTION]... [FILE]...')),
2834 _('hg debugrawcommit [OPTION]... [FILE]...')),
2821 "debugrebuildstate":
2835 "debugrebuildstate":
2822 (debugrebuildstate,
2836 (debugrebuildstate,
2823 [('r', 'rev', '', _('revision to rebuild to'))],
2837 [('r', 'rev', '', _('revision to rebuild to'))],
2824 _('hg debugrebuildstate [-r REV] [REV]')),
2838 _('hg debugrebuildstate [-r REV] [REV]')),
2825 "debugrename":
2839 "debugrename":
2826 (debugrename,
2840 (debugrename,
2827 [('r', 'rev', '', _('revision to debug'))],
2841 [('r', 'rev', '', _('revision to debug'))],
2828 _('hg debugrename [-r REV] FILE')),
2842 _('hg debugrename [-r REV] FILE')),
2829 "debugsetparents":
2843 "debugsetparents":
2830 (debugsetparents,
2844 (debugsetparents,
2831 [],
2845 [],
2832 _('hg debugsetparents REV1 [REV2]')),
2846 _('hg debugsetparents REV1 [REV2]')),
2833 "debugstate": (debugstate, [], _('hg debugstate')),
2847 "debugstate": (debugstate, [], _('hg debugstate')),
2834 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2848 "debugwalk": (debugwalk, walkopts, _('hg debugwalk [OPTION]... [FILE]...')),
2835 "^diff":
2849 "^diff":
2836 (diff,
2850 (diff,
2837 [('r', 'rev', [], _('revision')),
2851 [('r', 'rev', [], _('revision')),
2838 ('a', 'text', None, _('treat all files as text')),
2852 ('a', 'text', None, _('treat all files as text')),
2839 ('p', 'show-function', None,
2853 ('p', 'show-function', None,
2840 _('show which function each change is in')),
2854 _('show which function each change is in')),
2841 ('g', 'git', None, _('use git extended diff format')),
2855 ('g', 'git', None, _('use git extended diff format')),
2842 ('', 'nodates', None, _("don't include dates in diff headers")),
2856 ('', 'nodates', None, _("don't include dates in diff headers")),
2843 ('w', 'ignore-all-space', None,
2857 ('w', 'ignore-all-space', None,
2844 _('ignore white space when comparing lines')),
2858 _('ignore white space when comparing lines')),
2845 ('b', 'ignore-space-change', None,
2859 ('b', 'ignore-space-change', None,
2846 _('ignore changes in the amount of white space')),
2860 _('ignore changes in the amount of white space')),
2847 ('B', 'ignore-blank-lines', None,
2861 ('B', 'ignore-blank-lines', None,
2848 _('ignore changes whose lines are all blank')),
2862 _('ignore changes whose lines are all blank')),
2849 ('U', 'unified', 3,
2863 ('U', 'unified', 3,
2850 _('number of lines of context to show'))
2864 _('number of lines of context to show'))
2851 ] + walkopts,
2865 ] + walkopts,
2852 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2866 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2853 "^export":
2867 "^export":
2854 (export,
2868 (export,
2855 [('o', 'output', '', _('print output to file with formatted name')),
2869 [('o', 'output', '', _('print output to file with formatted name')),
2856 ('a', 'text', None, _('treat all files as text')),
2870 ('a', 'text', None, _('treat all files as text')),
2857 ('g', 'git', None, _('use git extended diff format')),
2871 ('g', 'git', None, _('use git extended diff format')),
2858 ('', 'nodates', None, _("don't include dates in diff headers")),
2872 ('', 'nodates', None, _("don't include dates in diff headers")),
2859 ('', 'switch-parent', None, _('diff against the second parent'))],
2873 ('', 'switch-parent', None, _('diff against the second parent'))],
2860 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2874 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2861 "grep":
2875 "grep":
2862 (grep,
2876 (grep,
2863 [('0', 'print0', None, _('end fields with NUL')),
2877 [('0', 'print0', None, _('end fields with NUL')),
2864 ('', 'all', None, _('print all revisions that match')),
2878 ('', 'all', None, _('print all revisions that match')),
2865 ('f', 'follow', None,
2879 ('f', 'follow', None,
2866 _('follow changeset history, or file history across copies and renames')),
2880 _('follow changeset history, or file history across copies and renames')),
2867 ('i', 'ignore-case', None, _('ignore case when matching')),
2881 ('i', 'ignore-case', None, _('ignore case when matching')),
2868 ('l', 'files-with-matches', None,
2882 ('l', 'files-with-matches', None,
2869 _('print only filenames and revs that match')),
2883 _('print only filenames and revs that match')),
2870 ('n', 'line-number', None, _('print matching line numbers')),
2884 ('n', 'line-number', None, _('print matching line numbers')),
2871 ('r', 'rev', [], _('search in given revision range')),
2885 ('r', 'rev', [], _('search in given revision range')),
2872 ('u', 'user', None, _('print user who committed change')),
2886 ('u', 'user', None, _('print user who committed change')),
2873 ] + walkopts,
2887 ] + walkopts,
2874 _('hg grep [OPTION]... PATTERN [FILE]...')),
2888 _('hg grep [OPTION]... PATTERN [FILE]...')),
2875 "heads":
2889 "heads":
2876 (heads,
2890 (heads,
2877 [('', 'style', '', _('display using template map file')),
2891 [('', 'style', '', _('display using template map file')),
2878 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2892 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2879 ('', 'template', '', _('display with template'))],
2893 ('', 'template', '', _('display with template'))],
2880 _('hg heads [-r REV] [REV]...')),
2894 _('hg heads [-r REV] [REV]...')),
2881 "help": (help_, [], _('hg help [COMMAND]')),
2895 "help": (help_, [], _('hg help [COMMAND]')),
2882 "identify|id":
2896 "identify|id":
2883 (identify,
2897 (identify,
2884 [('r', 'rev', '', _('identify the specified rev')),
2898 [('r', 'rev', '', _('identify the specified rev')),
2885 ('n', 'num', None, _('show local revision number')),
2899 ('n', 'num', None, _('show local revision number')),
2886 ('i', 'id', None, _('show global revision id')),
2900 ('i', 'id', None, _('show global revision id')),
2887 ('b', 'branch', None, _('show branch')),
2901 ('b', 'branch', None, _('show branch')),
2888 ('t', 'tags', None, _('show tags'))],
2902 ('t', 'tags', None, _('show tags'))],
2889 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2903 _('hg identify [-nibt] [-r REV] [SOURCE]')),
2890 "import|patch":
2904 "import|patch":
2891 (import_,
2905 (import_,
2892 [('p', 'strip', 1,
2906 [('p', 'strip', 1,
2893 _('directory strip option for patch. This has the same\n'
2907 _('directory strip option for patch. This has the same\n'
2894 'meaning as the corresponding patch option')),
2908 'meaning as the corresponding patch option')),
2895 ('b', 'base', '', _('base path')),
2909 ('b', 'base', '', _('base path')),
2896 ('f', 'force', None,
2910 ('f', 'force', None,
2897 _('skip check for outstanding uncommitted changes')),
2911 _('skip check for outstanding uncommitted changes')),
2898 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2912 ('', 'no-commit', None, _("don't commit, just update the working directory")),
2899 ('', 'exact', None,
2913 ('', 'exact', None,
2900 _('apply patch to the nodes from which it was generated')),
2914 _('apply patch to the nodes from which it was generated')),
2901 ('', 'import-branch', None,
2915 ('', 'import-branch', None,
2902 _('Use any branch information in patch (implied by --exact)'))] +
2916 _('Use any branch information in patch (implied by --exact)'))] +
2903 commitopts + commitopts2,
2917 commitopts + commitopts2,
2904 _('hg import [OPTION]... PATCH...')),
2918 _('hg import [OPTION]... PATCH...')),
2905 "incoming|in":
2919 "incoming|in":
2906 (incoming,
2920 (incoming,
2907 [('M', 'no-merges', None, _('do not show merges')),
2921 [('M', 'no-merges', None, _('do not show merges')),
2908 ('f', 'force', None,
2922 ('f', 'force', None,
2909 _('run even when remote repository is unrelated')),
2923 _('run even when remote repository is unrelated')),
2910 ('', 'style', '', _('display using template map file')),
2924 ('', 'style', '', _('display using template map file')),
2911 ('n', 'newest-first', None, _('show newest record first')),
2925 ('n', 'newest-first', None, _('show newest record first')),
2912 ('', 'bundle', '', _('file to store the bundles into')),
2926 ('', 'bundle', '', _('file to store the bundles into')),
2913 ('p', 'patch', None, _('show patch')),
2927 ('p', 'patch', None, _('show patch')),
2914 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2928 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2915 ('', 'template', '', _('display with template')),
2929 ('', 'template', '', _('display with template')),
2916 ] + remoteopts,
2930 ] + remoteopts,
2917 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2931 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2918 ' [--bundle FILENAME] [SOURCE]')),
2932 ' [--bundle FILENAME] [SOURCE]')),
2919 "^init":
2933 "^init":
2920 (init,
2934 (init,
2921 remoteopts,
2935 remoteopts,
2922 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2936 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2923 "locate":
2937 "locate":
2924 (locate,
2938 (locate,
2925 [('r', 'rev', '', _('search the repository as it stood at rev')),
2939 [('r', 'rev', '', _('search the repository as it stood at rev')),
2926 ('0', 'print0', None,
2940 ('0', 'print0', None,
2927 _('end filenames with NUL, for use with xargs')),
2941 _('end filenames with NUL, for use with xargs')),
2928 ('f', 'fullpath', None,
2942 ('f', 'fullpath', None,
2929 _('print complete paths from the filesystem root')),
2943 _('print complete paths from the filesystem root')),
2930 ] + walkopts,
2944 ] + walkopts,
2931 _('hg locate [OPTION]... [PATTERN]...')),
2945 _('hg locate [OPTION]... [PATTERN]...')),
2932 "^log|history":
2946 "^log|history":
2933 (log,
2947 (log,
2934 [('f', 'follow', None,
2948 [('f', 'follow', None,
2935 _('follow changeset history, or file history across copies and renames')),
2949 _('follow changeset history, or file history across copies and renames')),
2936 ('', 'follow-first', None,
2950 ('', 'follow-first', None,
2937 _('only follow the first parent of merge changesets')),
2951 _('only follow the first parent of merge changesets')),
2938 ('d', 'date', '', _('show revs matching date spec')),
2952 ('d', 'date', '', _('show revs matching date spec')),
2939 ('C', 'copies', None, _('show copied files')),
2953 ('C', 'copies', None, _('show copied files')),
2940 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2954 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2941 ('l', 'limit', '', _('limit number of changes displayed')),
2955 ('l', 'limit', '', _('limit number of changes displayed')),
2942 ('r', 'rev', [], _('show the specified revision or range')),
2956 ('r', 'rev', [], _('show the specified revision or range')),
2943 ('', 'removed', None, _('include revs where files were removed')),
2957 ('', 'removed', None, _('include revs where files were removed')),
2944 ('M', 'no-merges', None, _('do not show merges')),
2958 ('M', 'no-merges', None, _('do not show merges')),
2945 ('', 'style', '', _('display using template map file')),
2959 ('', 'style', '', _('display using template map file')),
2946 ('m', 'only-merges', None, _('show only merges')),
2960 ('m', 'only-merges', None, _('show only merges')),
2947 ('b', 'only-branch', [],
2961 ('b', 'only-branch', [],
2948 _('show only changesets within the given named branch')),
2962 _('show only changesets within the given named branch')),
2949 ('p', 'patch', None, _('show patch')),
2963 ('p', 'patch', None, _('show patch')),
2950 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2964 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2951 ('', 'template', '', _('display with template')),
2965 ('', 'template', '', _('display with template')),
2952 ] + walkopts,
2966 ] + walkopts,
2953 _('hg log [OPTION]... [FILE]')),
2967 _('hg log [OPTION]... [FILE]')),
2954 "manifest":
2968 "manifest":
2955 (manifest,
2969 (manifest,
2956 [('r', 'rev', '', _('revision to display'))],
2970 [('r', 'rev', '', _('revision to display'))],
2957 _('hg manifest [-r REV]')),
2971 _('hg manifest [-r REV]')),
2958 "^merge":
2972 "^merge":
2959 (merge,
2973 (merge,
2960 [('f', 'force', None, _('force a merge with outstanding changes')),
2974 [('f', 'force', None, _('force a merge with outstanding changes')),
2961 ('r', 'rev', '', _('revision to merge')),
2975 ('r', 'rev', '', _('revision to merge')),
2962 ],
2976 ],
2963 _('hg merge [-f] [[-r] REV]')),
2977 _('hg merge [-f] [[-r] REV]')),
2964 "outgoing|out":
2978 "outgoing|out":
2965 (outgoing,
2979 (outgoing,
2966 [('M', 'no-merges', None, _('do not show merges')),
2980 [('M', 'no-merges', None, _('do not show merges')),
2967 ('f', 'force', None,
2981 ('f', 'force', None,
2968 _('run even when remote repository is unrelated')),
2982 _('run even when remote repository is unrelated')),
2969 ('p', 'patch', None, _('show patch')),
2983 ('p', 'patch', None, _('show patch')),
2970 ('', 'style', '', _('display using template map file')),
2984 ('', 'style', '', _('display using template map file')),
2971 ('r', 'rev', [], _('a specific revision you would like to push')),
2985 ('r', 'rev', [], _('a specific revision you would like to push')),
2972 ('n', 'newest-first', None, _('show newest record first')),
2986 ('n', 'newest-first', None, _('show newest record first')),
2973 ('', 'template', '', _('display with template')),
2987 ('', 'template', '', _('display with template')),
2974 ] + remoteopts,
2988 ] + remoteopts,
2975 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2989 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2976 "^parents":
2990 "^parents":
2977 (parents,
2991 (parents,
2978 [('r', 'rev', '', _('show parents from the specified rev')),
2992 [('r', 'rev', '', _('show parents from the specified rev')),
2979 ('', 'style', '', _('display using template map file')),
2993 ('', 'style', '', _('display using template map file')),
2980 ('', 'template', '', _('display with template'))],
2994 ('', 'template', '', _('display with template'))],
2981 _('hg parents [-r REV] [FILE]')),
2995 _('hg parents [-r REV] [FILE]')),
2982 "paths": (paths, [], _('hg paths [NAME]')),
2996 "paths": (paths, [], _('hg paths [NAME]')),
2983 "^pull":
2997 "^pull":
2984 (pull,
2998 (pull,
2985 [('u', 'update', None,
2999 [('u', 'update', None,
2986 _('update to new tip if changesets were pulled')),
3000 _('update to new tip if changesets were pulled')),
2987 ('f', 'force', None,
3001 ('f', 'force', None,
2988 _('run even when remote repository is unrelated')),
3002 _('run even when remote repository is unrelated')),
2989 ('r', 'rev', [],
3003 ('r', 'rev', [],
2990 _('a specific revision up to which you would like to pull')),
3004 _('a specific revision up to which you would like to pull')),
2991 ] + remoteopts,
3005 ] + remoteopts,
2992 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
3006 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2993 "^push":
3007 "^push":
2994 (push,
3008 (push,
2995 [('f', 'force', None, _('force push')),
3009 [('f', 'force', None, _('force push')),
2996 ('r', 'rev', [], _('a specific revision you would like to push')),
3010 ('r', 'rev', [], _('a specific revision you would like to push')),
2997 ] + remoteopts,
3011 ] + remoteopts,
2998 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3012 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2999 "recover": (recover, [], _('hg recover')),
3013 "recover": (recover, [], _('hg recover')),
3000 "^remove|rm":
3014 "^remove|rm":
3001 (remove,
3015 (remove,
3002 [('A', 'after', None, _('record remove without deleting')),
3016 [('A', 'after', None, _('record remove without deleting')),
3003 ('f', 'force', None, _('remove file even if modified')),
3017 ('f', 'force', None, _('remove file even if modified')),
3004 ] + walkopts,
3018 ] + walkopts,
3005 _('hg remove [OPTION]... FILE...')),
3019 _('hg remove [OPTION]... FILE...')),
3006 "rename|mv":
3020 "rename|mv":
3007 (rename,
3021 (rename,
3008 [('A', 'after', None, _('record a rename that has already occurred')),
3022 [('A', 'after', None, _('record a rename that has already occurred')),
3009 ('f', 'force', None,
3023 ('f', 'force', None,
3010 _('forcibly copy over an existing managed file')),
3024 _('forcibly copy over an existing managed file')),
3011 ] + walkopts + dryrunopts,
3025 ] + walkopts + dryrunopts,
3012 _('hg rename [OPTION]... SOURCE... DEST')),
3026 _('hg rename [OPTION]... SOURCE... DEST')),
3013 "revert":
3027 "revert":
3014 (revert,
3028 (revert,
3015 [('a', 'all', None, _('revert all changes when no arguments given')),
3029 [('a', 'all', None, _('revert all changes when no arguments given')),
3016 ('d', 'date', '', _('tipmost revision matching date')),
3030 ('d', 'date', '', _('tipmost revision matching date')),
3017 ('r', 'rev', '', _('revision to revert to')),
3031 ('r', 'rev', '', _('revision to revert to')),
3018 ('', 'no-backup', None, _('do not save backup copies of files')),
3032 ('', 'no-backup', None, _('do not save backup copies of files')),
3019 ] + walkopts + dryrunopts,
3033 ] + walkopts + dryrunopts,
3020 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3034 _('hg revert [OPTION]... [-r REV] [NAME]...')),
3021 "rollback": (rollback, [], _('hg rollback')),
3035 "rollback": (rollback, [], _('hg rollback')),
3022 "root": (root, [], _('hg root')),
3036 "root": (root, [], _('hg root')),
3023 "^serve":
3037 "^serve":
3024 (serve,
3038 (serve,
3025 [('A', 'accesslog', '', _('name of access log file to write to')),
3039 [('A', 'accesslog', '', _('name of access log file to write to')),
3026 ('d', 'daemon', None, _('run server in background')),
3040 ('d', 'daemon', None, _('run server in background')),
3027 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3041 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3028 ('E', 'errorlog', '', _('name of error log file to write to')),
3042 ('E', 'errorlog', '', _('name of error log file to write to')),
3029 ('p', 'port', 0, _('port to use (default: 8000)')),
3043 ('p', 'port', 0, _('port to use (default: 8000)')),
3030 ('a', 'address', '', _('address to use')),
3044 ('a', 'address', '', _('address to use')),
3031 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3045 ('', 'prefix', '', _('prefix path to serve from (default: server root)')),
3032 ('n', 'name', '',
3046 ('n', 'name', '',
3033 _('name to show in web pages (default: working dir)')),
3047 _('name to show in web pages (default: working dir)')),
3034 ('', 'webdir-conf', '', _('name of the webdir config file'
3048 ('', 'webdir-conf', '', _('name of the webdir config file'
3035 ' (serve more than one repo)')),
3049 ' (serve more than one repo)')),
3036 ('', 'pid-file', '', _('name of file to write process ID to')),
3050 ('', 'pid-file', '', _('name of file to write process ID to')),
3037 ('', 'stdio', None, _('for remote clients')),
3051 ('', 'stdio', None, _('for remote clients')),
3038 ('t', 'templates', '', _('web templates to use')),
3052 ('t', 'templates', '', _('web templates to use')),
3039 ('', 'style', '', _('template style to use')),
3053 ('', 'style', '', _('template style to use')),
3040 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3054 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
3041 ('', 'certificate', '', _('SSL certificate file'))],
3055 ('', 'certificate', '', _('SSL certificate file'))],
3042 _('hg serve [OPTION]...')),
3056 _('hg serve [OPTION]...')),
3043 "showconfig|debugconfig":
3057 "showconfig|debugconfig":
3044 (showconfig,
3058 (showconfig,
3045 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3059 [('u', 'untrusted', None, _('show untrusted configuration options'))],
3046 _('hg showconfig [-u] [NAME]...')),
3060 _('hg showconfig [-u] [NAME]...')),
3047 "^status|st":
3061 "^status|st":
3048 (status,
3062 (status,
3049 [('A', 'all', None, _('show status of all files')),
3063 [('A', 'all', None, _('show status of all files')),
3050 ('m', 'modified', None, _('show only modified files')),
3064 ('m', 'modified', None, _('show only modified files')),
3051 ('a', 'added', None, _('show only added files')),
3065 ('a', 'added', None, _('show only added files')),
3052 ('r', 'removed', None, _('show only removed files')),
3066 ('r', 'removed', None, _('show only removed files')),
3053 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3067 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3054 ('c', 'clean', None, _('show only files without changes')),
3068 ('c', 'clean', None, _('show only files without changes')),
3055 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3069 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3056 ('i', 'ignored', None, _('show only ignored files')),
3070 ('i', 'ignored', None, _('show only ignored files')),
3057 ('n', 'no-status', None, _('hide status prefix')),
3071 ('n', 'no-status', None, _('hide status prefix')),
3058 ('C', 'copies', None, _('show source of copied files')),
3072 ('C', 'copies', None, _('show source of copied files')),
3059 ('0', 'print0', None,
3073 ('0', 'print0', None,
3060 _('end filenames with NUL, for use with xargs')),
3074 _('end filenames with NUL, for use with xargs')),
3061 ('', 'rev', [], _('show difference from revision')),
3075 ('', 'rev', [], _('show difference from revision')),
3062 ] + walkopts,
3076 ] + walkopts,
3063 _('hg status [OPTION]... [FILE]...')),
3077 _('hg status [OPTION]... [FILE]...')),
3064 "tag":
3078 "tag":
3065 (tag,
3079 (tag,
3066 [('f', 'force', None, _('replace existing tag')),
3080 [('f', 'force', None, _('replace existing tag')),
3067 ('l', 'local', None, _('make the tag local')),
3081 ('l', 'local', None, _('make the tag local')),
3068 ('r', 'rev', '', _('revision to tag')),
3082 ('r', 'rev', '', _('revision to tag')),
3069 ('', 'remove', None, _('remove a tag')),
3083 ('', 'remove', None, _('remove a tag')),
3070 # -l/--local is already there, commitopts cannot be used
3084 # -l/--local is already there, commitopts cannot be used
3071 ('m', 'message', '', _('use <text> as commit message')),
3085 ('m', 'message', '', _('use <text> as commit message')),
3072 ] + commitopts2,
3086 ] + commitopts2,
3073 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3087 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3074 "tags": (tags, [], _('hg tags')),
3088 "tags": (tags, [], _('hg tags')),
3075 "tip":
3089 "tip":
3076 (tip,
3090 (tip,
3077 [('', 'style', '', _('display using template map file')),
3091 [('', 'style', '', _('display using template map file')),
3078 ('p', 'patch', None, _('show patch')),
3092 ('p', 'patch', None, _('show patch')),
3079 ('', 'template', '', _('display with template'))],
3093 ('', 'template', '', _('display with template'))],
3080 _('hg tip [-p]')),
3094 _('hg tip [-p]')),
3081 "unbundle":
3095 "unbundle":
3082 (unbundle,
3096 (unbundle,
3083 [('u', 'update', None,
3097 [('u', 'update', None,
3084 _('update to new tip if changesets were unbundled'))],
3098 _('update to new tip if changesets were unbundled'))],
3085 _('hg unbundle [-u] FILE...')),
3099 _('hg unbundle [-u] FILE...')),
3086 "^update|up|checkout|co":
3100 "^update|up|checkout|co":
3087 (update,
3101 (update,
3088 [('C', 'clean', None, _('overwrite locally modified files')),
3102 [('C', 'clean', None, _('overwrite locally modified files')),
3089 ('d', 'date', '', _('tipmost revision matching date')),
3103 ('d', 'date', '', _('tipmost revision matching date')),
3090 ('r', 'rev', '', _('revision'))],
3104 ('r', 'rev', '', _('revision'))],
3091 _('hg update [-C] [-d DATE] [[-r] REV]')),
3105 _('hg update [-C] [-d DATE] [[-r] REV]')),
3092 "verify": (verify, [], _('hg verify')),
3106 "verify": (verify, [], _('hg verify')),
3093 "version": (version_, [], _('hg version')),
3107 "version": (version_, [], _('hg version')),
3094 }
3108 }
3095
3109
3096 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3110 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3097 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3111 " debugindex debugindexdot debugdate debuginstall debugfsinfo")
3098 optionalrepo = ("identify paths serve showconfig")
3112 optionalrepo = ("identify paths serve showconfig")
@@ -1,83 +1,81 b''
1 %% should show b unknown
1 %% should show b unknown
2 ? b
2 ? b
3 %% should show b unknown and c modified
3 %% should show b unknown and c modified
4 M c
4 M c
5 ? b
5 ? b
6 %% should show b added and c modified
6 %% should show b added and c modified
7 M c
7 M c
8 A b
8 A b
9 %% should show a removed, b added and c modified
9 %% should show a removed, b added and c modified
10 M c
10 M c
11 A b
11 A b
12 R a
12 R a
13 %% should show b added, copy saved, and c modified
13 %% should show b added, copy saved, and c modified
14 M c
14 M c
15 A b
15 A b
16 %% should show b unknown, and c modified
16 %% should show b unknown, and c modified
17 M c
17 M c
18 ? b
18 ? b
19 %% should show unknown: b
19 %% should show unknown: b
20 ? b
20 ? b
21 %% should show a b c e
21 %% should show a b c e
22 a
22 a
23 b
23 b
24 c
24 c
25 e
25 e
26 %% should verbosely save backup to e.orig
26 %% should verbosely save backup to e.orig
27 saving current version of e as e.orig
27 saving current version of e as e.orig
28 reverting e
28 reverting e
29 resolving manifests
30 getting e
31 %% should say no changes needed
29 %% should say no changes needed
32 no changes needed to a
30 no changes needed to a
33 %% should say file not managed
31 %% should say file not managed
34 file not managed: q
32 file not managed: q
35 %% should say file not found
33 %% should say file not found
36 notfound: No such file in rev 095eacd0c0d7
34 notfound: No such file in rev 095eacd0c0d7
37 A z
35 A z
38 ? b
36 ? b
39 ? e.orig
37 ? e.orig
40 %% should add a, remove d, forget z
38 %% should add a, remove d, forget z
41 adding a
39 adding a
42 removing d
40 removing d
43 forgetting z
41 forgetting z
44 %% should forget a, undelete d
42 %% should forget a, undelete d
45 forgetting a
43 forgetting a
46 undeleting d
44 undeleting d
47 %% should silently add a
45 %% should silently add a
48 A a
46 A a
49 R d
47 R d
50 %% should silently keep d removed
48 %% should silently keep d removed
51 R d
49 R d
52 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
53 reverting c
51 reverting c
54 %% should print non-executable
52 %% should print non-executable
55 non-executable
53 non-executable
56 reverting c
54 reverting c
57 %% should print executable
55 %% should print executable
58 executable
56 executable
59 %% issue 241
57 %% issue 241
60 adding a
58 adding a
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 % should fail - no arguments
60 % should fail - no arguments
63 abort: no files or directories specified; use --all to revert the whole repo
61 abort: no files or directories specified; use --all to revert the whole repo
64 % should succeed
62 % should succeed
65 reverting a
63 reverting a
66 %% issue332
64 %% issue332
67 adding b/b
65 adding b/b
68 reverting b/b
66 reverting b/b
69 forgetting newdir/newfile
67 forgetting newdir/newfile
70 reverting b/b
68 reverting b/b
71 % reverting a rename target should revert the source
69 % reverting a rename target should revert the source
72 ? newa
70 ? newa
73 %% 4 ignored files (we will add/commit everything)
71 %% 4 ignored files (we will add/commit everything)
74 I ignored
72 I ignored
75 I ignoreddir/file
73 I ignoreddir/file
76 I ignoreddir/removed
74 I ignoreddir/removed
77 I removed
75 I removed
78 %% should revert ignored* and undelete *removed
76 %% should revert ignored* and undelete *removed
79 reverting ignored
77 reverting ignored
80 reverting ignoreddir/file
78 reverting ignoreddir/file
81 undeleting ignoreddir/removed
79 undeleting ignoreddir/removed
82 undeleting removed
80 undeleting removed
83 %% should silently revert the named files
81 %% should silently revert the named files
General Comments 0
You need to be logged in to leave comments. Login now