##// END OF EJS Templates
help: make help deprecated mention the extension...
timeless -
r27152:ac27b1b3 default
parent child Browse files
Show More
@@ -1,536 +1,537 b''
1 # help.py - help data for mercurial
1 # help.py - help data for mercurial
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import gettext, _
8 from i18n import gettext, _
9 import itertools, os, textwrap
9 import itertools, os, textwrap
10 import error
10 import error
11 import extensions, revset, fileset, templatekw, templatefilters, filemerge
11 import extensions, revset, fileset, templatekw, templatefilters, filemerge
12 import templater
12 import templater
13 import encoding, util, minirst
13 import encoding, util, minirst
14 import cmdutil
14 import cmdutil
15 import hgweb.webcommands as webcommands
15 import hgweb.webcommands as webcommands
16
16
17 _exclkeywords = [
17 _exclkeywords = [
18 "(DEPRECATED)",
18 "(DEPRECATED)",
19 "(EXPERIMENTAL)",
19 "(EXPERIMENTAL)",
20 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently
20 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently
21 _("(DEPRECATED)"),
21 _("(DEPRECATED)"),
22 # i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently
22 # i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently
23 _("(EXPERIMENTAL)"),
23 _("(EXPERIMENTAL)"),
24 ]
24 ]
25
25
26 def listexts(header, exts, indent=1, showdeprecated=False):
26 def listexts(header, exts, indent=1, showdeprecated=False):
27 '''return a text listing of the given extensions'''
27 '''return a text listing of the given extensions'''
28 rst = []
28 rst = []
29 if exts:
29 if exts:
30 for name, desc in sorted(exts.iteritems()):
30 for name, desc in sorted(exts.iteritems()):
31 if not showdeprecated and any(w in desc for w in _exclkeywords):
31 if not showdeprecated and any(w in desc for w in _exclkeywords):
32 continue
32 continue
33 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
33 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
34 if rst:
34 if rst:
35 rst.insert(0, '\n%s\n\n' % header)
35 rst.insert(0, '\n%s\n\n' % header)
36 return rst
36 return rst
37
37
38 def extshelp(ui):
38 def extshelp(ui):
39 rst = loaddoc('extensions')(ui).splitlines(True)
39 rst = loaddoc('extensions')(ui).splitlines(True)
40 rst.extend(listexts(
40 rst.extend(listexts(
41 _('enabled extensions:'), extensions.enabled(), showdeprecated=True))
41 _('enabled extensions:'), extensions.enabled(), showdeprecated=True))
42 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
42 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
43 doc = ''.join(rst)
43 doc = ''.join(rst)
44 return doc
44 return doc
45
45
46 def optrst(header, options, verbose):
46 def optrst(header, options, verbose):
47 data = []
47 data = []
48 multioccur = False
48 multioccur = False
49 for option in options:
49 for option in options:
50 if len(option) == 5:
50 if len(option) == 5:
51 shortopt, longopt, default, desc, optlabel = option
51 shortopt, longopt, default, desc, optlabel = option
52 else:
52 else:
53 shortopt, longopt, default, desc = option
53 shortopt, longopt, default, desc = option
54 optlabel = _("VALUE") # default label
54 optlabel = _("VALUE") # default label
55
55
56 if not verbose and any(w in desc for w in _exclkeywords):
56 if not verbose and any(w in desc for w in _exclkeywords):
57 continue
57 continue
58
58
59 so = ''
59 so = ''
60 if shortopt:
60 if shortopt:
61 so = '-' + shortopt
61 so = '-' + shortopt
62 lo = '--' + longopt
62 lo = '--' + longopt
63 if default:
63 if default:
64 desc += _(" (default: %s)") % default
64 desc += _(" (default: %s)") % default
65
65
66 if isinstance(default, list):
66 if isinstance(default, list):
67 lo += " %s [+]" % optlabel
67 lo += " %s [+]" % optlabel
68 multioccur = True
68 multioccur = True
69 elif (default is not None) and not isinstance(default, bool):
69 elif (default is not None) and not isinstance(default, bool):
70 lo += " %s" % optlabel
70 lo += " %s" % optlabel
71
71
72 data.append((so, lo, desc))
72 data.append((so, lo, desc))
73
73
74 if multioccur:
74 if multioccur:
75 header += (_(" ([+] can be repeated)"))
75 header += (_(" ([+] can be repeated)"))
76
76
77 rst = ['\n%s:\n\n' % header]
77 rst = ['\n%s:\n\n' % header]
78 rst.extend(minirst.maketable(data, 1))
78 rst.extend(minirst.maketable(data, 1))
79
79
80 return ''.join(rst)
80 return ''.join(rst)
81
81
82 def indicateomitted(rst, omitted, notomitted=None):
82 def indicateomitted(rst, omitted, notomitted=None):
83 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
83 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
84 if notomitted:
84 if notomitted:
85 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
85 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
86
86
87 def topicmatch(ui, kw):
87 def topicmatch(ui, kw):
88 """Return help topics matching kw.
88 """Return help topics matching kw.
89
89
90 Returns {'section': [(name, summary), ...], ...} where section is
90 Returns {'section': [(name, summary), ...], ...} where section is
91 one of topics, commands, extensions, or extensioncommands.
91 one of topics, commands, extensions, or extensioncommands.
92 """
92 """
93 kw = encoding.lower(kw)
93 kw = encoding.lower(kw)
94 def lowercontains(container):
94 def lowercontains(container):
95 return kw in encoding.lower(container) # translated in helptable
95 return kw in encoding.lower(container) # translated in helptable
96 results = {'topics': [],
96 results = {'topics': [],
97 'commands': [],
97 'commands': [],
98 'extensions': [],
98 'extensions': [],
99 'extensioncommands': [],
99 'extensioncommands': [],
100 }
100 }
101 for names, header, doc in helptable:
101 for names, header, doc in helptable:
102 # Old extensions may use a str as doc.
102 # Old extensions may use a str as doc.
103 if (sum(map(lowercontains, names))
103 if (sum(map(lowercontains, names))
104 or lowercontains(header)
104 or lowercontains(header)
105 or (callable(doc) and lowercontains(doc(ui)))):
105 or (callable(doc) and lowercontains(doc(ui)))):
106 results['topics'].append((names[0], header))
106 results['topics'].append((names[0], header))
107 import commands # avoid cycle
107 import commands # avoid cycle
108 for cmd, entry in commands.table.iteritems():
108 for cmd, entry in commands.table.iteritems():
109 if len(entry) == 3:
109 if len(entry) == 3:
110 summary = entry[2]
110 summary = entry[2]
111 else:
111 else:
112 summary = ''
112 summary = ''
113 # translate docs *before* searching there
113 # translate docs *before* searching there
114 docs = _(getattr(entry[0], '__doc__', None)) or ''
114 docs = _(getattr(entry[0], '__doc__', None)) or ''
115 if kw in cmd or lowercontains(summary) or lowercontains(docs):
115 if kw in cmd or lowercontains(summary) or lowercontains(docs):
116 doclines = docs.splitlines()
116 doclines = docs.splitlines()
117 if doclines:
117 if doclines:
118 summary = doclines[0]
118 summary = doclines[0]
119 cmdname = cmd.partition('|')[0].lstrip('^')
119 cmdname = cmd.partition('|')[0].lstrip('^')
120 results['commands'].append((cmdname, summary))
120 results['commands'].append((cmdname, summary))
121 for name, docs in itertools.chain(
121 for name, docs in itertools.chain(
122 extensions.enabled(False).iteritems(),
122 extensions.enabled(False).iteritems(),
123 extensions.disabled().iteritems()):
123 extensions.disabled().iteritems()):
124 # extensions.load ignores the UI argument
124 # extensions.load ignores the UI argument
125 mod = extensions.load(None, name, '')
125 mod = extensions.load(None, name, '')
126 name = name.rpartition('.')[-1]
126 name = name.rpartition('.')[-1]
127 if lowercontains(name) or lowercontains(docs):
127 if lowercontains(name) or lowercontains(docs):
128 # extension docs are already translated
128 # extension docs are already translated
129 results['extensions'].append((name, docs.splitlines()[0]))
129 results['extensions'].append((name, docs.splitlines()[0]))
130 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
130 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
131 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
131 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
132 cmdname = cmd.partition('|')[0].lstrip('^')
132 cmdname = cmd.partition('|')[0].lstrip('^')
133 if entry[0].__doc__:
133 if entry[0].__doc__:
134 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
134 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
135 else:
135 else:
136 cmddoc = _('(no help text available)')
136 cmddoc = _('(no help text available)')
137 results['extensioncommands'].append((cmdname, cmddoc))
137 results['extensioncommands'].append((cmdname, cmddoc))
138 return results
138 return results
139
139
140 def loaddoc(topic):
140 def loaddoc(topic):
141 """Return a delayed loader for help/topic.txt."""
141 """Return a delayed loader for help/topic.txt."""
142
142
143 def loader(ui):
143 def loader(ui):
144 docdir = os.path.join(util.datapath, 'help')
144 docdir = os.path.join(util.datapath, 'help')
145 path = os.path.join(docdir, topic + ".txt")
145 path = os.path.join(docdir, topic + ".txt")
146 doc = gettext(util.readfile(path))
146 doc = gettext(util.readfile(path))
147 for rewriter in helphooks.get(topic, []):
147 for rewriter in helphooks.get(topic, []):
148 doc = rewriter(ui, topic, doc)
148 doc = rewriter(ui, topic, doc)
149 return doc
149 return doc
150
150
151 return loader
151 return loader
152
152
153 helptable = sorted([
153 helptable = sorted([
154 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
154 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
155 (["dates"], _("Date Formats"), loaddoc('dates')),
155 (["dates"], _("Date Formats"), loaddoc('dates')),
156 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
156 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
157 (['environment', 'env'], _('Environment Variables'),
157 (['environment', 'env'], _('Environment Variables'),
158 loaddoc('environment')),
158 loaddoc('environment')),
159 (['revisions', 'revs'], _('Specifying Single Revisions'),
159 (['revisions', 'revs'], _('Specifying Single Revisions'),
160 loaddoc('revisions')),
160 loaddoc('revisions')),
161 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
161 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
162 loaddoc('multirevs')),
162 loaddoc('multirevs')),
163 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
163 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
164 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
164 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
165 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
165 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
166 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
166 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
167 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
167 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
168 loaddoc('templates')),
168 loaddoc('templates')),
169 (['urls'], _('URL Paths'), loaddoc('urls')),
169 (['urls'], _('URL Paths'), loaddoc('urls')),
170 (["extensions"], _("Using Additional Features"), extshelp),
170 (["extensions"], _("Using Additional Features"), extshelp),
171 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
171 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
172 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
172 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
173 (["glossary"], _("Glossary"), loaddoc('glossary')),
173 (["glossary"], _("Glossary"), loaddoc('glossary')),
174 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
174 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
175 loaddoc('hgignore')),
175 loaddoc('hgignore')),
176 (["phases"], _("Working with Phases"), loaddoc('phases')),
176 (["phases"], _("Working with Phases"), loaddoc('phases')),
177 (['scripting'], _('Using Mercurial from scripts and automation'),
177 (['scripting'], _('Using Mercurial from scripts and automation'),
178 loaddoc('scripting')),
178 loaddoc('scripting')),
179 ])
179 ])
180
180
181 # Map topics to lists of callable taking the current topic help and
181 # Map topics to lists of callable taking the current topic help and
182 # returning the updated version
182 # returning the updated version
183 helphooks = {}
183 helphooks = {}
184
184
185 def addtopichook(topic, rewriter):
185 def addtopichook(topic, rewriter):
186 helphooks.setdefault(topic, []).append(rewriter)
186 helphooks.setdefault(topic, []).append(rewriter)
187
187
188 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False):
188 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False):
189 """Extract docstring from the items key to function mapping, build a
189 """Extract docstring from the items key to function mapping, build a
190 single documentation block and use it to overwrite the marker in doc.
190 single documentation block and use it to overwrite the marker in doc.
191 """
191 """
192 entries = []
192 entries = []
193 for name in sorted(items):
193 for name in sorted(items):
194 text = (items[name].__doc__ or '').rstrip()
194 text = (items[name].__doc__ or '').rstrip()
195 if (not text
195 if (not text
196 or not ui.verbose and any(w in text for w in _exclkeywords)):
196 or not ui.verbose and any(w in text for w in _exclkeywords)):
197 continue
197 continue
198 text = gettext(text)
198 text = gettext(text)
199 if dedent:
199 if dedent:
200 text = textwrap.dedent(text)
200 text = textwrap.dedent(text)
201 lines = text.splitlines()
201 lines = text.splitlines()
202 doclines = [(lines[0])]
202 doclines = [(lines[0])]
203 for l in lines[1:]:
203 for l in lines[1:]:
204 # Stop once we find some Python doctest
204 # Stop once we find some Python doctest
205 if l.strip().startswith('>>>'):
205 if l.strip().startswith('>>>'):
206 break
206 break
207 if dedent:
207 if dedent:
208 doclines.append(l.rstrip())
208 doclines.append(l.rstrip())
209 else:
209 else:
210 doclines.append(' ' + l.strip())
210 doclines.append(' ' + l.strip())
211 entries.append('\n'.join(doclines))
211 entries.append('\n'.join(doclines))
212 entries = '\n\n'.join(entries)
212 entries = '\n\n'.join(entries)
213 return doc.replace(marker, entries)
213 return doc.replace(marker, entries)
214
214
215 def addtopicsymbols(topic, marker, symbols, dedent=False):
215 def addtopicsymbols(topic, marker, symbols, dedent=False):
216 def add(ui, topic, doc):
216 def add(ui, topic, doc):
217 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent)
217 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent)
218 addtopichook(topic, add)
218 addtopichook(topic, add)
219
219
220 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
220 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
221 addtopicsymbols('merge-tools', '.. internaltoolsmarker',
221 addtopicsymbols('merge-tools', '.. internaltoolsmarker',
222 filemerge.internalsdoc)
222 filemerge.internalsdoc)
223 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
223 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
224 addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords)
224 addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords)
225 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
225 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
226 addtopicsymbols('templates', '.. functionsmarker', templater.funcs)
226 addtopicsymbols('templates', '.. functionsmarker', templater.funcs)
227 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
227 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
228 dedent=True)
228 dedent=True)
229
229
230 def help_(ui, name, unknowncmd=False, full=True, **opts):
230 def help_(ui, name, unknowncmd=False, full=True, **opts):
231 '''
231 '''
232 Generate the help for 'name' as unformatted restructured text. If
232 Generate the help for 'name' as unformatted restructured text. If
233 'name' is None, describe the commands available.
233 'name' is None, describe the commands available.
234 '''
234 '''
235
235
236 import commands # avoid cycle
236 import commands # avoid cycle
237
237
238 def helpcmd(name):
238 def helpcmd(name):
239 try:
239 try:
240 aliases, entry = cmdutil.findcmd(name, commands.table,
240 aliases, entry = cmdutil.findcmd(name, commands.table,
241 strict=unknowncmd)
241 strict=unknowncmd)
242 except error.AmbiguousCommand as inst:
242 except error.AmbiguousCommand as inst:
243 # py3k fix: except vars can't be used outside the scope of the
243 # py3k fix: except vars can't be used outside the scope of the
244 # except block, nor can be used inside a lambda. python issue4617
244 # except block, nor can be used inside a lambda. python issue4617
245 prefix = inst.args[0]
245 prefix = inst.args[0]
246 select = lambda c: c.lstrip('^').startswith(prefix)
246 select = lambda c: c.lstrip('^').startswith(prefix)
247 rst = helplist(select)
247 rst = helplist(select)
248 return rst
248 return rst
249
249
250 rst = []
250 rst = []
251
251
252 # check if it's an invalid alias and display its error if it is
252 # check if it's an invalid alias and display its error if it is
253 if getattr(entry[0], 'badalias', None):
253 if getattr(entry[0], 'badalias', None):
254 rst.append(entry[0].badalias + '\n')
254 rst.append(entry[0].badalias + '\n')
255 if entry[0].unknowncmd:
255 if entry[0].unknowncmd:
256 try:
256 try:
257 rst.extend(helpextcmd(entry[0].cmdname))
257 rst.extend(helpextcmd(entry[0].cmdname))
258 except error.UnknownCommand:
258 except error.UnknownCommand:
259 pass
259 pass
260 return rst
260 return rst
261
261
262 # synopsis
262 # synopsis
263 if len(entry) > 2:
263 if len(entry) > 2:
264 if entry[2].startswith('hg'):
264 if entry[2].startswith('hg'):
265 rst.append("%s\n" % entry[2])
265 rst.append("%s\n" % entry[2])
266 else:
266 else:
267 rst.append('hg %s %s\n' % (aliases[0], entry[2]))
267 rst.append('hg %s %s\n' % (aliases[0], entry[2]))
268 else:
268 else:
269 rst.append('hg %s\n' % aliases[0])
269 rst.append('hg %s\n' % aliases[0])
270 # aliases
270 # aliases
271 if full and not ui.quiet and len(aliases) > 1:
271 if full and not ui.quiet and len(aliases) > 1:
272 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
272 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
273 rst.append('\n')
273 rst.append('\n')
274
274
275 # description
275 # description
276 doc = gettext(entry[0].__doc__)
276 doc = gettext(entry[0].__doc__)
277 if not doc:
277 if not doc:
278 doc = _("(no help text available)")
278 doc = _("(no help text available)")
279 if util.safehasattr(entry[0], 'definition'): # aliased command
279 if util.safehasattr(entry[0], 'definition'): # aliased command
280 if entry[0].definition.startswith('!'): # shell alias
280 if entry[0].definition.startswith('!'): # shell alias
281 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
281 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
282 else:
282 else:
283 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
283 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
284 doc = doc.splitlines(True)
284 doc = doc.splitlines(True)
285 if ui.quiet or not full:
285 if ui.quiet or not full:
286 rst.append(doc[0])
286 rst.append(doc[0])
287 else:
287 else:
288 rst.extend(doc)
288 rst.extend(doc)
289 rst.append('\n')
289 rst.append('\n')
290
290
291 # check if this command shadows a non-trivial (multi-line)
291 # check if this command shadows a non-trivial (multi-line)
292 # extension help text
292 # extension help text
293 try:
293 try:
294 mod = extensions.find(name)
294 mod = extensions.find(name)
295 doc = gettext(mod.__doc__) or ''
295 doc = gettext(mod.__doc__) or ''
296 if '\n' in doc.strip():
296 if '\n' in doc.strip():
297 msg = _('(use "hg help -e %s" to show help for '
297 msg = _('(use "hg help -e %s" to show help for '
298 'the %s extension)') % (name, name)
298 'the %s extension)') % (name, name)
299 rst.append('\n%s\n' % msg)
299 rst.append('\n%s\n' % msg)
300 except KeyError:
300 except KeyError:
301 pass
301 pass
302
302
303 # options
303 # options
304 if not ui.quiet and entry[1]:
304 if not ui.quiet and entry[1]:
305 rst.append(optrst(_("options"), entry[1], ui.verbose))
305 rst.append(optrst(_("options"), entry[1], ui.verbose))
306
306
307 if ui.verbose:
307 if ui.verbose:
308 rst.append(optrst(_("global options"),
308 rst.append(optrst(_("global options"),
309 commands.globalopts, ui.verbose))
309 commands.globalopts, ui.verbose))
310
310
311 if not ui.verbose:
311 if not ui.verbose:
312 if not full:
312 if not full:
313 rst.append(_('\n(use "hg %s -h" to show more help)\n')
313 rst.append(_('\n(use "hg %s -h" to show more help)\n')
314 % name)
314 % name)
315 elif not ui.quiet:
315 elif not ui.quiet:
316 rst.append(_('\n(some details hidden, use --verbose '
316 rst.append(_('\n(some details hidden, use --verbose '
317 'to show complete help)'))
317 'to show complete help)'))
318
318
319 return rst
319 return rst
320
320
321
321
322 def helplist(select=None):
322 def helplist(select=None):
323 # list of commands
323 # list of commands
324 if name == "shortlist":
324 if name == "shortlist":
325 header = _('basic commands:\n\n')
325 header = _('basic commands:\n\n')
326 elif name == "debug":
326 elif name == "debug":
327 header = _('debug commands (internal and unsupported):\n\n')
327 header = _('debug commands (internal and unsupported):\n\n')
328 else:
328 else:
329 header = _('list of commands:\n\n')
329 header = _('list of commands:\n\n')
330
330
331 h = {}
331 h = {}
332 cmds = {}
332 cmds = {}
333 for c, e in commands.table.iteritems():
333 for c, e in commands.table.iteritems():
334 f = c.partition("|")[0]
334 f = c.partition("|")[0]
335 if select and not select(f):
335 if select and not select(f):
336 continue
336 continue
337 if (not select and name != 'shortlist' and
337 if (not select and name != 'shortlist' and
338 e[0].__module__ != commands.__name__):
338 e[0].__module__ != commands.__name__):
339 continue
339 continue
340 if name == "shortlist" and not f.startswith("^"):
340 if name == "shortlist" and not f.startswith("^"):
341 continue
341 continue
342 f = f.lstrip("^")
342 f = f.lstrip("^")
343 if not ui.debugflag and f.startswith("debug") and name != "debug":
343 if not ui.debugflag and f.startswith("debug") and name != "debug":
344 continue
344 continue
345 doc = e[0].__doc__
345 doc = e[0].__doc__
346 if not ui.verbose and doc and any(w in doc for w in _exclkeywords):
346 if not ui.verbose and doc and any(w in doc for w in _exclkeywords):
347 continue
347 continue
348 doc = gettext(doc)
348 doc = gettext(doc)
349 if not doc:
349 if not doc:
350 doc = _("(no help text available)")
350 doc = _("(no help text available)")
351 h[f] = doc.splitlines()[0].rstrip()
351 h[f] = doc.splitlines()[0].rstrip()
352 cmds[f] = c.lstrip("^")
352 cmds[f] = c.lstrip("^")
353
353
354 rst = []
354 rst = []
355 if not h:
355 if not h:
356 if not ui.quiet:
356 if not ui.quiet:
357 rst.append(_('no commands defined\n'))
357 rst.append(_('no commands defined\n'))
358 return rst
358 return rst
359
359
360 if not ui.quiet:
360 if not ui.quiet:
361 rst.append(header)
361 rst.append(header)
362 fns = sorted(h)
362 fns = sorted(h)
363 for f in fns:
363 for f in fns:
364 if ui.verbose:
364 if ui.verbose:
365 commacmds = cmds[f].replace("|",", ")
365 commacmds = cmds[f].replace("|",", ")
366 rst.append(" :%s: %s\n" % (commacmds, h[f]))
366 rst.append(" :%s: %s\n" % (commacmds, h[f]))
367 else:
367 else:
368 rst.append(' :%s: %s\n' % (f, h[f]))
368 rst.append(' :%s: %s\n' % (f, h[f]))
369
369
370 if not name:
370 if not name:
371 exts = listexts(_('enabled extensions:'), extensions.enabled())
371 exts = listexts(_('enabled extensions:'), extensions.enabled())
372 if exts:
372 if exts:
373 rst.append('\n')
373 rst.append('\n')
374 rst.extend(exts)
374 rst.extend(exts)
375
375
376 rst.append(_("\nadditional help topics:\n\n"))
376 rst.append(_("\nadditional help topics:\n\n"))
377 topics = []
377 topics = []
378 for names, header, doc in helptable:
378 for names, header, doc in helptable:
379 topics.append((names[0], header))
379 topics.append((names[0], header))
380 for t, desc in topics:
380 for t, desc in topics:
381 rst.append(" :%s: %s\n" % (t, desc))
381 rst.append(" :%s: %s\n" % (t, desc))
382
382
383 if ui.quiet:
383 if ui.quiet:
384 pass
384 pass
385 elif ui.verbose:
385 elif ui.verbose:
386 rst.append('\n%s\n' % optrst(_("global options"),
386 rst.append('\n%s\n' % optrst(_("global options"),
387 commands.globalopts, ui.verbose))
387 commands.globalopts, ui.verbose))
388 if name == 'shortlist':
388 if name == 'shortlist':
389 rst.append(_('\n(use "hg help" for the full list '
389 rst.append(_('\n(use "hg help" for the full list '
390 'of commands)\n'))
390 'of commands)\n'))
391 else:
391 else:
392 if name == 'shortlist':
392 if name == 'shortlist':
393 rst.append(_('\n(use "hg help" for the full list of commands '
393 rst.append(_('\n(use "hg help" for the full list of commands '
394 'or "hg -v" for details)\n'))
394 'or "hg -v" for details)\n'))
395 elif name and not full:
395 elif name and not full:
396 rst.append(_('\n(use "hg help %s" to show the full help '
396 rst.append(_('\n(use "hg help %s" to show the full help '
397 'text)\n') % name)
397 'text)\n') % name)
398 elif name and cmds and name in cmds.keys():
398 elif name and cmds and name in cmds.keys():
399 rst.append(_('\n(use "hg help -v -e %s" to show built-in '
399 rst.append(_('\n(use "hg help -v -e %s" to show built-in '
400 'aliases and global options)\n') % name)
400 'aliases and global options)\n') % name)
401 else:
401 else:
402 rst.append(_('\n(use "hg help -v%s" to show built-in aliases '
402 rst.append(_('\n(use "hg help -v%s" to show built-in aliases '
403 'and global options)\n')
403 'and global options)\n')
404 % (name and " " + name or ""))
404 % (name and " " + name or ""))
405 return rst
405 return rst
406
406
407 def helptopic(name):
407 def helptopic(name):
408 for names, header, doc in helptable:
408 for names, header, doc in helptable:
409 if name in names:
409 if name in names:
410 break
410 break
411 else:
411 else:
412 raise error.UnknownCommand(name)
412 raise error.UnknownCommand(name)
413
413
414 rst = [minirst.section(header)]
414 rst = [minirst.section(header)]
415
415
416 # description
416 # description
417 if not doc:
417 if not doc:
418 rst.append(" %s\n" % _("(no help text available)"))
418 rst.append(" %s\n" % _("(no help text available)"))
419 if callable(doc):
419 if callable(doc):
420 rst += [" %s\n" % l for l in doc(ui).splitlines()]
420 rst += [" %s\n" % l for l in doc(ui).splitlines()]
421
421
422 if not ui.verbose:
422 if not ui.verbose:
423 omitted = _('(some details hidden, use --verbose'
423 omitted = _('(some details hidden, use --verbose'
424 ' to show complete help)')
424 ' to show complete help)')
425 indicateomitted(rst, omitted)
425 indicateomitted(rst, omitted)
426
426
427 try:
427 try:
428 cmdutil.findcmd(name, commands.table)
428 cmdutil.findcmd(name, commands.table)
429 rst.append(_('\nuse "hg help -c %s" to see help for '
429 rst.append(_('\nuse "hg help -c %s" to see help for '
430 'the %s command\n') % (name, name))
430 'the %s command\n') % (name, name))
431 except error.UnknownCommand:
431 except error.UnknownCommand:
432 pass
432 pass
433 return rst
433 return rst
434
434
435 def helpext(name):
435 def helpext(name):
436 try:
436 try:
437 mod = extensions.find(name)
437 mod = extensions.find(name)
438 doc = gettext(mod.__doc__) or _('no help text available')
438 doc = gettext(mod.__doc__) or _('no help text available')
439 except KeyError:
439 except KeyError:
440 mod = None
440 mod = None
441 doc = extensions.disabledext(name)
441 doc = extensions.disabledext(name)
442 if not doc:
442 if not doc:
443 raise error.UnknownCommand(name)
443 raise error.UnknownCommand(name)
444
444
445 if '\n' not in doc:
445 if '\n' not in doc:
446 head, tail = doc, ""
446 head, tail = doc, ""
447 else:
447 else:
448 head, tail = doc.split('\n', 1)
448 head, tail = doc.split('\n', 1)
449 rst = [_('%s extension - %s\n\n') % (name.rpartition('.')[-1], head)]
449 rst = [_('%s extension - %s\n\n') % (name.rpartition('.')[-1], head)]
450 if tail:
450 if tail:
451 rst.extend(tail.splitlines(True))
451 rst.extend(tail.splitlines(True))
452 rst.append('\n')
452 rst.append('\n')
453
453
454 if not ui.verbose:
454 if not ui.verbose:
455 omitted = _('(some details hidden, use --verbose'
455 omitted = _('(some details hidden, use --verbose'
456 ' to show complete help)')
456 ' to show complete help)')
457 indicateomitted(rst, omitted)
457 indicateomitted(rst, omitted)
458
458
459 if mod:
459 if mod:
460 try:
460 try:
461 ct = mod.cmdtable
461 ct = mod.cmdtable
462 except AttributeError:
462 except AttributeError:
463 ct = {}
463 ct = {}
464 modcmds = set([c.partition('|')[0] for c in ct])
464 modcmds = set([c.partition('|')[0] for c in ct])
465 rst.extend(helplist(modcmds.__contains__))
465 rst.extend(helplist(modcmds.__contains__))
466 else:
466 else:
467 rst.append(_('(use "hg help extensions" for information on enabling'
467 rst.append(_('(use "hg help extensions" for information on enabling'
468 ' extensions)\n'))
468 ' extensions)\n'))
469 return rst
469 return rst
470
470
471 def helpextcmd(name):
471 def helpextcmd(name):
472 cmd, ext, mod = extensions.disabledcmd(ui, name,
472 cmd, ext, mod = extensions.disabledcmd(ui, name,
473 ui.configbool('ui', 'strict'))
473 ui.configbool('ui', 'strict'))
474 doc = gettext(mod.__doc__).splitlines()[0]
474 doc = gettext(mod.__doc__).splitlines()[0]
475
475
476 rst = listexts(_("'%s' is provided by the following "
476 rst = listexts(_("'%s' is provided by the following "
477 "extension:") % cmd, {ext: doc}, indent=4)
477 "extension:") % cmd, {ext: doc}, indent=4,
478 showdeprecated=True)
478 rst.append('\n')
479 rst.append('\n')
479 rst.append(_('(use "hg help extensions" for information on enabling '
480 rst.append(_('(use "hg help extensions" for information on enabling '
480 'extensions)\n'))
481 'extensions)\n'))
481 return rst
482 return rst
482
483
483
484
484 rst = []
485 rst = []
485 kw = opts.get('keyword')
486 kw = opts.get('keyword')
486 if kw:
487 if kw:
487 matches = topicmatch(ui, name)
488 matches = topicmatch(ui, name)
488 helpareas = []
489 helpareas = []
489 if opts.get('extension'):
490 if opts.get('extension'):
490 helpareas += [('extensions', _('Extensions'))]
491 helpareas += [('extensions', _('Extensions'))]
491 if opts.get('command'):
492 if opts.get('command'):
492 helpareas += [('commands', _('Commands'))]
493 helpareas += [('commands', _('Commands'))]
493 if not helpareas:
494 if not helpareas:
494 helpareas = [('topics', _('Topics')),
495 helpareas = [('topics', _('Topics')),
495 ('commands', _('Commands')),
496 ('commands', _('Commands')),
496 ('extensions', _('Extensions')),
497 ('extensions', _('Extensions')),
497 ('extensioncommands', _('Extension Commands'))]
498 ('extensioncommands', _('Extension Commands'))]
498 for t, title in helpareas:
499 for t, title in helpareas:
499 if matches[t]:
500 if matches[t]:
500 rst.append('%s:\n\n' % title)
501 rst.append('%s:\n\n' % title)
501 rst.extend(minirst.maketable(sorted(matches[t]), 1))
502 rst.extend(minirst.maketable(sorted(matches[t]), 1))
502 rst.append('\n')
503 rst.append('\n')
503 if not rst:
504 if not rst:
504 msg = _('no matches')
505 msg = _('no matches')
505 hint = _('try "hg help" for a list of topics')
506 hint = _('try "hg help" for a list of topics')
506 raise error.Abort(msg, hint=hint)
507 raise error.Abort(msg, hint=hint)
507 elif name and name != 'shortlist':
508 elif name and name != 'shortlist':
508 queries = []
509 queries = []
509 if unknowncmd:
510 if unknowncmd:
510 queries += [helpextcmd]
511 queries += [helpextcmd]
511 if opts.get('extension'):
512 if opts.get('extension'):
512 queries += [helpext]
513 queries += [helpext]
513 if opts.get('command'):
514 if opts.get('command'):
514 queries += [helpcmd]
515 queries += [helpcmd]
515 if not queries:
516 if not queries:
516 queries = (helptopic, helpcmd, helpext, helpextcmd)
517 queries = (helptopic, helpcmd, helpext, helpextcmd)
517 for f in queries:
518 for f in queries:
518 try:
519 try:
519 rst = f(name)
520 rst = f(name)
520 break
521 break
521 except error.UnknownCommand:
522 except error.UnknownCommand:
522 pass
523 pass
523 else:
524 else:
524 if unknowncmd:
525 if unknowncmd:
525 raise error.UnknownCommand(name)
526 raise error.UnknownCommand(name)
526 else:
527 else:
527 msg = _('no such help topic: %s') % name
528 msg = _('no such help topic: %s') % name
528 hint = _('try "hg help --keyword %s"') % name
529 hint = _('try "hg help --keyword %s"') % name
529 raise error.Abort(msg, hint=hint)
530 raise error.Abort(msg, hint=hint)
530 else:
531 else:
531 # program name
532 # program name
532 if not ui.quiet:
533 if not ui.quiet:
533 rst = [_("Mercurial Distributed SCM\n"), '\n']
534 rst = [_("Mercurial Distributed SCM\n"), '\n']
534 rst.extend(helplist())
535 rst.extend(helplist())
535
536
536 return ''.join(rst)
537 return ''.join(rst)
@@ -1,1215 +1,1224 b''
1 Test basic extension support
1 Test basic extension support
2
2
3 $ cat > foobar.py <<EOF
3 $ cat > foobar.py <<EOF
4 > import os
4 > import os
5 > from mercurial import cmdutil, commands
5 > from mercurial import cmdutil, commands
6 > cmdtable = {}
6 > cmdtable = {}
7 > command = cmdutil.command(cmdtable)
7 > command = cmdutil.command(cmdtable)
8 > def uisetup(ui):
8 > def uisetup(ui):
9 > ui.write("uisetup called\\n")
9 > ui.write("uisetup called\\n")
10 > def reposetup(ui, repo):
10 > def reposetup(ui, repo):
11 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
11 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
12 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
12 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
13 > @command('foo', [], 'hg foo')
13 > @command('foo', [], 'hg foo')
14 > def foo(ui, *args, **kwargs):
14 > def foo(ui, *args, **kwargs):
15 > ui.write("Foo\\n")
15 > ui.write("Foo\\n")
16 > @command('bar', [], 'hg bar', norepo=True)
16 > @command('bar', [], 'hg bar', norepo=True)
17 > def bar(ui, *args, **kwargs):
17 > def bar(ui, *args, **kwargs):
18 > ui.write("Bar\\n")
18 > ui.write("Bar\\n")
19 > EOF
19 > EOF
20 $ abspath=`pwd`/foobar.py
20 $ abspath=`pwd`/foobar.py
21
21
22 $ mkdir barfoo
22 $ mkdir barfoo
23 $ cp foobar.py barfoo/__init__.py
23 $ cp foobar.py barfoo/__init__.py
24 $ barfoopath=`pwd`/barfoo
24 $ barfoopath=`pwd`/barfoo
25
25
26 $ hg init a
26 $ hg init a
27 $ cd a
27 $ cd a
28 $ echo foo > file
28 $ echo foo > file
29 $ hg add file
29 $ hg add file
30 $ hg commit -m 'add file'
30 $ hg commit -m 'add file'
31
31
32 $ echo '[extensions]' >> $HGRCPATH
32 $ echo '[extensions]' >> $HGRCPATH
33 $ echo "foobar = $abspath" >> $HGRCPATH
33 $ echo "foobar = $abspath" >> $HGRCPATH
34 $ hg foo
34 $ hg foo
35 uisetup called
35 uisetup called
36 reposetup called for a
36 reposetup called for a
37 ui == repo.ui
37 ui == repo.ui
38 Foo
38 Foo
39
39
40 $ cd ..
40 $ cd ..
41 $ hg clone a b
41 $ hg clone a b
42 uisetup called
42 uisetup called
43 reposetup called for a
43 reposetup called for a
44 ui == repo.ui
44 ui == repo.ui
45 reposetup called for b
45 reposetup called for b
46 ui == repo.ui
46 ui == repo.ui
47 updating to branch default
47 updating to branch default
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49
49
50 $ hg bar
50 $ hg bar
51 uisetup called
51 uisetup called
52 Bar
52 Bar
53 $ echo 'foobar = !' >> $HGRCPATH
53 $ echo 'foobar = !' >> $HGRCPATH
54
54
55 module/__init__.py-style
55 module/__init__.py-style
56
56
57 $ echo "barfoo = $barfoopath" >> $HGRCPATH
57 $ echo "barfoo = $barfoopath" >> $HGRCPATH
58 $ cd a
58 $ cd a
59 $ hg foo
59 $ hg foo
60 uisetup called
60 uisetup called
61 reposetup called for a
61 reposetup called for a
62 ui == repo.ui
62 ui == repo.ui
63 Foo
63 Foo
64 $ echo 'barfoo = !' >> $HGRCPATH
64 $ echo 'barfoo = !' >> $HGRCPATH
65
65
66 Check that extensions are loaded in phases:
66 Check that extensions are loaded in phases:
67
67
68 $ cat > foo.py <<EOF
68 $ cat > foo.py <<EOF
69 > import os
69 > import os
70 > name = os.path.basename(__file__).rsplit('.', 1)[0]
70 > name = os.path.basename(__file__).rsplit('.', 1)[0]
71 > print "1) %s imported" % name
71 > print "1) %s imported" % name
72 > def uisetup(ui):
72 > def uisetup(ui):
73 > print "2) %s uisetup" % name
73 > print "2) %s uisetup" % name
74 > def extsetup():
74 > def extsetup():
75 > print "3) %s extsetup" % name
75 > print "3) %s extsetup" % name
76 > def reposetup(ui, repo):
76 > def reposetup(ui, repo):
77 > print "4) %s reposetup" % name
77 > print "4) %s reposetup" % name
78 > EOF
78 > EOF
79
79
80 $ cp foo.py bar.py
80 $ cp foo.py bar.py
81 $ echo 'foo = foo.py' >> $HGRCPATH
81 $ echo 'foo = foo.py' >> $HGRCPATH
82 $ echo 'bar = bar.py' >> $HGRCPATH
82 $ echo 'bar = bar.py' >> $HGRCPATH
83
83
84 Command with no output, we just want to see the extensions loaded:
84 Command with no output, we just want to see the extensions loaded:
85
85
86 $ hg paths
86 $ hg paths
87 1) foo imported
87 1) foo imported
88 1) bar imported
88 1) bar imported
89 2) foo uisetup
89 2) foo uisetup
90 2) bar uisetup
90 2) bar uisetup
91 3) foo extsetup
91 3) foo extsetup
92 3) bar extsetup
92 3) bar extsetup
93 4) foo reposetup
93 4) foo reposetup
94 4) bar reposetup
94 4) bar reposetup
95
95
96 Check hgweb's load order:
96 Check hgweb's load order:
97
97
98 $ cat > hgweb.cgi <<EOF
98 $ cat > hgweb.cgi <<EOF
99 > #!/usr/bin/env python
99 > #!/usr/bin/env python
100 > from mercurial import demandimport; demandimport.enable()
100 > from mercurial import demandimport; demandimport.enable()
101 > from mercurial.hgweb import hgweb
101 > from mercurial.hgweb import hgweb
102 > from mercurial.hgweb import wsgicgi
102 > from mercurial.hgweb import wsgicgi
103 > application = hgweb('.', 'test repo')
103 > application = hgweb('.', 'test repo')
104 > wsgicgi.launch(application)
104 > wsgicgi.launch(application)
105 > EOF
105 > EOF
106
106
107 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
107 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
108 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
108 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
109 > | grep '^[0-9]) ' # ignores HTML output
109 > | grep '^[0-9]) ' # ignores HTML output
110 1) foo imported
110 1) foo imported
111 1) bar imported
111 1) bar imported
112 2) foo uisetup
112 2) foo uisetup
113 2) bar uisetup
113 2) bar uisetup
114 3) foo extsetup
114 3) foo extsetup
115 3) bar extsetup
115 3) bar extsetup
116 4) foo reposetup
116 4) foo reposetup
117 4) bar reposetup
117 4) bar reposetup
118
118
119 $ echo 'foo = !' >> $HGRCPATH
119 $ echo 'foo = !' >> $HGRCPATH
120 $ echo 'bar = !' >> $HGRCPATH
120 $ echo 'bar = !' >> $HGRCPATH
121
121
122 Check "from __future__ import absolute_import" support for external libraries
122 Check "from __future__ import absolute_import" support for external libraries
123
123
124 #if windows
124 #if windows
125 $ PATHSEP=";"
125 $ PATHSEP=";"
126 #else
126 #else
127 $ PATHSEP=":"
127 $ PATHSEP=":"
128 #endif
128 #endif
129 $ export PATHSEP
129 $ export PATHSEP
130
130
131 $ mkdir $TESTTMP/libroot
131 $ mkdir $TESTTMP/libroot
132 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
132 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
133 $ mkdir $TESTTMP/libroot/mod
133 $ mkdir $TESTTMP/libroot/mod
134 $ touch $TESTTMP/libroot/mod/__init__.py
134 $ touch $TESTTMP/libroot/mod/__init__.py
135 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
135 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
136
136
137 #if absimport
137 #if absimport
138 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
138 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
139 > from __future__ import absolute_import
139 > from __future__ import absolute_import
140 > import ambig # should load "libroot/ambig.py"
140 > import ambig # should load "libroot/ambig.py"
141 > s = ambig.s
141 > s = ambig.s
142 > EOF
142 > EOF
143 $ cat > loadabs.py <<EOF
143 $ cat > loadabs.py <<EOF
144 > import mod.ambigabs as ambigabs
144 > import mod.ambigabs as ambigabs
145 > def extsetup():
145 > def extsetup():
146 > print 'ambigabs.s=%s' % ambigabs.s
146 > print 'ambigabs.s=%s' % ambigabs.s
147 > EOF
147 > EOF
148 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
148 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
149 ambigabs.s=libroot/ambig.py
149 ambigabs.s=libroot/ambig.py
150 $TESTTMP/a (glob)
150 $TESTTMP/a (glob)
151 #endif
151 #endif
152
152
153 #if no-py3k
153 #if no-py3k
154 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
154 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
155 > import ambig # should load "libroot/mod/ambig.py"
155 > import ambig # should load "libroot/mod/ambig.py"
156 > s = ambig.s
156 > s = ambig.s
157 > EOF
157 > EOF
158 $ cat > loadrel.py <<EOF
158 $ cat > loadrel.py <<EOF
159 > import mod.ambigrel as ambigrel
159 > import mod.ambigrel as ambigrel
160 > def extsetup():
160 > def extsetup():
161 > print 'ambigrel.s=%s' % ambigrel.s
161 > print 'ambigrel.s=%s' % ambigrel.s
162 > EOF
162 > EOF
163 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
163 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
164 ambigrel.s=libroot/mod/ambig.py
164 ambigrel.s=libroot/mod/ambig.py
165 $TESTTMP/a (glob)
165 $TESTTMP/a (glob)
166 #endif
166 #endif
167
167
168 Check absolute/relative import of extension specific modules
168 Check absolute/relative import of extension specific modules
169
169
170 $ mkdir $TESTTMP/extroot
170 $ mkdir $TESTTMP/extroot
171 $ cat > $TESTTMP/extroot/bar.py <<EOF
171 $ cat > $TESTTMP/extroot/bar.py <<EOF
172 > s = 'this is extroot.bar'
172 > s = 'this is extroot.bar'
173 > EOF
173 > EOF
174 $ mkdir $TESTTMP/extroot/sub1
174 $ mkdir $TESTTMP/extroot/sub1
175 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
175 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
176 > s = 'this is extroot.sub1.__init__'
176 > s = 'this is extroot.sub1.__init__'
177 > EOF
177 > EOF
178 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
178 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
179 > s = 'this is extroot.sub1.baz'
179 > s = 'this is extroot.sub1.baz'
180 > EOF
180 > EOF
181 $ cat > $TESTTMP/extroot/__init__.py <<EOF
181 $ cat > $TESTTMP/extroot/__init__.py <<EOF
182 > s = 'this is extroot.__init__'
182 > s = 'this is extroot.__init__'
183 > import foo
183 > import foo
184 > def extsetup(ui):
184 > def extsetup(ui):
185 > ui.write('(extroot) ', foo.func(), '\n')
185 > ui.write('(extroot) ', foo.func(), '\n')
186 > EOF
186 > EOF
187
187
188 $ cat > $TESTTMP/extroot/foo.py <<EOF
188 $ cat > $TESTTMP/extroot/foo.py <<EOF
189 > # test absolute import
189 > # test absolute import
190 > buf = []
190 > buf = []
191 > def func():
191 > def func():
192 > # "not locals" case
192 > # "not locals" case
193 > import extroot.bar
193 > import extroot.bar
194 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
194 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
195 > return '\n(extroot) '.join(buf)
195 > return '\n(extroot) '.join(buf)
196 > # "fromlist == ('*',)" case
196 > # "fromlist == ('*',)" case
197 > from extroot.bar import *
197 > from extroot.bar import *
198 > buf.append('from extroot.bar import *: %s' % s)
198 > buf.append('from extroot.bar import *: %s' % s)
199 > # "not fromlist" and "if '.' in name" case
199 > # "not fromlist" and "if '.' in name" case
200 > import extroot.sub1.baz
200 > import extroot.sub1.baz
201 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
201 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
202 > # "not fromlist" and NOT "if '.' in name" case
202 > # "not fromlist" and NOT "if '.' in name" case
203 > import extroot
203 > import extroot
204 > buf.append('import extroot: %s' % extroot.s)
204 > buf.append('import extroot: %s' % extroot.s)
205 > # NOT "not fromlist" and NOT "level != -1" case
205 > # NOT "not fromlist" and NOT "level != -1" case
206 > from extroot.bar import s
206 > from extroot.bar import s
207 > buf.append('from extroot.bar import s: %s' % s)
207 > buf.append('from extroot.bar import s: %s' % s)
208 > EOF
208 > EOF
209 $ hg --config extensions.extroot=$TESTTMP/extroot root
209 $ hg --config extensions.extroot=$TESTTMP/extroot root
210 (extroot) from extroot.bar import *: this is extroot.bar
210 (extroot) from extroot.bar import *: this is extroot.bar
211 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
211 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
212 (extroot) import extroot: this is extroot.__init__
212 (extroot) import extroot: this is extroot.__init__
213 (extroot) from extroot.bar import s: this is extroot.bar
213 (extroot) from extroot.bar import s: this is extroot.bar
214 (extroot) import extroot.bar in func(): this is extroot.bar
214 (extroot) import extroot.bar in func(): this is extroot.bar
215 $TESTTMP/a (glob)
215 $TESTTMP/a (glob)
216
216
217 #if no-py3k
217 #if no-py3k
218 $ rm "$TESTTMP"/extroot/foo.*
218 $ rm "$TESTTMP"/extroot/foo.*
219 $ cat > $TESTTMP/extroot/foo.py <<EOF
219 $ cat > $TESTTMP/extroot/foo.py <<EOF
220 > # test relative import
220 > # test relative import
221 > buf = []
221 > buf = []
222 > def func():
222 > def func():
223 > # "not locals" case
223 > # "not locals" case
224 > import bar
224 > import bar
225 > buf.append('import bar in func(): %s' % bar.s)
225 > buf.append('import bar in func(): %s' % bar.s)
226 > return '\n(extroot) '.join(buf)
226 > return '\n(extroot) '.join(buf)
227 > # "fromlist == ('*',)" case
227 > # "fromlist == ('*',)" case
228 > from bar import *
228 > from bar import *
229 > buf.append('from bar import *: %s' % s)
229 > buf.append('from bar import *: %s' % s)
230 > # "not fromlist" and "if '.' in name" case
230 > # "not fromlist" and "if '.' in name" case
231 > import sub1.baz
231 > import sub1.baz
232 > buf.append('import sub1.baz: %s' % sub1.baz.s)
232 > buf.append('import sub1.baz: %s' % sub1.baz.s)
233 > # "not fromlist" and NOT "if '.' in name" case
233 > # "not fromlist" and NOT "if '.' in name" case
234 > import sub1
234 > import sub1
235 > buf.append('import sub1: %s' % sub1.s)
235 > buf.append('import sub1: %s' % sub1.s)
236 > # NOT "not fromlist" and NOT "level != -1" case
236 > # NOT "not fromlist" and NOT "level != -1" case
237 > from bar import s
237 > from bar import s
238 > buf.append('from bar import s: %s' % s)
238 > buf.append('from bar import s: %s' % s)
239 > EOF
239 > EOF
240 $ hg --config extensions.extroot=$TESTTMP/extroot root
240 $ hg --config extensions.extroot=$TESTTMP/extroot root
241 (extroot) from bar import *: this is extroot.bar
241 (extroot) from bar import *: this is extroot.bar
242 (extroot) import sub1.baz: this is extroot.sub1.baz
242 (extroot) import sub1.baz: this is extroot.sub1.baz
243 (extroot) import sub1: this is extroot.sub1.__init__
243 (extroot) import sub1: this is extroot.sub1.__init__
244 (extroot) from bar import s: this is extroot.bar
244 (extroot) from bar import s: this is extroot.bar
245 (extroot) import bar in func(): this is extroot.bar
245 (extroot) import bar in func(): this is extroot.bar
246 $TESTTMP/a (glob)
246 $TESTTMP/a (glob)
247 #endif
247 #endif
248
248
249 $ cd ..
249 $ cd ..
250
250
251 hide outer repo
251 hide outer repo
252 $ hg init
252 $ hg init
253
253
254 $ cat > empty.py <<EOF
254 $ cat > empty.py <<EOF
255 > '''empty cmdtable
255 > '''empty cmdtable
256 > '''
256 > '''
257 > cmdtable = {}
257 > cmdtable = {}
258 > EOF
258 > EOF
259 $ emptypath=`pwd`/empty.py
259 $ emptypath=`pwd`/empty.py
260 $ echo "empty = $emptypath" >> $HGRCPATH
260 $ echo "empty = $emptypath" >> $HGRCPATH
261 $ hg help empty
261 $ hg help empty
262 empty extension - empty cmdtable
262 empty extension - empty cmdtable
263
263
264 no commands defined
264 no commands defined
265
265
266
266
267 $ echo 'empty = !' >> $HGRCPATH
267 $ echo 'empty = !' >> $HGRCPATH
268
268
269 $ cat > debugextension.py <<EOF
269 $ cat > debugextension.py <<EOF
270 > '''only debugcommands
270 > '''only debugcommands
271 > '''
271 > '''
272 > from mercurial import cmdutil
272 > from mercurial import cmdutil
273 > cmdtable = {}
273 > cmdtable = {}
274 > command = cmdutil.command(cmdtable)
274 > command = cmdutil.command(cmdtable)
275 > @command('debugfoobar', [], 'hg debugfoobar')
275 > @command('debugfoobar', [], 'hg debugfoobar')
276 > def debugfoobar(ui, repo, *args, **opts):
276 > def debugfoobar(ui, repo, *args, **opts):
277 > "yet another debug command"
277 > "yet another debug command"
278 > pass
278 > pass
279 > @command('foo', [], 'hg foo')
279 > @command('foo', [], 'hg foo')
280 > def foo(ui, repo, *args, **opts):
280 > def foo(ui, repo, *args, **opts):
281 > """yet another foo command
281 > """yet another foo command
282 > This command has been DEPRECATED since forever.
282 > This command has been DEPRECATED since forever.
283 > """
283 > """
284 > pass
284 > pass
285 > EOF
285 > EOF
286 $ debugpath=`pwd`/debugextension.py
286 $ debugpath=`pwd`/debugextension.py
287 $ echo "debugextension = $debugpath" >> $HGRCPATH
287 $ echo "debugextension = $debugpath" >> $HGRCPATH
288
288
289 $ hg help debugextension
289 $ hg help debugextension
290 hg debugextensions
290 hg debugextensions
291
291
292 show information about active extensions
292 show information about active extensions
293
293
294 options:
294 options:
295
295
296 (some details hidden, use --verbose to show complete help)
296 (some details hidden, use --verbose to show complete help)
297
297
298
298
299 $ hg --verbose help debugextension
299 $ hg --verbose help debugextension
300 hg debugextensions
300 hg debugextensions
301
301
302 show information about active extensions
302 show information about active extensions
303
303
304 options:
304 options:
305
305
306 -T --template TEMPLATE display with template (EXPERIMENTAL)
306 -T --template TEMPLATE display with template (EXPERIMENTAL)
307
307
308 global options ([+] can be repeated):
308 global options ([+] can be repeated):
309
309
310 -R --repository REPO repository root directory or name of overlay bundle
310 -R --repository REPO repository root directory or name of overlay bundle
311 file
311 file
312 --cwd DIR change working directory
312 --cwd DIR change working directory
313 -y --noninteractive do not prompt, automatically pick the first choice for
313 -y --noninteractive do not prompt, automatically pick the first choice for
314 all prompts
314 all prompts
315 -q --quiet suppress output
315 -q --quiet suppress output
316 -v --verbose enable additional output
316 -v --verbose enable additional output
317 --config CONFIG [+] set/override config option (use 'section.name=value')
317 --config CONFIG [+] set/override config option (use 'section.name=value')
318 --debug enable debugging output
318 --debug enable debugging output
319 --debugger start debugger
319 --debugger start debugger
320 --encoding ENCODE set the charset encoding (default: ascii)
320 --encoding ENCODE set the charset encoding (default: ascii)
321 --encodingmode MODE set the charset encoding mode (default: strict)
321 --encodingmode MODE set the charset encoding mode (default: strict)
322 --traceback always print a traceback on exception
322 --traceback always print a traceback on exception
323 --time time how long the command takes
323 --time time how long the command takes
324 --profile print command execution profile
324 --profile print command execution profile
325 --version output version information and exit
325 --version output version information and exit
326 -h --help display help and exit
326 -h --help display help and exit
327 --hidden consider hidden changesets
327 --hidden consider hidden changesets
328
328
329
329
330
330
331
331
332
332
333
333
334 $ hg --debug help debugextension
334 $ hg --debug help debugextension
335 hg debugextensions
335 hg debugextensions
336
336
337 show information about active extensions
337 show information about active extensions
338
338
339 options:
339 options:
340
340
341 -T --template TEMPLATE display with template (EXPERIMENTAL)
341 -T --template TEMPLATE display with template (EXPERIMENTAL)
342
342
343 global options ([+] can be repeated):
343 global options ([+] can be repeated):
344
344
345 -R --repository REPO repository root directory or name of overlay bundle
345 -R --repository REPO repository root directory or name of overlay bundle
346 file
346 file
347 --cwd DIR change working directory
347 --cwd DIR change working directory
348 -y --noninteractive do not prompt, automatically pick the first choice for
348 -y --noninteractive do not prompt, automatically pick the first choice for
349 all prompts
349 all prompts
350 -q --quiet suppress output
350 -q --quiet suppress output
351 -v --verbose enable additional output
351 -v --verbose enable additional output
352 --config CONFIG [+] set/override config option (use 'section.name=value')
352 --config CONFIG [+] set/override config option (use 'section.name=value')
353 --debug enable debugging output
353 --debug enable debugging output
354 --debugger start debugger
354 --debugger start debugger
355 --encoding ENCODE set the charset encoding (default: ascii)
355 --encoding ENCODE set the charset encoding (default: ascii)
356 --encodingmode MODE set the charset encoding mode (default: strict)
356 --encodingmode MODE set the charset encoding mode (default: strict)
357 --traceback always print a traceback on exception
357 --traceback always print a traceback on exception
358 --time time how long the command takes
358 --time time how long the command takes
359 --profile print command execution profile
359 --profile print command execution profile
360 --version output version information and exit
360 --version output version information and exit
361 -h --help display help and exit
361 -h --help display help and exit
362 --hidden consider hidden changesets
362 --hidden consider hidden changesets
363
363
364
364
365
365
366
366
367
367
368 $ echo 'debugextension = !' >> $HGRCPATH
368 $ echo 'debugextension = !' >> $HGRCPATH
369
369
370 Asking for help about a deprecated extension should do something useful:
371
372 $ hg help glog
373 'glog' is provided by the following extension:
374
375 graphlog command to view revision graphs from a shell (DEPRECATED)
376
377 (use "hg help extensions" for information on enabling extensions)
378
370 Extension module help vs command help:
379 Extension module help vs command help:
371
380
372 $ echo 'extdiff =' >> $HGRCPATH
381 $ echo 'extdiff =' >> $HGRCPATH
373 $ hg help extdiff
382 $ hg help extdiff
374 hg extdiff [OPT]... [FILE]...
383 hg extdiff [OPT]... [FILE]...
375
384
376 use external program to diff repository (or selected files)
385 use external program to diff repository (or selected files)
377
386
378 Show differences between revisions for the specified files, using an
387 Show differences between revisions for the specified files, using an
379 external program. The default program used is diff, with default options
388 external program. The default program used is diff, with default options
380 "-Npru".
389 "-Npru".
381
390
382 To select a different program, use the -p/--program option. The program
391 To select a different program, use the -p/--program option. The program
383 will be passed the names of two directories to compare. To pass additional
392 will be passed the names of two directories to compare. To pass additional
384 options to the program, use -o/--option. These will be passed before the
393 options to the program, use -o/--option. These will be passed before the
385 names of the directories to compare.
394 names of the directories to compare.
386
395
387 When two revision arguments are given, then changes are shown between
396 When two revision arguments are given, then changes are shown between
388 those revisions. If only one revision is specified then that revision is
397 those revisions. If only one revision is specified then that revision is
389 compared to the working directory, and, when no revisions are specified,
398 compared to the working directory, and, when no revisions are specified,
390 the working directory files are compared to its parent.
399 the working directory files are compared to its parent.
391
400
392 (use "hg help -e extdiff" to show help for the extdiff extension)
401 (use "hg help -e extdiff" to show help for the extdiff extension)
393
402
394 options ([+] can be repeated):
403 options ([+] can be repeated):
395
404
396 -p --program CMD comparison program to run
405 -p --program CMD comparison program to run
397 -o --option OPT [+] pass option to comparison program
406 -o --option OPT [+] pass option to comparison program
398 -r --rev REV [+] revision
407 -r --rev REV [+] revision
399 -c --change REV change made by revision
408 -c --change REV change made by revision
400 --patch compare patches for two revisions
409 --patch compare patches for two revisions
401 -I --include PATTERN [+] include names matching the given patterns
410 -I --include PATTERN [+] include names matching the given patterns
402 -X --exclude PATTERN [+] exclude names matching the given patterns
411 -X --exclude PATTERN [+] exclude names matching the given patterns
403 -S --subrepos recurse into subrepositories
412 -S --subrepos recurse into subrepositories
404
413
405 (some details hidden, use --verbose to show complete help)
414 (some details hidden, use --verbose to show complete help)
406
415
407
416
408
417
409
418
410
419
411
420
412
421
413
422
414
423
415
424
416 $ hg help --extension extdiff
425 $ hg help --extension extdiff
417 extdiff extension - command to allow external programs to compare revisions
426 extdiff extension - command to allow external programs to compare revisions
418
427
419 The extdiff Mercurial extension allows you to use external programs to compare
428 The extdiff Mercurial extension allows you to use external programs to compare
420 revisions, or revision with working directory. The external diff programs are
429 revisions, or revision with working directory. The external diff programs are
421 called with a configurable set of options and two non-option arguments: paths
430 called with a configurable set of options and two non-option arguments: paths
422 to directories containing snapshots of files to compare.
431 to directories containing snapshots of files to compare.
423
432
424 The extdiff extension also allows you to configure new diff commands, so you
433 The extdiff extension also allows you to configure new diff commands, so you
425 do not need to type "hg extdiff -p kdiff3" always.
434 do not need to type "hg extdiff -p kdiff3" always.
426
435
427 [extdiff]
436 [extdiff]
428 # add new command that runs GNU diff(1) in 'context diff' mode
437 # add new command that runs GNU diff(1) in 'context diff' mode
429 cdiff = gdiff -Nprc5
438 cdiff = gdiff -Nprc5
430 ## or the old way:
439 ## or the old way:
431 #cmd.cdiff = gdiff
440 #cmd.cdiff = gdiff
432 #opts.cdiff = -Nprc5
441 #opts.cdiff = -Nprc5
433
442
434 # add new command called meld, runs meld (no need to name twice). If
443 # add new command called meld, runs meld (no need to name twice). If
435 # the meld executable is not available, the meld tool in [merge-tools]
444 # the meld executable is not available, the meld tool in [merge-tools]
436 # will be used, if available
445 # will be used, if available
437 meld =
446 meld =
438
447
439 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
448 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
440 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
449 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
441 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
450 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
442 # your .vimrc
451 # your .vimrc
443 vimdiff = gvim -f "+next" \
452 vimdiff = gvim -f "+next" \
444 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
453 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
445
454
446 Tool arguments can include variables that are expanded at runtime:
455 Tool arguments can include variables that are expanded at runtime:
447
456
448 $parent1, $plabel1 - filename, descriptive label of first parent
457 $parent1, $plabel1 - filename, descriptive label of first parent
449 $child, $clabel - filename, descriptive label of child revision
458 $child, $clabel - filename, descriptive label of child revision
450 $parent2, $plabel2 - filename, descriptive label of second parent
459 $parent2, $plabel2 - filename, descriptive label of second parent
451 $root - repository root
460 $root - repository root
452 $parent is an alias for $parent1.
461 $parent is an alias for $parent1.
453
462
454 The extdiff extension will look in your [diff-tools] and [merge-tools]
463 The extdiff extension will look in your [diff-tools] and [merge-tools]
455 sections for diff tool arguments, when none are specified in [extdiff].
464 sections for diff tool arguments, when none are specified in [extdiff].
456
465
457 [extdiff]
466 [extdiff]
458 kdiff3 =
467 kdiff3 =
459
468
460 [diff-tools]
469 [diff-tools]
461 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
470 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
462
471
463 You can use -I/-X and list of file or directory names like normal "hg diff"
472 You can use -I/-X and list of file or directory names like normal "hg diff"
464 command. The extdiff extension makes snapshots of only needed files, so
473 command. The extdiff extension makes snapshots of only needed files, so
465 running the external diff program will actually be pretty fast (at least
474 running the external diff program will actually be pretty fast (at least
466 faster than having to compare the entire tree).
475 faster than having to compare the entire tree).
467
476
468 list of commands:
477 list of commands:
469
478
470 extdiff use external program to diff repository (or selected files)
479 extdiff use external program to diff repository (or selected files)
471
480
472 (use "hg help -v -e extdiff" to show built-in aliases and global options)
481 (use "hg help -v -e extdiff" to show built-in aliases and global options)
473
482
474
483
475
484
476
485
477
486
478
487
479
488
480
489
481
490
482
491
483
492
484
493
485
494
486
495
487
496
488
497
489 $ echo 'extdiff = !' >> $HGRCPATH
498 $ echo 'extdiff = !' >> $HGRCPATH
490
499
491 Test help topic with same name as extension
500 Test help topic with same name as extension
492
501
493 $ cat > multirevs.py <<EOF
502 $ cat > multirevs.py <<EOF
494 > from mercurial import cmdutil, commands
503 > from mercurial import cmdutil, commands
495 > cmdtable = {}
504 > cmdtable = {}
496 > command = cmdutil.command(cmdtable)
505 > command = cmdutil.command(cmdtable)
497 > """multirevs extension
506 > """multirevs extension
498 > Big multi-line module docstring."""
507 > Big multi-line module docstring."""
499 > @command('multirevs', [], 'ARG', norepo=True)
508 > @command('multirevs', [], 'ARG', norepo=True)
500 > def multirevs(ui, repo, arg, *args, **opts):
509 > def multirevs(ui, repo, arg, *args, **opts):
501 > """multirevs command"""
510 > """multirevs command"""
502 > pass
511 > pass
503 > EOF
512 > EOF
504 $ echo "multirevs = multirevs.py" >> $HGRCPATH
513 $ echo "multirevs = multirevs.py" >> $HGRCPATH
505
514
506 $ hg help multirevs
515 $ hg help multirevs
507 Specifying Multiple Revisions
516 Specifying Multiple Revisions
508 """""""""""""""""""""""""""""
517 """""""""""""""""""""""""""""
509
518
510 When Mercurial accepts more than one revision, they may be specified
519 When Mercurial accepts more than one revision, they may be specified
511 individually, or provided as a topologically continuous range, separated
520 individually, or provided as a topologically continuous range, separated
512 by the ":" character.
521 by the ":" character.
513
522
514 The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
523 The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
515 revision identifiers. Both BEGIN and END are optional. If BEGIN is not
524 revision identifiers. Both BEGIN and END are optional. If BEGIN is not
516 specified, it defaults to revision number 0. If END is not specified, it
525 specified, it defaults to revision number 0. If END is not specified, it
517 defaults to the tip. The range ":" thus means "all revisions".
526 defaults to the tip. The range ":" thus means "all revisions".
518
527
519 If BEGIN is greater than END, revisions are treated in reverse order.
528 If BEGIN is greater than END, revisions are treated in reverse order.
520
529
521 A range acts as a closed interval. This means that a range of 3:5 gives 3,
530 A range acts as a closed interval. This means that a range of 3:5 gives 3,
522 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
531 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
523
532
524 use "hg help -c multirevs" to see help for the multirevs command
533 use "hg help -c multirevs" to see help for the multirevs command
525
534
526
535
527
536
528
537
529
538
530
539
531 $ hg help -c multirevs
540 $ hg help -c multirevs
532 hg multirevs ARG
541 hg multirevs ARG
533
542
534 multirevs command
543 multirevs command
535
544
536 (some details hidden, use --verbose to show complete help)
545 (some details hidden, use --verbose to show complete help)
537
546
538
547
539
548
540 $ hg multirevs
549 $ hg multirevs
541 hg multirevs: invalid arguments
550 hg multirevs: invalid arguments
542 hg multirevs ARG
551 hg multirevs ARG
543
552
544 multirevs command
553 multirevs command
545
554
546 (use "hg multirevs -h" to show more help)
555 (use "hg multirevs -h" to show more help)
547 [255]
556 [255]
548
557
549
558
550
559
551 $ echo "multirevs = !" >> $HGRCPATH
560 $ echo "multirevs = !" >> $HGRCPATH
552
561
553 Issue811: Problem loading extensions twice (by site and by user)
562 Issue811: Problem loading extensions twice (by site and by user)
554
563
555 $ cat <<EOF >> $HGRCPATH
564 $ cat <<EOF >> $HGRCPATH
556 > mq =
565 > mq =
557 > strip =
566 > strip =
558 > hgext.mq =
567 > hgext.mq =
559 > hgext/mq =
568 > hgext/mq =
560 > EOF
569 > EOF
561
570
562 Show extensions:
571 Show extensions:
563 (note that mq force load strip, also checking it's not loaded twice)
572 (note that mq force load strip, also checking it's not loaded twice)
564
573
565 $ hg debugextensions
574 $ hg debugextensions
566 mq
575 mq
567 strip
576 strip
568
577
569 For extensions, which name matches one of its commands, help
578 For extensions, which name matches one of its commands, help
570 message should ask '-v -e' to get list of built-in aliases
579 message should ask '-v -e' to get list of built-in aliases
571 along with extension help itself
580 along with extension help itself
572
581
573 $ mkdir $TESTTMP/d
582 $ mkdir $TESTTMP/d
574 $ cat > $TESTTMP/d/dodo.py <<EOF
583 $ cat > $TESTTMP/d/dodo.py <<EOF
575 > """
584 > """
576 > This is an awesome 'dodo' extension. It does nothing and
585 > This is an awesome 'dodo' extension. It does nothing and
577 > writes 'Foo foo'
586 > writes 'Foo foo'
578 > """
587 > """
579 > from mercurial import cmdutil, commands
588 > from mercurial import cmdutil, commands
580 > cmdtable = {}
589 > cmdtable = {}
581 > command = cmdutil.command(cmdtable)
590 > command = cmdutil.command(cmdtable)
582 > @command('dodo', [], 'hg dodo')
591 > @command('dodo', [], 'hg dodo')
583 > def dodo(ui, *args, **kwargs):
592 > def dodo(ui, *args, **kwargs):
584 > """Does nothing"""
593 > """Does nothing"""
585 > ui.write("I do nothing. Yay\\n")
594 > ui.write("I do nothing. Yay\\n")
586 > @command('foofoo', [], 'hg foofoo')
595 > @command('foofoo', [], 'hg foofoo')
587 > def foofoo(ui, *args, **kwargs):
596 > def foofoo(ui, *args, **kwargs):
588 > """Writes 'Foo foo'"""
597 > """Writes 'Foo foo'"""
589 > ui.write("Foo foo\\n")
598 > ui.write("Foo foo\\n")
590 > EOF
599 > EOF
591 $ dodopath=$TESTTMP/d/dodo.py
600 $ dodopath=$TESTTMP/d/dodo.py
592
601
593 $ echo "dodo = $dodopath" >> $HGRCPATH
602 $ echo "dodo = $dodopath" >> $HGRCPATH
594
603
595 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
604 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
596 $ hg help -e dodo
605 $ hg help -e dodo
597 dodo extension -
606 dodo extension -
598
607
599 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
608 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
600
609
601 list of commands:
610 list of commands:
602
611
603 dodo Does nothing
612 dodo Does nothing
604 foofoo Writes 'Foo foo'
613 foofoo Writes 'Foo foo'
605
614
606 (use "hg help -v -e dodo" to show built-in aliases and global options)
615 (use "hg help -v -e dodo" to show built-in aliases and global options)
607
616
608 Make sure that '-v -e' prints list of built-in aliases along with
617 Make sure that '-v -e' prints list of built-in aliases along with
609 extension help itself
618 extension help itself
610 $ hg help -v -e dodo
619 $ hg help -v -e dodo
611 dodo extension -
620 dodo extension -
612
621
613 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
622 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
614
623
615 list of commands:
624 list of commands:
616
625
617 dodo Does nothing
626 dodo Does nothing
618 foofoo Writes 'Foo foo'
627 foofoo Writes 'Foo foo'
619
628
620 global options ([+] can be repeated):
629 global options ([+] can be repeated):
621
630
622 -R --repository REPO repository root directory or name of overlay bundle
631 -R --repository REPO repository root directory or name of overlay bundle
623 file
632 file
624 --cwd DIR change working directory
633 --cwd DIR change working directory
625 -y --noninteractive do not prompt, automatically pick the first choice for
634 -y --noninteractive do not prompt, automatically pick the first choice for
626 all prompts
635 all prompts
627 -q --quiet suppress output
636 -q --quiet suppress output
628 -v --verbose enable additional output
637 -v --verbose enable additional output
629 --config CONFIG [+] set/override config option (use 'section.name=value')
638 --config CONFIG [+] set/override config option (use 'section.name=value')
630 --debug enable debugging output
639 --debug enable debugging output
631 --debugger start debugger
640 --debugger start debugger
632 --encoding ENCODE set the charset encoding (default: ascii)
641 --encoding ENCODE set the charset encoding (default: ascii)
633 --encodingmode MODE set the charset encoding mode (default: strict)
642 --encodingmode MODE set the charset encoding mode (default: strict)
634 --traceback always print a traceback on exception
643 --traceback always print a traceback on exception
635 --time time how long the command takes
644 --time time how long the command takes
636 --profile print command execution profile
645 --profile print command execution profile
637 --version output version information and exit
646 --version output version information and exit
638 -h --help display help and exit
647 -h --help display help and exit
639 --hidden consider hidden changesets
648 --hidden consider hidden changesets
640
649
641 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
650 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
642 $ hg help -v dodo
651 $ hg help -v dodo
643 hg dodo
652 hg dodo
644
653
645 Does nothing
654 Does nothing
646
655
647 (use "hg help -e dodo" to show help for the dodo extension)
656 (use "hg help -e dodo" to show help for the dodo extension)
648
657
649 options:
658 options:
650
659
651 --mq operate on patch repository
660 --mq operate on patch repository
652
661
653 global options ([+] can be repeated):
662 global options ([+] can be repeated):
654
663
655 -R --repository REPO repository root directory or name of overlay bundle
664 -R --repository REPO repository root directory or name of overlay bundle
656 file
665 file
657 --cwd DIR change working directory
666 --cwd DIR change working directory
658 -y --noninteractive do not prompt, automatically pick the first choice for
667 -y --noninteractive do not prompt, automatically pick the first choice for
659 all prompts
668 all prompts
660 -q --quiet suppress output
669 -q --quiet suppress output
661 -v --verbose enable additional output
670 -v --verbose enable additional output
662 --config CONFIG [+] set/override config option (use 'section.name=value')
671 --config CONFIG [+] set/override config option (use 'section.name=value')
663 --debug enable debugging output
672 --debug enable debugging output
664 --debugger start debugger
673 --debugger start debugger
665 --encoding ENCODE set the charset encoding (default: ascii)
674 --encoding ENCODE set the charset encoding (default: ascii)
666 --encodingmode MODE set the charset encoding mode (default: strict)
675 --encodingmode MODE set the charset encoding mode (default: strict)
667 --traceback always print a traceback on exception
676 --traceback always print a traceback on exception
668 --time time how long the command takes
677 --time time how long the command takes
669 --profile print command execution profile
678 --profile print command execution profile
670 --version output version information and exit
679 --version output version information and exit
671 -h --help display help and exit
680 -h --help display help and exit
672 --hidden consider hidden changesets
681 --hidden consider hidden changesets
673
682
674 In case when extension name doesn't match any of its commands,
683 In case when extension name doesn't match any of its commands,
675 help message should ask for '-v' to get list of built-in aliases
684 help message should ask for '-v' to get list of built-in aliases
676 along with extension help
685 along with extension help
677 $ cat > $TESTTMP/d/dudu.py <<EOF
686 $ cat > $TESTTMP/d/dudu.py <<EOF
678 > """
687 > """
679 > This is an awesome 'dudu' extension. It does something and
688 > This is an awesome 'dudu' extension. It does something and
680 > also writes 'Beep beep'
689 > also writes 'Beep beep'
681 > """
690 > """
682 > from mercurial import cmdutil, commands
691 > from mercurial import cmdutil, commands
683 > cmdtable = {}
692 > cmdtable = {}
684 > command = cmdutil.command(cmdtable)
693 > command = cmdutil.command(cmdtable)
685 > @command('something', [], 'hg something')
694 > @command('something', [], 'hg something')
686 > def something(ui, *args, **kwargs):
695 > def something(ui, *args, **kwargs):
687 > """Does something"""
696 > """Does something"""
688 > ui.write("I do something. Yaaay\\n")
697 > ui.write("I do something. Yaaay\\n")
689 > @command('beep', [], 'hg beep')
698 > @command('beep', [], 'hg beep')
690 > def beep(ui, *args, **kwargs):
699 > def beep(ui, *args, **kwargs):
691 > """Writes 'Beep beep'"""
700 > """Writes 'Beep beep'"""
692 > ui.write("Beep beep\\n")
701 > ui.write("Beep beep\\n")
693 > EOF
702 > EOF
694 $ dudupath=$TESTTMP/d/dudu.py
703 $ dudupath=$TESTTMP/d/dudu.py
695
704
696 $ echo "dudu = $dudupath" >> $HGRCPATH
705 $ echo "dudu = $dudupath" >> $HGRCPATH
697
706
698 $ hg help -e dudu
707 $ hg help -e dudu
699 dudu extension -
708 dudu extension -
700
709
701 This is an awesome 'dudu' extension. It does something and also writes 'Beep
710 This is an awesome 'dudu' extension. It does something and also writes 'Beep
702 beep'
711 beep'
703
712
704 list of commands:
713 list of commands:
705
714
706 beep Writes 'Beep beep'
715 beep Writes 'Beep beep'
707 something Does something
716 something Does something
708
717
709 (use "hg help -v dudu" to show built-in aliases and global options)
718 (use "hg help -v dudu" to show built-in aliases and global options)
710
719
711 In case when extension name doesn't match any of its commands,
720 In case when extension name doesn't match any of its commands,
712 help options '-v' and '-v -e' should be equivalent
721 help options '-v' and '-v -e' should be equivalent
713 $ hg help -v dudu
722 $ hg help -v dudu
714 dudu extension -
723 dudu extension -
715
724
716 This is an awesome 'dudu' extension. It does something and also writes 'Beep
725 This is an awesome 'dudu' extension. It does something and also writes 'Beep
717 beep'
726 beep'
718
727
719 list of commands:
728 list of commands:
720
729
721 beep Writes 'Beep beep'
730 beep Writes 'Beep beep'
722 something Does something
731 something Does something
723
732
724 global options ([+] can be repeated):
733 global options ([+] can be repeated):
725
734
726 -R --repository REPO repository root directory or name of overlay bundle
735 -R --repository REPO repository root directory or name of overlay bundle
727 file
736 file
728 --cwd DIR change working directory
737 --cwd DIR change working directory
729 -y --noninteractive do not prompt, automatically pick the first choice for
738 -y --noninteractive do not prompt, automatically pick the first choice for
730 all prompts
739 all prompts
731 -q --quiet suppress output
740 -q --quiet suppress output
732 -v --verbose enable additional output
741 -v --verbose enable additional output
733 --config CONFIG [+] set/override config option (use 'section.name=value')
742 --config CONFIG [+] set/override config option (use 'section.name=value')
734 --debug enable debugging output
743 --debug enable debugging output
735 --debugger start debugger
744 --debugger start debugger
736 --encoding ENCODE set the charset encoding (default: ascii)
745 --encoding ENCODE set the charset encoding (default: ascii)
737 --encodingmode MODE set the charset encoding mode (default: strict)
746 --encodingmode MODE set the charset encoding mode (default: strict)
738 --traceback always print a traceback on exception
747 --traceback always print a traceback on exception
739 --time time how long the command takes
748 --time time how long the command takes
740 --profile print command execution profile
749 --profile print command execution profile
741 --version output version information and exit
750 --version output version information and exit
742 -h --help display help and exit
751 -h --help display help and exit
743 --hidden consider hidden changesets
752 --hidden consider hidden changesets
744
753
745 $ hg help -v -e dudu
754 $ hg help -v -e dudu
746 dudu extension -
755 dudu extension -
747
756
748 This is an awesome 'dudu' extension. It does something and also writes 'Beep
757 This is an awesome 'dudu' extension. It does something and also writes 'Beep
749 beep'
758 beep'
750
759
751 list of commands:
760 list of commands:
752
761
753 beep Writes 'Beep beep'
762 beep Writes 'Beep beep'
754 something Does something
763 something Does something
755
764
756 global options ([+] can be repeated):
765 global options ([+] can be repeated):
757
766
758 -R --repository REPO repository root directory or name of overlay bundle
767 -R --repository REPO repository root directory or name of overlay bundle
759 file
768 file
760 --cwd DIR change working directory
769 --cwd DIR change working directory
761 -y --noninteractive do not prompt, automatically pick the first choice for
770 -y --noninteractive do not prompt, automatically pick the first choice for
762 all prompts
771 all prompts
763 -q --quiet suppress output
772 -q --quiet suppress output
764 -v --verbose enable additional output
773 -v --verbose enable additional output
765 --config CONFIG [+] set/override config option (use 'section.name=value')
774 --config CONFIG [+] set/override config option (use 'section.name=value')
766 --debug enable debugging output
775 --debug enable debugging output
767 --debugger start debugger
776 --debugger start debugger
768 --encoding ENCODE set the charset encoding (default: ascii)
777 --encoding ENCODE set the charset encoding (default: ascii)
769 --encodingmode MODE set the charset encoding mode (default: strict)
778 --encodingmode MODE set the charset encoding mode (default: strict)
770 --traceback always print a traceback on exception
779 --traceback always print a traceback on exception
771 --time time how long the command takes
780 --time time how long the command takes
772 --profile print command execution profile
781 --profile print command execution profile
773 --version output version information and exit
782 --version output version information and exit
774 -h --help display help and exit
783 -h --help display help and exit
775 --hidden consider hidden changesets
784 --hidden consider hidden changesets
776
785
777 Disabled extension commands:
786 Disabled extension commands:
778
787
779 $ ORGHGRCPATH=$HGRCPATH
788 $ ORGHGRCPATH=$HGRCPATH
780 $ HGRCPATH=
789 $ HGRCPATH=
781 $ export HGRCPATH
790 $ export HGRCPATH
782 $ hg help email
791 $ hg help email
783 'email' is provided by the following extension:
792 'email' is provided by the following extension:
784
793
785 patchbomb command to send changesets as (a series of) patch emails
794 patchbomb command to send changesets as (a series of) patch emails
786
795
787 (use "hg help extensions" for information on enabling extensions)
796 (use "hg help extensions" for information on enabling extensions)
788
797
789
798
790 $ hg qdel
799 $ hg qdel
791 hg: unknown command 'qdel'
800 hg: unknown command 'qdel'
792 'qdelete' is provided by the following extension:
801 'qdelete' is provided by the following extension:
793
802
794 mq manage a stack of patches
803 mq manage a stack of patches
795
804
796 (use "hg help extensions" for information on enabling extensions)
805 (use "hg help extensions" for information on enabling extensions)
797 [255]
806 [255]
798
807
799
808
800 $ hg churn
809 $ hg churn
801 hg: unknown command 'churn'
810 hg: unknown command 'churn'
802 'churn' is provided by the following extension:
811 'churn' is provided by the following extension:
803
812
804 churn command to display statistics about repository history
813 churn command to display statistics about repository history
805
814
806 (use "hg help extensions" for information on enabling extensions)
815 (use "hg help extensions" for information on enabling extensions)
807 [255]
816 [255]
808
817
809
818
810
819
811 Disabled extensions:
820 Disabled extensions:
812
821
813 $ hg help churn
822 $ hg help churn
814 churn extension - command to display statistics about repository history
823 churn extension - command to display statistics about repository history
815
824
816 (use "hg help extensions" for information on enabling extensions)
825 (use "hg help extensions" for information on enabling extensions)
817
826
818 $ hg help patchbomb
827 $ hg help patchbomb
819 patchbomb extension - command to send changesets as (a series of) patch emails
828 patchbomb extension - command to send changesets as (a series of) patch emails
820
829
821 (use "hg help extensions" for information on enabling extensions)
830 (use "hg help extensions" for information on enabling extensions)
822
831
823
832
824 Broken disabled extension and command:
833 Broken disabled extension and command:
825
834
826 $ mkdir hgext
835 $ mkdir hgext
827 $ echo > hgext/__init__.py
836 $ echo > hgext/__init__.py
828 $ cat > hgext/broken.py <<EOF
837 $ cat > hgext/broken.py <<EOF
829 > "broken extension'
838 > "broken extension'
830 > EOF
839 > EOF
831 $ cat > path.py <<EOF
840 $ cat > path.py <<EOF
832 > import os, sys
841 > import os, sys
833 > sys.path.insert(0, os.environ['HGEXTPATH'])
842 > sys.path.insert(0, os.environ['HGEXTPATH'])
834 > EOF
843 > EOF
835 $ HGEXTPATH=`pwd`
844 $ HGEXTPATH=`pwd`
836 $ export HGEXTPATH
845 $ export HGEXTPATH
837
846
838 $ hg --config extensions.path=./path.py help broken
847 $ hg --config extensions.path=./path.py help broken
839 broken extension - (no help text available)
848 broken extension - (no help text available)
840
849
841 (use "hg help extensions" for information on enabling extensions)
850 (use "hg help extensions" for information on enabling extensions)
842
851
843
852
844 $ cat > hgext/forest.py <<EOF
853 $ cat > hgext/forest.py <<EOF
845 > cmdtable = None
854 > cmdtable = None
846 > EOF
855 > EOF
847 $ hg --config extensions.path=./path.py help foo > /dev/null
856 $ hg --config extensions.path=./path.py help foo > /dev/null
848 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
857 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
849 abort: no such help topic: foo
858 abort: no such help topic: foo
850 (try "hg help --keyword foo")
859 (try "hg help --keyword foo")
851 [255]
860 [255]
852
861
853 $ cat > throw.py <<EOF
862 $ cat > throw.py <<EOF
854 > from mercurial import cmdutil, commands, util
863 > from mercurial import cmdutil, commands, util
855 > cmdtable = {}
864 > cmdtable = {}
856 > command = cmdutil.command(cmdtable)
865 > command = cmdutil.command(cmdtable)
857 > class Bogon(Exception): pass
866 > class Bogon(Exception): pass
858 > @command('throw', [], 'hg throw', norepo=True)
867 > @command('throw', [], 'hg throw', norepo=True)
859 > def throw(ui, **opts):
868 > def throw(ui, **opts):
860 > """throws an exception"""
869 > """throws an exception"""
861 > raise Bogon()
870 > raise Bogon()
862 > EOF
871 > EOF
863
872
864 No declared supported version, extension complains:
873 No declared supported version, extension complains:
865 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
874 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
866 ** Unknown exception encountered with possibly-broken third-party extension throw
875 ** Unknown exception encountered with possibly-broken third-party extension throw
867 ** which supports versions unknown of Mercurial.
876 ** which supports versions unknown of Mercurial.
868 ** Please disable throw and try your action again.
877 ** Please disable throw and try your action again.
869 ** If that fixes the bug please report it to the extension author.
878 ** If that fixes the bug please report it to the extension author.
870 ** Python * (glob)
879 ** Python * (glob)
871 ** Mercurial Distributed SCM * (glob)
880 ** Mercurial Distributed SCM * (glob)
872 ** Extensions loaded: throw
881 ** Extensions loaded: throw
873
882
874 empty declaration of supported version, extension complains:
883 empty declaration of supported version, extension complains:
875 $ echo "testedwith = ''" >> throw.py
884 $ echo "testedwith = ''" >> throw.py
876 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
885 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
877 ** Unknown exception encountered with possibly-broken third-party extension throw
886 ** Unknown exception encountered with possibly-broken third-party extension throw
878 ** which supports versions unknown of Mercurial.
887 ** which supports versions unknown of Mercurial.
879 ** Please disable throw and try your action again.
888 ** Please disable throw and try your action again.
880 ** If that fixes the bug please report it to the extension author.
889 ** If that fixes the bug please report it to the extension author.
881 ** Python * (glob)
890 ** Python * (glob)
882 ** Mercurial Distributed SCM (*) (glob)
891 ** Mercurial Distributed SCM (*) (glob)
883 ** Extensions loaded: throw
892 ** Extensions loaded: throw
884
893
885 If the extension specifies a buglink, show that:
894 If the extension specifies a buglink, show that:
886 $ echo 'buglink = "http://example.com/bts"' >> throw.py
895 $ echo 'buglink = "http://example.com/bts"' >> throw.py
887 $ rm -f throw.pyc throw.pyo
896 $ rm -f throw.pyc throw.pyo
888 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
897 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
889 ** Unknown exception encountered with possibly-broken third-party extension throw
898 ** Unknown exception encountered with possibly-broken third-party extension throw
890 ** which supports versions unknown of Mercurial.
899 ** which supports versions unknown of Mercurial.
891 ** Please disable throw and try your action again.
900 ** Please disable throw and try your action again.
892 ** If that fixes the bug please report it to http://example.com/bts
901 ** If that fixes the bug please report it to http://example.com/bts
893 ** Python * (glob)
902 ** Python * (glob)
894 ** Mercurial Distributed SCM (*) (glob)
903 ** Mercurial Distributed SCM (*) (glob)
895 ** Extensions loaded: throw
904 ** Extensions loaded: throw
896
905
897 If the extensions declare outdated versions, accuse the older extension first:
906 If the extensions declare outdated versions, accuse the older extension first:
898 $ echo "from mercurial import util" >> older.py
907 $ echo "from mercurial import util" >> older.py
899 $ echo "util.version = lambda:'2.2'" >> older.py
908 $ echo "util.version = lambda:'2.2'" >> older.py
900 $ echo "testedwith = '1.9.3'" >> older.py
909 $ echo "testedwith = '1.9.3'" >> older.py
901 $ echo "testedwith = '2.1.1'" >> throw.py
910 $ echo "testedwith = '2.1.1'" >> throw.py
902 $ rm -f throw.pyc throw.pyo
911 $ rm -f throw.pyc throw.pyo
903 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
912 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
904 > throw 2>&1 | egrep '^\*\*'
913 > throw 2>&1 | egrep '^\*\*'
905 ** Unknown exception encountered with possibly-broken third-party extension older
914 ** Unknown exception encountered with possibly-broken third-party extension older
906 ** which supports versions 1.9 of Mercurial.
915 ** which supports versions 1.9 of Mercurial.
907 ** Please disable older and try your action again.
916 ** Please disable older and try your action again.
908 ** If that fixes the bug please report it to the extension author.
917 ** If that fixes the bug please report it to the extension author.
909 ** Python * (glob)
918 ** Python * (glob)
910 ** Mercurial Distributed SCM (version 2.2)
919 ** Mercurial Distributed SCM (version 2.2)
911 ** Extensions loaded: throw, older
920 ** Extensions loaded: throw, older
912
921
913 One extension only tested with older, one only with newer versions:
922 One extension only tested with older, one only with newer versions:
914 $ echo "util.version = lambda:'2.1'" >> older.py
923 $ echo "util.version = lambda:'2.1'" >> older.py
915 $ rm -f older.pyc older.pyo
924 $ rm -f older.pyc older.pyo
916 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
925 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
917 > throw 2>&1 | egrep '^\*\*'
926 > throw 2>&1 | egrep '^\*\*'
918 ** Unknown exception encountered with possibly-broken third-party extension older
927 ** Unknown exception encountered with possibly-broken third-party extension older
919 ** which supports versions 1.9 of Mercurial.
928 ** which supports versions 1.9 of Mercurial.
920 ** Please disable older and try your action again.
929 ** Please disable older and try your action again.
921 ** If that fixes the bug please report it to the extension author.
930 ** If that fixes the bug please report it to the extension author.
922 ** Python * (glob)
931 ** Python * (glob)
923 ** Mercurial Distributed SCM (version 2.1)
932 ** Mercurial Distributed SCM (version 2.1)
924 ** Extensions loaded: throw, older
933 ** Extensions loaded: throw, older
925
934
926 Older extension is tested with current version, the other only with newer:
935 Older extension is tested with current version, the other only with newer:
927 $ echo "util.version = lambda:'1.9.3'" >> older.py
936 $ echo "util.version = lambda:'1.9.3'" >> older.py
928 $ rm -f older.pyc older.pyo
937 $ rm -f older.pyc older.pyo
929 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
938 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
930 > throw 2>&1 | egrep '^\*\*'
939 > throw 2>&1 | egrep '^\*\*'
931 ** Unknown exception encountered with possibly-broken third-party extension throw
940 ** Unknown exception encountered with possibly-broken third-party extension throw
932 ** which supports versions 2.1 of Mercurial.
941 ** which supports versions 2.1 of Mercurial.
933 ** Please disable throw and try your action again.
942 ** Please disable throw and try your action again.
934 ** If that fixes the bug please report it to http://example.com/bts
943 ** If that fixes the bug please report it to http://example.com/bts
935 ** Python * (glob)
944 ** Python * (glob)
936 ** Mercurial Distributed SCM (version 1.9.3)
945 ** Mercurial Distributed SCM (version 1.9.3)
937 ** Extensions loaded: throw, older
946 ** Extensions loaded: throw, older
938
947
939 Ability to point to a different point
948 Ability to point to a different point
940 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
949 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
941 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
950 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
942 ** unknown exception encountered, please report by visiting
951 ** unknown exception encountered, please report by visiting
943 ** Your Local Goat Lenders
952 ** Your Local Goat Lenders
944 ** Python * (glob)
953 ** Python * (glob)
945 ** Mercurial Distributed SCM (*) (glob)
954 ** Mercurial Distributed SCM (*) (glob)
946 ** Extensions loaded: throw, older
955 ** Extensions loaded: throw, older
947
956
948 Declare the version as supporting this hg version, show regular bts link:
957 Declare the version as supporting this hg version, show regular bts link:
949 $ hgver=`$PYTHON -c 'from mercurial import util; print util.version().split("+")[0]'`
958 $ hgver=`$PYTHON -c 'from mercurial import util; print util.version().split("+")[0]'`
950 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
959 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
951 $ if [ -z "$hgver" ]; then
960 $ if [ -z "$hgver" ]; then
952 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
961 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
953 > fi
962 > fi
954 $ rm -f throw.pyc throw.pyo
963 $ rm -f throw.pyc throw.pyo
955 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
964 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
956 ** unknown exception encountered, please report by visiting
965 ** unknown exception encountered, please report by visiting
957 ** https://mercurial-scm.org/wiki/BugTracker
966 ** https://mercurial-scm.org/wiki/BugTracker
958 ** Python * (glob)
967 ** Python * (glob)
959 ** Mercurial Distributed SCM (*) (glob)
968 ** Mercurial Distributed SCM (*) (glob)
960 ** Extensions loaded: throw
969 ** Extensions loaded: throw
961
970
962 Patch version is ignored during compatibility check
971 Patch version is ignored during compatibility check
963 $ echo "testedwith = '3.2'" >> throw.py
972 $ echo "testedwith = '3.2'" >> throw.py
964 $ echo "util.version = lambda:'3.2.2'" >> throw.py
973 $ echo "util.version = lambda:'3.2.2'" >> throw.py
965 $ rm -f throw.pyc throw.pyo
974 $ rm -f throw.pyc throw.pyo
966 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
975 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
967 ** unknown exception encountered, please report by visiting
976 ** unknown exception encountered, please report by visiting
968 ** https://mercurial-scm.org/wiki/BugTracker
977 ** https://mercurial-scm.org/wiki/BugTracker
969 ** Python * (glob)
978 ** Python * (glob)
970 ** Mercurial Distributed SCM (*) (glob)
979 ** Mercurial Distributed SCM (*) (glob)
971 ** Extensions loaded: throw
980 ** Extensions loaded: throw
972
981
973 Test version number support in 'hg version':
982 Test version number support in 'hg version':
974 $ echo '__version__ = (1, 2, 3)' >> throw.py
983 $ echo '__version__ = (1, 2, 3)' >> throw.py
975 $ rm -f throw.pyc throw.pyo
984 $ rm -f throw.pyc throw.pyo
976 $ hg version -v
985 $ hg version -v
977 Mercurial Distributed SCM (version *) (glob)
986 Mercurial Distributed SCM (version *) (glob)
978 (see https://mercurial-scm.org for more information)
987 (see https://mercurial-scm.org for more information)
979
988
980 Copyright (C) 2005-* Matt Mackall and others (glob)
989 Copyright (C) 2005-* Matt Mackall and others (glob)
981 This is free software; see the source for copying conditions. There is NO
990 This is free software; see the source for copying conditions. There is NO
982 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
991 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
983
992
984 Enabled extensions:
993 Enabled extensions:
985
994
986
995
987 $ hg version -v --config extensions.throw=throw.py
996 $ hg version -v --config extensions.throw=throw.py
988 Mercurial Distributed SCM (version *) (glob)
997 Mercurial Distributed SCM (version *) (glob)
989 (see https://mercurial-scm.org for more information)
998 (see https://mercurial-scm.org for more information)
990
999
991 Copyright (C) 2005-* Matt Mackall and others (glob)
1000 Copyright (C) 2005-* Matt Mackall and others (glob)
992 This is free software; see the source for copying conditions. There is NO
1001 This is free software; see the source for copying conditions. There is NO
993 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1002 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
994
1003
995 Enabled extensions:
1004 Enabled extensions:
996
1005
997 throw 1.2.3
1006 throw 1.2.3
998 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1007 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
999 $ rm -f throw.pyc throw.pyo
1008 $ rm -f throw.pyc throw.pyo
1000 $ hg version -v --config extensions.throw=throw.py
1009 $ hg version -v --config extensions.throw=throw.py
1001 Mercurial Distributed SCM (version *) (glob)
1010 Mercurial Distributed SCM (version *) (glob)
1002 (see https://mercurial-scm.org for more information)
1011 (see https://mercurial-scm.org for more information)
1003
1012
1004 Copyright (C) 2005-* Matt Mackall and others (glob)
1013 Copyright (C) 2005-* Matt Mackall and others (glob)
1005 This is free software; see the source for copying conditions. There is NO
1014 This is free software; see the source for copying conditions. There is NO
1006 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1015 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1007
1016
1008 Enabled extensions:
1017 Enabled extensions:
1009
1018
1010 throw 1.twentythree
1019 throw 1.twentythree
1011
1020
1012 Refuse to load extensions with minimum version requirements
1021 Refuse to load extensions with minimum version requirements
1013
1022
1014 $ cat > minversion1.py << EOF
1023 $ cat > minversion1.py << EOF
1015 > from mercurial import util
1024 > from mercurial import util
1016 > util.version = lambda: '3.5.2'
1025 > util.version = lambda: '3.5.2'
1017 > minimumhgversion = '3.6'
1026 > minimumhgversion = '3.6'
1018 > EOF
1027 > EOF
1019 $ hg --config extensions.minversion=minversion1.py version
1028 $ hg --config extensions.minversion=minversion1.py version
1020 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1029 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1021 Mercurial Distributed SCM (version 3.5.2)
1030 Mercurial Distributed SCM (version 3.5.2)
1022 (see https://mercurial-scm.org for more information)
1031 (see https://mercurial-scm.org for more information)
1023
1032
1024 Copyright (C) 2005-* Matt Mackall and others (glob)
1033 Copyright (C) 2005-* Matt Mackall and others (glob)
1025 This is free software; see the source for copying conditions. There is NO
1034 This is free software; see the source for copying conditions. There is NO
1026 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1035 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1027
1036
1028 $ cat > minversion2.py << EOF
1037 $ cat > minversion2.py << EOF
1029 > from mercurial import util
1038 > from mercurial import util
1030 > util.version = lambda: '3.6'
1039 > util.version = lambda: '3.6'
1031 > minimumhgversion = '3.7'
1040 > minimumhgversion = '3.7'
1032 > EOF
1041 > EOF
1033 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1042 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1034 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1043 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1035
1044
1036 Can load version that is only off by point release
1045 Can load version that is only off by point release
1037
1046
1038 $ cat > minversion2.py << EOF
1047 $ cat > minversion2.py << EOF
1039 > from mercurial import util
1048 > from mercurial import util
1040 > util.version = lambda: '3.6.1'
1049 > util.version = lambda: '3.6.1'
1041 > minimumhgversion = '3.6'
1050 > minimumhgversion = '3.6'
1042 > EOF
1051 > EOF
1043 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1052 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1044 [1]
1053 [1]
1045
1054
1046 Can load minimum version identical to current
1055 Can load minimum version identical to current
1047
1056
1048 $ cat > minversion3.py << EOF
1057 $ cat > minversion3.py << EOF
1049 > from mercurial import util
1058 > from mercurial import util
1050 > util.version = lambda: '3.5'
1059 > util.version = lambda: '3.5'
1051 > minimumhgversion = '3.5'
1060 > minimumhgversion = '3.5'
1052 > EOF
1061 > EOF
1053 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1062 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1054 [1]
1063 [1]
1055
1064
1056 Restore HGRCPATH
1065 Restore HGRCPATH
1057
1066
1058 $ HGRCPATH=$ORGHGRCPATH
1067 $ HGRCPATH=$ORGHGRCPATH
1059 $ export HGRCPATH
1068 $ export HGRCPATH
1060
1069
1061 Commands handling multiple repositories at a time should invoke only
1070 Commands handling multiple repositories at a time should invoke only
1062 "reposetup()" of extensions enabling in the target repository.
1071 "reposetup()" of extensions enabling in the target repository.
1063
1072
1064 $ mkdir reposetup-test
1073 $ mkdir reposetup-test
1065 $ cd reposetup-test
1074 $ cd reposetup-test
1066
1075
1067 $ cat > $TESTTMP/reposetuptest.py <<EOF
1076 $ cat > $TESTTMP/reposetuptest.py <<EOF
1068 > from mercurial import extensions
1077 > from mercurial import extensions
1069 > def reposetup(ui, repo):
1078 > def reposetup(ui, repo):
1070 > ui.write('reposetup() for %s\n' % (repo.root))
1079 > ui.write('reposetup() for %s\n' % (repo.root))
1071 > EOF
1080 > EOF
1072 $ hg init src
1081 $ hg init src
1073 $ echo a > src/a
1082 $ echo a > src/a
1074 $ hg -R src commit -Am '#0 at src/a'
1083 $ hg -R src commit -Am '#0 at src/a'
1075 adding a
1084 adding a
1076 $ echo '[extensions]' >> src/.hg/hgrc
1085 $ echo '[extensions]' >> src/.hg/hgrc
1077 $ echo '# enable extension locally' >> src/.hg/hgrc
1086 $ echo '# enable extension locally' >> src/.hg/hgrc
1078 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1087 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1079 $ hg -R src status
1088 $ hg -R src status
1080 reposetup() for $TESTTMP/reposetup-test/src (glob)
1089 reposetup() for $TESTTMP/reposetup-test/src (glob)
1081
1090
1082 $ hg clone -U src clone-dst1
1091 $ hg clone -U src clone-dst1
1083 reposetup() for $TESTTMP/reposetup-test/src (glob)
1092 reposetup() for $TESTTMP/reposetup-test/src (glob)
1084 $ hg init push-dst1
1093 $ hg init push-dst1
1085 $ hg -q -R src push push-dst1
1094 $ hg -q -R src push push-dst1
1086 reposetup() for $TESTTMP/reposetup-test/src (glob)
1095 reposetup() for $TESTTMP/reposetup-test/src (glob)
1087 $ hg init pull-src1
1096 $ hg init pull-src1
1088 $ hg -q -R pull-src1 pull src
1097 $ hg -q -R pull-src1 pull src
1089 reposetup() for $TESTTMP/reposetup-test/src (glob)
1098 reposetup() for $TESTTMP/reposetup-test/src (glob)
1090
1099
1091 $ cat <<EOF >> $HGRCPATH
1100 $ cat <<EOF >> $HGRCPATH
1092 > [extensions]
1101 > [extensions]
1093 > # disable extension globally and explicitly
1102 > # disable extension globally and explicitly
1094 > reposetuptest = !
1103 > reposetuptest = !
1095 > EOF
1104 > EOF
1096 $ hg clone -U src clone-dst2
1105 $ hg clone -U src clone-dst2
1097 reposetup() for $TESTTMP/reposetup-test/src (glob)
1106 reposetup() for $TESTTMP/reposetup-test/src (glob)
1098 $ hg init push-dst2
1107 $ hg init push-dst2
1099 $ hg -q -R src push push-dst2
1108 $ hg -q -R src push push-dst2
1100 reposetup() for $TESTTMP/reposetup-test/src (glob)
1109 reposetup() for $TESTTMP/reposetup-test/src (glob)
1101 $ hg init pull-src2
1110 $ hg init pull-src2
1102 $ hg -q -R pull-src2 pull src
1111 $ hg -q -R pull-src2 pull src
1103 reposetup() for $TESTTMP/reposetup-test/src (glob)
1112 reposetup() for $TESTTMP/reposetup-test/src (glob)
1104
1113
1105 $ cat <<EOF >> $HGRCPATH
1114 $ cat <<EOF >> $HGRCPATH
1106 > [extensions]
1115 > [extensions]
1107 > # enable extension globally
1116 > # enable extension globally
1108 > reposetuptest = $TESTTMP/reposetuptest.py
1117 > reposetuptest = $TESTTMP/reposetuptest.py
1109 > EOF
1118 > EOF
1110 $ hg clone -U src clone-dst3
1119 $ hg clone -U src clone-dst3
1111 reposetup() for $TESTTMP/reposetup-test/src (glob)
1120 reposetup() for $TESTTMP/reposetup-test/src (glob)
1112 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1121 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1113 $ hg init push-dst3
1122 $ hg init push-dst3
1114 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1123 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1115 $ hg -q -R src push push-dst3
1124 $ hg -q -R src push push-dst3
1116 reposetup() for $TESTTMP/reposetup-test/src (glob)
1125 reposetup() for $TESTTMP/reposetup-test/src (glob)
1117 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1126 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1118 $ hg init pull-src3
1127 $ hg init pull-src3
1119 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1128 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1120 $ hg -q -R pull-src3 pull src
1129 $ hg -q -R pull-src3 pull src
1121 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1130 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1122 reposetup() for $TESTTMP/reposetup-test/src (glob)
1131 reposetup() for $TESTTMP/reposetup-test/src (glob)
1123
1132
1124 $ echo '[extensions]' >> src/.hg/hgrc
1133 $ echo '[extensions]' >> src/.hg/hgrc
1125 $ echo '# disable extension locally' >> src/.hg/hgrc
1134 $ echo '# disable extension locally' >> src/.hg/hgrc
1126 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1135 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1127 $ hg clone -U src clone-dst4
1136 $ hg clone -U src clone-dst4
1128 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1137 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1129 $ hg init push-dst4
1138 $ hg init push-dst4
1130 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1139 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1131 $ hg -q -R src push push-dst4
1140 $ hg -q -R src push push-dst4
1132 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1141 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1133 $ hg init pull-src4
1142 $ hg init pull-src4
1134 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1143 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1135 $ hg -q -R pull-src4 pull src
1144 $ hg -q -R pull-src4 pull src
1136 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1145 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1137
1146
1138 disabling in command line overlays with all configuration
1147 disabling in command line overlays with all configuration
1139 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1148 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1140 $ hg --config extensions.reposetuptest=! init push-dst5
1149 $ hg --config extensions.reposetuptest=! init push-dst5
1141 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1150 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1142 $ hg --config extensions.reposetuptest=! init pull-src5
1151 $ hg --config extensions.reposetuptest=! init pull-src5
1143 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1152 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1144
1153
1145 $ cat <<EOF >> $HGRCPATH
1154 $ cat <<EOF >> $HGRCPATH
1146 > [extensions]
1155 > [extensions]
1147 > # disable extension globally and explicitly
1156 > # disable extension globally and explicitly
1148 > reposetuptest = !
1157 > reposetuptest = !
1149 > EOF
1158 > EOF
1150 $ hg init parent
1159 $ hg init parent
1151 $ hg init parent/sub1
1160 $ hg init parent/sub1
1152 $ echo 1 > parent/sub1/1
1161 $ echo 1 > parent/sub1/1
1153 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1162 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1154 adding 1
1163 adding 1
1155 $ hg init parent/sub2
1164 $ hg init parent/sub2
1156 $ hg init parent/sub2/sub21
1165 $ hg init parent/sub2/sub21
1157 $ echo 21 > parent/sub2/sub21/21
1166 $ echo 21 > parent/sub2/sub21/21
1158 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1167 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1159 adding 21
1168 adding 21
1160 $ cat > parent/sub2/.hgsub <<EOF
1169 $ cat > parent/sub2/.hgsub <<EOF
1161 > sub21 = sub21
1170 > sub21 = sub21
1162 > EOF
1171 > EOF
1163 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1172 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1164 adding .hgsub
1173 adding .hgsub
1165 $ hg init parent/sub3
1174 $ hg init parent/sub3
1166 $ echo 3 > parent/sub3/3
1175 $ echo 3 > parent/sub3/3
1167 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1176 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1168 adding 3
1177 adding 3
1169 $ cat > parent/.hgsub <<EOF
1178 $ cat > parent/.hgsub <<EOF
1170 > sub1 = sub1
1179 > sub1 = sub1
1171 > sub2 = sub2
1180 > sub2 = sub2
1172 > sub3 = sub3
1181 > sub3 = sub3
1173 > EOF
1182 > EOF
1174 $ hg -R parent commit -Am '#0 at parent'
1183 $ hg -R parent commit -Am '#0 at parent'
1175 adding .hgsub
1184 adding .hgsub
1176 $ echo '[extensions]' >> parent/.hg/hgrc
1185 $ echo '[extensions]' >> parent/.hg/hgrc
1177 $ echo '# enable extension locally' >> parent/.hg/hgrc
1186 $ echo '# enable extension locally' >> parent/.hg/hgrc
1178 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1187 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1179 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1188 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1180 $ hg -R parent status -S -A
1189 $ hg -R parent status -S -A
1181 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1190 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1182 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1191 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1183 C .hgsub
1192 C .hgsub
1184 C .hgsubstate
1193 C .hgsubstate
1185 C sub1/1
1194 C sub1/1
1186 C sub2/.hgsub
1195 C sub2/.hgsub
1187 C sub2/.hgsubstate
1196 C sub2/.hgsubstate
1188 C sub2/sub21/21
1197 C sub2/sub21/21
1189 C sub3/3
1198 C sub3/3
1190
1199
1191 $ cd ..
1200 $ cd ..
1192
1201
1193 Test synopsis and docstring extending
1202 Test synopsis and docstring extending
1194
1203
1195 $ hg init exthelp
1204 $ hg init exthelp
1196 $ cat > exthelp.py <<EOF
1205 $ cat > exthelp.py <<EOF
1197 > from mercurial import commands, extensions
1206 > from mercurial import commands, extensions
1198 > def exbookmarks(orig, *args, **opts):
1207 > def exbookmarks(orig, *args, **opts):
1199 > return orig(*args, **opts)
1208 > return orig(*args, **opts)
1200 > def uisetup(ui):
1209 > def uisetup(ui):
1201 > synopsis = ' GREPME [--foo] [-x]'
1210 > synopsis = ' GREPME [--foo] [-x]'
1202 > docstring = '''
1211 > docstring = '''
1203 > GREPME make sure that this is in the help!
1212 > GREPME make sure that this is in the help!
1204 > '''
1213 > '''
1205 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1214 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1206 > synopsis, docstring)
1215 > synopsis, docstring)
1207 > EOF
1216 > EOF
1208 $ abspath=`pwd`/exthelp.py
1217 $ abspath=`pwd`/exthelp.py
1209 $ echo '[extensions]' >> $HGRCPATH
1218 $ echo '[extensions]' >> $HGRCPATH
1210 $ echo "exthelp = $abspath" >> $HGRCPATH
1219 $ echo "exthelp = $abspath" >> $HGRCPATH
1211 $ cd exthelp
1220 $ cd exthelp
1212 $ hg help bookmarks | grep GREPME
1221 $ hg help bookmarks | grep GREPME
1213 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1222 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1214 GREPME make sure that this is in the help!
1223 GREPME make sure that this is in the help!
1215
1224
General Comments 0
You need to be logged in to leave comments. Login now