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