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