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