##// END OF EJS Templates
help: use a full header for topic titles...
Dan Villiom Podlaski Christiansen -
r18748:6e676fb6 default
parent child Browse files
Show More
@@ -1,168 +1,156
1 1 import os, sys, textwrap
2 2 # import from the live mercurial repo
3 3 sys.path.insert(0, "..")
4 4 # fall back to pure modules if required C extensions are not available
5 5 sys.path.append(os.path.join('..', 'mercurial', 'pure'))
6 6 from mercurial import demandimport; demandimport.enable()
7 7 from mercurial import encoding
8 from mercurial import minirst
8 9 from mercurial.commands import table, globalopts
9 10 from mercurial.i18n import _
10 11 from mercurial.help import helptable
11 12 from mercurial import extensions
12 13 from mercurial import util
13 14
14 15 def get_desc(docstr):
15 16 if not docstr:
16 17 return "", ""
17 18 # sanitize
18 19 docstr = docstr.strip("\n")
19 20 docstr = docstr.rstrip()
20 21 shortdesc = docstr.splitlines()[0].strip()
21 22
22 23 i = docstr.find("\n")
23 24 if i != -1:
24 25 desc = docstr[i + 2:]
25 26 else:
26 27 desc = shortdesc
27 28
28 29 desc = textwrap.dedent(desc)
29 30
30 31 return (shortdesc, desc)
31 32
32 33 def get_opts(opts):
33 34 for opt in opts:
34 35 if len(opt) == 5:
35 36 shortopt, longopt, default, desc, optlabel = opt
36 37 else:
37 38 shortopt, longopt, default, desc = opt
38 39 allopts = []
39 40 if shortopt:
40 41 allopts.append("-%s" % shortopt)
41 42 if longopt:
42 43 allopts.append("--%s" % longopt)
43 44 desc += default and _(" (default: %s)") % default or ""
44 45 yield (", ".join(allopts), desc)
45 46
46 47 def get_cmd(cmd, cmdtable):
47 48 d = {}
48 49 attr = cmdtable[cmd]
49 50 cmds = cmd.lstrip("^").split("|")
50 51
51 52 d['cmd'] = cmds[0]
52 53 d['aliases'] = cmd.split("|")[1:]
53 54 d['desc'] = get_desc(attr[0].__doc__)
54 55 d['opts'] = list(get_opts(attr[1]))
55 56
56 57 s = 'hg ' + cmds[0]
57 58 if len(attr) > 2:
58 59 if not attr[2].startswith('hg'):
59 60 s += ' ' + attr[2]
60 61 else:
61 62 s = attr[2]
62 63 d['synopsis'] = s.strip()
63 64
64 65 return d
65 66
66 def section(ui, s):
67 ui.write("%s\n%s\n\n" % (s, "\"" * encoding.colwidth(s)))
68
69 def subsection(ui, s):
70 ui.write("%s\n%s\n\n" % (s, '=' * encoding.colwidth(s)))
71
72 def subsubsection(ui, s):
73 ui.write("%s\n%s\n\n" % (s, "-" * encoding.colwidth(s)))
74
75 def subsubsubsection(ui, s):
76 ui.write("%s\n%s\n\n" % (s, "." * encoding.colwidth(s)))
77
78
79 67 def show_doc(ui):
80 68 # print options
81 section(ui, _("Options"))
69 ui.write(minirst.section(_("Options")))
82 70 for optstr, desc in get_opts(globalopts):
83 71 ui.write("%s\n %s\n\n" % (optstr, desc))
84 72
85 73 # print cmds
86 section(ui, _("Commands"))
87 commandprinter(ui, table, subsection)
74 ui.write(minirst.section(_("Commands")))
75 commandprinter(ui, table, minirst.subsection)
88 76
89 77 # print topics
90 78 for names, sec, doc in helptable:
91 79 if names[0] == "config":
92 80 # The config help topic is included in the hgrc.5 man
93 81 # page.
94 82 continue
95 83 for name in names:
96 84 ui.write(".. _%s:\n" % name)
97 85 ui.write("\n")
98 section(ui, sec)
86 ui.write(minirst.section(sec))
99 87 if util.safehasattr(doc, '__call__'):
100 88 doc = doc()
101 89 ui.write(doc)
102 90 ui.write("\n")
103 91
104 section(ui, _("Extensions"))
92 ui.write(minirst.section(_("Extensions")))
105 93 ui.write(_("This section contains help for extensions that are "
106 94 "distributed together with Mercurial. Help for other "
107 95 "extensions is available in the help system."))
108 96 ui.write("\n\n"
109 97 ".. contents::\n"
110 98 " :class: htmlonly\n"
111 99 " :local:\n"
112 100 " :depth: 1\n\n")
113 101
114 102 for extensionname in sorted(allextensionnames()):
115 103 mod = extensions.load(None, extensionname, None)
116 subsection(ui, extensionname)
104 ui.write(minirst.subsection(extensionname))
117 105 ui.write("%s\n\n" % mod.__doc__)
118 106 cmdtable = getattr(mod, 'cmdtable', None)
119 107 if cmdtable:
120 subsubsection(ui, _('Commands'))
121 commandprinter(ui, cmdtable, subsubsubsection)
108 ui.write(minirst.subsubsection(_('Commands')))
109 commandprinter(ui, cmdtable, minirst.subsubsubsection)
122 110
123 111 def commandprinter(ui, cmdtable, sectionfunc):
124 112 h = {}
125 113 for c, attr in cmdtable.items():
126 114 f = c.split("|")[0]
127 115 f = f.lstrip("^")
128 116 h[f] = c
129 117 cmds = h.keys()
130 118 cmds.sort()
131 119
132 120 for f in cmds:
133 121 if f.startswith("debug"):
134 122 continue
135 123 d = get_cmd(h[f], cmdtable)
136 sectionfunc(ui, d['cmd'])
124 ui.write(sectionfunc(d['cmd']))
137 125 # synopsis
138 126 ui.write("::\n\n")
139 127 synopsislines = d['synopsis'].splitlines()
140 128 for line in synopsislines:
141 129 # some commands (such as rebase) have a multi-line
142 130 # synopsis
143 131 ui.write(" %s\n" % line)
144 132 ui.write('\n')
145 133 # description
146 134 ui.write("%s\n\n" % d['desc'][1])
147 135 # options
148 136 opt_output = list(d['opts'])
149 137 if opt_output:
150 138 opts_len = max([len(line[0]) for line in opt_output])
151 139 ui.write(_("Options:\n\n"))
152 140 for optstr, desc in opt_output:
153 141 if desc:
154 142 s = "%-*s %s" % (opts_len, optstr, desc)
155 143 else:
156 144 s = optstr
157 145 ui.write("%s\n" % s)
158 146 ui.write("\n")
159 147 # aliases
160 148 if d['aliases']:
161 149 ui.write(_(" aliases: %s\n\n") % " ".join(d['aliases']))
162 150
163 151
164 152 def allextensionnames():
165 153 return extensions.enabled().keys() + extensions.disabled().keys()
166 154
167 155 if __name__ == "__main__":
168 156 show_doc(sys.stdout)
@@ -1,503 +1,504
1 1 # help.py - help data for mercurial
2 2 #
3 3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from i18n import gettext, _
9 9 import itertools, sys, os, error
10 10 import extensions, revset, fileset, templatekw, templatefilters, filemerge
11 11 import encoding, util, minirst
12 12 import cmdutil
13 13
14 14 def listexts(header, exts, indent=1):
15 15 '''return a text listing of the given extensions'''
16 16 rst = []
17 17 if exts:
18 18 rst.append('\n%s\n\n' % header)
19 19 for name, desc in sorted(exts.iteritems()):
20 20 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
21 21 return rst
22 22
23 23 def extshelp():
24 24 rst = loaddoc('extensions')().splitlines(True)
25 25 rst.extend(listexts(_('enabled extensions:'), extensions.enabled()))
26 26 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
27 27 doc = ''.join(rst)
28 28 return doc
29 29
30 30 def optrst(options, verbose):
31 31 data = []
32 32 multioccur = False
33 33 for option in options:
34 34 if len(option) == 5:
35 35 shortopt, longopt, default, desc, optlabel = option
36 36 else:
37 37 shortopt, longopt, default, desc = option
38 38 optlabel = _("VALUE") # default label
39 39
40 40 if _("DEPRECATED") in desc and not verbose:
41 41 continue
42 42
43 43 so = ''
44 44 if shortopt:
45 45 so = '-' + shortopt
46 46 lo = '--' + longopt
47 47 if default:
48 48 desc += _(" (default: %s)") % default
49 49
50 50 if isinstance(default, list):
51 51 lo += " %s [+]" % optlabel
52 52 multioccur = True
53 53 elif (default is not None) and not isinstance(default, bool):
54 54 lo += " %s" % optlabel
55 55
56 56 data.append((so, lo, desc))
57 57
58 58 rst = minirst.maketable(data, 1)
59 59
60 60 if multioccur:
61 61 rst.append(_("\n[+] marked option can be specified multiple times\n"))
62 62
63 63 return ''.join(rst)
64 64
65 65 def indicateomitted(rst, omitted, notomitted=None):
66 66 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
67 67 if notomitted:
68 68 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
69 69
70 70 def topicmatch(kw):
71 71 """Return help topics matching kw.
72 72
73 73 Returns {'section': [(name, summary), ...], ...} where section is
74 74 one of topics, commands, extensions, or extensioncommands.
75 75 """
76 76 kw = encoding.lower(kw)
77 77 def lowercontains(container):
78 78 return kw in encoding.lower(container) # translated in helptable
79 79 results = {'topics': [],
80 80 'commands': [],
81 81 'extensions': [],
82 82 'extensioncommands': [],
83 83 }
84 84 for names, header, doc in helptable:
85 85 if (sum(map(lowercontains, names))
86 86 or lowercontains(header)
87 87 or lowercontains(doc())):
88 88 results['topics'].append((names[0], header))
89 89 import commands # avoid cycle
90 90 for cmd, entry in commands.table.iteritems():
91 91 if cmd.startswith('debug'):
92 92 continue
93 93 if len(entry) == 3:
94 94 summary = entry[2]
95 95 else:
96 96 summary = ''
97 97 # translate docs *before* searching there
98 98 docs = _(getattr(entry[0], '__doc__', None)) or ''
99 99 if kw in cmd or lowercontains(summary) or lowercontains(docs):
100 100 doclines = docs.splitlines()
101 101 if doclines:
102 102 summary = doclines[0]
103 103 cmdname = cmd.split('|')[0].lstrip('^')
104 104 results['commands'].append((cmdname, summary))
105 105 for name, docs in itertools.chain(
106 106 extensions.enabled().iteritems(),
107 107 extensions.disabled().iteritems()):
108 108 # extensions.load ignores the UI argument
109 109 mod = extensions.load(None, name, '')
110 110 if lowercontains(name) or lowercontains(docs):
111 111 # extension docs are already translated
112 112 results['extensions'].append((name, docs.splitlines()[0]))
113 113 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
114 114 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
115 115 cmdname = cmd.split('|')[0].lstrip('^')
116 116 if entry[0].__doc__:
117 117 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
118 118 else:
119 119 cmddoc = _('(no help text available)')
120 120 results['extensioncommands'].append((cmdname, cmddoc))
121 121 return results
122 122
123 123 def loaddoc(topic):
124 124 """Return a delayed loader for help/topic.txt."""
125 125
126 126 def loader():
127 127 if util.mainfrozen():
128 128 module = sys.executable
129 129 else:
130 130 module = __file__
131 131 base = os.path.dirname(module)
132 132
133 133 for dir in ('.', '..'):
134 134 docdir = os.path.join(base, dir, 'help')
135 135 if os.path.isdir(docdir):
136 136 break
137 137
138 138 path = os.path.join(docdir, topic + ".txt")
139 139 doc = gettext(util.readfile(path))
140 140 for rewriter in helphooks.get(topic, []):
141 141 doc = rewriter(topic, doc)
142 142 return doc
143 143
144 144 return loader
145 145
146 146 helptable = sorted([
147 147 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
148 148 (["dates"], _("Date Formats"), loaddoc('dates')),
149 149 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
150 150 (['environment', 'env'], _('Environment Variables'),
151 151 loaddoc('environment')),
152 152 (['revisions', 'revs'], _('Specifying Single Revisions'),
153 153 loaddoc('revisions')),
154 154 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
155 155 loaddoc('multirevs')),
156 156 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
157 157 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
158 158 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
159 159 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
160 160 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
161 161 loaddoc('templates')),
162 162 (['urls'], _('URL Paths'), loaddoc('urls')),
163 163 (["extensions"], _("Using Additional Features"), extshelp),
164 164 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
165 165 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
166 166 (["glossary"], _("Glossary"), loaddoc('glossary')),
167 167 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
168 168 loaddoc('hgignore')),
169 169 (["phases"], _("Working with Phases"), loaddoc('phases')),
170 170 ])
171 171
172 172 # Map topics to lists of callable taking the current topic help and
173 173 # returning the updated version
174 174 helphooks = {}
175 175
176 176 def addtopichook(topic, rewriter):
177 177 helphooks.setdefault(topic, []).append(rewriter)
178 178
179 179 def makeitemsdoc(topic, doc, marker, items):
180 180 """Extract docstring from the items key to function mapping, build a
181 181 .single documentation block and use it to overwrite the marker in doc
182 182 """
183 183 entries = []
184 184 for name in sorted(items):
185 185 text = (items[name].__doc__ or '').rstrip()
186 186 if not text:
187 187 continue
188 188 text = gettext(text)
189 189 lines = text.splitlines()
190 190 doclines = [(lines[0])]
191 191 for l in lines[1:]:
192 192 # Stop once we find some Python doctest
193 193 if l.strip().startswith('>>>'):
194 194 break
195 195 doclines.append(' ' + l.strip())
196 196 entries.append('\n'.join(doclines))
197 197 entries = '\n\n'.join(entries)
198 198 return doc.replace(marker, entries)
199 199
200 200 def addtopicsymbols(topic, marker, symbols):
201 201 def add(topic, doc):
202 202 return makeitemsdoc(topic, doc, marker, symbols)
203 203 addtopichook(topic, add)
204 204
205 205 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
206 206 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals)
207 207 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
208 208 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
209 209 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
210 210
211 211 def help_(ui, name, unknowncmd=False, full=True, **opts):
212 212 '''
213 213 Generate the help for 'name' as unformatted restructured text. If
214 214 'name' is None, describe the commands available.
215 215 '''
216 216
217 217 import commands # avoid cycle
218 218
219 219 def helpcmd(name):
220 220 try:
221 221 aliases, entry = cmdutil.findcmd(name, commands.table,
222 222 strict=unknowncmd)
223 223 except error.AmbiguousCommand, inst:
224 224 # py3k fix: except vars can't be used outside the scope of the
225 225 # except block, nor can be used inside a lambda. python issue4617
226 226 prefix = inst.args[0]
227 227 select = lambda c: c.lstrip('^').startswith(prefix)
228 228 rst = helplist(select)
229 229 return rst
230 230
231 231 rst = []
232 232
233 233 # check if it's an invalid alias and display its error if it is
234 234 if getattr(entry[0], 'badalias', False):
235 235 if not unknowncmd:
236 236 ui.pushbuffer()
237 237 entry[0](ui)
238 238 rst.append(ui.popbuffer())
239 239 return rst
240 240
241 241 # synopsis
242 242 if len(entry) > 2:
243 243 if entry[2].startswith('hg'):
244 244 rst.append("%s\n" % entry[2])
245 245 else:
246 246 rst.append('hg %s %s\n' % (aliases[0], entry[2]))
247 247 else:
248 248 rst.append('hg %s\n' % aliases[0])
249 249 # aliases
250 250 if full and not ui.quiet and len(aliases) > 1:
251 251 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
252 252 rst.append('\n')
253 253
254 254 # description
255 255 doc = gettext(entry[0].__doc__)
256 256 if not doc:
257 257 doc = _("(no help text available)")
258 258 if util.safehasattr(entry[0], 'definition'): # aliased command
259 259 if entry[0].definition.startswith('!'): # shell alias
260 260 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
261 261 else:
262 262 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
263 263 doc = doc.splitlines(True)
264 264 if ui.quiet or not full:
265 265 rst.append(doc[0])
266 266 else:
267 267 rst.extend(doc)
268 268 rst.append('\n')
269 269
270 270 # check if this command shadows a non-trivial (multi-line)
271 271 # extension help text
272 272 try:
273 273 mod = extensions.find(name)
274 274 doc = gettext(mod.__doc__) or ''
275 275 if '\n' in doc.strip():
276 276 msg = _('use "hg help -e %s" to show help for '
277 277 'the %s extension') % (name, name)
278 278 rst.append('\n%s\n' % msg)
279 279 except KeyError:
280 280 pass
281 281
282 282 # options
283 283 if not ui.quiet and entry[1]:
284 284 rst.append('\n%s\n\n' % _("options:"))
285 285 rst.append(optrst(entry[1], ui.verbose))
286 286
287 287 if ui.verbose:
288 288 rst.append('\n%s\n\n' % _("global options:"))
289 289 rst.append(optrst(commands.globalopts, ui.verbose))
290 290
291 291 if not ui.verbose:
292 292 if not full:
293 293 rst.append(_('\nuse "hg help %s" to show the full help text\n')
294 294 % name)
295 295 elif not ui.quiet:
296 296 omitted = _('use "hg -v help %s" to show more complete'
297 297 ' help and the global options') % name
298 298 notomitted = _('use "hg -v help %s" to show'
299 299 ' the global options') % name
300 300 indicateomitted(rst, omitted, notomitted)
301 301
302 302 return rst
303 303
304 304
305 305 def helplist(select=None):
306 306 # list of commands
307 307 if name == "shortlist":
308 308 header = _('basic commands:\n\n')
309 309 else:
310 310 header = _('list of commands:\n\n')
311 311
312 312 h = {}
313 313 cmds = {}
314 314 for c, e in commands.table.iteritems():
315 315 f = c.split("|", 1)[0]
316 316 if select and not select(f):
317 317 continue
318 318 if (not select and name != 'shortlist' and
319 319 e[0].__module__ != commands.__name__):
320 320 continue
321 321 if name == "shortlist" and not f.startswith("^"):
322 322 continue
323 323 f = f.lstrip("^")
324 324 if not ui.debugflag and f.startswith("debug"):
325 325 continue
326 326 doc = e[0].__doc__
327 327 if doc and 'DEPRECATED' in doc and not ui.verbose:
328 328 continue
329 329 doc = gettext(doc)
330 330 if not doc:
331 331 doc = _("(no help text available)")
332 332 h[f] = doc.splitlines()[0].rstrip()
333 333 cmds[f] = c.lstrip("^")
334 334
335 335 rst = []
336 336 if not h:
337 337 if not ui.quiet:
338 338 rst.append(_('no commands defined\n'))
339 339 return rst
340 340
341 341 if not ui.quiet:
342 342 rst.append(header)
343 343 fns = sorted(h)
344 344 for f in fns:
345 345 if ui.verbose:
346 346 commacmds = cmds[f].replace("|",", ")
347 347 rst.append(" :%s: %s\n" % (commacmds, h[f]))
348 348 else:
349 349 rst.append(' :%s: %s\n' % (f, h[f]))
350 350
351 351 if not name:
352 352 exts = listexts(_('enabled extensions:'), extensions.enabled())
353 353 if exts:
354 354 rst.append('\n')
355 355 rst.extend(exts)
356 356
357 357 rst.append(_("\nadditional help topics:\n\n"))
358 358 topics = []
359 359 for names, header, doc in helptable:
360 360 topics.append((names[0], header))
361 361 for t, desc in topics:
362 362 rst.append(" :%s: %s\n" % (t, desc))
363 363
364 364 optlist = []
365 365 if not ui.quiet:
366 366 if ui.verbose:
367 367 optlist.append((_("global options:"), commands.globalopts))
368 368 if name == 'shortlist':
369 369 optlist.append((_('use "hg help" for the full list '
370 370 'of commands'), ()))
371 371 else:
372 372 if name == 'shortlist':
373 373 msg = _('use "hg help" for the full list of commands '
374 374 'or "hg -v" for details')
375 375 elif name and not full:
376 376 msg = _('use "hg help %s" to show the full help '
377 377 'text') % name
378 378 else:
379 379 msg = _('use "hg -v help%s" to show builtin aliases and '
380 380 'global options') % (name and " " + name or "")
381 381 optlist.append((msg, ()))
382 382
383 383 if optlist:
384 384 for title, options in optlist:
385 385 rst.append('\n%s\n' % title)
386 386 if options:
387 387 rst.append('\n%s\n' % optrst(options, ui.verbose))
388 388 return rst
389 389
390 390 def helptopic(name):
391 391 for names, header, doc in helptable:
392 392 if name in names:
393 393 break
394 394 else:
395 395 raise error.UnknownCommand(name)
396 396
397 rst = ["%s\n\n" % header]
397 rst = [minirst.section(header)]
398
398 399 # description
399 400 if not doc:
400 401 rst.append(" %s\n" % _("(no help text available)"))
401 402 if util.safehasattr(doc, '__call__'):
402 403 rst += [" %s\n" % l for l in doc().splitlines()]
403 404
404 405 if not ui.verbose:
405 406 omitted = (_('use "hg help -v %s" to show more complete help') %
406 407 name)
407 408 indicateomitted(rst, omitted)
408 409
409 410 try:
410 411 cmdutil.findcmd(name, commands.table)
411 412 rst.append(_('\nuse "hg help -c %s" to see help for '
412 413 'the %s command\n') % (name, name))
413 414 except error.UnknownCommand:
414 415 pass
415 416 return rst
416 417
417 418 def helpext(name):
418 419 try:
419 420 mod = extensions.find(name)
420 421 doc = gettext(mod.__doc__) or _('no help text available')
421 422 except KeyError:
422 423 mod = None
423 424 doc = extensions.disabledext(name)
424 425 if not doc:
425 426 raise error.UnknownCommand(name)
426 427
427 428 if '\n' not in doc:
428 429 head, tail = doc, ""
429 430 else:
430 431 head, tail = doc.split('\n', 1)
431 432 rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)]
432 433 if tail:
433 434 rst.extend(tail.splitlines(True))
434 435 rst.append('\n')
435 436
436 437 if not ui.verbose:
437 438 omitted = (_('use "hg help -v %s" to show more complete help') %
438 439 name)
439 440 indicateomitted(rst, omitted)
440 441
441 442 if mod:
442 443 try:
443 444 ct = mod.cmdtable
444 445 except AttributeError:
445 446 ct = {}
446 447 modcmds = set([c.split('|', 1)[0] for c in ct])
447 448 rst.extend(helplist(modcmds.__contains__))
448 449 else:
449 450 rst.append(_('use "hg help extensions" for information on enabling '
450 451 'extensions\n'))
451 452 return rst
452 453
453 454 def helpextcmd(name):
454 455 cmd, ext, mod = extensions.disabledcmd(ui, name,
455 456 ui.configbool('ui', 'strict'))
456 457 doc = gettext(mod.__doc__).splitlines()[0]
457 458
458 459 rst = listexts(_("'%s' is provided by the following "
459 460 "extension:") % cmd, {ext: doc}, indent=4)
460 461 rst.append('\n')
461 462 rst.append(_('use "hg help extensions" for information on enabling '
462 463 'extensions\n'))
463 464 return rst
464 465
465 466
466 467 rst = []
467 468 kw = opts.get('keyword')
468 469 if kw:
469 470 matches = topicmatch(kw)
470 471 for t, title in (('topics', _('Topics')),
471 472 ('commands', _('Commands')),
472 473 ('extensions', _('Extensions')),
473 474 ('extensioncommands', _('Extension Commands'))):
474 475 if matches[t]:
475 476 rst.append('%s:\n\n' % title)
476 477 rst.extend(minirst.maketable(sorted(matches[t]), 1))
477 478 rst.append('\n')
478 479 elif name and name != 'shortlist':
479 480 i = None
480 481 if unknowncmd:
481 482 queries = (helpextcmd,)
482 483 elif opts.get('extension'):
483 484 queries = (helpext,)
484 485 elif opts.get('command'):
485 486 queries = (helpcmd,)
486 487 else:
487 488 queries = (helptopic, helpcmd, helpext, helpextcmd)
488 489 for f in queries:
489 490 try:
490 491 rst = f(name)
491 492 i = None
492 493 break
493 494 except error.UnknownCommand, inst:
494 495 i = inst
495 496 if i:
496 497 raise i
497 498 else:
498 499 # program name
499 500 if not ui.quiet:
500 501 rst = [_("Mercurial Distributed SCM\n"), '\n']
501 502 rst.extend(helplist())
502 503
503 504 return ''.join(rst)
@@ -1,677 +1,689
1 1 # minirst.py - minimal reStructuredText parser
2 2 #
3 3 # Copyright 2009, 2010 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """simplified reStructuredText parser.
9 9
10 10 This parser knows just enough about reStructuredText to parse the
11 11 Mercurial docstrings.
12 12
13 13 It cheats in a major way: nested blocks are not really nested. They
14 14 are just indented blocks that look like they are nested. This relies
15 15 on the user to keep the right indentation for the blocks.
16 16
17 17 Remember to update http://mercurial.selenic.com/wiki/HelpStyleGuide
18 18 when adding support for new constructs.
19 19 """
20 20
21 21 import re
22 22 import util, encoding
23 23 from i18n import _
24 24
25 def section(s):
26 return "%s\n%s\n\n" % (s, "\"" * encoding.colwidth(s))
27
28 def subsection(s):
29 return "%s\n%s\n\n" % (s, '=' * encoding.colwidth(s))
30
31 def subsubsection(s):
32 return "%s\n%s\n\n" % (s, "-" * encoding.colwidth(s))
33
34 def subsubsubsection(s):
35 return "%s\n%s\n\n" % (s, "." * encoding.colwidth(s))
36
25 37 def replace(text, substs):
26 38 '''
27 39 Apply a list of (find, replace) pairs to a text.
28 40
29 41 >>> replace("foo bar", [('f', 'F'), ('b', 'B')])
30 42 'Foo Bar'
31 43 >>> encoding.encoding = 'latin1'
32 44 >>> replace('\\x81\\\\', [('\\\\', '/')])
33 45 '\\x81/'
34 46 >>> encoding.encoding = 'shiftjis'
35 47 >>> replace('\\x81\\\\', [('\\\\', '/')])
36 48 '\\x81\\\\'
37 49 '''
38 50
39 51 # some character encodings (cp932 for Japanese, at least) use
40 52 # ASCII characters other than control/alphabet/digit as a part of
41 53 # multi-bytes characters, so direct replacing with such characters
42 54 # on strings in local encoding causes invalid byte sequences.
43 55 utext = text.decode(encoding.encoding)
44 56 for f, t in substs:
45 57 utext = utext.replace(f, t)
46 58 return utext.encode(encoding.encoding)
47 59
48 60 _blockre = re.compile(r"\n(?:\s*\n)+")
49 61
50 62 def findblocks(text):
51 63 """Find continuous blocks of lines in text.
52 64
53 65 Returns a list of dictionaries representing the blocks. Each block
54 66 has an 'indent' field and a 'lines' field.
55 67 """
56 68 blocks = []
57 69 for b in _blockre.split(text.lstrip('\n').rstrip()):
58 70 lines = b.splitlines()
59 71 if lines:
60 72 indent = min((len(l) - len(l.lstrip())) for l in lines)
61 73 lines = [l[indent:] for l in lines]
62 74 blocks.append(dict(indent=indent, lines=lines))
63 75 return blocks
64 76
65 77 def findliteralblocks(blocks):
66 78 """Finds literal blocks and adds a 'type' field to the blocks.
67 79
68 80 Literal blocks are given the type 'literal', all other blocks are
69 81 given type the 'paragraph'.
70 82 """
71 83 i = 0
72 84 while i < len(blocks):
73 85 # Searching for a block that looks like this:
74 86 #
75 87 # +------------------------------+
76 88 # | paragraph |
77 89 # | (ends with "::") |
78 90 # +------------------------------+
79 91 # +---------------------------+
80 92 # | indented literal block |
81 93 # +---------------------------+
82 94 blocks[i]['type'] = 'paragraph'
83 95 if blocks[i]['lines'][-1].endswith('::') and i + 1 < len(blocks):
84 96 indent = blocks[i]['indent']
85 97 adjustment = blocks[i + 1]['indent'] - indent
86 98
87 99 if blocks[i]['lines'] == ['::']:
88 100 # Expanded form: remove block
89 101 del blocks[i]
90 102 i -= 1
91 103 elif blocks[i]['lines'][-1].endswith(' ::'):
92 104 # Partially minimized form: remove space and both
93 105 # colons.
94 106 blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-3]
95 107 else:
96 108 # Fully minimized form: remove just one colon.
97 109 blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-1]
98 110
99 111 # List items are formatted with a hanging indent. We must
100 112 # correct for this here while we still have the original
101 113 # information on the indentation of the subsequent literal
102 114 # blocks available.
103 115 m = _bulletre.match(blocks[i]['lines'][0])
104 116 if m:
105 117 indent += m.end()
106 118 adjustment -= m.end()
107 119
108 120 # Mark the following indented blocks.
109 121 while i + 1 < len(blocks) and blocks[i + 1]['indent'] > indent:
110 122 blocks[i + 1]['type'] = 'literal'
111 123 blocks[i + 1]['indent'] -= adjustment
112 124 i += 1
113 125 i += 1
114 126 return blocks
115 127
116 128 _bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)|\|) ')
117 129 _optionre = re.compile(r'^(-([a-zA-Z0-9]), )?(--[a-z0-9-]+)'
118 130 r'((.*) +)(.*)$')
119 131 _fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):[ ]+(.*)')
120 132 _definitionre = re.compile(r'[^ ]')
121 133 _tablere = re.compile(r'(=+\s+)*=+')
122 134
123 135 def splitparagraphs(blocks):
124 136 """Split paragraphs into lists."""
125 137 # Tuples with (list type, item regexp, single line items?). Order
126 138 # matters: definition lists has the least specific regexp and must
127 139 # come last.
128 140 listtypes = [('bullet', _bulletre, True),
129 141 ('option', _optionre, True),
130 142 ('field', _fieldre, True),
131 143 ('definition', _definitionre, False)]
132 144
133 145 def match(lines, i, itemre, singleline):
134 146 """Does itemre match an item at line i?
135 147
136 148 A list item can be followed by an indented line or another list
137 149 item (but only if singleline is True).
138 150 """
139 151 line1 = lines[i]
140 152 line2 = i + 1 < len(lines) and lines[i + 1] or ''
141 153 if not itemre.match(line1):
142 154 return False
143 155 if singleline:
144 156 return line2 == '' or line2[0] == ' ' or itemre.match(line2)
145 157 else:
146 158 return line2.startswith(' ')
147 159
148 160 i = 0
149 161 while i < len(blocks):
150 162 if blocks[i]['type'] == 'paragraph':
151 163 lines = blocks[i]['lines']
152 164 for type, itemre, singleline in listtypes:
153 165 if match(lines, 0, itemre, singleline):
154 166 items = []
155 167 for j, line in enumerate(lines):
156 168 if match(lines, j, itemre, singleline):
157 169 items.append(dict(type=type, lines=[],
158 170 indent=blocks[i]['indent']))
159 171 items[-1]['lines'].append(line)
160 172 blocks[i:i + 1] = items
161 173 break
162 174 i += 1
163 175 return blocks
164 176
165 177 _fieldwidth = 14
166 178
167 179 def updatefieldlists(blocks):
168 180 """Find key for field lists."""
169 181 i = 0
170 182 while i < len(blocks):
171 183 if blocks[i]['type'] != 'field':
172 184 i += 1
173 185 continue
174 186
175 187 j = i
176 188 while j < len(blocks) and blocks[j]['type'] == 'field':
177 189 m = _fieldre.match(blocks[j]['lines'][0])
178 190 key, rest = m.groups()
179 191 blocks[j]['lines'][0] = rest
180 192 blocks[j]['key'] = key
181 193 j += 1
182 194
183 195 i = j + 1
184 196
185 197 return blocks
186 198
187 199 def updateoptionlists(blocks):
188 200 i = 0
189 201 while i < len(blocks):
190 202 if blocks[i]['type'] != 'option':
191 203 i += 1
192 204 continue
193 205
194 206 optstrwidth = 0
195 207 j = i
196 208 while j < len(blocks) and blocks[j]['type'] == 'option':
197 209 m = _optionre.match(blocks[j]['lines'][0])
198 210
199 211 shortoption = m.group(2)
200 212 group3 = m.group(3)
201 213 longoption = group3[2:].strip()
202 214 desc = m.group(6).strip()
203 215 longoptionarg = m.group(5).strip()
204 216 blocks[j]['lines'][0] = desc
205 217
206 218 noshortop = ''
207 219 if not shortoption:
208 220 noshortop = ' '
209 221
210 222 opt = "%s%s" % (shortoption and "-%s " % shortoption or '',
211 223 ("%s--%s %s") % (noshortop, longoption,
212 224 longoptionarg))
213 225 opt = opt.rstrip()
214 226 blocks[j]['optstr'] = opt
215 227 optstrwidth = max(optstrwidth, encoding.colwidth(opt))
216 228 j += 1
217 229
218 230 for block in blocks[i:j]:
219 231 block['optstrwidth'] = optstrwidth
220 232 i = j + 1
221 233 return blocks
222 234
223 235 def prunecontainers(blocks, keep):
224 236 """Prune unwanted containers.
225 237
226 238 The blocks must have a 'type' field, i.e., they should have been
227 239 run through findliteralblocks first.
228 240 """
229 241 pruned = []
230 242 i = 0
231 243 while i + 1 < len(blocks):
232 244 # Searching for a block that looks like this:
233 245 #
234 246 # +-------+---------------------------+
235 247 # | ".. container ::" type |
236 248 # +---+ |
237 249 # | blocks |
238 250 # +-------------------------------+
239 251 if (blocks[i]['type'] == 'paragraph' and
240 252 blocks[i]['lines'][0].startswith('.. container::')):
241 253 indent = blocks[i]['indent']
242 254 adjustment = blocks[i + 1]['indent'] - indent
243 255 containertype = blocks[i]['lines'][0][15:]
244 256 prune = containertype not in keep
245 257 if prune:
246 258 pruned.append(containertype)
247 259
248 260 # Always delete "..container:: type" block
249 261 del blocks[i]
250 262 j = i
251 263 i -= 1
252 264 while j < len(blocks) and blocks[j]['indent'] > indent:
253 265 if prune:
254 266 del blocks[j]
255 267 else:
256 268 blocks[j]['indent'] -= adjustment
257 269 j += 1
258 270 i += 1
259 271 return blocks, pruned
260 272
261 273 _sectionre = re.compile(r"""^([-=`:.'"~^_*+#])\1+$""")
262 274
263 275 def findtables(blocks):
264 276 '''Find simple tables
265 277
266 278 Only simple one-line table elements are supported
267 279 '''
268 280
269 281 for block in blocks:
270 282 # Searching for a block that looks like this:
271 283 #
272 284 # === ==== ===
273 285 # A B C
274 286 # === ==== === <- optional
275 287 # 1 2 3
276 288 # x y z
277 289 # === ==== ===
278 290 if (block['type'] == 'paragraph' and
279 291 len(block['lines']) > 2 and
280 292 _tablere.match(block['lines'][0]) and
281 293 block['lines'][0] == block['lines'][-1]):
282 294 block['type'] = 'table'
283 295 block['header'] = False
284 296 div = block['lines'][0]
285 297
286 298 # column markers are ASCII so we can calculate column
287 299 # position in bytes
288 300 columns = [x for x in xrange(len(div))
289 301 if div[x] == '=' and (x == 0 or div[x - 1] == ' ')]
290 302 rows = []
291 303 for l in block['lines'][1:-1]:
292 304 if l == div:
293 305 block['header'] = True
294 306 continue
295 307 row = []
296 308 # we measure columns not in bytes or characters but in
297 309 # colwidth which makes things tricky
298 310 pos = columns[0] # leading whitespace is bytes
299 311 for n, start in enumerate(columns):
300 312 if n + 1 < len(columns):
301 313 width = columns[n + 1] - start
302 314 v = encoding.getcols(l, pos, width) # gather columns
303 315 pos += len(v) # calculate byte position of end
304 316 row.append(v.strip())
305 317 else:
306 318 row.append(l[pos:].strip())
307 319 rows.append(row)
308 320
309 321 block['table'] = rows
310 322
311 323 return blocks
312 324
313 325 def findsections(blocks):
314 326 """Finds sections.
315 327
316 328 The blocks must have a 'type' field, i.e., they should have been
317 329 run through findliteralblocks first.
318 330 """
319 331 for block in blocks:
320 332 # Searching for a block that looks like this:
321 333 #
322 334 # +------------------------------+
323 335 # | Section title |
324 336 # | ------------- |
325 337 # +------------------------------+
326 338 if (block['type'] == 'paragraph' and
327 339 len(block['lines']) == 2 and
328 340 encoding.colwidth(block['lines'][0]) == len(block['lines'][1]) and
329 341 _sectionre.match(block['lines'][1])):
330 342 block['underline'] = block['lines'][1][0]
331 343 block['type'] = 'section'
332 344 del block['lines'][1]
333 345 return blocks
334 346
335 347 def inlineliterals(blocks):
336 348 substs = [('``', '"')]
337 349 for b in blocks:
338 350 if b['type'] in ('paragraph', 'section'):
339 351 b['lines'] = [replace(l, substs) for l in b['lines']]
340 352 return blocks
341 353
342 354 def hgrole(blocks):
343 355 substs = [(':hg:`', '"hg '), ('`', '"')]
344 356 for b in blocks:
345 357 if b['type'] in ('paragraph', 'section'):
346 358 # Turn :hg:`command` into "hg command". This also works
347 359 # when there is a line break in the command and relies on
348 360 # the fact that we have no stray back-quotes in the input
349 361 # (run the blocks through inlineliterals first).
350 362 b['lines'] = [replace(l, substs) for l in b['lines']]
351 363 return blocks
352 364
353 365 def addmargins(blocks):
354 366 """Adds empty blocks for vertical spacing.
355 367
356 368 This groups bullets, options, and definitions together with no vertical
357 369 space between them, and adds an empty block between all other blocks.
358 370 """
359 371 i = 1
360 372 while i < len(blocks):
361 373 if (blocks[i]['type'] == blocks[i - 1]['type'] and
362 374 blocks[i]['type'] in ('bullet', 'option', 'field')):
363 375 i += 1
364 376 else:
365 377 blocks.insert(i, dict(lines=[''], indent=0, type='margin'))
366 378 i += 2
367 379 return blocks
368 380
369 381 def prunecomments(blocks):
370 382 """Remove comments."""
371 383 i = 0
372 384 while i < len(blocks):
373 385 b = blocks[i]
374 386 if b['type'] == 'paragraph' and (b['lines'][0].startswith('.. ') or
375 387 b['lines'] == ['..']):
376 388 del blocks[i]
377 389 if i < len(blocks) and blocks[i]['type'] == 'margin':
378 390 del blocks[i]
379 391 else:
380 392 i += 1
381 393 return blocks
382 394
383 395 _admonitionre = re.compile(r"\.\. (admonition|attention|caution|danger|"
384 396 r"error|hint|important|note|tip|warning)::",
385 397 flags=re.IGNORECASE)
386 398
387 399 def findadmonitions(blocks):
388 400 """
389 401 Makes the type of the block an admonition block if
390 402 the first line is an admonition directive
391 403 """
392 404 i = 0
393 405 while i < len(blocks):
394 406 m = _admonitionre.match(blocks[i]['lines'][0])
395 407 if m:
396 408 blocks[i]['type'] = 'admonition'
397 409 admonitiontitle = blocks[i]['lines'][0][3:m.end() - 2].lower()
398 410
399 411 firstline = blocks[i]['lines'][0][m.end() + 1:]
400 412 if firstline:
401 413 blocks[i]['lines'].insert(1, ' ' + firstline)
402 414
403 415 blocks[i]['admonitiontitle'] = admonitiontitle
404 416 del blocks[i]['lines'][0]
405 417 i = i + 1
406 418 return blocks
407 419
408 420 _admonitiontitles = {'attention': _('Attention:'),
409 421 'caution': _('Caution:'),
410 422 'danger': _('!Danger!') ,
411 423 'error': _('Error:'),
412 424 'hint': _('Hint:'),
413 425 'important': _('Important:'),
414 426 'note': _('Note:'),
415 427 'tip': _('Tip:'),
416 428 'warning': _('Warning!')}
417 429
418 430 def formatoption(block, width):
419 431 desc = ' '.join(map(str.strip, block['lines']))
420 432 colwidth = encoding.colwidth(block['optstr'])
421 433 usablewidth = width - 1
422 434 hanging = block['optstrwidth']
423 435 initindent = '%s%s ' % (block['optstr'], ' ' * ((hanging - colwidth)))
424 436 hangindent = ' ' * (encoding.colwidth(initindent) + 1)
425 437 return ' %s\n' % (util.wrap(desc, usablewidth,
426 438 initindent=initindent,
427 439 hangindent=hangindent))
428 440
429 441 def formatblock(block, width):
430 442 """Format a block according to width."""
431 443 if width <= 0:
432 444 width = 78
433 445 indent = ' ' * block['indent']
434 446 if block['type'] == 'admonition':
435 447 admonition = _admonitiontitles[block['admonitiontitle']]
436 448 hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
437 449
438 450 defindent = indent + hang * ' '
439 451 text = ' '.join(map(str.strip, block['lines']))
440 452 return '%s\n%s\n' % (indent + admonition,
441 453 util.wrap(text, width=width,
442 454 initindent=defindent,
443 455 hangindent=defindent))
444 456 if block['type'] == 'margin':
445 457 return '\n'
446 458 if block['type'] == 'literal':
447 459 indent += ' '
448 460 return indent + ('\n' + indent).join(block['lines']) + '\n'
449 461 if block['type'] == 'section':
450 462 underline = encoding.colwidth(block['lines'][0]) * block['underline']
451 463 return "%s%s\n%s%s\n" % (indent, block['lines'][0],indent, underline)
452 464 if block['type'] == 'table':
453 465 table = block['table']
454 466 # compute column widths
455 467 widths = [max([encoding.colwidth(e) for e in c]) for c in zip(*table)]
456 468 text = ''
457 469 span = sum(widths) + len(widths) - 1
458 470 indent = ' ' * block['indent']
459 471 hang = ' ' * (len(indent) + span - widths[-1])
460 472
461 473 for row in table:
462 474 l = []
463 475 for w, v in zip(widths, row):
464 476 pad = ' ' * (w - encoding.colwidth(v))
465 477 l.append(v + pad)
466 478 l = ' '.join(l)
467 479 l = util.wrap(l, width=width, initindent=indent, hangindent=hang)
468 480 if not text and block['header']:
469 481 text = l + '\n' + indent + '-' * (min(width, span)) + '\n'
470 482 else:
471 483 text += l + "\n"
472 484 return text
473 485 if block['type'] == 'definition':
474 486 term = indent + block['lines'][0]
475 487 hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
476 488 defindent = indent + hang * ' '
477 489 text = ' '.join(map(str.strip, block['lines'][1:]))
478 490 return '%s\n%s\n' % (term, util.wrap(text, width=width,
479 491 initindent=defindent,
480 492 hangindent=defindent))
481 493 subindent = indent
482 494 if block['type'] == 'bullet':
483 495 if block['lines'][0].startswith('| '):
484 496 # Remove bullet for line blocks and add no extra
485 497 # indention.
486 498 block['lines'][0] = block['lines'][0][2:]
487 499 else:
488 500 m = _bulletre.match(block['lines'][0])
489 501 subindent = indent + m.end() * ' '
490 502 elif block['type'] == 'field':
491 503 key = block['key']
492 504 subindent = indent + _fieldwidth * ' '
493 505 if len(key) + 2 > _fieldwidth:
494 506 # key too large, use full line width
495 507 key = key.ljust(width)
496 508 else:
497 509 # key fits within field width
498 510 key = key.ljust(_fieldwidth)
499 511 block['lines'][0] = key + block['lines'][0]
500 512 elif block['type'] == 'option':
501 513 return formatoption(block, width)
502 514
503 515 text = ' '.join(map(str.strip, block['lines']))
504 516 return util.wrap(text, width=width,
505 517 initindent=indent,
506 518 hangindent=subindent) + '\n'
507 519
508 520 def formathtml(blocks):
509 521 """Format RST blocks as HTML"""
510 522
511 523 out = []
512 524 headernest = ''
513 525 listnest = []
514 526
515 527 def openlist(start, level):
516 528 if not listnest or listnest[-1][0] != start:
517 529 listnest.append((start, level))
518 530 out.append('<%s>\n' % start)
519 531
520 532 blocks = [b for b in blocks if b['type'] != 'margin']
521 533
522 534 for pos, b in enumerate(blocks):
523 535 btype = b['type']
524 536 level = b['indent']
525 537 lines = b['lines']
526 538
527 539 if btype == 'admonition':
528 540 admonition = _admonitiontitles[b['admonitiontitle']]
529 541 text = ' '.join(map(str.strip, lines))
530 542 out.append('<p>\n<b>%s</b> %s\n</p>\n' % (admonition, text))
531 543 elif btype == 'paragraph':
532 544 out.append('<p>\n%s\n</p>\n' % '\n'.join(lines))
533 545 elif btype == 'margin':
534 546 pass
535 547 elif btype == 'literal':
536 548 out.append('<pre>\n%s\n</pre>\n' % '\n'.join(lines))
537 549 elif btype == 'section':
538 550 i = b['underline']
539 551 if i not in headernest:
540 552 headernest += i
541 553 level = headernest.index(i) + 1
542 554 out.append('<h%d>%s</h%d>\n' % (level, lines[0], level))
543 555 elif btype == 'table':
544 556 table = b['table']
545 557 t = []
546 558 for row in table:
547 559 l = []
548 560 for v in zip(row):
549 561 if not t:
550 562 l.append('<th>%s</th>' % v)
551 563 else:
552 564 l.append('<td>%s</td>' % v)
553 565 t.append(' <tr>%s</tr>\n' % ''.join(l))
554 566 out.append('<table>\n%s</table>\n' % ''.join(t))
555 567 elif btype == 'definition':
556 568 openlist('dl', level)
557 569 term = lines[0]
558 570 text = ' '.join(map(str.strip, lines[1:]))
559 571 out.append(' <dt>%s\n <dd>%s\n' % (term, text))
560 572 elif btype == 'bullet':
561 573 bullet, head = lines[0].split(' ', 1)
562 574 if bullet == '-':
563 575 openlist('ul', level)
564 576 else:
565 577 openlist('ol', level)
566 578 out.append(' <li> %s\n' % ' '.join([head] + lines[1:]))
567 579 elif btype == 'field':
568 580 openlist('dl', level)
569 581 key = b['key']
570 582 text = ' '.join(map(str.strip, lines))
571 583 out.append(' <dt>%s\n <dd>%s\n' % (key, text))
572 584 elif btype == 'option':
573 585 openlist('dl', level)
574 586 opt = b['optstr']
575 587 desc = ' '.join(map(str.strip, lines))
576 588 out.append(' <dt>%s\n <dd>%s\n' % (opt, desc))
577 589
578 590 # close lists if indent level of next block is lower
579 591 if listnest:
580 592 start, level = listnest[-1]
581 593 if pos == len(blocks) - 1:
582 594 out.append('</%s>\n' % start)
583 595 listnest.pop()
584 596 else:
585 597 nb = blocks[pos + 1]
586 598 ni = nb['indent']
587 599 if (ni < level or
588 600 (ni == level and
589 601 nb['type'] not in 'definition bullet field option')):
590 602 out.append('</%s>\n' % start)
591 603 listnest.pop()
592 604
593 605 return ''.join(out)
594 606
595 607 def parse(text, indent=0, keep=None):
596 608 """Parse text into a list of blocks"""
597 609 pruned = []
598 610 blocks = findblocks(text)
599 611 for b in blocks:
600 612 b['indent'] += indent
601 613 blocks = findliteralblocks(blocks)
602 614 blocks = findtables(blocks)
603 615 blocks, pruned = prunecontainers(blocks, keep or [])
604 616 blocks = findsections(blocks)
605 617 blocks = inlineliterals(blocks)
606 618 blocks = hgrole(blocks)
607 619 blocks = splitparagraphs(blocks)
608 620 blocks = updatefieldlists(blocks)
609 621 blocks = updateoptionlists(blocks)
610 622 blocks = addmargins(blocks)
611 623 blocks = prunecomments(blocks)
612 624 blocks = findadmonitions(blocks)
613 625 return blocks, pruned
614 626
615 627 def formatblocks(blocks, width):
616 628 text = ''.join(formatblock(b, width) for b in blocks)
617 629 return text
618 630
619 631 def format(text, width=80, indent=0, keep=None, style='plain'):
620 632 """Parse and format the text according to width."""
621 633 blocks, pruned = parse(text, indent, keep or [])
622 634 if style == 'html':
623 635 text = formathtml(blocks)
624 636 else:
625 637 text = ''.join(formatblock(b, width) for b in blocks)
626 638 if keep is None:
627 639 return text
628 640 else:
629 641 return text, pruned
630 642
631 643 def getsections(blocks):
632 644 '''return a list of (section name, nesting level, blocks) tuples'''
633 645 nest = ""
634 646 level = 0
635 647 secs = []
636 648 for b in blocks:
637 649 if b['type'] == 'section':
638 650 i = b['underline']
639 651 if i not in nest:
640 652 nest += i
641 653 level = nest.index(i) + 1
642 654 nest = nest[:level]
643 655 secs.append((b['lines'][0], level, [b]))
644 656 else:
645 657 if not secs:
646 658 # add an initial empty section
647 659 secs = [('', 0, [])]
648 660 secs[-1][2].append(b)
649 661 return secs
650 662
651 663 def decorateblocks(blocks, width):
652 664 '''generate a list of (section name, line text) pairs for search'''
653 665 lines = []
654 666 for s in getsections(blocks):
655 667 section = s[0]
656 668 text = formatblocks(s[2], width)
657 669 lines.append([(section, l) for l in text.splitlines(True)])
658 670 return lines
659 671
660 672 def maketable(data, indent=0, header=False):
661 673 '''Generate an RST table for the given table data as a list of lines'''
662 674
663 675 widths = [max(encoding.colwidth(e) for e in c) for c in zip(*data)]
664 676 indent = ' ' * indent
665 677 div = indent + ' '.join('=' * w for w in widths) + '\n'
666 678
667 679 out = [div]
668 680 for row in data:
669 681 l = []
670 682 for w, v in zip(widths, row):
671 683 pad = ' ' * (w - encoding.colwidth(v))
672 684 l.append(v + pad)
673 685 out.append(indent + ' '.join(l) + "\n")
674 686 if header and len(data) > 1:
675 687 out.insert(2, div)
676 688 out.append(div)
677 689 return out
@@ -1,574 +1,575
1 1 Test basic extension support
2 2
3 3 $ cat > foobar.py <<EOF
4 4 > import os
5 5 > from mercurial import commands
6 6 >
7 7 > def uisetup(ui):
8 8 > ui.write("uisetup called\\n")
9 9 >
10 10 > def reposetup(ui, repo):
11 11 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
12 12 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
13 13 >
14 14 > def foo(ui, *args, **kwargs):
15 15 > ui.write("Foo\\n")
16 16 >
17 17 > def bar(ui, *args, **kwargs):
18 18 > ui.write("Bar\\n")
19 19 >
20 20 > cmdtable = {
21 21 > "foo": (foo, [], "hg foo"),
22 22 > "bar": (bar, [], "hg bar"),
23 23 > }
24 24 >
25 25 > commands.norepo += ' bar'
26 26 > EOF
27 27 $ abspath=`pwd`/foobar.py
28 28
29 29 $ mkdir barfoo
30 30 $ cp foobar.py barfoo/__init__.py
31 31 $ barfoopath=`pwd`/barfoo
32 32
33 33 $ hg init a
34 34 $ cd a
35 35 $ echo foo > file
36 36 $ hg add file
37 37 $ hg commit -m 'add file'
38 38
39 39 $ echo '[extensions]' >> $HGRCPATH
40 40 $ echo "foobar = $abspath" >> $HGRCPATH
41 41 $ hg foo
42 42 uisetup called
43 43 reposetup called for a
44 44 ui == repo.ui
45 45 Foo
46 46
47 47 $ cd ..
48 48 $ hg clone a b
49 49 uisetup called
50 50 reposetup called for a
51 51 ui == repo.ui
52 52 reposetup called for b
53 53 ui == repo.ui
54 54 updating to branch default
55 55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 56
57 57 $ hg bar
58 58 uisetup called
59 59 Bar
60 60 $ echo 'foobar = !' >> $HGRCPATH
61 61
62 62 module/__init__.py-style
63 63
64 64 $ echo "barfoo = $barfoopath" >> $HGRCPATH
65 65 $ cd a
66 66 $ hg foo
67 67 uisetup called
68 68 reposetup called for a
69 69 ui == repo.ui
70 70 Foo
71 71 $ echo 'barfoo = !' >> $HGRCPATH
72 72
73 73 Check that extensions are loaded in phases:
74 74
75 75 $ cat > foo.py <<EOF
76 76 > import os
77 77 > name = os.path.basename(__file__).rsplit('.', 1)[0]
78 78 > print "1) %s imported" % name
79 79 > def uisetup(ui):
80 80 > print "2) %s uisetup" % name
81 81 > def extsetup():
82 82 > print "3) %s extsetup" % name
83 83 > def reposetup(ui, repo):
84 84 > print "4) %s reposetup" % name
85 85 > EOF
86 86
87 87 $ cp foo.py bar.py
88 88 $ echo 'foo = foo.py' >> $HGRCPATH
89 89 $ echo 'bar = bar.py' >> $HGRCPATH
90 90
91 91 Command with no output, we just want to see the extensions loaded:
92 92
93 93 $ hg paths
94 94 1) foo imported
95 95 1) bar imported
96 96 2) foo uisetup
97 97 2) bar uisetup
98 98 3) foo extsetup
99 99 3) bar extsetup
100 100 4) foo reposetup
101 101 4) bar reposetup
102 102
103 103 Check hgweb's load order:
104 104
105 105 $ cat > hgweb.cgi <<EOF
106 106 > #!/usr/bin/env python
107 107 > from mercurial import demandimport; demandimport.enable()
108 108 > from mercurial.hgweb import hgweb
109 109 > from mercurial.hgweb import wsgicgi
110 110 >
111 111 > application = hgweb('.', 'test repo')
112 112 > wsgicgi.launch(application)
113 113 > EOF
114 114
115 115 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
116 116 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
117 117 > | grep '^[0-9]) ' # ignores HTML output
118 118 1) foo imported
119 119 1) bar imported
120 120 2) foo uisetup
121 121 2) bar uisetup
122 122 3) foo extsetup
123 123 3) bar extsetup
124 124 4) foo reposetup
125 125 4) bar reposetup
126 126 4) foo reposetup
127 127 4) bar reposetup
128 128
129 129 $ echo 'foo = !' >> $HGRCPATH
130 130 $ echo 'bar = !' >> $HGRCPATH
131 131
132 132 $ cd ..
133 133
134 134 hide outer repo
135 135 $ hg init
136 136
137 137 $ cat > empty.py <<EOF
138 138 > '''empty cmdtable
139 139 > '''
140 140 > cmdtable = {}
141 141 > EOF
142 142 $ emptypath=`pwd`/empty.py
143 143 $ echo "empty = $emptypath" >> $HGRCPATH
144 144 $ hg help empty
145 145 empty extension - empty cmdtable
146 146
147 147 no commands defined
148 148
149 149 $ echo 'empty = !' >> $HGRCPATH
150 150
151 151 $ cat > debugextension.py <<EOF
152 152 > '''only debugcommands
153 153 > '''
154 154 > def debugfoobar(ui, repo, *args, **opts):
155 155 > "yet another debug command"
156 156 > pass
157 157 >
158 158 > def foo(ui, repo, *args, **opts):
159 159 > """yet another foo command
160 160 >
161 161 > This command has been DEPRECATED since forever.
162 162 > """
163 163 > pass
164 164 >
165 165 > cmdtable = {
166 166 > "debugfoobar": (debugfoobar, (), "hg debugfoobar"),
167 167 > "foo": (foo, (), "hg foo")
168 168 > }
169 169 > EOF
170 170 $ debugpath=`pwd`/debugextension.py
171 171 $ echo "debugextension = $debugpath" >> $HGRCPATH
172 172
173 173 $ hg help debugextension
174 174 debugextension extension - only debugcommands
175 175
176 176 no commands defined
177 177
178 178 $ hg --verbose help debugextension
179 179 debugextension extension - only debugcommands
180 180
181 181 list of commands:
182 182
183 183 foo yet another foo command
184 184
185 185 global options:
186 186
187 187 -R --repository REPO repository root directory or name of overlay bundle
188 188 file
189 189 --cwd DIR change working directory
190 190 -y --noninteractive do not prompt, automatically pick the first choice for
191 191 all prompts
192 192 -q --quiet suppress output
193 193 -v --verbose enable additional output
194 194 --config CONFIG [+] set/override config option (use 'section.name=value')
195 195 --debug enable debugging output
196 196 --debugger start debugger
197 197 --encoding ENCODE set the charset encoding (default: ascii)
198 198 --encodingmode MODE set the charset encoding mode (default: strict)
199 199 --traceback always print a traceback on exception
200 200 --time time how long the command takes
201 201 --profile print command execution profile
202 202 --version output version information and exit
203 203 -h --help display help and exit
204 204 --hidden consider hidden changesets
205 205
206 206 [+] marked option can be specified multiple times
207 207
208 208 $ hg --debug help debugextension
209 209 debugextension extension - only debugcommands
210 210
211 211 list of commands:
212 212
213 213 debugfoobar yet another debug command
214 214 foo yet another foo command
215 215
216 216 global options:
217 217
218 218 -R --repository REPO repository root directory or name of overlay bundle
219 219 file
220 220 --cwd DIR change working directory
221 221 -y --noninteractive do not prompt, automatically pick the first choice for
222 222 all prompts
223 223 -q --quiet suppress output
224 224 -v --verbose enable additional output
225 225 --config CONFIG [+] set/override config option (use 'section.name=value')
226 226 --debug enable debugging output
227 227 --debugger start debugger
228 228 --encoding ENCODE set the charset encoding (default: ascii)
229 229 --encodingmode MODE set the charset encoding mode (default: strict)
230 230 --traceback always print a traceback on exception
231 231 --time time how long the command takes
232 232 --profile print command execution profile
233 233 --version output version information and exit
234 234 -h --help display help and exit
235 235 --hidden consider hidden changesets
236 236
237 237 [+] marked option can be specified multiple times
238 238 $ echo 'debugextension = !' >> $HGRCPATH
239 239
240 240 Extension module help vs command help:
241 241
242 242 $ echo 'extdiff =' >> $HGRCPATH
243 243 $ hg help extdiff
244 244 hg extdiff [OPT]... [FILE]...
245 245
246 246 use external program to diff repository (or selected files)
247 247
248 248 Show differences between revisions for the specified files, using an
249 249 external program. The default program used is diff, with default options
250 250 "-Npru".
251 251
252 252 To select a different program, use the -p/--program option. The program
253 253 will be passed the names of two directories to compare. To pass additional
254 254 options to the program, use -o/--option. These will be passed before the
255 255 names of the directories to compare.
256 256
257 257 When two revision arguments are given, then changes are shown between
258 258 those revisions. If only one revision is specified then that revision is
259 259 compared to the working directory, and, when no revisions are specified,
260 260 the working directory files are compared to its parent.
261 261
262 262 use "hg help -e extdiff" to show help for the extdiff extension
263 263
264 264 options:
265 265
266 266 -p --program CMD comparison program to run
267 267 -o --option OPT [+] pass option to comparison program
268 268 -r --rev REV [+] revision
269 269 -c --change REV change made by revision
270 270 -I --include PATTERN [+] include names matching the given patterns
271 271 -X --exclude PATTERN [+] exclude names matching the given patterns
272 272
273 273 [+] marked option can be specified multiple times
274 274
275 275 use "hg -v help extdiff" to show the global options
276 276
277 277 $ hg help --extension extdiff
278 278 extdiff extension - command to allow external programs to compare revisions
279 279
280 280 The extdiff Mercurial extension allows you to use external programs to compare
281 281 revisions, or revision with working directory. The external diff programs are
282 282 called with a configurable set of options and two non-option arguments: paths
283 283 to directories containing snapshots of files to compare.
284 284
285 285 The extdiff extension also allows you to configure new diff commands, so you
286 286 do not need to type "hg extdiff -p kdiff3" always.
287 287
288 288 [extdiff]
289 289 # add new command that runs GNU diff(1) in 'context diff' mode
290 290 cdiff = gdiff -Nprc5
291 291 ## or the old way:
292 292 #cmd.cdiff = gdiff
293 293 #opts.cdiff = -Nprc5
294 294
295 295 # add new command called vdiff, runs kdiff3
296 296 vdiff = kdiff3
297 297
298 298 # add new command called meld, runs meld (no need to name twice)
299 299 meld =
300 300
301 301 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
302 302 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
303 303 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
304 304 # your .vimrc
305 305 vimdiff = gvim -f "+next" \
306 306 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
307 307
308 308 Tool arguments can include variables that are expanded at runtime:
309 309
310 310 $parent1, $plabel1 - filename, descriptive label of first parent
311 311 $child, $clabel - filename, descriptive label of child revision
312 312 $parent2, $plabel2 - filename, descriptive label of second parent
313 313 $root - repository root
314 314 $parent is an alias for $parent1.
315 315
316 316 The extdiff extension will look in your [diff-tools] and [merge-tools]
317 317 sections for diff tool arguments, when none are specified in [extdiff].
318 318
319 319 [extdiff]
320 320 kdiff3 =
321 321
322 322 [diff-tools]
323 323 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
324 324
325 325 You can use -I/-X and list of file or directory names like normal "hg diff"
326 326 command. The extdiff extension makes snapshots of only needed files, so
327 327 running the external diff program will actually be pretty fast (at least
328 328 faster than having to compare the entire tree).
329 329
330 330 list of commands:
331 331
332 332 extdiff use external program to diff repository (or selected files)
333 333
334 334 use "hg -v help extdiff" to show builtin aliases and global options
335 335
336 336 $ echo 'extdiff = !' >> $HGRCPATH
337 337
338 338 Test help topic with same name as extension
339 339
340 340 $ cat > multirevs.py <<EOF
341 341 > from mercurial import commands
342 342 > """multirevs extension
343 343 > Big multi-line module docstring."""
344 344 > def multirevs(ui, repo, arg, *args, **opts):
345 345 > """multirevs command"""
346 346 > pass
347 347 > cmdtable = {
348 348 > "multirevs": (multirevs, [], 'ARG')
349 349 > }
350 350 > commands.norepo += ' multirevs'
351 351 > EOF
352 352 $ echo "multirevs = multirevs.py" >> $HGRCPATH
353 353
354 354 $ hg help multirevs
355 355 Specifying Multiple Revisions
356 """""""""""""""""""""""""""""
356 357
357 358 When Mercurial accepts more than one revision, they may be specified
358 359 individually, or provided as a topologically continuous range, separated
359 360 by the ":" character.
360 361
361 362 The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
362 363 revision identifiers. Both BEGIN and END are optional. If BEGIN is not
363 364 specified, it defaults to revision number 0. If END is not specified, it
364 365 defaults to the tip. The range ":" thus means "all revisions".
365 366
366 367 If BEGIN is greater than END, revisions are treated in reverse order.
367 368
368 369 A range acts as a closed interval. This means that a range of 3:5 gives 3,
369 370 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
370 371
371 372 use "hg help -c multirevs" to see help for the multirevs command
372 373
373 374 $ hg help -c multirevs
374 375 hg multirevs ARG
375 376
376 377 multirevs command
377 378
378 379 use "hg -v help multirevs" to show the global options
379 380
380 381 $ hg multirevs
381 382 hg multirevs: invalid arguments
382 383 hg multirevs ARG
383 384
384 385 multirevs command
385 386
386 387 use "hg help multirevs" to show the full help text
387 388 [255]
388 389
389 390 $ echo "multirevs = !" >> $HGRCPATH
390 391
391 392 Issue811: Problem loading extensions twice (by site and by user)
392 393
393 394 $ debugpath=`pwd`/debugissue811.py
394 395 $ cat > debugissue811.py <<EOF
395 396 > '''show all loaded extensions
396 397 > '''
397 398 > from mercurial import extensions, commands
398 399 >
399 400 > def debugextensions(ui):
400 401 > "yet another debug command"
401 402 > ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
402 403 >
403 404 > cmdtable = {"debugextensions": (debugextensions, (), "hg debugextensions")}
404 405 > commands.norepo += " debugextensions"
405 406 > EOF
406 407 $ echo "debugissue811 = $debugpath" >> $HGRCPATH
407 408 $ echo "mq=" >> $HGRCPATH
408 409 $ echo "hgext.mq=" >> $HGRCPATH
409 410 $ echo "hgext/mq=" >> $HGRCPATH
410 411
411 412 Show extensions:
412 413
413 414 $ hg debugextensions
414 415 debugissue811
415 416 mq
416 417
417 418 Disabled extension commands:
418 419
419 420 $ HGRCPATH=
420 421 $ export HGRCPATH
421 422 $ hg help email
422 423 'email' is provided by the following extension:
423 424
424 425 patchbomb command to send changesets as (a series of) patch emails
425 426
426 427 use "hg help extensions" for information on enabling extensions
427 428 $ hg qdel
428 429 hg: unknown command 'qdel'
429 430 'qdelete' is provided by the following extension:
430 431
431 432 mq manage a stack of patches
432 433
433 434 use "hg help extensions" for information on enabling extensions
434 435 [255]
435 436 $ hg churn
436 437 hg: unknown command 'churn'
437 438 'churn' is provided by the following extension:
438 439
439 440 churn command to display statistics about repository history
440 441
441 442 use "hg help extensions" for information on enabling extensions
442 443 [255]
443 444
444 445 Disabled extensions:
445 446
446 447 $ hg help churn
447 448 churn extension - command to display statistics about repository history
448 449
449 450 use "hg help extensions" for information on enabling extensions
450 451 $ hg help patchbomb
451 452 patchbomb extension - command to send changesets as (a series of) patch emails
452 453
453 454 use "hg help extensions" for information on enabling extensions
454 455
455 456 Broken disabled extension and command:
456 457
457 458 $ mkdir hgext
458 459 $ echo > hgext/__init__.py
459 460 $ cat > hgext/broken.py <<EOF
460 461 > "broken extension'
461 462 > EOF
462 463 $ cat > path.py <<EOF
463 464 > import os, sys
464 465 > sys.path.insert(0, os.environ['HGEXTPATH'])
465 466 > EOF
466 467 $ HGEXTPATH=`pwd`
467 468 $ export HGEXTPATH
468 469
469 470 $ hg --config extensions.path=./path.py help broken
470 471 broken extension - (no help text available)
471 472
472 473 use "hg help extensions" for information on enabling extensions
473 474
474 475 $ cat > hgext/forest.py <<EOF
475 476 > cmdtable = None
476 477 > EOF
477 478 $ hg --config extensions.path=./path.py help foo > /dev/null
478 479 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
479 480 hg: unknown command 'foo'
480 481 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
481 482 [255]
482 483
483 484 $ cat > throw.py <<EOF
484 485 > from mercurial import cmdutil, commands
485 486 > cmdtable = {}
486 487 > command = cmdutil.command(cmdtable)
487 488 > class Bogon(Exception): pass
488 489 >
489 490 > @command('throw', [], 'hg throw')
490 491 > def throw(ui, **opts):
491 492 > """throws an exception"""
492 493 > raise Bogon()
493 494 > commands.norepo += " throw"
494 495 > EOF
495 496 No declared supported version, extension complains:
496 497 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
497 498 ** Unknown exception encountered with possibly-broken third-party extension throw
498 499 ** which supports versions unknown of Mercurial.
499 500 ** Please disable throw and try your action again.
500 501 ** If that fixes the bug please report it to the extension author.
501 502 ** Python * (glob)
502 503 ** Mercurial Distributed SCM * (glob)
503 504 ** Extensions loaded: throw
504 505 empty declaration of supported version, extension complains:
505 506 $ echo "testedwith = ''" >> throw.py
506 507 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
507 508 ** Unknown exception encountered with possibly-broken third-party extension throw
508 509 ** which supports versions unknown of Mercurial.
509 510 ** Please disable throw and try your action again.
510 511 ** If that fixes the bug please report it to the extension author.
511 512 ** Python * (glob)
512 513 ** Mercurial Distributed SCM (*) (glob)
513 514 ** Extensions loaded: throw
514 515 If the extension specifies a buglink, show that:
515 516 $ echo 'buglink = "http://example.com/bts"' >> throw.py
516 517 $ rm -f throw.pyc throw.pyo
517 518 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
518 519 ** Unknown exception encountered with possibly-broken third-party extension throw
519 520 ** which supports versions unknown of Mercurial.
520 521 ** Please disable throw and try your action again.
521 522 ** If that fixes the bug please report it to http://example.com/bts
522 523 ** Python * (glob)
523 524 ** Mercurial Distributed SCM (*) (glob)
524 525 ** Extensions loaded: throw
525 526 If the extensions declare outdated versions, accuse the older extension first:
526 527 $ echo "from mercurial import util" >> older.py
527 528 $ echo "util.version = lambda:'2.2'" >> older.py
528 529 $ echo "testedwith = '1.9.3'" >> older.py
529 530 $ echo "testedwith = '2.1.1'" >> throw.py
530 531 $ rm -f throw.pyc throw.pyo
531 532 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
532 533 > throw 2>&1 | egrep '^\*\*'
533 534 ** Unknown exception encountered with possibly-broken third-party extension older
534 535 ** which supports versions 1.9.3 of Mercurial.
535 536 ** Please disable older and try your action again.
536 537 ** If that fixes the bug please report it to the extension author.
537 538 ** Python * (glob)
538 539 ** Mercurial Distributed SCM (version 2.2)
539 540 ** Extensions loaded: throw, older
540 541 One extension only tested with older, one only with newer versions:
541 542 $ echo "util.version = lambda:'2.1.0'" >> older.py
542 543 $ rm -f older.pyc older.pyo
543 544 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
544 545 > throw 2>&1 | egrep '^\*\*'
545 546 ** Unknown exception encountered with possibly-broken third-party extension older
546 547 ** which supports versions 1.9.3 of Mercurial.
547 548 ** Please disable older and try your action again.
548 549 ** If that fixes the bug please report it to the extension author.
549 550 ** Python * (glob)
550 551 ** Mercurial Distributed SCM (version 2.1.0)
551 552 ** Extensions loaded: throw, older
552 553 Older extension is tested with current version, the other only with newer:
553 554 $ echo "util.version = lambda:'1.9.3'" >> older.py
554 555 $ rm -f older.pyc older.pyo
555 556 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
556 557 > throw 2>&1 | egrep '^\*\*'
557 558 ** Unknown exception encountered with possibly-broken third-party extension throw
558 559 ** which supports versions 2.1.1 of Mercurial.
559 560 ** Please disable throw and try your action again.
560 561 ** If that fixes the bug please report it to http://example.com/bts
561 562 ** Python * (glob)
562 563 ** Mercurial Distributed SCM (version 1.9.3)
563 564 ** Extensions loaded: throw, older
564 565
565 566 Declare the version as supporting this hg version, show regular bts link:
566 567 $ hgver=`python -c 'from mercurial import util; print util.version().split("+")[0]'`
567 568 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
568 569 $ rm -f throw.pyc throw.pyo
569 570 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
570 571 ** unknown exception encountered, please report by visiting
571 572 ** http://mercurial.selenic.com/wiki/BugTracker
572 573 ** Python * (glob)
573 574 ** Mercurial Distributed SCM (*) (glob)
574 575 ** Extensions loaded: throw
@@ -1,1786 +1,1787
1 1 Short help:
2 2
3 3 $ hg
4 4 Mercurial Distributed SCM
5 5
6 6 basic commands:
7 7
8 8 add add the specified files on the next commit
9 9 annotate show changeset information by line for each file
10 10 clone make a copy of an existing repository
11 11 commit commit the specified files or all outstanding changes
12 12 diff diff repository (or selected files)
13 13 export dump the header and diffs for one or more changesets
14 14 forget forget the specified files on the next commit
15 15 init create a new repository in the given directory
16 16 log show revision history of entire repository or files
17 17 merge merge working directory with another revision
18 18 pull pull changes from the specified source
19 19 push push changes to the specified destination
20 20 remove remove the specified files on the next commit
21 21 serve start stand-alone webserver
22 22 status show changed files in the working directory
23 23 summary summarize working directory state
24 24 update update working directory (or switch revisions)
25 25
26 26 use "hg help" for the full list of commands or "hg -v" for details
27 27
28 28 $ hg -q
29 29 add add the specified files on the next commit
30 30 annotate show changeset information by line for each file
31 31 clone make a copy of an existing repository
32 32 commit commit the specified files or all outstanding changes
33 33 diff diff repository (or selected files)
34 34 export dump the header and diffs for one or more changesets
35 35 forget forget the specified files on the next commit
36 36 init create a new repository in the given directory
37 37 log show revision history of entire repository or files
38 38 merge merge working directory with another revision
39 39 pull pull changes from the specified source
40 40 push push changes to the specified destination
41 41 remove remove the specified files on the next commit
42 42 serve start stand-alone webserver
43 43 status show changed files in the working directory
44 44 summary summarize working directory state
45 45 update update working directory (or switch revisions)
46 46
47 47 $ hg help
48 48 Mercurial Distributed SCM
49 49
50 50 list of commands:
51 51
52 52 add add the specified files on the next commit
53 53 addremove add all new files, delete all missing files
54 54 annotate show changeset information by line for each file
55 55 archive create an unversioned archive of a repository revision
56 56 backout reverse effect of earlier changeset
57 57 bisect subdivision search of changesets
58 58 bookmarks track a line of development with movable markers
59 59 branch set or show the current branch name
60 60 branches list repository named branches
61 61 bundle create a changegroup file
62 62 cat output the current or given revision of files
63 63 clone make a copy of an existing repository
64 64 commit commit the specified files or all outstanding changes
65 65 copy mark files as copied for the next commit
66 66 diff diff repository (or selected files)
67 67 export dump the header and diffs for one or more changesets
68 68 forget forget the specified files on the next commit
69 69 graft copy changes from other branches onto the current branch
70 70 grep search for a pattern in specified files and revisions
71 71 heads show current repository heads or show branch heads
72 72 help show help for a given topic or a help overview
73 73 identify identify the working copy or specified revision
74 74 import import an ordered set of patches
75 75 incoming show new changesets found in source
76 76 init create a new repository in the given directory
77 77 locate locate files matching specific patterns
78 78 log show revision history of entire repository or files
79 79 manifest output the current or given revision of the project manifest
80 80 merge merge working directory with another revision
81 81 outgoing show changesets not found in the destination
82 82 parents show the parents of the working directory or revision
83 83 paths show aliases for remote repositories
84 84 phase set or show the current phase name
85 85 pull pull changes from the specified source
86 86 push push changes to the specified destination
87 87 recover roll back an interrupted transaction
88 88 remove remove the specified files on the next commit
89 89 rename rename files; equivalent of copy + remove
90 90 resolve redo merges or set/view the merge status of files
91 91 revert restore files to their checkout state
92 92 rollback roll back the last transaction (dangerous)
93 93 root print the root (top) of the current working directory
94 94 serve start stand-alone webserver
95 95 showconfig show combined config settings from all hgrc files
96 96 status show changed files in the working directory
97 97 summary summarize working directory state
98 98 tag add one or more tags for the current or given revision
99 99 tags list repository tags
100 100 tip show the tip revision
101 101 unbundle apply one or more changegroup files
102 102 update update working directory (or switch revisions)
103 103 verify verify the integrity of the repository
104 104 version output version and copyright information
105 105
106 106 additional help topics:
107 107
108 108 config Configuration Files
109 109 dates Date Formats
110 110 diffs Diff Formats
111 111 environment Environment Variables
112 112 extensions Using Additional Features
113 113 filesets Specifying File Sets
114 114 glossary Glossary
115 115 hgignore Syntax for Mercurial Ignore Files
116 116 hgweb Configuring hgweb
117 117 merge-tools Merge Tools
118 118 multirevs Specifying Multiple Revisions
119 119 patterns File Name Patterns
120 120 phases Working with Phases
121 121 revisions Specifying Single Revisions
122 122 revsets Specifying Revision Sets
123 123 subrepos Subrepositories
124 124 templating Template Usage
125 125 urls URL Paths
126 126
127 127 use "hg -v help" to show builtin aliases and global options
128 128
129 129 $ hg -q help
130 130 add add the specified files on the next commit
131 131 addremove add all new files, delete all missing files
132 132 annotate show changeset information by line for each file
133 133 archive create an unversioned archive of a repository revision
134 134 backout reverse effect of earlier changeset
135 135 bisect subdivision search of changesets
136 136 bookmarks track a line of development with movable markers
137 137 branch set or show the current branch name
138 138 branches list repository named branches
139 139 bundle create a changegroup file
140 140 cat output the current or given revision of files
141 141 clone make a copy of an existing repository
142 142 commit commit the specified files or all outstanding changes
143 143 copy mark files as copied for the next commit
144 144 diff diff repository (or selected files)
145 145 export dump the header and diffs for one or more changesets
146 146 forget forget the specified files on the next commit
147 147 graft copy changes from other branches onto the current branch
148 148 grep search for a pattern in specified files and revisions
149 149 heads show current repository heads or show branch heads
150 150 help show help for a given topic or a help overview
151 151 identify identify the working copy or specified revision
152 152 import import an ordered set of patches
153 153 incoming show new changesets found in source
154 154 init create a new repository in the given directory
155 155 locate locate files matching specific patterns
156 156 log show revision history of entire repository or files
157 157 manifest output the current or given revision of the project manifest
158 158 merge merge working directory with another revision
159 159 outgoing show changesets not found in the destination
160 160 parents show the parents of the working directory or revision
161 161 paths show aliases for remote repositories
162 162 phase set or show the current phase name
163 163 pull pull changes from the specified source
164 164 push push changes to the specified destination
165 165 recover roll back an interrupted transaction
166 166 remove remove the specified files on the next commit
167 167 rename rename files; equivalent of copy + remove
168 168 resolve redo merges or set/view the merge status of files
169 169 revert restore files to their checkout state
170 170 rollback roll back the last transaction (dangerous)
171 171 root print the root (top) of the current working directory
172 172 serve start stand-alone webserver
173 173 showconfig show combined config settings from all hgrc files
174 174 status show changed files in the working directory
175 175 summary summarize working directory state
176 176 tag add one or more tags for the current or given revision
177 177 tags list repository tags
178 178 tip show the tip revision
179 179 unbundle apply one or more changegroup files
180 180 update update working directory (or switch revisions)
181 181 verify verify the integrity of the repository
182 182 version output version and copyright information
183 183
184 184 additional help topics:
185 185
186 186 config Configuration Files
187 187 dates Date Formats
188 188 diffs Diff Formats
189 189 environment Environment Variables
190 190 extensions Using Additional Features
191 191 filesets Specifying File Sets
192 192 glossary Glossary
193 193 hgignore Syntax for Mercurial Ignore Files
194 194 hgweb Configuring hgweb
195 195 merge-tools Merge Tools
196 196 multirevs Specifying Multiple Revisions
197 197 patterns File Name Patterns
198 198 phases Working with Phases
199 199 revisions Specifying Single Revisions
200 200 revsets Specifying Revision Sets
201 201 subrepos Subrepositories
202 202 templating Template Usage
203 203 urls URL Paths
204 204
205 205 Test short command list with verbose option
206 206
207 207 $ hg -v help shortlist
208 208 Mercurial Distributed SCM
209 209
210 210 basic commands:
211 211
212 212 add add the specified files on the next commit
213 213 annotate, blame
214 214 show changeset information by line for each file
215 215 clone make a copy of an existing repository
216 216 commit, ci commit the specified files or all outstanding changes
217 217 diff diff repository (or selected files)
218 218 export dump the header and diffs for one or more changesets
219 219 forget forget the specified files on the next commit
220 220 init create a new repository in the given directory
221 221 log, history show revision history of entire repository or files
222 222 merge merge working directory with another revision
223 223 pull pull changes from the specified source
224 224 push push changes to the specified destination
225 225 remove, rm remove the specified files on the next commit
226 226 serve start stand-alone webserver
227 227 status, st show changed files in the working directory
228 228 summary, sum summarize working directory state
229 229 update, up, checkout, co
230 230 update working directory (or switch revisions)
231 231
232 232 global options:
233 233
234 234 -R --repository REPO repository root directory or name of overlay bundle
235 235 file
236 236 --cwd DIR change working directory
237 237 -y --noninteractive do not prompt, automatically pick the first choice for
238 238 all prompts
239 239 -q --quiet suppress output
240 240 -v --verbose enable additional output
241 241 --config CONFIG [+] set/override config option (use 'section.name=value')
242 242 --debug enable debugging output
243 243 --debugger start debugger
244 244 --encoding ENCODE set the charset encoding (default: ascii)
245 245 --encodingmode MODE set the charset encoding mode (default: strict)
246 246 --traceback always print a traceback on exception
247 247 --time time how long the command takes
248 248 --profile print command execution profile
249 249 --version output version information and exit
250 250 -h --help display help and exit
251 251 --hidden consider hidden changesets
252 252
253 253 [+] marked option can be specified multiple times
254 254
255 255 use "hg help" for the full list of commands
256 256
257 257 $ hg add -h
258 258 hg add [OPTION]... [FILE]...
259 259
260 260 add the specified files on the next commit
261 261
262 262 Schedule files to be version controlled and added to the repository.
263 263
264 264 The files will be added to the repository at the next commit. To undo an
265 265 add before that, see "hg forget".
266 266
267 267 If no names are given, add all files to the repository.
268 268
269 269 Returns 0 if all files are successfully added.
270 270
271 271 options:
272 272
273 273 -I --include PATTERN [+] include names matching the given patterns
274 274 -X --exclude PATTERN [+] exclude names matching the given patterns
275 275 -S --subrepos recurse into subrepositories
276 276 -n --dry-run do not perform actions, just print output
277 277
278 278 [+] marked option can be specified multiple times
279 279
280 280 use "hg -v help add" to show more complete help and the global options
281 281
282 282 Verbose help for add
283 283
284 284 $ hg add -hv
285 285 hg add [OPTION]... [FILE]...
286 286
287 287 add the specified files on the next commit
288 288
289 289 Schedule files to be version controlled and added to the repository.
290 290
291 291 The files will be added to the repository at the next commit. To undo an
292 292 add before that, see "hg forget".
293 293
294 294 If no names are given, add all files to the repository.
295 295
296 296 An example showing how new (unknown) files are added automatically by "hg
297 297 add":
298 298
299 299 $ ls
300 300 foo.c
301 301 $ hg status
302 302 ? foo.c
303 303 $ hg add
304 304 adding foo.c
305 305 $ hg status
306 306 A foo.c
307 307
308 308 Returns 0 if all files are successfully added.
309 309
310 310 options:
311 311
312 312 -I --include PATTERN [+] include names matching the given patterns
313 313 -X --exclude PATTERN [+] exclude names matching the given patterns
314 314 -S --subrepos recurse into subrepositories
315 315 -n --dry-run do not perform actions, just print output
316 316
317 317 [+] marked option can be specified multiple times
318 318
319 319 global options:
320 320
321 321 -R --repository REPO repository root directory or name of overlay bundle
322 322 file
323 323 --cwd DIR change working directory
324 324 -y --noninteractive do not prompt, automatically pick the first choice for
325 325 all prompts
326 326 -q --quiet suppress output
327 327 -v --verbose enable additional output
328 328 --config CONFIG [+] set/override config option (use 'section.name=value')
329 329 --debug enable debugging output
330 330 --debugger start debugger
331 331 --encoding ENCODE set the charset encoding (default: ascii)
332 332 --encodingmode MODE set the charset encoding mode (default: strict)
333 333 --traceback always print a traceback on exception
334 334 --time time how long the command takes
335 335 --profile print command execution profile
336 336 --version output version information and exit
337 337 -h --help display help and exit
338 338 --hidden consider hidden changesets
339 339
340 340 [+] marked option can be specified multiple times
341 341
342 342 Test help option with version option
343 343
344 344 $ hg add -h --version
345 345 Mercurial Distributed SCM (version *) (glob)
346 346 (see http://mercurial.selenic.com for more information)
347 347
348 348 Copyright (C) 2005-2012 Matt Mackall and others
349 349 This is free software; see the source for copying conditions. There is NO
350 350 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
351 351
352 352 $ hg add --skjdfks
353 353 hg add: option --skjdfks not recognized
354 354 hg add [OPTION]... [FILE]...
355 355
356 356 add the specified files on the next commit
357 357
358 358 options:
359 359
360 360 -I --include PATTERN [+] include names matching the given patterns
361 361 -X --exclude PATTERN [+] exclude names matching the given patterns
362 362 -S --subrepos recurse into subrepositories
363 363 -n --dry-run do not perform actions, just print output
364 364
365 365 [+] marked option can be specified multiple times
366 366
367 367 use "hg help add" to show the full help text
368 368 [255]
369 369
370 370 Test ambiguous command help
371 371
372 372 $ hg help ad
373 373 list of commands:
374 374
375 375 add add the specified files on the next commit
376 376 addremove add all new files, delete all missing files
377 377
378 378 use "hg -v help ad" to show builtin aliases and global options
379 379
380 380 Test command without options
381 381
382 382 $ hg help verify
383 383 hg verify
384 384
385 385 verify the integrity of the repository
386 386
387 387 Verify the integrity of the current repository.
388 388
389 389 This will perform an extensive check of the repository's integrity,
390 390 validating the hashes and checksums of each entry in the changelog,
391 391 manifest, and tracked files, as well as the integrity of their crosslinks
392 392 and indices.
393 393
394 394 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption for more
395 395 information about recovery from corruption of the repository.
396 396
397 397 Returns 0 on success, 1 if errors are encountered.
398 398
399 399 use "hg -v help verify" to show the global options
400 400
401 401 $ hg help diff
402 402 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
403 403
404 404 diff repository (or selected files)
405 405
406 406 Show differences between revisions for the specified files.
407 407
408 408 Differences between files are shown using the unified diff format.
409 409
410 410 Note:
411 411 diff may generate unexpected results for merges, as it will default to
412 412 comparing against the working directory's first parent changeset if no
413 413 revisions are specified.
414 414
415 415 When two revision arguments are given, then changes are shown between
416 416 those revisions. If only one revision is specified then that revision is
417 417 compared to the working directory, and, when no revisions are specified,
418 418 the working directory files are compared to its parent.
419 419
420 420 Alternatively you can specify -c/--change with a revision to see the
421 421 changes in that changeset relative to its first parent.
422 422
423 423 Without the -a/--text option, diff will avoid generating diffs of files it
424 424 detects as binary. With -a, diff will generate a diff anyway, probably
425 425 with undesirable results.
426 426
427 427 Use the -g/--git option to generate diffs in the git extended diff format.
428 428 For more information, read "hg help diffs".
429 429
430 430 Returns 0 on success.
431 431
432 432 options:
433 433
434 434 -r --rev REV [+] revision
435 435 -c --change REV change made by revision
436 436 -a --text treat all files as text
437 437 -g --git use git extended diff format
438 438 --nodates omit dates from diff headers
439 439 -p --show-function show which function each change is in
440 440 --reverse produce a diff that undoes the changes
441 441 -w --ignore-all-space ignore white space when comparing lines
442 442 -b --ignore-space-change ignore changes in the amount of white space
443 443 -B --ignore-blank-lines ignore changes whose lines are all blank
444 444 -U --unified NUM number of lines of context to show
445 445 --stat output diffstat-style summary of changes
446 446 -I --include PATTERN [+] include names matching the given patterns
447 447 -X --exclude PATTERN [+] exclude names matching the given patterns
448 448 -S --subrepos recurse into subrepositories
449 449
450 450 [+] marked option can be specified multiple times
451 451
452 452 use "hg -v help diff" to show more complete help and the global options
453 453
454 454 $ hg help status
455 455 hg status [OPTION]... [FILE]...
456 456
457 457 aliases: st
458 458
459 459 show changed files in the working directory
460 460
461 461 Show status of files in the repository. If names are given, only files
462 462 that match are shown. Files that are clean or ignored or the source of a
463 463 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
464 464 -C/--copies or -A/--all are given. Unless options described with "show
465 465 only ..." are given, the options -mardu are used.
466 466
467 467 Option -q/--quiet hides untracked (unknown and ignored) files unless
468 468 explicitly requested with -u/--unknown or -i/--ignored.
469 469
470 470 Note:
471 471 status may appear to disagree with diff if permissions have changed or
472 472 a merge has occurred. The standard diff format does not report
473 473 permission changes and diff only reports changes relative to one merge
474 474 parent.
475 475
476 476 If one revision is given, it is used as the base revision. If two
477 477 revisions are given, the differences between them are shown. The --change
478 478 option can also be used as a shortcut to list the changed files of a
479 479 revision from its first parent.
480 480
481 481 The codes used to show the status of files are:
482 482
483 483 M = modified
484 484 A = added
485 485 R = removed
486 486 C = clean
487 487 ! = missing (deleted by non-hg command, but still tracked)
488 488 ? = not tracked
489 489 I = ignored
490 490 = origin of the previous file listed as A (added)
491 491
492 492 Returns 0 on success.
493 493
494 494 options:
495 495
496 496 -A --all show status of all files
497 497 -m --modified show only modified files
498 498 -a --added show only added files
499 499 -r --removed show only removed files
500 500 -d --deleted show only deleted (but tracked) files
501 501 -c --clean show only files without changes
502 502 -u --unknown show only unknown (not tracked) files
503 503 -i --ignored show only ignored files
504 504 -n --no-status hide status prefix
505 505 -C --copies show source of copied files
506 506 -0 --print0 end filenames with NUL, for use with xargs
507 507 --rev REV [+] show difference from revision
508 508 --change REV list the changed files of a revision
509 509 -I --include PATTERN [+] include names matching the given patterns
510 510 -X --exclude PATTERN [+] exclude names matching the given patterns
511 511 -S --subrepos recurse into subrepositories
512 512
513 513 [+] marked option can be specified multiple times
514 514
515 515 use "hg -v help status" to show more complete help and the global options
516 516
517 517 $ hg -q help status
518 518 hg status [OPTION]... [FILE]...
519 519
520 520 show changed files in the working directory
521 521
522 522 $ hg help foo
523 523 hg: unknown command 'foo'
524 524 Mercurial Distributed SCM
525 525
526 526 basic commands:
527 527
528 528 add add the specified files on the next commit
529 529 annotate show changeset information by line for each file
530 530 clone make a copy of an existing repository
531 531 commit commit the specified files or all outstanding changes
532 532 diff diff repository (or selected files)
533 533 export dump the header and diffs for one or more changesets
534 534 forget forget the specified files on the next commit
535 535 init create a new repository in the given directory
536 536 log show revision history of entire repository or files
537 537 merge merge working directory with another revision
538 538 pull pull changes from the specified source
539 539 push push changes to the specified destination
540 540 remove remove the specified files on the next commit
541 541 serve start stand-alone webserver
542 542 status show changed files in the working directory
543 543 summary summarize working directory state
544 544 update update working directory (or switch revisions)
545 545
546 546 use "hg help" for the full list of commands or "hg -v" for details
547 547 [255]
548 548
549 549 $ hg skjdfks
550 550 hg: unknown command 'skjdfks'
551 551 Mercurial Distributed SCM
552 552
553 553 basic commands:
554 554
555 555 add add the specified files on the next commit
556 556 annotate show changeset information by line for each file
557 557 clone make a copy of an existing repository
558 558 commit commit the specified files or all outstanding changes
559 559 diff diff repository (or selected files)
560 560 export dump the header and diffs for one or more changesets
561 561 forget forget the specified files on the next commit
562 562 init create a new repository in the given directory
563 563 log show revision history of entire repository or files
564 564 merge merge working directory with another revision
565 565 pull pull changes from the specified source
566 566 push push changes to the specified destination
567 567 remove remove the specified files on the next commit
568 568 serve start stand-alone webserver
569 569 status show changed files in the working directory
570 570 summary summarize working directory state
571 571 update update working directory (or switch revisions)
572 572
573 573 use "hg help" for the full list of commands or "hg -v" for details
574 574 [255]
575 575
576 576 $ cat > helpext.py <<EOF
577 577 > import os
578 578 > from mercurial import commands
579 579 >
580 580 > def nohelp(ui, *args, **kwargs):
581 581 > pass
582 582 >
583 583 > cmdtable = {
584 584 > "nohelp": (nohelp, [], "hg nohelp"),
585 585 > }
586 586 >
587 587 > commands.norepo += ' nohelp'
588 588 > EOF
589 589 $ echo '[extensions]' >> $HGRCPATH
590 590 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
591 591
592 592 Test command with no help text
593 593
594 594 $ hg help nohelp
595 595 hg nohelp
596 596
597 597 (no help text available)
598 598
599 599 use "hg -v help nohelp" to show the global options
600 600
601 601 $ hg help -k nohelp
602 602 Commands:
603 603
604 604 nohelp hg nohelp
605 605
606 606 Extension Commands:
607 607
608 608 nohelp (no help text available)
609 609
610 610 Test that default list of commands omits extension commands
611 611
612 612 $ hg help
613 613 Mercurial Distributed SCM
614 614
615 615 list of commands:
616 616
617 617 add add the specified files on the next commit
618 618 addremove add all new files, delete all missing files
619 619 annotate show changeset information by line for each file
620 620 archive create an unversioned archive of a repository revision
621 621 backout reverse effect of earlier changeset
622 622 bisect subdivision search of changesets
623 623 bookmarks track a line of development with movable markers
624 624 branch set or show the current branch name
625 625 branches list repository named branches
626 626 bundle create a changegroup file
627 627 cat output the current or given revision of files
628 628 clone make a copy of an existing repository
629 629 commit commit the specified files or all outstanding changes
630 630 copy mark files as copied for the next commit
631 631 diff diff repository (or selected files)
632 632 export dump the header and diffs for one or more changesets
633 633 forget forget the specified files on the next commit
634 634 graft copy changes from other branches onto the current branch
635 635 grep search for a pattern in specified files and revisions
636 636 heads show current repository heads or show branch heads
637 637 help show help for a given topic or a help overview
638 638 identify identify the working copy or specified revision
639 639 import import an ordered set of patches
640 640 incoming show new changesets found in source
641 641 init create a new repository in the given directory
642 642 locate locate files matching specific patterns
643 643 log show revision history of entire repository or files
644 644 manifest output the current or given revision of the project manifest
645 645 merge merge working directory with another revision
646 646 outgoing show changesets not found in the destination
647 647 parents show the parents of the working directory or revision
648 648 paths show aliases for remote repositories
649 649 phase set or show the current phase name
650 650 pull pull changes from the specified source
651 651 push push changes to the specified destination
652 652 recover roll back an interrupted transaction
653 653 remove remove the specified files on the next commit
654 654 rename rename files; equivalent of copy + remove
655 655 resolve redo merges or set/view the merge status of files
656 656 revert restore files to their checkout state
657 657 rollback roll back the last transaction (dangerous)
658 658 root print the root (top) of the current working directory
659 659 serve start stand-alone webserver
660 660 showconfig show combined config settings from all hgrc files
661 661 status show changed files in the working directory
662 662 summary summarize working directory state
663 663 tag add one or more tags for the current or given revision
664 664 tags list repository tags
665 665 tip show the tip revision
666 666 unbundle apply one or more changegroup files
667 667 update update working directory (or switch revisions)
668 668 verify verify the integrity of the repository
669 669 version output version and copyright information
670 670
671 671 enabled extensions:
672 672
673 673 helpext (no help text available)
674 674
675 675 additional help topics:
676 676
677 677 config Configuration Files
678 678 dates Date Formats
679 679 diffs Diff Formats
680 680 environment Environment Variables
681 681 extensions Using Additional Features
682 682 filesets Specifying File Sets
683 683 glossary Glossary
684 684 hgignore Syntax for Mercurial Ignore Files
685 685 hgweb Configuring hgweb
686 686 merge-tools Merge Tools
687 687 multirevs Specifying Multiple Revisions
688 688 patterns File Name Patterns
689 689 phases Working with Phases
690 690 revisions Specifying Single Revisions
691 691 revsets Specifying Revision Sets
692 692 subrepos Subrepositories
693 693 templating Template Usage
694 694 urls URL Paths
695 695
696 696 use "hg -v help" to show builtin aliases and global options
697 697
698 698
699 699
700 700 Test list of commands with command with no help text
701 701
702 702 $ hg help helpext
703 703 helpext extension - no help text available
704 704
705 705 list of commands:
706 706
707 707 nohelp (no help text available)
708 708
709 709 use "hg -v help helpext" to show builtin aliases and global options
710 710
711 711 Test a help topic
712 712
713 713 $ hg help revs
714 714 Specifying Single Revisions
715 """""""""""""""""""""""""""
715 716
716 717 Mercurial supports several ways to specify individual revisions.
717 718
718 719 A plain integer is treated as a revision number. Negative integers are
719 720 treated as sequential offsets from the tip, with -1 denoting the tip, -2
720 721 denoting the revision prior to the tip, and so forth.
721 722
722 723 A 40-digit hexadecimal string is treated as a unique revision identifier.
723 724
724 725 A hexadecimal string less than 40 characters long is treated as a unique
725 726 revision identifier and is referred to as a short-form identifier. A
726 727 short-form identifier is only valid if it is the prefix of exactly one
727 728 full-length identifier.
728 729
729 730 Any other string is treated as a bookmark, tag, or branch name. A bookmark
730 731 is a movable pointer to a revision. A tag is a permanent name associated
731 732 with a revision. A branch name denotes the tipmost revision of that
732 733 branch. Bookmark, tag, and branch names must not contain the ":"
733 734 character.
734 735
735 736 The reserved name "tip" always identifies the most recent revision.
736 737
737 738 The reserved name "null" indicates the null revision. This is the revision
738 739 of an empty repository, and the parent of revision 0.
739 740
740 741 The reserved name "." indicates the working directory parent. If no
741 742 working directory is checked out, it is equivalent to null. If an
742 743 uncommitted merge is in progress, "." is the revision of the first parent.
743 744
744 745 Test templating help
745 746
746 747 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
747 748 desc String. The text of the changeset description.
748 749 diffstat String. Statistics of changes with the following format:
749 750 firstline Any text. Returns the first line of text.
750 751 nonempty Any text. Returns '(none)' if the string is empty.
751 752
752 753 Test help hooks
753 754
754 755 $ cat > helphook1.py <<EOF
755 756 > from mercurial import help
756 757 >
757 758 > def rewrite(topic, doc):
758 759 > return doc + '\nhelphook1\n'
759 760 >
760 761 > def extsetup(ui):
761 762 > help.addtopichook('revsets', rewrite)
762 763 > EOF
763 764 $ cat > helphook2.py <<EOF
764 765 > from mercurial import help
765 766 >
766 767 > def rewrite(topic, doc):
767 768 > return doc + '\nhelphook2\n'
768 769 >
769 770 > def extsetup(ui):
770 771 > help.addtopichook('revsets', rewrite)
771 772 > EOF
772 773 $ echo '[extensions]' >> $HGRCPATH
773 774 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
774 775 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
775 776 $ hg help revsets | grep helphook
776 777 helphook1
777 778 helphook2
778 779
779 780 Test keyword search help
780 781
781 782 $ hg help -k clone
782 783 Topics:
783 784
784 785 config Configuration Files
785 786 extensions Using Additional Features
786 787 glossary Glossary
787 788 phases Working with Phases
788 789 subrepos Subrepositories
789 790 urls URL Paths
790 791
791 792 Commands:
792 793
793 794 bookmarks track a line of development with movable markers
794 795 clone make a copy of an existing repository
795 796 paths show aliases for remote repositories
796 797 update update working directory (or switch revisions)
797 798
798 799 Extensions:
799 800
800 801 relink recreates hardlinks between repository clones
801 802
802 803 Extension Commands:
803 804
804 805 qclone clone main and patch repository at same time
805 806
806 807 Test omit indicating for help
807 808
808 809 $ cat > addverboseitems.py <<EOF
809 810 > '''extension to test omit indicating.
810 811 >
811 812 > This paragraph is never omitted (for extension)
812 813 >
813 814 > .. container:: verbose
814 815 >
815 816 > This paragraph is omitted,
816 817 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for extension)
817 818 >
818 819 > This paragraph is never omitted, too (for extension)
819 820 > '''
820 821 >
821 822 > from mercurial import help, commands
822 823 > testtopic = """This paragraph is never omitted (for topic).
823 824 >
824 825 > .. container:: verbose
825 826 >
826 827 > This paragraph is omitted,
827 828 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for topic)
828 829 >
829 830 > This paragraph is never omitted, too (for topic)
830 831 > """
831 832 > def extsetup(ui):
832 833 > help.helptable.append((["topic-containing-verbose"],
833 834 > "This is the topic to test omit indicating.",
834 835 > lambda : testtopic))
835 836 > EOF
836 837 $ echo '[extensions]' >> $HGRCPATH
837 838 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
838 839 $ hg help addverboseitems
839 840 addverboseitems extension - extension to test omit indicating.
840 841
841 842 This paragraph is never omitted (for extension)
842 843
843 844 This paragraph is never omitted, too (for extension)
844 845
845 846 use "hg help -v addverboseitems" to show more complete help
846 847
847 848 no commands defined
848 849 $ hg help -v addverboseitems
849 850 addverboseitems extension - extension to test omit indicating.
850 851
851 852 This paragraph is never omitted (for extension)
852 853
853 854 This paragraph is omitted, if "hg help" is invoked witout "-v" (for extension)
854 855
855 856 This paragraph is never omitted, too (for extension)
856 857
857 858 no commands defined
858 859 $ hg help topic-containing-verbose
859 860 This is the topic to test omit indicating.
861 """"""""""""""""""""""""""""""""""""""""""
860 862
861 863 This paragraph is never omitted (for topic).
862 864
863 865 This paragraph is never omitted, too (for topic)
864 866
865 867 use "hg help -v topic-containing-verbose" to show more complete help
866 868 $ hg help -v topic-containing-verbose
867 869 This is the topic to test omit indicating.
870 """"""""""""""""""""""""""""""""""""""""""
868 871
869 872 This paragraph is never omitted (for topic).
870 873
871 874 This paragraph is omitted, if "hg help" is invoked witout "-v" (for topic)
872 875
873 876 This paragraph is never omitted, too (for topic)
874 877
875 878 Test usage of section marks in help documents
876 879
877 880 $ cd "$TESTDIR"/../doc
878 881 $ python check-seclevel.py
879 882 $ cd $TESTTMP
880 883
881 884 #if serve
882 885
883 886 Test the help pages in hgweb.
884 887
885 888 Dish up an empty repo; serve it cold.
886 889
887 890 $ hg init "$TESTTMP/test"
888 891 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
889 892 $ cat hg.pid >> $DAEMON_PIDS
890 893
891 894 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help"
892 895 200 Script output follows
893 896
894 897 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
895 898 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
896 899 <head>
897 900 <link rel="icon" href="/static/hgicon.png" type="image/png" />
898 901 <meta name="robots" content="index, nofollow" />
899 902 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
900 903 <script type="text/javascript" src="/static/mercurial.js"></script>
901 904
902 905 <title>Help: Index</title>
903 906 </head>
904 907 <body>
905 908
906 909 <div class="container">
907 910 <div class="menu">
908 911 <div class="logo">
909 912 <a href="http://mercurial.selenic.com/">
910 913 <img src="/static/hglogo.png" alt="mercurial" /></a>
911 914 </div>
912 915 <ul>
913 916 <li><a href="/shortlog">log</a></li>
914 917 <li><a href="/graph">graph</a></li>
915 918 <li><a href="/tags">tags</a></li>
916 919 <li><a href="/bookmarks">bookmarks</a></li>
917 920 <li><a href="/branches">branches</a></li>
918 921 </ul>
919 922 <ul>
920 923 <li class="active">help</li>
921 924 </ul>
922 925 </div>
923 926
924 927 <div class="main">
925 928 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
926 929 <form class="search" action="/log">
927 930
928 931 <p><input name="rev" id="search1" type="text" size="30" /></p>
929 932 <div id="hint">find changesets by author, revision,
930 933 files, or words in the commit message</div>
931 934 </form>
932 935 <table class="bigtable">
933 936 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
934 937
935 938 <tr><td>
936 939 <a href="/help/config">
937 940 config
938 941 </a>
939 942 </td><td>
940 943 Configuration Files
941 944 </td></tr>
942 945 <tr><td>
943 946 <a href="/help/dates">
944 947 dates
945 948 </a>
946 949 </td><td>
947 950 Date Formats
948 951 </td></tr>
949 952 <tr><td>
950 953 <a href="/help/diffs">
951 954 diffs
952 955 </a>
953 956 </td><td>
954 957 Diff Formats
955 958 </td></tr>
956 959 <tr><td>
957 960 <a href="/help/environment">
958 961 environment
959 962 </a>
960 963 </td><td>
961 964 Environment Variables
962 965 </td></tr>
963 966 <tr><td>
964 967 <a href="/help/extensions">
965 968 extensions
966 969 </a>
967 970 </td><td>
968 971 Using Additional Features
969 972 </td></tr>
970 973 <tr><td>
971 974 <a href="/help/filesets">
972 975 filesets
973 976 </a>
974 977 </td><td>
975 978 Specifying File Sets
976 979 </td></tr>
977 980 <tr><td>
978 981 <a href="/help/glossary">
979 982 glossary
980 983 </a>
981 984 </td><td>
982 985 Glossary
983 986 </td></tr>
984 987 <tr><td>
985 988 <a href="/help/hgignore">
986 989 hgignore
987 990 </a>
988 991 </td><td>
989 992 Syntax for Mercurial Ignore Files
990 993 </td></tr>
991 994 <tr><td>
992 995 <a href="/help/hgweb">
993 996 hgweb
994 997 </a>
995 998 </td><td>
996 999 Configuring hgweb
997 1000 </td></tr>
998 1001 <tr><td>
999 1002 <a href="/help/merge-tools">
1000 1003 merge-tools
1001 1004 </a>
1002 1005 </td><td>
1003 1006 Merge Tools
1004 1007 </td></tr>
1005 1008 <tr><td>
1006 1009 <a href="/help/multirevs">
1007 1010 multirevs
1008 1011 </a>
1009 1012 </td><td>
1010 1013 Specifying Multiple Revisions
1011 1014 </td></tr>
1012 1015 <tr><td>
1013 1016 <a href="/help/patterns">
1014 1017 patterns
1015 1018 </a>
1016 1019 </td><td>
1017 1020 File Name Patterns
1018 1021 </td></tr>
1019 1022 <tr><td>
1020 1023 <a href="/help/phases">
1021 1024 phases
1022 1025 </a>
1023 1026 </td><td>
1024 1027 Working with Phases
1025 1028 </td></tr>
1026 1029 <tr><td>
1027 1030 <a href="/help/revisions">
1028 1031 revisions
1029 1032 </a>
1030 1033 </td><td>
1031 1034 Specifying Single Revisions
1032 1035 </td></tr>
1033 1036 <tr><td>
1034 1037 <a href="/help/revsets">
1035 1038 revsets
1036 1039 </a>
1037 1040 </td><td>
1038 1041 Specifying Revision Sets
1039 1042 </td></tr>
1040 1043 <tr><td>
1041 1044 <a href="/help/subrepos">
1042 1045 subrepos
1043 1046 </a>
1044 1047 </td><td>
1045 1048 Subrepositories
1046 1049 </td></tr>
1047 1050 <tr><td>
1048 1051 <a href="/help/templating">
1049 1052 templating
1050 1053 </a>
1051 1054 </td><td>
1052 1055 Template Usage
1053 1056 </td></tr>
1054 1057 <tr><td>
1055 1058 <a href="/help/urls">
1056 1059 urls
1057 1060 </a>
1058 1061 </td><td>
1059 1062 URL Paths
1060 1063 </td></tr>
1061 1064 <tr><td>
1062 1065 <a href="/help/topic-containing-verbose">
1063 1066 topic-containing-verbose
1064 1067 </a>
1065 1068 </td><td>
1066 1069 This is the topic to test omit indicating.
1067 1070 </td></tr>
1068 1071
1069 1072 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1070 1073
1071 1074 <tr><td>
1072 1075 <a href="/help/add">
1073 1076 add
1074 1077 </a>
1075 1078 </td><td>
1076 1079 add the specified files on the next commit
1077 1080 </td></tr>
1078 1081 <tr><td>
1079 1082 <a href="/help/annotate">
1080 1083 annotate
1081 1084 </a>
1082 1085 </td><td>
1083 1086 show changeset information by line for each file
1084 1087 </td></tr>
1085 1088 <tr><td>
1086 1089 <a href="/help/clone">
1087 1090 clone
1088 1091 </a>
1089 1092 </td><td>
1090 1093 make a copy of an existing repository
1091 1094 </td></tr>
1092 1095 <tr><td>
1093 1096 <a href="/help/commit">
1094 1097 commit
1095 1098 </a>
1096 1099 </td><td>
1097 1100 commit the specified files or all outstanding changes
1098 1101 </td></tr>
1099 1102 <tr><td>
1100 1103 <a href="/help/diff">
1101 1104 diff
1102 1105 </a>
1103 1106 </td><td>
1104 1107 diff repository (or selected files)
1105 1108 </td></tr>
1106 1109 <tr><td>
1107 1110 <a href="/help/export">
1108 1111 export
1109 1112 </a>
1110 1113 </td><td>
1111 1114 dump the header and diffs for one or more changesets
1112 1115 </td></tr>
1113 1116 <tr><td>
1114 1117 <a href="/help/forget">
1115 1118 forget
1116 1119 </a>
1117 1120 </td><td>
1118 1121 forget the specified files on the next commit
1119 1122 </td></tr>
1120 1123 <tr><td>
1121 1124 <a href="/help/init">
1122 1125 init
1123 1126 </a>
1124 1127 </td><td>
1125 1128 create a new repository in the given directory
1126 1129 </td></tr>
1127 1130 <tr><td>
1128 1131 <a href="/help/log">
1129 1132 log
1130 1133 </a>
1131 1134 </td><td>
1132 1135 show revision history of entire repository or files
1133 1136 </td></tr>
1134 1137 <tr><td>
1135 1138 <a href="/help/merge">
1136 1139 merge
1137 1140 </a>
1138 1141 </td><td>
1139 1142 merge working directory with another revision
1140 1143 </td></tr>
1141 1144 <tr><td>
1142 1145 <a href="/help/pull">
1143 1146 pull
1144 1147 </a>
1145 1148 </td><td>
1146 1149 pull changes from the specified source
1147 1150 </td></tr>
1148 1151 <tr><td>
1149 1152 <a href="/help/push">
1150 1153 push
1151 1154 </a>
1152 1155 </td><td>
1153 1156 push changes to the specified destination
1154 1157 </td></tr>
1155 1158 <tr><td>
1156 1159 <a href="/help/remove">
1157 1160 remove
1158 1161 </a>
1159 1162 </td><td>
1160 1163 remove the specified files on the next commit
1161 1164 </td></tr>
1162 1165 <tr><td>
1163 1166 <a href="/help/serve">
1164 1167 serve
1165 1168 </a>
1166 1169 </td><td>
1167 1170 start stand-alone webserver
1168 1171 </td></tr>
1169 1172 <tr><td>
1170 1173 <a href="/help/status">
1171 1174 status
1172 1175 </a>
1173 1176 </td><td>
1174 1177 show changed files in the working directory
1175 1178 </td></tr>
1176 1179 <tr><td>
1177 1180 <a href="/help/summary">
1178 1181 summary
1179 1182 </a>
1180 1183 </td><td>
1181 1184 summarize working directory state
1182 1185 </td></tr>
1183 1186 <tr><td>
1184 1187 <a href="/help/update">
1185 1188 update
1186 1189 </a>
1187 1190 </td><td>
1188 1191 update working directory (or switch revisions)
1189 1192 </td></tr>
1190 1193
1191 1194 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1192 1195
1193 1196 <tr><td>
1194 1197 <a href="/help/addremove">
1195 1198 addremove
1196 1199 </a>
1197 1200 </td><td>
1198 1201 add all new files, delete all missing files
1199 1202 </td></tr>
1200 1203 <tr><td>
1201 1204 <a href="/help/archive">
1202 1205 archive
1203 1206 </a>
1204 1207 </td><td>
1205 1208 create an unversioned archive of a repository revision
1206 1209 </td></tr>
1207 1210 <tr><td>
1208 1211 <a href="/help/backout">
1209 1212 backout
1210 1213 </a>
1211 1214 </td><td>
1212 1215 reverse effect of earlier changeset
1213 1216 </td></tr>
1214 1217 <tr><td>
1215 1218 <a href="/help/bisect">
1216 1219 bisect
1217 1220 </a>
1218 1221 </td><td>
1219 1222 subdivision search of changesets
1220 1223 </td></tr>
1221 1224 <tr><td>
1222 1225 <a href="/help/bookmarks">
1223 1226 bookmarks
1224 1227 </a>
1225 1228 </td><td>
1226 1229 track a line of development with movable markers
1227 1230 </td></tr>
1228 1231 <tr><td>
1229 1232 <a href="/help/branch">
1230 1233 branch
1231 1234 </a>
1232 1235 </td><td>
1233 1236 set or show the current branch name
1234 1237 </td></tr>
1235 1238 <tr><td>
1236 1239 <a href="/help/branches">
1237 1240 branches
1238 1241 </a>
1239 1242 </td><td>
1240 1243 list repository named branches
1241 1244 </td></tr>
1242 1245 <tr><td>
1243 1246 <a href="/help/bundle">
1244 1247 bundle
1245 1248 </a>
1246 1249 </td><td>
1247 1250 create a changegroup file
1248 1251 </td></tr>
1249 1252 <tr><td>
1250 1253 <a href="/help/cat">
1251 1254 cat
1252 1255 </a>
1253 1256 </td><td>
1254 1257 output the current or given revision of files
1255 1258 </td></tr>
1256 1259 <tr><td>
1257 1260 <a href="/help/copy">
1258 1261 copy
1259 1262 </a>
1260 1263 </td><td>
1261 1264 mark files as copied for the next commit
1262 1265 </td></tr>
1263 1266 <tr><td>
1264 1267 <a href="/help/graft">
1265 1268 graft
1266 1269 </a>
1267 1270 </td><td>
1268 1271 copy changes from other branches onto the current branch
1269 1272 </td></tr>
1270 1273 <tr><td>
1271 1274 <a href="/help/grep">
1272 1275 grep
1273 1276 </a>
1274 1277 </td><td>
1275 1278 search for a pattern in specified files and revisions
1276 1279 </td></tr>
1277 1280 <tr><td>
1278 1281 <a href="/help/heads">
1279 1282 heads
1280 1283 </a>
1281 1284 </td><td>
1282 1285 show current repository heads or show branch heads
1283 1286 </td></tr>
1284 1287 <tr><td>
1285 1288 <a href="/help/help">
1286 1289 help
1287 1290 </a>
1288 1291 </td><td>
1289 1292 show help for a given topic or a help overview
1290 1293 </td></tr>
1291 1294 <tr><td>
1292 1295 <a href="/help/identify">
1293 1296 identify
1294 1297 </a>
1295 1298 </td><td>
1296 1299 identify the working copy or specified revision
1297 1300 </td></tr>
1298 1301 <tr><td>
1299 1302 <a href="/help/import">
1300 1303 import
1301 1304 </a>
1302 1305 </td><td>
1303 1306 import an ordered set of patches
1304 1307 </td></tr>
1305 1308 <tr><td>
1306 1309 <a href="/help/incoming">
1307 1310 incoming
1308 1311 </a>
1309 1312 </td><td>
1310 1313 show new changesets found in source
1311 1314 </td></tr>
1312 1315 <tr><td>
1313 1316 <a href="/help/locate">
1314 1317 locate
1315 1318 </a>
1316 1319 </td><td>
1317 1320 locate files matching specific patterns
1318 1321 </td></tr>
1319 1322 <tr><td>
1320 1323 <a href="/help/manifest">
1321 1324 manifest
1322 1325 </a>
1323 1326 </td><td>
1324 1327 output the current or given revision of the project manifest
1325 1328 </td></tr>
1326 1329 <tr><td>
1327 1330 <a href="/help/nohelp">
1328 1331 nohelp
1329 1332 </a>
1330 1333 </td><td>
1331 1334 (no help text available)
1332 1335 </td></tr>
1333 1336 <tr><td>
1334 1337 <a href="/help/outgoing">
1335 1338 outgoing
1336 1339 </a>
1337 1340 </td><td>
1338 1341 show changesets not found in the destination
1339 1342 </td></tr>
1340 1343 <tr><td>
1341 1344 <a href="/help/parents">
1342 1345 parents
1343 1346 </a>
1344 1347 </td><td>
1345 1348 show the parents of the working directory or revision
1346 1349 </td></tr>
1347 1350 <tr><td>
1348 1351 <a href="/help/paths">
1349 1352 paths
1350 1353 </a>
1351 1354 </td><td>
1352 1355 show aliases for remote repositories
1353 1356 </td></tr>
1354 1357 <tr><td>
1355 1358 <a href="/help/phase">
1356 1359 phase
1357 1360 </a>
1358 1361 </td><td>
1359 1362 set or show the current phase name
1360 1363 </td></tr>
1361 1364 <tr><td>
1362 1365 <a href="/help/recover">
1363 1366 recover
1364 1367 </a>
1365 1368 </td><td>
1366 1369 roll back an interrupted transaction
1367 1370 </td></tr>
1368 1371 <tr><td>
1369 1372 <a href="/help/rename">
1370 1373 rename
1371 1374 </a>
1372 1375 </td><td>
1373 1376 rename files; equivalent of copy + remove
1374 1377 </td></tr>
1375 1378 <tr><td>
1376 1379 <a href="/help/resolve">
1377 1380 resolve
1378 1381 </a>
1379 1382 </td><td>
1380 1383 redo merges or set/view the merge status of files
1381 1384 </td></tr>
1382 1385 <tr><td>
1383 1386 <a href="/help/revert">
1384 1387 revert
1385 1388 </a>
1386 1389 </td><td>
1387 1390 restore files to their checkout state
1388 1391 </td></tr>
1389 1392 <tr><td>
1390 1393 <a href="/help/rollback">
1391 1394 rollback
1392 1395 </a>
1393 1396 </td><td>
1394 1397 roll back the last transaction (dangerous)
1395 1398 </td></tr>
1396 1399 <tr><td>
1397 1400 <a href="/help/root">
1398 1401 root
1399 1402 </a>
1400 1403 </td><td>
1401 1404 print the root (top) of the current working directory
1402 1405 </td></tr>
1403 1406 <tr><td>
1404 1407 <a href="/help/showconfig">
1405 1408 showconfig
1406 1409 </a>
1407 1410 </td><td>
1408 1411 show combined config settings from all hgrc files
1409 1412 </td></tr>
1410 1413 <tr><td>
1411 1414 <a href="/help/tag">
1412 1415 tag
1413 1416 </a>
1414 1417 </td><td>
1415 1418 add one or more tags for the current or given revision
1416 1419 </td></tr>
1417 1420 <tr><td>
1418 1421 <a href="/help/tags">
1419 1422 tags
1420 1423 </a>
1421 1424 </td><td>
1422 1425 list repository tags
1423 1426 </td></tr>
1424 1427 <tr><td>
1425 1428 <a href="/help/tip">
1426 1429 tip
1427 1430 </a>
1428 1431 </td><td>
1429 1432 show the tip revision
1430 1433 </td></tr>
1431 1434 <tr><td>
1432 1435 <a href="/help/unbundle">
1433 1436 unbundle
1434 1437 </a>
1435 1438 </td><td>
1436 1439 apply one or more changegroup files
1437 1440 </td></tr>
1438 1441 <tr><td>
1439 1442 <a href="/help/verify">
1440 1443 verify
1441 1444 </a>
1442 1445 </td><td>
1443 1446 verify the integrity of the repository
1444 1447 </td></tr>
1445 1448 <tr><td>
1446 1449 <a href="/help/version">
1447 1450 version
1448 1451 </a>
1449 1452 </td><td>
1450 1453 output version and copyright information
1451 1454 </td></tr>
1452 1455 </table>
1453 1456 </div>
1454 1457 </div>
1455 1458
1456 1459 <script type="text/javascript">process_dates()</script>
1457 1460
1458 1461
1459 1462 </body>
1460 1463 </html>
1461 1464
1462 1465
1463 1466 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/add"
1464 1467 200 Script output follows
1465 1468
1466 1469 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1467 1470 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1468 1471 <head>
1469 1472 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1470 1473 <meta name="robots" content="index, nofollow" />
1471 1474 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1472 1475 <script type="text/javascript" src="/static/mercurial.js"></script>
1473 1476
1474 1477 <title>Help: add</title>
1475 1478 </head>
1476 1479 <body>
1477 1480
1478 1481 <div class="container">
1479 1482 <div class="menu">
1480 1483 <div class="logo">
1481 1484 <a href="http://mercurial.selenic.com/">
1482 1485 <img src="/static/hglogo.png" alt="mercurial" /></a>
1483 1486 </div>
1484 1487 <ul>
1485 1488 <li><a href="/shortlog">log</a></li>
1486 1489 <li><a href="/graph">graph</a></li>
1487 1490 <li><a href="/tags">tags</a></li>
1488 1491 <li><a href="/bookmarks">bookmarks</a></li>
1489 1492 <li><a href="/branches">branches</a></li>
1490 1493 </ul>
1491 1494 <ul>
1492 1495 <li class="active"><a href="/help">help</a></li>
1493 1496 </ul>
1494 1497 </div>
1495 1498
1496 1499 <div class="main">
1497 1500 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1498 1501 <h3>Help: add</h3>
1499 1502
1500 1503 <form class="search" action="/log">
1501 1504
1502 1505 <p><input name="rev" id="search1" type="text" size="30" /></p>
1503 1506 <div id="hint">find changesets by author, revision,
1504 1507 files, or words in the commit message</div>
1505 1508 </form>
1506 1509 <div id="doc">
1507 1510 <p>
1508 1511 hg add [OPTION]... [FILE]...
1509 1512 </p>
1510 1513 <p>
1511 1514 add the specified files on the next commit
1512 1515 </p>
1513 1516 <p>
1514 1517 Schedule files to be version controlled and added to the
1515 1518 repository.
1516 1519 </p>
1517 1520 <p>
1518 1521 The files will be added to the repository at the next commit. To
1519 1522 undo an add before that, see "hg forget".
1520 1523 </p>
1521 1524 <p>
1522 1525 If no names are given, add all files to the repository.
1523 1526 </p>
1524 1527 <p>
1525 1528 Returns 0 if all files are successfully added.
1526 1529 </p>
1527 1530 <p>
1528 1531 options:
1529 1532 </p>
1530 1533 <table>
1531 1534 <tr><th>-I</th><th>--include PATTERN [+]</th><th>include names matching the given patterns</th></tr>
1532 1535 <tr><td>-X</td><td>--exclude PATTERN [+]</td><td>exclude names matching the given patterns</td></tr>
1533 1536 <tr><td>-S</td><td>--subrepos</td><td>recurse into subrepositories</td></tr>
1534 1537 <tr><td>-n</td><td>--dry-run</td><td>do not perform actions, just print output</td></tr>
1535 1538 </table>
1536 1539 <p>
1537 1540 [+] marked option can be specified multiple times
1538 1541 </p>
1539 1542 <p>
1540 1543 global options:
1541 1544 </p>
1542 1545 <table>
1543 1546 <tr><th>-R</th><th>--repository REPO</th><th>repository root directory or name of overlay bundle file</th></tr>
1544 1547 <tr><td></td><td>--cwd DIR</td><td>change working directory</td></tr>
1545 1548 <tr><td>-y</td><td>--noninteractive</td><td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1546 1549 <tr><td>-q</td><td>--quiet</td><td>suppress output</td></tr>
1547 1550 <tr><td>-v</td><td>--verbose</td><td>enable additional output</td></tr>
1548 1551 <tr><td></td><td>--config CONFIG [+]</td><td>set/override config option (use 'section.name=value')</td></tr>
1549 1552 <tr><td></td><td>--debug</td><td>enable debugging output</td></tr>
1550 1553 <tr><td></td><td>--debugger</td><td>start debugger</td></tr>
1551 1554 <tr><td></td><td>--encoding ENCODE</td><td>set the charset encoding (default: ascii)</td></tr>
1552 1555 <tr><td></td><td>--encodingmode MODE</td><td>set the charset encoding mode (default: strict)</td></tr>
1553 1556 <tr><td></td><td>--traceback</td><td>always print a traceback on exception</td></tr>
1554 1557 <tr><td></td><td>--time</td><td>time how long the command takes</td></tr>
1555 1558 <tr><td></td><td>--profile</td><td>print command execution profile</td></tr>
1556 1559 <tr><td></td><td>--version</td><td>output version information and exit</td></tr>
1557 1560 <tr><td>-h</td><td>--help</td><td>display help and exit</td></tr>
1558 1561 <tr><td></td><td>--hidden</td><td>consider hidden changesets</td></tr>
1559 1562 </table>
1560 1563 <p>
1561 1564 [+] marked option can be specified multiple times
1562 1565 </p>
1563 1566
1564 1567 </div>
1565 1568 </div>
1566 1569 </div>
1567 1570
1568 1571 <script type="text/javascript">process_dates()</script>
1569 1572
1570 1573
1571 1574 </body>
1572 1575 </html>
1573 1576
1574 1577
1575 1578 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/remove"
1576 1579 200 Script output follows
1577 1580
1578 1581 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1579 1582 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1580 1583 <head>
1581 1584 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1582 1585 <meta name="robots" content="index, nofollow" />
1583 1586 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1584 1587 <script type="text/javascript" src="/static/mercurial.js"></script>
1585 1588
1586 1589 <title>Help: remove</title>
1587 1590 </head>
1588 1591 <body>
1589 1592
1590 1593 <div class="container">
1591 1594 <div class="menu">
1592 1595 <div class="logo">
1593 1596 <a href="http://mercurial.selenic.com/">
1594 1597 <img src="/static/hglogo.png" alt="mercurial" /></a>
1595 1598 </div>
1596 1599 <ul>
1597 1600 <li><a href="/shortlog">log</a></li>
1598 1601 <li><a href="/graph">graph</a></li>
1599 1602 <li><a href="/tags">tags</a></li>
1600 1603 <li><a href="/bookmarks">bookmarks</a></li>
1601 1604 <li><a href="/branches">branches</a></li>
1602 1605 </ul>
1603 1606 <ul>
1604 1607 <li class="active"><a href="/help">help</a></li>
1605 1608 </ul>
1606 1609 </div>
1607 1610
1608 1611 <div class="main">
1609 1612 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1610 1613 <h3>Help: remove</h3>
1611 1614
1612 1615 <form class="search" action="/log">
1613 1616
1614 1617 <p><input name="rev" id="search1" type="text" size="30" /></p>
1615 1618 <div id="hint">find changesets by author, revision,
1616 1619 files, or words in the commit message</div>
1617 1620 </form>
1618 1621 <div id="doc">
1619 1622 <p>
1620 1623 hg remove [OPTION]... FILE...
1621 1624 </p>
1622 1625 <p>
1623 1626 aliases: rm
1624 1627 </p>
1625 1628 <p>
1626 1629 remove the specified files on the next commit
1627 1630 </p>
1628 1631 <p>
1629 1632 Schedule the indicated files for removal from the current branch.
1630 1633 </p>
1631 1634 <p>
1632 1635 This command schedules the files to be removed at the next commit.
1633 1636 To undo a remove before that, see "hg revert". To undo added
1634 1637 files, see "hg forget".
1635 1638 </p>
1636 1639 <p>
1637 1640 Returns 0 on success, 1 if any warnings encountered.
1638 1641 </p>
1639 1642 <p>
1640 1643 options:
1641 1644 </p>
1642 1645 <table>
1643 1646 <tr><th>-A</th><th>--after</th><th>record delete for missing files</th></tr>
1644 1647 <tr><td>-f</td><td>--force</td><td>remove (and delete) file even if added or modified</td></tr>
1645 1648 <tr><td>-I</td><td>--include PATTERN [+]</td><td>include names matching the given patterns</td></tr>
1646 1649 <tr><td>-X</td><td>--exclude PATTERN [+]</td><td>exclude names matching the given patterns</td></tr>
1647 1650 </table>
1648 1651 <p>
1649 1652 [+] marked option can be specified multiple times
1650 1653 </p>
1651 1654 <p>
1652 1655 global options:
1653 1656 </p>
1654 1657 <table>
1655 1658 <tr><th>-R</th><th>--repository REPO</th><th>repository root directory or name of overlay bundle file</th></tr>
1656 1659 <tr><td></td><td>--cwd DIR</td><td>change working directory</td></tr>
1657 1660 <tr><td>-y</td><td>--noninteractive</td><td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1658 1661 <tr><td>-q</td><td>--quiet</td><td>suppress output</td></tr>
1659 1662 <tr><td>-v</td><td>--verbose</td><td>enable additional output</td></tr>
1660 1663 <tr><td></td><td>--config CONFIG [+]</td><td>set/override config option (use 'section.name=value')</td></tr>
1661 1664 <tr><td></td><td>--debug</td><td>enable debugging output</td></tr>
1662 1665 <tr><td></td><td>--debugger</td><td>start debugger</td></tr>
1663 1666 <tr><td></td><td>--encoding ENCODE</td><td>set the charset encoding (default: ascii)</td></tr>
1664 1667 <tr><td></td><td>--encodingmode MODE</td><td>set the charset encoding mode (default: strict)</td></tr>
1665 1668 <tr><td></td><td>--traceback</td><td>always print a traceback on exception</td></tr>
1666 1669 <tr><td></td><td>--time</td><td>time how long the command takes</td></tr>
1667 1670 <tr><td></td><td>--profile</td><td>print command execution profile</td></tr>
1668 1671 <tr><td></td><td>--version</td><td>output version information and exit</td></tr>
1669 1672 <tr><td>-h</td><td>--help</td><td>display help and exit</td></tr>
1670 1673 <tr><td></td><td>--hidden</td><td>consider hidden changesets</td></tr>
1671 1674 </table>
1672 1675 <p>
1673 1676 [+] marked option can be specified multiple times
1674 1677 </p>
1675 1678
1676 1679 </div>
1677 1680 </div>
1678 1681 </div>
1679 1682
1680 1683 <script type="text/javascript">process_dates()</script>
1681 1684
1682 1685
1683 1686 </body>
1684 1687 </html>
1685 1688
1686 1689
1687 1690 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/revisions"
1688 1691 200 Script output follows
1689 1692
1690 1693 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1691 1694 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1692 1695 <head>
1693 1696 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1694 1697 <meta name="robots" content="index, nofollow" />
1695 1698 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1696 1699 <script type="text/javascript" src="/static/mercurial.js"></script>
1697 1700
1698 1701 <title>Help: revisions</title>
1699 1702 </head>
1700 1703 <body>
1701 1704
1702 1705 <div class="container">
1703 1706 <div class="menu">
1704 1707 <div class="logo">
1705 1708 <a href="http://mercurial.selenic.com/">
1706 1709 <img src="/static/hglogo.png" alt="mercurial" /></a>
1707 1710 </div>
1708 1711 <ul>
1709 1712 <li><a href="/shortlog">log</a></li>
1710 1713 <li><a href="/graph">graph</a></li>
1711 1714 <li><a href="/tags">tags</a></li>
1712 1715 <li><a href="/bookmarks">bookmarks</a></li>
1713 1716 <li><a href="/branches">branches</a></li>
1714 1717 </ul>
1715 1718 <ul>
1716 1719 <li class="active"><a href="/help">help</a></li>
1717 1720 </ul>
1718 1721 </div>
1719 1722
1720 1723 <div class="main">
1721 1724 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1722 1725 <h3>Help: revisions</h3>
1723 1726
1724 1727 <form class="search" action="/log">
1725 1728
1726 1729 <p><input name="rev" id="search1" type="text" size="30" /></p>
1727 1730 <div id="hint">find changesets by author, revision,
1728 1731 files, or words in the commit message</div>
1729 1732 </form>
1730 1733 <div id="doc">
1731 <p>
1732 Specifying Single Revisions
1733 </p>
1734 <h1>Specifying Single Revisions</h1>
1734 1735 <p>
1735 1736 Mercurial supports several ways to specify individual revisions.
1736 1737 </p>
1737 1738 <p>
1738 1739 A plain integer is treated as a revision number. Negative integers are
1739 1740 treated as sequential offsets from the tip, with -1 denoting the tip,
1740 1741 -2 denoting the revision prior to the tip, and so forth.
1741 1742 </p>
1742 1743 <p>
1743 1744 A 40-digit hexadecimal string is treated as a unique revision
1744 1745 identifier.
1745 1746 </p>
1746 1747 <p>
1747 1748 A hexadecimal string less than 40 characters long is treated as a
1748 1749 unique revision identifier and is referred to as a short-form
1749 1750 identifier. A short-form identifier is only valid if it is the prefix
1750 1751 of exactly one full-length identifier.
1751 1752 </p>
1752 1753 <p>
1753 1754 Any other string is treated as a bookmark, tag, or branch name. A
1754 1755 bookmark is a movable pointer to a revision. A tag is a permanent name
1755 1756 associated with a revision. A branch name denotes the tipmost revision
1756 1757 of that branch. Bookmark, tag, and branch names must not contain the ":"
1757 1758 character.
1758 1759 </p>
1759 1760 <p>
1760 1761 The reserved name "tip" always identifies the most recent revision.
1761 1762 </p>
1762 1763 <p>
1763 1764 The reserved name "null" indicates the null revision. This is the
1764 1765 revision of an empty repository, and the parent of revision 0.
1765 1766 </p>
1766 1767 <p>
1767 1768 The reserved name "." indicates the working directory parent. If no
1768 1769 working directory is checked out, it is equivalent to null. If an
1769 1770 uncommitted merge is in progress, "." is the revision of the first
1770 1771 parent.
1771 1772 </p>
1772 1773
1773 1774 </div>
1774 1775 </div>
1775 1776 </div>
1776 1777
1777 1778 <script type="text/javascript">process_dates()</script>
1778 1779
1779 1780
1780 1781 </body>
1781 1782 </html>
1782 1783
1783 1784
1784 1785 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1785 1786
1786 1787 #endif
General Comments 0
You need to be logged in to leave comments. Login now