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