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