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