##// END OF EJS Templates
hgweb: raw file mimetype guessing configurable, off by default (BC) (issue2923)...
Matt Mackall -
r15004:d06b9c55 stable
parent child Browse files
Show More
@@ -1,1293 +1,1300
1 The Mercurial system uses a set of configuration files to control
1 The Mercurial system uses a set of configuration files to control
2 aspects of its behavior.
2 aspects of its behavior.
3
3
4 The configuration files use a simple ini-file format. A configuration
4 The configuration files use a simple ini-file format. A configuration
5 file consists of sections, led by a ``[section]`` header and followed
5 file consists of sections, led by a ``[section]`` header and followed
6 by ``name = value`` entries::
6 by ``name = value`` entries::
7
7
8 [ui]
8 [ui]
9 username = Firstname Lastname <firstname.lastname@example.net>
9 username = Firstname Lastname <firstname.lastname@example.net>
10 verbose = True
10 verbose = True
11
11
12 The above entries will be referred to as ``ui.username`` and
12 The above entries will be referred to as ``ui.username`` and
13 ``ui.verbose``, respectively. See the Syntax section below.
13 ``ui.verbose``, respectively. See the Syntax section below.
14
14
15 Files
15 Files
16 -----
16 -----
17
17
18 Mercurial reads configuration data from several files, if they exist.
18 Mercurial reads configuration data from several files, if they exist.
19 These files do not exist by default and you will have to create the
19 These files do not exist by default and you will have to create the
20 appropriate configuration files yourself: global configuration like
20 appropriate configuration files yourself: global configuration like
21 the username setting is typically put into
21 the username setting is typically put into
22 ``%USERPROFILE%\mercurial.ini`` or ``$HOME/.hgrc`` and local
22 ``%USERPROFILE%\mercurial.ini`` or ``$HOME/.hgrc`` and local
23 configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
23 configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
24
24
25 The names of these files depend on the system on which Mercurial is
25 The names of these files depend on the system on which Mercurial is
26 installed. ``*.rc`` files from a single directory are read in
26 installed. ``*.rc`` files from a single directory are read in
27 alphabetical order, later ones overriding earlier ones. Where multiple
27 alphabetical order, later ones overriding earlier ones. Where multiple
28 paths are given below, settings from earlier paths override later
28 paths are given below, settings from earlier paths override later
29 ones.
29 ones.
30
30
31 | (Unix, Windows) ``<repo>/.hg/hgrc``
31 | (Unix, Windows) ``<repo>/.hg/hgrc``
32
32
33 Per-repository configuration options that only apply in a
33 Per-repository configuration options that only apply in a
34 particular repository. This file is not version-controlled, and
34 particular repository. This file is not version-controlled, and
35 will not get transferred during a "clone" operation. Options in
35 will not get transferred during a "clone" operation. Options in
36 this file override options in all other configuration files. On
36 this file override options in all other configuration files. On
37 Unix, most of this file will be ignored if it doesn't belong to a
37 Unix, most of this file will be ignored if it doesn't belong to a
38 trusted user or to a trusted group. See the documentation for the
38 trusted user or to a trusted group. See the documentation for the
39 ``[trusted]`` section below for more details.
39 ``[trusted]`` section below for more details.
40
40
41 | (Unix) ``$HOME/.hgrc``
41 | (Unix) ``$HOME/.hgrc``
42 | (Windows) ``%USERPROFILE%\.hgrc``
42 | (Windows) ``%USERPROFILE%\.hgrc``
43 | (Windows) ``%USERPROFILE%\Mercurial.ini``
43 | (Windows) ``%USERPROFILE%\Mercurial.ini``
44 | (Windows) ``%HOME%\.hgrc``
44 | (Windows) ``%HOME%\.hgrc``
45 | (Windows) ``%HOME%\Mercurial.ini``
45 | (Windows) ``%HOME%\Mercurial.ini``
46
46
47 Per-user configuration file(s), for the user running Mercurial. On
47 Per-user configuration file(s), for the user running Mercurial. On
48 Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
48 Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
49 files apply to all Mercurial commands executed by this user in any
49 files apply to all Mercurial commands executed by this user in any
50 directory. Options in these files override per-system and per-installation
50 directory. Options in these files override per-system and per-installation
51 options.
51 options.
52
52
53 | (Unix) ``/etc/mercurial/hgrc``
53 | (Unix) ``/etc/mercurial/hgrc``
54 | (Unix) ``/etc/mercurial/hgrc.d/*.rc``
54 | (Unix) ``/etc/mercurial/hgrc.d/*.rc``
55
55
56 Per-system configuration files, for the system on which Mercurial
56 Per-system configuration files, for the system on which Mercurial
57 is running. Options in these files apply to all Mercurial commands
57 is running. Options in these files apply to all Mercurial commands
58 executed by any user in any directory. Options in these files
58 executed by any user in any directory. Options in these files
59 override per-installation options.
59 override per-installation options.
60
60
61 | (Unix) ``<install-root>/etc/mercurial/hgrc``
61 | (Unix) ``<install-root>/etc/mercurial/hgrc``
62 | (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
62 | (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
63
63
64 Per-installation configuration files, searched for in the
64 Per-installation configuration files, searched for in the
65 directory where Mercurial is installed. ``<install-root>`` is the
65 directory where Mercurial is installed. ``<install-root>`` is the
66 parent directory of the **hg** executable (or symlink) being run. For
66 parent directory of the **hg** executable (or symlink) being run. For
67 example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
67 example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
68 in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
68 in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
69 to all Mercurial commands executed by any user in any directory.
69 to all Mercurial commands executed by any user in any directory.
70
70
71 | (Windows) ``<install-dir>\Mercurial.ini`` **or**
71 | (Windows) ``<install-dir>\Mercurial.ini`` **or**
72 | (Windows) ``<install-dir>\hgrc.d\*.rc`` **or**
72 | (Windows) ``<install-dir>\hgrc.d\*.rc`` **or**
73 | (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
73 | (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
74
74
75 Per-installation/system configuration files, for the system on
75 Per-installation/system configuration files, for the system on
76 which Mercurial is running. Options in these files apply to all
76 which Mercurial is running. Options in these files apply to all
77 Mercurial commands executed by any user in any directory. Registry
77 Mercurial commands executed by any user in any directory. Registry
78 keys contain PATH-like strings, every part of which must reference
78 keys contain PATH-like strings, every part of which must reference
79 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
79 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
80 be read. Mercurial checks each of these locations in the specified
80 be read. Mercurial checks each of these locations in the specified
81 order until one or more configuration files are detected. If the
81 order until one or more configuration files are detected. If the
82 pywin32 extensions are not installed, Mercurial will only look for
82 pywin32 extensions are not installed, Mercurial will only look for
83 site-wide configuration in ``C:\Mercurial\Mercurial.ini``.
83 site-wide configuration in ``C:\Mercurial\Mercurial.ini``.
84
84
85 Syntax
85 Syntax
86 ------
86 ------
87
87
88 A configuration file consists of sections, led by a ``[section]`` header
88 A configuration file consists of sections, led by a ``[section]`` header
89 and followed by ``name = value`` entries (sometimes called
89 and followed by ``name = value`` entries (sometimes called
90 ``configuration keys``)::
90 ``configuration keys``)::
91
91
92 [spam]
92 [spam]
93 eggs=ham
93 eggs=ham
94 green=
94 green=
95 eggs
95 eggs
96
96
97 Each line contains one entry. If the lines that follow are indented,
97 Each line contains one entry. If the lines that follow are indented,
98 they are treated as continuations of that entry. Leading whitespace is
98 they are treated as continuations of that entry. Leading whitespace is
99 removed from values. Empty lines are skipped. Lines beginning with
99 removed from values. Empty lines are skipped. Lines beginning with
100 ``#`` or ``;`` are ignored and may be used to provide comments.
100 ``#`` or ``;`` are ignored and may be used to provide comments.
101
101
102 Configuration keys can be set multiple times, in which case Mercurial
102 Configuration keys can be set multiple times, in which case Mercurial
103 will use the value that was configured last. As an example::
103 will use the value that was configured last. As an example::
104
104
105 [spam]
105 [spam]
106 eggs=large
106 eggs=large
107 ham=serrano
107 ham=serrano
108 eggs=small
108 eggs=small
109
109
110 This would set the configuration key named ``eggs`` to ``small``.
110 This would set the configuration key named ``eggs`` to ``small``.
111
111
112 It is also possible to define a section multiple times. A section can
112 It is also possible to define a section multiple times. A section can
113 be redefined on the same and/or on different configuration files. For
113 be redefined on the same and/or on different configuration files. For
114 example::
114 example::
115
115
116 [foo]
116 [foo]
117 eggs=large
117 eggs=large
118 ham=serrano
118 ham=serrano
119 eggs=small
119 eggs=small
120
120
121 [bar]
121 [bar]
122 eggs=ham
122 eggs=ham
123 green=
123 green=
124 eggs
124 eggs
125
125
126 [foo]
126 [foo]
127 ham=prosciutto
127 ham=prosciutto
128 eggs=medium
128 eggs=medium
129 bread=toasted
129 bread=toasted
130
130
131 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
131 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
132 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
132 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
133 respectively. As you can see there only thing that matters is the last
133 respectively. As you can see there only thing that matters is the last
134 value that was set for each of the configuration keys.
134 value that was set for each of the configuration keys.
135
135
136 If a configuration key is set multiple times in different
136 If a configuration key is set multiple times in different
137 configuration files the final value will depend on the order in which
137 configuration files the final value will depend on the order in which
138 the different configuration files are read, with settings from earlier
138 the different configuration files are read, with settings from earlier
139 paths overriding later ones as described on the ``Files`` section
139 paths overriding later ones as described on the ``Files`` section
140 above.
140 above.
141
141
142 A line of the form ``%include file`` will include ``file`` into the
142 A line of the form ``%include file`` will include ``file`` into the
143 current configuration file. The inclusion is recursive, which means
143 current configuration file. The inclusion is recursive, which means
144 that included files can include other files. Filenames are relative to
144 that included files can include other files. Filenames are relative to
145 the configuration file in which the ``%include`` directive is found.
145 the configuration file in which the ``%include`` directive is found.
146 Environment variables and ``~user`` constructs are expanded in
146 Environment variables and ``~user`` constructs are expanded in
147 ``file``. This lets you do something like::
147 ``file``. This lets you do something like::
148
148
149 %include ~/.hgrc.d/$HOST.rc
149 %include ~/.hgrc.d/$HOST.rc
150
150
151 to include a different configuration file on each computer you use.
151 to include a different configuration file on each computer you use.
152
152
153 A line with ``%unset name`` will remove ``name`` from the current
153 A line with ``%unset name`` will remove ``name`` from the current
154 section, if it has been set previously.
154 section, if it has been set previously.
155
155
156 The values are either free-form text strings, lists of text strings,
156 The values are either free-form text strings, lists of text strings,
157 or Boolean values. Boolean values can be set to true using any of "1",
157 or Boolean values. Boolean values can be set to true using any of "1",
158 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
158 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
159 (all case insensitive).
159 (all case insensitive).
160
160
161 List values are separated by whitespace or comma, except when values are
161 List values are separated by whitespace or comma, except when values are
162 placed in double quotation marks::
162 placed in double quotation marks::
163
163
164 allow_read = "John Doe, PhD", brian, betty
164 allow_read = "John Doe, PhD", brian, betty
165
165
166 Quotation marks can be escaped by prefixing them with a backslash. Only
166 Quotation marks can be escaped by prefixing them with a backslash. Only
167 quotation marks at the beginning of a word is counted as a quotation
167 quotation marks at the beginning of a word is counted as a quotation
168 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
168 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
169
169
170 Sections
170 Sections
171 --------
171 --------
172
172
173 This section describes the different sections that may appear in a
173 This section describes the different sections that may appear in a
174 Mercurial configuration file, the purpose of each section, its possible
174 Mercurial configuration file, the purpose of each section, its possible
175 keys, and their possible values.
175 keys, and their possible values.
176
176
177 ``alias``
177 ``alias``
178 """""""""
178 """""""""
179
179
180 Defines command aliases.
180 Defines command aliases.
181 Aliases allow you to define your own commands in terms of other
181 Aliases allow you to define your own commands in terms of other
182 commands (or aliases), optionally including arguments. Positional
182 commands (or aliases), optionally including arguments. Positional
183 arguments in the form of ``$1``, ``$2``, etc in the alias definition
183 arguments in the form of ``$1``, ``$2``, etc in the alias definition
184 are expanded by Mercurial before execution. Positional arguments not
184 are expanded by Mercurial before execution. Positional arguments not
185 already used by ``$N`` in the definition are put at the end of the
185 already used by ``$N`` in the definition are put at the end of the
186 command to be executed.
186 command to be executed.
187
187
188 Alias definitions consist of lines of the form::
188 Alias definitions consist of lines of the form::
189
189
190 <alias> = <command> [<argument>]...
190 <alias> = <command> [<argument>]...
191
191
192 For example, this definition::
192 For example, this definition::
193
193
194 latest = log --limit 5
194 latest = log --limit 5
195
195
196 creates a new command ``latest`` that shows only the five most recent
196 creates a new command ``latest`` that shows only the five most recent
197 changesets. You can define subsequent aliases using earlier ones::
197 changesets. You can define subsequent aliases using earlier ones::
198
198
199 stable5 = latest -b stable
199 stable5 = latest -b stable
200
200
201 .. note:: It is possible to create aliases with the same names as
201 .. note:: It is possible to create aliases with the same names as
202 existing commands, which will then override the original
202 existing commands, which will then override the original
203 definitions. This is almost always a bad idea!
203 definitions. This is almost always a bad idea!
204
204
205 An alias can start with an exclamation point (``!``) to make it a
205 An alias can start with an exclamation point (``!``) to make it a
206 shell alias. A shell alias is executed with the shell and will let you
206 shell alias. A shell alias is executed with the shell and will let you
207 run arbitrary commands. As an example, ::
207 run arbitrary commands. As an example, ::
208
208
209 echo = !echo
209 echo = !echo
210
210
211 will let you do ``hg echo foo`` to have ``foo`` printed in your
211 will let you do ``hg echo foo`` to have ``foo`` printed in your
212 terminal. A better example might be::
212 terminal. A better example might be::
213
213
214 purge = !$HG status --no-status --unknown -0 | xargs -0 rm
214 purge = !$HG status --no-status --unknown -0 | xargs -0 rm
215
215
216 which will make ``hg purge`` delete all unknown files in the
216 which will make ``hg purge`` delete all unknown files in the
217 repository in the same manner as the purge extension.
217 repository in the same manner as the purge extension.
218
218
219 Shell aliases are executed in an environment where ``$HG`` expand to
219 Shell aliases are executed in an environment where ``$HG`` expand to
220 the path of the Mercurial that was used to execute the alias. This is
220 the path of the Mercurial that was used to execute the alias. This is
221 useful when you want to call further Mercurial commands in a shell
221 useful when you want to call further Mercurial commands in a shell
222 alias, as was done above for the purge alias. In addition,
222 alias, as was done above for the purge alias. In addition,
223 ``$HG_ARGS`` expand to the arguments given to Mercurial. In the ``hg
223 ``$HG_ARGS`` expand to the arguments given to Mercurial. In the ``hg
224 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
224 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
225
225
226 ``auth``
226 ``auth``
227 """"""""
227 """"""""
228
228
229 Authentication credentials for HTTP authentication. This section
229 Authentication credentials for HTTP authentication. This section
230 allows you to store usernames and passwords for use when logging
230 allows you to store usernames and passwords for use when logging
231 *into* HTTP servers. See the ``[web]`` configuration section if
231 *into* HTTP servers. See the ``[web]`` configuration section if
232 you want to configure *who* can login to your HTTP server.
232 you want to configure *who* can login to your HTTP server.
233
233
234 Each line has the following format::
234 Each line has the following format::
235
235
236 <name>.<argument> = <value>
236 <name>.<argument> = <value>
237
237
238 where ``<name>`` is used to group arguments into authentication
238 where ``<name>`` is used to group arguments into authentication
239 entries. Example::
239 entries. Example::
240
240
241 foo.prefix = hg.intevation.org/mercurial
241 foo.prefix = hg.intevation.org/mercurial
242 foo.username = foo
242 foo.username = foo
243 foo.password = bar
243 foo.password = bar
244 foo.schemes = http https
244 foo.schemes = http https
245
245
246 bar.prefix = secure.example.org
246 bar.prefix = secure.example.org
247 bar.key = path/to/file.key
247 bar.key = path/to/file.key
248 bar.cert = path/to/file.cert
248 bar.cert = path/to/file.cert
249 bar.schemes = https
249 bar.schemes = https
250
250
251 Supported arguments:
251 Supported arguments:
252
252
253 ``prefix``
253 ``prefix``
254 Either ``*`` or a URI prefix with or without the scheme part.
254 Either ``*`` or a URI prefix with or without the scheme part.
255 The authentication entry with the longest matching prefix is used
255 The authentication entry with the longest matching prefix is used
256 (where ``*`` matches everything and counts as a match of length
256 (where ``*`` matches everything and counts as a match of length
257 1). If the prefix doesn't include a scheme, the match is performed
257 1). If the prefix doesn't include a scheme, the match is performed
258 against the URI with its scheme stripped as well, and the schemes
258 against the URI with its scheme stripped as well, and the schemes
259 argument, q.v., is then subsequently consulted.
259 argument, q.v., is then subsequently consulted.
260
260
261 ``username``
261 ``username``
262 Optional. Username to authenticate with. If not given, and the
262 Optional. Username to authenticate with. If not given, and the
263 remote site requires basic or digest authentication, the user will
263 remote site requires basic or digest authentication, the user will
264 be prompted for it. Environment variables are expanded in the
264 be prompted for it. Environment variables are expanded in the
265 username letting you do ``foo.username = $USER``.
265 username letting you do ``foo.username = $USER``.
266
266
267 ``password``
267 ``password``
268 Optional. Password to authenticate with. If not given, and the
268 Optional. Password to authenticate with. If not given, and the
269 remote site requires basic or digest authentication, the user
269 remote site requires basic or digest authentication, the user
270 will be prompted for it.
270 will be prompted for it.
271
271
272 ``key``
272 ``key``
273 Optional. PEM encoded client certificate key file. Environment
273 Optional. PEM encoded client certificate key file. Environment
274 variables are expanded in the filename.
274 variables are expanded in the filename.
275
275
276 ``cert``
276 ``cert``
277 Optional. PEM encoded client certificate chain file. Environment
277 Optional. PEM encoded client certificate chain file. Environment
278 variables are expanded in the filename.
278 variables are expanded in the filename.
279
279
280 ``schemes``
280 ``schemes``
281 Optional. Space separated list of URI schemes to use this
281 Optional. Space separated list of URI schemes to use this
282 authentication entry with. Only used if the prefix doesn't include
282 authentication entry with. Only used if the prefix doesn't include
283 a scheme. Supported schemes are http and https. They will match
283 a scheme. Supported schemes are http and https. They will match
284 static-http and static-https respectively, as well.
284 static-http and static-https respectively, as well.
285 Default: https.
285 Default: https.
286
286
287 If no suitable authentication entry is found, the user is prompted
287 If no suitable authentication entry is found, the user is prompted
288 for credentials as usual if required by the remote.
288 for credentials as usual if required by the remote.
289
289
290
290
291 ``decode/encode``
291 ``decode/encode``
292 """""""""""""""""
292 """""""""""""""""
293
293
294 Filters for transforming files on checkout/checkin. This would
294 Filters for transforming files on checkout/checkin. This would
295 typically be used for newline processing or other
295 typically be used for newline processing or other
296 localization/canonicalization of files.
296 localization/canonicalization of files.
297
297
298 Filters consist of a filter pattern followed by a filter command.
298 Filters consist of a filter pattern followed by a filter command.
299 Filter patterns are globs by default, rooted at the repository root.
299 Filter patterns are globs by default, rooted at the repository root.
300 For example, to match any file ending in ``.txt`` in the root
300 For example, to match any file ending in ``.txt`` in the root
301 directory only, use the pattern ``*.txt``. To match any file ending
301 directory only, use the pattern ``*.txt``. To match any file ending
302 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
302 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
303 For each file only the first matching filter applies.
303 For each file only the first matching filter applies.
304
304
305 The filter command can start with a specifier, either ``pipe:`` or
305 The filter command can start with a specifier, either ``pipe:`` or
306 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
306 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
307
307
308 A ``pipe:`` command must accept data on stdin and return the transformed
308 A ``pipe:`` command must accept data on stdin and return the transformed
309 data on stdout.
309 data on stdout.
310
310
311 Pipe example::
311 Pipe example::
312
312
313 [encode]
313 [encode]
314 # uncompress gzip files on checkin to improve delta compression
314 # uncompress gzip files on checkin to improve delta compression
315 # note: not necessarily a good idea, just an example
315 # note: not necessarily a good idea, just an example
316 *.gz = pipe: gunzip
316 *.gz = pipe: gunzip
317
317
318 [decode]
318 [decode]
319 # recompress gzip files when writing them to the working dir (we
319 # recompress gzip files when writing them to the working dir (we
320 # can safely omit "pipe:", because it's the default)
320 # can safely omit "pipe:", because it's the default)
321 *.gz = gzip
321 *.gz = gzip
322
322
323 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
323 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
324 with the name of a temporary file that contains the data to be
324 with the name of a temporary file that contains the data to be
325 filtered by the command. The string ``OUTFILE`` is replaced with the name
325 filtered by the command. The string ``OUTFILE`` is replaced with the name
326 of an empty temporary file, where the filtered data must be written by
326 of an empty temporary file, where the filtered data must be written by
327 the command.
327 the command.
328
328
329 .. note:: The tempfile mechanism is recommended for Windows systems,
329 .. note:: The tempfile mechanism is recommended for Windows systems,
330 where the standard shell I/O redirection operators often have
330 where the standard shell I/O redirection operators often have
331 strange effects and may corrupt the contents of your files.
331 strange effects and may corrupt the contents of your files.
332
332
333 This filter mechanism is used internally by the ``eol`` extension to
333 This filter mechanism is used internally by the ``eol`` extension to
334 translate line ending characters between Windows (CRLF) and Unix (LF)
334 translate line ending characters between Windows (CRLF) and Unix (LF)
335 format. We suggest you use the ``eol`` extension for convenience.
335 format. We suggest you use the ``eol`` extension for convenience.
336
336
337
337
338 ``defaults``
338 ``defaults``
339 """"""""""""
339 """"""""""""
340
340
341 (defaults are deprecated. Don't use them. Use aliases instead)
341 (defaults are deprecated. Don't use them. Use aliases instead)
342
342
343 Use the ``[defaults]`` section to define command defaults, i.e. the
343 Use the ``[defaults]`` section to define command defaults, i.e. the
344 default options/arguments to pass to the specified commands.
344 default options/arguments to pass to the specified commands.
345
345
346 The following example makes :hg:`log` run in verbose mode, and
346 The following example makes :hg:`log` run in verbose mode, and
347 :hg:`status` show only the modified files, by default::
347 :hg:`status` show only the modified files, by default::
348
348
349 [defaults]
349 [defaults]
350 log = -v
350 log = -v
351 status = -m
351 status = -m
352
352
353 The actual commands, instead of their aliases, must be used when
353 The actual commands, instead of their aliases, must be used when
354 defining command defaults. The command defaults will also be applied
354 defining command defaults. The command defaults will also be applied
355 to the aliases of the commands defined.
355 to the aliases of the commands defined.
356
356
357
357
358 ``diff``
358 ``diff``
359 """"""""
359 """"""""
360
360
361 Settings used when displaying diffs. Everything except for ``unified`` is a
361 Settings used when displaying diffs. Everything except for ``unified`` is a
362 Boolean and defaults to False.
362 Boolean and defaults to False.
363
363
364 ``git``
364 ``git``
365 Use git extended diff format.
365 Use git extended diff format.
366
366
367 ``nodates``
367 ``nodates``
368 Don't include dates in diff headers.
368 Don't include dates in diff headers.
369
369
370 ``showfunc``
370 ``showfunc``
371 Show which function each change is in.
371 Show which function each change is in.
372
372
373 ``ignorews``
373 ``ignorews``
374 Ignore white space when comparing lines.
374 Ignore white space when comparing lines.
375
375
376 ``ignorewsamount``
376 ``ignorewsamount``
377 Ignore changes in the amount of white space.
377 Ignore changes in the amount of white space.
378
378
379 ``ignoreblanklines``
379 ``ignoreblanklines``
380 Ignore changes whose lines are all blank.
380 Ignore changes whose lines are all blank.
381
381
382 ``unified``
382 ``unified``
383 Number of lines of context to show.
383 Number of lines of context to show.
384
384
385 ``email``
385 ``email``
386 """""""""
386 """""""""
387
387
388 Settings for extensions that send email messages.
388 Settings for extensions that send email messages.
389
389
390 ``from``
390 ``from``
391 Optional. Email address to use in "From" header and SMTP envelope
391 Optional. Email address to use in "From" header and SMTP envelope
392 of outgoing messages.
392 of outgoing messages.
393
393
394 ``to``
394 ``to``
395 Optional. Comma-separated list of recipients' email addresses.
395 Optional. Comma-separated list of recipients' email addresses.
396
396
397 ``cc``
397 ``cc``
398 Optional. Comma-separated list of carbon copy recipients'
398 Optional. Comma-separated list of carbon copy recipients'
399 email addresses.
399 email addresses.
400
400
401 ``bcc``
401 ``bcc``
402 Optional. Comma-separated list of blind carbon copy recipients'
402 Optional. Comma-separated list of blind carbon copy recipients'
403 email addresses.
403 email addresses.
404
404
405 ``method``
405 ``method``
406 Optional. Method to use to send email messages. If value is ``smtp``
406 Optional. Method to use to send email messages. If value is ``smtp``
407 (default), use SMTP (see the ``[smtp]`` section for configuration).
407 (default), use SMTP (see the ``[smtp]`` section for configuration).
408 Otherwise, use as name of program to run that acts like sendmail
408 Otherwise, use as name of program to run that acts like sendmail
409 (takes ``-f`` option for sender, list of recipients on command line,
409 (takes ``-f`` option for sender, list of recipients on command line,
410 message on stdin). Normally, setting this to ``sendmail`` or
410 message on stdin). Normally, setting this to ``sendmail`` or
411 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
411 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
412
412
413 ``charsets``
413 ``charsets``
414 Optional. Comma-separated list of character sets considered
414 Optional. Comma-separated list of character sets considered
415 convenient for recipients. Addresses, headers, and parts not
415 convenient for recipients. Addresses, headers, and parts not
416 containing patches of outgoing messages will be encoded in the
416 containing patches of outgoing messages will be encoded in the
417 first character set to which conversion from local encoding
417 first character set to which conversion from local encoding
418 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
418 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
419 conversion fails, the text in question is sent as is. Defaults to
419 conversion fails, the text in question is sent as is. Defaults to
420 empty (explicit) list.
420 empty (explicit) list.
421
421
422 Order of outgoing email character sets:
422 Order of outgoing email character sets:
423
423
424 1. ``us-ascii``: always first, regardless of settings
424 1. ``us-ascii``: always first, regardless of settings
425 2. ``email.charsets``: in order given by user
425 2. ``email.charsets``: in order given by user
426 3. ``ui.fallbackencoding``: if not in email.charsets
426 3. ``ui.fallbackencoding``: if not in email.charsets
427 4. ``$HGENCODING``: if not in email.charsets
427 4. ``$HGENCODING``: if not in email.charsets
428 5. ``utf-8``: always last, regardless of settings
428 5. ``utf-8``: always last, regardless of settings
429
429
430 Email example::
430 Email example::
431
431
432 [email]
432 [email]
433 from = Joseph User <joe.user@example.com>
433 from = Joseph User <joe.user@example.com>
434 method = /usr/sbin/sendmail
434 method = /usr/sbin/sendmail
435 # charsets for western Europeans
435 # charsets for western Europeans
436 # us-ascii, utf-8 omitted, as they are tried first and last
436 # us-ascii, utf-8 omitted, as they are tried first and last
437 charsets = iso-8859-1, iso-8859-15, windows-1252
437 charsets = iso-8859-1, iso-8859-15, windows-1252
438
438
439
439
440 ``extensions``
440 ``extensions``
441 """"""""""""""
441 """"""""""""""
442
442
443 Mercurial has an extension mechanism for adding new features. To
443 Mercurial has an extension mechanism for adding new features. To
444 enable an extension, create an entry for it in this section.
444 enable an extension, create an entry for it in this section.
445
445
446 If you know that the extension is already in Python's search path,
446 If you know that the extension is already in Python's search path,
447 you can give the name of the module, followed by ``=``, with nothing
447 you can give the name of the module, followed by ``=``, with nothing
448 after the ``=``.
448 after the ``=``.
449
449
450 Otherwise, give a name that you choose, followed by ``=``, followed by
450 Otherwise, give a name that you choose, followed by ``=``, followed by
451 the path to the ``.py`` file (including the file name extension) that
451 the path to the ``.py`` file (including the file name extension) that
452 defines the extension.
452 defines the extension.
453
453
454 To explicitly disable an extension that is enabled in an hgrc of
454 To explicitly disable an extension that is enabled in an hgrc of
455 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
455 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
456 or ``foo = !`` when path is not supplied.
456 or ``foo = !`` when path is not supplied.
457
457
458 Example for ``~/.hgrc``::
458 Example for ``~/.hgrc``::
459
459
460 [extensions]
460 [extensions]
461 # (the mq extension will get loaded from Mercurial's path)
461 # (the mq extension will get loaded from Mercurial's path)
462 mq =
462 mq =
463 # (this extension will get loaded from the file specified)
463 # (this extension will get loaded from the file specified)
464 myfeature = ~/.hgext/myfeature.py
464 myfeature = ~/.hgext/myfeature.py
465
465
466
466
467 ``hostfingerprints``
467 ``hostfingerprints``
468 """"""""""""""""""""
468 """"""""""""""""""""
469
469
470 Fingerprints of the certificates of known HTTPS servers.
470 Fingerprints of the certificates of known HTTPS servers.
471 A HTTPS connection to a server with a fingerprint configured here will
471 A HTTPS connection to a server with a fingerprint configured here will
472 only succeed if the servers certificate matches the fingerprint.
472 only succeed if the servers certificate matches the fingerprint.
473 This is very similar to how ssh known hosts works.
473 This is very similar to how ssh known hosts works.
474 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
474 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
475 The CA chain and web.cacerts is not used for servers with a fingerprint.
475 The CA chain and web.cacerts is not used for servers with a fingerprint.
476
476
477 For example::
477 For example::
478
478
479 [hostfingerprints]
479 [hostfingerprints]
480 hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:d6:4b:ee:cc
480 hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:d6:4b:ee:cc
481
481
482 This feature is only supported when using Python 2.6 or later.
482 This feature is only supported when using Python 2.6 or later.
483
483
484
484
485 ``format``
485 ``format``
486 """"""""""
486 """"""""""
487
487
488 ``usestore``
488 ``usestore``
489 Enable or disable the "store" repository format which improves
489 Enable or disable the "store" repository format which improves
490 compatibility with systems that fold case or otherwise mangle
490 compatibility with systems that fold case or otherwise mangle
491 filenames. Enabled by default. Disabling this option will allow
491 filenames. Enabled by default. Disabling this option will allow
492 you to store longer filenames in some situations at the expense of
492 you to store longer filenames in some situations at the expense of
493 compatibility and ensures that the on-disk format of newly created
493 compatibility and ensures that the on-disk format of newly created
494 repositories will be compatible with Mercurial before version 0.9.4.
494 repositories will be compatible with Mercurial before version 0.9.4.
495
495
496 ``usefncache``
496 ``usefncache``
497 Enable or disable the "fncache" repository format which enhances
497 Enable or disable the "fncache" repository format which enhances
498 the "store" repository format (which has to be enabled to use
498 the "store" repository format (which has to be enabled to use
499 fncache) to allow longer filenames and avoids using Windows
499 fncache) to allow longer filenames and avoids using Windows
500 reserved names, e.g. "nul". Enabled by default. Disabling this
500 reserved names, e.g. "nul". Enabled by default. Disabling this
501 option ensures that the on-disk format of newly created
501 option ensures that the on-disk format of newly created
502 repositories will be compatible with Mercurial before version 1.1.
502 repositories will be compatible with Mercurial before version 1.1.
503
503
504 ``dotencode``
504 ``dotencode``
505 Enable or disable the "dotencode" repository format which enhances
505 Enable or disable the "dotencode" repository format which enhances
506 the "fncache" repository format (which has to be enabled to use
506 the "fncache" repository format (which has to be enabled to use
507 dotencode) to avoid issues with filenames starting with ._ on
507 dotencode) to avoid issues with filenames starting with ._ on
508 Mac OS X and spaces on Windows. Enabled by default. Disabling this
508 Mac OS X and spaces on Windows. Enabled by default. Disabling this
509 option ensures that the on-disk format of newly created
509 option ensures that the on-disk format of newly created
510 repositories will be compatible with Mercurial before version 1.7.
510 repositories will be compatible with Mercurial before version 1.7.
511
511
512 ``merge-patterns``
512 ``merge-patterns``
513 """"""""""""""""""
513 """"""""""""""""""
514
514
515 This section specifies merge tools to associate with particular file
515 This section specifies merge tools to associate with particular file
516 patterns. Tools matched here will take precedence over the default
516 patterns. Tools matched here will take precedence over the default
517 merge tool. Patterns are globs by default, rooted at the repository
517 merge tool. Patterns are globs by default, rooted at the repository
518 root.
518 root.
519
519
520 Example::
520 Example::
521
521
522 [merge-patterns]
522 [merge-patterns]
523 **.c = kdiff3
523 **.c = kdiff3
524 **.jpg = myimgmerge
524 **.jpg = myimgmerge
525
525
526 ``merge-tools``
526 ``merge-tools``
527 """""""""""""""
527 """""""""""""""
528
528
529 This section configures external merge tools to use for file-level
529 This section configures external merge tools to use for file-level
530 merges.
530 merges.
531
531
532 Example ``~/.hgrc``::
532 Example ``~/.hgrc``::
533
533
534 [merge-tools]
534 [merge-tools]
535 # Override stock tool location
535 # Override stock tool location
536 kdiff3.executable = ~/bin/kdiff3
536 kdiff3.executable = ~/bin/kdiff3
537 # Specify command line
537 # Specify command line
538 kdiff3.args = $base $local $other -o $output
538 kdiff3.args = $base $local $other -o $output
539 # Give higher priority
539 # Give higher priority
540 kdiff3.priority = 1
540 kdiff3.priority = 1
541
541
542 # Define new tool
542 # Define new tool
543 myHtmlTool.args = -m $local $other $base $output
543 myHtmlTool.args = -m $local $other $base $output
544 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
544 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
545 myHtmlTool.priority = 1
545 myHtmlTool.priority = 1
546
546
547 Supported arguments:
547 Supported arguments:
548
548
549 ``priority``
549 ``priority``
550 The priority in which to evaluate this tool.
550 The priority in which to evaluate this tool.
551 Default: 0.
551 Default: 0.
552
552
553 ``executable``
553 ``executable``
554 Either just the name of the executable or its pathname. On Windows,
554 Either just the name of the executable or its pathname. On Windows,
555 the path can use environment variables with ${ProgramFiles} syntax.
555 the path can use environment variables with ${ProgramFiles} syntax.
556 Default: the tool name.
556 Default: the tool name.
557
557
558 ``args``
558 ``args``
559 The arguments to pass to the tool executable. You can refer to the
559 The arguments to pass to the tool executable. You can refer to the
560 files being merged as well as the output file through these
560 files being merged as well as the output file through these
561 variables: ``$base``, ``$local``, ``$other``, ``$output``.
561 variables: ``$base``, ``$local``, ``$other``, ``$output``.
562 Default: ``$local $base $other``
562 Default: ``$local $base $other``
563
563
564 ``premerge``
564 ``premerge``
565 Attempt to run internal non-interactive 3-way merge tool before
565 Attempt to run internal non-interactive 3-way merge tool before
566 launching external tool. Options are ``true``, ``false``, or ``keep``
566 launching external tool. Options are ``true``, ``false``, or ``keep``
567 to leave markers in the file if the premerge fails.
567 to leave markers in the file if the premerge fails.
568 Default: True
568 Default: True
569
569
570 ``binary``
570 ``binary``
571 This tool can merge binary files. Defaults to False, unless tool
571 This tool can merge binary files. Defaults to False, unless tool
572 was selected by file pattern match.
572 was selected by file pattern match.
573
573
574 ``symlink``
574 ``symlink``
575 This tool can merge symlinks. Defaults to False, even if tool was
575 This tool can merge symlinks. Defaults to False, even if tool was
576 selected by file pattern match.
576 selected by file pattern match.
577
577
578 ``check``
578 ``check``
579 A list of merge success-checking options:
579 A list of merge success-checking options:
580
580
581 ``changed``
581 ``changed``
582 Ask whether merge was successful when the merged file shows no changes.
582 Ask whether merge was successful when the merged file shows no changes.
583 ``conflicts``
583 ``conflicts``
584 Check whether there are conflicts even though the tool reported success.
584 Check whether there are conflicts even though the tool reported success.
585 ``prompt``
585 ``prompt``
586 Always prompt for merge success, regardless of success reported by tool.
586 Always prompt for merge success, regardless of success reported by tool.
587
587
588 ``checkchanged``
588 ``checkchanged``
589 True is equivalent to ``check = changed``.
589 True is equivalent to ``check = changed``.
590 Default: False
590 Default: False
591
591
592 ``checkconflicts``
592 ``checkconflicts``
593 True is equivalent to ``check = conflicts``.
593 True is equivalent to ``check = conflicts``.
594 Default: False
594 Default: False
595
595
596 ``fixeol``
596 ``fixeol``
597 Attempt to fix up EOL changes caused by the merge tool.
597 Attempt to fix up EOL changes caused by the merge tool.
598 Default: False
598 Default: False
599
599
600 ``gui``
600 ``gui``
601 This tool requires a graphical interface to run. Default: False
601 This tool requires a graphical interface to run. Default: False
602
602
603 ``regkey``
603 ``regkey``
604 Windows registry key which describes install location of this
604 Windows registry key which describes install location of this
605 tool. Mercurial will search for this key first under
605 tool. Mercurial will search for this key first under
606 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
606 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
607 Default: None
607 Default: None
608
608
609 ``regkeyalt``
609 ``regkeyalt``
610 An alternate Windows registry key to try if the first key is not
610 An alternate Windows registry key to try if the first key is not
611 found. The alternate key uses the same ``regname`` and ``regappend``
611 found. The alternate key uses the same ``regname`` and ``regappend``
612 semantics of the primary key. The most common use for this key
612 semantics of the primary key. The most common use for this key
613 is to search for 32bit applications on 64bit operating systems.
613 is to search for 32bit applications on 64bit operating systems.
614 Default: None
614 Default: None
615
615
616 ``regname``
616 ``regname``
617 Name of value to read from specified registry key. Defaults to the
617 Name of value to read from specified registry key. Defaults to the
618 unnamed (default) value.
618 unnamed (default) value.
619
619
620 ``regappend``
620 ``regappend``
621 String to append to the value read from the registry, typically
621 String to append to the value read from the registry, typically
622 the executable name of the tool.
622 the executable name of the tool.
623 Default: None
623 Default: None
624
624
625
625
626 ``hooks``
626 ``hooks``
627 """""""""
627 """""""""
628
628
629 Commands or Python functions that get automatically executed by
629 Commands or Python functions that get automatically executed by
630 various actions such as starting or finishing a commit. Multiple
630 various actions such as starting or finishing a commit. Multiple
631 hooks can be run for the same action by appending a suffix to the
631 hooks can be run for the same action by appending a suffix to the
632 action. Overriding a site-wide hook can be done by changing its
632 action. Overriding a site-wide hook can be done by changing its
633 value or setting it to an empty string.
633 value or setting it to an empty string.
634
634
635 Example ``.hg/hgrc``::
635 Example ``.hg/hgrc``::
636
636
637 [hooks]
637 [hooks]
638 # update working directory after adding changesets
638 # update working directory after adding changesets
639 changegroup.update = hg update
639 changegroup.update = hg update
640 # do not use the site-wide hook
640 # do not use the site-wide hook
641 incoming =
641 incoming =
642 incoming.email = /my/email/hook
642 incoming.email = /my/email/hook
643 incoming.autobuild = /my/build/hook
643 incoming.autobuild = /my/build/hook
644
644
645 Most hooks are run with environment variables set that give useful
645 Most hooks are run with environment variables set that give useful
646 additional information. For each hook below, the environment
646 additional information. For each hook below, the environment
647 variables it is passed are listed with names of the form ``$HG_foo``.
647 variables it is passed are listed with names of the form ``$HG_foo``.
648
648
649 ``changegroup``
649 ``changegroup``
650 Run after a changegroup has been added via push, pull or unbundle.
650 Run after a changegroup has been added via push, pull or unbundle.
651 ID of the first new changeset is in ``$HG_NODE``. URL from which
651 ID of the first new changeset is in ``$HG_NODE``. URL from which
652 changes came is in ``$HG_URL``.
652 changes came is in ``$HG_URL``.
653
653
654 ``commit``
654 ``commit``
655 Run after a changeset has been created in the local repository. ID
655 Run after a changeset has been created in the local repository. ID
656 of the newly created changeset is in ``$HG_NODE``. Parent changeset
656 of the newly created changeset is in ``$HG_NODE``. Parent changeset
657 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
657 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
658
658
659 ``incoming``
659 ``incoming``
660 Run after a changeset has been pulled, pushed, or unbundled into
660 Run after a changeset has been pulled, pushed, or unbundled into
661 the local repository. The ID of the newly arrived changeset is in
661 the local repository. The ID of the newly arrived changeset is in
662 ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
662 ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
663
663
664 ``outgoing``
664 ``outgoing``
665 Run after sending changes from local repository to another. ID of
665 Run after sending changes from local repository to another. ID of
666 first changeset sent is in ``$HG_NODE``. Source of operation is in
666 first changeset sent is in ``$HG_NODE``. Source of operation is in
667 ``$HG_SOURCE``; see "preoutgoing" hook for description.
667 ``$HG_SOURCE``; see "preoutgoing" hook for description.
668
668
669 ``post-<command>``
669 ``post-<command>``
670 Run after successful invocations of the associated command. The
670 Run after successful invocations of the associated command. The
671 contents of the command line are passed as ``$HG_ARGS`` and the result
671 contents of the command line are passed as ``$HG_ARGS`` and the result
672 code in ``$HG_RESULT``. Parsed command line arguments are passed as
672 code in ``$HG_RESULT``. Parsed command line arguments are passed as
673 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
673 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
674 the python data internally passed to <command>. ``$HG_OPTS`` is a
674 the python data internally passed to <command>. ``$HG_OPTS`` is a
675 dictionary of options (with unspecified options set to their defaults).
675 dictionary of options (with unspecified options set to their defaults).
676 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
676 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
677
677
678 ``pre-<command>``
678 ``pre-<command>``
679 Run before executing the associated command. The contents of the
679 Run before executing the associated command. The contents of the
680 command line are passed as ``$HG_ARGS``. Parsed command line arguments
680 command line are passed as ``$HG_ARGS``. Parsed command line arguments
681 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
681 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
682 representations of the data internally passed to <command>. ``$HG_OPTS``
682 representations of the data internally passed to <command>. ``$HG_OPTS``
683 is a dictionary of options (with unspecified options set to their
683 is a dictionary of options (with unspecified options set to their
684 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
684 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
685 failure, the command doesn't execute and Mercurial returns the failure
685 failure, the command doesn't execute and Mercurial returns the failure
686 code.
686 code.
687
687
688 ``prechangegroup``
688 ``prechangegroup``
689 Run before a changegroup is added via push, pull or unbundle. Exit
689 Run before a changegroup is added via push, pull or unbundle. Exit
690 status 0 allows the changegroup to proceed. Non-zero status will
690 status 0 allows the changegroup to proceed. Non-zero status will
691 cause the push, pull or unbundle to fail. URL from which changes
691 cause the push, pull or unbundle to fail. URL from which changes
692 will come is in ``$HG_URL``.
692 will come is in ``$HG_URL``.
693
693
694 ``precommit``
694 ``precommit``
695 Run before starting a local commit. Exit status 0 allows the
695 Run before starting a local commit. Exit status 0 allows the
696 commit to proceed. Non-zero status will cause the commit to fail.
696 commit to proceed. Non-zero status will cause the commit to fail.
697 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
697 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
698
698
699 ``prelistkeys``
699 ``prelistkeys``
700 Run before listing pushkeys (like bookmarks) in the
700 Run before listing pushkeys (like bookmarks) in the
701 repository. Non-zero status will cause failure. The key namespace is
701 repository. Non-zero status will cause failure. The key namespace is
702 in ``$HG_NAMESPACE``.
702 in ``$HG_NAMESPACE``.
703
703
704 ``preoutgoing``
704 ``preoutgoing``
705 Run before collecting changes to send from the local repository to
705 Run before collecting changes to send from the local repository to
706 another. Non-zero status will cause failure. This lets you prevent
706 another. Non-zero status will cause failure. This lets you prevent
707 pull over HTTP or SSH. Also prevents against local pull, push
707 pull over HTTP or SSH. Also prevents against local pull, push
708 (outbound) or bundle commands, but not effective, since you can
708 (outbound) or bundle commands, but not effective, since you can
709 just copy files instead then. Source of operation is in
709 just copy files instead then. Source of operation is in
710 ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
710 ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
711 SSH or HTTP repository. If "push", "pull" or "bundle", operation
711 SSH or HTTP repository. If "push", "pull" or "bundle", operation
712 is happening on behalf of repository on same system.
712 is happening on behalf of repository on same system.
713
713
714 ``prepushkey``
714 ``prepushkey``
715 Run before a pushkey (like a bookmark) is added to the
715 Run before a pushkey (like a bookmark) is added to the
716 repository. Non-zero status will cause the key to be rejected. The
716 repository. Non-zero status will cause the key to be rejected. The
717 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
717 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
718 the old value (if any) is in ``$HG_OLD``, and the new value is in
718 the old value (if any) is in ``$HG_OLD``, and the new value is in
719 ``$HG_NEW``.
719 ``$HG_NEW``.
720
720
721 ``pretag``
721 ``pretag``
722 Run before creating a tag. Exit status 0 allows the tag to be
722 Run before creating a tag. Exit status 0 allows the tag to be
723 created. Non-zero status will cause the tag to fail. ID of
723 created. Non-zero status will cause the tag to fail. ID of
724 changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
724 changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
725 local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
725 local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
726
726
727 ``pretxnchangegroup``
727 ``pretxnchangegroup``
728 Run after a changegroup has been added via push, pull or unbundle,
728 Run after a changegroup has been added via push, pull or unbundle,
729 but before the transaction has been committed. Changegroup is
729 but before the transaction has been committed. Changegroup is
730 visible to hook program. This lets you validate incoming changes
730 visible to hook program. This lets you validate incoming changes
731 before accepting them. Passed the ID of the first new changeset in
731 before accepting them. Passed the ID of the first new changeset in
732 ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
732 ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
733 status will cause the transaction to be rolled back and the push,
733 status will cause the transaction to be rolled back and the push,
734 pull or unbundle will fail. URL that was source of changes is in
734 pull or unbundle will fail. URL that was source of changes is in
735 ``$HG_URL``.
735 ``$HG_URL``.
736
736
737 ``pretxncommit``
737 ``pretxncommit``
738 Run after a changeset has been created but the transaction not yet
738 Run after a changeset has been created but the transaction not yet
739 committed. Changeset is visible to hook program. This lets you
739 committed. Changeset is visible to hook program. This lets you
740 validate commit message and changes. Exit status 0 allows the
740 validate commit message and changes. Exit status 0 allows the
741 commit to proceed. Non-zero status will cause the transaction to
741 commit to proceed. Non-zero status will cause the transaction to
742 be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
742 be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
743 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
743 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
744
744
745 ``preupdate``
745 ``preupdate``
746 Run before updating the working directory. Exit status 0 allows
746 Run before updating the working directory. Exit status 0 allows
747 the update to proceed. Non-zero status will prevent the update.
747 the update to proceed. Non-zero status will prevent the update.
748 Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
748 Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
749 of second new parent is in ``$HG_PARENT2``.
749 of second new parent is in ``$HG_PARENT2``.
750
750
751 ``listkeys``
751 ``listkeys``
752 Run after listing pushkeys (like bookmarks) in the repository. The
752 Run after listing pushkeys (like bookmarks) in the repository. The
753 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
753 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
754 dictionary containing the keys and values.
754 dictionary containing the keys and values.
755
755
756 ``pushkey``
756 ``pushkey``
757 Run after a pushkey (like a bookmark) is added to the
757 Run after a pushkey (like a bookmark) is added to the
758 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
758 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
759 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
759 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
760 value is in ``$HG_NEW``.
760 value is in ``$HG_NEW``.
761
761
762 ``tag``
762 ``tag``
763 Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
763 Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
764 Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
764 Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
765 repository if ``$HG_LOCAL=0``.
765 repository if ``$HG_LOCAL=0``.
766
766
767 ``update``
767 ``update``
768 Run after updating the working directory. Changeset ID of first
768 Run after updating the working directory. Changeset ID of first
769 new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
769 new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
770 in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
770 in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
771 update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
771 update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
772
772
773 .. note:: It is generally better to use standard hooks rather than the
773 .. note:: It is generally better to use standard hooks rather than the
774 generic pre- and post- command hooks as they are guaranteed to be
774 generic pre- and post- command hooks as they are guaranteed to be
775 called in the appropriate contexts for influencing transactions.
775 called in the appropriate contexts for influencing transactions.
776 Also, hooks like "commit" will be called in all contexts that
776 Also, hooks like "commit" will be called in all contexts that
777 generate a commit (e.g. tag) and not just the commit command.
777 generate a commit (e.g. tag) and not just the commit command.
778
778
779 .. note:: Environment variables with empty values may not be passed to
779 .. note:: Environment variables with empty values may not be passed to
780 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
780 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
781 will have an empty value under Unix-like platforms for non-merge
781 will have an empty value under Unix-like platforms for non-merge
782 changesets, while it will not be available at all under Windows.
782 changesets, while it will not be available at all under Windows.
783
783
784 The syntax for Python hooks is as follows::
784 The syntax for Python hooks is as follows::
785
785
786 hookname = python:modulename.submodule.callable
786 hookname = python:modulename.submodule.callable
787 hookname = python:/path/to/python/module.py:callable
787 hookname = python:/path/to/python/module.py:callable
788
788
789 Python hooks are run within the Mercurial process. Each hook is
789 Python hooks are run within the Mercurial process. Each hook is
790 called with at least three keyword arguments: a ui object (keyword
790 called with at least three keyword arguments: a ui object (keyword
791 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
791 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
792 keyword that tells what kind of hook is used. Arguments listed as
792 keyword that tells what kind of hook is used. Arguments listed as
793 environment variables above are passed as keyword arguments, with no
793 environment variables above are passed as keyword arguments, with no
794 ``HG_`` prefix, and names in lower case.
794 ``HG_`` prefix, and names in lower case.
795
795
796 If a Python hook returns a "true" value or raises an exception, this
796 If a Python hook returns a "true" value or raises an exception, this
797 is treated as a failure.
797 is treated as a failure.
798
798
799
799
800 ``http_proxy``
800 ``http_proxy``
801 """"""""""""""
801 """"""""""""""
802
802
803 Used to access web-based Mercurial repositories through a HTTP
803 Used to access web-based Mercurial repositories through a HTTP
804 proxy.
804 proxy.
805
805
806 ``host``
806 ``host``
807 Host name and (optional) port of the proxy server, for example
807 Host name and (optional) port of the proxy server, for example
808 "myproxy:8000".
808 "myproxy:8000".
809
809
810 ``no``
810 ``no``
811 Optional. Comma-separated list of host names that should bypass
811 Optional. Comma-separated list of host names that should bypass
812 the proxy.
812 the proxy.
813
813
814 ``passwd``
814 ``passwd``
815 Optional. Password to authenticate with at the proxy server.
815 Optional. Password to authenticate with at the proxy server.
816
816
817 ``user``
817 ``user``
818 Optional. User name to authenticate with at the proxy server.
818 Optional. User name to authenticate with at the proxy server.
819
819
820 ``always``
820 ``always``
821 Optional. Always use the proxy, even for localhost and any entries
821 Optional. Always use the proxy, even for localhost and any entries
822 in ``http_proxy.no``. True or False. Default: False.
822 in ``http_proxy.no``. True or False. Default: False.
823
823
824 ``smtp``
824 ``smtp``
825 """"""""
825 """"""""
826
826
827 Configuration for extensions that need to send email messages.
827 Configuration for extensions that need to send email messages.
828
828
829 ``host``
829 ``host``
830 Host name of mail server, e.g. "mail.example.com".
830 Host name of mail server, e.g. "mail.example.com".
831
831
832 ``port``
832 ``port``
833 Optional. Port to connect to on mail server. Default: 25.
833 Optional. Port to connect to on mail server. Default: 25.
834
834
835 ``tls``
835 ``tls``
836 Optional. Method to enable TLS when connecting to mail server: starttls,
836 Optional. Method to enable TLS when connecting to mail server: starttls,
837 smtps or none. Default: none.
837 smtps or none. Default: none.
838
838
839 ``username``
839 ``username``
840 Optional. User name for authenticating with the SMTP server.
840 Optional. User name for authenticating with the SMTP server.
841 Default: none.
841 Default: none.
842
842
843 ``password``
843 ``password``
844 Optional. Password for authenticating with the SMTP server. If not
844 Optional. Password for authenticating with the SMTP server. If not
845 specified, interactive sessions will prompt the user for a
845 specified, interactive sessions will prompt the user for a
846 password; non-interactive sessions will fail. Default: none.
846 password; non-interactive sessions will fail. Default: none.
847
847
848 ``local_hostname``
848 ``local_hostname``
849 Optional. It's the hostname that the sender can use to identify
849 Optional. It's the hostname that the sender can use to identify
850 itself to the MTA.
850 itself to the MTA.
851
851
852
852
853 ``patch``
853 ``patch``
854 """""""""
854 """""""""
855
855
856 Settings used when applying patches, for instance through the 'import'
856 Settings used when applying patches, for instance through the 'import'
857 command or with Mercurial Queues extension.
857 command or with Mercurial Queues extension.
858
858
859 ``eol``
859 ``eol``
860 When set to 'strict' patch content and patched files end of lines
860 When set to 'strict' patch content and patched files end of lines
861 are preserved. When set to ``lf`` or ``crlf``, both files end of
861 are preserved. When set to ``lf`` or ``crlf``, both files end of
862 lines are ignored when patching and the result line endings are
862 lines are ignored when patching and the result line endings are
863 normalized to either LF (Unix) or CRLF (Windows). When set to
863 normalized to either LF (Unix) or CRLF (Windows). When set to
864 ``auto``, end of lines are again ignored while patching but line
864 ``auto``, end of lines are again ignored while patching but line
865 endings in patched files are normalized to their original setting
865 endings in patched files are normalized to their original setting
866 on a per-file basis. If target file does not exist or has no end
866 on a per-file basis. If target file does not exist or has no end
867 of line, patch line endings are preserved.
867 of line, patch line endings are preserved.
868 Default: strict.
868 Default: strict.
869
869
870
870
871 ``paths``
871 ``paths``
872 """""""""
872 """""""""
873
873
874 Assigns symbolic names to repositories. The left side is the
874 Assigns symbolic names to repositories. The left side is the
875 symbolic name, and the right gives the directory or URL that is the
875 symbolic name, and the right gives the directory or URL that is the
876 location of the repository. Default paths can be declared by setting
876 location of the repository. Default paths can be declared by setting
877 the following entries.
877 the following entries.
878
878
879 ``default``
879 ``default``
880 Directory or URL to use when pulling if no source is specified.
880 Directory or URL to use when pulling if no source is specified.
881 Default is set to repository from which the current repository was
881 Default is set to repository from which the current repository was
882 cloned.
882 cloned.
883
883
884 ``default-push``
884 ``default-push``
885 Optional. Directory or URL to use when pushing if no destination
885 Optional. Directory or URL to use when pushing if no destination
886 is specified.
886 is specified.
887
887
888
888
889 ``profiling``
889 ``profiling``
890 """""""""""""
890 """""""""""""
891
891
892 Specifies profiling format and file output. In this section
892 Specifies profiling format and file output. In this section
893 description, 'profiling data' stands for the raw data collected
893 description, 'profiling data' stands for the raw data collected
894 during profiling, while 'profiling report' stands for a statistical
894 during profiling, while 'profiling report' stands for a statistical
895 text report generated from the profiling data. The profiling is done
895 text report generated from the profiling data. The profiling is done
896 using lsprof.
896 using lsprof.
897
897
898 ``format``
898 ``format``
899 Profiling format.
899 Profiling format.
900 Default: text.
900 Default: text.
901
901
902 ``text``
902 ``text``
903 Generate a profiling report. When saving to a file, it should be
903 Generate a profiling report. When saving to a file, it should be
904 noted that only the report is saved, and the profiling data is
904 noted that only the report is saved, and the profiling data is
905 not kept.
905 not kept.
906 ``kcachegrind``
906 ``kcachegrind``
907 Format profiling data for kcachegrind use: when saving to a
907 Format profiling data for kcachegrind use: when saving to a
908 file, the generated file can directly be loaded into
908 file, the generated file can directly be loaded into
909 kcachegrind.
909 kcachegrind.
910
910
911 ``output``
911 ``output``
912 File path where profiling data or report should be saved. If the
912 File path where profiling data or report should be saved. If the
913 file exists, it is replaced. Default: None, data is printed on
913 file exists, it is replaced. Default: None, data is printed on
914 stderr
914 stderr
915
915
916 ``revsetalias``
916 ``revsetalias``
917 """""""""""""""
917 """""""""""""""
918
918
919 Alias definitions for revsets. See :hg:`help revsets` for details.
919 Alias definitions for revsets. See :hg:`help revsets` for details.
920
920
921 ``server``
921 ``server``
922 """"""""""
922 """"""""""
923
923
924 Controls generic server settings.
924 Controls generic server settings.
925
925
926 ``uncompressed``
926 ``uncompressed``
927 Whether to allow clients to clone a repository using the
927 Whether to allow clients to clone a repository using the
928 uncompressed streaming protocol. This transfers about 40% more
928 uncompressed streaming protocol. This transfers about 40% more
929 data than a regular clone, but uses less memory and CPU on both
929 data than a regular clone, but uses less memory and CPU on both
930 server and client. Over a LAN (100 Mbps or better) or a very fast
930 server and client. Over a LAN (100 Mbps or better) or a very fast
931 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
931 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
932 regular clone. Over most WAN connections (anything slower than
932 regular clone. Over most WAN connections (anything slower than
933 about 6 Mbps), uncompressed streaming is slower, because of the
933 about 6 Mbps), uncompressed streaming is slower, because of the
934 extra data transfer overhead. This mode will also temporarily hold
934 extra data transfer overhead. This mode will also temporarily hold
935 the write lock while determining what data to transfer.
935 the write lock while determining what data to transfer.
936 Default is True.
936 Default is True.
937
937
938 ``validate``
938 ``validate``
939 Whether to validate the completeness of pushed changesets by
939 Whether to validate the completeness of pushed changesets by
940 checking that all new file revisions specified in manifests are
940 checking that all new file revisions specified in manifests are
941 present. Default is False.
941 present. Default is False.
942
942
943 ``subpaths``
943 ``subpaths``
944 """"""""""""
944 """"""""""""
945
945
946 Defines subrepositories source locations rewriting rules of the form::
946 Defines subrepositories source locations rewriting rules of the form::
947
947
948 <pattern> = <replacement>
948 <pattern> = <replacement>
949
949
950 Where ``pattern`` is a regular expression matching the source and
950 Where ``pattern`` is a regular expression matching the source and
951 ``replacement`` is the replacement string used to rewrite it. Groups
951 ``replacement`` is the replacement string used to rewrite it. Groups
952 can be matched in ``pattern`` and referenced in ``replacements``. For
952 can be matched in ``pattern`` and referenced in ``replacements``. For
953 instance::
953 instance::
954
954
955 http://server/(.*)-hg/ = http://hg.server/\1/
955 http://server/(.*)-hg/ = http://hg.server/\1/
956
956
957 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
957 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
958
958
959 All patterns are applied in definition order.
959 All patterns are applied in definition order.
960
960
961 ``trusted``
961 ``trusted``
962 """""""""""
962 """""""""""
963
963
964 Mercurial will not use the settings in the
964 Mercurial will not use the settings in the
965 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
965 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
966 user or to a trusted group, as various hgrc features allow arbitrary
966 user or to a trusted group, as various hgrc features allow arbitrary
967 commands to be run. This issue is often encountered when configuring
967 commands to be run. This issue is often encountered when configuring
968 hooks or extensions for shared repositories or servers. However,
968 hooks or extensions for shared repositories or servers. However,
969 the web interface will use some safe settings from the ``[web]``
969 the web interface will use some safe settings from the ``[web]``
970 section.
970 section.
971
971
972 This section specifies what users and groups are trusted. The
972 This section specifies what users and groups are trusted. The
973 current user is always trusted. To trust everybody, list a user or a
973 current user is always trusted. To trust everybody, list a user or a
974 group with name ``*``. These settings must be placed in an
974 group with name ``*``. These settings must be placed in an
975 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
975 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
976 user or service running Mercurial.
976 user or service running Mercurial.
977
977
978 ``users``
978 ``users``
979 Comma-separated list of trusted users.
979 Comma-separated list of trusted users.
980
980
981 ``groups``
981 ``groups``
982 Comma-separated list of trusted groups.
982 Comma-separated list of trusted groups.
983
983
984
984
985 ``ui``
985 ``ui``
986 """"""
986 """"""
987
987
988 User interface controls.
988 User interface controls.
989
989
990 ``archivemeta``
990 ``archivemeta``
991 Whether to include the .hg_archival.txt file containing meta data
991 Whether to include the .hg_archival.txt file containing meta data
992 (hashes for the repository base and for tip) in archives created
992 (hashes for the repository base and for tip) in archives created
993 by the :hg:`archive` command or downloaded via hgweb.
993 by the :hg:`archive` command or downloaded via hgweb.
994 Default is True.
994 Default is True.
995
995
996 ``askusername``
996 ``askusername``
997 Whether to prompt for a username when committing. If True, and
997 Whether to prompt for a username when committing. If True, and
998 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
998 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
999 be prompted to enter a username. If no username is entered, the
999 be prompted to enter a username. If no username is entered, the
1000 default ``USER@HOST`` is used instead.
1000 default ``USER@HOST`` is used instead.
1001 Default is False.
1001 Default is False.
1002
1002
1003 ``commitsubrepos``
1003 ``commitsubrepos``
1004 Whether to commit modified subrepositories when committing the
1004 Whether to commit modified subrepositories when committing the
1005 parent repository. If False and one subrepository has uncommitted
1005 parent repository. If False and one subrepository has uncommitted
1006 changes, abort the commit.
1006 changes, abort the commit.
1007 Default is True.
1007 Default is True.
1008
1008
1009 ``debug``
1009 ``debug``
1010 Print debugging information. True or False. Default is False.
1010 Print debugging information. True or False. Default is False.
1011
1011
1012 ``editor``
1012 ``editor``
1013 The editor to use during a commit. Default is ``$EDITOR`` or ``vi``.
1013 The editor to use during a commit. Default is ``$EDITOR`` or ``vi``.
1014
1014
1015 ``fallbackencoding``
1015 ``fallbackencoding``
1016 Encoding to try if it's not possible to decode the changelog using
1016 Encoding to try if it's not possible to decode the changelog using
1017 UTF-8. Default is ISO-8859-1.
1017 UTF-8. Default is ISO-8859-1.
1018
1018
1019 ``ignore``
1019 ``ignore``
1020 A file to read per-user ignore patterns from. This file should be
1020 A file to read per-user ignore patterns from. This file should be
1021 in the same format as a repository-wide .hgignore file. This
1021 in the same format as a repository-wide .hgignore file. This
1022 option supports hook syntax, so if you want to specify multiple
1022 option supports hook syntax, so if you want to specify multiple
1023 ignore files, you can do so by setting something like
1023 ignore files, you can do so by setting something like
1024 ``ignore.other = ~/.hgignore2``. For details of the ignore file
1024 ``ignore.other = ~/.hgignore2``. For details of the ignore file
1025 format, see the ``hgignore(5)`` man page.
1025 format, see the ``hgignore(5)`` man page.
1026
1026
1027 ``interactive``
1027 ``interactive``
1028 Allow to prompt the user. True or False. Default is True.
1028 Allow to prompt the user. True or False. Default is True.
1029
1029
1030 ``logtemplate``
1030 ``logtemplate``
1031 Template string for commands that print changesets.
1031 Template string for commands that print changesets.
1032
1032
1033 ``merge``
1033 ``merge``
1034 The conflict resolution program to use during a manual merge.
1034 The conflict resolution program to use during a manual merge.
1035 For more information on merge tools see :hg:`help merge-tools`.
1035 For more information on merge tools see :hg:`help merge-tools`.
1036 For configuring merge tools see the ``[merge-tools]`` section.
1036 For configuring merge tools see the ``[merge-tools]`` section.
1037
1037
1038 ``portablefilenames``
1038 ``portablefilenames``
1039 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
1039 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
1040 Default is ``warn``.
1040 Default is ``warn``.
1041 If set to ``warn`` (or ``true``), a warning message is printed on POSIX
1041 If set to ``warn`` (or ``true``), a warning message is printed on POSIX
1042 platforms, if a file with a non-portable filename is added (e.g. a file
1042 platforms, if a file with a non-portable filename is added (e.g. a file
1043 with a name that can't be created on Windows because it contains reserved
1043 with a name that can't be created on Windows because it contains reserved
1044 parts like ``AUX``, reserved characters like ``:``, or would cause a case
1044 parts like ``AUX``, reserved characters like ``:``, or would cause a case
1045 collision with an existing file).
1045 collision with an existing file).
1046 If set to ``ignore`` (or ``false``), no warning is printed.
1046 If set to ``ignore`` (or ``false``), no warning is printed.
1047 If set to ``abort``, the command is aborted.
1047 If set to ``abort``, the command is aborted.
1048 On Windows, this configuration option is ignored and the command aborted.
1048 On Windows, this configuration option is ignored and the command aborted.
1049
1049
1050 ``quiet``
1050 ``quiet``
1051 Reduce the amount of output printed. True or False. Default is False.
1051 Reduce the amount of output printed. True or False. Default is False.
1052
1052
1053 ``remotecmd``
1053 ``remotecmd``
1054 remote command to use for clone/push/pull operations. Default is ``hg``.
1054 remote command to use for clone/push/pull operations. Default is ``hg``.
1055
1055
1056 ``report_untrusted``
1056 ``report_untrusted``
1057 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
1057 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
1058 trusted user or group. True or False. Default is True.
1058 trusted user or group. True or False. Default is True.
1059
1059
1060 ``slash``
1060 ``slash``
1061 Display paths using a slash (``/``) as the path separator. This
1061 Display paths using a slash (``/``) as the path separator. This
1062 only makes a difference on systems where the default path
1062 only makes a difference on systems where the default path
1063 separator is not the slash character (e.g. Windows uses the
1063 separator is not the slash character (e.g. Windows uses the
1064 backslash character (``\``)).
1064 backslash character (``\``)).
1065 Default is False.
1065 Default is False.
1066
1066
1067 ``ssh``
1067 ``ssh``
1068 command to use for SSH connections. Default is ``ssh``.
1068 command to use for SSH connections. Default is ``ssh``.
1069
1069
1070 ``strict``
1070 ``strict``
1071 Require exact command names, instead of allowing unambiguous
1071 Require exact command names, instead of allowing unambiguous
1072 abbreviations. True or False. Default is False.
1072 abbreviations. True or False. Default is False.
1073
1073
1074 ``style``
1074 ``style``
1075 Name of style to use for command output.
1075 Name of style to use for command output.
1076
1076
1077 ``timeout``
1077 ``timeout``
1078 The timeout used when a lock is held (in seconds), a negative value
1078 The timeout used when a lock is held (in seconds), a negative value
1079 means no timeout. Default is 600.
1079 means no timeout. Default is 600.
1080
1080
1081 ``traceback``
1081 ``traceback``
1082 Mercurial always prints a traceback when an unknown exception
1082 Mercurial always prints a traceback when an unknown exception
1083 occurs. Setting this to True will make Mercurial print a traceback
1083 occurs. Setting this to True will make Mercurial print a traceback
1084 on all exceptions, even those recognized by Mercurial (such as
1084 on all exceptions, even those recognized by Mercurial (such as
1085 IOError or MemoryError). Default is False.
1085 IOError or MemoryError). Default is False.
1086
1086
1087 ``username``
1087 ``username``
1088 The committer of a changeset created when running "commit".
1088 The committer of a changeset created when running "commit".
1089 Typically a person's name and email address, e.g. ``Fred Widget
1089 Typically a person's name and email address, e.g. ``Fred Widget
1090 <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If
1090 <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If
1091 the username in hgrc is empty, it has to be specified manually or
1091 the username in hgrc is empty, it has to be specified manually or
1092 in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
1092 in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
1093 ``username =`` in the system hgrc). Environment variables in the
1093 ``username =`` in the system hgrc). Environment variables in the
1094 username are expanded.
1094 username are expanded.
1095
1095
1096 ``verbose``
1096 ``verbose``
1097 Increase the amount of output printed. True or False. Default is False.
1097 Increase the amount of output printed. True or False. Default is False.
1098
1098
1099
1099
1100 ``web``
1100 ``web``
1101 """""""
1101 """""""
1102
1102
1103 Web interface configuration. The settings in this section apply to
1103 Web interface configuration. The settings in this section apply to
1104 both the builtin webserver (started by :hg:`serve`) and the script you
1104 both the builtin webserver (started by :hg:`serve`) and the script you
1105 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
1105 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
1106 and WSGI).
1106 and WSGI).
1107
1107
1108 The Mercurial webserver does no authentication (it does not prompt for
1108 The Mercurial webserver does no authentication (it does not prompt for
1109 usernames and passwords to validate *who* users are), but it does do
1109 usernames and passwords to validate *who* users are), but it does do
1110 authorization (it grants or denies access for *authenticated users*
1110 authorization (it grants or denies access for *authenticated users*
1111 based on settings in this section). You must either configure your
1111 based on settings in this section). You must either configure your
1112 webserver to do authentication for you, or disable the authorization
1112 webserver to do authentication for you, or disable the authorization
1113 checks.
1113 checks.
1114
1114
1115 For a quick setup in a trusted environment, e.g., a private LAN, where
1115 For a quick setup in a trusted environment, e.g., a private LAN, where
1116 you want it to accept pushes from anybody, you can use the following
1116 you want it to accept pushes from anybody, you can use the following
1117 command line::
1117 command line::
1118
1118
1119 $ hg --config web.allow_push=* --config web.push_ssl=False serve
1119 $ hg --config web.allow_push=* --config web.push_ssl=False serve
1120
1120
1121 Note that this will allow anybody to push anything to the server and
1121 Note that this will allow anybody to push anything to the server and
1122 that this should not be used for public servers.
1122 that this should not be used for public servers.
1123
1123
1124 The full set of options is:
1124 The full set of options is:
1125
1125
1126 ``accesslog``
1126 ``accesslog``
1127 Where to output the access log. Default is stdout.
1127 Where to output the access log. Default is stdout.
1128
1128
1129 ``address``
1129 ``address``
1130 Interface address to bind to. Default is all.
1130 Interface address to bind to. Default is all.
1131
1131
1132 ``allow_archive``
1132 ``allow_archive``
1133 List of archive format (bz2, gz, zip) allowed for downloading.
1133 List of archive format (bz2, gz, zip) allowed for downloading.
1134 Default is empty.
1134 Default is empty.
1135
1135
1136 ``allowbz2``
1136 ``allowbz2``
1137 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
1137 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
1138 revisions.
1138 revisions.
1139 Default is False.
1139 Default is False.
1140
1140
1141 ``allowgz``
1141 ``allowgz``
1142 (DEPRECATED) Whether to allow .tar.gz downloading of repository
1142 (DEPRECATED) Whether to allow .tar.gz downloading of repository
1143 revisions.
1143 revisions.
1144 Default is False.
1144 Default is False.
1145
1145
1146 ``allowpull``
1146 ``allowpull``
1147 Whether to allow pulling from the repository. Default is True.
1147 Whether to allow pulling from the repository. Default is True.
1148
1148
1149 ``allow_push``
1149 ``allow_push``
1150 Whether to allow pushing to the repository. If empty or not set,
1150 Whether to allow pushing to the repository. If empty or not set,
1151 push is not allowed. If the special value ``*``, any remote user can
1151 push is not allowed. If the special value ``*``, any remote user can
1152 push, including unauthenticated users. Otherwise, the remote user
1152 push, including unauthenticated users. Otherwise, the remote user
1153 must have been authenticated, and the authenticated user name must
1153 must have been authenticated, and the authenticated user name must
1154 be present in this list. The contents of the allow_push list are
1154 be present in this list. The contents of the allow_push list are
1155 examined after the deny_push list.
1155 examined after the deny_push list.
1156
1156
1157 ``guessmime``
1158 Control MIME types for raw download of file content.
1159 Set to True to let hgweb guess the content type from the file
1160 extension. This will serve HTML files as ``text/html`` and might
1161 allow cross-site scripting attacks when serving untrusted
1162 repositories. Default is False.
1163
1157 ``allow_read``
1164 ``allow_read``
1158 If the user has not already been denied repository access due to
1165 If the user has not already been denied repository access due to
1159 the contents of deny_read, this list determines whether to grant
1166 the contents of deny_read, this list determines whether to grant
1160 repository access to the user. If this list is not empty, and the
1167 repository access to the user. If this list is not empty, and the
1161 user is unauthenticated or not present in the list, then access is
1168 user is unauthenticated or not present in the list, then access is
1162 denied for the user. If the list is empty or not set, then access
1169 denied for the user. If the list is empty or not set, then access
1163 is permitted to all users by default. Setting allow_read to the
1170 is permitted to all users by default. Setting allow_read to the
1164 special value ``*`` is equivalent to it not being set (i.e. access
1171 special value ``*`` is equivalent to it not being set (i.e. access
1165 is permitted to all users). The contents of the allow_read list are
1172 is permitted to all users). The contents of the allow_read list are
1166 examined after the deny_read list.
1173 examined after the deny_read list.
1167
1174
1168 ``allowzip``
1175 ``allowzip``
1169 (DEPRECATED) Whether to allow .zip downloading of repository
1176 (DEPRECATED) Whether to allow .zip downloading of repository
1170 revisions. Default is False. This feature creates temporary files.
1177 revisions. Default is False. This feature creates temporary files.
1171
1178
1172 ``baseurl``
1179 ``baseurl``
1173 Base URL to use when publishing URLs in other locations, so
1180 Base URL to use when publishing URLs in other locations, so
1174 third-party tools like email notification hooks can construct
1181 third-party tools like email notification hooks can construct
1175 URLs. Example: ``http://hgserver/repos/``.
1182 URLs. Example: ``http://hgserver/repos/``.
1176
1183
1177 ``cacerts``
1184 ``cacerts``
1178 Path to file containing a list of PEM encoded certificate
1185 Path to file containing a list of PEM encoded certificate
1179 authority certificates. Environment variables and ``~user``
1186 authority certificates. Environment variables and ``~user``
1180 constructs are expanded in the filename. If specified on the
1187 constructs are expanded in the filename. If specified on the
1181 client, then it will verify the identity of remote HTTPS servers
1188 client, then it will verify the identity of remote HTTPS servers
1182 with these certificates. The form must be as follows::
1189 with these certificates. The form must be as follows::
1183
1190
1184 -----BEGIN CERTIFICATE-----
1191 -----BEGIN CERTIFICATE-----
1185 ... (certificate in base64 PEM encoding) ...
1192 ... (certificate in base64 PEM encoding) ...
1186 -----END CERTIFICATE-----
1193 -----END CERTIFICATE-----
1187 -----BEGIN CERTIFICATE-----
1194 -----BEGIN CERTIFICATE-----
1188 ... (certificate in base64 PEM encoding) ...
1195 ... (certificate in base64 PEM encoding) ...
1189 -----END CERTIFICATE-----
1196 -----END CERTIFICATE-----
1190
1197
1191 This feature is only supported when using Python 2.6 or later. If you wish
1198 This feature is only supported when using Python 2.6 or later. If you wish
1192 to use it with earlier versions of Python, install the backported
1199 to use it with earlier versions of Python, install the backported
1193 version of the ssl library that is available from
1200 version of the ssl library that is available from
1194 ``http://pypi.python.org``.
1201 ``http://pypi.python.org``.
1195
1202
1196 You can use OpenSSL's CA certificate file if your platform has one.
1203 You can use OpenSSL's CA certificate file if your platform has one.
1197 On most Linux systems this will be ``/etc/ssl/certs/ca-certificates.crt``.
1204 On most Linux systems this will be ``/etc/ssl/certs/ca-certificates.crt``.
1198 Otherwise you will have to generate this file manually.
1205 Otherwise you will have to generate this file manually.
1199
1206
1200 To disable SSL verification temporarily, specify ``--insecure`` from
1207 To disable SSL verification temporarily, specify ``--insecure`` from
1201 command line.
1208 command line.
1202
1209
1203 ``cache``
1210 ``cache``
1204 Whether to support caching in hgweb. Defaults to True.
1211 Whether to support caching in hgweb. Defaults to True.
1205
1212
1206 ``contact``
1213 ``contact``
1207 Name or email address of the person in charge of the repository.
1214 Name or email address of the person in charge of the repository.
1208 Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
1215 Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
1209
1216
1210 ``deny_push``
1217 ``deny_push``
1211 Whether to deny pushing to the repository. If empty or not set,
1218 Whether to deny pushing to the repository. If empty or not set,
1212 push is not denied. If the special value ``*``, all remote users are
1219 push is not denied. If the special value ``*``, all remote users are
1213 denied push. Otherwise, unauthenticated users are all denied, and
1220 denied push. Otherwise, unauthenticated users are all denied, and
1214 any authenticated user name present in this list is also denied. The
1221 any authenticated user name present in this list is also denied. The
1215 contents of the deny_push list are examined before the allow_push list.
1222 contents of the deny_push list are examined before the allow_push list.
1216
1223
1217 ``deny_read``
1224 ``deny_read``
1218 Whether to deny reading/viewing of the repository. If this list is
1225 Whether to deny reading/viewing of the repository. If this list is
1219 not empty, unauthenticated users are all denied, and any
1226 not empty, unauthenticated users are all denied, and any
1220 authenticated user name present in this list is also denied access to
1227 authenticated user name present in this list is also denied access to
1221 the repository. If set to the special value ``*``, all remote users
1228 the repository. If set to the special value ``*``, all remote users
1222 are denied access (rarely needed ;). If deny_read is empty or not set,
1229 are denied access (rarely needed ;). If deny_read is empty or not set,
1223 the determination of repository access depends on the presence and
1230 the determination of repository access depends on the presence and
1224 content of the allow_read list (see description). If both
1231 content of the allow_read list (see description). If both
1225 deny_read and allow_read are empty or not set, then access is
1232 deny_read and allow_read are empty or not set, then access is
1226 permitted to all users by default. If the repository is being
1233 permitted to all users by default. If the repository is being
1227 served via hgwebdir, denied users will not be able to see it in
1234 served via hgwebdir, denied users will not be able to see it in
1228 the list of repositories. The contents of the deny_read list have
1235 the list of repositories. The contents of the deny_read list have
1229 priority over (are examined before) the contents of the allow_read
1236 priority over (are examined before) the contents of the allow_read
1230 list.
1237 list.
1231
1238
1232 ``descend``
1239 ``descend``
1233 hgwebdir indexes will not descend into subdirectories. Only repositories
1240 hgwebdir indexes will not descend into subdirectories. Only repositories
1234 directly in the current path will be shown (other repositories are still
1241 directly in the current path will be shown (other repositories are still
1235 available from the index corresponding to their containing path).
1242 available from the index corresponding to their containing path).
1236
1243
1237 ``description``
1244 ``description``
1238 Textual description of the repository's purpose or contents.
1245 Textual description of the repository's purpose or contents.
1239 Default is "unknown".
1246 Default is "unknown".
1240
1247
1241 ``encoding``
1248 ``encoding``
1242 Character encoding name. Default is the current locale charset.
1249 Character encoding name. Default is the current locale charset.
1243 Example: "UTF-8"
1250 Example: "UTF-8"
1244
1251
1245 ``errorlog``
1252 ``errorlog``
1246 Where to output the error log. Default is stderr.
1253 Where to output the error log. Default is stderr.
1247
1254
1248 ``hidden``
1255 ``hidden``
1249 Whether to hide the repository in the hgwebdir index.
1256 Whether to hide the repository in the hgwebdir index.
1250 Default is False.
1257 Default is False.
1251
1258
1252 ``ipv6``
1259 ``ipv6``
1253 Whether to use IPv6. Default is False.
1260 Whether to use IPv6. Default is False.
1254
1261
1255 ``logourl``
1262 ``logourl``
1256 Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``
1263 Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``
1257 will be used.
1264 will be used.
1258
1265
1259 ``name``
1266 ``name``
1260 Repository name to use in the web interface. Default is current
1267 Repository name to use in the web interface. Default is current
1261 working directory.
1268 working directory.
1262
1269
1263 ``maxchanges``
1270 ``maxchanges``
1264 Maximum number of changes to list on the changelog. Default is 10.
1271 Maximum number of changes to list on the changelog. Default is 10.
1265
1272
1266 ``maxfiles``
1273 ``maxfiles``
1267 Maximum number of files to list per changeset. Default is 10.
1274 Maximum number of files to list per changeset. Default is 10.
1268
1275
1269 ``port``
1276 ``port``
1270 Port to listen on. Default is 8000.
1277 Port to listen on. Default is 8000.
1271
1278
1272 ``prefix``
1279 ``prefix``
1273 Prefix path to serve from. Default is '' (server root).
1280 Prefix path to serve from. Default is '' (server root).
1274
1281
1275 ``push_ssl``
1282 ``push_ssl``
1276 Whether to require that inbound pushes be transported over SSL to
1283 Whether to require that inbound pushes be transported over SSL to
1277 prevent password sniffing. Default is True.
1284 prevent password sniffing. Default is True.
1278
1285
1279 ``staticurl``
1286 ``staticurl``
1280 Base URL to use for static files. If unset, static files (e.g. the
1287 Base URL to use for static files. If unset, static files (e.g. the
1281 hgicon.png favicon) will be served by the CGI script itself. Use
1288 hgicon.png favicon) will be served by the CGI script itself. Use
1282 this setting to serve them directly with the HTTP server.
1289 this setting to serve them directly with the HTTP server.
1283 Example: ``http://hgserver/static/``.
1290 Example: ``http://hgserver/static/``.
1284
1291
1285 ``stripes``
1292 ``stripes``
1286 How many lines a "zebra stripe" should span in multiline output.
1293 How many lines a "zebra stripe" should span in multiline output.
1287 Default is 1; set to 0 to disable.
1294 Default is 1; set to 0 to disable.
1288
1295
1289 ``style``
1296 ``style``
1290 Which template map style to use.
1297 Which template map style to use.
1291
1298
1292 ``templates``
1299 ``templates``
1293 Where to find the HTML templates. Default is install path.
1300 Where to find the HTML templates. Default is install path.
@@ -1,838 +1,842
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import os, mimetypes, re, cgi, copy
8 import os, mimetypes, re, cgi, copy
9 import webutil
9 import webutil
10 from mercurial import error, encoding, archival, templater, templatefilters
10 from mercurial import error, encoding, archival, templater, templatefilters
11 from mercurial.node import short, hex
11 from mercurial.node import short, hex
12 from mercurial.util import binary
12 from mercurial.util import binary
13 from common import paritygen, staticfile, get_contact, ErrorResponse
13 from common import paritygen, staticfile, get_contact, ErrorResponse
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
15 from mercurial import graphmod
15 from mercurial import graphmod
16 from mercurial import help as helpmod
16 from mercurial import help as helpmod
17 from mercurial.i18n import _
17 from mercurial.i18n import _
18
18
19 # __all__ is populated with the allowed commands. Be sure to add to it if
19 # __all__ is populated with the allowed commands. Be sure to add to it if
20 # you're adding a new command, or the new command won't work.
20 # you're adding a new command, or the new command won't work.
21
21
22 __all__ = [
22 __all__ = [
23 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
23 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
24 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
24 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
25 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
25 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
26 ]
26 ]
27
27
28 def log(web, req, tmpl):
28 def log(web, req, tmpl):
29 if 'file' in req.form and req.form['file'][0]:
29 if 'file' in req.form and req.form['file'][0]:
30 return filelog(web, req, tmpl)
30 return filelog(web, req, tmpl)
31 else:
31 else:
32 return changelog(web, req, tmpl)
32 return changelog(web, req, tmpl)
33
33
34 def rawfile(web, req, tmpl):
34 def rawfile(web, req, tmpl):
35 guessmime = web.configbool('web', 'guessmime', False)
36
35 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
37 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
36 if not path:
38 if not path:
37 content = manifest(web, req, tmpl)
39 content = manifest(web, req, tmpl)
38 req.respond(HTTP_OK, web.ctype)
40 req.respond(HTTP_OK, web.ctype)
39 return content
41 return content
40
42
41 try:
43 try:
42 fctx = webutil.filectx(web.repo, req)
44 fctx = webutil.filectx(web.repo, req)
43 except error.LookupError, inst:
45 except error.LookupError, inst:
44 try:
46 try:
45 content = manifest(web, req, tmpl)
47 content = manifest(web, req, tmpl)
46 req.respond(HTTP_OK, web.ctype)
48 req.respond(HTTP_OK, web.ctype)
47 return content
49 return content
48 except ErrorResponse:
50 except ErrorResponse:
49 raise inst
51 raise inst
50
52
51 path = fctx.path()
53 path = fctx.path()
52 text = fctx.data()
54 text = fctx.data()
53 mt = mimetypes.guess_type(path)[0]
55 mt = 'application/binary'
54 if mt is None:
56 if guessmime:
55 mt = binary(text) and 'application/octet-stream' or 'text/plain'
57 mt = mimetypes.guess_type(path)[0]
58 if mt is None:
59 mt = binary(text) and 'application/binary' or 'text/plain'
56 if mt.startswith('text/'):
60 if mt.startswith('text/'):
57 mt += '; charset="%s"' % encoding.encoding
61 mt += '; charset="%s"' % encoding.encoding
58
62
59 req.respond(HTTP_OK, mt, path, len(text))
63 req.respond(HTTP_OK, mt, path, len(text))
60 return [text]
64 return [text]
61
65
62 def _filerevision(web, tmpl, fctx):
66 def _filerevision(web, tmpl, fctx):
63 f = fctx.path()
67 f = fctx.path()
64 text = fctx.data()
68 text = fctx.data()
65 parity = paritygen(web.stripecount)
69 parity = paritygen(web.stripecount)
66
70
67 if binary(text):
71 if binary(text):
68 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
72 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
69 text = '(binary:%s)' % mt
73 text = '(binary:%s)' % mt
70
74
71 def lines():
75 def lines():
72 for lineno, t in enumerate(text.splitlines(True)):
76 for lineno, t in enumerate(text.splitlines(True)):
73 yield {"line": t,
77 yield {"line": t,
74 "lineid": "l%d" % (lineno + 1),
78 "lineid": "l%d" % (lineno + 1),
75 "linenumber": "% 6d" % (lineno + 1),
79 "linenumber": "% 6d" % (lineno + 1),
76 "parity": parity.next()}
80 "parity": parity.next()}
77
81
78 return tmpl("filerevision",
82 return tmpl("filerevision",
79 file=f,
83 file=f,
80 path=webutil.up(f),
84 path=webutil.up(f),
81 text=lines(),
85 text=lines(),
82 rev=fctx.rev(),
86 rev=fctx.rev(),
83 node=fctx.hex(),
87 node=fctx.hex(),
84 author=fctx.user(),
88 author=fctx.user(),
85 date=fctx.date(),
89 date=fctx.date(),
86 desc=fctx.description(),
90 desc=fctx.description(),
87 branch=webutil.nodebranchnodefault(fctx),
91 branch=webutil.nodebranchnodefault(fctx),
88 parent=webutil.parents(fctx),
92 parent=webutil.parents(fctx),
89 child=webutil.children(fctx),
93 child=webutil.children(fctx),
90 rename=webutil.renamelink(fctx),
94 rename=webutil.renamelink(fctx),
91 permissions=fctx.manifest().flags(f))
95 permissions=fctx.manifest().flags(f))
92
96
93 def file(web, req, tmpl):
97 def file(web, req, tmpl):
94 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
98 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
95 if not path:
99 if not path:
96 return manifest(web, req, tmpl)
100 return manifest(web, req, tmpl)
97 try:
101 try:
98 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
102 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
99 except error.LookupError, inst:
103 except error.LookupError, inst:
100 try:
104 try:
101 return manifest(web, req, tmpl)
105 return manifest(web, req, tmpl)
102 except ErrorResponse:
106 except ErrorResponse:
103 raise inst
107 raise inst
104
108
105 def _search(web, req, tmpl):
109 def _search(web, req, tmpl):
106
110
107 query = req.form['rev'][0]
111 query = req.form['rev'][0]
108 revcount = web.maxchanges
112 revcount = web.maxchanges
109 if 'revcount' in req.form:
113 if 'revcount' in req.form:
110 revcount = int(req.form.get('revcount', [revcount])[0])
114 revcount = int(req.form.get('revcount', [revcount])[0])
111 revcount = max(revcount, 1)
115 revcount = max(revcount, 1)
112 tmpl.defaults['sessionvars']['revcount'] = revcount
116 tmpl.defaults['sessionvars']['revcount'] = revcount
113
117
114 lessvars = copy.copy(tmpl.defaults['sessionvars'])
118 lessvars = copy.copy(tmpl.defaults['sessionvars'])
115 lessvars['revcount'] = max(revcount / 2, 1)
119 lessvars['revcount'] = max(revcount / 2, 1)
116 lessvars['rev'] = query
120 lessvars['rev'] = query
117 morevars = copy.copy(tmpl.defaults['sessionvars'])
121 morevars = copy.copy(tmpl.defaults['sessionvars'])
118 morevars['revcount'] = revcount * 2
122 morevars['revcount'] = revcount * 2
119 morevars['rev'] = query
123 morevars['rev'] = query
120
124
121 def changelist(**map):
125 def changelist(**map):
122 count = 0
126 count = 0
123 qw = query.lower().split()
127 qw = query.lower().split()
124
128
125 def revgen():
129 def revgen():
126 for i in xrange(len(web.repo) - 1, 0, -100):
130 for i in xrange(len(web.repo) - 1, 0, -100):
127 l = []
131 l = []
128 for j in xrange(max(0, i - 100), i + 1):
132 for j in xrange(max(0, i - 100), i + 1):
129 ctx = web.repo[j]
133 ctx = web.repo[j]
130 l.append(ctx)
134 l.append(ctx)
131 l.reverse()
135 l.reverse()
132 for e in l:
136 for e in l:
133 yield e
137 yield e
134
138
135 for ctx in revgen():
139 for ctx in revgen():
136 miss = 0
140 miss = 0
137 for q in qw:
141 for q in qw:
138 if not (q in ctx.user().lower() or
142 if not (q in ctx.user().lower() or
139 q in ctx.description().lower() or
143 q in ctx.description().lower() or
140 q in " ".join(ctx.files()).lower()):
144 q in " ".join(ctx.files()).lower()):
141 miss = 1
145 miss = 1
142 break
146 break
143 if miss:
147 if miss:
144 continue
148 continue
145
149
146 count += 1
150 count += 1
147 n = ctx.node()
151 n = ctx.node()
148 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
152 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
149 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
153 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
150
154
151 yield tmpl('searchentry',
155 yield tmpl('searchentry',
152 parity=parity.next(),
156 parity=parity.next(),
153 author=ctx.user(),
157 author=ctx.user(),
154 parent=webutil.parents(ctx),
158 parent=webutil.parents(ctx),
155 child=webutil.children(ctx),
159 child=webutil.children(ctx),
156 changelogtag=showtags,
160 changelogtag=showtags,
157 desc=ctx.description(),
161 desc=ctx.description(),
158 date=ctx.date(),
162 date=ctx.date(),
159 files=files,
163 files=files,
160 rev=ctx.rev(),
164 rev=ctx.rev(),
161 node=hex(n),
165 node=hex(n),
162 tags=webutil.nodetagsdict(web.repo, n),
166 tags=webutil.nodetagsdict(web.repo, n),
163 bookmarks=webutil.nodebookmarksdict(web.repo, n),
167 bookmarks=webutil.nodebookmarksdict(web.repo, n),
164 inbranch=webutil.nodeinbranch(web.repo, ctx),
168 inbranch=webutil.nodeinbranch(web.repo, ctx),
165 branches=webutil.nodebranchdict(web.repo, ctx))
169 branches=webutil.nodebranchdict(web.repo, ctx))
166
170
167 if count >= revcount:
171 if count >= revcount:
168 break
172 break
169
173
170 tip = web.repo['tip']
174 tip = web.repo['tip']
171 parity = paritygen(web.stripecount)
175 parity = paritygen(web.stripecount)
172
176
173 return tmpl('search', query=query, node=tip.hex(),
177 return tmpl('search', query=query, node=tip.hex(),
174 entries=changelist, archives=web.archivelist("tip"),
178 entries=changelist, archives=web.archivelist("tip"),
175 morevars=morevars, lessvars=lessvars)
179 morevars=morevars, lessvars=lessvars)
176
180
177 def changelog(web, req, tmpl, shortlog=False):
181 def changelog(web, req, tmpl, shortlog=False):
178
182
179 if 'node' in req.form:
183 if 'node' in req.form:
180 ctx = webutil.changectx(web.repo, req)
184 ctx = webutil.changectx(web.repo, req)
181 else:
185 else:
182 if 'rev' in req.form:
186 if 'rev' in req.form:
183 hi = req.form['rev'][0]
187 hi = req.form['rev'][0]
184 else:
188 else:
185 hi = len(web.repo) - 1
189 hi = len(web.repo) - 1
186 try:
190 try:
187 ctx = web.repo[hi]
191 ctx = web.repo[hi]
188 except error.RepoError:
192 except error.RepoError:
189 return _search(web, req, tmpl) # XXX redirect to 404 page?
193 return _search(web, req, tmpl) # XXX redirect to 404 page?
190
194
191 def changelist(limit=0, **map):
195 def changelist(limit=0, **map):
192 l = [] # build a list in forward order for efficiency
196 l = [] # build a list in forward order for efficiency
193 for i in xrange(start, end):
197 for i in xrange(start, end):
194 ctx = web.repo[i]
198 ctx = web.repo[i]
195 n = ctx.node()
199 n = ctx.node()
196 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
200 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
197 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
201 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
198
202
199 l.insert(0, {"parity": parity.next(),
203 l.insert(0, {"parity": parity.next(),
200 "author": ctx.user(),
204 "author": ctx.user(),
201 "parent": webutil.parents(ctx, i - 1),
205 "parent": webutil.parents(ctx, i - 1),
202 "child": webutil.children(ctx, i + 1),
206 "child": webutil.children(ctx, i + 1),
203 "changelogtag": showtags,
207 "changelogtag": showtags,
204 "desc": ctx.description(),
208 "desc": ctx.description(),
205 "date": ctx.date(),
209 "date": ctx.date(),
206 "files": files,
210 "files": files,
207 "rev": i,
211 "rev": i,
208 "node": hex(n),
212 "node": hex(n),
209 "tags": webutil.nodetagsdict(web.repo, n),
213 "tags": webutil.nodetagsdict(web.repo, n),
210 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
214 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
211 "inbranch": webutil.nodeinbranch(web.repo, ctx),
215 "inbranch": webutil.nodeinbranch(web.repo, ctx),
212 "branches": webutil.nodebranchdict(web.repo, ctx)
216 "branches": webutil.nodebranchdict(web.repo, ctx)
213 })
217 })
214
218
215 if limit > 0:
219 if limit > 0:
216 l = l[:limit]
220 l = l[:limit]
217
221
218 for e in l:
222 for e in l:
219 yield e
223 yield e
220
224
221 revcount = shortlog and web.maxshortchanges or web.maxchanges
225 revcount = shortlog and web.maxshortchanges or web.maxchanges
222 if 'revcount' in req.form:
226 if 'revcount' in req.form:
223 revcount = int(req.form.get('revcount', [revcount])[0])
227 revcount = int(req.form.get('revcount', [revcount])[0])
224 revcount = max(revcount, 1)
228 revcount = max(revcount, 1)
225 tmpl.defaults['sessionvars']['revcount'] = revcount
229 tmpl.defaults['sessionvars']['revcount'] = revcount
226
230
227 lessvars = copy.copy(tmpl.defaults['sessionvars'])
231 lessvars = copy.copy(tmpl.defaults['sessionvars'])
228 lessvars['revcount'] = max(revcount / 2, 1)
232 lessvars['revcount'] = max(revcount / 2, 1)
229 morevars = copy.copy(tmpl.defaults['sessionvars'])
233 morevars = copy.copy(tmpl.defaults['sessionvars'])
230 morevars['revcount'] = revcount * 2
234 morevars['revcount'] = revcount * 2
231
235
232 count = len(web.repo)
236 count = len(web.repo)
233 pos = ctx.rev()
237 pos = ctx.rev()
234 start = max(0, pos - revcount + 1)
238 start = max(0, pos - revcount + 1)
235 end = min(count, start + revcount)
239 end = min(count, start + revcount)
236 pos = end - 1
240 pos = end - 1
237 parity = paritygen(web.stripecount, offset=start - end)
241 parity = paritygen(web.stripecount, offset=start - end)
238
242
239 changenav = webutil.revnavgen(pos, revcount, count, web.repo.changectx)
243 changenav = webutil.revnavgen(pos, revcount, count, web.repo.changectx)
240
244
241 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
245 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
242 node=ctx.hex(), rev=pos, changesets=count,
246 node=ctx.hex(), rev=pos, changesets=count,
243 entries=lambda **x: changelist(limit=0,**x),
247 entries=lambda **x: changelist(limit=0,**x),
244 latestentry=lambda **x: changelist(limit=1,**x),
248 latestentry=lambda **x: changelist(limit=1,**x),
245 archives=web.archivelist("tip"), revcount=revcount,
249 archives=web.archivelist("tip"), revcount=revcount,
246 morevars=morevars, lessvars=lessvars)
250 morevars=morevars, lessvars=lessvars)
247
251
248 def shortlog(web, req, tmpl):
252 def shortlog(web, req, tmpl):
249 return changelog(web, req, tmpl, shortlog = True)
253 return changelog(web, req, tmpl, shortlog = True)
250
254
251 def changeset(web, req, tmpl):
255 def changeset(web, req, tmpl):
252 ctx = webutil.changectx(web.repo, req)
256 ctx = webutil.changectx(web.repo, req)
253 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
257 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
254 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
258 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
255 ctx.node())
259 ctx.node())
256 showbranch = webutil.nodebranchnodefault(ctx)
260 showbranch = webutil.nodebranchnodefault(ctx)
257
261
258 files = []
262 files = []
259 parity = paritygen(web.stripecount)
263 parity = paritygen(web.stripecount)
260 for f in ctx.files():
264 for f in ctx.files():
261 template = f in ctx and 'filenodelink' or 'filenolink'
265 template = f in ctx and 'filenodelink' or 'filenolink'
262 files.append(tmpl(template,
266 files.append(tmpl(template,
263 node=ctx.hex(), file=f,
267 node=ctx.hex(), file=f,
264 parity=parity.next()))
268 parity=parity.next()))
265
269
266 style = web.config('web', 'style', 'paper')
270 style = web.config('web', 'style', 'paper')
267 if 'style' in req.form:
271 if 'style' in req.form:
268 style = req.form['style'][0]
272 style = req.form['style'][0]
269
273
270 parity = paritygen(web.stripecount)
274 parity = paritygen(web.stripecount)
271 diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
275 diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
272
276
273 parity = paritygen(web.stripecount)
277 parity = paritygen(web.stripecount)
274 diffstatgen = webutil.diffstatgen(ctx)
278 diffstatgen = webutil.diffstatgen(ctx)
275 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
279 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
276
280
277 return tmpl('changeset',
281 return tmpl('changeset',
278 diff=diffs,
282 diff=diffs,
279 rev=ctx.rev(),
283 rev=ctx.rev(),
280 node=ctx.hex(),
284 node=ctx.hex(),
281 parent=webutil.parents(ctx),
285 parent=webutil.parents(ctx),
282 child=webutil.children(ctx),
286 child=webutil.children(ctx),
283 changesettag=showtags,
287 changesettag=showtags,
284 changesetbookmark=showbookmarks,
288 changesetbookmark=showbookmarks,
285 changesetbranch=showbranch,
289 changesetbranch=showbranch,
286 author=ctx.user(),
290 author=ctx.user(),
287 desc=ctx.description(),
291 desc=ctx.description(),
288 date=ctx.date(),
292 date=ctx.date(),
289 files=files,
293 files=files,
290 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
294 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
291 diffstat=diffstat,
295 diffstat=diffstat,
292 archives=web.archivelist(ctx.hex()),
296 archives=web.archivelist(ctx.hex()),
293 tags=webutil.nodetagsdict(web.repo, ctx.node()),
297 tags=webutil.nodetagsdict(web.repo, ctx.node()),
294 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
298 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
295 branch=webutil.nodebranchnodefault(ctx),
299 branch=webutil.nodebranchnodefault(ctx),
296 inbranch=webutil.nodeinbranch(web.repo, ctx),
300 inbranch=webutil.nodeinbranch(web.repo, ctx),
297 branches=webutil.nodebranchdict(web.repo, ctx))
301 branches=webutil.nodebranchdict(web.repo, ctx))
298
302
299 rev = changeset
303 rev = changeset
300
304
301 def manifest(web, req, tmpl):
305 def manifest(web, req, tmpl):
302 ctx = webutil.changectx(web.repo, req)
306 ctx = webutil.changectx(web.repo, req)
303 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
307 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
304 mf = ctx.manifest()
308 mf = ctx.manifest()
305 node = ctx.node()
309 node = ctx.node()
306
310
307 files = {}
311 files = {}
308 dirs = {}
312 dirs = {}
309 parity = paritygen(web.stripecount)
313 parity = paritygen(web.stripecount)
310
314
311 if path and path[-1] != "/":
315 if path and path[-1] != "/":
312 path += "/"
316 path += "/"
313 l = len(path)
317 l = len(path)
314 abspath = "/" + path
318 abspath = "/" + path
315
319
316 for f, n in mf.iteritems():
320 for f, n in mf.iteritems():
317 if f[:l] != path:
321 if f[:l] != path:
318 continue
322 continue
319 remain = f[l:]
323 remain = f[l:]
320 elements = remain.split('/')
324 elements = remain.split('/')
321 if len(elements) == 1:
325 if len(elements) == 1:
322 files[remain] = f
326 files[remain] = f
323 else:
327 else:
324 h = dirs # need to retain ref to dirs (root)
328 h = dirs # need to retain ref to dirs (root)
325 for elem in elements[0:-1]:
329 for elem in elements[0:-1]:
326 if elem not in h:
330 if elem not in h:
327 h[elem] = {}
331 h[elem] = {}
328 h = h[elem]
332 h = h[elem]
329 if len(h) > 1:
333 if len(h) > 1:
330 break
334 break
331 h[None] = None # denotes files present
335 h[None] = None # denotes files present
332
336
333 if mf and not files and not dirs:
337 if mf and not files and not dirs:
334 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
338 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
335
339
336 def filelist(**map):
340 def filelist(**map):
337 for f in sorted(files):
341 for f in sorted(files):
338 full = files[f]
342 full = files[f]
339
343
340 fctx = ctx.filectx(full)
344 fctx = ctx.filectx(full)
341 yield {"file": full,
345 yield {"file": full,
342 "parity": parity.next(),
346 "parity": parity.next(),
343 "basename": f,
347 "basename": f,
344 "date": fctx.date(),
348 "date": fctx.date(),
345 "size": fctx.size(),
349 "size": fctx.size(),
346 "permissions": mf.flags(full)}
350 "permissions": mf.flags(full)}
347
351
348 def dirlist(**map):
352 def dirlist(**map):
349 for d in sorted(dirs):
353 for d in sorted(dirs):
350
354
351 emptydirs = []
355 emptydirs = []
352 h = dirs[d]
356 h = dirs[d]
353 while isinstance(h, dict) and len(h) == 1:
357 while isinstance(h, dict) and len(h) == 1:
354 k, v = h.items()[0]
358 k, v = h.items()[0]
355 if v:
359 if v:
356 emptydirs.append(k)
360 emptydirs.append(k)
357 h = v
361 h = v
358
362
359 path = "%s%s" % (abspath, d)
363 path = "%s%s" % (abspath, d)
360 yield {"parity": parity.next(),
364 yield {"parity": parity.next(),
361 "path": path,
365 "path": path,
362 "emptydirs": "/".join(emptydirs),
366 "emptydirs": "/".join(emptydirs),
363 "basename": d}
367 "basename": d}
364
368
365 return tmpl("manifest",
369 return tmpl("manifest",
366 rev=ctx.rev(),
370 rev=ctx.rev(),
367 node=hex(node),
371 node=hex(node),
368 path=abspath,
372 path=abspath,
369 up=webutil.up(abspath),
373 up=webutil.up(abspath),
370 upparity=parity.next(),
374 upparity=parity.next(),
371 fentries=filelist,
375 fentries=filelist,
372 dentries=dirlist,
376 dentries=dirlist,
373 archives=web.archivelist(hex(node)),
377 archives=web.archivelist(hex(node)),
374 tags=webutil.nodetagsdict(web.repo, node),
378 tags=webutil.nodetagsdict(web.repo, node),
375 bookmarks=webutil.nodebookmarksdict(web.repo, node),
379 bookmarks=webutil.nodebookmarksdict(web.repo, node),
376 inbranch=webutil.nodeinbranch(web.repo, ctx),
380 inbranch=webutil.nodeinbranch(web.repo, ctx),
377 branches=webutil.nodebranchdict(web.repo, ctx))
381 branches=webutil.nodebranchdict(web.repo, ctx))
378
382
379 def tags(web, req, tmpl):
383 def tags(web, req, tmpl):
380 i = web.repo.tagslist()
384 i = web.repo.tagslist()
381 i.reverse()
385 i.reverse()
382 parity = paritygen(web.stripecount)
386 parity = paritygen(web.stripecount)
383
387
384 def entries(notip=False, limit=0, **map):
388 def entries(notip=False, limit=0, **map):
385 count = 0
389 count = 0
386 for k, n in i:
390 for k, n in i:
387 if notip and k == "tip":
391 if notip and k == "tip":
388 continue
392 continue
389 if limit > 0 and count >= limit:
393 if limit > 0 and count >= limit:
390 continue
394 continue
391 count = count + 1
395 count = count + 1
392 yield {"parity": parity.next(),
396 yield {"parity": parity.next(),
393 "tag": k,
397 "tag": k,
394 "date": web.repo[n].date(),
398 "date": web.repo[n].date(),
395 "node": hex(n)}
399 "node": hex(n)}
396
400
397 return tmpl("tags",
401 return tmpl("tags",
398 node=hex(web.repo.changelog.tip()),
402 node=hex(web.repo.changelog.tip()),
399 entries=lambda **x: entries(False, 0, **x),
403 entries=lambda **x: entries(False, 0, **x),
400 entriesnotip=lambda **x: entries(True, 0, **x),
404 entriesnotip=lambda **x: entries(True, 0, **x),
401 latestentry=lambda **x: entries(True, 1, **x))
405 latestentry=lambda **x: entries(True, 1, **x))
402
406
403 def bookmarks(web, req, tmpl):
407 def bookmarks(web, req, tmpl):
404 i = web.repo._bookmarks.items()
408 i = web.repo._bookmarks.items()
405 parity = paritygen(web.stripecount)
409 parity = paritygen(web.stripecount)
406
410
407 def entries(limit=0, **map):
411 def entries(limit=0, **map):
408 count = 0
412 count = 0
409 for k, n in sorted(i):
413 for k, n in sorted(i):
410 if limit > 0 and count >= limit:
414 if limit > 0 and count >= limit:
411 continue
415 continue
412 count = count + 1
416 count = count + 1
413 yield {"parity": parity.next(),
417 yield {"parity": parity.next(),
414 "bookmark": k,
418 "bookmark": k,
415 "date": web.repo[n].date(),
419 "date": web.repo[n].date(),
416 "node": hex(n)}
420 "node": hex(n)}
417
421
418 return tmpl("bookmarks",
422 return tmpl("bookmarks",
419 node=hex(web.repo.changelog.tip()),
423 node=hex(web.repo.changelog.tip()),
420 entries=lambda **x: entries(0, **x),
424 entries=lambda **x: entries(0, **x),
421 latestentry=lambda **x: entries(1, **x))
425 latestentry=lambda **x: entries(1, **x))
422
426
423 def branches(web, req, tmpl):
427 def branches(web, req, tmpl):
424 tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
428 tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
425 heads = web.repo.heads()
429 heads = web.repo.heads()
426 parity = paritygen(web.stripecount)
430 parity = paritygen(web.stripecount)
427 sortkey = lambda ctx: ('close' not in ctx.extra(), ctx.rev())
431 sortkey = lambda ctx: ('close' not in ctx.extra(), ctx.rev())
428
432
429 def entries(limit, **map):
433 def entries(limit, **map):
430 count = 0
434 count = 0
431 for ctx in sorted(tips, key=sortkey, reverse=True):
435 for ctx in sorted(tips, key=sortkey, reverse=True):
432 if limit > 0 and count >= limit:
436 if limit > 0 and count >= limit:
433 return
437 return
434 count += 1
438 count += 1
435 if not web.repo.branchheads(ctx.branch()):
439 if not web.repo.branchheads(ctx.branch()):
436 status = 'closed'
440 status = 'closed'
437 elif ctx.node() not in heads:
441 elif ctx.node() not in heads:
438 status = 'inactive'
442 status = 'inactive'
439 else:
443 else:
440 status = 'open'
444 status = 'open'
441 yield {'parity': parity.next(),
445 yield {'parity': parity.next(),
442 'branch': ctx.branch(),
446 'branch': ctx.branch(),
443 'status': status,
447 'status': status,
444 'node': ctx.hex(),
448 'node': ctx.hex(),
445 'date': ctx.date()}
449 'date': ctx.date()}
446
450
447 return tmpl('branches', node=hex(web.repo.changelog.tip()),
451 return tmpl('branches', node=hex(web.repo.changelog.tip()),
448 entries=lambda **x: entries(0, **x),
452 entries=lambda **x: entries(0, **x),
449 latestentry=lambda **x: entries(1, **x))
453 latestentry=lambda **x: entries(1, **x))
450
454
451 def summary(web, req, tmpl):
455 def summary(web, req, tmpl):
452 i = web.repo.tagslist()
456 i = web.repo.tagslist()
453 i.reverse()
457 i.reverse()
454
458
455 def tagentries(**map):
459 def tagentries(**map):
456 parity = paritygen(web.stripecount)
460 parity = paritygen(web.stripecount)
457 count = 0
461 count = 0
458 for k, n in i:
462 for k, n in i:
459 if k == "tip": # skip tip
463 if k == "tip": # skip tip
460 continue
464 continue
461
465
462 count += 1
466 count += 1
463 if count > 10: # limit to 10 tags
467 if count > 10: # limit to 10 tags
464 break
468 break
465
469
466 yield tmpl("tagentry",
470 yield tmpl("tagentry",
467 parity=parity.next(),
471 parity=parity.next(),
468 tag=k,
472 tag=k,
469 node=hex(n),
473 node=hex(n),
470 date=web.repo[n].date())
474 date=web.repo[n].date())
471
475
472 def bookmarks(**map):
476 def bookmarks(**map):
473 parity = paritygen(web.stripecount)
477 parity = paritygen(web.stripecount)
474 b = web.repo._bookmarks.items()
478 b = web.repo._bookmarks.items()
475 for k, n in sorted(b)[:10]: # limit to 10 bookmarks
479 for k, n in sorted(b)[:10]: # limit to 10 bookmarks
476 yield {'parity': parity.next(),
480 yield {'parity': parity.next(),
477 'bookmark': k,
481 'bookmark': k,
478 'date': web.repo[n].date(),
482 'date': web.repo[n].date(),
479 'node': hex(n)}
483 'node': hex(n)}
480
484
481 def branches(**map):
485 def branches(**map):
482 parity = paritygen(web.stripecount)
486 parity = paritygen(web.stripecount)
483
487
484 b = web.repo.branchtags()
488 b = web.repo.branchtags()
485 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
489 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
486 for r, n, t in sorted(l):
490 for r, n, t in sorted(l):
487 yield {'parity': parity.next(),
491 yield {'parity': parity.next(),
488 'branch': t,
492 'branch': t,
489 'node': hex(n),
493 'node': hex(n),
490 'date': web.repo[n].date()}
494 'date': web.repo[n].date()}
491
495
492 def changelist(**map):
496 def changelist(**map):
493 parity = paritygen(web.stripecount, offset=start - end)
497 parity = paritygen(web.stripecount, offset=start - end)
494 l = [] # build a list in forward order for efficiency
498 l = [] # build a list in forward order for efficiency
495 for i in xrange(start, end):
499 for i in xrange(start, end):
496 ctx = web.repo[i]
500 ctx = web.repo[i]
497 n = ctx.node()
501 n = ctx.node()
498 hn = hex(n)
502 hn = hex(n)
499
503
500 l.insert(0, tmpl(
504 l.insert(0, tmpl(
501 'shortlogentry',
505 'shortlogentry',
502 parity=parity.next(),
506 parity=parity.next(),
503 author=ctx.user(),
507 author=ctx.user(),
504 desc=ctx.description(),
508 desc=ctx.description(),
505 date=ctx.date(),
509 date=ctx.date(),
506 rev=i,
510 rev=i,
507 node=hn,
511 node=hn,
508 tags=webutil.nodetagsdict(web.repo, n),
512 tags=webutil.nodetagsdict(web.repo, n),
509 bookmarks=webutil.nodebookmarksdict(web.repo, n),
513 bookmarks=webutil.nodebookmarksdict(web.repo, n),
510 inbranch=webutil.nodeinbranch(web.repo, ctx),
514 inbranch=webutil.nodeinbranch(web.repo, ctx),
511 branches=webutil.nodebranchdict(web.repo, ctx)))
515 branches=webutil.nodebranchdict(web.repo, ctx)))
512
516
513 yield l
517 yield l
514
518
515 tip = web.repo['tip']
519 tip = web.repo['tip']
516 count = len(web.repo)
520 count = len(web.repo)
517 start = max(0, count - web.maxchanges)
521 start = max(0, count - web.maxchanges)
518 end = min(count, start + web.maxchanges)
522 end = min(count, start + web.maxchanges)
519
523
520 return tmpl("summary",
524 return tmpl("summary",
521 desc=web.config("web", "description", "unknown"),
525 desc=web.config("web", "description", "unknown"),
522 owner=get_contact(web.config) or "unknown",
526 owner=get_contact(web.config) or "unknown",
523 lastchange=tip.date(),
527 lastchange=tip.date(),
524 tags=tagentries,
528 tags=tagentries,
525 bookmarks=bookmarks,
529 bookmarks=bookmarks,
526 branches=branches,
530 branches=branches,
527 shortlog=changelist,
531 shortlog=changelist,
528 node=tip.hex(),
532 node=tip.hex(),
529 archives=web.archivelist("tip"))
533 archives=web.archivelist("tip"))
530
534
531 def filediff(web, req, tmpl):
535 def filediff(web, req, tmpl):
532 fctx, ctx = None, None
536 fctx, ctx = None, None
533 try:
537 try:
534 fctx = webutil.filectx(web.repo, req)
538 fctx = webutil.filectx(web.repo, req)
535 except LookupError:
539 except LookupError:
536 ctx = webutil.changectx(web.repo, req)
540 ctx = webutil.changectx(web.repo, req)
537 path = webutil.cleanpath(web.repo, req.form['file'][0])
541 path = webutil.cleanpath(web.repo, req.form['file'][0])
538 if path not in ctx.files():
542 if path not in ctx.files():
539 raise
543 raise
540
544
541 if fctx is not None:
545 if fctx is not None:
542 n = fctx.node()
546 n = fctx.node()
543 path = fctx.path()
547 path = fctx.path()
544 else:
548 else:
545 n = ctx.node()
549 n = ctx.node()
546 # path already defined in except clause
550 # path already defined in except clause
547
551
548 parity = paritygen(web.stripecount)
552 parity = paritygen(web.stripecount)
549 style = web.config('web', 'style', 'paper')
553 style = web.config('web', 'style', 'paper')
550 if 'style' in req.form:
554 if 'style' in req.form:
551 style = req.form['style'][0]
555 style = req.form['style'][0]
552
556
553 diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity, style)
557 diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity, style)
554 rename = fctx and webutil.renamelink(fctx) or []
558 rename = fctx and webutil.renamelink(fctx) or []
555 ctx = fctx and fctx or ctx
559 ctx = fctx and fctx or ctx
556 return tmpl("filediff",
560 return tmpl("filediff",
557 file=path,
561 file=path,
558 node=hex(n),
562 node=hex(n),
559 rev=ctx.rev(),
563 rev=ctx.rev(),
560 date=ctx.date(),
564 date=ctx.date(),
561 desc=ctx.description(),
565 desc=ctx.description(),
562 author=ctx.user(),
566 author=ctx.user(),
563 rename=rename,
567 rename=rename,
564 branch=webutil.nodebranchnodefault(ctx),
568 branch=webutil.nodebranchnodefault(ctx),
565 parent=webutil.parents(ctx),
569 parent=webutil.parents(ctx),
566 child=webutil.children(ctx),
570 child=webutil.children(ctx),
567 diff=diffs)
571 diff=diffs)
568
572
569 diff = filediff
573 diff = filediff
570
574
571 def annotate(web, req, tmpl):
575 def annotate(web, req, tmpl):
572 fctx = webutil.filectx(web.repo, req)
576 fctx = webutil.filectx(web.repo, req)
573 f = fctx.path()
577 f = fctx.path()
574 parity = paritygen(web.stripecount)
578 parity = paritygen(web.stripecount)
575
579
576 def annotate(**map):
580 def annotate(**map):
577 last = None
581 last = None
578 if binary(fctx.data()):
582 if binary(fctx.data()):
579 mt = (mimetypes.guess_type(fctx.path())[0]
583 mt = (mimetypes.guess_type(fctx.path())[0]
580 or 'application/octet-stream')
584 or 'application/octet-stream')
581 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
585 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
582 '(binary:%s)' % mt)])
586 '(binary:%s)' % mt)])
583 else:
587 else:
584 lines = enumerate(fctx.annotate(follow=True, linenumber=True))
588 lines = enumerate(fctx.annotate(follow=True, linenumber=True))
585 for lineno, ((f, targetline), l) in lines:
589 for lineno, ((f, targetline), l) in lines:
586 fnode = f.filenode()
590 fnode = f.filenode()
587
591
588 if last != fnode:
592 if last != fnode:
589 last = fnode
593 last = fnode
590
594
591 yield {"parity": parity.next(),
595 yield {"parity": parity.next(),
592 "node": f.hex(),
596 "node": f.hex(),
593 "rev": f.rev(),
597 "rev": f.rev(),
594 "author": f.user(),
598 "author": f.user(),
595 "desc": f.description(),
599 "desc": f.description(),
596 "file": f.path(),
600 "file": f.path(),
597 "targetline": targetline,
601 "targetline": targetline,
598 "line": l,
602 "line": l,
599 "lineid": "l%d" % (lineno + 1),
603 "lineid": "l%d" % (lineno + 1),
600 "linenumber": "% 6d" % (lineno + 1),
604 "linenumber": "% 6d" % (lineno + 1),
601 "revdate": f.date()}
605 "revdate": f.date()}
602
606
603 return tmpl("fileannotate",
607 return tmpl("fileannotate",
604 file=f,
608 file=f,
605 annotate=annotate,
609 annotate=annotate,
606 path=webutil.up(f),
610 path=webutil.up(f),
607 rev=fctx.rev(),
611 rev=fctx.rev(),
608 node=fctx.hex(),
612 node=fctx.hex(),
609 author=fctx.user(),
613 author=fctx.user(),
610 date=fctx.date(),
614 date=fctx.date(),
611 desc=fctx.description(),
615 desc=fctx.description(),
612 rename=webutil.renamelink(fctx),
616 rename=webutil.renamelink(fctx),
613 branch=webutil.nodebranchnodefault(fctx),
617 branch=webutil.nodebranchnodefault(fctx),
614 parent=webutil.parents(fctx),
618 parent=webutil.parents(fctx),
615 child=webutil.children(fctx),
619 child=webutil.children(fctx),
616 permissions=fctx.manifest().flags(f))
620 permissions=fctx.manifest().flags(f))
617
621
618 def filelog(web, req, tmpl):
622 def filelog(web, req, tmpl):
619
623
620 try:
624 try:
621 fctx = webutil.filectx(web.repo, req)
625 fctx = webutil.filectx(web.repo, req)
622 f = fctx.path()
626 f = fctx.path()
623 fl = fctx.filelog()
627 fl = fctx.filelog()
624 except error.LookupError:
628 except error.LookupError:
625 f = webutil.cleanpath(web.repo, req.form['file'][0])
629 f = webutil.cleanpath(web.repo, req.form['file'][0])
626 fl = web.repo.file(f)
630 fl = web.repo.file(f)
627 numrevs = len(fl)
631 numrevs = len(fl)
628 if not numrevs: # file doesn't exist at all
632 if not numrevs: # file doesn't exist at all
629 raise
633 raise
630 rev = webutil.changectx(web.repo, req).rev()
634 rev = webutil.changectx(web.repo, req).rev()
631 first = fl.linkrev(0)
635 first = fl.linkrev(0)
632 if rev < first: # current rev is from before file existed
636 if rev < first: # current rev is from before file existed
633 raise
637 raise
634 frev = numrevs - 1
638 frev = numrevs - 1
635 while fl.linkrev(frev) > rev:
639 while fl.linkrev(frev) > rev:
636 frev -= 1
640 frev -= 1
637 fctx = web.repo.filectx(f, fl.linkrev(frev))
641 fctx = web.repo.filectx(f, fl.linkrev(frev))
638
642
639 revcount = web.maxshortchanges
643 revcount = web.maxshortchanges
640 if 'revcount' in req.form:
644 if 'revcount' in req.form:
641 revcount = int(req.form.get('revcount', [revcount])[0])
645 revcount = int(req.form.get('revcount', [revcount])[0])
642 revcount = max(revcount, 1)
646 revcount = max(revcount, 1)
643 tmpl.defaults['sessionvars']['revcount'] = revcount
647 tmpl.defaults['sessionvars']['revcount'] = revcount
644
648
645 lessvars = copy.copy(tmpl.defaults['sessionvars'])
649 lessvars = copy.copy(tmpl.defaults['sessionvars'])
646 lessvars['revcount'] = max(revcount / 2, 1)
650 lessvars['revcount'] = max(revcount / 2, 1)
647 morevars = copy.copy(tmpl.defaults['sessionvars'])
651 morevars = copy.copy(tmpl.defaults['sessionvars'])
648 morevars['revcount'] = revcount * 2
652 morevars['revcount'] = revcount * 2
649
653
650 count = fctx.filerev() + 1
654 count = fctx.filerev() + 1
651 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
655 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
652 end = min(count, start + revcount) # last rev on this page
656 end = min(count, start + revcount) # last rev on this page
653 parity = paritygen(web.stripecount, offset=start - end)
657 parity = paritygen(web.stripecount, offset=start - end)
654
658
655 def entries(limit=0, **map):
659 def entries(limit=0, **map):
656 l = []
660 l = []
657
661
658 repo = web.repo
662 repo = web.repo
659 for i in xrange(start, end):
663 for i in xrange(start, end):
660 iterfctx = fctx.filectx(i)
664 iterfctx = fctx.filectx(i)
661
665
662 l.insert(0, {"parity": parity.next(),
666 l.insert(0, {"parity": parity.next(),
663 "filerev": i,
667 "filerev": i,
664 "file": f,
668 "file": f,
665 "node": iterfctx.hex(),
669 "node": iterfctx.hex(),
666 "author": iterfctx.user(),
670 "author": iterfctx.user(),
667 "date": iterfctx.date(),
671 "date": iterfctx.date(),
668 "rename": webutil.renamelink(iterfctx),
672 "rename": webutil.renamelink(iterfctx),
669 "parent": webutil.parents(iterfctx),
673 "parent": webutil.parents(iterfctx),
670 "child": webutil.children(iterfctx),
674 "child": webutil.children(iterfctx),
671 "desc": iterfctx.description(),
675 "desc": iterfctx.description(),
672 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
676 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
673 "bookmarks": webutil.nodebookmarksdict(
677 "bookmarks": webutil.nodebookmarksdict(
674 repo, iterfctx.node()),
678 repo, iterfctx.node()),
675 "branch": webutil.nodebranchnodefault(iterfctx),
679 "branch": webutil.nodebranchnodefault(iterfctx),
676 "inbranch": webutil.nodeinbranch(repo, iterfctx),
680 "inbranch": webutil.nodeinbranch(repo, iterfctx),
677 "branches": webutil.nodebranchdict(repo, iterfctx)})
681 "branches": webutil.nodebranchdict(repo, iterfctx)})
678
682
679 if limit > 0:
683 if limit > 0:
680 l = l[:limit]
684 l = l[:limit]
681
685
682 for e in l:
686 for e in l:
683 yield e
687 yield e
684
688
685 nodefunc = lambda x: fctx.filectx(fileid=x)
689 nodefunc = lambda x: fctx.filectx(fileid=x)
686 nav = webutil.revnavgen(end - 1, revcount, count, nodefunc)
690 nav = webutil.revnavgen(end - 1, revcount, count, nodefunc)
687 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
691 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
688 entries=lambda **x: entries(limit=0, **x),
692 entries=lambda **x: entries(limit=0, **x),
689 latestentry=lambda **x: entries(limit=1, **x),
693 latestentry=lambda **x: entries(limit=1, **x),
690 revcount=revcount, morevars=morevars, lessvars=lessvars)
694 revcount=revcount, morevars=morevars, lessvars=lessvars)
691
695
692 def archive(web, req, tmpl):
696 def archive(web, req, tmpl):
693 type_ = req.form.get('type', [None])[0]
697 type_ = req.form.get('type', [None])[0]
694 allowed = web.configlist("web", "allow_archive")
698 allowed = web.configlist("web", "allow_archive")
695 key = req.form['node'][0]
699 key = req.form['node'][0]
696
700
697 if type_ not in web.archives:
701 if type_ not in web.archives:
698 msg = 'Unsupported archive type: %s' % type_
702 msg = 'Unsupported archive type: %s' % type_
699 raise ErrorResponse(HTTP_NOT_FOUND, msg)
703 raise ErrorResponse(HTTP_NOT_FOUND, msg)
700
704
701 if not ((type_ in allowed or
705 if not ((type_ in allowed or
702 web.configbool("web", "allow" + type_, False))):
706 web.configbool("web", "allow" + type_, False))):
703 msg = 'Archive type not allowed: %s' % type_
707 msg = 'Archive type not allowed: %s' % type_
704 raise ErrorResponse(HTTP_FORBIDDEN, msg)
708 raise ErrorResponse(HTTP_FORBIDDEN, msg)
705
709
706 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
710 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
707 cnode = web.repo.lookup(key)
711 cnode = web.repo.lookup(key)
708 arch_version = key
712 arch_version = key
709 if cnode == key or key == 'tip':
713 if cnode == key or key == 'tip':
710 arch_version = short(cnode)
714 arch_version = short(cnode)
711 name = "%s-%s" % (reponame, arch_version)
715 name = "%s-%s" % (reponame, arch_version)
712 mimetype, artype, extension, encoding = web.archive_specs[type_]
716 mimetype, artype, extension, encoding = web.archive_specs[type_]
713 headers = [
717 headers = [
714 ('Content-Type', mimetype),
718 ('Content-Type', mimetype),
715 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
719 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
716 ]
720 ]
717 if encoding:
721 if encoding:
718 headers.append(('Content-Encoding', encoding))
722 headers.append(('Content-Encoding', encoding))
719 req.header(headers)
723 req.header(headers)
720 req.respond(HTTP_OK)
724 req.respond(HTTP_OK)
721 archival.archive(web.repo, req, cnode, artype, prefix=name)
725 archival.archive(web.repo, req, cnode, artype, prefix=name)
722 return []
726 return []
723
727
724
728
725 def static(web, req, tmpl):
729 def static(web, req, tmpl):
726 fname = req.form['file'][0]
730 fname = req.form['file'][0]
727 # a repo owner may set web.static in .hg/hgrc to get any file
731 # a repo owner may set web.static in .hg/hgrc to get any file
728 # readable by the user running the CGI script
732 # readable by the user running the CGI script
729 static = web.config("web", "static", None, untrusted=False)
733 static = web.config("web", "static", None, untrusted=False)
730 if not static:
734 if not static:
731 tp = web.templatepath or templater.templatepath()
735 tp = web.templatepath or templater.templatepath()
732 if isinstance(tp, str):
736 if isinstance(tp, str):
733 tp = [tp]
737 tp = [tp]
734 static = [os.path.join(p, 'static') for p in tp]
738 static = [os.path.join(p, 'static') for p in tp]
735 return [staticfile(static, fname, req)]
739 return [staticfile(static, fname, req)]
736
740
737 def graph(web, req, tmpl):
741 def graph(web, req, tmpl):
738
742
739 rev = webutil.changectx(web.repo, req).rev()
743 rev = webutil.changectx(web.repo, req).rev()
740 bg_height = 39
744 bg_height = 39
741 revcount = web.maxshortchanges
745 revcount = web.maxshortchanges
742 if 'revcount' in req.form:
746 if 'revcount' in req.form:
743 revcount = int(req.form.get('revcount', [revcount])[0])
747 revcount = int(req.form.get('revcount', [revcount])[0])
744 revcount = max(revcount, 1)
748 revcount = max(revcount, 1)
745 tmpl.defaults['sessionvars']['revcount'] = revcount
749 tmpl.defaults['sessionvars']['revcount'] = revcount
746
750
747 lessvars = copy.copy(tmpl.defaults['sessionvars'])
751 lessvars = copy.copy(tmpl.defaults['sessionvars'])
748 lessvars['revcount'] = max(revcount / 2, 1)
752 lessvars['revcount'] = max(revcount / 2, 1)
749 morevars = copy.copy(tmpl.defaults['sessionvars'])
753 morevars = copy.copy(tmpl.defaults['sessionvars'])
750 morevars['revcount'] = revcount * 2
754 morevars['revcount'] = revcount * 2
751
755
752 max_rev = len(web.repo) - 1
756 max_rev = len(web.repo) - 1
753 revcount = min(max_rev, revcount)
757 revcount = min(max_rev, revcount)
754 revnode = web.repo.changelog.node(rev)
758 revnode = web.repo.changelog.node(rev)
755 revnode_hex = hex(revnode)
759 revnode_hex = hex(revnode)
756 uprev = min(max_rev, rev + revcount)
760 uprev = min(max_rev, rev + revcount)
757 downrev = max(0, rev - revcount)
761 downrev = max(0, rev - revcount)
758 count = len(web.repo)
762 count = len(web.repo)
759 changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
763 changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
760 startrev = rev
764 startrev = rev
761 # if starting revision is less than 60 set it to uprev
765 # if starting revision is less than 60 set it to uprev
762 if rev < web.maxshortchanges:
766 if rev < web.maxshortchanges:
763 startrev = uprev
767 startrev = uprev
764
768
765 dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1))
769 dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1))
766 tree = list(graphmod.colored(dag))
770 tree = list(graphmod.colored(dag))
767 canvasheight = (len(tree) + 1) * bg_height - 27
771 canvasheight = (len(tree) + 1) * bg_height - 27
768 data = []
772 data = []
769 for (id, type, ctx, vtx, edges) in tree:
773 for (id, type, ctx, vtx, edges) in tree:
770 if type != graphmod.CHANGESET:
774 if type != graphmod.CHANGESET:
771 continue
775 continue
772 node = str(ctx)
776 node = str(ctx)
773 age = templatefilters.age(ctx.date())
777 age = templatefilters.age(ctx.date())
774 desc = templatefilters.firstline(ctx.description())
778 desc = templatefilters.firstline(ctx.description())
775 desc = cgi.escape(templatefilters.nonempty(desc))
779 desc = cgi.escape(templatefilters.nonempty(desc))
776 user = cgi.escape(templatefilters.person(ctx.user()))
780 user = cgi.escape(templatefilters.person(ctx.user()))
777 branch = ctx.branch()
781 branch = ctx.branch()
778 branch = branch, web.repo.branchtags().get(branch) == ctx.node()
782 branch = branch, web.repo.branchtags().get(branch) == ctx.node()
779 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(),
783 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(),
780 ctx.bookmarks()))
784 ctx.bookmarks()))
781
785
782 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
786 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
783 lessvars=lessvars, morevars=morevars, downrev=downrev,
787 lessvars=lessvars, morevars=morevars, downrev=downrev,
784 canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
788 canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
785 node=revnode_hex, changenav=changenav)
789 node=revnode_hex, changenav=changenav)
786
790
787 def _getdoc(e):
791 def _getdoc(e):
788 doc = e[0].__doc__
792 doc = e[0].__doc__
789 if doc:
793 if doc:
790 doc = doc.split('\n')[0]
794 doc = doc.split('\n')[0]
791 else:
795 else:
792 doc = _('(no help text available)')
796 doc = _('(no help text available)')
793 return doc
797 return doc
794
798
795 def help(web, req, tmpl):
799 def help(web, req, tmpl):
796 from mercurial import commands # avoid cycle
800 from mercurial import commands # avoid cycle
797
801
798 topicname = req.form.get('node', [None])[0]
802 topicname = req.form.get('node', [None])[0]
799 if not topicname:
803 if not topicname:
800 def topics(**map):
804 def topics(**map):
801 for entries, summary, _ in helpmod.helptable:
805 for entries, summary, _ in helpmod.helptable:
802 entries = sorted(entries, key=len)
806 entries = sorted(entries, key=len)
803 yield {'topic': entries[-1], 'summary': summary}
807 yield {'topic': entries[-1], 'summary': summary}
804
808
805 early, other = [], []
809 early, other = [], []
806 primary = lambda s: s.split('|')[0]
810 primary = lambda s: s.split('|')[0]
807 for c, e in commands.table.iteritems():
811 for c, e in commands.table.iteritems():
808 doc = _getdoc(e)
812 doc = _getdoc(e)
809 if 'DEPRECATED' in doc or c.startswith('debug'):
813 if 'DEPRECATED' in doc or c.startswith('debug'):
810 continue
814 continue
811 cmd = primary(c)
815 cmd = primary(c)
812 if cmd.startswith('^'):
816 if cmd.startswith('^'):
813 early.append((cmd[1:], doc))
817 early.append((cmd[1:], doc))
814 else:
818 else:
815 other.append((cmd, doc))
819 other.append((cmd, doc))
816
820
817 early.sort()
821 early.sort()
818 other.sort()
822 other.sort()
819
823
820 def earlycommands(**map):
824 def earlycommands(**map):
821 for c, doc in early:
825 for c, doc in early:
822 yield {'topic': c, 'summary': doc}
826 yield {'topic': c, 'summary': doc}
823
827
824 def othercommands(**map):
828 def othercommands(**map):
825 for c, doc in other:
829 for c, doc in other:
826 yield {'topic': c, 'summary': doc}
830 yield {'topic': c, 'summary': doc}
827
831
828 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
832 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
829 othercommands=othercommands, title='Index')
833 othercommands=othercommands, title='Index')
830
834
831 u = webutil.wsgiui()
835 u = webutil.wsgiui()
832 u.pushbuffer()
836 u.pushbuffer()
833 try:
837 try:
834 commands.help_(u, topicname)
838 commands.help_(u, topicname)
835 except error.UnknownCommand:
839 except error.UnknownCommand:
836 raise ErrorResponse(HTTP_NOT_FOUND)
840 raise ErrorResponse(HTTP_NOT_FOUND)
837 doc = u.popbuffer()
841 doc = u.popbuffer()
838 return tmpl('help', topic=topicname, doc=doc)
842 return tmpl('help', topic=topicname, doc=doc)
@@ -1,35 +1,57
1 Test raw style of hgweb
1 Test raw style of hgweb
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ mkdir sub
5 $ mkdir sub
6 $ cat >'sub/some "text".txt' <<ENDSOME
6 $ cat >'sub/some "text".txt' <<ENDSOME
7 > This is just some random text
7 > This is just some random text
8 > that will go inside the file and take a few lines.
8 > that will go inside the file and take a few lines.
9 > It is very boring to read, but computers don't
9 > It is very boring to read, but computers don't
10 > care about things like that.
10 > care about things like that.
11 > ENDSOME
11 > ENDSOME
12 $ hg add 'sub/some "text".txt'
12 $ hg add 'sub/some "text".txt'
13 warning: filename contains '"', which is reserved on Windows: 'sub/some "text".txt'
13 warning: filename contains '"', which is reserved on Windows: 'sub/some "text".txt'
14 $ hg commit -d "1 0" -m "Just some text"
14 $ hg commit -d "1 0" -m "Just some text"
15
15
16 $ hg serve -p $HGPORT -A access.log -E error.log -d --pid-file=hg.pid
16 $ hg serve -p $HGPORT -A access.log -E error.log -d --pid-file=hg.pid
17
17
18 $ cat hg.pid >> $DAEMON_PIDS
18 $ cat hg.pid >> $DAEMON_PIDS
19 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/?f=a23bf1310f6e;file=sub/some%20%22text%22.txt;style=raw' content-type content-length content-disposition) >getoutput.txt &
19 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/?f=a23bf1310f6e;file=sub/some%20%22text%22.txt;style=raw' content-type content-length content-disposition) >getoutput.txt &
20 $ sleep 5
20 $ sleep 5
21 $ kill `cat hg.pid`
21 $ kill `cat hg.pid`
22 $ sleep 1 # wait for server to scream and die
22 $ sleep 1 # wait for server to scream and die
23 $ cat getoutput.txt
23 $ cat getoutput.txt
24 200 Script output follows
24 200 Script output follows
25 content-type: application/binary
26 content-length: 157
27 content-disposition: inline; filename="some \"text\".txt"
28
29 This is just some random text
30 that will go inside the file and take a few lines.
31 It is very boring to read, but computers don't
32 care about things like that.
33 $ cat access.log error.log
34 127.0.0.1 - - [*] "GET /?f=a23bf1310f6e;file=sub/some%20%22text%22.txt;style=raw HTTP/1.1" 200 - (glob)
35
36 $ rm access.log error.log
37 $ hg serve -p $HGPORT -A access.log -E error.log -d --pid-file=hg.pid \
38 > --config web.guessmime=True
39
40 $ cat hg.pid >> $DAEMON_PIDS
41 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/?f=a23bf1310f6e;file=sub/some%20%22text%22.txt;style=raw' content-type content-length content-disposition) >getoutput.txt &
42 $ sleep 5
43 $ kill `cat hg.pid`
44 $ sleep 1 # wait for server to scream and die
45 $ cat getoutput.txt
46 200 Script output follows
25 content-type: text/plain; charset="ascii"
47 content-type: text/plain; charset="ascii"
26 content-length: 157
48 content-length: 157
27 content-disposition: inline; filename="some \"text\".txt"
49 content-disposition: inline; filename="some \"text\".txt"
28
50
29 This is just some random text
51 This is just some random text
30 that will go inside the file and take a few lines.
52 that will go inside the file and take a few lines.
31 It is very boring to read, but computers don't
53 It is very boring to read, but computers don't
32 care about things like that.
54 care about things like that.
33 $ cat access.log error.log
55 $ cat access.log error.log
34 127.0.0.1 - - [*] "GET /?f=a23bf1310f6e;file=sub/some%20%22text%22.txt;style=raw HTTP/1.1" 200 - (glob)
56 127.0.0.1 - - [*] "GET /?f=a23bf1310f6e;file=sub/some%20%22text%22.txt;style=raw HTTP/1.1" 200 - (glob)
35
57
General Comments 0
You need to be logged in to leave comments. Login now