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