##// END OF EJS Templates
tests: avoid test failure for mangling path-like string by MSYS
FUJIWARA Katsunori -
r33098:c4a20c94 default
parent child Browse files
Show More
@@ -1,1678 +1,1684
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 commands, registrar
5 > from mercurial import commands, registrar
6 > cmdtable = {}
6 > cmdtable = {}
7 > command = registrar.command(cmdtable)
7 > command = registrar.command(cmdtable)
8 > def uisetup(ui):
8 > def uisetup(ui):
9 > ui.write("uisetup called\\n")
9 > ui.write("uisetup called\\n")
10 > ui.flush()
10 > ui.flush()
11 > def reposetup(ui, repo):
11 > def reposetup(ui, repo):
12 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
12 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
13 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
13 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
14 > ui.flush()
14 > ui.flush()
15 > @command(b'foo', [], 'hg foo')
15 > @command(b'foo', [], 'hg foo')
16 > def foo(ui, *args, **kwargs):
16 > def foo(ui, *args, **kwargs):
17 > ui.write("Foo\\n")
17 > ui.write("Foo\\n")
18 > @command(b'bar', [], 'hg bar', norepo=True)
18 > @command(b'bar', [], 'hg bar', norepo=True)
19 > def bar(ui, *args, **kwargs):
19 > def bar(ui, *args, **kwargs):
20 > ui.write("Bar\\n")
20 > ui.write("Bar\\n")
21 > EOF
21 > EOF
22 $ abspath=`pwd`/foobar.py
22 $ abspath=`pwd`/foobar.py
23
23
24 $ mkdir barfoo
24 $ mkdir barfoo
25 $ cp foobar.py barfoo/__init__.py
25 $ cp foobar.py barfoo/__init__.py
26 $ barfoopath=`pwd`/barfoo
26 $ barfoopath=`pwd`/barfoo
27
27
28 $ hg init a
28 $ hg init a
29 $ cd a
29 $ cd a
30 $ echo foo > file
30 $ echo foo > file
31 $ hg add file
31 $ hg add file
32 $ hg commit -m 'add file'
32 $ hg commit -m 'add file'
33
33
34 $ echo '[extensions]' >> $HGRCPATH
34 $ echo '[extensions]' >> $HGRCPATH
35 $ echo "foobar = $abspath" >> $HGRCPATH
35 $ echo "foobar = $abspath" >> $HGRCPATH
36 $ hg foo
36 $ hg foo
37 uisetup called
37 uisetup called
38 reposetup called for a
38 reposetup called for a
39 ui == repo.ui
39 ui == repo.ui
40 Foo
40 Foo
41
41
42 $ cd ..
42 $ cd ..
43 $ hg clone a b
43 $ hg clone a b
44 uisetup called
44 uisetup called
45 reposetup called for a
45 reposetup called for a
46 ui == repo.ui
46 ui == repo.ui
47 reposetup called for b
47 reposetup called for b
48 ui == repo.ui
48 ui == repo.ui
49 updating to branch default
49 updating to branch default
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51
51
52 $ hg bar
52 $ hg bar
53 uisetup called
53 uisetup called
54 Bar
54 Bar
55 $ echo 'foobar = !' >> $HGRCPATH
55 $ echo 'foobar = !' >> $HGRCPATH
56
56
57 module/__init__.py-style
57 module/__init__.py-style
58
58
59 $ echo "barfoo = $barfoopath" >> $HGRCPATH
59 $ echo "barfoo = $barfoopath" >> $HGRCPATH
60 $ cd a
60 $ cd a
61 $ hg foo
61 $ hg foo
62 uisetup called
62 uisetup called
63 reposetup called for a
63 reposetup called for a
64 ui == repo.ui
64 ui == repo.ui
65 Foo
65 Foo
66 $ echo 'barfoo = !' >> $HGRCPATH
66 $ echo 'barfoo = !' >> $HGRCPATH
67
67
68 Check that extensions are loaded in phases:
68 Check that extensions are loaded in phases:
69
69
70 $ cat > foo.py <<EOF
70 $ cat > foo.py <<EOF
71 > import os
71 > import os
72 > name = os.path.basename(__file__).rsplit('.', 1)[0]
72 > name = os.path.basename(__file__).rsplit('.', 1)[0]
73 > print "1) %s imported" % name
73 > print "1) %s imported" % name
74 > def uisetup(ui):
74 > def uisetup(ui):
75 > print "2) %s uisetup" % name
75 > print "2) %s uisetup" % name
76 > def extsetup():
76 > def extsetup():
77 > print "3) %s extsetup" % name
77 > print "3) %s extsetup" % name
78 > def reposetup(ui, repo):
78 > def reposetup(ui, repo):
79 > print "4) %s reposetup" % name
79 > print "4) %s reposetup" % name
80 >
80 >
81 > # custom predicate to check registration of functions at loading
81 > # custom predicate to check registration of functions at loading
82 > from mercurial import (
82 > from mercurial import (
83 > registrar,
83 > registrar,
84 > smartset,
84 > smartset,
85 > )
85 > )
86 > revsetpredicate = registrar.revsetpredicate()
86 > revsetpredicate = registrar.revsetpredicate()
87 > @revsetpredicate(name, safe=True) # safe=True for query via hgweb
87 > @revsetpredicate(name, safe=True) # safe=True for query via hgweb
88 > def custompredicate(repo, subset, x):
88 > def custompredicate(repo, subset, x):
89 > return smartset.baseset([r for r in subset if r in {0}])
89 > return smartset.baseset([r for r in subset if r in {0}])
90 > EOF
90 > EOF
91
91
92 $ cp foo.py bar.py
92 $ cp foo.py bar.py
93 $ echo 'foo = foo.py' >> $HGRCPATH
93 $ echo 'foo = foo.py' >> $HGRCPATH
94 $ echo 'bar = bar.py' >> $HGRCPATH
94 $ echo 'bar = bar.py' >> $HGRCPATH
95
95
96 Check normal command's load order of extensions and registration of functions
96 Check normal command's load order of extensions and registration of functions
97
97
98 $ hg log -r "foo() and bar()" -q
98 $ hg log -r "foo() and bar()" -q
99 1) foo imported
99 1) foo imported
100 1) bar imported
100 1) bar imported
101 2) foo uisetup
101 2) foo uisetup
102 2) bar uisetup
102 2) bar uisetup
103 3) foo extsetup
103 3) foo extsetup
104 3) bar extsetup
104 3) bar extsetup
105 4) foo reposetup
105 4) foo reposetup
106 4) bar reposetup
106 4) bar reposetup
107 0:c24b9ac61126
107 0:c24b9ac61126
108
108
109 Check hgweb's load order of extensions and registration of functions
109 Check hgweb's load order of extensions and registration of functions
110
110
111 $ cat > hgweb.cgi <<EOF
111 $ cat > hgweb.cgi <<EOF
112 > #!$PYTHON
112 > #!$PYTHON
113 > from mercurial import demandimport; demandimport.enable()
113 > from mercurial import demandimport; demandimport.enable()
114 > from mercurial.hgweb import hgweb
114 > from mercurial.hgweb import hgweb
115 > from mercurial.hgweb import wsgicgi
115 > from mercurial.hgweb import wsgicgi
116 > application = hgweb('.', 'test repo')
116 > application = hgweb('.', 'test repo')
117 > wsgicgi.launch(application)
117 > wsgicgi.launch(application)
118 > EOF
118 > EOF
119
119
120 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
120 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
121 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
121 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
122 > | grep '^[0-9]) ' # ignores HTML output
122 > | grep '^[0-9]) ' # ignores HTML output
123 1) foo imported
123 1) foo imported
124 1) bar imported
124 1) bar imported
125 2) foo uisetup
125 2) foo uisetup
126 2) bar uisetup
126 2) bar uisetup
127 3) foo extsetup
127 3) foo extsetup
128 3) bar extsetup
128 3) bar extsetup
129 4) foo reposetup
129 4) foo reposetup
130 4) bar reposetup
130 4) bar reposetup
131
131
132 (check that revset predicate foo() and bar() are available)
132 (check that revset predicate foo() and bar() are available)
133
133
134 $ REQUEST_METHOD='GET' PATH_INFO='/shortlog' SCRIPT_NAME='' \
134 #if msys
135 $ PATH_INFO='//shortlog'
136 #else
137 $ PATH_INFO='/shortlog'
138 #endif
139 $ export PATH_INFO
140 $ REQUEST_METHOD='GET' SCRIPT_NAME='' \
135 > QUERY_STRING='rev=foo() and bar()' \
141 > QUERY_STRING='rev=foo() and bar()' \
136 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
142 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
137 > | grep '<a href="/rev/[0-9a-z]*">'
143 > | grep '<a href="/rev/[0-9a-z]*">'
138 <a href="/rev/c24b9ac61126">add file</a>
144 <a href="/rev/c24b9ac61126">add file</a>
139
145
140 $ echo 'foo = !' >> $HGRCPATH
146 $ echo 'foo = !' >> $HGRCPATH
141 $ echo 'bar = !' >> $HGRCPATH
147 $ echo 'bar = !' >> $HGRCPATH
142
148
143 Check "from __future__ import absolute_import" support for external libraries
149 Check "from __future__ import absolute_import" support for external libraries
144
150
145 #if windows
151 #if windows
146 $ PATHSEP=";"
152 $ PATHSEP=";"
147 #else
153 #else
148 $ PATHSEP=":"
154 $ PATHSEP=":"
149 #endif
155 #endif
150 $ export PATHSEP
156 $ export PATHSEP
151
157
152 $ mkdir $TESTTMP/libroot
158 $ mkdir $TESTTMP/libroot
153 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
159 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
154 $ mkdir $TESTTMP/libroot/mod
160 $ mkdir $TESTTMP/libroot/mod
155 $ touch $TESTTMP/libroot/mod/__init__.py
161 $ touch $TESTTMP/libroot/mod/__init__.py
156 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
162 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
157
163
158 #if absimport
164 #if absimport
159 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
165 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
160 > from __future__ import absolute_import
166 > from __future__ import absolute_import
161 > import ambig # should load "libroot/ambig.py"
167 > import ambig # should load "libroot/ambig.py"
162 > s = ambig.s
168 > s = ambig.s
163 > EOF
169 > EOF
164 $ cat > loadabs.py <<EOF
170 $ cat > loadabs.py <<EOF
165 > import mod.ambigabs as ambigabs
171 > import mod.ambigabs as ambigabs
166 > def extsetup():
172 > def extsetup():
167 > print 'ambigabs.s=%s' % ambigabs.s
173 > print 'ambigabs.s=%s' % ambigabs.s
168 > EOF
174 > EOF
169 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
175 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
170 ambigabs.s=libroot/ambig.py
176 ambigabs.s=libroot/ambig.py
171 $TESTTMP/a (glob)
177 $TESTTMP/a (glob)
172 #endif
178 #endif
173
179
174 #if no-py3k
180 #if no-py3k
175 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
181 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
176 > import ambig # should load "libroot/mod/ambig.py"
182 > import ambig # should load "libroot/mod/ambig.py"
177 > s = ambig.s
183 > s = ambig.s
178 > EOF
184 > EOF
179 $ cat > loadrel.py <<EOF
185 $ cat > loadrel.py <<EOF
180 > import mod.ambigrel as ambigrel
186 > import mod.ambigrel as ambigrel
181 > def extsetup():
187 > def extsetup():
182 > print 'ambigrel.s=%s' % ambigrel.s
188 > print 'ambigrel.s=%s' % ambigrel.s
183 > EOF
189 > EOF
184 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
190 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
185 ambigrel.s=libroot/mod/ambig.py
191 ambigrel.s=libroot/mod/ambig.py
186 $TESTTMP/a (glob)
192 $TESTTMP/a (glob)
187 #endif
193 #endif
188
194
189 Check absolute/relative import of extension specific modules
195 Check absolute/relative import of extension specific modules
190
196
191 $ mkdir $TESTTMP/extroot
197 $ mkdir $TESTTMP/extroot
192 $ cat > $TESTTMP/extroot/bar.py <<EOF
198 $ cat > $TESTTMP/extroot/bar.py <<EOF
193 > s = 'this is extroot.bar'
199 > s = 'this is extroot.bar'
194 > EOF
200 > EOF
195 $ mkdir $TESTTMP/extroot/sub1
201 $ mkdir $TESTTMP/extroot/sub1
196 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
202 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
197 > s = 'this is extroot.sub1.__init__'
203 > s = 'this is extroot.sub1.__init__'
198 > EOF
204 > EOF
199 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
205 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
200 > s = 'this is extroot.sub1.baz'
206 > s = 'this is extroot.sub1.baz'
201 > EOF
207 > EOF
202 $ cat > $TESTTMP/extroot/__init__.py <<EOF
208 $ cat > $TESTTMP/extroot/__init__.py <<EOF
203 > s = 'this is extroot.__init__'
209 > s = 'this is extroot.__init__'
204 > import foo
210 > import foo
205 > def extsetup(ui):
211 > def extsetup(ui):
206 > ui.write('(extroot) ', foo.func(), '\n')
212 > ui.write('(extroot) ', foo.func(), '\n')
207 > ui.flush()
213 > ui.flush()
208 > EOF
214 > EOF
209
215
210 $ cat > $TESTTMP/extroot/foo.py <<EOF
216 $ cat > $TESTTMP/extroot/foo.py <<EOF
211 > # test absolute import
217 > # test absolute import
212 > buf = []
218 > buf = []
213 > def func():
219 > def func():
214 > # "not locals" case
220 > # "not locals" case
215 > import extroot.bar
221 > import extroot.bar
216 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
222 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
217 > return '\n(extroot) '.join(buf)
223 > return '\n(extroot) '.join(buf)
218 > # "fromlist == ('*',)" case
224 > # "fromlist == ('*',)" case
219 > from extroot.bar import *
225 > from extroot.bar import *
220 > buf.append('from extroot.bar import *: %s' % s)
226 > buf.append('from extroot.bar import *: %s' % s)
221 > # "not fromlist" and "if '.' in name" case
227 > # "not fromlist" and "if '.' in name" case
222 > import extroot.sub1.baz
228 > import extroot.sub1.baz
223 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
229 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
224 > # "not fromlist" and NOT "if '.' in name" case
230 > # "not fromlist" and NOT "if '.' in name" case
225 > import extroot
231 > import extroot
226 > buf.append('import extroot: %s' % extroot.s)
232 > buf.append('import extroot: %s' % extroot.s)
227 > # NOT "not fromlist" and NOT "level != -1" case
233 > # NOT "not fromlist" and NOT "level != -1" case
228 > from extroot.bar import s
234 > from extroot.bar import s
229 > buf.append('from extroot.bar import s: %s' % s)
235 > buf.append('from extroot.bar import s: %s' % s)
230 > EOF
236 > EOF
231 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
237 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
232 (extroot) from extroot.bar import *: this is extroot.bar
238 (extroot) from extroot.bar import *: this is extroot.bar
233 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
239 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
234 (extroot) import extroot: this is extroot.__init__
240 (extroot) import extroot: this is extroot.__init__
235 (extroot) from extroot.bar import s: this is extroot.bar
241 (extroot) from extroot.bar import s: this is extroot.bar
236 (extroot) import extroot.bar in func(): this is extroot.bar
242 (extroot) import extroot.bar in func(): this is extroot.bar
237 $TESTTMP/a (glob)
243 $TESTTMP/a (glob)
238
244
239 #if no-py3k
245 #if no-py3k
240 $ rm "$TESTTMP"/extroot/foo.*
246 $ rm "$TESTTMP"/extroot/foo.*
241 $ cat > $TESTTMP/extroot/foo.py <<EOF
247 $ cat > $TESTTMP/extroot/foo.py <<EOF
242 > # test relative import
248 > # test relative import
243 > buf = []
249 > buf = []
244 > def func():
250 > def func():
245 > # "not locals" case
251 > # "not locals" case
246 > import bar
252 > import bar
247 > buf.append('import bar in func(): %s' % bar.s)
253 > buf.append('import bar in func(): %s' % bar.s)
248 > return '\n(extroot) '.join(buf)
254 > return '\n(extroot) '.join(buf)
249 > # "fromlist == ('*',)" case
255 > # "fromlist == ('*',)" case
250 > from bar import *
256 > from bar import *
251 > buf.append('from bar import *: %s' % s)
257 > buf.append('from bar import *: %s' % s)
252 > # "not fromlist" and "if '.' in name" case
258 > # "not fromlist" and "if '.' in name" case
253 > import sub1.baz
259 > import sub1.baz
254 > buf.append('import sub1.baz: %s' % sub1.baz.s)
260 > buf.append('import sub1.baz: %s' % sub1.baz.s)
255 > # "not fromlist" and NOT "if '.' in name" case
261 > # "not fromlist" and NOT "if '.' in name" case
256 > import sub1
262 > import sub1
257 > buf.append('import sub1: %s' % sub1.s)
263 > buf.append('import sub1: %s' % sub1.s)
258 > # NOT "not fromlist" and NOT "level != -1" case
264 > # NOT "not fromlist" and NOT "level != -1" case
259 > from bar import s
265 > from bar import s
260 > buf.append('from bar import s: %s' % s)
266 > buf.append('from bar import s: %s' % s)
261 > EOF
267 > EOF
262 $ hg --config extensions.extroot=$TESTTMP/extroot root
268 $ hg --config extensions.extroot=$TESTTMP/extroot root
263 (extroot) from bar import *: this is extroot.bar
269 (extroot) from bar import *: this is extroot.bar
264 (extroot) import sub1.baz: this is extroot.sub1.baz
270 (extroot) import sub1.baz: this is extroot.sub1.baz
265 (extroot) import sub1: this is extroot.sub1.__init__
271 (extroot) import sub1: this is extroot.sub1.__init__
266 (extroot) from bar import s: this is extroot.bar
272 (extroot) from bar import s: this is extroot.bar
267 (extroot) import bar in func(): this is extroot.bar
273 (extroot) import bar in func(): this is extroot.bar
268 $TESTTMP/a (glob)
274 $TESTTMP/a (glob)
269 #endif
275 #endif
270
276
271 #if demandimport absimport
277 #if demandimport absimport
272
278
273 Examine whether module loading is delayed until actual referring, even
279 Examine whether module loading is delayed until actual referring, even
274 though module is imported with "absolute_import" feature.
280 though module is imported with "absolute_import" feature.
275
281
276 Files below in each packages are used for described purpose:
282 Files below in each packages are used for described purpose:
277
283
278 - "called": examine whether "from MODULE import ATTR" works correctly
284 - "called": examine whether "from MODULE import ATTR" works correctly
279 - "unused": examine whether loading is delayed correctly
285 - "unused": examine whether loading is delayed correctly
280 - "used": examine whether "from PACKAGE import MODULE" works correctly
286 - "used": examine whether "from PACKAGE import MODULE" works correctly
281
287
282 Package hierarchy is needed to examine whether demand importing works
288 Package hierarchy is needed to examine whether demand importing works
283 as expected for "from SUB.PACK.AGE import MODULE".
289 as expected for "from SUB.PACK.AGE import MODULE".
284
290
285 Setup "external library" to be imported with "absolute_import"
291 Setup "external library" to be imported with "absolute_import"
286 feature.
292 feature.
287
293
288 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
294 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
289 $ touch $TESTTMP/extlibroot/__init__.py
295 $ touch $TESTTMP/extlibroot/__init__.py
290 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
296 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
291 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
297 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
292
298
293 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
299 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
294 > def func():
300 > def func():
295 > return "this is extlibroot.lsub1.lsub2.called.func()"
301 > return "this is extlibroot.lsub1.lsub2.called.func()"
296 > EOF
302 > EOF
297 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
303 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
298 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
304 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
299 > EOF
305 > EOF
300 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
306 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
301 > detail = "this is extlibroot.lsub1.lsub2.used"
307 > detail = "this is extlibroot.lsub1.lsub2.used"
302 > EOF
308 > EOF
303
309
304 Setup sub-package of "external library", which causes instantiation of
310 Setup sub-package of "external library", which causes instantiation of
305 demandmod in "recurse down the module chain" code path. Relative
311 demandmod in "recurse down the module chain" code path. Relative
306 importing with "absolute_import" feature isn't tested, because "level
312 importing with "absolute_import" feature isn't tested, because "level
307 >=1 " doesn't cause instantiation of demandmod.
313 >=1 " doesn't cause instantiation of demandmod.
308
314
309 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
315 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
310 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
316 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
311 > detail = "this is extlibroot.recursedown.abs.used"
317 > detail = "this is extlibroot.recursedown.abs.used"
312 > EOF
318 > EOF
313 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
319 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
314 > from __future__ import absolute_import
320 > from __future__ import absolute_import
315 > from extlibroot.recursedown.abs.used import detail
321 > from extlibroot.recursedown.abs.used import detail
316 > EOF
322 > EOF
317
323
318 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
324 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
319 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
325 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
320 > detail = "this is extlibroot.recursedown.legacy.used"
326 > detail = "this is extlibroot.recursedown.legacy.used"
321 > EOF
327 > EOF
322 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
328 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
323 > # legacy style (level == -1) import
329 > # legacy style (level == -1) import
324 > from extlibroot.recursedown.legacy.used import detail
330 > from extlibroot.recursedown.legacy.used import detail
325 > EOF
331 > EOF
326
332
327 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
333 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
328 > from __future__ import absolute_import
334 > from __future__ import absolute_import
329 > from extlibroot.recursedown.abs import detail as absdetail
335 > from extlibroot.recursedown.abs import detail as absdetail
330 > from .legacy import detail as legacydetail
336 > from .legacy import detail as legacydetail
331 > EOF
337 > EOF
332
338
333 Setup extension local modules to be imported with "absolute_import"
339 Setup extension local modules to be imported with "absolute_import"
334 feature.
340 feature.
335
341
336 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
342 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
337 $ touch $TESTTMP/absextroot/xsub1/__init__.py
343 $ touch $TESTTMP/absextroot/xsub1/__init__.py
338 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
344 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
339
345
340 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
346 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
341 > def func():
347 > def func():
342 > return "this is absextroot.xsub1.xsub2.called.func()"
348 > return "this is absextroot.xsub1.xsub2.called.func()"
343 > EOF
349 > EOF
344 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
350 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
345 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
351 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
346 > EOF
352 > EOF
347 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
353 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
348 > detail = "this is absextroot.xsub1.xsub2.used"
354 > detail = "this is absextroot.xsub1.xsub2.used"
349 > EOF
355 > EOF
350
356
351 Setup extension local modules to examine whether demand importing
357 Setup extension local modules to examine whether demand importing
352 works as expected in "level > 1" case.
358 works as expected in "level > 1" case.
353
359
354 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
360 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
355 > detail = "this is absextroot.relimportee"
361 > detail = "this is absextroot.relimportee"
356 > EOF
362 > EOF
357 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
363 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
358 > from __future__ import absolute_import
364 > from __future__ import absolute_import
359 > from ... import relimportee
365 > from ... import relimportee
360 > detail = "this relimporter imports %r" % (relimportee.detail)
366 > detail = "this relimporter imports %r" % (relimportee.detail)
361 > EOF
367 > EOF
362
368
363 Setup modules, which actually import extension local modules at
369 Setup modules, which actually import extension local modules at
364 runtime.
370 runtime.
365
371
366 $ cat > $TESTTMP/absextroot/absolute.py << EOF
372 $ cat > $TESTTMP/absextroot/absolute.py << EOF
367 > from __future__ import absolute_import
373 > from __future__ import absolute_import
368 >
374 >
369 > # import extension local modules absolutely (level = 0)
375 > # import extension local modules absolutely (level = 0)
370 > from absextroot.xsub1.xsub2 import used, unused
376 > from absextroot.xsub1.xsub2 import used, unused
371 > from absextroot.xsub1.xsub2.called import func
377 > from absextroot.xsub1.xsub2.called import func
372 >
378 >
373 > def getresult():
379 > def getresult():
374 > result = []
380 > result = []
375 > result.append(used.detail)
381 > result.append(used.detail)
376 > result.append(func())
382 > result.append(func())
377 > return result
383 > return result
378 > EOF
384 > EOF
379
385
380 $ cat > $TESTTMP/absextroot/relative.py << EOF
386 $ cat > $TESTTMP/absextroot/relative.py << EOF
381 > from __future__ import absolute_import
387 > from __future__ import absolute_import
382 >
388 >
383 > # import extension local modules relatively (level == 1)
389 > # import extension local modules relatively (level == 1)
384 > from .xsub1.xsub2 import used, unused
390 > from .xsub1.xsub2 import used, unused
385 > from .xsub1.xsub2.called import func
391 > from .xsub1.xsub2.called import func
386 >
392 >
387 > # import a module, which implies "importing with level > 1"
393 > # import a module, which implies "importing with level > 1"
388 > from .xsub1.xsub2 import relimporter
394 > from .xsub1.xsub2 import relimporter
389 >
395 >
390 > def getresult():
396 > def getresult():
391 > result = []
397 > result = []
392 > result.append(used.detail)
398 > result.append(used.detail)
393 > result.append(func())
399 > result.append(func())
394 > result.append(relimporter.detail)
400 > result.append(relimporter.detail)
395 > return result
401 > return result
396 > EOF
402 > EOF
397
403
398 Setup main procedure of extension.
404 Setup main procedure of extension.
399
405
400 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
406 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
401 > from __future__ import absolute_import
407 > from __future__ import absolute_import
402 > from mercurial import registrar
408 > from mercurial import registrar
403 > cmdtable = {}
409 > cmdtable = {}
404 > command = registrar.command(cmdtable)
410 > command = registrar.command(cmdtable)
405 >
411 >
406 > # "absolute" and "relative" shouldn't be imported before actual
412 > # "absolute" and "relative" shouldn't be imported before actual
407 > # command execution, because (1) they import same modules, and (2)
413 > # command execution, because (1) they import same modules, and (2)
408 > # preceding import (= instantiate "demandmod" object instead of
414 > # preceding import (= instantiate "demandmod" object instead of
409 > # real "module" object) might hide problem of succeeding import.
415 > # real "module" object) might hide problem of succeeding import.
410 >
416 >
411 > @command(b'showabsolute', [], norepo=True)
417 > @command(b'showabsolute', [], norepo=True)
412 > def showabsolute(ui, *args, **opts):
418 > def showabsolute(ui, *args, **opts):
413 > from absextroot import absolute
419 > from absextroot import absolute
414 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
420 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
415 >
421 >
416 > @command(b'showrelative', [], norepo=True)
422 > @command(b'showrelative', [], norepo=True)
417 > def showrelative(ui, *args, **opts):
423 > def showrelative(ui, *args, **opts):
418 > from . import relative
424 > from . import relative
419 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
425 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
420 >
426 >
421 > # import modules from external library
427 > # import modules from external library
422 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
428 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
423 > from extlibroot.lsub1.lsub2.called import func as lfunc
429 > from extlibroot.lsub1.lsub2.called import func as lfunc
424 > from extlibroot.recursedown import absdetail, legacydetail
430 > from extlibroot.recursedown import absdetail, legacydetail
425 >
431 >
426 > def uisetup(ui):
432 > def uisetup(ui):
427 > result = []
433 > result = []
428 > result.append(lused.detail)
434 > result.append(lused.detail)
429 > result.append(lfunc())
435 > result.append(lfunc())
430 > result.append(absdetail)
436 > result.append(absdetail)
431 > result.append(legacydetail)
437 > result.append(legacydetail)
432 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
438 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
433 > EOF
439 > EOF
434
440
435 Examine module importing.
441 Examine module importing.
436
442
437 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
443 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
438 LIB: this is extlibroot.lsub1.lsub2.used
444 LIB: this is extlibroot.lsub1.lsub2.used
439 LIB: this is extlibroot.lsub1.lsub2.called.func()
445 LIB: this is extlibroot.lsub1.lsub2.called.func()
440 LIB: this is extlibroot.recursedown.abs.used
446 LIB: this is extlibroot.recursedown.abs.used
441 LIB: this is extlibroot.recursedown.legacy.used
447 LIB: this is extlibroot.recursedown.legacy.used
442 ABS: this is absextroot.xsub1.xsub2.used
448 ABS: this is absextroot.xsub1.xsub2.used
443 ABS: this is absextroot.xsub1.xsub2.called.func()
449 ABS: this is absextroot.xsub1.xsub2.called.func()
444
450
445 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
451 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
446 LIB: this is extlibroot.lsub1.lsub2.used
452 LIB: this is extlibroot.lsub1.lsub2.used
447 LIB: this is extlibroot.lsub1.lsub2.called.func()
453 LIB: this is extlibroot.lsub1.lsub2.called.func()
448 LIB: this is extlibroot.recursedown.abs.used
454 LIB: this is extlibroot.recursedown.abs.used
449 LIB: this is extlibroot.recursedown.legacy.used
455 LIB: this is extlibroot.recursedown.legacy.used
450 REL: this is absextroot.xsub1.xsub2.used
456 REL: this is absextroot.xsub1.xsub2.used
451 REL: this is absextroot.xsub1.xsub2.called.func()
457 REL: this is absextroot.xsub1.xsub2.called.func()
452 REL: this relimporter imports 'this is absextroot.relimportee'
458 REL: this relimporter imports 'this is absextroot.relimportee'
453
459
454 Examine whether sub-module is imported relatively as expected.
460 Examine whether sub-module is imported relatively as expected.
455
461
456 See also issue5208 for detail about example case on Python 3.x.
462 See also issue5208 for detail about example case on Python 3.x.
457
463
458 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
464 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
459 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
465 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
460
466
461 $ cat > $TESTTMP/notexist.py <<EOF
467 $ cat > $TESTTMP/notexist.py <<EOF
462 > text = 'notexist.py at root is loaded unintentionally\n'
468 > text = 'notexist.py at root is loaded unintentionally\n'
463 > EOF
469 > EOF
464
470
465 $ cat > $TESTTMP/checkrelativity.py <<EOF
471 $ cat > $TESTTMP/checkrelativity.py <<EOF
466 > from mercurial import registrar
472 > from mercurial import registrar
467 > cmdtable = {}
473 > cmdtable = {}
468 > command = registrar.command(cmdtable)
474 > command = registrar.command(cmdtable)
469 >
475 >
470 > # demand import avoids failure of importing notexist here
476 > # demand import avoids failure of importing notexist here
471 > import extlibroot.lsub1.lsub2.notexist
477 > import extlibroot.lsub1.lsub2.notexist
472 >
478 >
473 > @command(b'checkrelativity', [], norepo=True)
479 > @command(b'checkrelativity', [], norepo=True)
474 > def checkrelativity(ui, *args, **opts):
480 > def checkrelativity(ui, *args, **opts):
475 > try:
481 > try:
476 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
482 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
477 > return 1 # unintentional success
483 > return 1 # unintentional success
478 > except ImportError:
484 > except ImportError:
479 > pass # intentional failure
485 > pass # intentional failure
480 > EOF
486 > EOF
481
487
482 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
488 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
483
489
484 #endif
490 #endif
485
491
486 $ cd ..
492 $ cd ..
487
493
488 hide outer repo
494 hide outer repo
489 $ hg init
495 $ hg init
490
496
491 $ cat > empty.py <<EOF
497 $ cat > empty.py <<EOF
492 > '''empty cmdtable
498 > '''empty cmdtable
493 > '''
499 > '''
494 > cmdtable = {}
500 > cmdtable = {}
495 > EOF
501 > EOF
496 $ emptypath=`pwd`/empty.py
502 $ emptypath=`pwd`/empty.py
497 $ echo "empty = $emptypath" >> $HGRCPATH
503 $ echo "empty = $emptypath" >> $HGRCPATH
498 $ hg help empty
504 $ hg help empty
499 empty extension - empty cmdtable
505 empty extension - empty cmdtable
500
506
501 no commands defined
507 no commands defined
502
508
503
509
504 $ echo 'empty = !' >> $HGRCPATH
510 $ echo 'empty = !' >> $HGRCPATH
505
511
506 $ cat > debugextension.py <<EOF
512 $ cat > debugextension.py <<EOF
507 > '''only debugcommands
513 > '''only debugcommands
508 > '''
514 > '''
509 > from mercurial import registrar
515 > from mercurial import registrar
510 > cmdtable = {}
516 > cmdtable = {}
511 > command = registrar.command(cmdtable)
517 > command = registrar.command(cmdtable)
512 > @command(b'debugfoobar', [], 'hg debugfoobar')
518 > @command(b'debugfoobar', [], 'hg debugfoobar')
513 > def debugfoobar(ui, repo, *args, **opts):
519 > def debugfoobar(ui, repo, *args, **opts):
514 > "yet another debug command"
520 > "yet another debug command"
515 > pass
521 > pass
516 > @command(b'foo', [], 'hg foo')
522 > @command(b'foo', [], 'hg foo')
517 > def foo(ui, repo, *args, **opts):
523 > def foo(ui, repo, *args, **opts):
518 > """yet another foo command
524 > """yet another foo command
519 > This command has been DEPRECATED since forever.
525 > This command has been DEPRECATED since forever.
520 > """
526 > """
521 > pass
527 > pass
522 > EOF
528 > EOF
523 $ debugpath=`pwd`/debugextension.py
529 $ debugpath=`pwd`/debugextension.py
524 $ echo "debugextension = $debugpath" >> $HGRCPATH
530 $ echo "debugextension = $debugpath" >> $HGRCPATH
525
531
526 $ hg help debugextension
532 $ hg help debugextension
527 hg debugextensions
533 hg debugextensions
528
534
529 show information about active extensions
535 show information about active extensions
530
536
531 options:
537 options:
532
538
533 (some details hidden, use --verbose to show complete help)
539 (some details hidden, use --verbose to show complete help)
534
540
535
541
536 $ hg --verbose help debugextension
542 $ hg --verbose help debugextension
537 hg debugextensions
543 hg debugextensions
538
544
539 show information about active extensions
545 show information about active extensions
540
546
541 options:
547 options:
542
548
543 -T --template TEMPLATE display with template (EXPERIMENTAL)
549 -T --template TEMPLATE display with template (EXPERIMENTAL)
544
550
545 global options ([+] can be repeated):
551 global options ([+] can be repeated):
546
552
547 -R --repository REPO repository root directory or name of overlay bundle
553 -R --repository REPO repository root directory or name of overlay bundle
548 file
554 file
549 --cwd DIR change working directory
555 --cwd DIR change working directory
550 -y --noninteractive do not prompt, automatically pick the first choice for
556 -y --noninteractive do not prompt, automatically pick the first choice for
551 all prompts
557 all prompts
552 -q --quiet suppress output
558 -q --quiet suppress output
553 -v --verbose enable additional output
559 -v --verbose enable additional output
554 --color TYPE when to colorize (boolean, always, auto, never, or
560 --color TYPE when to colorize (boolean, always, auto, never, or
555 debug)
561 debug)
556 --config CONFIG [+] set/override config option (use 'section.name=value')
562 --config CONFIG [+] set/override config option (use 'section.name=value')
557 --debug enable debugging output
563 --debug enable debugging output
558 --debugger start debugger
564 --debugger start debugger
559 --encoding ENCODE set the charset encoding (default: ascii)
565 --encoding ENCODE set the charset encoding (default: ascii)
560 --encodingmode MODE set the charset encoding mode (default: strict)
566 --encodingmode MODE set the charset encoding mode (default: strict)
561 --traceback always print a traceback on exception
567 --traceback always print a traceback on exception
562 --time time how long the command takes
568 --time time how long the command takes
563 --profile print command execution profile
569 --profile print command execution profile
564 --version output version information and exit
570 --version output version information and exit
565 -h --help display help and exit
571 -h --help display help and exit
566 --hidden consider hidden changesets
572 --hidden consider hidden changesets
567 --pager TYPE when to paginate (boolean, always, auto, or never)
573 --pager TYPE when to paginate (boolean, always, auto, or never)
568 (default: auto)
574 (default: auto)
569
575
570
576
571
577
572
578
573
579
574
580
575 $ hg --debug help debugextension
581 $ hg --debug help debugextension
576 hg debugextensions
582 hg debugextensions
577
583
578 show information about active extensions
584 show information about active extensions
579
585
580 options:
586 options:
581
587
582 -T --template TEMPLATE display with template (EXPERIMENTAL)
588 -T --template TEMPLATE display with template (EXPERIMENTAL)
583
589
584 global options ([+] can be repeated):
590 global options ([+] can be repeated):
585
591
586 -R --repository REPO repository root directory or name of overlay bundle
592 -R --repository REPO repository root directory or name of overlay bundle
587 file
593 file
588 --cwd DIR change working directory
594 --cwd DIR change working directory
589 -y --noninteractive do not prompt, automatically pick the first choice for
595 -y --noninteractive do not prompt, automatically pick the first choice for
590 all prompts
596 all prompts
591 -q --quiet suppress output
597 -q --quiet suppress output
592 -v --verbose enable additional output
598 -v --verbose enable additional output
593 --color TYPE when to colorize (boolean, always, auto, never, or
599 --color TYPE when to colorize (boolean, always, auto, never, or
594 debug)
600 debug)
595 --config CONFIG [+] set/override config option (use 'section.name=value')
601 --config CONFIG [+] set/override config option (use 'section.name=value')
596 --debug enable debugging output
602 --debug enable debugging output
597 --debugger start debugger
603 --debugger start debugger
598 --encoding ENCODE set the charset encoding (default: ascii)
604 --encoding ENCODE set the charset encoding (default: ascii)
599 --encodingmode MODE set the charset encoding mode (default: strict)
605 --encodingmode MODE set the charset encoding mode (default: strict)
600 --traceback always print a traceback on exception
606 --traceback always print a traceback on exception
601 --time time how long the command takes
607 --time time how long the command takes
602 --profile print command execution profile
608 --profile print command execution profile
603 --version output version information and exit
609 --version output version information and exit
604 -h --help display help and exit
610 -h --help display help and exit
605 --hidden consider hidden changesets
611 --hidden consider hidden changesets
606 --pager TYPE when to paginate (boolean, always, auto, or never)
612 --pager TYPE when to paginate (boolean, always, auto, or never)
607 (default: auto)
613 (default: auto)
608
614
609
615
610
616
611
617
612
618
613 $ echo 'debugextension = !' >> $HGRCPATH
619 $ echo 'debugextension = !' >> $HGRCPATH
614
620
615 Asking for help about a deprecated extension should do something useful:
621 Asking for help about a deprecated extension should do something useful:
616
622
617 $ hg help glog
623 $ hg help glog
618 'glog' is provided by the following extension:
624 'glog' is provided by the following extension:
619
625
620 graphlog command to view revision graphs from a shell (DEPRECATED)
626 graphlog command to view revision graphs from a shell (DEPRECATED)
621
627
622 (use 'hg help extensions' for information on enabling extensions)
628 (use 'hg help extensions' for information on enabling extensions)
623
629
624 Extension module help vs command help:
630 Extension module help vs command help:
625
631
626 $ echo 'extdiff =' >> $HGRCPATH
632 $ echo 'extdiff =' >> $HGRCPATH
627 $ hg help extdiff
633 $ hg help extdiff
628 hg extdiff [OPT]... [FILE]...
634 hg extdiff [OPT]... [FILE]...
629
635
630 use external program to diff repository (or selected files)
636 use external program to diff repository (or selected files)
631
637
632 Show differences between revisions for the specified files, using an
638 Show differences between revisions for the specified files, using an
633 external program. The default program used is diff, with default options
639 external program. The default program used is diff, with default options
634 "-Npru".
640 "-Npru".
635
641
636 To select a different program, use the -p/--program option. The program
642 To select a different program, use the -p/--program option. The program
637 will be passed the names of two directories to compare. To pass additional
643 will be passed the names of two directories to compare. To pass additional
638 options to the program, use -o/--option. These will be passed before the
644 options to the program, use -o/--option. These will be passed before the
639 names of the directories to compare.
645 names of the directories to compare.
640
646
641 When two revision arguments are given, then changes are shown between
647 When two revision arguments are given, then changes are shown between
642 those revisions. If only one revision is specified then that revision is
648 those revisions. If only one revision is specified then that revision is
643 compared to the working directory, and, when no revisions are specified,
649 compared to the working directory, and, when no revisions are specified,
644 the working directory files are compared to its parent.
650 the working directory files are compared to its parent.
645
651
646 (use 'hg help -e extdiff' to show help for the extdiff extension)
652 (use 'hg help -e extdiff' to show help for the extdiff extension)
647
653
648 options ([+] can be repeated):
654 options ([+] can be repeated):
649
655
650 -p --program CMD comparison program to run
656 -p --program CMD comparison program to run
651 -o --option OPT [+] pass option to comparison program
657 -o --option OPT [+] pass option to comparison program
652 -r --rev REV [+] revision
658 -r --rev REV [+] revision
653 -c --change REV change made by revision
659 -c --change REV change made by revision
654 --patch compare patches for two revisions
660 --patch compare patches for two revisions
655 -I --include PATTERN [+] include names matching the given patterns
661 -I --include PATTERN [+] include names matching the given patterns
656 -X --exclude PATTERN [+] exclude names matching the given patterns
662 -X --exclude PATTERN [+] exclude names matching the given patterns
657 -S --subrepos recurse into subrepositories
663 -S --subrepos recurse into subrepositories
658
664
659 (some details hidden, use --verbose to show complete help)
665 (some details hidden, use --verbose to show complete help)
660
666
661
667
662
668
663
669
664
670
665
671
666
672
667
673
668
674
669
675
670 $ hg help --extension extdiff
676 $ hg help --extension extdiff
671 extdiff extension - command to allow external programs to compare revisions
677 extdiff extension - command to allow external programs to compare revisions
672
678
673 The extdiff Mercurial extension allows you to use external programs to compare
679 The extdiff Mercurial extension allows you to use external programs to compare
674 revisions, or revision with working directory. The external diff programs are
680 revisions, or revision with working directory. The external diff programs are
675 called with a configurable set of options and two non-option arguments: paths
681 called with a configurable set of options and two non-option arguments: paths
676 to directories containing snapshots of files to compare.
682 to directories containing snapshots of files to compare.
677
683
678 The extdiff extension also allows you to configure new diff commands, so you
684 The extdiff extension also allows you to configure new diff commands, so you
679 do not need to type 'hg extdiff -p kdiff3' always.
685 do not need to type 'hg extdiff -p kdiff3' always.
680
686
681 [extdiff]
687 [extdiff]
682 # add new command that runs GNU diff(1) in 'context diff' mode
688 # add new command that runs GNU diff(1) in 'context diff' mode
683 cdiff = gdiff -Nprc5
689 cdiff = gdiff -Nprc5
684 ## or the old way:
690 ## or the old way:
685 #cmd.cdiff = gdiff
691 #cmd.cdiff = gdiff
686 #opts.cdiff = -Nprc5
692 #opts.cdiff = -Nprc5
687
693
688 # add new command called meld, runs meld (no need to name twice). If
694 # add new command called meld, runs meld (no need to name twice). If
689 # the meld executable is not available, the meld tool in [merge-tools]
695 # the meld executable is not available, the meld tool in [merge-tools]
690 # will be used, if available
696 # will be used, if available
691 meld =
697 meld =
692
698
693 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
699 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
694 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
700 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
695 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
701 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
696 # your .vimrc
702 # your .vimrc
697 vimdiff = gvim -f "+next" \
703 vimdiff = gvim -f "+next" \
698 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
704 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
699
705
700 Tool arguments can include variables that are expanded at runtime:
706 Tool arguments can include variables that are expanded at runtime:
701
707
702 $parent1, $plabel1 - filename, descriptive label of first parent
708 $parent1, $plabel1 - filename, descriptive label of first parent
703 $child, $clabel - filename, descriptive label of child revision
709 $child, $clabel - filename, descriptive label of child revision
704 $parent2, $plabel2 - filename, descriptive label of second parent
710 $parent2, $plabel2 - filename, descriptive label of second parent
705 $root - repository root
711 $root - repository root
706 $parent is an alias for $parent1.
712 $parent is an alias for $parent1.
707
713
708 The extdiff extension will look in your [diff-tools] and [merge-tools]
714 The extdiff extension will look in your [diff-tools] and [merge-tools]
709 sections for diff tool arguments, when none are specified in [extdiff].
715 sections for diff tool arguments, when none are specified in [extdiff].
710
716
711 [extdiff]
717 [extdiff]
712 kdiff3 =
718 kdiff3 =
713
719
714 [diff-tools]
720 [diff-tools]
715 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
721 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
716
722
717 You can use -I/-X and list of file or directory names like normal 'hg diff'
723 You can use -I/-X and list of file or directory names like normal 'hg diff'
718 command. The extdiff extension makes snapshots of only needed files, so
724 command. The extdiff extension makes snapshots of only needed files, so
719 running the external diff program will actually be pretty fast (at least
725 running the external diff program will actually be pretty fast (at least
720 faster than having to compare the entire tree).
726 faster than having to compare the entire tree).
721
727
722 list of commands:
728 list of commands:
723
729
724 extdiff use external program to diff repository (or selected files)
730 extdiff use external program to diff repository (or selected files)
725
731
726 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
732 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
727
733
728
734
729
735
730
736
731
737
732
738
733
739
734
740
735
741
736
742
737
743
738
744
739
745
740
746
741
747
742
748
743 $ echo 'extdiff = !' >> $HGRCPATH
749 $ echo 'extdiff = !' >> $HGRCPATH
744
750
745 Test help topic with same name as extension
751 Test help topic with same name as extension
746
752
747 $ cat > multirevs.py <<EOF
753 $ cat > multirevs.py <<EOF
748 > from mercurial import commands, registrar
754 > from mercurial import commands, registrar
749 > cmdtable = {}
755 > cmdtable = {}
750 > command = registrar.command(cmdtable)
756 > command = registrar.command(cmdtable)
751 > """multirevs extension
757 > """multirevs extension
752 > Big multi-line module docstring."""
758 > Big multi-line module docstring."""
753 > @command(b'multirevs', [], 'ARG', norepo=True)
759 > @command(b'multirevs', [], 'ARG', norepo=True)
754 > def multirevs(ui, repo, arg, *args, **opts):
760 > def multirevs(ui, repo, arg, *args, **opts):
755 > """multirevs command"""
761 > """multirevs command"""
756 > pass
762 > pass
757 > EOF
763 > EOF
758 $ echo "multirevs = multirevs.py" >> $HGRCPATH
764 $ echo "multirevs = multirevs.py" >> $HGRCPATH
759
765
760 $ hg help multirevs | tail
766 $ hg help multirevs | tail
761 bookmark (this works because the last revision of the revset is used):
767 bookmark (this works because the last revision of the revset is used):
762
768
763 hg update :@
769 hg update :@
764
770
765 - Show diff between tags 1.3 and 1.5 (this works because the first and the
771 - Show diff between tags 1.3 and 1.5 (this works because the first and the
766 last revisions of the revset are used):
772 last revisions of the revset are used):
767
773
768 hg diff -r 1.3::1.5
774 hg diff -r 1.3::1.5
769
775
770 use 'hg help -c multirevs' to see help for the multirevs command
776 use 'hg help -c multirevs' to see help for the multirevs command
771
777
772
778
773
779
774
780
775
781
776
782
777 $ hg help -c multirevs
783 $ hg help -c multirevs
778 hg multirevs ARG
784 hg multirevs ARG
779
785
780 multirevs command
786 multirevs command
781
787
782 (some details hidden, use --verbose to show complete help)
788 (some details hidden, use --verbose to show complete help)
783
789
784
790
785
791
786 $ hg multirevs
792 $ hg multirevs
787 hg multirevs: invalid arguments
793 hg multirevs: invalid arguments
788 hg multirevs ARG
794 hg multirevs ARG
789
795
790 multirevs command
796 multirevs command
791
797
792 (use 'hg multirevs -h' to show more help)
798 (use 'hg multirevs -h' to show more help)
793 [255]
799 [255]
794
800
795
801
796
802
797 $ echo "multirevs = !" >> $HGRCPATH
803 $ echo "multirevs = !" >> $HGRCPATH
798
804
799 Issue811: Problem loading extensions twice (by site and by user)
805 Issue811: Problem loading extensions twice (by site and by user)
800
806
801 $ cat <<EOF >> $HGRCPATH
807 $ cat <<EOF >> $HGRCPATH
802 > mq =
808 > mq =
803 > strip =
809 > strip =
804 > hgext.mq =
810 > hgext.mq =
805 > hgext/mq =
811 > hgext/mq =
806 > EOF
812 > EOF
807
813
808 Show extensions:
814 Show extensions:
809 (note that mq force load strip, also checking it's not loaded twice)
815 (note that mq force load strip, also checking it's not loaded twice)
810
816
811 $ hg debugextensions
817 $ hg debugextensions
812 mq
818 mq
813 strip
819 strip
814
820
815 For extensions, which name matches one of its commands, help
821 For extensions, which name matches one of its commands, help
816 message should ask '-v -e' to get list of built-in aliases
822 message should ask '-v -e' to get list of built-in aliases
817 along with extension help itself
823 along with extension help itself
818
824
819 $ mkdir $TESTTMP/d
825 $ mkdir $TESTTMP/d
820 $ cat > $TESTTMP/d/dodo.py <<EOF
826 $ cat > $TESTTMP/d/dodo.py <<EOF
821 > """
827 > """
822 > This is an awesome 'dodo' extension. It does nothing and
828 > This is an awesome 'dodo' extension. It does nothing and
823 > writes 'Foo foo'
829 > writes 'Foo foo'
824 > """
830 > """
825 > from mercurial import commands, registrar
831 > from mercurial import commands, registrar
826 > cmdtable = {}
832 > cmdtable = {}
827 > command = registrar.command(cmdtable)
833 > command = registrar.command(cmdtable)
828 > @command(b'dodo', [], 'hg dodo')
834 > @command(b'dodo', [], 'hg dodo')
829 > def dodo(ui, *args, **kwargs):
835 > def dodo(ui, *args, **kwargs):
830 > """Does nothing"""
836 > """Does nothing"""
831 > ui.write("I do nothing. Yay\\n")
837 > ui.write("I do nothing. Yay\\n")
832 > @command(b'foofoo', [], 'hg foofoo')
838 > @command(b'foofoo', [], 'hg foofoo')
833 > def foofoo(ui, *args, **kwargs):
839 > def foofoo(ui, *args, **kwargs):
834 > """Writes 'Foo foo'"""
840 > """Writes 'Foo foo'"""
835 > ui.write("Foo foo\\n")
841 > ui.write("Foo foo\\n")
836 > EOF
842 > EOF
837 $ dodopath=$TESTTMP/d/dodo.py
843 $ dodopath=$TESTTMP/d/dodo.py
838
844
839 $ echo "dodo = $dodopath" >> $HGRCPATH
845 $ echo "dodo = $dodopath" >> $HGRCPATH
840
846
841 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
847 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
842 $ hg help -e dodo
848 $ hg help -e dodo
843 dodo extension -
849 dodo extension -
844
850
845 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
851 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
846
852
847 list of commands:
853 list of commands:
848
854
849 dodo Does nothing
855 dodo Does nothing
850 foofoo Writes 'Foo foo'
856 foofoo Writes 'Foo foo'
851
857
852 (use 'hg help -v -e dodo' to show built-in aliases and global options)
858 (use 'hg help -v -e dodo' to show built-in aliases and global options)
853
859
854 Make sure that '-v -e' prints list of built-in aliases along with
860 Make sure that '-v -e' prints list of built-in aliases along with
855 extension help itself
861 extension help itself
856 $ hg help -v -e dodo
862 $ hg help -v -e dodo
857 dodo extension -
863 dodo extension -
858
864
859 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
865 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
860
866
861 list of commands:
867 list of commands:
862
868
863 dodo Does nothing
869 dodo Does nothing
864 foofoo Writes 'Foo foo'
870 foofoo Writes 'Foo foo'
865
871
866 global options ([+] can be repeated):
872 global options ([+] can be repeated):
867
873
868 -R --repository REPO repository root directory or name of overlay bundle
874 -R --repository REPO repository root directory or name of overlay bundle
869 file
875 file
870 --cwd DIR change working directory
876 --cwd DIR change working directory
871 -y --noninteractive do not prompt, automatically pick the first choice for
877 -y --noninteractive do not prompt, automatically pick the first choice for
872 all prompts
878 all prompts
873 -q --quiet suppress output
879 -q --quiet suppress output
874 -v --verbose enable additional output
880 -v --verbose enable additional output
875 --color TYPE when to colorize (boolean, always, auto, never, or
881 --color TYPE when to colorize (boolean, always, auto, never, or
876 debug)
882 debug)
877 --config CONFIG [+] set/override config option (use 'section.name=value')
883 --config CONFIG [+] set/override config option (use 'section.name=value')
878 --debug enable debugging output
884 --debug enable debugging output
879 --debugger start debugger
885 --debugger start debugger
880 --encoding ENCODE set the charset encoding (default: ascii)
886 --encoding ENCODE set the charset encoding (default: ascii)
881 --encodingmode MODE set the charset encoding mode (default: strict)
887 --encodingmode MODE set the charset encoding mode (default: strict)
882 --traceback always print a traceback on exception
888 --traceback always print a traceback on exception
883 --time time how long the command takes
889 --time time how long the command takes
884 --profile print command execution profile
890 --profile print command execution profile
885 --version output version information and exit
891 --version output version information and exit
886 -h --help display help and exit
892 -h --help display help and exit
887 --hidden consider hidden changesets
893 --hidden consider hidden changesets
888 --pager TYPE when to paginate (boolean, always, auto, or never)
894 --pager TYPE when to paginate (boolean, always, auto, or never)
889 (default: auto)
895 (default: auto)
890
896
891 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
897 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
892 $ hg help -v dodo
898 $ hg help -v dodo
893 hg dodo
899 hg dodo
894
900
895 Does nothing
901 Does nothing
896
902
897 (use 'hg help -e dodo' to show help for the dodo extension)
903 (use 'hg help -e dodo' to show help for the dodo extension)
898
904
899 options:
905 options:
900
906
901 --mq operate on patch repository
907 --mq operate on patch repository
902
908
903 global options ([+] can be repeated):
909 global options ([+] can be repeated):
904
910
905 -R --repository REPO repository root directory or name of overlay bundle
911 -R --repository REPO repository root directory or name of overlay bundle
906 file
912 file
907 --cwd DIR change working directory
913 --cwd DIR change working directory
908 -y --noninteractive do not prompt, automatically pick the first choice for
914 -y --noninteractive do not prompt, automatically pick the first choice for
909 all prompts
915 all prompts
910 -q --quiet suppress output
916 -q --quiet suppress output
911 -v --verbose enable additional output
917 -v --verbose enable additional output
912 --color TYPE when to colorize (boolean, always, auto, never, or
918 --color TYPE when to colorize (boolean, always, auto, never, or
913 debug)
919 debug)
914 --config CONFIG [+] set/override config option (use 'section.name=value')
920 --config CONFIG [+] set/override config option (use 'section.name=value')
915 --debug enable debugging output
921 --debug enable debugging output
916 --debugger start debugger
922 --debugger start debugger
917 --encoding ENCODE set the charset encoding (default: ascii)
923 --encoding ENCODE set the charset encoding (default: ascii)
918 --encodingmode MODE set the charset encoding mode (default: strict)
924 --encodingmode MODE set the charset encoding mode (default: strict)
919 --traceback always print a traceback on exception
925 --traceback always print a traceback on exception
920 --time time how long the command takes
926 --time time how long the command takes
921 --profile print command execution profile
927 --profile print command execution profile
922 --version output version information and exit
928 --version output version information and exit
923 -h --help display help and exit
929 -h --help display help and exit
924 --hidden consider hidden changesets
930 --hidden consider hidden changesets
925 --pager TYPE when to paginate (boolean, always, auto, or never)
931 --pager TYPE when to paginate (boolean, always, auto, or never)
926 (default: auto)
932 (default: auto)
927
933
928 In case when extension name doesn't match any of its commands,
934 In case when extension name doesn't match any of its commands,
929 help message should ask for '-v' to get list of built-in aliases
935 help message should ask for '-v' to get list of built-in aliases
930 along with extension help
936 along with extension help
931 $ cat > $TESTTMP/d/dudu.py <<EOF
937 $ cat > $TESTTMP/d/dudu.py <<EOF
932 > """
938 > """
933 > This is an awesome 'dudu' extension. It does something and
939 > This is an awesome 'dudu' extension. It does something and
934 > also writes 'Beep beep'
940 > also writes 'Beep beep'
935 > """
941 > """
936 > from mercurial import commands, registrar
942 > from mercurial import commands, registrar
937 > cmdtable = {}
943 > cmdtable = {}
938 > command = registrar.command(cmdtable)
944 > command = registrar.command(cmdtable)
939 > @command(b'something', [], 'hg something')
945 > @command(b'something', [], 'hg something')
940 > def something(ui, *args, **kwargs):
946 > def something(ui, *args, **kwargs):
941 > """Does something"""
947 > """Does something"""
942 > ui.write("I do something. Yaaay\\n")
948 > ui.write("I do something. Yaaay\\n")
943 > @command(b'beep', [], 'hg beep')
949 > @command(b'beep', [], 'hg beep')
944 > def beep(ui, *args, **kwargs):
950 > def beep(ui, *args, **kwargs):
945 > """Writes 'Beep beep'"""
951 > """Writes 'Beep beep'"""
946 > ui.write("Beep beep\\n")
952 > ui.write("Beep beep\\n")
947 > EOF
953 > EOF
948 $ dudupath=$TESTTMP/d/dudu.py
954 $ dudupath=$TESTTMP/d/dudu.py
949
955
950 $ echo "dudu = $dudupath" >> $HGRCPATH
956 $ echo "dudu = $dudupath" >> $HGRCPATH
951
957
952 $ hg help -e dudu
958 $ hg help -e dudu
953 dudu extension -
959 dudu extension -
954
960
955 This is an awesome 'dudu' extension. It does something and also writes 'Beep
961 This is an awesome 'dudu' extension. It does something and also writes 'Beep
956 beep'
962 beep'
957
963
958 list of commands:
964 list of commands:
959
965
960 beep Writes 'Beep beep'
966 beep Writes 'Beep beep'
961 something Does something
967 something Does something
962
968
963 (use 'hg help -v dudu' to show built-in aliases and global options)
969 (use 'hg help -v dudu' to show built-in aliases and global options)
964
970
965 In case when extension name doesn't match any of its commands,
971 In case when extension name doesn't match any of its commands,
966 help options '-v' and '-v -e' should be equivalent
972 help options '-v' and '-v -e' should be equivalent
967 $ hg help -v dudu
973 $ hg help -v dudu
968 dudu extension -
974 dudu extension -
969
975
970 This is an awesome 'dudu' extension. It does something and also writes 'Beep
976 This is an awesome 'dudu' extension. It does something and also writes 'Beep
971 beep'
977 beep'
972
978
973 list of commands:
979 list of commands:
974
980
975 beep Writes 'Beep beep'
981 beep Writes 'Beep beep'
976 something Does something
982 something Does something
977
983
978 global options ([+] can be repeated):
984 global options ([+] can be repeated):
979
985
980 -R --repository REPO repository root directory or name of overlay bundle
986 -R --repository REPO repository root directory or name of overlay bundle
981 file
987 file
982 --cwd DIR change working directory
988 --cwd DIR change working directory
983 -y --noninteractive do not prompt, automatically pick the first choice for
989 -y --noninteractive do not prompt, automatically pick the first choice for
984 all prompts
990 all prompts
985 -q --quiet suppress output
991 -q --quiet suppress output
986 -v --verbose enable additional output
992 -v --verbose enable additional output
987 --color TYPE when to colorize (boolean, always, auto, never, or
993 --color TYPE when to colorize (boolean, always, auto, never, or
988 debug)
994 debug)
989 --config CONFIG [+] set/override config option (use 'section.name=value')
995 --config CONFIG [+] set/override config option (use 'section.name=value')
990 --debug enable debugging output
996 --debug enable debugging output
991 --debugger start debugger
997 --debugger start debugger
992 --encoding ENCODE set the charset encoding (default: ascii)
998 --encoding ENCODE set the charset encoding (default: ascii)
993 --encodingmode MODE set the charset encoding mode (default: strict)
999 --encodingmode MODE set the charset encoding mode (default: strict)
994 --traceback always print a traceback on exception
1000 --traceback always print a traceback on exception
995 --time time how long the command takes
1001 --time time how long the command takes
996 --profile print command execution profile
1002 --profile print command execution profile
997 --version output version information and exit
1003 --version output version information and exit
998 -h --help display help and exit
1004 -h --help display help and exit
999 --hidden consider hidden changesets
1005 --hidden consider hidden changesets
1000 --pager TYPE when to paginate (boolean, always, auto, or never)
1006 --pager TYPE when to paginate (boolean, always, auto, or never)
1001 (default: auto)
1007 (default: auto)
1002
1008
1003 $ hg help -v -e dudu
1009 $ hg help -v -e dudu
1004 dudu extension -
1010 dudu extension -
1005
1011
1006 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1012 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1007 beep'
1013 beep'
1008
1014
1009 list of commands:
1015 list of commands:
1010
1016
1011 beep Writes 'Beep beep'
1017 beep Writes 'Beep beep'
1012 something Does something
1018 something Does something
1013
1019
1014 global options ([+] can be repeated):
1020 global options ([+] can be repeated):
1015
1021
1016 -R --repository REPO repository root directory or name of overlay bundle
1022 -R --repository REPO repository root directory or name of overlay bundle
1017 file
1023 file
1018 --cwd DIR change working directory
1024 --cwd DIR change working directory
1019 -y --noninteractive do not prompt, automatically pick the first choice for
1025 -y --noninteractive do not prompt, automatically pick the first choice for
1020 all prompts
1026 all prompts
1021 -q --quiet suppress output
1027 -q --quiet suppress output
1022 -v --verbose enable additional output
1028 -v --verbose enable additional output
1023 --color TYPE when to colorize (boolean, always, auto, never, or
1029 --color TYPE when to colorize (boolean, always, auto, never, or
1024 debug)
1030 debug)
1025 --config CONFIG [+] set/override config option (use 'section.name=value')
1031 --config CONFIG [+] set/override config option (use 'section.name=value')
1026 --debug enable debugging output
1032 --debug enable debugging output
1027 --debugger start debugger
1033 --debugger start debugger
1028 --encoding ENCODE set the charset encoding (default: ascii)
1034 --encoding ENCODE set the charset encoding (default: ascii)
1029 --encodingmode MODE set the charset encoding mode (default: strict)
1035 --encodingmode MODE set the charset encoding mode (default: strict)
1030 --traceback always print a traceback on exception
1036 --traceback always print a traceback on exception
1031 --time time how long the command takes
1037 --time time how long the command takes
1032 --profile print command execution profile
1038 --profile print command execution profile
1033 --version output version information and exit
1039 --version output version information and exit
1034 -h --help display help and exit
1040 -h --help display help and exit
1035 --hidden consider hidden changesets
1041 --hidden consider hidden changesets
1036 --pager TYPE when to paginate (boolean, always, auto, or never)
1042 --pager TYPE when to paginate (boolean, always, auto, or never)
1037 (default: auto)
1043 (default: auto)
1038
1044
1039 Disabled extension commands:
1045 Disabled extension commands:
1040
1046
1041 $ ORGHGRCPATH=$HGRCPATH
1047 $ ORGHGRCPATH=$HGRCPATH
1042 $ HGRCPATH=
1048 $ HGRCPATH=
1043 $ export HGRCPATH
1049 $ export HGRCPATH
1044 $ hg help email
1050 $ hg help email
1045 'email' is provided by the following extension:
1051 'email' is provided by the following extension:
1046
1052
1047 patchbomb command to send changesets as (a series of) patch emails
1053 patchbomb command to send changesets as (a series of) patch emails
1048
1054
1049 (use 'hg help extensions' for information on enabling extensions)
1055 (use 'hg help extensions' for information on enabling extensions)
1050
1056
1051
1057
1052 $ hg qdel
1058 $ hg qdel
1053 hg: unknown command 'qdel'
1059 hg: unknown command 'qdel'
1054 'qdelete' is provided by the following extension:
1060 'qdelete' is provided by the following extension:
1055
1061
1056 mq manage a stack of patches
1062 mq manage a stack of patches
1057
1063
1058 (use 'hg help extensions' for information on enabling extensions)
1064 (use 'hg help extensions' for information on enabling extensions)
1059 [255]
1065 [255]
1060
1066
1061
1067
1062 $ hg churn
1068 $ hg churn
1063 hg: unknown command 'churn'
1069 hg: unknown command 'churn'
1064 'churn' is provided by the following extension:
1070 'churn' is provided by the following extension:
1065
1071
1066 churn command to display statistics about repository history
1072 churn command to display statistics about repository history
1067
1073
1068 (use 'hg help extensions' for information on enabling extensions)
1074 (use 'hg help extensions' for information on enabling extensions)
1069 [255]
1075 [255]
1070
1076
1071
1077
1072
1078
1073 Disabled extensions:
1079 Disabled extensions:
1074
1080
1075 $ hg help churn
1081 $ hg help churn
1076 churn extension - command to display statistics about repository history
1082 churn extension - command to display statistics about repository history
1077
1083
1078 (use 'hg help extensions' for information on enabling extensions)
1084 (use 'hg help extensions' for information on enabling extensions)
1079
1085
1080 $ hg help patchbomb
1086 $ hg help patchbomb
1081 patchbomb extension - command to send changesets as (a series of) patch emails
1087 patchbomb extension - command to send changesets as (a series of) patch emails
1082
1088
1083 The series is started off with a "[PATCH 0 of N]" introduction, which
1089 The series is started off with a "[PATCH 0 of N]" introduction, which
1084 describes the series as a whole.
1090 describes the series as a whole.
1085
1091
1086 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1092 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1087 line of the changeset description as the subject text. The message contains
1093 line of the changeset description as the subject text. The message contains
1088 two or three body parts:
1094 two or three body parts:
1089
1095
1090 - The changeset description.
1096 - The changeset description.
1091 - [Optional] The result of running diffstat on the patch.
1097 - [Optional] The result of running diffstat on the patch.
1092 - The patch itself, as generated by 'hg export'.
1098 - The patch itself, as generated by 'hg export'.
1093
1099
1094 Each message refers to the first in the series using the In-Reply-To and
1100 Each message refers to the first in the series using the In-Reply-To and
1095 References headers, so they will show up as a sequence in threaded mail and
1101 References headers, so they will show up as a sequence in threaded mail and
1096 news readers, and in mail archives.
1102 news readers, and in mail archives.
1097
1103
1098 To configure other defaults, add a section like this to your configuration
1104 To configure other defaults, add a section like this to your configuration
1099 file:
1105 file:
1100
1106
1101 [email]
1107 [email]
1102 from = My Name <my@email>
1108 from = My Name <my@email>
1103 to = recipient1, recipient2, ...
1109 to = recipient1, recipient2, ...
1104 cc = cc1, cc2, ...
1110 cc = cc1, cc2, ...
1105 bcc = bcc1, bcc2, ...
1111 bcc = bcc1, bcc2, ...
1106 reply-to = address1, address2, ...
1112 reply-to = address1, address2, ...
1107
1113
1108 Use "[patchbomb]" as configuration section name if you need to override global
1114 Use "[patchbomb]" as configuration section name if you need to override global
1109 "[email]" address settings.
1115 "[email]" address settings.
1110
1116
1111 Then you can use the 'hg email' command to mail a series of changesets as a
1117 Then you can use the 'hg email' command to mail a series of changesets as a
1112 patchbomb.
1118 patchbomb.
1113
1119
1114 You can also either configure the method option in the email section to be a
1120 You can also either configure the method option in the email section to be a
1115 sendmail compatible mailer or fill out the [smtp] section so that the
1121 sendmail compatible mailer or fill out the [smtp] section so that the
1116 patchbomb extension can automatically send patchbombs directly from the
1122 patchbomb extension can automatically send patchbombs directly from the
1117 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1123 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1118
1124
1119 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1125 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1120 supply one via configuration or the command line. You can override this to
1126 supply one via configuration or the command line. You can override this to
1121 never prompt by configuring an empty value:
1127 never prompt by configuring an empty value:
1122
1128
1123 [email]
1129 [email]
1124 cc =
1130 cc =
1125
1131
1126 You can control the default inclusion of an introduction message with the
1132 You can control the default inclusion of an introduction message with the
1127 "patchbomb.intro" configuration option. The configuration is always
1133 "patchbomb.intro" configuration option. The configuration is always
1128 overwritten by command line flags like --intro and --desc:
1134 overwritten by command line flags like --intro and --desc:
1129
1135
1130 [patchbomb]
1136 [patchbomb]
1131 intro=auto # include introduction message if more than 1 patch (default)
1137 intro=auto # include introduction message if more than 1 patch (default)
1132 intro=never # never include an introduction message
1138 intro=never # never include an introduction message
1133 intro=always # always include an introduction message
1139 intro=always # always include an introduction message
1134
1140
1135 You can specify a template for flags to be added in subject prefixes. Flags
1141 You can specify a template for flags to be added in subject prefixes. Flags
1136 specified by --flag option are exported as "{flags}" keyword:
1142 specified by --flag option are exported as "{flags}" keyword:
1137
1143
1138 [patchbomb]
1144 [patchbomb]
1139 flagtemplate = "{separate(' ',
1145 flagtemplate = "{separate(' ',
1140 ifeq(branch, 'default', '', branch|upper),
1146 ifeq(branch, 'default', '', branch|upper),
1141 flags)}"
1147 flags)}"
1142
1148
1143 You can set patchbomb to always ask for confirmation by setting
1149 You can set patchbomb to always ask for confirmation by setting
1144 "patchbomb.confirm" to true.
1150 "patchbomb.confirm" to true.
1145
1151
1146 (use 'hg help extensions' for information on enabling extensions)
1152 (use 'hg help extensions' for information on enabling extensions)
1147
1153
1148
1154
1149 Broken disabled extension and command:
1155 Broken disabled extension and command:
1150
1156
1151 $ mkdir hgext
1157 $ mkdir hgext
1152 $ echo > hgext/__init__.py
1158 $ echo > hgext/__init__.py
1153 $ cat > hgext/broken.py <<EOF
1159 $ cat > hgext/broken.py <<EOF
1154 > "broken extension'
1160 > "broken extension'
1155 > EOF
1161 > EOF
1156 $ cat > path.py <<EOF
1162 $ cat > path.py <<EOF
1157 > import os, sys
1163 > import os, sys
1158 > sys.path.insert(0, os.environ['HGEXTPATH'])
1164 > sys.path.insert(0, os.environ['HGEXTPATH'])
1159 > EOF
1165 > EOF
1160 $ HGEXTPATH=`pwd`
1166 $ HGEXTPATH=`pwd`
1161 $ export HGEXTPATH
1167 $ export HGEXTPATH
1162
1168
1163 $ hg --config extensions.path=./path.py help broken
1169 $ hg --config extensions.path=./path.py help broken
1164 broken extension - (no help text available)
1170 broken extension - (no help text available)
1165
1171
1166 (use 'hg help extensions' for information on enabling extensions)
1172 (use 'hg help extensions' for information on enabling extensions)
1167
1173
1168
1174
1169 $ cat > hgext/forest.py <<EOF
1175 $ cat > hgext/forest.py <<EOF
1170 > cmdtable = None
1176 > cmdtable = None
1171 > EOF
1177 > EOF
1172 $ hg --config extensions.path=./path.py help foo > /dev/null
1178 $ hg --config extensions.path=./path.py help foo > /dev/null
1173 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1179 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1174 abort: no such help topic: foo
1180 abort: no such help topic: foo
1175 (try 'hg help --keyword foo')
1181 (try 'hg help --keyword foo')
1176 [255]
1182 [255]
1177
1183
1178 $ cat > throw.py <<EOF
1184 $ cat > throw.py <<EOF
1179 > from mercurial import commands, registrar, util
1185 > from mercurial import commands, registrar, util
1180 > cmdtable = {}
1186 > cmdtable = {}
1181 > command = registrar.command(cmdtable)
1187 > command = registrar.command(cmdtable)
1182 > class Bogon(Exception): pass
1188 > class Bogon(Exception): pass
1183 > @command(b'throw', [], 'hg throw', norepo=True)
1189 > @command(b'throw', [], 'hg throw', norepo=True)
1184 > def throw(ui, **opts):
1190 > def throw(ui, **opts):
1185 > """throws an exception"""
1191 > """throws an exception"""
1186 > raise Bogon()
1192 > raise Bogon()
1187 > EOF
1193 > EOF
1188
1194
1189 No declared supported version, extension complains:
1195 No declared supported version, extension complains:
1190 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1196 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1191 ** Unknown exception encountered with possibly-broken third-party extension throw
1197 ** Unknown exception encountered with possibly-broken third-party extension throw
1192 ** which supports versions unknown of Mercurial.
1198 ** which supports versions unknown of Mercurial.
1193 ** Please disable throw and try your action again.
1199 ** Please disable throw and try your action again.
1194 ** If that fixes the bug please report it to the extension author.
1200 ** If that fixes the bug please report it to the extension author.
1195 ** Python * (glob)
1201 ** Python * (glob)
1196 ** Mercurial Distributed SCM * (glob)
1202 ** Mercurial Distributed SCM * (glob)
1197 ** Extensions loaded: throw
1203 ** Extensions loaded: throw
1198
1204
1199 empty declaration of supported version, extension complains:
1205 empty declaration of supported version, extension complains:
1200 $ echo "testedwith = ''" >> throw.py
1206 $ echo "testedwith = ''" >> throw.py
1201 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1207 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1202 ** Unknown exception encountered with possibly-broken third-party extension throw
1208 ** Unknown exception encountered with possibly-broken third-party extension throw
1203 ** which supports versions unknown of Mercurial.
1209 ** which supports versions unknown of Mercurial.
1204 ** Please disable throw and try your action again.
1210 ** Please disable throw and try your action again.
1205 ** If that fixes the bug please report it to the extension author.
1211 ** If that fixes the bug please report it to the extension author.
1206 ** Python * (glob)
1212 ** Python * (glob)
1207 ** Mercurial Distributed SCM (*) (glob)
1213 ** Mercurial Distributed SCM (*) (glob)
1208 ** Extensions loaded: throw
1214 ** Extensions loaded: throw
1209
1215
1210 If the extension specifies a buglink, show that:
1216 If the extension specifies a buglink, show that:
1211 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1217 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1212 $ rm -f throw.pyc throw.pyo
1218 $ rm -f throw.pyc throw.pyo
1213 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1219 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1214 ** Unknown exception encountered with possibly-broken third-party extension throw
1220 ** Unknown exception encountered with possibly-broken third-party extension throw
1215 ** which supports versions unknown of Mercurial.
1221 ** which supports versions unknown of Mercurial.
1216 ** Please disable throw and try your action again.
1222 ** Please disable throw and try your action again.
1217 ** If that fixes the bug please report it to http://example.com/bts
1223 ** If that fixes the bug please report it to http://example.com/bts
1218 ** Python * (glob)
1224 ** Python * (glob)
1219 ** Mercurial Distributed SCM (*) (glob)
1225 ** Mercurial Distributed SCM (*) (glob)
1220 ** Extensions loaded: throw
1226 ** Extensions loaded: throw
1221
1227
1222 If the extensions declare outdated versions, accuse the older extension first:
1228 If the extensions declare outdated versions, accuse the older extension first:
1223 $ echo "from mercurial import util" >> older.py
1229 $ echo "from mercurial import util" >> older.py
1224 $ echo "util.version = lambda:'2.2'" >> older.py
1230 $ echo "util.version = lambda:'2.2'" >> older.py
1225 $ echo "testedwith = '1.9.3'" >> older.py
1231 $ echo "testedwith = '1.9.3'" >> older.py
1226 $ echo "testedwith = '2.1.1'" >> throw.py
1232 $ echo "testedwith = '2.1.1'" >> throw.py
1227 $ rm -f throw.pyc throw.pyo
1233 $ rm -f throw.pyc throw.pyo
1228 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1234 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1229 > throw 2>&1 | egrep '^\*\*'
1235 > throw 2>&1 | egrep '^\*\*'
1230 ** Unknown exception encountered with possibly-broken third-party extension older
1236 ** Unknown exception encountered with possibly-broken third-party extension older
1231 ** which supports versions 1.9 of Mercurial.
1237 ** which supports versions 1.9 of Mercurial.
1232 ** Please disable older and try your action again.
1238 ** Please disable older and try your action again.
1233 ** If that fixes the bug please report it to the extension author.
1239 ** If that fixes the bug please report it to the extension author.
1234 ** Python * (glob)
1240 ** Python * (glob)
1235 ** Mercurial Distributed SCM (version 2.2)
1241 ** Mercurial Distributed SCM (version 2.2)
1236 ** Extensions loaded: throw, older
1242 ** Extensions loaded: throw, older
1237
1243
1238 One extension only tested with older, one only with newer versions:
1244 One extension only tested with older, one only with newer versions:
1239 $ echo "util.version = lambda:'2.1'" >> older.py
1245 $ echo "util.version = lambda:'2.1'" >> older.py
1240 $ rm -f older.pyc older.pyo
1246 $ rm -f older.pyc older.pyo
1241 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1247 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1242 > throw 2>&1 | egrep '^\*\*'
1248 > throw 2>&1 | egrep '^\*\*'
1243 ** Unknown exception encountered with possibly-broken third-party extension older
1249 ** Unknown exception encountered with possibly-broken third-party extension older
1244 ** which supports versions 1.9 of Mercurial.
1250 ** which supports versions 1.9 of Mercurial.
1245 ** Please disable older and try your action again.
1251 ** Please disable older and try your action again.
1246 ** If that fixes the bug please report it to the extension author.
1252 ** If that fixes the bug please report it to the extension author.
1247 ** Python * (glob)
1253 ** Python * (glob)
1248 ** Mercurial Distributed SCM (version 2.1)
1254 ** Mercurial Distributed SCM (version 2.1)
1249 ** Extensions loaded: throw, older
1255 ** Extensions loaded: throw, older
1250
1256
1251 Older extension is tested with current version, the other only with newer:
1257 Older extension is tested with current version, the other only with newer:
1252 $ echo "util.version = lambda:'1.9.3'" >> older.py
1258 $ echo "util.version = lambda:'1.9.3'" >> older.py
1253 $ rm -f older.pyc older.pyo
1259 $ rm -f older.pyc older.pyo
1254 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1260 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1255 > throw 2>&1 | egrep '^\*\*'
1261 > throw 2>&1 | egrep '^\*\*'
1256 ** Unknown exception encountered with possibly-broken third-party extension throw
1262 ** Unknown exception encountered with possibly-broken third-party extension throw
1257 ** which supports versions 2.1 of Mercurial.
1263 ** which supports versions 2.1 of Mercurial.
1258 ** Please disable throw and try your action again.
1264 ** Please disable throw and try your action again.
1259 ** If that fixes the bug please report it to http://example.com/bts
1265 ** If that fixes the bug please report it to http://example.com/bts
1260 ** Python * (glob)
1266 ** Python * (glob)
1261 ** Mercurial Distributed SCM (version 1.9.3)
1267 ** Mercurial Distributed SCM (version 1.9.3)
1262 ** Extensions loaded: throw, older
1268 ** Extensions loaded: throw, older
1263
1269
1264 Ability to point to a different point
1270 Ability to point to a different point
1265 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1271 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1266 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1272 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1267 ** unknown exception encountered, please report by visiting
1273 ** unknown exception encountered, please report by visiting
1268 ** Your Local Goat Lenders
1274 ** Your Local Goat Lenders
1269 ** Python * (glob)
1275 ** Python * (glob)
1270 ** Mercurial Distributed SCM (*) (glob)
1276 ** Mercurial Distributed SCM (*) (glob)
1271 ** Extensions loaded: throw, older
1277 ** Extensions loaded: throw, older
1272
1278
1273 Declare the version as supporting this hg version, show regular bts link:
1279 Declare the version as supporting this hg version, show regular bts link:
1274 $ hgver=`hg debuginstall -T '{hgver}'`
1280 $ hgver=`hg debuginstall -T '{hgver}'`
1275 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1281 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1276 $ if [ -z "$hgver" ]; then
1282 $ if [ -z "$hgver" ]; then
1277 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1283 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1278 > fi
1284 > fi
1279 $ rm -f throw.pyc throw.pyo
1285 $ rm -f throw.pyc throw.pyo
1280 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1286 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1281 ** unknown exception encountered, please report by visiting
1287 ** unknown exception encountered, please report by visiting
1282 ** https://mercurial-scm.org/wiki/BugTracker
1288 ** https://mercurial-scm.org/wiki/BugTracker
1283 ** Python * (glob)
1289 ** Python * (glob)
1284 ** Mercurial Distributed SCM (*) (glob)
1290 ** Mercurial Distributed SCM (*) (glob)
1285 ** Extensions loaded: throw
1291 ** Extensions loaded: throw
1286
1292
1287 Patch version is ignored during compatibility check
1293 Patch version is ignored during compatibility check
1288 $ echo "testedwith = '3.2'" >> throw.py
1294 $ echo "testedwith = '3.2'" >> throw.py
1289 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1295 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1290 $ rm -f throw.pyc throw.pyo
1296 $ rm -f throw.pyc throw.pyo
1291 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1297 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1292 ** unknown exception encountered, please report by visiting
1298 ** unknown exception encountered, please report by visiting
1293 ** https://mercurial-scm.org/wiki/BugTracker
1299 ** https://mercurial-scm.org/wiki/BugTracker
1294 ** Python * (glob)
1300 ** Python * (glob)
1295 ** Mercurial Distributed SCM (*) (glob)
1301 ** Mercurial Distributed SCM (*) (glob)
1296 ** Extensions loaded: throw
1302 ** Extensions loaded: throw
1297
1303
1298 Test version number support in 'hg version':
1304 Test version number support in 'hg version':
1299 $ echo '__version__ = (1, 2, 3)' >> throw.py
1305 $ echo '__version__ = (1, 2, 3)' >> throw.py
1300 $ rm -f throw.pyc throw.pyo
1306 $ rm -f throw.pyc throw.pyo
1301 $ hg version -v
1307 $ hg version -v
1302 Mercurial Distributed SCM (version *) (glob)
1308 Mercurial Distributed SCM (version *) (glob)
1303 (see https://mercurial-scm.org for more information)
1309 (see https://mercurial-scm.org for more information)
1304
1310
1305 Copyright (C) 2005-* Matt Mackall and others (glob)
1311 Copyright (C) 2005-* Matt Mackall and others (glob)
1306 This is free software; see the source for copying conditions. There is NO
1312 This is free software; see the source for copying conditions. There is NO
1307 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1313 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1308
1314
1309 Enabled extensions:
1315 Enabled extensions:
1310
1316
1311
1317
1312 $ hg version -v --config extensions.throw=throw.py
1318 $ hg version -v --config extensions.throw=throw.py
1313 Mercurial Distributed SCM (version *) (glob)
1319 Mercurial Distributed SCM (version *) (glob)
1314 (see https://mercurial-scm.org for more information)
1320 (see https://mercurial-scm.org for more information)
1315
1321
1316 Copyright (C) 2005-* Matt Mackall and others (glob)
1322 Copyright (C) 2005-* Matt Mackall and others (glob)
1317 This is free software; see the source for copying conditions. There is NO
1323 This is free software; see the source for copying conditions. There is NO
1318 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1324 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1319
1325
1320 Enabled extensions:
1326 Enabled extensions:
1321
1327
1322 throw external 1.2.3
1328 throw external 1.2.3
1323 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1329 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1324 $ rm -f throw.pyc throw.pyo
1330 $ rm -f throw.pyc throw.pyo
1325 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1331 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1326 Mercurial Distributed SCM (version *) (glob)
1332 Mercurial Distributed SCM (version *) (glob)
1327 (see https://mercurial-scm.org for more information)
1333 (see https://mercurial-scm.org for more information)
1328
1334
1329 Copyright (C) 2005-* Matt Mackall and others (glob)
1335 Copyright (C) 2005-* Matt Mackall and others (glob)
1330 This is free software; see the source for copying conditions. There is NO
1336 This is free software; see the source for copying conditions. There is NO
1331 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1337 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1332
1338
1333 Enabled extensions:
1339 Enabled extensions:
1334
1340
1335 throw external 1.twentythree
1341 throw external 1.twentythree
1336 strip internal
1342 strip internal
1337
1343
1338 $ hg version -q --config extensions.throw=throw.py
1344 $ hg version -q --config extensions.throw=throw.py
1339 Mercurial Distributed SCM (version *) (glob)
1345 Mercurial Distributed SCM (version *) (glob)
1340
1346
1341 Test JSON output of version:
1347 Test JSON output of version:
1342
1348
1343 $ hg version -Tjson
1349 $ hg version -Tjson
1344 [
1350 [
1345 {
1351 {
1346 "extensions": [],
1352 "extensions": [],
1347 "ver": "*" (glob)
1353 "ver": "*" (glob)
1348 }
1354 }
1349 ]
1355 ]
1350
1356
1351 $ hg version --config extensions.throw=throw.py -Tjson
1357 $ hg version --config extensions.throw=throw.py -Tjson
1352 [
1358 [
1353 {
1359 {
1354 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1360 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1355 "ver": "3.2.2"
1361 "ver": "3.2.2"
1356 }
1362 }
1357 ]
1363 ]
1358
1364
1359 $ hg version --config extensions.strip= -Tjson
1365 $ hg version --config extensions.strip= -Tjson
1360 [
1366 [
1361 {
1367 {
1362 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1368 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1363 "ver": "*" (glob)
1369 "ver": "*" (glob)
1364 }
1370 }
1365 ]
1371 ]
1366
1372
1367 Test template output of version:
1373 Test template output of version:
1368
1374
1369 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1375 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1370 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1376 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1371 throw 1.twentythree (external)
1377 throw 1.twentythree (external)
1372 strip (internal)
1378 strip (internal)
1373
1379
1374 Refuse to load extensions with minimum version requirements
1380 Refuse to load extensions with minimum version requirements
1375
1381
1376 $ cat > minversion1.py << EOF
1382 $ cat > minversion1.py << EOF
1377 > from mercurial import util
1383 > from mercurial import util
1378 > util.version = lambda: '3.5.2'
1384 > util.version = lambda: '3.5.2'
1379 > minimumhgversion = '3.6'
1385 > minimumhgversion = '3.6'
1380 > EOF
1386 > EOF
1381 $ hg --config extensions.minversion=minversion1.py version
1387 $ hg --config extensions.minversion=minversion1.py version
1382 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1388 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1383 Mercurial Distributed SCM (version 3.5.2)
1389 Mercurial Distributed SCM (version 3.5.2)
1384 (see https://mercurial-scm.org for more information)
1390 (see https://mercurial-scm.org for more information)
1385
1391
1386 Copyright (C) 2005-* Matt Mackall and others (glob)
1392 Copyright (C) 2005-* Matt Mackall and others (glob)
1387 This is free software; see the source for copying conditions. There is NO
1393 This is free software; see the source for copying conditions. There is NO
1388 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1394 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1389
1395
1390 $ cat > minversion2.py << EOF
1396 $ cat > minversion2.py << EOF
1391 > from mercurial import util
1397 > from mercurial import util
1392 > util.version = lambda: '3.6'
1398 > util.version = lambda: '3.6'
1393 > minimumhgversion = '3.7'
1399 > minimumhgversion = '3.7'
1394 > EOF
1400 > EOF
1395 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1401 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1396 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1402 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1397
1403
1398 Can load version that is only off by point release
1404 Can load version that is only off by point release
1399
1405
1400 $ cat > minversion2.py << EOF
1406 $ cat > minversion2.py << EOF
1401 > from mercurial import util
1407 > from mercurial import util
1402 > util.version = lambda: '3.6.1'
1408 > util.version = lambda: '3.6.1'
1403 > minimumhgversion = '3.6'
1409 > minimumhgversion = '3.6'
1404 > EOF
1410 > EOF
1405 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1411 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1406 [1]
1412 [1]
1407
1413
1408 Can load minimum version identical to current
1414 Can load minimum version identical to current
1409
1415
1410 $ cat > minversion3.py << EOF
1416 $ cat > minversion3.py << EOF
1411 > from mercurial import util
1417 > from mercurial import util
1412 > util.version = lambda: '3.5'
1418 > util.version = lambda: '3.5'
1413 > minimumhgversion = '3.5'
1419 > minimumhgversion = '3.5'
1414 > EOF
1420 > EOF
1415 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1421 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1416 [1]
1422 [1]
1417
1423
1418 Restore HGRCPATH
1424 Restore HGRCPATH
1419
1425
1420 $ HGRCPATH=$ORGHGRCPATH
1426 $ HGRCPATH=$ORGHGRCPATH
1421 $ export HGRCPATH
1427 $ export HGRCPATH
1422
1428
1423 Commands handling multiple repositories at a time should invoke only
1429 Commands handling multiple repositories at a time should invoke only
1424 "reposetup()" of extensions enabling in the target repository.
1430 "reposetup()" of extensions enabling in the target repository.
1425
1431
1426 $ mkdir reposetup-test
1432 $ mkdir reposetup-test
1427 $ cd reposetup-test
1433 $ cd reposetup-test
1428
1434
1429 $ cat > $TESTTMP/reposetuptest.py <<EOF
1435 $ cat > $TESTTMP/reposetuptest.py <<EOF
1430 > from mercurial import extensions
1436 > from mercurial import extensions
1431 > def reposetup(ui, repo):
1437 > def reposetup(ui, repo):
1432 > ui.write('reposetup() for %s\n' % (repo.root))
1438 > ui.write('reposetup() for %s\n' % (repo.root))
1433 > ui.flush()
1439 > ui.flush()
1434 > EOF
1440 > EOF
1435 $ hg init src
1441 $ hg init src
1436 $ echo a > src/a
1442 $ echo a > src/a
1437 $ hg -R src commit -Am '#0 at src/a'
1443 $ hg -R src commit -Am '#0 at src/a'
1438 adding a
1444 adding a
1439 $ echo '[extensions]' >> src/.hg/hgrc
1445 $ echo '[extensions]' >> src/.hg/hgrc
1440 $ echo '# enable extension locally' >> src/.hg/hgrc
1446 $ echo '# enable extension locally' >> src/.hg/hgrc
1441 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1447 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1442 $ hg -R src status
1448 $ hg -R src status
1443 reposetup() for $TESTTMP/reposetup-test/src (glob)
1449 reposetup() for $TESTTMP/reposetup-test/src (glob)
1444
1450
1445 $ hg clone -U src clone-dst1
1451 $ hg clone -U src clone-dst1
1446 reposetup() for $TESTTMP/reposetup-test/src (glob)
1452 reposetup() for $TESTTMP/reposetup-test/src (glob)
1447 $ hg init push-dst1
1453 $ hg init push-dst1
1448 $ hg -q -R src push push-dst1
1454 $ hg -q -R src push push-dst1
1449 reposetup() for $TESTTMP/reposetup-test/src (glob)
1455 reposetup() for $TESTTMP/reposetup-test/src (glob)
1450 $ hg init pull-src1
1456 $ hg init pull-src1
1451 $ hg -q -R pull-src1 pull src
1457 $ hg -q -R pull-src1 pull src
1452 reposetup() for $TESTTMP/reposetup-test/src (glob)
1458 reposetup() for $TESTTMP/reposetup-test/src (glob)
1453
1459
1454 $ cat <<EOF >> $HGRCPATH
1460 $ cat <<EOF >> $HGRCPATH
1455 > [extensions]
1461 > [extensions]
1456 > # disable extension globally and explicitly
1462 > # disable extension globally and explicitly
1457 > reposetuptest = !
1463 > reposetuptest = !
1458 > EOF
1464 > EOF
1459 $ hg clone -U src clone-dst2
1465 $ hg clone -U src clone-dst2
1460 reposetup() for $TESTTMP/reposetup-test/src (glob)
1466 reposetup() for $TESTTMP/reposetup-test/src (glob)
1461 $ hg init push-dst2
1467 $ hg init push-dst2
1462 $ hg -q -R src push push-dst2
1468 $ hg -q -R src push push-dst2
1463 reposetup() for $TESTTMP/reposetup-test/src (glob)
1469 reposetup() for $TESTTMP/reposetup-test/src (glob)
1464 $ hg init pull-src2
1470 $ hg init pull-src2
1465 $ hg -q -R pull-src2 pull src
1471 $ hg -q -R pull-src2 pull src
1466 reposetup() for $TESTTMP/reposetup-test/src (glob)
1472 reposetup() for $TESTTMP/reposetup-test/src (glob)
1467
1473
1468 $ cat <<EOF >> $HGRCPATH
1474 $ cat <<EOF >> $HGRCPATH
1469 > [extensions]
1475 > [extensions]
1470 > # enable extension globally
1476 > # enable extension globally
1471 > reposetuptest = $TESTTMP/reposetuptest.py
1477 > reposetuptest = $TESTTMP/reposetuptest.py
1472 > EOF
1478 > EOF
1473 $ hg clone -U src clone-dst3
1479 $ hg clone -U src clone-dst3
1474 reposetup() for $TESTTMP/reposetup-test/src (glob)
1480 reposetup() for $TESTTMP/reposetup-test/src (glob)
1475 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1481 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1476 $ hg init push-dst3
1482 $ hg init push-dst3
1477 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1483 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1478 $ hg -q -R src push push-dst3
1484 $ hg -q -R src push push-dst3
1479 reposetup() for $TESTTMP/reposetup-test/src (glob)
1485 reposetup() for $TESTTMP/reposetup-test/src (glob)
1480 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1486 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1481 $ hg init pull-src3
1487 $ hg init pull-src3
1482 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1488 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1483 $ hg -q -R pull-src3 pull src
1489 $ hg -q -R pull-src3 pull src
1484 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1490 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1485 reposetup() for $TESTTMP/reposetup-test/src (glob)
1491 reposetup() for $TESTTMP/reposetup-test/src (glob)
1486
1492
1487 $ echo '[extensions]' >> src/.hg/hgrc
1493 $ echo '[extensions]' >> src/.hg/hgrc
1488 $ echo '# disable extension locally' >> src/.hg/hgrc
1494 $ echo '# disable extension locally' >> src/.hg/hgrc
1489 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1495 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1490 $ hg clone -U src clone-dst4
1496 $ hg clone -U src clone-dst4
1491 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1497 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1492 $ hg init push-dst4
1498 $ hg init push-dst4
1493 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1499 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1494 $ hg -q -R src push push-dst4
1500 $ hg -q -R src push push-dst4
1495 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1501 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1496 $ hg init pull-src4
1502 $ hg init pull-src4
1497 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1503 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1498 $ hg -q -R pull-src4 pull src
1504 $ hg -q -R pull-src4 pull src
1499 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1505 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1500
1506
1501 disabling in command line overlays with all configuration
1507 disabling in command line overlays with all configuration
1502 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1508 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1503 $ hg --config extensions.reposetuptest=! init push-dst5
1509 $ hg --config extensions.reposetuptest=! init push-dst5
1504 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1510 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1505 $ hg --config extensions.reposetuptest=! init pull-src5
1511 $ hg --config extensions.reposetuptest=! init pull-src5
1506 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1512 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1507
1513
1508 $ cat <<EOF >> $HGRCPATH
1514 $ cat <<EOF >> $HGRCPATH
1509 > [extensions]
1515 > [extensions]
1510 > # disable extension globally and explicitly
1516 > # disable extension globally and explicitly
1511 > reposetuptest = !
1517 > reposetuptest = !
1512 > EOF
1518 > EOF
1513 $ hg init parent
1519 $ hg init parent
1514 $ hg init parent/sub1
1520 $ hg init parent/sub1
1515 $ echo 1 > parent/sub1/1
1521 $ echo 1 > parent/sub1/1
1516 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1522 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1517 adding 1
1523 adding 1
1518 $ hg init parent/sub2
1524 $ hg init parent/sub2
1519 $ hg init parent/sub2/sub21
1525 $ hg init parent/sub2/sub21
1520 $ echo 21 > parent/sub2/sub21/21
1526 $ echo 21 > parent/sub2/sub21/21
1521 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1527 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1522 adding 21
1528 adding 21
1523 $ cat > parent/sub2/.hgsub <<EOF
1529 $ cat > parent/sub2/.hgsub <<EOF
1524 > sub21 = sub21
1530 > sub21 = sub21
1525 > EOF
1531 > EOF
1526 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1532 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1527 adding .hgsub
1533 adding .hgsub
1528 $ hg init parent/sub3
1534 $ hg init parent/sub3
1529 $ echo 3 > parent/sub3/3
1535 $ echo 3 > parent/sub3/3
1530 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1536 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1531 adding 3
1537 adding 3
1532 $ cat > parent/.hgsub <<EOF
1538 $ cat > parent/.hgsub <<EOF
1533 > sub1 = sub1
1539 > sub1 = sub1
1534 > sub2 = sub2
1540 > sub2 = sub2
1535 > sub3 = sub3
1541 > sub3 = sub3
1536 > EOF
1542 > EOF
1537 $ hg -R parent commit -Am '#0 at parent'
1543 $ hg -R parent commit -Am '#0 at parent'
1538 adding .hgsub
1544 adding .hgsub
1539 $ echo '[extensions]' >> parent/.hg/hgrc
1545 $ echo '[extensions]' >> parent/.hg/hgrc
1540 $ echo '# enable extension locally' >> parent/.hg/hgrc
1546 $ echo '# enable extension locally' >> parent/.hg/hgrc
1541 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1547 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1542 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1548 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1543 $ hg -R parent status -S -A
1549 $ hg -R parent status -S -A
1544 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1550 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1545 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1551 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1546 C .hgsub
1552 C .hgsub
1547 C .hgsubstate
1553 C .hgsubstate
1548 C sub1/1
1554 C sub1/1
1549 C sub2/.hgsub
1555 C sub2/.hgsub
1550 C sub2/.hgsubstate
1556 C sub2/.hgsubstate
1551 C sub2/sub21/21
1557 C sub2/sub21/21
1552 C sub3/3
1558 C sub3/3
1553
1559
1554 $ cd ..
1560 $ cd ..
1555
1561
1556 Prohibit registration of commands that don't use @command (issue5137)
1562 Prohibit registration of commands that don't use @command (issue5137)
1557
1563
1558 $ hg init deprecated
1564 $ hg init deprecated
1559 $ cd deprecated
1565 $ cd deprecated
1560
1566
1561 $ cat <<EOF > deprecatedcmd.py
1567 $ cat <<EOF > deprecatedcmd.py
1562 > def deprecatedcmd(repo, ui):
1568 > def deprecatedcmd(repo, ui):
1563 > pass
1569 > pass
1564 > cmdtable = {
1570 > cmdtable = {
1565 > 'deprecatedcmd': (deprecatedcmd, [], ''),
1571 > 'deprecatedcmd': (deprecatedcmd, [], ''),
1566 > }
1572 > }
1567 > EOF
1573 > EOF
1568 $ cat <<EOF > .hg/hgrc
1574 $ cat <<EOF > .hg/hgrc
1569 > [extensions]
1575 > [extensions]
1570 > deprecatedcmd = `pwd`/deprecatedcmd.py
1576 > deprecatedcmd = `pwd`/deprecatedcmd.py
1571 > mq = !
1577 > mq = !
1572 > hgext.mq = !
1578 > hgext.mq = !
1573 > hgext/mq = !
1579 > hgext/mq = !
1574 > EOF
1580 > EOF
1575
1581
1576 $ hg deprecatedcmd > /dev/null
1582 $ hg deprecatedcmd > /dev/null
1577 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1583 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1578 *** (use @command decorator to register 'deprecatedcmd')
1584 *** (use @command decorator to register 'deprecatedcmd')
1579 hg: unknown command 'deprecatedcmd'
1585 hg: unknown command 'deprecatedcmd'
1580 [255]
1586 [255]
1581
1587
1582 the extension shouldn't be loaded at all so the mq works:
1588 the extension shouldn't be loaded at all so the mq works:
1583
1589
1584 $ hg qseries --config extensions.mq= > /dev/null
1590 $ hg qseries --config extensions.mq= > /dev/null
1585 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1591 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1586 *** (use @command decorator to register 'deprecatedcmd')
1592 *** (use @command decorator to register 'deprecatedcmd')
1587
1593
1588 $ cd ..
1594 $ cd ..
1589
1595
1590 Test synopsis and docstring extending
1596 Test synopsis and docstring extending
1591
1597
1592 $ hg init exthelp
1598 $ hg init exthelp
1593 $ cat > exthelp.py <<EOF
1599 $ cat > exthelp.py <<EOF
1594 > from mercurial import commands, extensions
1600 > from mercurial import commands, extensions
1595 > def exbookmarks(orig, *args, **opts):
1601 > def exbookmarks(orig, *args, **opts):
1596 > return orig(*args, **opts)
1602 > return orig(*args, **opts)
1597 > def uisetup(ui):
1603 > def uisetup(ui):
1598 > synopsis = ' GREPME [--foo] [-x]'
1604 > synopsis = ' GREPME [--foo] [-x]'
1599 > docstring = '''
1605 > docstring = '''
1600 > GREPME make sure that this is in the help!
1606 > GREPME make sure that this is in the help!
1601 > '''
1607 > '''
1602 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1608 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1603 > synopsis, docstring)
1609 > synopsis, docstring)
1604 > EOF
1610 > EOF
1605 $ abspath=`pwd`/exthelp.py
1611 $ abspath=`pwd`/exthelp.py
1606 $ echo '[extensions]' >> $HGRCPATH
1612 $ echo '[extensions]' >> $HGRCPATH
1607 $ echo "exthelp = $abspath" >> $HGRCPATH
1613 $ echo "exthelp = $abspath" >> $HGRCPATH
1608 $ cd exthelp
1614 $ cd exthelp
1609 $ hg help bookmarks | grep GREPME
1615 $ hg help bookmarks | grep GREPME
1610 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1616 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1611 GREPME make sure that this is in the help!
1617 GREPME make sure that this is in the help!
1612 $ cd ..
1618 $ cd ..
1613
1619
1614 Show deprecation warning for the use of cmdutil.command
1620 Show deprecation warning for the use of cmdutil.command
1615
1621
1616 $ cat > nonregistrar.py <<EOF
1622 $ cat > nonregistrar.py <<EOF
1617 > from mercurial import cmdutil
1623 > from mercurial import cmdutil
1618 > cmdtable = {}
1624 > cmdtable = {}
1619 > command = cmdutil.command(cmdtable)
1625 > command = cmdutil.command(cmdtable)
1620 > @command(b'foo', [], norepo=True)
1626 > @command(b'foo', [], norepo=True)
1621 > def foo(ui):
1627 > def foo(ui):
1622 > pass
1628 > pass
1623 > EOF
1629 > EOF
1624
1630
1625 $ hg --config extensions.nonregistrar=`pwd`/nonregistrar.py version > /dev/null
1631 $ hg --config extensions.nonregistrar=`pwd`/nonregistrar.py version > /dev/null
1626 devel-warn: cmdutil.command is deprecated, use registrar.command to register 'foo'
1632 devel-warn: cmdutil.command is deprecated, use registrar.command to register 'foo'
1627 (compatibility will be dropped after Mercurial-4.6, update your code.) * (glob)
1633 (compatibility will be dropped after Mercurial-4.6, update your code.) * (glob)
1628
1634
1629 Make sure a broken uisetup doesn't globally break hg:
1635 Make sure a broken uisetup doesn't globally break hg:
1630 $ cat > $TESTTMP/baduisetup.py <<EOF
1636 $ cat > $TESTTMP/baduisetup.py <<EOF
1631 > from mercurial import (
1637 > from mercurial import (
1632 > bdiff,
1638 > bdiff,
1633 > extensions,
1639 > extensions,
1634 > )
1640 > )
1635 >
1641 >
1636 > def blockswrapper(orig, *args, **kwargs):
1642 > def blockswrapper(orig, *args, **kwargs):
1637 > return orig(*args, **kwargs)
1643 > return orig(*args, **kwargs)
1638 >
1644 >
1639 > def uisetup(ui):
1645 > def uisetup(ui):
1640 > extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
1646 > extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
1641 > EOF
1647 > EOF
1642 $ cat >> $HGRCPATH <<EOF
1648 $ cat >> $HGRCPATH <<EOF
1643 > [extensions]
1649 > [extensions]
1644 > baduisetup = $TESTTMP/baduisetup.py
1650 > baduisetup = $TESTTMP/baduisetup.py
1645 > EOF
1651 > EOF
1646
1652
1647 Even though the extension fails during uisetup, hg is still basically usable:
1653 Even though the extension fails during uisetup, hg is still basically usable:
1648 $ hg version
1654 $ hg version
1649 *** failed to set up extension baduisetup: No module named bdiff
1655 *** failed to set up extension baduisetup: No module named bdiff
1650 Mercurial Distributed SCM (version *) (glob)
1656 Mercurial Distributed SCM (version *) (glob)
1651 (see https://mercurial-scm.org for more information)
1657 (see https://mercurial-scm.org for more information)
1652
1658
1653 Copyright (C) 2005-2017 Matt Mackall and others
1659 Copyright (C) 2005-2017 Matt Mackall and others
1654 This is free software; see the source for copying conditions. There is NO
1660 This is free software; see the source for copying conditions. There is NO
1655 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1661 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1656
1662
1657 $ hg version --traceback
1663 $ hg version --traceback
1658 Traceback (most recent call last):
1664 Traceback (most recent call last):
1659 File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
1665 File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
1660 uisetup(ui)
1666 uisetup(ui)
1661 File "$TESTTMP/baduisetup.py", line 10, in uisetup
1667 File "$TESTTMP/baduisetup.py", line 10, in uisetup
1662 extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
1668 extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
1663 File "*/mercurial/extensions.py", line *, in wrapfunction (glob)
1669 File "*/mercurial/extensions.py", line *, in wrapfunction (glob)
1664 origfn = getattr(container, funcname)
1670 origfn = getattr(container, funcname)
1665 File "*/hgdemandimport/demandimportpy2.py", line *, in __getattr__ (glob)
1671 File "*/hgdemandimport/demandimportpy2.py", line *, in __getattr__ (glob)
1666 self._load()
1672 self._load()
1667 File "*/hgdemandimport/demandimportpy2.py", line *, in _load (glob)
1673 File "*/hgdemandimport/demandimportpy2.py", line *, in _load (glob)
1668 mod = _hgextimport(_import, head, globals, locals, None, level)
1674 mod = _hgextimport(_import, head, globals, locals, None, level)
1669 File "*/hgdemandimport/demandimportpy2.py", line *, in _hgextimport (glob)
1675 File "*/hgdemandimport/demandimportpy2.py", line *, in _hgextimport (glob)
1670 return importfunc(name, globals, *args, **kwargs)
1676 return importfunc(name, globals, *args, **kwargs)
1671 ImportError: No module named bdiff
1677 ImportError: No module named bdiff
1672 *** failed to set up extension baduisetup: No module named bdiff
1678 *** failed to set up extension baduisetup: No module named bdiff
1673 Mercurial Distributed SCM (version *) (glob)
1679 Mercurial Distributed SCM (version *) (glob)
1674 (see https://mercurial-scm.org for more information)
1680 (see https://mercurial-scm.org for more information)
1675
1681
1676 Copyright (C) 2005-2017 Matt Mackall and others
1682 Copyright (C) 2005-2017 Matt Mackall and others
1677 This is free software; see the source for copying conditions. There is NO
1683 This is free software; see the source for copying conditions. There is NO
1678 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1684 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
General Comments 0
You need to be logged in to leave comments. Login now