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