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