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