##// END OF EJS Templates
Fix read mode when importing patch.
Patrick Mezard -
r4646:196d90bf default
parent child Browse files
Show More
@@ -1,3012 +1,3012 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, **opts):
1209 def heads(ui, repo, **opts):
1210 """show current repository heads
1210 """show current repository heads
1211
1211
1212 Show all repository head changesets.
1212 Show all repository head changesets.
1213
1213
1214 Repository "heads" are changesets that don't have children
1214 Repository "heads" are changesets that don't have children
1215 changesets. They are where development generally takes place and
1215 changesets. They are where development generally takes place and
1216 are the usual targets for update and merge operations.
1216 are the usual targets for update and merge operations.
1217 """
1217 """
1218 if opts['rev']:
1218 if opts['rev']:
1219 heads = repo.heads(repo.lookup(opts['rev']))
1219 heads = repo.heads(repo.lookup(opts['rev']))
1220 else:
1220 else:
1221 heads = repo.heads()
1221 heads = repo.heads()
1222 displayer = cmdutil.show_changeset(ui, repo, opts)
1222 displayer = cmdutil.show_changeset(ui, repo, opts)
1223 for n in heads:
1223 for n in heads:
1224 displayer.show(changenode=n)
1224 displayer.show(changenode=n)
1225
1225
1226 def help_(ui, name=None, with_version=False):
1226 def help_(ui, name=None, with_version=False):
1227 """show help for a command, extension, or list of commands
1227 """show help for a command, extension, or list of commands
1228
1228
1229 With no arguments, print a list of commands and short help.
1229 With no arguments, print a list of commands and short help.
1230
1230
1231 Given a command name, print help for that command.
1231 Given a command name, print help for that command.
1232
1232
1233 Given an extension name, print help for that extension, and the
1233 Given an extension name, print help for that extension, and the
1234 commands it provides."""
1234 commands it provides."""
1235 option_lists = []
1235 option_lists = []
1236
1236
1237 def addglobalopts(aliases):
1237 def addglobalopts(aliases):
1238 if ui.verbose:
1238 if ui.verbose:
1239 option_lists.append((_("global options:"), globalopts))
1239 option_lists.append((_("global options:"), globalopts))
1240 if name == 'shortlist':
1240 if name == 'shortlist':
1241 option_lists.append((_('use "hg help" for the full list '
1241 option_lists.append((_('use "hg help" for the full list '
1242 'of commands'), ()))
1242 'of commands'), ()))
1243 else:
1243 else:
1244 if name == 'shortlist':
1244 if name == 'shortlist':
1245 msg = _('use "hg help" for the full list of commands '
1245 msg = _('use "hg help" for the full list of commands '
1246 'or "hg -v" for details')
1246 'or "hg -v" for details')
1247 elif aliases:
1247 elif aliases:
1248 msg = _('use "hg -v help%s" to show aliases and '
1248 msg = _('use "hg -v help%s" to show aliases and '
1249 'global options') % (name and " " + name or "")
1249 'global options') % (name and " " + name or "")
1250 else:
1250 else:
1251 msg = _('use "hg -v help %s" to show global options') % name
1251 msg = _('use "hg -v help %s" to show global options') % name
1252 option_lists.append((msg, ()))
1252 option_lists.append((msg, ()))
1253
1253
1254 def helpcmd(name):
1254 def helpcmd(name):
1255 if with_version:
1255 if with_version:
1256 version_(ui)
1256 version_(ui)
1257 ui.write('\n')
1257 ui.write('\n')
1258 aliases, i = cmdutil.findcmd(ui, name)
1258 aliases, i = cmdutil.findcmd(ui, name)
1259 # synopsis
1259 # synopsis
1260 ui.write("%s\n\n" % i[2])
1260 ui.write("%s\n\n" % i[2])
1261
1261
1262 # description
1262 # description
1263 doc = i[0].__doc__
1263 doc = i[0].__doc__
1264 if not doc:
1264 if not doc:
1265 doc = _("(No help text available)")
1265 doc = _("(No help text available)")
1266 if ui.quiet:
1266 if ui.quiet:
1267 doc = doc.splitlines(0)[0]
1267 doc = doc.splitlines(0)[0]
1268 ui.write("%s\n" % doc.rstrip())
1268 ui.write("%s\n" % doc.rstrip())
1269
1269
1270 if not ui.quiet:
1270 if not ui.quiet:
1271 # aliases
1271 # aliases
1272 if len(aliases) > 1:
1272 if len(aliases) > 1:
1273 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1273 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1274
1274
1275 # options
1275 # options
1276 if i[1]:
1276 if i[1]:
1277 option_lists.append((_("options:\n"), i[1]))
1277 option_lists.append((_("options:\n"), i[1]))
1278
1278
1279 addglobalopts(False)
1279 addglobalopts(False)
1280
1280
1281 def helplist(select=None):
1281 def helplist(select=None):
1282 h = {}
1282 h = {}
1283 cmds = {}
1283 cmds = {}
1284 for c, e in table.items():
1284 for c, e in table.items():
1285 f = c.split("|", 1)[0]
1285 f = c.split("|", 1)[0]
1286 if select and not select(f):
1286 if select and not select(f):
1287 continue
1287 continue
1288 if name == "shortlist" and not f.startswith("^"):
1288 if name == "shortlist" and not f.startswith("^"):
1289 continue
1289 continue
1290 f = f.lstrip("^")
1290 f = f.lstrip("^")
1291 if not ui.debugflag and f.startswith("debug"):
1291 if not ui.debugflag and f.startswith("debug"):
1292 continue
1292 continue
1293 doc = e[0].__doc__
1293 doc = e[0].__doc__
1294 if not doc:
1294 if not doc:
1295 doc = _("(No help text available)")
1295 doc = _("(No help text available)")
1296 h[f] = doc.splitlines(0)[0].rstrip()
1296 h[f] = doc.splitlines(0)[0].rstrip()
1297 cmds[f] = c.lstrip("^")
1297 cmds[f] = c.lstrip("^")
1298
1298
1299 fns = h.keys()
1299 fns = h.keys()
1300 fns.sort()
1300 fns.sort()
1301 m = max(map(len, fns))
1301 m = max(map(len, fns))
1302 for f in fns:
1302 for f in fns:
1303 if ui.verbose:
1303 if ui.verbose:
1304 commands = cmds[f].replace("|",", ")
1304 commands = cmds[f].replace("|",", ")
1305 ui.write(" %s:\n %s\n"%(commands, h[f]))
1305 ui.write(" %s:\n %s\n"%(commands, h[f]))
1306 else:
1306 else:
1307 ui.write(' %-*s %s\n' % (m, f, h[f]))
1307 ui.write(' %-*s %s\n' % (m, f, h[f]))
1308
1308
1309 if not ui.quiet:
1309 if not ui.quiet:
1310 addglobalopts(True)
1310 addglobalopts(True)
1311
1311
1312 def helptopic(name):
1312 def helptopic(name):
1313 v = None
1313 v = None
1314 for i in help.helptable:
1314 for i in help.helptable:
1315 l = i.split('|')
1315 l = i.split('|')
1316 if name in l:
1316 if name in l:
1317 v = i
1317 v = i
1318 header = l[-1]
1318 header = l[-1]
1319 if not v:
1319 if not v:
1320 raise cmdutil.UnknownCommand(name)
1320 raise cmdutil.UnknownCommand(name)
1321
1321
1322 # description
1322 # description
1323 doc = help.helptable[v]
1323 doc = help.helptable[v]
1324 if not doc:
1324 if not doc:
1325 doc = _("(No help text available)")
1325 doc = _("(No help text available)")
1326 if callable(doc):
1326 if callable(doc):
1327 doc = doc()
1327 doc = doc()
1328
1328
1329 ui.write("%s\n" % header)
1329 ui.write("%s\n" % header)
1330 ui.write("%s\n" % doc.rstrip())
1330 ui.write("%s\n" % doc.rstrip())
1331
1331
1332 def helpext(name):
1332 def helpext(name):
1333 try:
1333 try:
1334 mod = extensions.find(name)
1334 mod = extensions.find(name)
1335 except KeyError:
1335 except KeyError:
1336 raise cmdutil.UnknownCommand(name)
1336 raise cmdutil.UnknownCommand(name)
1337
1337
1338 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1338 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1339 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1339 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
1340 for d in doc[1:]:
1340 for d in doc[1:]:
1341 ui.write(d, '\n')
1341 ui.write(d, '\n')
1342
1342
1343 ui.status('\n')
1343 ui.status('\n')
1344
1344
1345 try:
1345 try:
1346 ct = mod.cmdtable
1346 ct = mod.cmdtable
1347 except AttributeError:
1347 except AttributeError:
1348 ui.status(_('no commands defined\n'))
1348 ui.status(_('no commands defined\n'))
1349 return
1349 return
1350
1350
1351 ui.status(_('list of commands:\n\n'))
1351 ui.status(_('list of commands:\n\n'))
1352 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1352 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
1353 helplist(modcmds.has_key)
1353 helplist(modcmds.has_key)
1354
1354
1355 if name and name != 'shortlist':
1355 if name and name != 'shortlist':
1356 i = None
1356 i = None
1357 for f in (helpcmd, helptopic, helpext):
1357 for f in (helpcmd, helptopic, helpext):
1358 try:
1358 try:
1359 f(name)
1359 f(name)
1360 i = None
1360 i = None
1361 break
1361 break
1362 except cmdutil.UnknownCommand, inst:
1362 except cmdutil.UnknownCommand, inst:
1363 i = inst
1363 i = inst
1364 if i:
1364 if i:
1365 raise i
1365 raise i
1366
1366
1367 else:
1367 else:
1368 # program name
1368 # program name
1369 if ui.verbose or with_version:
1369 if ui.verbose or with_version:
1370 version_(ui)
1370 version_(ui)
1371 else:
1371 else:
1372 ui.status(_("Mercurial Distributed SCM\n"))
1372 ui.status(_("Mercurial Distributed SCM\n"))
1373 ui.status('\n')
1373 ui.status('\n')
1374
1374
1375 # list of commands
1375 # list of commands
1376 if name == "shortlist":
1376 if name == "shortlist":
1377 ui.status(_('basic commands:\n\n'))
1377 ui.status(_('basic commands:\n\n'))
1378 else:
1378 else:
1379 ui.status(_('list of commands:\n\n'))
1379 ui.status(_('list of commands:\n\n'))
1380
1380
1381 helplist()
1381 helplist()
1382
1382
1383 # list all option lists
1383 # list all option lists
1384 opt_output = []
1384 opt_output = []
1385 for title, options in option_lists:
1385 for title, options in option_lists:
1386 opt_output.append(("\n%s" % title, None))
1386 opt_output.append(("\n%s" % title, None))
1387 for shortopt, longopt, default, desc in options:
1387 for shortopt, longopt, default, desc in options:
1388 if "DEPRECATED" in desc and not ui.verbose: continue
1388 if "DEPRECATED" in desc and not ui.verbose: continue
1389 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1389 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
1390 longopt and " --%s" % longopt),
1390 longopt and " --%s" % longopt),
1391 "%s%s" % (desc,
1391 "%s%s" % (desc,
1392 default
1392 default
1393 and _(" (default: %s)") % default
1393 and _(" (default: %s)") % default
1394 or "")))
1394 or "")))
1395
1395
1396 if opt_output:
1396 if opt_output:
1397 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1397 opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
1398 for first, second in opt_output:
1398 for first, second in opt_output:
1399 if second:
1399 if second:
1400 ui.write(" %-*s %s\n" % (opts_len, first, second))
1400 ui.write(" %-*s %s\n" % (opts_len, first, second))
1401 else:
1401 else:
1402 ui.write("%s\n" % first)
1402 ui.write("%s\n" % first)
1403
1403
1404 def identify(ui, repo):
1404 def identify(ui, repo):
1405 """print information about the working copy
1405 """print information about the working copy
1406
1406
1407 Print a short summary of the current state of the repo.
1407 Print a short summary of the current state of the repo.
1408
1408
1409 This summary identifies the repository state using one or two parent
1409 This summary identifies the repository state using one or two parent
1410 hash identifiers, followed by a "+" if there are uncommitted changes
1410 hash identifiers, followed by a "+" if there are uncommitted changes
1411 in the working directory, followed by a list of tags for this revision.
1411 in the working directory, followed by a list of tags for this revision.
1412 """
1412 """
1413 parents = [p for p in repo.dirstate.parents() if p != nullid]
1413 parents = [p for p in repo.dirstate.parents() if p != nullid]
1414 if not parents:
1414 if not parents:
1415 ui.write(_("unknown\n"))
1415 ui.write(_("unknown\n"))
1416 return
1416 return
1417
1417
1418 hexfunc = ui.debugflag and hex or short
1418 hexfunc = ui.debugflag and hex or short
1419 modified, added, removed, deleted = repo.status()[:4]
1419 modified, added, removed, deleted = repo.status()[:4]
1420 output = ["%s%s" %
1420 output = ["%s%s" %
1421 ('+'.join([hexfunc(parent) for parent in parents]),
1421 ('+'.join([hexfunc(parent) for parent in parents]),
1422 (modified or added or removed or deleted) and "+" or "")]
1422 (modified or added or removed or deleted) and "+" or "")]
1423
1423
1424 if not ui.quiet:
1424 if not ui.quiet:
1425
1425
1426 branch = util.tolocal(repo.workingctx().branch())
1426 branch = util.tolocal(repo.workingctx().branch())
1427 if branch != 'default':
1427 if branch != 'default':
1428 output.append("(%s)" % branch)
1428 output.append("(%s)" % branch)
1429
1429
1430 # multiple tags for a single parent separated by '/'
1430 # multiple tags for a single parent separated by '/'
1431 parenttags = ['/'.join(tags)
1431 parenttags = ['/'.join(tags)
1432 for tags in map(repo.nodetags, parents) if tags]
1432 for tags in map(repo.nodetags, parents) if tags]
1433 # tags for multiple parents separated by ' + '
1433 # tags for multiple parents separated by ' + '
1434 if parenttags:
1434 if parenttags:
1435 output.append(' + '.join(parenttags))
1435 output.append(' + '.join(parenttags))
1436
1436
1437 ui.write("%s\n" % ' '.join(output))
1437 ui.write("%s\n" % ' '.join(output))
1438
1438
1439 def import_(ui, repo, patch1, *patches, **opts):
1439 def import_(ui, repo, patch1, *patches, **opts):
1440 """import an ordered set of patches
1440 """import an ordered set of patches
1441
1441
1442 Import a list of patches and commit them individually.
1442 Import a list of patches and commit them individually.
1443
1443
1444 If there are outstanding changes in the working directory, import
1444 If there are outstanding changes in the working directory, import
1445 will abort unless given the -f flag.
1445 will abort unless given the -f flag.
1446
1446
1447 You can import a patch straight from a mail message. Even patches
1447 You can import a patch straight from a mail message. Even patches
1448 as attachments work (body part must be type text/plain or
1448 as attachments work (body part must be type text/plain or
1449 text/x-patch to be used). From and Subject headers of email
1449 text/x-patch to be used). From and Subject headers of email
1450 message are used as default committer and commit message. All
1450 message are used as default committer and commit message. All
1451 text/plain body parts before first diff are added to commit
1451 text/plain body parts before first diff are added to commit
1452 message.
1452 message.
1453
1453
1454 If the imported patch was generated by hg export, user and description
1454 If the imported patch was generated by hg export, user and description
1455 from patch override values from message headers and body. Values
1455 from patch override values from message headers and body. Values
1456 given on command line with -m and -u override these.
1456 given on command line with -m and -u override these.
1457
1457
1458 If --exact is specified, import will set the working directory
1458 If --exact is specified, import will set the working directory
1459 to the parent of each patch before applying it, and will abort
1459 to the parent of each patch before applying it, and will abort
1460 if the resulting changeset has a different ID than the one
1460 if the resulting changeset has a different ID than the one
1461 recorded in the patch. This may happen due to character set
1461 recorded in the patch. This may happen due to character set
1462 problems or other deficiencies in the text patch format.
1462 problems or other deficiencies in the text patch format.
1463
1463
1464 To read a patch from standard input, use patch name "-".
1464 To read a patch from standard input, use patch name "-".
1465 """
1465 """
1466 patches = (patch1,) + patches
1466 patches = (patch1,) + patches
1467
1467
1468 if opts.get('exact') or not opts['force']:
1468 if opts.get('exact') or not opts['force']:
1469 cmdutil.bail_if_changed(repo)
1469 cmdutil.bail_if_changed(repo)
1470
1470
1471 d = opts["base"]
1471 d = opts["base"]
1472 strip = opts["strip"]
1472 strip = opts["strip"]
1473
1473
1474 wlock = repo.wlock()
1474 wlock = repo.wlock()
1475 lock = repo.lock()
1475 lock = repo.lock()
1476
1476
1477 for p in patches:
1477 for p in patches:
1478 pf = os.path.join(d, p)
1478 pf = os.path.join(d, p)
1479
1479
1480 if pf == '-':
1480 if pf == '-':
1481 ui.status(_("applying patch from stdin\n"))
1481 ui.status(_("applying patch from stdin\n"))
1482 tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, sys.stdin)
1482 tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, sys.stdin)
1483 else:
1483 else:
1484 ui.status(_("applying %s\n") % p)
1484 ui.status(_("applying %s\n") % p)
1485 tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, file(pf))
1485 tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, file(pf, 'rb'))
1486
1486
1487 if tmpname is None:
1487 if tmpname is None:
1488 raise util.Abort(_('no diffs found'))
1488 raise util.Abort(_('no diffs found'))
1489
1489
1490 try:
1490 try:
1491 cmdline_message = cmdutil.logmessage(opts)
1491 cmdline_message = cmdutil.logmessage(opts)
1492 if cmdline_message:
1492 if cmdline_message:
1493 # pickup the cmdline msg
1493 # pickup the cmdline msg
1494 message = cmdline_message
1494 message = cmdline_message
1495 elif message:
1495 elif message:
1496 # pickup the patch msg
1496 # pickup the patch msg
1497 message = message.strip()
1497 message = message.strip()
1498 else:
1498 else:
1499 # launch the editor
1499 # launch the editor
1500 message = None
1500 message = None
1501 ui.debug(_('message:\n%s\n') % message)
1501 ui.debug(_('message:\n%s\n') % message)
1502
1502
1503 wp = repo.workingctx().parents()
1503 wp = repo.workingctx().parents()
1504 if opts.get('exact'):
1504 if opts.get('exact'):
1505 if not nodeid or not p1:
1505 if not nodeid or not p1:
1506 raise util.Abort(_('not a mercurial patch'))
1506 raise util.Abort(_('not a mercurial patch'))
1507 p1 = repo.lookup(p1)
1507 p1 = repo.lookup(p1)
1508 p2 = repo.lookup(p2 or hex(nullid))
1508 p2 = repo.lookup(p2 or hex(nullid))
1509
1509
1510 if p1 != wp[0].node():
1510 if p1 != wp[0].node():
1511 hg.clean(repo, p1, wlock=wlock)
1511 hg.clean(repo, p1, wlock=wlock)
1512 repo.dirstate.setparents(p1, p2)
1512 repo.dirstate.setparents(p1, p2)
1513 elif p2:
1513 elif p2:
1514 try:
1514 try:
1515 p1 = repo.lookup(p1)
1515 p1 = repo.lookup(p1)
1516 p2 = repo.lookup(p2)
1516 p2 = repo.lookup(p2)
1517 if p1 == wp[0].node():
1517 if p1 == wp[0].node():
1518 repo.dirstate.setparents(p1, p2)
1518 repo.dirstate.setparents(p1, p2)
1519 except hg.RepoError:
1519 except hg.RepoError:
1520 pass
1520 pass
1521 if opts.get('exact') or opts.get('import_branch'):
1521 if opts.get('exact') or opts.get('import_branch'):
1522 repo.dirstate.setbranch(branch or 'default')
1522 repo.dirstate.setbranch(branch or 'default')
1523
1523
1524 files = {}
1524 files = {}
1525 try:
1525 try:
1526 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1526 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1527 files=files)
1527 files=files)
1528 finally:
1528 finally:
1529 files = patch.updatedir(ui, repo, files, wlock=wlock)
1529 files = patch.updatedir(ui, repo, files, wlock=wlock)
1530 n = repo.commit(files, message, user, date, wlock=wlock, lock=lock)
1530 n = repo.commit(files, message, user, date, wlock=wlock, lock=lock)
1531 if opts.get('exact'):
1531 if opts.get('exact'):
1532 if hex(n) != nodeid:
1532 if hex(n) != nodeid:
1533 repo.rollback(wlock=wlock, lock=lock)
1533 repo.rollback(wlock=wlock, lock=lock)
1534 raise util.Abort(_('patch is damaged or loses information'))
1534 raise util.Abort(_('patch is damaged or loses information'))
1535 finally:
1535 finally:
1536 os.unlink(tmpname)
1536 os.unlink(tmpname)
1537
1537
1538 def incoming(ui, repo, source="default", **opts):
1538 def incoming(ui, repo, source="default", **opts):
1539 """show new changesets found in source
1539 """show new changesets found in source
1540
1540
1541 Show new changesets found in the specified path/URL or the default
1541 Show new changesets found in the specified path/URL or the default
1542 pull location. These are the changesets that would be pulled if a pull
1542 pull location. These are the changesets that would be pulled if a pull
1543 was requested.
1543 was requested.
1544
1544
1545 For remote repository, using --bundle avoids downloading the changesets
1545 For remote repository, using --bundle avoids downloading the changesets
1546 twice if the incoming is followed by a pull.
1546 twice if the incoming is followed by a pull.
1547
1547
1548 See pull for valid source format details.
1548 See pull for valid source format details.
1549 """
1549 """
1550 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1550 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1551 cmdutil.setremoteconfig(ui, opts)
1551 cmdutil.setremoteconfig(ui, opts)
1552
1552
1553 other = hg.repository(ui, source)
1553 other = hg.repository(ui, source)
1554 ui.status(_('comparing with %s\n') % source)
1554 ui.status(_('comparing with %s\n') % source)
1555 if revs:
1555 if revs:
1556 if 'lookup' in other.capabilities:
1556 if 'lookup' in other.capabilities:
1557 revs = [other.lookup(rev) for rev in revs]
1557 revs = [other.lookup(rev) for rev in revs]
1558 else:
1558 else:
1559 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1559 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1560 raise util.Abort(error)
1560 raise util.Abort(error)
1561 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1561 incoming = repo.findincoming(other, heads=revs, force=opts["force"])
1562 if not incoming:
1562 if not incoming:
1563 try:
1563 try:
1564 os.unlink(opts["bundle"])
1564 os.unlink(opts["bundle"])
1565 except:
1565 except:
1566 pass
1566 pass
1567 ui.status(_("no changes found\n"))
1567 ui.status(_("no changes found\n"))
1568 return 1
1568 return 1
1569
1569
1570 cleanup = None
1570 cleanup = None
1571 try:
1571 try:
1572 fname = opts["bundle"]
1572 fname = opts["bundle"]
1573 if fname or not other.local():
1573 if fname or not other.local():
1574 # create a bundle (uncompressed if other repo is not local)
1574 # create a bundle (uncompressed if other repo is not local)
1575 if revs is None:
1575 if revs is None:
1576 cg = other.changegroup(incoming, "incoming")
1576 cg = other.changegroup(incoming, "incoming")
1577 else:
1577 else:
1578 if 'changegroupsubset' not in other.capabilities:
1578 if 'changegroupsubset' not in other.capabilities:
1579 raise util.Abort(_("Partial incoming cannot be done because other repository doesn't support changegroupsubset."))
1579 raise util.Abort(_("Partial incoming cannot be done because other repository doesn't support changegroupsubset."))
1580 cg = other.changegroupsubset(incoming, revs, 'incoming')
1580 cg = other.changegroupsubset(incoming, revs, 'incoming')
1581 bundletype = other.local() and "HG10BZ" or "HG10UN"
1581 bundletype = other.local() and "HG10BZ" or "HG10UN"
1582 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1582 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
1583 # keep written bundle?
1583 # keep written bundle?
1584 if opts["bundle"]:
1584 if opts["bundle"]:
1585 cleanup = None
1585 cleanup = None
1586 if not other.local():
1586 if not other.local():
1587 # use the created uncompressed bundlerepo
1587 # use the created uncompressed bundlerepo
1588 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1588 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1589
1589
1590 o = other.changelog.nodesbetween(incoming, revs)[0]
1590 o = other.changelog.nodesbetween(incoming, revs)[0]
1591 if opts['newest_first']:
1591 if opts['newest_first']:
1592 o.reverse()
1592 o.reverse()
1593 displayer = cmdutil.show_changeset(ui, other, opts)
1593 displayer = cmdutil.show_changeset(ui, other, opts)
1594 for n in o:
1594 for n in o:
1595 parents = [p for p in other.changelog.parents(n) if p != nullid]
1595 parents = [p for p in other.changelog.parents(n) if p != nullid]
1596 if opts['no_merges'] and len(parents) == 2:
1596 if opts['no_merges'] and len(parents) == 2:
1597 continue
1597 continue
1598 displayer.show(changenode=n)
1598 displayer.show(changenode=n)
1599 finally:
1599 finally:
1600 if hasattr(other, 'close'):
1600 if hasattr(other, 'close'):
1601 other.close()
1601 other.close()
1602 if cleanup:
1602 if cleanup:
1603 os.unlink(cleanup)
1603 os.unlink(cleanup)
1604
1604
1605 def init(ui, dest=".", **opts):
1605 def init(ui, dest=".", **opts):
1606 """create a new repository in the given directory
1606 """create a new repository in the given directory
1607
1607
1608 Initialize a new repository in the given directory. If the given
1608 Initialize a new repository in the given directory. If the given
1609 directory does not exist, it is created.
1609 directory does not exist, it is created.
1610
1610
1611 If no directory is given, the current directory is used.
1611 If no directory is given, the current directory is used.
1612
1612
1613 It is possible to specify an ssh:// URL as the destination.
1613 It is possible to specify an ssh:// URL as the destination.
1614 Look at the help text for the pull command for important details
1614 Look at the help text for the pull command for important details
1615 about ssh:// URLs.
1615 about ssh:// URLs.
1616 """
1616 """
1617 cmdutil.setremoteconfig(ui, opts)
1617 cmdutil.setremoteconfig(ui, opts)
1618 hg.repository(ui, dest, create=1)
1618 hg.repository(ui, dest, create=1)
1619
1619
1620 def locate(ui, repo, *pats, **opts):
1620 def locate(ui, repo, *pats, **opts):
1621 """locate files matching specific patterns
1621 """locate files matching specific patterns
1622
1622
1623 Print all files under Mercurial control whose names match the
1623 Print all files under Mercurial control whose names match the
1624 given patterns.
1624 given patterns.
1625
1625
1626 This command searches the entire repository by default. To search
1626 This command searches the entire repository by default. To search
1627 just the current directory and its subdirectories, use "--include .".
1627 just the current directory and its subdirectories, use "--include .".
1628
1628
1629 If no patterns are given to match, this command prints all file
1629 If no patterns are given to match, this command prints all file
1630 names.
1630 names.
1631
1631
1632 If you want to feed the output of this command into the "xargs"
1632 If you want to feed the output of this command into the "xargs"
1633 command, use the "-0" option to both this command and "xargs".
1633 command, use the "-0" option to both this command and "xargs".
1634 This will avoid the problem of "xargs" treating single filenames
1634 This will avoid the problem of "xargs" treating single filenames
1635 that contain white space as multiple filenames.
1635 that contain white space as multiple filenames.
1636 """
1636 """
1637 end = opts['print0'] and '\0' or '\n'
1637 end = opts['print0'] and '\0' or '\n'
1638 rev = opts['rev']
1638 rev = opts['rev']
1639 if rev:
1639 if rev:
1640 node = repo.lookup(rev)
1640 node = repo.lookup(rev)
1641 else:
1641 else:
1642 node = None
1642 node = None
1643
1643
1644 ret = 1
1644 ret = 1
1645 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1645 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
1646 badmatch=util.always,
1646 badmatch=util.always,
1647 default='relglob'):
1647 default='relglob'):
1648 if src == 'b':
1648 if src == 'b':
1649 continue
1649 continue
1650 if not node and repo.dirstate.state(abs) == '?':
1650 if not node and repo.dirstate.state(abs) == '?':
1651 continue
1651 continue
1652 if opts['fullpath']:
1652 if opts['fullpath']:
1653 ui.write(os.path.join(repo.root, abs), end)
1653 ui.write(os.path.join(repo.root, abs), end)
1654 else:
1654 else:
1655 ui.write(((pats and rel) or abs), end)
1655 ui.write(((pats and rel) or abs), end)
1656 ret = 0
1656 ret = 0
1657
1657
1658 return ret
1658 return ret
1659
1659
1660 def log(ui, repo, *pats, **opts):
1660 def log(ui, repo, *pats, **opts):
1661 """show revision history of entire repository or files
1661 """show revision history of entire repository or files
1662
1662
1663 Print the revision history of the specified files or the entire
1663 Print the revision history of the specified files or the entire
1664 project.
1664 project.
1665
1665
1666 File history is shown without following rename or copy history of
1666 File history is shown without following rename or copy history of
1667 files. Use -f/--follow with a file name to follow history across
1667 files. Use -f/--follow with a file name to follow history across
1668 renames and copies. --follow without a file name will only show
1668 renames and copies. --follow without a file name will only show
1669 ancestors or descendants of the starting revision. --follow-first
1669 ancestors or descendants of the starting revision. --follow-first
1670 only follows the first parent of merge revisions.
1670 only follows the first parent of merge revisions.
1671
1671
1672 If no revision range is specified, the default is tip:0 unless
1672 If no revision range is specified, the default is tip:0 unless
1673 --follow is set, in which case the working directory parent is
1673 --follow is set, in which case the working directory parent is
1674 used as the starting revision.
1674 used as the starting revision.
1675
1675
1676 By default this command outputs: changeset id and hash, tags,
1676 By default this command outputs: changeset id and hash, tags,
1677 non-trivial parents, user, date and time, and a summary for each
1677 non-trivial parents, user, date and time, and a summary for each
1678 commit. When the -v/--verbose switch is used, the list of changed
1678 commit. When the -v/--verbose switch is used, the list of changed
1679 files and full commit message is shown.
1679 files and full commit message is shown.
1680
1680
1681 NOTE: log -p may generate unexpected diff output for merge
1681 NOTE: log -p may generate unexpected diff output for merge
1682 changesets, as it will compare the merge changeset against its
1682 changesets, as it will compare the merge changeset against its
1683 first parent only. Also, the files: list will only reflect files
1683 first parent only. Also, the files: list will only reflect files
1684 that are different from BOTH parents.
1684 that are different from BOTH parents.
1685
1685
1686 """
1686 """
1687
1687
1688 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1688 get = util.cachefunc(lambda r: repo.changectx(r).changeset())
1689 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1689 changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
1690
1690
1691 if opts['limit']:
1691 if opts['limit']:
1692 try:
1692 try:
1693 limit = int(opts['limit'])
1693 limit = int(opts['limit'])
1694 except ValueError:
1694 except ValueError:
1695 raise util.Abort(_('limit must be a positive integer'))
1695 raise util.Abort(_('limit must be a positive integer'))
1696 if limit <= 0: raise util.Abort(_('limit must be positive'))
1696 if limit <= 0: raise util.Abort(_('limit must be positive'))
1697 else:
1697 else:
1698 limit = sys.maxint
1698 limit = sys.maxint
1699 count = 0
1699 count = 0
1700
1700
1701 if opts['copies'] and opts['rev']:
1701 if opts['copies'] and opts['rev']:
1702 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1702 endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
1703 else:
1703 else:
1704 endrev = repo.changelog.count()
1704 endrev = repo.changelog.count()
1705 rcache = {}
1705 rcache = {}
1706 ncache = {}
1706 ncache = {}
1707 dcache = []
1707 dcache = []
1708 def getrenamed(fn, rev, man):
1708 def getrenamed(fn, rev, man):
1709 '''looks up all renames for a file (up to endrev) the first
1709 '''looks up all renames for a file (up to endrev) the first
1710 time the file is given. It indexes on the changerev and only
1710 time the file is given. It indexes on the changerev and only
1711 parses the manifest if linkrev != changerev.
1711 parses the manifest if linkrev != changerev.
1712 Returns rename info for fn at changerev rev.'''
1712 Returns rename info for fn at changerev rev.'''
1713 if fn not in rcache:
1713 if fn not in rcache:
1714 rcache[fn] = {}
1714 rcache[fn] = {}
1715 ncache[fn] = {}
1715 ncache[fn] = {}
1716 fl = repo.file(fn)
1716 fl = repo.file(fn)
1717 for i in xrange(fl.count()):
1717 for i in xrange(fl.count()):
1718 node = fl.node(i)
1718 node = fl.node(i)
1719 lr = fl.linkrev(node)
1719 lr = fl.linkrev(node)
1720 renamed = fl.renamed(node)
1720 renamed = fl.renamed(node)
1721 rcache[fn][lr] = renamed
1721 rcache[fn][lr] = renamed
1722 if renamed:
1722 if renamed:
1723 ncache[fn][node] = renamed
1723 ncache[fn][node] = renamed
1724 if lr >= endrev:
1724 if lr >= endrev:
1725 break
1725 break
1726 if rev in rcache[fn]:
1726 if rev in rcache[fn]:
1727 return rcache[fn][rev]
1727 return rcache[fn][rev]
1728 mr = repo.manifest.rev(man)
1728 mr = repo.manifest.rev(man)
1729 if repo.manifest.parentrevs(mr) != (mr - 1, nullrev):
1729 if repo.manifest.parentrevs(mr) != (mr - 1, nullrev):
1730 return ncache[fn].get(repo.manifest.find(man, fn)[0])
1730 return ncache[fn].get(repo.manifest.find(man, fn)[0])
1731 if not dcache or dcache[0] != man:
1731 if not dcache or dcache[0] != man:
1732 dcache[:] = [man, repo.manifest.readdelta(man)]
1732 dcache[:] = [man, repo.manifest.readdelta(man)]
1733 if fn in dcache[1]:
1733 if fn in dcache[1]:
1734 return ncache[fn].get(dcache[1][fn])
1734 return ncache[fn].get(dcache[1][fn])
1735 return None
1735 return None
1736
1736
1737 df = False
1737 df = False
1738 if opts["date"]:
1738 if opts["date"]:
1739 df = util.matchdate(opts["date"])
1739 df = util.matchdate(opts["date"])
1740
1740
1741 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1741 displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
1742 for st, rev, fns in changeiter:
1742 for st, rev, fns in changeiter:
1743 if st == 'add':
1743 if st == 'add':
1744 changenode = repo.changelog.node(rev)
1744 changenode = repo.changelog.node(rev)
1745 parents = [p for p in repo.changelog.parentrevs(rev)
1745 parents = [p for p in repo.changelog.parentrevs(rev)
1746 if p != nullrev]
1746 if p != nullrev]
1747 if opts['no_merges'] and len(parents) == 2:
1747 if opts['no_merges'] and len(parents) == 2:
1748 continue
1748 continue
1749 if opts['only_merges'] and len(parents) != 2:
1749 if opts['only_merges'] and len(parents) != 2:
1750 continue
1750 continue
1751
1751
1752 if df:
1752 if df:
1753 changes = get(rev)
1753 changes = get(rev)
1754 if not df(changes[2][0]):
1754 if not df(changes[2][0]):
1755 continue
1755 continue
1756
1756
1757 if opts['keyword']:
1757 if opts['keyword']:
1758 changes = get(rev)
1758 changes = get(rev)
1759 miss = 0
1759 miss = 0
1760 for k in [kw.lower() for kw in opts['keyword']]:
1760 for k in [kw.lower() for kw in opts['keyword']]:
1761 if not (k in changes[1].lower() or
1761 if not (k in changes[1].lower() or
1762 k in changes[4].lower() or
1762 k in changes[4].lower() or
1763 k in " ".join(changes[3]).lower()):
1763 k in " ".join(changes[3]).lower()):
1764 miss = 1
1764 miss = 1
1765 break
1765 break
1766 if miss:
1766 if miss:
1767 continue
1767 continue
1768
1768
1769 copies = []
1769 copies = []
1770 if opts.get('copies') and rev:
1770 if opts.get('copies') and rev:
1771 mf = get(rev)[0]
1771 mf = get(rev)[0]
1772 for fn in get(rev)[3]:
1772 for fn in get(rev)[3]:
1773 rename = getrenamed(fn, rev, mf)
1773 rename = getrenamed(fn, rev, mf)
1774 if rename:
1774 if rename:
1775 copies.append((fn, rename[0]))
1775 copies.append((fn, rename[0]))
1776 displayer.show(rev, changenode, copies=copies)
1776 displayer.show(rev, changenode, copies=copies)
1777 elif st == 'iter':
1777 elif st == 'iter':
1778 if count == limit: break
1778 if count == limit: break
1779 if displayer.flush(rev):
1779 if displayer.flush(rev):
1780 count += 1
1780 count += 1
1781
1781
1782 def manifest(ui, repo, rev=None):
1782 def manifest(ui, repo, rev=None):
1783 """output the current or given revision of the project manifest
1783 """output the current or given revision of the project manifest
1784
1784
1785 Print a list of version controlled files for the given revision.
1785 Print a list of version controlled files for the given revision.
1786 If no revision is given, the parent of the working directory is used,
1786 If no revision is given, the parent of the working directory is used,
1787 or tip if no revision is checked out.
1787 or tip if no revision is checked out.
1788
1788
1789 The manifest is the list of files being version controlled. If no revision
1789 The manifest is the list of files being version controlled. If no revision
1790 is given then the first parent of the working directory is used.
1790 is given then the first parent of the working directory is used.
1791
1791
1792 With -v flag, print file permissions. With --debug flag, print
1792 With -v flag, print file permissions. With --debug flag, print
1793 file revision hashes.
1793 file revision hashes.
1794 """
1794 """
1795
1795
1796 m = repo.changectx(rev).manifest()
1796 m = repo.changectx(rev).manifest()
1797 files = m.keys()
1797 files = m.keys()
1798 files.sort()
1798 files.sort()
1799
1799
1800 for f in files:
1800 for f in files:
1801 if ui.debugflag:
1801 if ui.debugflag:
1802 ui.write("%40s " % hex(m[f]))
1802 ui.write("%40s " % hex(m[f]))
1803 if ui.verbose:
1803 if ui.verbose:
1804 ui.write("%3s " % (m.execf(f) and "755" or "644"))
1804 ui.write("%3s " % (m.execf(f) and "755" or "644"))
1805 ui.write("%s\n" % f)
1805 ui.write("%s\n" % f)
1806
1806
1807 def merge(ui, repo, node=None, force=None, rev=None):
1807 def merge(ui, repo, node=None, force=None, rev=None):
1808 """merge working directory with another revision
1808 """merge working directory with another revision
1809
1809
1810 Merge the contents of the current working directory and the
1810 Merge the contents of the current working directory and the
1811 requested revision. Files that changed between either parent are
1811 requested revision. Files that changed between either parent are
1812 marked as changed for the next commit and a commit must be
1812 marked as changed for the next commit and a commit must be
1813 performed before any further updates are allowed.
1813 performed before any further updates are allowed.
1814
1814
1815 If no revision is specified, the working directory's parent is a
1815 If no revision is specified, the working directory's parent is a
1816 head revision, and the repository contains exactly one other head,
1816 head revision, and the repository contains exactly one other head,
1817 the other head is merged with by default. Otherwise, an explicit
1817 the other head is merged with by default. Otherwise, an explicit
1818 revision to merge with must be provided.
1818 revision to merge with must be provided.
1819 """
1819 """
1820
1820
1821 if rev and node:
1821 if rev and node:
1822 raise util.Abort(_("please specify just one revision"))
1822 raise util.Abort(_("please specify just one revision"))
1823
1823
1824 if not node:
1824 if not node:
1825 node = rev
1825 node = rev
1826
1826
1827 if not node:
1827 if not node:
1828 heads = repo.heads()
1828 heads = repo.heads()
1829 if len(heads) > 2:
1829 if len(heads) > 2:
1830 raise util.Abort(_('repo has %d heads - '
1830 raise util.Abort(_('repo has %d heads - '
1831 'please merge with an explicit rev') %
1831 'please merge with an explicit rev') %
1832 len(heads))
1832 len(heads))
1833 if len(heads) == 1:
1833 if len(heads) == 1:
1834 raise util.Abort(_('there is nothing to merge - '
1834 raise util.Abort(_('there is nothing to merge - '
1835 'use "hg update" instead'))
1835 'use "hg update" instead'))
1836 parent = repo.dirstate.parents()[0]
1836 parent = repo.dirstate.parents()[0]
1837 if parent not in heads:
1837 if parent not in heads:
1838 raise util.Abort(_('working dir not at a head rev - '
1838 raise util.Abort(_('working dir not at a head rev - '
1839 'use "hg update" or merge with an explicit rev'))
1839 'use "hg update" or merge with an explicit rev'))
1840 node = parent == heads[0] and heads[-1] or heads[0]
1840 node = parent == heads[0] and heads[-1] or heads[0]
1841 return hg.merge(repo, node, force=force)
1841 return hg.merge(repo, node, force=force)
1842
1842
1843 def outgoing(ui, repo, dest=None, **opts):
1843 def outgoing(ui, repo, dest=None, **opts):
1844 """show changesets not found in destination
1844 """show changesets not found in destination
1845
1845
1846 Show changesets not found in the specified destination repository or
1846 Show changesets not found in the specified destination repository or
1847 the default push location. These are the changesets that would be pushed
1847 the default push location. These are the changesets that would be pushed
1848 if a push was requested.
1848 if a push was requested.
1849
1849
1850 See pull for valid destination format details.
1850 See pull for valid destination format details.
1851 """
1851 """
1852 dest, revs = cmdutil.parseurl(
1852 dest, revs = cmdutil.parseurl(
1853 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1853 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1854 cmdutil.setremoteconfig(ui, opts)
1854 cmdutil.setremoteconfig(ui, opts)
1855 if revs:
1855 if revs:
1856 revs = [repo.lookup(rev) for rev in revs]
1856 revs = [repo.lookup(rev) for rev in revs]
1857
1857
1858 other = hg.repository(ui, dest)
1858 other = hg.repository(ui, dest)
1859 ui.status(_('comparing with %s\n') % dest)
1859 ui.status(_('comparing with %s\n') % dest)
1860 o = repo.findoutgoing(other, force=opts['force'])
1860 o = repo.findoutgoing(other, force=opts['force'])
1861 if not o:
1861 if not o:
1862 ui.status(_("no changes found\n"))
1862 ui.status(_("no changes found\n"))
1863 return 1
1863 return 1
1864 o = repo.changelog.nodesbetween(o, revs)[0]
1864 o = repo.changelog.nodesbetween(o, revs)[0]
1865 if opts['newest_first']:
1865 if opts['newest_first']:
1866 o.reverse()
1866 o.reverse()
1867 displayer = cmdutil.show_changeset(ui, repo, opts)
1867 displayer = cmdutil.show_changeset(ui, repo, opts)
1868 for n in o:
1868 for n in o:
1869 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1869 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1870 if opts['no_merges'] and len(parents) == 2:
1870 if opts['no_merges'] and len(parents) == 2:
1871 continue
1871 continue
1872 displayer.show(changenode=n)
1872 displayer.show(changenode=n)
1873
1873
1874 def parents(ui, repo, file_=None, **opts):
1874 def parents(ui, repo, file_=None, **opts):
1875 """show the parents of the working dir or revision
1875 """show the parents of the working dir or revision
1876
1876
1877 Print the working directory's parent revisions. If a
1877 Print the working directory's parent revisions. If a
1878 revision is given via --rev, the parent of that revision
1878 revision is given via --rev, the parent of that revision
1879 will be printed. If a file argument is given, revision in
1879 will be printed. If a file argument is given, revision in
1880 which the file was last changed (before the working directory
1880 which the file was last changed (before the working directory
1881 revision or the argument to --rev if given) is printed.
1881 revision or the argument to --rev if given) is printed.
1882 """
1882 """
1883 rev = opts.get('rev')
1883 rev = opts.get('rev')
1884 if file_:
1884 if file_:
1885 ctx = repo.filectx(file_, changeid=rev)
1885 ctx = repo.filectx(file_, changeid=rev)
1886 elif rev:
1886 elif rev:
1887 ctx = repo.changectx(rev)
1887 ctx = repo.changectx(rev)
1888 else:
1888 else:
1889 ctx = repo.workingctx()
1889 ctx = repo.workingctx()
1890 p = [cp.node() for cp in ctx.parents()]
1890 p = [cp.node() for cp in ctx.parents()]
1891
1891
1892 displayer = cmdutil.show_changeset(ui, repo, opts)
1892 displayer = cmdutil.show_changeset(ui, repo, opts)
1893 for n in p:
1893 for n in p:
1894 if n != nullid:
1894 if n != nullid:
1895 displayer.show(changenode=n)
1895 displayer.show(changenode=n)
1896
1896
1897 def paths(ui, repo, search=None):
1897 def paths(ui, repo, search=None):
1898 """show definition of symbolic path names
1898 """show definition of symbolic path names
1899
1899
1900 Show definition of symbolic path name NAME. If no name is given, show
1900 Show definition of symbolic path name NAME. If no name is given, show
1901 definition of available names.
1901 definition of available names.
1902
1902
1903 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1903 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1904 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1904 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1905 """
1905 """
1906 if search:
1906 if search:
1907 for name, path in ui.configitems("paths"):
1907 for name, path in ui.configitems("paths"):
1908 if name == search:
1908 if name == search:
1909 ui.write("%s\n" % path)
1909 ui.write("%s\n" % path)
1910 return
1910 return
1911 ui.warn(_("not found!\n"))
1911 ui.warn(_("not found!\n"))
1912 return 1
1912 return 1
1913 else:
1913 else:
1914 for name, path in ui.configitems("paths"):
1914 for name, path in ui.configitems("paths"):
1915 ui.write("%s = %s\n" % (name, path))
1915 ui.write("%s = %s\n" % (name, path))
1916
1916
1917 def postincoming(ui, repo, modheads, optupdate):
1917 def postincoming(ui, repo, modheads, optupdate):
1918 if modheads == 0:
1918 if modheads == 0:
1919 return
1919 return
1920 if optupdate:
1920 if optupdate:
1921 if modheads == 1:
1921 if modheads == 1:
1922 return hg.update(repo, repo.changelog.tip()) # update
1922 return hg.update(repo, repo.changelog.tip()) # update
1923 else:
1923 else:
1924 ui.status(_("not updating, since new heads added\n"))
1924 ui.status(_("not updating, since new heads added\n"))
1925 if modheads > 1:
1925 if modheads > 1:
1926 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1926 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
1927 else:
1927 else:
1928 ui.status(_("(run 'hg update' to get a working copy)\n"))
1928 ui.status(_("(run 'hg update' to get a working copy)\n"))
1929
1929
1930 def pull(ui, repo, source="default", **opts):
1930 def pull(ui, repo, source="default", **opts):
1931 """pull changes from the specified source
1931 """pull changes from the specified source
1932
1932
1933 Pull changes from a remote repository to a local one.
1933 Pull changes from a remote repository to a local one.
1934
1934
1935 This finds all changes from the repository at the specified path
1935 This finds all changes from the repository at the specified path
1936 or URL and adds them to the local repository. By default, this
1936 or URL and adds them to the local repository. By default, this
1937 does not update the copy of the project in the working directory.
1937 does not update the copy of the project in the working directory.
1938
1938
1939 Valid URLs are of the form:
1939 Valid URLs are of the form:
1940
1940
1941 local/filesystem/path (or file://local/filesystem/path)
1941 local/filesystem/path (or file://local/filesystem/path)
1942 http://[user@]host[:port]/[path]
1942 http://[user@]host[:port]/[path]
1943 https://[user@]host[:port]/[path]
1943 https://[user@]host[:port]/[path]
1944 ssh://[user@]host[:port]/[path]
1944 ssh://[user@]host[:port]/[path]
1945 static-http://host[:port]/[path]
1945 static-http://host[:port]/[path]
1946
1946
1947 Paths in the local filesystem can either point to Mercurial
1947 Paths in the local filesystem can either point to Mercurial
1948 repositories or to bundle files (as created by 'hg bundle' or
1948 repositories or to bundle files (as created by 'hg bundle' or
1949 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1949 'hg incoming --bundle'). The static-http:// protocol, albeit slow,
1950 allows access to a Mercurial repository where you simply use a web
1950 allows access to a Mercurial repository where you simply use a web
1951 server to publish the .hg directory as static content.
1951 server to publish the .hg directory as static content.
1952
1952
1953 An optional identifier after # indicates a particular branch, tag,
1953 An optional identifier after # indicates a particular branch, tag,
1954 or changeset to pull.
1954 or changeset to pull.
1955
1955
1956 Some notes about using SSH with Mercurial:
1956 Some notes about using SSH with Mercurial:
1957 - SSH requires an accessible shell account on the destination machine
1957 - SSH requires an accessible shell account on the destination machine
1958 and a copy of hg in the remote path or specified with as remotecmd.
1958 and a copy of hg in the remote path or specified with as remotecmd.
1959 - path is relative to the remote user's home directory by default.
1959 - path is relative to the remote user's home directory by default.
1960 Use an extra slash at the start of a path to specify an absolute path:
1960 Use an extra slash at the start of a path to specify an absolute path:
1961 ssh://example.com//tmp/repository
1961 ssh://example.com//tmp/repository
1962 - Mercurial doesn't use its own compression via SSH; the right thing
1962 - Mercurial doesn't use its own compression via SSH; the right thing
1963 to do is to configure it in your ~/.ssh/config, e.g.:
1963 to do is to configure it in your ~/.ssh/config, e.g.:
1964 Host *.mylocalnetwork.example.com
1964 Host *.mylocalnetwork.example.com
1965 Compression no
1965 Compression no
1966 Host *
1966 Host *
1967 Compression yes
1967 Compression yes
1968 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1968 Alternatively specify "ssh -C" as your ssh command in your hgrc or
1969 with the --ssh command line option.
1969 with the --ssh command line option.
1970 """
1970 """
1971 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1971 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1972 cmdutil.setremoteconfig(ui, opts)
1972 cmdutil.setremoteconfig(ui, opts)
1973
1973
1974 other = hg.repository(ui, source)
1974 other = hg.repository(ui, source)
1975 ui.status(_('pulling from %s\n') % (source))
1975 ui.status(_('pulling from %s\n') % (source))
1976 if revs:
1976 if revs:
1977 if 'lookup' in other.capabilities:
1977 if 'lookup' in other.capabilities:
1978 revs = [other.lookup(rev) for rev in revs]
1978 revs = [other.lookup(rev) for rev in revs]
1979 else:
1979 else:
1980 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1980 error = _("Other repository doesn't support revision lookup, so a rev cannot be specified.")
1981 raise util.Abort(error)
1981 raise util.Abort(error)
1982
1982
1983 modheads = repo.pull(other, heads=revs, force=opts['force'])
1983 modheads = repo.pull(other, heads=revs, force=opts['force'])
1984 return postincoming(ui, repo, modheads, opts['update'])
1984 return postincoming(ui, repo, modheads, opts['update'])
1985
1985
1986 def push(ui, repo, dest=None, **opts):
1986 def push(ui, repo, dest=None, **opts):
1987 """push changes to the specified destination
1987 """push changes to the specified destination
1988
1988
1989 Push changes from the local repository to the given destination.
1989 Push changes from the local repository to the given destination.
1990
1990
1991 This is the symmetrical operation for pull. It helps to move
1991 This is the symmetrical operation for pull. It helps to move
1992 changes from the current repository to a different one. If the
1992 changes from the current repository to a different one. If the
1993 destination is local this is identical to a pull in that directory
1993 destination is local this is identical to a pull in that directory
1994 from the current one.
1994 from the current one.
1995
1995
1996 By default, push will refuse to run if it detects the result would
1996 By default, push will refuse to run if it detects the result would
1997 increase the number of remote heads. This generally indicates the
1997 increase the number of remote heads. This generally indicates the
1998 the client has forgotten to sync and merge before pushing.
1998 the client has forgotten to sync and merge before pushing.
1999
1999
2000 Valid URLs are of the form:
2000 Valid URLs are of the form:
2001
2001
2002 local/filesystem/path (or file://local/filesystem/path)
2002 local/filesystem/path (or file://local/filesystem/path)
2003 ssh://[user@]host[:port]/[path]
2003 ssh://[user@]host[:port]/[path]
2004 http://[user@]host[:port]/[path]
2004 http://[user@]host[:port]/[path]
2005 https://[user@]host[:port]/[path]
2005 https://[user@]host[:port]/[path]
2006
2006
2007 An optional identifier after # indicates a particular branch, tag,
2007 An optional identifier after # indicates a particular branch, tag,
2008 or changeset to push.
2008 or changeset to push.
2009
2009
2010 Look at the help text for the pull command for important details
2010 Look at the help text for the pull command for important details
2011 about ssh:// URLs.
2011 about ssh:// URLs.
2012
2012
2013 Pushing to http:// and https:// URLs is only possible, if this
2013 Pushing to http:// and https:// URLs is only possible, if this
2014 feature is explicitly enabled on the remote Mercurial server.
2014 feature is explicitly enabled on the remote Mercurial server.
2015 """
2015 """
2016 dest, revs = cmdutil.parseurl(
2016 dest, revs = cmdutil.parseurl(
2017 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2017 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2018 cmdutil.setremoteconfig(ui, opts)
2018 cmdutil.setremoteconfig(ui, opts)
2019
2019
2020 other = hg.repository(ui, dest)
2020 other = hg.repository(ui, dest)
2021 ui.status('pushing to %s\n' % (dest))
2021 ui.status('pushing to %s\n' % (dest))
2022 if revs:
2022 if revs:
2023 revs = [repo.lookup(rev) for rev in revs]
2023 revs = [repo.lookup(rev) for rev in revs]
2024 r = repo.push(other, opts['force'], revs=revs)
2024 r = repo.push(other, opts['force'], revs=revs)
2025 return r == 0
2025 return r == 0
2026
2026
2027 def rawcommit(ui, repo, *pats, **opts):
2027 def rawcommit(ui, repo, *pats, **opts):
2028 """raw commit interface (DEPRECATED)
2028 """raw commit interface (DEPRECATED)
2029
2029
2030 (DEPRECATED)
2030 (DEPRECATED)
2031 Lowlevel commit, for use in helper scripts.
2031 Lowlevel commit, for use in helper scripts.
2032
2032
2033 This command is not intended to be used by normal users, as it is
2033 This command is not intended to be used by normal users, as it is
2034 primarily useful for importing from other SCMs.
2034 primarily useful for importing from other SCMs.
2035
2035
2036 This command is now deprecated and will be removed in a future
2036 This command is now deprecated and will be removed in a future
2037 release, please use debugsetparents and commit instead.
2037 release, please use debugsetparents and commit instead.
2038 """
2038 """
2039
2039
2040 ui.warn(_("(the rawcommit command is deprecated)\n"))
2040 ui.warn(_("(the rawcommit command is deprecated)\n"))
2041
2041
2042 message = cmdutil.logmessage(opts)
2042 message = cmdutil.logmessage(opts)
2043
2043
2044 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2044 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2045 if opts['files']:
2045 if opts['files']:
2046 files += open(opts['files']).read().splitlines()
2046 files += open(opts['files']).read().splitlines()
2047
2047
2048 parents = [repo.lookup(p) for p in opts['parent']]
2048 parents = [repo.lookup(p) for p in opts['parent']]
2049
2049
2050 try:
2050 try:
2051 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2051 repo.rawcommit(files, message, opts['user'], opts['date'], *parents)
2052 except ValueError, inst:
2052 except ValueError, inst:
2053 raise util.Abort(str(inst))
2053 raise util.Abort(str(inst))
2054
2054
2055 def recover(ui, repo):
2055 def recover(ui, repo):
2056 """roll back an interrupted transaction
2056 """roll back an interrupted transaction
2057
2057
2058 Recover from an interrupted commit or pull.
2058 Recover from an interrupted commit or pull.
2059
2059
2060 This command tries to fix the repository status after an interrupted
2060 This command tries to fix the repository status after an interrupted
2061 operation. It should only be necessary when Mercurial suggests it.
2061 operation. It should only be necessary when Mercurial suggests it.
2062 """
2062 """
2063 if repo.recover():
2063 if repo.recover():
2064 return hg.verify(repo)
2064 return hg.verify(repo)
2065 return 1
2065 return 1
2066
2066
2067 def remove(ui, repo, *pats, **opts):
2067 def remove(ui, repo, *pats, **opts):
2068 """remove the specified files on the next commit
2068 """remove the specified files on the next commit
2069
2069
2070 Schedule the indicated files for removal from the repository.
2070 Schedule the indicated files for removal from the repository.
2071
2071
2072 This only removes files from the current branch, not from the
2072 This only removes files from the current branch, not from the
2073 entire project history. If the files still exist in the working
2073 entire project history. If the files still exist in the working
2074 directory, they will be deleted from it. If invoked with --after,
2074 directory, they will be deleted from it. If invoked with --after,
2075 files are marked as removed, but not actually unlinked unless --force
2075 files are marked as removed, but not actually unlinked unless --force
2076 is also given. Without exact file names, --after will only mark
2076 is also given. Without exact file names, --after will only mark
2077 files as removed if they are no longer in the working directory.
2077 files as removed if they are no longer in the working directory.
2078
2078
2079 This command schedules the files to be removed at the next commit.
2079 This command schedules the files to be removed at the next commit.
2080 To undo a remove before that, see hg revert.
2080 To undo a remove before that, see hg revert.
2081
2081
2082 Modified files and added files are not removed by default. To
2082 Modified files and added files are not removed by default. To
2083 remove them, use the -f/--force option.
2083 remove them, use the -f/--force option.
2084 """
2084 """
2085 names = []
2085 names = []
2086 if not opts['after'] and not pats:
2086 if not opts['after'] and not pats:
2087 raise util.Abort(_('no files specified'))
2087 raise util.Abort(_('no files specified'))
2088 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2088 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2089 exact = dict.fromkeys(files)
2089 exact = dict.fromkeys(files)
2090 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2090 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2091 modified, added, removed, deleted, unknown = mardu
2091 modified, added, removed, deleted, unknown = mardu
2092 remove, forget = [], []
2092 remove, forget = [], []
2093 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2093 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2094 reason = None
2094 reason = None
2095 if abs in modified and not opts['force']:
2095 if abs in modified and not opts['force']:
2096 reason = _('is modified (use -f to force removal)')
2096 reason = _('is modified (use -f to force removal)')
2097 elif abs in added:
2097 elif abs in added:
2098 if opts['force']:
2098 if opts['force']:
2099 forget.append(abs)
2099 forget.append(abs)
2100 continue
2100 continue
2101 reason = _('has been marked for add (use -f to force removal)')
2101 reason = _('has been marked for add (use -f to force removal)')
2102 elif repo.dirstate.state(abs) == '?':
2102 elif repo.dirstate.state(abs) == '?':
2103 reason = _('is not managed')
2103 reason = _('is not managed')
2104 elif opts['after'] and not exact and abs not in deleted:
2104 elif opts['after'] and not exact and abs not in deleted:
2105 continue
2105 continue
2106 elif abs in removed:
2106 elif abs in removed:
2107 continue
2107 continue
2108 if reason:
2108 if reason:
2109 if exact:
2109 if exact:
2110 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2110 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2111 else:
2111 else:
2112 if ui.verbose or not exact:
2112 if ui.verbose or not exact:
2113 ui.status(_('removing %s\n') % rel)
2113 ui.status(_('removing %s\n') % rel)
2114 remove.append(abs)
2114 remove.append(abs)
2115 repo.forget(forget)
2115 repo.forget(forget)
2116 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2116 repo.remove(remove, unlink=opts['force'] or not opts['after'])
2117
2117
2118 def rename(ui, repo, *pats, **opts):
2118 def rename(ui, repo, *pats, **opts):
2119 """rename files; equivalent of copy + remove
2119 """rename files; equivalent of copy + remove
2120
2120
2121 Mark dest as copies of sources; mark sources for deletion. If
2121 Mark dest as copies of sources; mark sources for deletion. If
2122 dest is a directory, copies are put in that directory. If dest is
2122 dest is a directory, copies are put in that directory. If dest is
2123 a file, there can only be one source.
2123 a file, there can only be one source.
2124
2124
2125 By default, this command copies the contents of files as they
2125 By default, this command copies the contents of files as they
2126 stand in the working directory. If invoked with --after, the
2126 stand in the working directory. If invoked with --after, the
2127 operation is recorded, but no copying is performed.
2127 operation is recorded, but no copying is performed.
2128
2128
2129 This command takes effect in the next commit. To undo a rename
2129 This command takes effect in the next commit. To undo a rename
2130 before that, see hg revert.
2130 before that, see hg revert.
2131 """
2131 """
2132 wlock = repo.wlock(0)
2132 wlock = repo.wlock(0)
2133 errs, copied = docopy(ui, repo, pats, opts, wlock)
2133 errs, copied = docopy(ui, repo, pats, opts, wlock)
2134 names = []
2134 names = []
2135 for abs, rel, exact in copied:
2135 for abs, rel, exact in copied:
2136 if ui.verbose or not exact:
2136 if ui.verbose or not exact:
2137 ui.status(_('removing %s\n') % rel)
2137 ui.status(_('removing %s\n') % rel)
2138 names.append(abs)
2138 names.append(abs)
2139 if not opts.get('dry_run'):
2139 if not opts.get('dry_run'):
2140 repo.remove(names, True, wlock=wlock)
2140 repo.remove(names, True, wlock=wlock)
2141 return errs
2141 return errs
2142
2142
2143 def revert(ui, repo, *pats, **opts):
2143 def revert(ui, repo, *pats, **opts):
2144 """revert files or dirs to their states as of some revision
2144 """revert files or dirs to their states as of some revision
2145
2145
2146 With no revision specified, revert the named files or directories
2146 With no revision specified, revert the named files or directories
2147 to the contents they had in the parent of the working directory.
2147 to the contents they had in the parent of the working directory.
2148 This restores the contents of the affected files to an unmodified
2148 This restores the contents of the affected files to an unmodified
2149 state and unschedules adds, removes, copies, and renames. If the
2149 state and unschedules adds, removes, copies, and renames. If the
2150 working directory has two parents, you must explicitly specify the
2150 working directory has two parents, you must explicitly specify the
2151 revision to revert to.
2151 revision to revert to.
2152
2152
2153 Modified files are saved with a .orig suffix before reverting.
2153 Modified files are saved with a .orig suffix before reverting.
2154 To disable these backups, use --no-backup.
2154 To disable these backups, use --no-backup.
2155
2155
2156 Using the -r option, revert the given files or directories to their
2156 Using the -r option, revert the given files or directories to their
2157 contents as of a specific revision. This can be helpful to "roll
2157 contents as of a specific revision. This can be helpful to "roll
2158 back" some or all of a change that should not have been committed.
2158 back" some or all of a change that should not have been committed.
2159
2159
2160 Revert modifies the working directory. It does not commit any
2160 Revert modifies the working directory. It does not commit any
2161 changes, or change the parent of the working directory. If you
2161 changes, or change the parent of the working directory. If you
2162 revert to a revision other than the parent of the working
2162 revert to a revision other than the parent of the working
2163 directory, the reverted files will thus appear modified
2163 directory, the reverted files will thus appear modified
2164 afterwards.
2164 afterwards.
2165
2165
2166 If a file has been deleted, it is recreated. If the executable
2166 If a file has been deleted, it is recreated. If the executable
2167 mode of a file was changed, it is reset.
2167 mode of a file was changed, it is reset.
2168
2168
2169 If names are given, all files matching the names are reverted.
2169 If names are given, all files matching the names are reverted.
2170
2170
2171 If no arguments are given, no files are reverted.
2171 If no arguments are given, no files are reverted.
2172 """
2172 """
2173
2173
2174 if opts["date"]:
2174 if opts["date"]:
2175 if opts["rev"]:
2175 if opts["rev"]:
2176 raise util.Abort(_("you can't specify a revision and a date"))
2176 raise util.Abort(_("you can't specify a revision and a date"))
2177 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2177 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
2178
2178
2179 if not pats and not opts['all']:
2179 if not pats and not opts['all']:
2180 raise util.Abort(_('no files or directories specified; '
2180 raise util.Abort(_('no files or directories specified; '
2181 'use --all to revert the whole repo'))
2181 'use --all to revert the whole repo'))
2182
2182
2183 parent, p2 = repo.dirstate.parents()
2183 parent, p2 = repo.dirstate.parents()
2184 if not opts['rev'] and p2 != nullid:
2184 if not opts['rev'] and p2 != nullid:
2185 raise util.Abort(_('uncommitted merge - please provide a '
2185 raise util.Abort(_('uncommitted merge - please provide a '
2186 'specific revision'))
2186 'specific revision'))
2187 ctx = repo.changectx(opts['rev'])
2187 ctx = repo.changectx(opts['rev'])
2188 node = ctx.node()
2188 node = ctx.node()
2189 mf = ctx.manifest()
2189 mf = ctx.manifest()
2190 if node == parent:
2190 if node == parent:
2191 pmf = mf
2191 pmf = mf
2192 else:
2192 else:
2193 pmf = None
2193 pmf = None
2194
2194
2195 wlock = repo.wlock()
2195 wlock = repo.wlock()
2196
2196
2197 # need all matching names in dirstate and manifest of target rev,
2197 # need all matching names in dirstate and manifest of target rev,
2198 # so have to walk both. do not print errors if files exist in one
2198 # so have to walk both. do not print errors if files exist in one
2199 # but not other.
2199 # but not other.
2200
2200
2201 names = {}
2201 names = {}
2202 target_only = {}
2202 target_only = {}
2203
2203
2204 # walk dirstate.
2204 # walk dirstate.
2205
2205
2206 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2206 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
2207 badmatch=mf.has_key):
2207 badmatch=mf.has_key):
2208 names[abs] = (rel, exact)
2208 names[abs] = (rel, exact)
2209 if src == 'b':
2209 if src == 'b':
2210 target_only[abs] = True
2210 target_only[abs] = True
2211
2211
2212 # walk target manifest.
2212 # walk target manifest.
2213
2213
2214 def badmatch(path):
2214 def badmatch(path):
2215 if path in names:
2215 if path in names:
2216 return True
2216 return True
2217 path_ = path + '/'
2217 path_ = path + '/'
2218 for f in names:
2218 for f in names:
2219 if f.startswith(path_):
2219 if f.startswith(path_):
2220 return True
2220 return True
2221 return False
2221 return False
2222
2222
2223 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2223 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
2224 badmatch=badmatch):
2224 badmatch=badmatch):
2225 if abs in names or src == 'b':
2225 if abs in names or src == 'b':
2226 continue
2226 continue
2227 names[abs] = (rel, exact)
2227 names[abs] = (rel, exact)
2228 target_only[abs] = True
2228 target_only[abs] = True
2229
2229
2230 changes = repo.status(match=names.has_key, wlock=wlock)[:5]
2230 changes = repo.status(match=names.has_key, wlock=wlock)[:5]
2231 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2231 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2232
2232
2233 revert = ([], _('reverting %s\n'))
2233 revert = ([], _('reverting %s\n'))
2234 add = ([], _('adding %s\n'))
2234 add = ([], _('adding %s\n'))
2235 remove = ([], _('removing %s\n'))
2235 remove = ([], _('removing %s\n'))
2236 forget = ([], _('forgetting %s\n'))
2236 forget = ([], _('forgetting %s\n'))
2237 undelete = ([], _('undeleting %s\n'))
2237 undelete = ([], _('undeleting %s\n'))
2238 update = {}
2238 update = {}
2239
2239
2240 disptable = (
2240 disptable = (
2241 # dispatch table:
2241 # dispatch table:
2242 # file state
2242 # file state
2243 # action if in target manifest
2243 # action if in target manifest
2244 # action if not in target manifest
2244 # action if not in target manifest
2245 # make backup if in target manifest
2245 # make backup if in target manifest
2246 # make backup if not in target manifest
2246 # make backup if not in target manifest
2247 (modified, revert, remove, True, True),
2247 (modified, revert, remove, True, True),
2248 (added, revert, forget, True, False),
2248 (added, revert, forget, True, False),
2249 (removed, undelete, None, False, False),
2249 (removed, undelete, None, False, False),
2250 (deleted, revert, remove, False, False),
2250 (deleted, revert, remove, False, False),
2251 (unknown, add, None, True, False),
2251 (unknown, add, None, True, False),
2252 (target_only, add, None, False, False),
2252 (target_only, add, None, False, False),
2253 )
2253 )
2254
2254
2255 entries = names.items()
2255 entries = names.items()
2256 entries.sort()
2256 entries.sort()
2257
2257
2258 for abs, (rel, exact) in entries:
2258 for abs, (rel, exact) in entries:
2259 mfentry = mf.get(abs)
2259 mfentry = mf.get(abs)
2260 target = repo.wjoin(abs)
2260 target = repo.wjoin(abs)
2261 def handle(xlist, dobackup):
2261 def handle(xlist, dobackup):
2262 xlist[0].append(abs)
2262 xlist[0].append(abs)
2263 update[abs] = 1
2263 update[abs] = 1
2264 if dobackup and not opts['no_backup'] and util.lexists(target):
2264 if dobackup and not opts['no_backup'] and util.lexists(target):
2265 bakname = "%s.orig" % rel
2265 bakname = "%s.orig" % rel
2266 ui.note(_('saving current version of %s as %s\n') %
2266 ui.note(_('saving current version of %s as %s\n') %
2267 (rel, bakname))
2267 (rel, bakname))
2268 if not opts.get('dry_run'):
2268 if not opts.get('dry_run'):
2269 util.copyfile(target, bakname)
2269 util.copyfile(target, bakname)
2270 if ui.verbose or not exact:
2270 if ui.verbose or not exact:
2271 ui.status(xlist[1] % rel)
2271 ui.status(xlist[1] % rel)
2272 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2272 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2273 if abs not in table: continue
2273 if abs not in table: continue
2274 # file has changed in dirstate
2274 # file has changed in dirstate
2275 if mfentry:
2275 if mfentry:
2276 handle(hitlist, backuphit)
2276 handle(hitlist, backuphit)
2277 elif misslist is not None:
2277 elif misslist is not None:
2278 handle(misslist, backupmiss)
2278 handle(misslist, backupmiss)
2279 else:
2279 else:
2280 if exact: ui.warn(_('file not managed: %s\n') % rel)
2280 if exact: ui.warn(_('file not managed: %s\n') % rel)
2281 break
2281 break
2282 else:
2282 else:
2283 # file has not changed in dirstate
2283 # file has not changed in dirstate
2284 if node == parent:
2284 if node == parent:
2285 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2285 if exact: ui.warn(_('no changes needed to %s\n') % rel)
2286 continue
2286 continue
2287 if pmf is None:
2287 if pmf is None:
2288 # only need parent manifest in this unlikely case,
2288 # only need parent manifest in this unlikely case,
2289 # so do not read by default
2289 # so do not read by default
2290 pmf = repo.changectx(parent).manifest()
2290 pmf = repo.changectx(parent).manifest()
2291 if abs in pmf:
2291 if abs in pmf:
2292 if mfentry:
2292 if mfentry:
2293 # if version of file is same in parent and target
2293 # if version of file is same in parent and target
2294 # manifests, do nothing
2294 # manifests, do nothing
2295 if pmf[abs] != mfentry:
2295 if pmf[abs] != mfentry:
2296 handle(revert, False)
2296 handle(revert, False)
2297 else:
2297 else:
2298 handle(remove, False)
2298 handle(remove, False)
2299
2299
2300 if not opts.get('dry_run'):
2300 if not opts.get('dry_run'):
2301 repo.dirstate.forget(forget[0])
2301 repo.dirstate.forget(forget[0])
2302 r = hg.revert(repo, node, update.has_key, wlock)
2302 r = hg.revert(repo, node, update.has_key, wlock)
2303 repo.dirstate.update(add[0], 'a')
2303 repo.dirstate.update(add[0], 'a')
2304 repo.dirstate.update(undelete[0], 'n')
2304 repo.dirstate.update(undelete[0], 'n')
2305 repo.dirstate.update(remove[0], 'r')
2305 repo.dirstate.update(remove[0], 'r')
2306 return r
2306 return r
2307
2307
2308 def rollback(ui, repo):
2308 def rollback(ui, repo):
2309 """roll back the last transaction in this repository
2309 """roll back the last transaction in this repository
2310
2310
2311 Roll back the last transaction in this repository, restoring the
2311 Roll back the last transaction in this repository, restoring the
2312 project to its state prior to the transaction.
2312 project to its state prior to the transaction.
2313
2313
2314 Transactions are used to encapsulate the effects of all commands
2314 Transactions are used to encapsulate the effects of all commands
2315 that create new changesets or propagate existing changesets into a
2315 that create new changesets or propagate existing changesets into a
2316 repository. For example, the following commands are transactional,
2316 repository. For example, the following commands are transactional,
2317 and their effects can be rolled back:
2317 and their effects can be rolled back:
2318
2318
2319 commit
2319 commit
2320 import
2320 import
2321 pull
2321 pull
2322 push (with this repository as destination)
2322 push (with this repository as destination)
2323 unbundle
2323 unbundle
2324
2324
2325 This command should be used with care. There is only one level of
2325 This command should be used with care. There is only one level of
2326 rollback, and there is no way to undo a rollback.
2326 rollback, and there is no way to undo a rollback.
2327
2327
2328 This command is not intended for use on public repositories. Once
2328 This command is not intended for use on public repositories. Once
2329 changes are visible for pull by other users, rolling a transaction
2329 changes are visible for pull by other users, rolling a transaction
2330 back locally is ineffective (someone else may already have pulled
2330 back locally is ineffective (someone else may already have pulled
2331 the changes). Furthermore, a race is possible with readers of the
2331 the changes). Furthermore, a race is possible with readers of the
2332 repository; for example an in-progress pull from the repository
2332 repository; for example an in-progress pull from the repository
2333 may fail if a rollback is performed.
2333 may fail if a rollback is performed.
2334 """
2334 """
2335 repo.rollback()
2335 repo.rollback()
2336
2336
2337 def root(ui, repo):
2337 def root(ui, repo):
2338 """print the root (top) of the current working dir
2338 """print the root (top) of the current working dir
2339
2339
2340 Print the root directory of the current repository.
2340 Print the root directory of the current repository.
2341 """
2341 """
2342 ui.write(repo.root + "\n")
2342 ui.write(repo.root + "\n")
2343
2343
2344 def serve(ui, repo, **opts):
2344 def serve(ui, repo, **opts):
2345 """export the repository via HTTP
2345 """export the repository via HTTP
2346
2346
2347 Start a local HTTP repository browser and pull server.
2347 Start a local HTTP repository browser and pull server.
2348
2348
2349 By default, the server logs accesses to stdout and errors to
2349 By default, the server logs accesses to stdout and errors to
2350 stderr. Use the "-A" and "-E" options to log to files.
2350 stderr. Use the "-A" and "-E" options to log to files.
2351 """
2351 """
2352
2352
2353 if opts["stdio"]:
2353 if opts["stdio"]:
2354 if repo is None:
2354 if repo is None:
2355 raise hg.RepoError(_("There is no Mercurial repository here"
2355 raise hg.RepoError(_("There is no Mercurial repository here"
2356 " (.hg not found)"))
2356 " (.hg not found)"))
2357 s = sshserver.sshserver(ui, repo)
2357 s = sshserver.sshserver(ui, repo)
2358 s.serve_forever()
2358 s.serve_forever()
2359
2359
2360 parentui = ui.parentui or ui
2360 parentui = ui.parentui or ui
2361 optlist = ("name templates style address port ipv6"
2361 optlist = ("name templates style address port ipv6"
2362 " accesslog errorlog webdir_conf")
2362 " accesslog errorlog webdir_conf")
2363 for o in optlist.split():
2363 for o in optlist.split():
2364 if opts[o]:
2364 if opts[o]:
2365 parentui.setconfig("web", o, str(opts[o]))
2365 parentui.setconfig("web", o, str(opts[o]))
2366
2366
2367 if repo is None and not ui.config("web", "webdir_conf"):
2367 if repo is None and not ui.config("web", "webdir_conf"):
2368 raise hg.RepoError(_("There is no Mercurial repository here"
2368 raise hg.RepoError(_("There is no Mercurial repository here"
2369 " (.hg not found)"))
2369 " (.hg not found)"))
2370
2370
2371 class service:
2371 class service:
2372 def init(self):
2372 def init(self):
2373 try:
2373 try:
2374 self.httpd = hgweb.server.create_server(parentui, repo)
2374 self.httpd = hgweb.server.create_server(parentui, repo)
2375 except socket.error, inst:
2375 except socket.error, inst:
2376 raise util.Abort(_('cannot start server: ') + inst.args[1])
2376 raise util.Abort(_('cannot start server: ') + inst.args[1])
2377
2377
2378 if not ui.verbose: return
2378 if not ui.verbose: return
2379
2379
2380 if self.httpd.port != 80:
2380 if self.httpd.port != 80:
2381 ui.status(_('listening at http://%s:%d/\n') %
2381 ui.status(_('listening at http://%s:%d/\n') %
2382 (self.httpd.addr, self.httpd.port))
2382 (self.httpd.addr, self.httpd.port))
2383 else:
2383 else:
2384 ui.status(_('listening at http://%s/\n') % self.httpd.addr)
2384 ui.status(_('listening at http://%s/\n') % self.httpd.addr)
2385
2385
2386 def run(self):
2386 def run(self):
2387 self.httpd.serve_forever()
2387 self.httpd.serve_forever()
2388
2388
2389 service = service()
2389 service = service()
2390
2390
2391 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2391 cmdutil.service(opts, initfn=service.init, runfn=service.run)
2392
2392
2393 def status(ui, repo, *pats, **opts):
2393 def status(ui, repo, *pats, **opts):
2394 """show changed files in the working directory
2394 """show changed files in the working directory
2395
2395
2396 Show status of files in the repository. If names are given, only
2396 Show status of files in the repository. If names are given, only
2397 files that match are shown. Files that are clean or ignored, are
2397 files that match are shown. Files that are clean or ignored, are
2398 not listed unless -c (clean), -i (ignored) or -A is given.
2398 not listed unless -c (clean), -i (ignored) or -A is given.
2399
2399
2400 NOTE: status may appear to disagree with diff if permissions have
2400 NOTE: status may appear to disagree with diff if permissions have
2401 changed or a merge has occurred. The standard diff format does not
2401 changed or a merge has occurred. The standard diff format does not
2402 report permission changes and diff only reports changes relative
2402 report permission changes and diff only reports changes relative
2403 to one merge parent.
2403 to one merge parent.
2404
2404
2405 If one revision is given, it is used as the base revision.
2405 If one revision is given, it is used as the base revision.
2406 If two revisions are given, the difference between them is shown.
2406 If two revisions are given, the difference between them is shown.
2407
2407
2408 The codes used to show the status of files are:
2408 The codes used to show the status of files are:
2409 M = modified
2409 M = modified
2410 A = added
2410 A = added
2411 R = removed
2411 R = removed
2412 C = clean
2412 C = clean
2413 ! = deleted, but still tracked
2413 ! = deleted, but still tracked
2414 ? = not tracked
2414 ? = not tracked
2415 I = ignored (not shown by default)
2415 I = ignored (not shown by default)
2416 = the previous added file was copied from here
2416 = the previous added file was copied from here
2417 """
2417 """
2418
2418
2419 all = opts['all']
2419 all = opts['all']
2420 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2420 node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
2421
2421
2422 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2422 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2423 cwd = (pats and repo.getcwd()) or ''
2423 cwd = (pats and repo.getcwd()) or ''
2424 modified, added, removed, deleted, unknown, ignored, clean = [
2424 modified, added, removed, deleted, unknown, ignored, clean = [
2425 n for n in repo.status(node1=node1, node2=node2, files=files,
2425 n for n in repo.status(node1=node1, node2=node2, files=files,
2426 match=matchfn,
2426 match=matchfn,
2427 list_ignored=all or opts['ignored'],
2427 list_ignored=all or opts['ignored'],
2428 list_clean=all or opts['clean'])]
2428 list_clean=all or opts['clean'])]
2429
2429
2430 changetypes = (('modified', 'M', modified),
2430 changetypes = (('modified', 'M', modified),
2431 ('added', 'A', added),
2431 ('added', 'A', added),
2432 ('removed', 'R', removed),
2432 ('removed', 'R', removed),
2433 ('deleted', '!', deleted),
2433 ('deleted', '!', deleted),
2434 ('unknown', '?', unknown),
2434 ('unknown', '?', unknown),
2435 ('ignored', 'I', ignored))
2435 ('ignored', 'I', ignored))
2436
2436
2437 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2437 explicit_changetypes = changetypes + (('clean', 'C', clean),)
2438
2438
2439 end = opts['print0'] and '\0' or '\n'
2439 end = opts['print0'] and '\0' or '\n'
2440
2440
2441 for opt, char, changes in ([ct for ct in explicit_changetypes
2441 for opt, char, changes in ([ct for ct in explicit_changetypes
2442 if all or opts[ct[0]]]
2442 if all or opts[ct[0]]]
2443 or changetypes):
2443 or changetypes):
2444 if opts['no_status']:
2444 if opts['no_status']:
2445 format = "%%s%s" % end
2445 format = "%%s%s" % end
2446 else:
2446 else:
2447 format = "%s %%s%s" % (char, end)
2447 format = "%s %%s%s" % (char, end)
2448
2448
2449 for f in changes:
2449 for f in changes:
2450 ui.write(format % repo.pathto(f, cwd))
2450 ui.write(format % repo.pathto(f, cwd))
2451 if ((all or opts.get('copies')) and not opts.get('no_status')):
2451 if ((all or opts.get('copies')) and not opts.get('no_status')):
2452 copied = repo.dirstate.copied(f)
2452 copied = repo.dirstate.copied(f)
2453 if copied:
2453 if copied:
2454 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2454 ui.write(' %s%s' % (repo.pathto(copied, cwd), end))
2455
2455
2456 def tag(ui, repo, name, rev_=None, **opts):
2456 def tag(ui, repo, name, rev_=None, **opts):
2457 """add a tag for the current or given revision
2457 """add a tag for the current or given revision
2458
2458
2459 Name a particular revision using <name>.
2459 Name a particular revision using <name>.
2460
2460
2461 Tags are used to name particular revisions of the repository and are
2461 Tags are used to name particular revisions of the repository and are
2462 very useful to compare different revision, to go back to significant
2462 very useful to compare different revision, to go back to significant
2463 earlier versions or to mark branch points as releases, etc.
2463 earlier versions or to mark branch points as releases, etc.
2464
2464
2465 If no revision is given, the parent of the working directory is used,
2465 If no revision is given, the parent of the working directory is used,
2466 or tip if no revision is checked out.
2466 or tip if no revision is checked out.
2467
2467
2468 To facilitate version control, distribution, and merging of tags,
2468 To facilitate version control, distribution, and merging of tags,
2469 they are stored as a file named ".hgtags" which is managed
2469 they are stored as a file named ".hgtags" which is managed
2470 similarly to other project files and can be hand-edited if
2470 similarly to other project files and can be hand-edited if
2471 necessary. The file '.hg/localtags' is used for local tags (not
2471 necessary. The file '.hg/localtags' is used for local tags (not
2472 shared among repositories).
2472 shared among repositories).
2473 """
2473 """
2474 if name in ['tip', '.', 'null']:
2474 if name in ['tip', '.', 'null']:
2475 raise util.Abort(_("the name '%s' is reserved") % name)
2475 raise util.Abort(_("the name '%s' is reserved") % name)
2476 if rev_ is not None:
2476 if rev_ is not None:
2477 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2477 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2478 "please use 'hg tag [-r REV] NAME' instead\n"))
2478 "please use 'hg tag [-r REV] NAME' instead\n"))
2479 if opts['rev']:
2479 if opts['rev']:
2480 raise util.Abort(_("use only one form to specify the revision"))
2480 raise util.Abort(_("use only one form to specify the revision"))
2481 if opts['rev'] and opts['remove']:
2481 if opts['rev'] and opts['remove']:
2482 raise util.Abort(_("--rev and --remove are incompatible"))
2482 raise util.Abort(_("--rev and --remove are incompatible"))
2483 if opts['rev']:
2483 if opts['rev']:
2484 rev_ = opts['rev']
2484 rev_ = opts['rev']
2485 message = opts['message']
2485 message = opts['message']
2486 if opts['remove']:
2486 if opts['remove']:
2487 rev_ = nullid
2487 rev_ = nullid
2488 if not message:
2488 if not message:
2489 message = _('Removed tag %s') % name
2489 message = _('Removed tag %s') % name
2490 elif name in repo.tags() and not opts['force']:
2490 elif name in repo.tags() and not opts['force']:
2491 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2491 raise util.Abort(_('a tag named %s already exists (use -f to force)')
2492 % name)
2492 % name)
2493 if not rev_ and repo.dirstate.parents()[1] != nullid:
2493 if not rev_ and repo.dirstate.parents()[1] != nullid:
2494 raise util.Abort(_('uncommitted merge - please provide a '
2494 raise util.Abort(_('uncommitted merge - please provide a '
2495 'specific revision'))
2495 'specific revision'))
2496 r = repo.changectx(rev_).node()
2496 r = repo.changectx(rev_).node()
2497
2497
2498 if not message:
2498 if not message:
2499 message = _('Added tag %s for changeset %s') % (name, short(r))
2499 message = _('Added tag %s for changeset %s') % (name, short(r))
2500
2500
2501 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2501 repo.tag(name, r, message, opts['local'], opts['user'], opts['date'])
2502
2502
2503 def tags(ui, repo):
2503 def tags(ui, repo):
2504 """list repository tags
2504 """list repository tags
2505
2505
2506 List the repository tags.
2506 List the repository tags.
2507
2507
2508 This lists both regular and local tags.
2508 This lists both regular and local tags.
2509 """
2509 """
2510
2510
2511 l = repo.tagslist()
2511 l = repo.tagslist()
2512 l.reverse()
2512 l.reverse()
2513 hexfunc = ui.debugflag and hex or short
2513 hexfunc = ui.debugflag and hex or short
2514 for t, n in l:
2514 for t, n in l:
2515 try:
2515 try:
2516 hn = hexfunc(n)
2516 hn = hexfunc(n)
2517 r = "%5d:%s" % (repo.changelog.rev(n), hexfunc(n))
2517 r = "%5d:%s" % (repo.changelog.rev(n), hexfunc(n))
2518 except revlog.LookupError:
2518 except revlog.LookupError:
2519 r = " ?:%s" % hn
2519 r = " ?:%s" % hn
2520 if ui.quiet:
2520 if ui.quiet:
2521 ui.write("%s\n" % t)
2521 ui.write("%s\n" % t)
2522 else:
2522 else:
2523 spaces = " " * (30 - util.locallen(t))
2523 spaces = " " * (30 - util.locallen(t))
2524 ui.write("%s%s %s\n" % (t, spaces, r))
2524 ui.write("%s%s %s\n" % (t, spaces, r))
2525
2525
2526 def tip(ui, repo, **opts):
2526 def tip(ui, repo, **opts):
2527 """show the tip revision
2527 """show the tip revision
2528
2528
2529 Show the tip revision.
2529 Show the tip revision.
2530 """
2530 """
2531 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2531 cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
2532
2532
2533 def unbundle(ui, repo, fname, **opts):
2533 def unbundle(ui, repo, fname, **opts):
2534 """apply a changegroup file
2534 """apply a changegroup file
2535
2535
2536 Apply a compressed changegroup file generated by the bundle
2536 Apply a compressed changegroup file generated by the bundle
2537 command.
2537 command.
2538 """
2538 """
2539 if os.path.exists(fname):
2539 if os.path.exists(fname):
2540 f = open(fname, "rb")
2540 f = open(fname, "rb")
2541 else:
2541 else:
2542 f = urllib.urlopen(fname)
2542 f = urllib.urlopen(fname)
2543 gen = changegroup.readbundle(f, fname)
2543 gen = changegroup.readbundle(f, fname)
2544 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2544 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2545 return postincoming(ui, repo, modheads, opts['update'])
2545 return postincoming(ui, repo, modheads, opts['update'])
2546
2546
2547 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2547 def update(ui, repo, node=None, rev=None, clean=False, date=None):
2548 """update working directory
2548 """update working directory
2549
2549
2550 Update the working directory to the specified revision, or the
2550 Update the working directory to the specified revision, or the
2551 tip of the current branch if none is specified.
2551 tip of the current branch if none is specified.
2552
2552
2553 If there are no outstanding changes in the working directory and
2553 If there are no outstanding changes in the working directory and
2554 there is a linear relationship between the current version and the
2554 there is a linear relationship between the current version and the
2555 requested version, the result is the requested version.
2555 requested version, the result is the requested version.
2556
2556
2557 To merge the working directory with another revision, use the
2557 To merge the working directory with another revision, use the
2558 merge command.
2558 merge command.
2559
2559
2560 By default, update will refuse to run if doing so would require
2560 By default, update will refuse to run if doing so would require
2561 discarding local changes.
2561 discarding local changes.
2562 """
2562 """
2563 if rev and node:
2563 if rev and node:
2564 raise util.Abort(_("please specify just one revision"))
2564 raise util.Abort(_("please specify just one revision"))
2565
2565
2566 if not rev:
2566 if not rev:
2567 rev = node
2567 rev = node
2568
2568
2569 if date:
2569 if date:
2570 if rev:
2570 if rev:
2571 raise util.Abort(_("you can't specify a revision and a date"))
2571 raise util.Abort(_("you can't specify a revision and a date"))
2572 rev = cmdutil.finddate(ui, repo, date)
2572 rev = cmdutil.finddate(ui, repo, date)
2573
2573
2574 if clean:
2574 if clean:
2575 return hg.clean(repo, rev)
2575 return hg.clean(repo, rev)
2576 else:
2576 else:
2577 return hg.update(repo, rev)
2577 return hg.update(repo, rev)
2578
2578
2579 def verify(ui, repo):
2579 def verify(ui, repo):
2580 """verify the integrity of the repository
2580 """verify the integrity of the repository
2581
2581
2582 Verify the integrity of the current repository.
2582 Verify the integrity of the current repository.
2583
2583
2584 This will perform an extensive check of the repository's
2584 This will perform an extensive check of the repository's
2585 integrity, validating the hashes and checksums of each entry in
2585 integrity, validating the hashes and checksums of each entry in
2586 the changelog, manifest, and tracked files, as well as the
2586 the changelog, manifest, and tracked files, as well as the
2587 integrity of their crosslinks and indices.
2587 integrity of their crosslinks and indices.
2588 """
2588 """
2589 return hg.verify(repo)
2589 return hg.verify(repo)
2590
2590
2591 def version_(ui):
2591 def version_(ui):
2592 """output version and copyright information"""
2592 """output version and copyright information"""
2593 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2593 ui.write(_("Mercurial Distributed SCM (version %s)\n")
2594 % version.get_version())
2594 % version.get_version())
2595 ui.status(_(
2595 ui.status(_(
2596 "\nCopyright (C) 2005-2007 Matt Mackall <mpm@selenic.com> and others\n"
2596 "\nCopyright (C) 2005-2007 Matt Mackall <mpm@selenic.com> and others\n"
2597 "This is free software; see the source for copying conditions. "
2597 "This is free software; see the source for copying conditions. "
2598 "There is NO\nwarranty; "
2598 "There is NO\nwarranty; "
2599 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2599 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
2600 ))
2600 ))
2601
2601
2602 # Command options and aliases are listed here, alphabetically
2602 # Command options and aliases are listed here, alphabetically
2603
2603
2604 globalopts = [
2604 globalopts = [
2605 ('R', 'repository', '',
2605 ('R', 'repository', '',
2606 _('repository root directory or symbolic path name')),
2606 _('repository root directory or symbolic path name')),
2607 ('', 'cwd', '', _('change working directory')),
2607 ('', 'cwd', '', _('change working directory')),
2608 ('y', 'noninteractive', None,
2608 ('y', 'noninteractive', None,
2609 _('do not prompt, assume \'yes\' for any required answers')),
2609 _('do not prompt, assume \'yes\' for any required answers')),
2610 ('q', 'quiet', None, _('suppress output')),
2610 ('q', 'quiet', None, _('suppress output')),
2611 ('v', 'verbose', None, _('enable additional output')),
2611 ('v', 'verbose', None, _('enable additional output')),
2612 ('', 'config', [], _('set/override config option')),
2612 ('', 'config', [], _('set/override config option')),
2613 ('', 'debug', None, _('enable debugging output')),
2613 ('', 'debug', None, _('enable debugging output')),
2614 ('', 'debugger', None, _('start debugger')),
2614 ('', 'debugger', None, _('start debugger')),
2615 ('', 'encoding', util._encoding, _('set the charset encoding')),
2615 ('', 'encoding', util._encoding, _('set the charset encoding')),
2616 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2616 ('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
2617 ('', 'lsprof', None, _('print improved command execution profile')),
2617 ('', 'lsprof', None, _('print improved command execution profile')),
2618 ('', 'traceback', None, _('print traceback on exception')),
2618 ('', 'traceback', None, _('print traceback on exception')),
2619 ('', 'time', None, _('time how long the command takes')),
2619 ('', 'time', None, _('time how long the command takes')),
2620 ('', 'profile', None, _('print command execution profile')),
2620 ('', 'profile', None, _('print command execution profile')),
2621 ('', 'version', None, _('output version information and exit')),
2621 ('', 'version', None, _('output version information and exit')),
2622 ('h', 'help', None, _('display help and exit')),
2622 ('h', 'help', None, _('display help and exit')),
2623 ]
2623 ]
2624
2624
2625 dryrunopts = [('n', 'dry-run', None,
2625 dryrunopts = [('n', 'dry-run', None,
2626 _('do not perform actions, just print output'))]
2626 _('do not perform actions, just print output'))]
2627
2627
2628 remoteopts = [
2628 remoteopts = [
2629 ('e', 'ssh', '', _('specify ssh command to use')),
2629 ('e', 'ssh', '', _('specify ssh command to use')),
2630 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2630 ('', 'remotecmd', '', _('specify hg command to run on the remote side')),
2631 ]
2631 ]
2632
2632
2633 walkopts = [
2633 walkopts = [
2634 ('I', 'include', [], _('include names matching the given patterns')),
2634 ('I', 'include', [], _('include names matching the given patterns')),
2635 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2635 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2636 ]
2636 ]
2637
2637
2638 commitopts = [
2638 commitopts = [
2639 ('m', 'message', '', _('use <text> as commit message')),
2639 ('m', 'message', '', _('use <text> as commit message')),
2640 ('l', 'logfile', '', _('read commit message from <file>')),
2640 ('l', 'logfile', '', _('read commit message from <file>')),
2641 ]
2641 ]
2642
2642
2643 table = {
2643 table = {
2644 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2644 "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
2645 "addremove":
2645 "addremove":
2646 (addremove,
2646 (addremove,
2647 [('s', 'similarity', '',
2647 [('s', 'similarity', '',
2648 _('guess renamed files by similarity (0<=s<=100)')),
2648 _('guess renamed files by similarity (0<=s<=100)')),
2649 ] + walkopts + dryrunopts,
2649 ] + walkopts + dryrunopts,
2650 _('hg addremove [OPTION]... [FILE]...')),
2650 _('hg addremove [OPTION]... [FILE]...')),
2651 "^annotate":
2651 "^annotate":
2652 (annotate,
2652 (annotate,
2653 [('r', 'rev', '', _('annotate the specified revision')),
2653 [('r', 'rev', '', _('annotate the specified revision')),
2654 ('f', 'follow', None, _('follow file copies and renames')),
2654 ('f', 'follow', None, _('follow file copies and renames')),
2655 ('a', 'text', None, _('treat all files as text')),
2655 ('a', 'text', None, _('treat all files as text')),
2656 ('u', 'user', None, _('list the author')),
2656 ('u', 'user', None, _('list the author')),
2657 ('d', 'date', None, _('list the date')),
2657 ('d', 'date', None, _('list the date')),
2658 ('n', 'number', None, _('list the revision number (default)')),
2658 ('n', 'number', None, _('list the revision number (default)')),
2659 ('c', 'changeset', None, _('list the changeset')),
2659 ('c', 'changeset', None, _('list the changeset')),
2660 ] + walkopts,
2660 ] + walkopts,
2661 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] FILE...')),
2661 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] FILE...')),
2662 "archive":
2662 "archive":
2663 (archive,
2663 (archive,
2664 [('', 'no-decode', None, _('do not pass files through decoders')),
2664 [('', 'no-decode', None, _('do not pass files through decoders')),
2665 ('p', 'prefix', '', _('directory prefix for files in archive')),
2665 ('p', 'prefix', '', _('directory prefix for files in archive')),
2666 ('r', 'rev', '', _('revision to distribute')),
2666 ('r', 'rev', '', _('revision to distribute')),
2667 ('t', 'type', '', _('type of distribution to create')),
2667 ('t', 'type', '', _('type of distribution to create')),
2668 ] + walkopts,
2668 ] + walkopts,
2669 _('hg archive [OPTION]... DEST')),
2669 _('hg archive [OPTION]... DEST')),
2670 "backout":
2670 "backout":
2671 (backout,
2671 (backout,
2672 [('', 'merge', None,
2672 [('', 'merge', None,
2673 _('merge with old dirstate parent after backout')),
2673 _('merge with old dirstate parent after backout')),
2674 ('d', 'date', '', _('record datecode as commit date')),
2674 ('d', 'date', '', _('record datecode as commit date')),
2675 ('', 'parent', '', _('parent to choose when backing out merge')),
2675 ('', 'parent', '', _('parent to choose when backing out merge')),
2676 ('u', 'user', '', _('record user as committer')),
2676 ('u', 'user', '', _('record user as committer')),
2677 ('r', 'rev', '', _('revision to backout')),
2677 ('r', 'rev', '', _('revision to backout')),
2678 ] + walkopts + commitopts,
2678 ] + walkopts + commitopts,
2679 _('hg backout [OPTION]... [-r] REV')),
2679 _('hg backout [OPTION]... [-r] REV')),
2680 "branch": (branch,
2680 "branch": (branch,
2681 [('f', 'force', None,
2681 [('f', 'force', None,
2682 _('set branch name even if it shadows an existing branch'))],
2682 _('set branch name even if it shadows an existing branch'))],
2683 _('hg branch [NAME]')),
2683 _('hg branch [NAME]')),
2684 "branches": (branches, [], _('hg branches')),
2684 "branches": (branches, [], _('hg branches')),
2685 "bundle":
2685 "bundle":
2686 (bundle,
2686 (bundle,
2687 [('f', 'force', None,
2687 [('f', 'force', None,
2688 _('run even when remote repository is unrelated')),
2688 _('run even when remote repository is unrelated')),
2689 ('r', 'rev', [],
2689 ('r', 'rev', [],
2690 _('a changeset you would like to bundle')),
2690 _('a changeset you would like to bundle')),
2691 ('', 'base', [],
2691 ('', 'base', [],
2692 _('a base changeset to specify instead of a destination')),
2692 _('a base changeset to specify instead of a destination')),
2693 ] + remoteopts,
2693 ] + remoteopts,
2694 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2694 _('hg bundle [-f] [-r REV]... [--base REV]... FILE [DEST]')),
2695 "cat":
2695 "cat":
2696 (cat,
2696 (cat,
2697 [('o', 'output', '', _('print output to file with formatted name')),
2697 [('o', 'output', '', _('print output to file with formatted name')),
2698 ('r', 'rev', '', _('print the given revision')),
2698 ('r', 'rev', '', _('print the given revision')),
2699 ] + walkopts,
2699 ] + walkopts,
2700 _('hg cat [OPTION]... FILE...')),
2700 _('hg cat [OPTION]... FILE...')),
2701 "^clone":
2701 "^clone":
2702 (clone,
2702 (clone,
2703 [('U', 'noupdate', None, _('do not update the new working directory')),
2703 [('U', 'noupdate', None, _('do not update the new working directory')),
2704 ('r', 'rev', [],
2704 ('r', 'rev', [],
2705 _('a changeset you would like to have after cloning')),
2705 _('a changeset you would like to have after cloning')),
2706 ('', 'pull', None, _('use pull protocol to copy metadata')),
2706 ('', 'pull', None, _('use pull protocol to copy metadata')),
2707 ('', 'uncompressed', None,
2707 ('', 'uncompressed', None,
2708 _('use uncompressed transfer (fast over LAN)')),
2708 _('use uncompressed transfer (fast over LAN)')),
2709 ] + remoteopts,
2709 ] + remoteopts,
2710 _('hg clone [OPTION]... SOURCE [DEST]')),
2710 _('hg clone [OPTION]... SOURCE [DEST]')),
2711 "^commit|ci":
2711 "^commit|ci":
2712 (commit,
2712 (commit,
2713 [('A', 'addremove', None,
2713 [('A', 'addremove', None,
2714 _('mark new/missing files as added/removed before committing')),
2714 _('mark new/missing files as added/removed before committing')),
2715 ('d', 'date', '', _('record datecode as commit date')),
2715 ('d', 'date', '', _('record datecode as commit date')),
2716 ('u', 'user', '', _('record user as commiter')),
2716 ('u', 'user', '', _('record user as commiter')),
2717 ] + walkopts + commitopts,
2717 ] + walkopts + commitopts,
2718 _('hg commit [OPTION]... [FILE]...')),
2718 _('hg commit [OPTION]... [FILE]...')),
2719 "copy|cp":
2719 "copy|cp":
2720 (copy,
2720 (copy,
2721 [('A', 'after', None, _('record a copy that has already occurred')),
2721 [('A', 'after', None, _('record a copy that has already occurred')),
2722 ('f', 'force', None,
2722 ('f', 'force', None,
2723 _('forcibly copy over an existing managed file')),
2723 _('forcibly copy over an existing managed file')),
2724 ] + walkopts + dryrunopts,
2724 ] + walkopts + dryrunopts,
2725 _('hg copy [OPTION]... [SOURCE]... DEST')),
2725 _('hg copy [OPTION]... [SOURCE]... DEST')),
2726 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2726 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2727 "debugcomplete":
2727 "debugcomplete":
2728 (debugcomplete,
2728 (debugcomplete,
2729 [('o', 'options', None, _('show the command options'))],
2729 [('o', 'options', None, _('show the command options'))],
2730 _('debugcomplete [-o] CMD')),
2730 _('debugcomplete [-o] CMD')),
2731 "debuginstall": (debuginstall, [], _('debuginstall')),
2731 "debuginstall": (debuginstall, [], _('debuginstall')),
2732 "debugrebuildstate":
2732 "debugrebuildstate":
2733 (debugrebuildstate,
2733 (debugrebuildstate,
2734 [('r', 'rev', '', _('revision to rebuild to'))],
2734 [('r', 'rev', '', _('revision to rebuild to'))],
2735 _('debugrebuildstate [-r REV] [REV]')),
2735 _('debugrebuildstate [-r REV] [REV]')),
2736 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2736 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2737 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2737 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2738 "debugstate": (debugstate, [], _('debugstate')),
2738 "debugstate": (debugstate, [], _('debugstate')),
2739 "debugdate":
2739 "debugdate":
2740 (debugdate,
2740 (debugdate,
2741 [('e', 'extended', None, _('try extended date formats'))],
2741 [('e', 'extended', None, _('try extended date formats'))],
2742 _('debugdate [-e] DATE [RANGE]')),
2742 _('debugdate [-e] DATE [RANGE]')),
2743 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2743 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2744 "debugindex": (debugindex, [], _('debugindex FILE')),
2744 "debugindex": (debugindex, [], _('debugindex FILE')),
2745 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2745 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2746 "debugrename": (debugrename,
2746 "debugrename": (debugrename,
2747 [('r', 'rev', '', _('revision to debug'))],
2747 [('r', 'rev', '', _('revision to debug'))],
2748 _('debugrename [-r REV] FILE')),
2748 _('debugrename [-r REV] FILE')),
2749 "debugwalk": (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')),
2749 "debugwalk": (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')),
2750 "^diff":
2750 "^diff":
2751 (diff,
2751 (diff,
2752 [('r', 'rev', [], _('revision')),
2752 [('r', 'rev', [], _('revision')),
2753 ('a', 'text', None, _('treat all files as text')),
2753 ('a', 'text', None, _('treat all files as text')),
2754 ('p', 'show-function', None,
2754 ('p', 'show-function', None,
2755 _('show which function each change is in')),
2755 _('show which function each change is in')),
2756 ('g', 'git', None, _('use git extended diff format')),
2756 ('g', 'git', None, _('use git extended diff format')),
2757 ('', 'nodates', None, _("don't include dates in diff headers")),
2757 ('', 'nodates', None, _("don't include dates in diff headers")),
2758 ('w', 'ignore-all-space', None,
2758 ('w', 'ignore-all-space', None,
2759 _('ignore white space when comparing lines')),
2759 _('ignore white space when comparing lines')),
2760 ('b', 'ignore-space-change', None,
2760 ('b', 'ignore-space-change', None,
2761 _('ignore changes in the amount of white space')),
2761 _('ignore changes in the amount of white space')),
2762 ('B', 'ignore-blank-lines', None,
2762 ('B', 'ignore-blank-lines', None,
2763 _('ignore changes whose lines are all blank')),
2763 _('ignore changes whose lines are all blank')),
2764 ] + walkopts,
2764 ] + walkopts,
2765 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2765 _('hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...')),
2766 "^export":
2766 "^export":
2767 (export,
2767 (export,
2768 [('o', 'output', '', _('print output to file with formatted name')),
2768 [('o', 'output', '', _('print output to file with formatted name')),
2769 ('a', 'text', None, _('treat all files as text')),
2769 ('a', 'text', None, _('treat all files as text')),
2770 ('g', 'git', None, _('use git extended diff format')),
2770 ('g', 'git', None, _('use git extended diff format')),
2771 ('', 'nodates', None, _("don't include dates in diff headers")),
2771 ('', 'nodates', None, _("don't include dates in diff headers")),
2772 ('', 'switch-parent', None, _('diff against the second parent'))],
2772 ('', 'switch-parent', None, _('diff against the second parent'))],
2773 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2773 _('hg export [OPTION]... [-o OUTFILESPEC] REV...')),
2774 "grep":
2774 "grep":
2775 (grep,
2775 (grep,
2776 [('0', 'print0', None, _('end fields with NUL')),
2776 [('0', 'print0', None, _('end fields with NUL')),
2777 ('', 'all', None, _('print all revisions that match')),
2777 ('', 'all', None, _('print all revisions that match')),
2778 ('f', 'follow', None,
2778 ('f', 'follow', None,
2779 _('follow changeset history, or file history across copies and renames')),
2779 _('follow changeset history, or file history across copies and renames')),
2780 ('i', 'ignore-case', None, _('ignore case when matching')),
2780 ('i', 'ignore-case', None, _('ignore case when matching')),
2781 ('l', 'files-with-matches', None,
2781 ('l', 'files-with-matches', None,
2782 _('print only filenames and revs that match')),
2782 _('print only filenames and revs that match')),
2783 ('n', 'line-number', None, _('print matching line numbers')),
2783 ('n', 'line-number', None, _('print matching line numbers')),
2784 ('r', 'rev', [], _('search in given revision range')),
2784 ('r', 'rev', [], _('search in given revision range')),
2785 ('u', 'user', None, _('print user who committed change')),
2785 ('u', 'user', None, _('print user who committed change')),
2786 ] + walkopts,
2786 ] + walkopts,
2787 _('hg grep [OPTION]... PATTERN [FILE]...')),
2787 _('hg grep [OPTION]... PATTERN [FILE]...')),
2788 "heads":
2788 "heads":
2789 (heads,
2789 (heads,
2790 [('', 'style', '', _('display using template map file')),
2790 [('', 'style', '', _('display using template map file')),
2791 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2791 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2792 ('', 'template', '', _('display with template'))],
2792 ('', 'template', '', _('display with template'))],
2793 _('hg heads [-r REV]')),
2793 _('hg heads [-r REV]')),
2794 "help": (help_, [], _('hg help [COMMAND]')),
2794 "help": (help_, [], _('hg help [COMMAND]')),
2795 "identify|id": (identify, [], _('hg identify')),
2795 "identify|id": (identify, [], _('hg identify')),
2796 "import|patch":
2796 "import|patch":
2797 (import_,
2797 (import_,
2798 [('p', 'strip', 1,
2798 [('p', 'strip', 1,
2799 _('directory strip option for patch. This has the same\n'
2799 _('directory strip option for patch. This has the same\n'
2800 'meaning as the corresponding patch option')),
2800 'meaning as the corresponding patch option')),
2801 ('b', 'base', '', _('base path')),
2801 ('b', 'base', '', _('base path')),
2802 ('f', 'force', None,
2802 ('f', 'force', None,
2803 _('skip check for outstanding uncommitted changes')),
2803 _('skip check for outstanding uncommitted changes')),
2804 ('', 'exact', None,
2804 ('', 'exact', None,
2805 _('apply patch to the nodes from which it was generated')),
2805 _('apply patch to the nodes from which it was generated')),
2806 ('', 'import-branch', None,
2806 ('', 'import-branch', None,
2807 _('Use any branch information in patch (implied by --exact)'))] + commitopts,
2807 _('Use any branch information in patch (implied by --exact)'))] + commitopts,
2808 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')),
2808 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')),
2809 "incoming|in": (incoming,
2809 "incoming|in": (incoming,
2810 [('M', 'no-merges', None, _('do not show merges')),
2810 [('M', 'no-merges', None, _('do not show merges')),
2811 ('f', 'force', None,
2811 ('f', 'force', None,
2812 _('run even when remote repository is unrelated')),
2812 _('run even when remote repository is unrelated')),
2813 ('', 'style', '', _('display using template map file')),
2813 ('', 'style', '', _('display using template map file')),
2814 ('n', 'newest-first', None, _('show newest record first')),
2814 ('n', 'newest-first', None, _('show newest record first')),
2815 ('', 'bundle', '', _('file to store the bundles into')),
2815 ('', 'bundle', '', _('file to store the bundles into')),
2816 ('p', 'patch', None, _('show patch')),
2816 ('p', 'patch', None, _('show patch')),
2817 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2817 ('r', 'rev', [], _('a specific revision up to which you would like to pull')),
2818 ('', 'template', '', _('display with template')),
2818 ('', 'template', '', _('display with template')),
2819 ] + remoteopts,
2819 ] + remoteopts,
2820 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2820 _('hg incoming [-p] [-n] [-M] [-f] [-r REV]...'
2821 ' [--bundle FILENAME] [SOURCE]')),
2821 ' [--bundle FILENAME] [SOURCE]')),
2822 "^init":
2822 "^init":
2823 (init,
2823 (init,
2824 remoteopts,
2824 remoteopts,
2825 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2825 _('hg init [-e CMD] [--remotecmd CMD] [DEST]')),
2826 "locate":
2826 "locate":
2827 (locate,
2827 (locate,
2828 [('r', 'rev', '', _('search the repository as it stood at rev')),
2828 [('r', 'rev', '', _('search the repository as it stood at rev')),
2829 ('0', 'print0', None,
2829 ('0', 'print0', None,
2830 _('end filenames with NUL, for use with xargs')),
2830 _('end filenames with NUL, for use with xargs')),
2831 ('f', 'fullpath', None,
2831 ('f', 'fullpath', None,
2832 _('print complete paths from the filesystem root')),
2832 _('print complete paths from the filesystem root')),
2833 ] + walkopts,
2833 ] + walkopts,
2834 _('hg locate [OPTION]... [PATTERN]...')),
2834 _('hg locate [OPTION]... [PATTERN]...')),
2835 "^log|history":
2835 "^log|history":
2836 (log,
2836 (log,
2837 [('f', 'follow', None,
2837 [('f', 'follow', None,
2838 _('follow changeset history, or file history across copies and renames')),
2838 _('follow changeset history, or file history across copies and renames')),
2839 ('', 'follow-first', None,
2839 ('', 'follow-first', None,
2840 _('only follow the first parent of merge changesets')),
2840 _('only follow the first parent of merge changesets')),
2841 ('d', 'date', '', _('show revs matching date spec')),
2841 ('d', 'date', '', _('show revs matching date spec')),
2842 ('C', 'copies', None, _('show copied files')),
2842 ('C', 'copies', None, _('show copied files')),
2843 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2843 ('k', 'keyword', [], _('do case-insensitive search for a keyword')),
2844 ('l', 'limit', '', _('limit number of changes displayed')),
2844 ('l', 'limit', '', _('limit number of changes displayed')),
2845 ('r', 'rev', [], _('show the specified revision or range')),
2845 ('r', 'rev', [], _('show the specified revision or range')),
2846 ('', 'removed', None, _('include revs where files were removed')),
2846 ('', 'removed', None, _('include revs where files were removed')),
2847 ('M', 'no-merges', None, _('do not show merges')),
2847 ('M', 'no-merges', None, _('do not show merges')),
2848 ('', 'style', '', _('display using template map file')),
2848 ('', 'style', '', _('display using template map file')),
2849 ('m', 'only-merges', None, _('show only merges')),
2849 ('m', 'only-merges', None, _('show only merges')),
2850 ('p', 'patch', None, _('show patch')),
2850 ('p', 'patch', None, _('show patch')),
2851 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2851 ('P', 'prune', [], _('do not display revision or any of its ancestors')),
2852 ('', 'template', '', _('display with template')),
2852 ('', 'template', '', _('display with template')),
2853 ] + walkopts,
2853 ] + walkopts,
2854 _('hg log [OPTION]... [FILE]')),
2854 _('hg log [OPTION]... [FILE]')),
2855 "manifest": (manifest, [], _('hg manifest [REV]')),
2855 "manifest": (manifest, [], _('hg manifest [REV]')),
2856 "^merge":
2856 "^merge":
2857 (merge,
2857 (merge,
2858 [('f', 'force', None, _('force a merge with outstanding changes')),
2858 [('f', 'force', None, _('force a merge with outstanding changes')),
2859 ('r', 'rev', '', _('revision to merge')),
2859 ('r', 'rev', '', _('revision to merge')),
2860 ],
2860 ],
2861 _('hg merge [-f] [[-r] REV]')),
2861 _('hg merge [-f] [[-r] REV]')),
2862 "outgoing|out": (outgoing,
2862 "outgoing|out": (outgoing,
2863 [('M', 'no-merges', None, _('do not show merges')),
2863 [('M', 'no-merges', None, _('do not show merges')),
2864 ('f', 'force', None,
2864 ('f', 'force', None,
2865 _('run even when remote repository is unrelated')),
2865 _('run even when remote repository is unrelated')),
2866 ('p', 'patch', None, _('show patch')),
2866 ('p', 'patch', None, _('show patch')),
2867 ('', 'style', '', _('display using template map file')),
2867 ('', 'style', '', _('display using template map file')),
2868 ('r', 'rev', [], _('a specific revision you would like to push')),
2868 ('r', 'rev', [], _('a specific revision you would like to push')),
2869 ('n', 'newest-first', None, _('show newest record first')),
2869 ('n', 'newest-first', None, _('show newest record first')),
2870 ('', 'template', '', _('display with template')),
2870 ('', 'template', '', _('display with template')),
2871 ] + remoteopts,
2871 ] + remoteopts,
2872 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2872 _('hg outgoing [-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
2873 "^parents":
2873 "^parents":
2874 (parents,
2874 (parents,
2875 [('r', 'rev', '', _('show parents from the specified rev')),
2875 [('r', 'rev', '', _('show parents from the specified rev')),
2876 ('', 'style', '', _('display using template map file')),
2876 ('', 'style', '', _('display using template map file')),
2877 ('', 'template', '', _('display with template'))],
2877 ('', 'template', '', _('display with template'))],
2878 _('hg parents [-r REV] [FILE]')),
2878 _('hg parents [-r REV] [FILE]')),
2879 "paths": (paths, [], _('hg paths [NAME]')),
2879 "paths": (paths, [], _('hg paths [NAME]')),
2880 "^pull":
2880 "^pull":
2881 (pull,
2881 (pull,
2882 [('u', 'update', None,
2882 [('u', 'update', None,
2883 _('update to new tip if changesets were pulled')),
2883 _('update to new tip if changesets were pulled')),
2884 ('f', 'force', None,
2884 ('f', 'force', None,
2885 _('run even when remote repository is unrelated')),
2885 _('run even when remote repository is unrelated')),
2886 ('r', 'rev', [],
2886 ('r', 'rev', [],
2887 _('a specific revision up to which you would like to pull')),
2887 _('a specific revision up to which you would like to pull')),
2888 ] + remoteopts,
2888 ] + remoteopts,
2889 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2889 _('hg pull [-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
2890 "^push":
2890 "^push":
2891 (push,
2891 (push,
2892 [('f', 'force', None, _('force push')),
2892 [('f', 'force', None, _('force push')),
2893 ('r', 'rev', [], _('a specific revision you would like to push')),
2893 ('r', 'rev', [], _('a specific revision you would like to push')),
2894 ] + remoteopts,
2894 ] + remoteopts,
2895 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2895 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
2896 "debugrawcommit|rawcommit":
2896 "debugrawcommit|rawcommit":
2897 (rawcommit,
2897 (rawcommit,
2898 [('p', 'parent', [], _('parent')),
2898 [('p', 'parent', [], _('parent')),
2899 ('d', 'date', '', _('date code')),
2899 ('d', 'date', '', _('date code')),
2900 ('u', 'user', '', _('user')),
2900 ('u', 'user', '', _('user')),
2901 ('F', 'files', '', _('file list'))
2901 ('F', 'files', '', _('file list'))
2902 ] + commitopts,
2902 ] + commitopts,
2903 _('hg debugrawcommit [OPTION]... [FILE]...')),
2903 _('hg debugrawcommit [OPTION]... [FILE]...')),
2904 "recover": (recover, [], _('hg recover')),
2904 "recover": (recover, [], _('hg recover')),
2905 "^remove|rm":
2905 "^remove|rm":
2906 (remove,
2906 (remove,
2907 [('A', 'after', None, _('record remove that has already occurred')),
2907 [('A', 'after', None, _('record remove that has already occurred')),
2908 ('f', 'force', None, _('remove file even if modified')),
2908 ('f', 'force', None, _('remove file even if modified')),
2909 ] + walkopts,
2909 ] + walkopts,
2910 _('hg remove [OPTION]... FILE...')),
2910 _('hg remove [OPTION]... FILE...')),
2911 "rename|mv":
2911 "rename|mv":
2912 (rename,
2912 (rename,
2913 [('A', 'after', None, _('record a rename that has already occurred')),
2913 [('A', 'after', None, _('record a rename that has already occurred')),
2914 ('f', 'force', None,
2914 ('f', 'force', None,
2915 _('forcibly copy over an existing managed file')),
2915 _('forcibly copy over an existing managed file')),
2916 ] + walkopts + dryrunopts,
2916 ] + walkopts + dryrunopts,
2917 _('hg rename [OPTION]... SOURCE... DEST')),
2917 _('hg rename [OPTION]... SOURCE... DEST')),
2918 "^revert":
2918 "^revert":
2919 (revert,
2919 (revert,
2920 [('a', 'all', None, _('revert all changes when no arguments given')),
2920 [('a', 'all', None, _('revert all changes when no arguments given')),
2921 ('d', 'date', '', _('tipmost revision matching date')),
2921 ('d', 'date', '', _('tipmost revision matching date')),
2922 ('r', 'rev', '', _('revision to revert to')),
2922 ('r', 'rev', '', _('revision to revert to')),
2923 ('', 'no-backup', None, _('do not save backup copies of files')),
2923 ('', 'no-backup', None, _('do not save backup copies of files')),
2924 ] + walkopts + dryrunopts,
2924 ] + walkopts + dryrunopts,
2925 _('hg revert [OPTION]... [-r REV] [NAME]...')),
2925 _('hg revert [OPTION]... [-r REV] [NAME]...')),
2926 "rollback": (rollback, [], _('hg rollback')),
2926 "rollback": (rollback, [], _('hg rollback')),
2927 "root": (root, [], _('hg root')),
2927 "root": (root, [], _('hg root')),
2928 "showconfig|debugconfig":
2928 "showconfig|debugconfig":
2929 (showconfig,
2929 (showconfig,
2930 [('u', 'untrusted', None, _('show untrusted configuration options'))],
2930 [('u', 'untrusted', None, _('show untrusted configuration options'))],
2931 _('showconfig [-u] [NAME]...')),
2931 _('showconfig [-u] [NAME]...')),
2932 "^serve":
2932 "^serve":
2933 (serve,
2933 (serve,
2934 [('A', 'accesslog', '', _('name of access log file to write to')),
2934 [('A', 'accesslog', '', _('name of access log file to write to')),
2935 ('d', 'daemon', None, _('run server in background')),
2935 ('d', 'daemon', None, _('run server in background')),
2936 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
2936 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
2937 ('E', 'errorlog', '', _('name of error log file to write to')),
2937 ('E', 'errorlog', '', _('name of error log file to write to')),
2938 ('p', 'port', 0, _('port to use (default: 8000)')),
2938 ('p', 'port', 0, _('port to use (default: 8000)')),
2939 ('a', 'address', '', _('address to use')),
2939 ('a', 'address', '', _('address to use')),
2940 ('n', 'name', '',
2940 ('n', 'name', '',
2941 _('name to show in web pages (default: working dir)')),
2941 _('name to show in web pages (default: working dir)')),
2942 ('', 'webdir-conf', '', _('name of the webdir config file'
2942 ('', 'webdir-conf', '', _('name of the webdir config file'
2943 ' (serve more than one repo)')),
2943 ' (serve more than one repo)')),
2944 ('', 'pid-file', '', _('name of file to write process ID to')),
2944 ('', 'pid-file', '', _('name of file to write process ID to')),
2945 ('', 'stdio', None, _('for remote clients')),
2945 ('', 'stdio', None, _('for remote clients')),
2946 ('t', 'templates', '', _('web templates to use')),
2946 ('t', 'templates', '', _('web templates to use')),
2947 ('', 'style', '', _('template style to use')),
2947 ('', 'style', '', _('template style to use')),
2948 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2948 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2949 _('hg serve [OPTION]...')),
2949 _('hg serve [OPTION]...')),
2950 "^status|st":
2950 "^status|st":
2951 (status,
2951 (status,
2952 [('A', 'all', None, _('show status of all files')),
2952 [('A', 'all', None, _('show status of all files')),
2953 ('m', 'modified', None, _('show only modified files')),
2953 ('m', 'modified', None, _('show only modified files')),
2954 ('a', 'added', None, _('show only added files')),
2954 ('a', 'added', None, _('show only added files')),
2955 ('r', 'removed', None, _('show only removed files')),
2955 ('r', 'removed', None, _('show only removed files')),
2956 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
2956 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
2957 ('c', 'clean', None, _('show only files without changes')),
2957 ('c', 'clean', None, _('show only files without changes')),
2958 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2958 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2959 ('i', 'ignored', None, _('show only ignored files')),
2959 ('i', 'ignored', None, _('show only ignored files')),
2960 ('n', 'no-status', None, _('hide status prefix')),
2960 ('n', 'no-status', None, _('hide status prefix')),
2961 ('C', 'copies', None, _('show source of copied files')),
2961 ('C', 'copies', None, _('show source of copied files')),
2962 ('0', 'print0', None,
2962 ('0', 'print0', None,
2963 _('end filenames with NUL, for use with xargs')),
2963 _('end filenames with NUL, for use with xargs')),
2964 ('', 'rev', [], _('show difference from revision')),
2964 ('', 'rev', [], _('show difference from revision')),
2965 ] + walkopts,
2965 ] + walkopts,
2966 _('hg status [OPTION]... [FILE]...')),
2966 _('hg status [OPTION]... [FILE]...')),
2967 "tag":
2967 "tag":
2968 (tag,
2968 (tag,
2969 [('f', 'force', None, _('replace existing tag')),
2969 [('f', 'force', None, _('replace existing tag')),
2970 ('l', 'local', None, _('make the tag local')),
2970 ('l', 'local', None, _('make the tag local')),
2971 ('m', 'message', '', _('message for tag commit log entry')),
2971 ('m', 'message', '', _('message for tag commit log entry')),
2972 ('d', 'date', '', _('record datecode as commit date')),
2972 ('d', 'date', '', _('record datecode as commit date')),
2973 ('u', 'user', '', _('record user as commiter')),
2973 ('u', 'user', '', _('record user as commiter')),
2974 ('r', 'rev', '', _('revision to tag')),
2974 ('r', 'rev', '', _('revision to tag')),
2975 ('', 'remove', None, _('remove a tag'))],
2975 ('', 'remove', None, _('remove a tag'))],
2976 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
2976 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
2977 "tags": (tags, [], _('hg tags')),
2977 "tags": (tags, [], _('hg tags')),
2978 "tip":
2978 "tip":
2979 (tip,
2979 (tip,
2980 [('', 'style', '', _('display using template map file')),
2980 [('', 'style', '', _('display using template map file')),
2981 ('p', 'patch', None, _('show patch')),
2981 ('p', 'patch', None, _('show patch')),
2982 ('', 'template', '', _('display with template'))],
2982 ('', 'template', '', _('display with template'))],
2983 _('hg tip [-p]')),
2983 _('hg tip [-p]')),
2984 "unbundle":
2984 "unbundle":
2985 (unbundle,
2985 (unbundle,
2986 [('u', 'update', None,
2986 [('u', 'update', None,
2987 _('update to new tip if changesets were unbundled'))],
2987 _('update to new tip if changesets were unbundled'))],
2988 _('hg unbundle [-u] FILE')),
2988 _('hg unbundle [-u] FILE')),
2989 "^update|up|checkout|co":
2989 "^update|up|checkout|co":
2990 (update,
2990 (update,
2991 [('C', 'clean', None, _('overwrite locally modified files')),
2991 [('C', 'clean', None, _('overwrite locally modified files')),
2992 ('d', 'date', '', _('tipmost revision matching date')),
2992 ('d', 'date', '', _('tipmost revision matching date')),
2993 ('r', 'rev', '', _('revision'))],
2993 ('r', 'rev', '', _('revision'))],
2994 _('hg update [-C] [-d DATE] [[-r] REV]')),
2994 _('hg update [-C] [-d DATE] [[-r] REV]')),
2995 "verify": (verify, [], _('hg verify')),
2995 "verify": (verify, [], _('hg verify')),
2996 "version": (version_, [], _('hg version')),
2996 "version": (version_, [], _('hg version')),
2997 }
2997 }
2998
2998
2999 norepo = ("clone init version help debugancestor debugcomplete debugdata"
2999 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3000 " debugindex debugindexdot debugdate debuginstall")
3000 " debugindex debugindexdot debugdate debuginstall")
3001 optionalrepo = ("paths serve showconfig")
3001 optionalrepo = ("paths serve showconfig")
3002
3002
3003 def dispatch(args):
3003 def dispatch(args):
3004 try:
3004 try:
3005 u = ui.ui(traceback='--traceback' in args)
3005 u = ui.ui(traceback='--traceback' in args)
3006 except util.Abort, inst:
3006 except util.Abort, inst:
3007 sys.stderr.write(_("abort: %s\n") % inst)
3007 sys.stderr.write(_("abort: %s\n") % inst)
3008 return -1
3008 return -1
3009 return cmdutil.runcatch(u, args)
3009 return cmdutil.runcatch(u, args)
3010
3010
3011 def run():
3011 def run():
3012 sys.exit(dispatch(sys.argv[1:]))
3012 sys.exit(dispatch(sys.argv[1:]))
General Comments 0
You need to be logged in to leave comments. Login now