##// END OF EJS Templates
Add option "hidden" to hgwebdir....
Markus F.X.J. Oberhumer -
r4709:53eca35c default
parent child Browse files
Show More
@@ -1,574 +1,576 b''
1 HGRC(5)
1 HGRC(5)
2 =======
2 =======
3 Bryan O'Sullivan <bos@serpentine.com>
3 Bryan O'Sullivan <bos@serpentine.com>
4
4
5 NAME
5 NAME
6 ----
6 ----
7 hgrc - configuration files for Mercurial
7 hgrc - configuration files for Mercurial
8
8
9 SYNOPSIS
9 SYNOPSIS
10 --------
10 --------
11
11
12 The Mercurial system uses a set of configuration files to control
12 The Mercurial system uses a set of configuration files to control
13 aspects of its behaviour.
13 aspects of its behaviour.
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 The names of these files depend on the system on which Mercurial is
19 The names of these files depend on the system on which Mercurial is
20 installed.
20 installed.
21
21
22 (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc::
22 (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc::
23 (Unix) <install-root>/etc/mercurial/hgrc::
23 (Unix) <install-root>/etc/mercurial/hgrc::
24 Per-installation configuration files, searched for in the
24 Per-installation configuration files, searched for in the
25 directory where Mercurial is installed. For example, if installed
25 directory where Mercurial is installed. For example, if installed
26 in /shared/tools, Mercurial will look in
26 in /shared/tools, Mercurial will look in
27 /shared/tools/etc/mercurial/hgrc. Options in these files apply to
27 /shared/tools/etc/mercurial/hgrc. Options in these files apply to
28 all Mercurial commands executed by any user in any directory.
28 all Mercurial commands executed by any user in any directory.
29
29
30 (Unix) /etc/mercurial/hgrc.d/*.rc::
30 (Unix) /etc/mercurial/hgrc.d/*.rc::
31 (Unix) /etc/mercurial/hgrc::
31 (Unix) /etc/mercurial/hgrc::
32 (Windows) C:\Mercurial\Mercurial.ini::
32 (Windows) C:\Mercurial\Mercurial.ini::
33 Per-system configuration files, for the system on which Mercurial
33 Per-system configuration files, for the system on which Mercurial
34 is running. Options in these files apply to all Mercurial
34 is running. Options in these files apply to all Mercurial
35 commands executed by any user in any directory. Options in these
35 commands executed by any user in any directory. Options in these
36 files override per-installation options.
36 files override per-installation options.
37
37
38 (Unix) $HOME/.hgrc::
38 (Unix) $HOME/.hgrc::
39 (Windows) C:\Documents and Settings\USERNAME\Mercurial.ini::
39 (Windows) C:\Documents and Settings\USERNAME\Mercurial.ini::
40 (Windows) $HOME\Mercurial.ini::
40 (Windows) $HOME\Mercurial.ini::
41 Per-user configuration file, for the user running Mercurial.
41 Per-user configuration file, for the user running Mercurial.
42 Options in this file apply to all Mercurial commands executed by
42 Options in this file apply to all Mercurial commands executed by
43 any user in any directory. Options in this file override
43 any user in any directory. Options in this file override
44 per-installation and per-system options.
44 per-installation and per-system options.
45 On Windows system, one of these is chosen exclusively according
45 On Windows system, one of these is chosen exclusively according
46 to definition of HOME environment variable.
46 to definition of HOME environment variable.
47
47
48 (Unix, Windows) <repo>/.hg/hgrc::
48 (Unix, Windows) <repo>/.hg/hgrc::
49 Per-repository configuration options that only apply in a
49 Per-repository configuration options that only apply in a
50 particular repository. This file is not version-controlled, and
50 particular repository. This file is not version-controlled, and
51 will not get transferred during a "clone" operation. Options in
51 will not get transferred during a "clone" operation. Options in
52 this file override options in all other configuration files.
52 this file override options in all other configuration files.
53 On Unix, most of this file will be ignored if it doesn't belong
53 On Unix, most of this file will be ignored if it doesn't belong
54 to a trusted user or to a trusted group. See the documentation
54 to a trusted user or to a trusted group. See the documentation
55 for the trusted section below for more details.
55 for the trusted section below for more details.
56
56
57 SYNTAX
57 SYNTAX
58 ------
58 ------
59
59
60 A configuration file consists of sections, led by a "[section]" header
60 A configuration file consists of sections, led by a "[section]" header
61 and followed by "name: value" entries; "name=value" is also accepted.
61 and followed by "name: value" entries; "name=value" is also accepted.
62
62
63 [spam]
63 [spam]
64 eggs=ham
64 eggs=ham
65 green=
65 green=
66 eggs
66 eggs
67
67
68 Each line contains one entry. If the lines that follow are indented,
68 Each line contains one entry. If the lines that follow are indented,
69 they are treated as continuations of that entry.
69 they are treated as continuations of that entry.
70
70
71 Leading whitespace is removed from values. Empty lines are skipped.
71 Leading whitespace is removed from values. Empty lines are skipped.
72
72
73 The optional values can contain format strings which refer to other
73 The optional values can contain format strings which refer to other
74 values in the same section, or values in a special DEFAULT section.
74 values in the same section, or values in a special DEFAULT section.
75
75
76 Lines beginning with "#" or ";" are ignored and may be used to provide
76 Lines beginning with "#" or ";" are ignored and may be used to provide
77 comments.
77 comments.
78
78
79 SECTIONS
79 SECTIONS
80 --------
80 --------
81
81
82 This section describes the different sections that may appear in a
82 This section describes the different sections that may appear in a
83 Mercurial "hgrc" file, the purpose of each section, its possible
83 Mercurial "hgrc" file, the purpose of each section, its possible
84 keys, and their possible values.
84 keys, and their possible values.
85
85
86 decode/encode::
86 decode/encode::
87 Filters for transforming files on checkout/checkin. This would
87 Filters for transforming files on checkout/checkin. This would
88 typically be used for newline processing or other
88 typically be used for newline processing or other
89 localization/canonicalization of files.
89 localization/canonicalization of files.
90
90
91 Filters consist of a filter pattern followed by a filter command.
91 Filters consist of a filter pattern followed by a filter command.
92 Filter patterns are globs by default, rooted at the repository
92 Filter patterns are globs by default, rooted at the repository
93 root. For example, to match any file ending in ".txt" in the root
93 root. For example, to match any file ending in ".txt" in the root
94 directory only, use the pattern "*.txt". To match any file ending
94 directory only, use the pattern "*.txt". To match any file ending
95 in ".c" anywhere in the repository, use the pattern "**.c".
95 in ".c" anywhere in the repository, use the pattern "**.c".
96
96
97 The filter command can start with a specifier, either "pipe:" or
97 The filter command can start with a specifier, either "pipe:" or
98 "tempfile:". If no specifier is given, "pipe:" is used by default.
98 "tempfile:". If no specifier is given, "pipe:" is used by default.
99
99
100 A "pipe:" command must accept data on stdin and return the
100 A "pipe:" command must accept data on stdin and return the
101 transformed data on stdout.
101 transformed data on stdout.
102
102
103 Pipe example:
103 Pipe example:
104
104
105 [encode]
105 [encode]
106 # uncompress gzip files on checkin to improve delta compression
106 # uncompress gzip files on checkin to improve delta compression
107 # note: not necessarily a good idea, just an example
107 # note: not necessarily a good idea, just an example
108 *.gz = pipe: gunzip
108 *.gz = pipe: gunzip
109
109
110 [decode]
110 [decode]
111 # recompress gzip files when writing them to the working dir (we
111 # recompress gzip files when writing them to the working dir (we
112 # can safely omit "pipe:", because it's the default)
112 # can safely omit "pipe:", because it's the default)
113 *.gz = gzip
113 *.gz = gzip
114
114
115 A "tempfile:" command is a template. The string INFILE is replaced
115 A "tempfile:" command is a template. The string INFILE is replaced
116 with the name of a temporary file that contains the data to be
116 with the name of a temporary file that contains the data to be
117 filtered by the command. The string OUTFILE is replaced with the
117 filtered by the command. The string OUTFILE is replaced with the
118 name of an empty temporary file, where the filtered data must be
118 name of an empty temporary file, where the filtered data must be
119 written by the command.
119 written by the command.
120
120
121 NOTE: the tempfile mechanism is recommended for Windows systems,
121 NOTE: the tempfile mechanism is recommended for Windows systems,
122 where the standard shell I/O redirection operators often have
122 where the standard shell I/O redirection operators often have
123 strange effects. In particular, if you are doing line ending
123 strange effects. In particular, if you are doing line ending
124 conversion on Windows using the popular dos2unix and unix2dos
124 conversion on Windows using the popular dos2unix and unix2dos
125 programs, you *must* use the tempfile mechanism, as using pipes will
125 programs, you *must* use the tempfile mechanism, as using pipes will
126 corrupt the contents of your files.
126 corrupt the contents of your files.
127
127
128 Tempfile example:
128 Tempfile example:
129
129
130 [encode]
130 [encode]
131 # convert files to unix line ending conventions on checkin
131 # convert files to unix line ending conventions on checkin
132 **.txt = tempfile: dos2unix -n INFILE OUTFILE
132 **.txt = tempfile: dos2unix -n INFILE OUTFILE
133
133
134 [decode]
134 [decode]
135 # convert files to windows line ending conventions when writing
135 # convert files to windows line ending conventions when writing
136 # them to the working dir
136 # them to the working dir
137 **.txt = tempfile: unix2dos -n INFILE OUTFILE
137 **.txt = tempfile: unix2dos -n INFILE OUTFILE
138
138
139 defaults::
139 defaults::
140 Use the [defaults] section to define command defaults, i.e. the
140 Use the [defaults] section to define command defaults, i.e. the
141 default options/arguments to pass to the specified commands.
141 default options/arguments to pass to the specified commands.
142
142
143 The following example makes 'hg log' run in verbose mode, and
143 The following example makes 'hg log' run in verbose mode, and
144 'hg status' show only the modified files, by default.
144 'hg status' show only the modified files, by default.
145
145
146 [defaults]
146 [defaults]
147 log = -v
147 log = -v
148 status = -m
148 status = -m
149
149
150 The actual commands, instead of their aliases, must be used when
150 The actual commands, instead of their aliases, must be used when
151 defining command defaults. The command defaults will also be
151 defining command defaults. The command defaults will also be
152 applied to the aliases of the commands defined.
152 applied to the aliases of the commands defined.
153
153
154 diff::
154 diff::
155 Settings used when displaying diffs. They are all boolean and
155 Settings used when displaying diffs. They are all boolean and
156 defaults to False.
156 defaults to False.
157 git;;
157 git;;
158 Use git extended diff format.
158 Use git extended diff format.
159 nodates;;
159 nodates;;
160 Don't include dates in diff headers.
160 Don't include dates in diff headers.
161 showfunc;;
161 showfunc;;
162 Show which function each change is in.
162 Show which function each change is in.
163 ignorews;;
163 ignorews;;
164 Ignore white space when comparing lines.
164 Ignore white space when comparing lines.
165 ignorewsamount;;
165 ignorewsamount;;
166 Ignore changes in the amount of white space.
166 Ignore changes in the amount of white space.
167 ignoreblanklines;;
167 ignoreblanklines;;
168 Ignore changes whose lines are all blank.
168 Ignore changes whose lines are all blank.
169
169
170 email::
170 email::
171 Settings for extensions that send email messages.
171 Settings for extensions that send email messages.
172 from;;
172 from;;
173 Optional. Email address to use in "From" header and SMTP envelope
173 Optional. Email address to use in "From" header and SMTP envelope
174 of outgoing messages.
174 of outgoing messages.
175 to;;
175 to;;
176 Optional. Comma-separated list of recipients' email addresses.
176 Optional. Comma-separated list of recipients' email addresses.
177 cc;;
177 cc;;
178 Optional. Comma-separated list of carbon copy recipients'
178 Optional. Comma-separated list of carbon copy recipients'
179 email addresses.
179 email addresses.
180 bcc;;
180 bcc;;
181 Optional. Comma-separated list of blind carbon copy
181 Optional. Comma-separated list of blind carbon copy
182 recipients' email addresses. Cannot be set interactively.
182 recipients' email addresses. Cannot be set interactively.
183 method;;
183 method;;
184 Optional. Method to use to send email messages. If value is
184 Optional. Method to use to send email messages. If value is
185 "smtp" (default), use SMTP (see section "[smtp]" for
185 "smtp" (default), use SMTP (see section "[smtp]" for
186 configuration). Otherwise, use as name of program to run that
186 configuration). Otherwise, use as name of program to run that
187 acts like sendmail (takes "-f" option for sender, list of
187 acts like sendmail (takes "-f" option for sender, list of
188 recipients on command line, message on stdin). Normally, setting
188 recipients on command line, message on stdin). Normally, setting
189 this to "sendmail" or "/usr/sbin/sendmail" is enough to use
189 this to "sendmail" or "/usr/sbin/sendmail" is enough to use
190 sendmail to send messages.
190 sendmail to send messages.
191
191
192 Email example:
192 Email example:
193
193
194 [email]
194 [email]
195 from = Joseph User <joe.user@example.com>
195 from = Joseph User <joe.user@example.com>
196 method = /usr/sbin/sendmail
196 method = /usr/sbin/sendmail
197
197
198 extensions::
198 extensions::
199 Mercurial has an extension mechanism for adding new features. To
199 Mercurial has an extension mechanism for adding new features. To
200 enable an extension, create an entry for it in this section.
200 enable an extension, create an entry for it in this section.
201
201
202 If you know that the extension is already in Python's search path,
202 If you know that the extension is already in Python's search path,
203 you can give the name of the module, followed by "=", with nothing
203 you can give the name of the module, followed by "=", with nothing
204 after the "=".
204 after the "=".
205
205
206 Otherwise, give a name that you choose, followed by "=", followed by
206 Otherwise, give a name that you choose, followed by "=", followed by
207 the path to the ".py" file (including the file name extension) that
207 the path to the ".py" file (including the file name extension) that
208 defines the extension.
208 defines the extension.
209
209
210 Example for ~/.hgrc:
210 Example for ~/.hgrc:
211
211
212 [extensions]
212 [extensions]
213 # (the mq extension will get loaded from mercurial's path)
213 # (the mq extension will get loaded from mercurial's path)
214 hgext.mq =
214 hgext.mq =
215 # (this extension will get loaded from the file specified)
215 # (this extension will get loaded from the file specified)
216 myfeature = ~/.hgext/myfeature.py
216 myfeature = ~/.hgext/myfeature.py
217
217
218 format::
218 format::
219
219
220 usestore;;
220 usestore;;
221 Enable or disable the "store" repository format which improves
221 Enable or disable the "store" repository format which improves
222 compatibility with systems that fold case or otherwise mangle
222 compatibility with systems that fold case or otherwise mangle
223 filenames. Enabled by default. Disabling this option will allow
223 filenames. Enabled by default. Disabling this option will allow
224 you to store longer filenames in some situations at the expense of
224 you to store longer filenames in some situations at the expense of
225 compatibility.
225 compatibility.
226
226
227 hooks::
227 hooks::
228 Commands or Python functions that get automatically executed by
228 Commands or Python functions that get automatically executed by
229 various actions such as starting or finishing a commit. Multiple
229 various actions such as starting or finishing a commit. Multiple
230 hooks can be run for the same action by appending a suffix to the
230 hooks can be run for the same action by appending a suffix to the
231 action. Overriding a site-wide hook can be done by changing its
231 action. Overriding a site-wide hook can be done by changing its
232 value or setting it to an empty string.
232 value or setting it to an empty string.
233
233
234 Example .hg/hgrc:
234 Example .hg/hgrc:
235
235
236 [hooks]
236 [hooks]
237 # do not use the site-wide hook
237 # do not use the site-wide hook
238 incoming =
238 incoming =
239 incoming.email = /my/email/hook
239 incoming.email = /my/email/hook
240 incoming.autobuild = /my/build/hook
240 incoming.autobuild = /my/build/hook
241
241
242 Most hooks are run with environment variables set that give added
242 Most hooks are run with environment variables set that give added
243 useful information. For each hook below, the environment variables
243 useful information. For each hook below, the environment variables
244 it is passed are listed with names of the form "$HG_foo".
244 it is passed are listed with names of the form "$HG_foo".
245
245
246 changegroup;;
246 changegroup;;
247 Run after a changegroup has been added via push, pull or
247 Run after a changegroup has been added via push, pull or
248 unbundle. ID of the first new changeset is in $HG_NODE. URL from
248 unbundle. ID of the first new changeset is in $HG_NODE. URL from
249 which changes came is in $HG_URL.
249 which changes came is in $HG_URL.
250 commit;;
250 commit;;
251 Run after a changeset has been created in the local repository.
251 Run after a changeset has been created in the local repository.
252 ID of the newly created changeset is in $HG_NODE. Parent
252 ID of the newly created changeset is in $HG_NODE. Parent
253 changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
253 changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
254 incoming;;
254 incoming;;
255 Run after a changeset has been pulled, pushed, or unbundled into
255 Run after a changeset has been pulled, pushed, or unbundled into
256 the local repository. The ID of the newly arrived changeset is in
256 the local repository. The ID of the newly arrived changeset is in
257 $HG_NODE. URL that was source of changes came is in $HG_URL.
257 $HG_NODE. URL that was source of changes came is in $HG_URL.
258 outgoing;;
258 outgoing;;
259 Run after sending changes from local repository to another. ID of
259 Run after sending changes from local repository to another. ID of
260 first changeset sent is in $HG_NODE. Source of operation is in
260 first changeset sent is in $HG_NODE. Source of operation is in
261 $HG_SOURCE; see "preoutgoing" hook for description.
261 $HG_SOURCE; see "preoutgoing" hook for description.
262 prechangegroup;;
262 prechangegroup;;
263 Run before a changegroup is added via push, pull or unbundle.
263 Run before a changegroup is added via push, pull or unbundle.
264 Exit status 0 allows the changegroup to proceed. Non-zero status
264 Exit status 0 allows the changegroup to proceed. Non-zero status
265 will cause the push, pull or unbundle to fail. URL from which
265 will cause the push, pull or unbundle to fail. URL from which
266 changes will come is in $HG_URL.
266 changes will come is in $HG_URL.
267 precommit;;
267 precommit;;
268 Run before starting a local commit. Exit status 0 allows the
268 Run before starting a local commit. Exit status 0 allows the
269 commit to proceed. Non-zero status will cause the commit to fail.
269 commit to proceed. Non-zero status will cause the commit to fail.
270 Parent changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
270 Parent changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
271 preoutgoing;;
271 preoutgoing;;
272 Run before computing changes to send from the local repository to
272 Run before computing changes to send from the local repository to
273 another. Non-zero status will cause failure. This lets you
273 another. Non-zero status will cause failure. This lets you
274 prevent pull over http or ssh. Also prevents against local pull,
274 prevent pull over http or ssh. Also prevents against local pull,
275 push (outbound) or bundle commands, but not effective, since you
275 push (outbound) or bundle commands, but not effective, since you
276 can just copy files instead then. Source of operation is in
276 can just copy files instead then. Source of operation is in
277 $HG_SOURCE. If "serve", operation is happening on behalf of
277 $HG_SOURCE. If "serve", operation is happening on behalf of
278 remote ssh or http repository. If "push", "pull" or "bundle",
278 remote ssh or http repository. If "push", "pull" or "bundle",
279 operation is happening on behalf of repository on same system.
279 operation is happening on behalf of repository on same system.
280 pretag;;
280 pretag;;
281 Run before creating a tag. Exit status 0 allows the tag to be
281 Run before creating a tag. Exit status 0 allows the tag to be
282 created. Non-zero status will cause the tag to fail. ID of
282 created. Non-zero status will cause the tag to fail. ID of
283 changeset to tag is in $HG_NODE. Name of tag is in $HG_TAG. Tag
283 changeset to tag is in $HG_NODE. Name of tag is in $HG_TAG. Tag
284 is local if $HG_LOCAL=1, in repo if $HG_LOCAL=0.
284 is local if $HG_LOCAL=1, in repo if $HG_LOCAL=0.
285 pretxnchangegroup;;
285 pretxnchangegroup;;
286 Run after a changegroup has been added via push, pull or unbundle,
286 Run after a changegroup has been added via push, pull or unbundle,
287 but before the transaction has been committed. Changegroup is
287 but before the transaction has been committed. Changegroup is
288 visible to hook program. This lets you validate incoming changes
288 visible to hook program. This lets you validate incoming changes
289 before accepting them. Passed the ID of the first new changeset
289 before accepting them. Passed the ID of the first new changeset
290 in $HG_NODE. Exit status 0 allows the transaction to commit.
290 in $HG_NODE. Exit status 0 allows the transaction to commit.
291 Non-zero status will cause the transaction to be rolled back and
291 Non-zero status will cause the transaction to be rolled back and
292 the push, pull or unbundle will fail. URL that was source of
292 the push, pull or unbundle will fail. URL that was source of
293 changes is in $HG_URL.
293 changes is in $HG_URL.
294 pretxncommit;;
294 pretxncommit;;
295 Run after a changeset has been created but the transaction not yet
295 Run after a changeset has been created but the transaction not yet
296 committed. Changeset is visible to hook program. This lets you
296 committed. Changeset is visible to hook program. This lets you
297 validate commit message and changes. Exit status 0 allows the
297 validate commit message and changes. Exit status 0 allows the
298 commit to proceed. Non-zero status will cause the transaction to
298 commit to proceed. Non-zero status will cause the transaction to
299 be rolled back. ID of changeset is in $HG_NODE. Parent changeset
299 be rolled back. ID of changeset is in $HG_NODE. Parent changeset
300 IDs are in $HG_PARENT1 and $HG_PARENT2.
300 IDs are in $HG_PARENT1 and $HG_PARENT2.
301 preupdate;;
301 preupdate;;
302 Run before updating the working directory. Exit status 0 allows
302 Run before updating the working directory. Exit status 0 allows
303 the update to proceed. Non-zero status will prevent the update.
303 the update to proceed. Non-zero status will prevent the update.
304 Changeset ID of first new parent is in $HG_PARENT1. If merge, ID
304 Changeset ID of first new parent is in $HG_PARENT1. If merge, ID
305 of second new parent is in $HG_PARENT2.
305 of second new parent is in $HG_PARENT2.
306 tag;;
306 tag;;
307 Run after a tag is created. ID of tagged changeset is in
307 Run after a tag is created. ID of tagged changeset is in
308 $HG_NODE. Name of tag is in $HG_TAG. Tag is local if
308 $HG_NODE. Name of tag is in $HG_TAG. Tag is local if
309 $HG_LOCAL=1, in repo if $HG_LOCAL=0.
309 $HG_LOCAL=1, in repo if $HG_LOCAL=0.
310 update;;
310 update;;
311 Run after updating the working directory. Changeset ID of first
311 Run after updating the working directory. Changeset ID of first
312 new parent is in $HG_PARENT1. If merge, ID of second new parent
312 new parent is in $HG_PARENT1. If merge, ID of second new parent
313 is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update
313 is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update
314 failed (e.g. because conflicts not resolved), $HG_ERROR=1.
314 failed (e.g. because conflicts not resolved), $HG_ERROR=1.
315 pre-<command>;;
315 pre-<command>;;
316 Run before executing the associated command. The contents of the
316 Run before executing the associated command. The contents of the
317 command line are passed as $HG_ARGS. If the hook returns failure,
317 command line are passed as $HG_ARGS. If the hook returns failure,
318 the command doesn't execute and Mercurial returns the failure code.
318 the command doesn't execute and Mercurial returns the failure code.
319 post-<command>;;
319 post-<command>;;
320 Run after successful invocations of the associated command. The
320 Run after successful invocations of the associated command. The
321 contents of the command line are passed as $HG_ARGS and the result
321 contents of the command line are passed as $HG_ARGS and the result
322 code in $HG_RESULT. Hook failure is ignored.
322 code in $HG_RESULT. Hook failure is ignored.
323
323
324 Note: it is generally better to use standard hooks rather than the
324 Note: it is generally better to use standard hooks rather than the
325 generic pre- and post- command hooks as they are guaranteed to be
325 generic pre- and post- command hooks as they are guaranteed to be
326 called in the appropriate contexts for influencing transactions.
326 called in the appropriate contexts for influencing transactions.
327 Also, hooks like "commit" will be called in all contexts that
327 Also, hooks like "commit" will be called in all contexts that
328 generate a commit (eg. tag) and not just the commit command.
328 generate a commit (eg. tag) and not just the commit command.
329
329
330 Note2: Environment variables with empty values may not be passed to
330 Note2: Environment variables with empty values may not be passed to
331 hooks on platforms like Windows. For instance, $HG_PARENT2 will
331 hooks on platforms like Windows. For instance, $HG_PARENT2 will
332 not be available under Windows for non-merge changesets while being
332 not be available under Windows for non-merge changesets while being
333 set to an empty value under Unix-like systems.
333 set to an empty value under Unix-like systems.
334
334
335 The syntax for Python hooks is as follows:
335 The syntax for Python hooks is as follows:
336
336
337 hookname = python:modulename.submodule.callable
337 hookname = python:modulename.submodule.callable
338
338
339 Python hooks are run within the Mercurial process. Each hook is
339 Python hooks are run within the Mercurial process. Each hook is
340 called with at least three keyword arguments: a ui object (keyword
340 called with at least three keyword arguments: a ui object (keyword
341 "ui"), a repository object (keyword "repo"), and a "hooktype"
341 "ui"), a repository object (keyword "repo"), and a "hooktype"
342 keyword that tells what kind of hook is used. Arguments listed as
342 keyword that tells what kind of hook is used. Arguments listed as
343 environment variables above are passed as keyword arguments, with no
343 environment variables above are passed as keyword arguments, with no
344 "HG_" prefix, and names in lower case.
344 "HG_" prefix, and names in lower case.
345
345
346 If a Python hook returns a "true" value or raises an exception, this
346 If a Python hook returns a "true" value or raises an exception, this
347 is treated as failure of the hook.
347 is treated as failure of the hook.
348
348
349 http_proxy::
349 http_proxy::
350 Used to access web-based Mercurial repositories through a HTTP
350 Used to access web-based Mercurial repositories through a HTTP
351 proxy.
351 proxy.
352 host;;
352 host;;
353 Host name and (optional) port of the proxy server, for example
353 Host name and (optional) port of the proxy server, for example
354 "myproxy:8000".
354 "myproxy:8000".
355 no;;
355 no;;
356 Optional. Comma-separated list of host names that should bypass
356 Optional. Comma-separated list of host names that should bypass
357 the proxy.
357 the proxy.
358 passwd;;
358 passwd;;
359 Optional. Password to authenticate with at the proxy server.
359 Optional. Password to authenticate with at the proxy server.
360 user;;
360 user;;
361 Optional. User name to authenticate with at the proxy server.
361 Optional. User name to authenticate with at the proxy server.
362
362
363 smtp::
363 smtp::
364 Configuration for extensions that need to send email messages.
364 Configuration for extensions that need to send email messages.
365 host;;
365 host;;
366 Host name of mail server, e.g. "mail.example.com".
366 Host name of mail server, e.g. "mail.example.com".
367 port;;
367 port;;
368 Optional. Port to connect to on mail server. Default: 25.
368 Optional. Port to connect to on mail server. Default: 25.
369 tls;;
369 tls;;
370 Optional. Whether to connect to mail server using TLS. True or
370 Optional. Whether to connect to mail server using TLS. True or
371 False. Default: False.
371 False. Default: False.
372 username;;
372 username;;
373 Optional. User name to authenticate to SMTP server with.
373 Optional. User name to authenticate to SMTP server with.
374 If username is specified, password must also be specified.
374 If username is specified, password must also be specified.
375 Default: none.
375 Default: none.
376 password;;
376 password;;
377 Optional. Password to authenticate to SMTP server with.
377 Optional. Password to authenticate to SMTP server with.
378 If username is specified, password must also be specified.
378 If username is specified, password must also be specified.
379 Default: none.
379 Default: none.
380 local_hostname;;
380 local_hostname;;
381 Optional. It's the hostname that the sender can use to identify itself
381 Optional. It's the hostname that the sender can use to identify itself
382 to the MTA.
382 to the MTA.
383
383
384 paths::
384 paths::
385 Assigns symbolic names to repositories. The left side is the
385 Assigns symbolic names to repositories. The left side is the
386 symbolic name, and the right gives the directory or URL that is the
386 symbolic name, and the right gives the directory or URL that is the
387 location of the repository. Default paths can be declared by
387 location of the repository. Default paths can be declared by
388 setting the following entries.
388 setting the following entries.
389 default;;
389 default;;
390 Directory or URL to use when pulling if no source is specified.
390 Directory or URL to use when pulling if no source is specified.
391 Default is set to repository from which the current repository
391 Default is set to repository from which the current repository
392 was cloned.
392 was cloned.
393 default-push;;
393 default-push;;
394 Optional. Directory or URL to use when pushing if no destination
394 Optional. Directory or URL to use when pushing if no destination
395 is specified.
395 is specified.
396
396
397 server::
397 server::
398 Controls generic server settings.
398 Controls generic server settings.
399 uncompressed;;
399 uncompressed;;
400 Whether to allow clients to clone a repo using the uncompressed
400 Whether to allow clients to clone a repo using the uncompressed
401 streaming protocol. This transfers about 40% more data than a
401 streaming protocol. This transfers about 40% more data than a
402 regular clone, but uses less memory and CPU on both server and
402 regular clone, but uses less memory and CPU on both server and
403 client. Over a LAN (100Mbps or better) or a very fast WAN, an
403 client. Over a LAN (100Mbps or better) or a very fast WAN, an
404 uncompressed streaming clone is a lot faster (~10x) than a regular
404 uncompressed streaming clone is a lot faster (~10x) than a regular
405 clone. Over most WAN connections (anything slower than about
405 clone. Over most WAN connections (anything slower than about
406 6Mbps), uncompressed streaming is slower, because of the extra
406 6Mbps), uncompressed streaming is slower, because of the extra
407 data transfer overhead. Default is False.
407 data transfer overhead. Default is False.
408
408
409 trusted::
409 trusted::
410 For security reasons, Mercurial will not use the settings in
410 For security reasons, Mercurial will not use the settings in
411 the .hg/hgrc file from a repository if it doesn't belong to a
411 the .hg/hgrc file from a repository if it doesn't belong to a
412 trusted user or to a trusted group. The main exception is the
412 trusted user or to a trusted group. The main exception is the
413 web interface, which automatically uses some safe settings, since
413 web interface, which automatically uses some safe settings, since
414 it's common to serve repositories from different users.
414 it's common to serve repositories from different users.
415
415
416 This section specifies what users and groups are trusted. The
416 This section specifies what users and groups are trusted. The
417 current user is always trusted. To trust everybody, list a user
417 current user is always trusted. To trust everybody, list a user
418 or a group with name "*".
418 or a group with name "*".
419
419
420 users;;
420 users;;
421 Comma-separated list of trusted users.
421 Comma-separated list of trusted users.
422 groups;;
422 groups;;
423 Comma-separated list of trusted groups.
423 Comma-separated list of trusted groups.
424
424
425 ui::
425 ui::
426 User interface controls.
426 User interface controls.
427 debug;;
427 debug;;
428 Print debugging information. True or False. Default is False.
428 Print debugging information. True or False. Default is False.
429 editor;;
429 editor;;
430 The editor to use during a commit. Default is $EDITOR or "vi".
430 The editor to use during a commit. Default is $EDITOR or "vi".
431 fallbackencoding;;
431 fallbackencoding;;
432 Encoding to try if it's not possible to decode the changelog using
432 Encoding to try if it's not possible to decode the changelog using
433 UTF-8. Default is ISO-8859-1.
433 UTF-8. Default is ISO-8859-1.
434 ignore;;
434 ignore;;
435 A file to read per-user ignore patterns from. This file should be in
435 A file to read per-user ignore patterns from. This file should be in
436 the same format as a repository-wide .hgignore file. This option
436 the same format as a repository-wide .hgignore file. This option
437 supports hook syntax, so if you want to specify multiple ignore
437 supports hook syntax, so if you want to specify multiple ignore
438 files, you can do so by setting something like
438 files, you can do so by setting something like
439 "ignore.other = ~/.hgignore2". For details of the ignore file
439 "ignore.other = ~/.hgignore2". For details of the ignore file
440 format, see the hgignore(5) man page.
440 format, see the hgignore(5) man page.
441 interactive;;
441 interactive;;
442 Allow to prompt the user. True or False. Default is True.
442 Allow to prompt the user. True or False. Default is True.
443 logtemplate;;
443 logtemplate;;
444 Template string for commands that print changesets.
444 Template string for commands that print changesets.
445 style;;
445 style;;
446 Name of style to use for command output.
446 Name of style to use for command output.
447 merge;;
447 merge;;
448 The conflict resolution program to use during a manual merge.
448 The conflict resolution program to use during a manual merge.
449 Default is "hgmerge".
449 Default is "hgmerge".
450 patch;;
450 patch;;
451 command to use to apply patches. Look for 'gpatch' or 'patch' in PATH if
451 command to use to apply patches. Look for 'gpatch' or 'patch' in PATH if
452 unset.
452 unset.
453 quiet;;
453 quiet;;
454 Reduce the amount of output printed. True or False. Default is False.
454 Reduce the amount of output printed. True or False. Default is False.
455 remotecmd;;
455 remotecmd;;
456 remote command to use for clone/push/pull operations. Default is 'hg'.
456 remote command to use for clone/push/pull operations. Default is 'hg'.
457 slash;;
457 slash;;
458 Display paths using a slash ("/") as the path separator. This only
458 Display paths using a slash ("/") as the path separator. This only
459 makes a difference on systems where the default path separator is not
459 makes a difference on systems where the default path separator is not
460 the slash character (e.g. Windows uses the backslash character ("\")).
460 the slash character (e.g. Windows uses the backslash character ("\")).
461 Default is False.
461 Default is False.
462 ssh;;
462 ssh;;
463 command to use for SSH connections. Default is 'ssh'.
463 command to use for SSH connections. Default is 'ssh'.
464 strict;;
464 strict;;
465 Require exact command names, instead of allowing unambiguous
465 Require exact command names, instead of allowing unambiguous
466 abbreviations. True or False. Default is False.
466 abbreviations. True or False. Default is False.
467 timeout;;
467 timeout;;
468 The timeout used when a lock is held (in seconds), a negative value
468 The timeout used when a lock is held (in seconds), a negative value
469 means no timeout. Default is 600.
469 means no timeout. Default is 600.
470 username;;
470 username;;
471 The committer of a changeset created when running "commit".
471 The committer of a changeset created when running "commit".
472 Typically a person's name and email address, e.g. "Fred Widget
472 Typically a person's name and email address, e.g. "Fred Widget
473 <fred@example.com>". Default is $EMAIL or username@hostname.
473 <fred@example.com>". Default is $EMAIL or username@hostname.
474 If the username in hgrc is empty, it has to be specified manually or
474 If the username in hgrc is empty, it has to be specified manually or
475 in a different hgrc file (e.g. $HOME/.hgrc, if the admin set "username ="
475 in a different hgrc file (e.g. $HOME/.hgrc, if the admin set "username ="
476 in the system hgrc).
476 in the system hgrc).
477 verbose;;
477 verbose;;
478 Increase the amount of output printed. True or False. Default is False.
478 Increase the amount of output printed. True or False. Default is False.
479
479
480
480
481 web::
481 web::
482 Web interface configuration.
482 Web interface configuration.
483 accesslog;;
483 accesslog;;
484 Where to output the access log. Default is stdout.
484 Where to output the access log. Default is stdout.
485 address;;
485 address;;
486 Interface address to bind to. Default is all.
486 Interface address to bind to. Default is all.
487 allow_archive;;
487 allow_archive;;
488 List of archive format (bz2, gz, zip) allowed for downloading.
488 List of archive format (bz2, gz, zip) allowed for downloading.
489 Default is empty.
489 Default is empty.
490 allowbz2;;
490 allowbz2;;
491 (DEPRECATED) Whether to allow .tar.bz2 downloading of repo revisions.
491 (DEPRECATED) Whether to allow .tar.bz2 downloading of repo revisions.
492 Default is false.
492 Default is false.
493 allowgz;;
493 allowgz;;
494 (DEPRECATED) Whether to allow .tar.gz downloading of repo revisions.
494 (DEPRECATED) Whether to allow .tar.gz downloading of repo revisions.
495 Default is false.
495 Default is false.
496 allowpull;;
496 allowpull;;
497 Whether to allow pulling from the repository. Default is true.
497 Whether to allow pulling from the repository. Default is true.
498 allow_push;;
498 allow_push;;
499 Whether to allow pushing to the repository. If empty or not set,
499 Whether to allow pushing to the repository. If empty or not set,
500 push is not allowed. If the special value "*", any remote user
500 push is not allowed. If the special value "*", any remote user
501 can push, including unauthenticated users. Otherwise, the remote
501 can push, including unauthenticated users. Otherwise, the remote
502 user must have been authenticated, and the authenticated user name
502 user must have been authenticated, and the authenticated user name
503 must be present in this list (separated by whitespace or ",").
503 must be present in this list (separated by whitespace or ",").
504 The contents of the allow_push list are examined after the
504 The contents of the allow_push list are examined after the
505 deny_push list.
505 deny_push list.
506 allowzip;;
506 allowzip;;
507 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
507 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
508 Default is false. This feature creates temporary files.
508 Default is false. This feature creates temporary files.
509 baseurl;;
509 baseurl;;
510 Base URL to use when publishing URLs in other locations, so
510 Base URL to use when publishing URLs in other locations, so
511 third-party tools like email notification hooks can construct URLs.
511 third-party tools like email notification hooks can construct URLs.
512 Example: "http://hgserver/repos/"
512 Example: "http://hgserver/repos/"
513 contact;;
513 contact;;
514 Name or email address of the person in charge of the repository.
514 Name or email address of the person in charge of the repository.
515 Default is "unknown".
515 Default is "unknown".
516 deny_push;;
516 deny_push;;
517 Whether to deny pushing to the repository. If empty or not set,
517 Whether to deny pushing to the repository. If empty or not set,
518 push is not denied. If the special value "*", all remote users
518 push is not denied. If the special value "*", all remote users
519 are denied push. Otherwise, unauthenticated users are all denied,
519 are denied push. Otherwise, unauthenticated users are all denied,
520 and any authenticated user name present in this list (separated by
520 and any authenticated user name present in this list (separated by
521 whitespace or ",") is also denied. The contents of the deny_push
521 whitespace or ",") is also denied. The contents of the deny_push
522 list are examined before the allow_push list.
522 list are examined before the allow_push list.
523 description;;
523 description;;
524 Textual description of the repository's purpose or contents.
524 Textual description of the repository's purpose or contents.
525 Default is "unknown".
525 Default is "unknown".
526 errorlog;;
526 errorlog;;
527 Where to output the error log. Default is stderr.
527 Where to output the error log. Default is stderr.
528 hidden;;
529 Whether to hide the repository in the hgwebdir index. Default is false.
528 ipv6;;
530 ipv6;;
529 Whether to use IPv6. Default is false.
531 Whether to use IPv6. Default is false.
530 name;;
532 name;;
531 Repository name to use in the web interface. Default is current
533 Repository name to use in the web interface. Default is current
532 working directory.
534 working directory.
533 maxchanges;;
535 maxchanges;;
534 Maximum number of changes to list on the changelog. Default is 10.
536 Maximum number of changes to list on the changelog. Default is 10.
535 maxfiles;;
537 maxfiles;;
536 Maximum number of files to list per changeset. Default is 10.
538 Maximum number of files to list per changeset. Default is 10.
537 port;;
539 port;;
538 Port to listen on. Default is 8000.
540 Port to listen on. Default is 8000.
539 push_ssl;;
541 push_ssl;;
540 Whether to require that inbound pushes be transported over SSL to
542 Whether to require that inbound pushes be transported over SSL to
541 prevent password sniffing. Default is true.
543 prevent password sniffing. Default is true.
542 staticurl;;
544 staticurl;;
543 Base URL to use for static files. If unset, static files (e.g.
545 Base URL to use for static files. If unset, static files (e.g.
544 the hgicon.png favicon) will be served by the CGI script itself.
546 the hgicon.png favicon) will be served by the CGI script itself.
545 Use this setting to serve them directly with the HTTP server.
547 Use this setting to serve them directly with the HTTP server.
546 Example: "http://hgserver/static/"
548 Example: "http://hgserver/static/"
547 stripes;;
549 stripes;;
548 How many lines a "zebra stripe" should span in multiline output.
550 How many lines a "zebra stripe" should span in multiline output.
549 Default is 1; set to 0 to disable.
551 Default is 1; set to 0 to disable.
550 style;;
552 style;;
551 Which template map style to use.
553 Which template map style to use.
552 templates;;
554 templates;;
553 Where to find the HTML templates. Default is install path.
555 Where to find the HTML templates. Default is install path.
554 encoding;;
556 encoding;;
555 Character encoding name.
557 Character encoding name.
556 Example: "UTF-8"
558 Example: "UTF-8"
557
559
558
560
559 AUTHOR
561 AUTHOR
560 ------
562 ------
561 Bryan O'Sullivan <bos@serpentine.com>.
563 Bryan O'Sullivan <bos@serpentine.com>.
562
564
563 Mercurial was written by Matt Mackall <mpm@selenic.com>.
565 Mercurial was written by Matt Mackall <mpm@selenic.com>.
564
566
565 SEE ALSO
567 SEE ALSO
566 --------
568 --------
567 hg(1), hgignore(5)
569 hg(1), hgignore(5)
568
570
569 COPYING
571 COPYING
570 -------
572 -------
571 This manual page is copyright 2005 Bryan O'Sullivan.
573 This manual page is copyright 2005 Bryan O'Sullivan.
572 Mercurial is copyright 2005-2007 Matt Mackall.
574 Mercurial is copyright 2005-2007 Matt Mackall.
573 Free use of this software is granted under the terms of the GNU General
575 Free use of this software is granted under the terms of the GNU General
574 Public License (GPL).
576 Public License (GPL).
@@ -1,237 +1,240 b''
1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms
6 # This software may be used and distributed according to the terms
7 # of the GNU General Public License, incorporated herein by reference.
7 # of the GNU General Public License, incorporated herein by reference.
8
8
9 from mercurial import demandimport; demandimport.enable()
9 from mercurial import demandimport; demandimport.enable()
10 import os, mimetools, cStringIO
10 import os, mimetools, cStringIO
11 from mercurial.i18n import gettext as _
11 from mercurial.i18n import gettext as _
12 from mercurial import ui, hg, util, templater
12 from mercurial import ui, hg, util, templater
13 from common import get_mtime, staticfile, style_map, paritygen
13 from common import get_mtime, staticfile, style_map, paritygen
14 from hgweb_mod import hgweb
14 from hgweb_mod import hgweb
15
15
16 # This is a stopgap
16 # This is a stopgap
17 class hgwebdir(object):
17 class hgwebdir(object):
18 def __init__(self, config, parentui=None):
18 def __init__(self, config, parentui=None):
19 def cleannames(items):
19 def cleannames(items):
20 return [(name.strip(os.sep), path) for name, path in items]
20 return [(name.strip(os.sep), path) for name, path in items]
21
21
22 self.parentui = parentui
22 self.parentui = parentui
23 self.motd = None
23 self.motd = None
24 self.style = None
24 self.style = None
25 self.stripecount = None
25 self.stripecount = None
26 self.repos_sorted = ('name', False)
26 self.repos_sorted = ('name', False)
27 if isinstance(config, (list, tuple)):
27 if isinstance(config, (list, tuple)):
28 self.repos = cleannames(config)
28 self.repos = cleannames(config)
29 self.repos_sorted = ('', False)
29 self.repos_sorted = ('', False)
30 elif isinstance(config, dict):
30 elif isinstance(config, dict):
31 self.repos = cleannames(config.items())
31 self.repos = cleannames(config.items())
32 self.repos.sort()
32 self.repos.sort()
33 else:
33 else:
34 if isinstance(config, util.configparser):
34 if isinstance(config, util.configparser):
35 cp = config
35 cp = config
36 else:
36 else:
37 cp = util.configparser()
37 cp = util.configparser()
38 cp.read(config)
38 cp.read(config)
39 self.repos = []
39 self.repos = []
40 if cp.has_section('web'):
40 if cp.has_section('web'):
41 if cp.has_option('web', 'motd'):
41 if cp.has_option('web', 'motd'):
42 self.motd = cp.get('web', 'motd')
42 self.motd = cp.get('web', 'motd')
43 if cp.has_option('web', 'style'):
43 if cp.has_option('web', 'style'):
44 self.style = cp.get('web', 'style')
44 self.style = cp.get('web', 'style')
45 if cp.has_option('web', 'stripes'):
45 if cp.has_option('web', 'stripes'):
46 self.stripecount = int(cp.get('web', 'stripes'))
46 self.stripecount = int(cp.get('web', 'stripes'))
47 if cp.has_section('paths'):
47 if cp.has_section('paths'):
48 self.repos.extend(cleannames(cp.items('paths')))
48 self.repos.extend(cleannames(cp.items('paths')))
49 if cp.has_section('collections'):
49 if cp.has_section('collections'):
50 for prefix, root in cp.items('collections'):
50 for prefix, root in cp.items('collections'):
51 for path in util.walkrepos(root):
51 for path in util.walkrepos(root):
52 repo = os.path.normpath(path)
52 repo = os.path.normpath(path)
53 name = repo
53 name = repo
54 if name.startswith(prefix):
54 if name.startswith(prefix):
55 name = name[len(prefix):]
55 name = name[len(prefix):]
56 self.repos.append((name.lstrip(os.sep), repo))
56 self.repos.append((name.lstrip(os.sep), repo))
57 self.repos.sort()
57 self.repos.sort()
58
58
59 def run(self):
59 def run(self):
60 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
60 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
61 raise RuntimeError("This function is only intended to be called while running as a CGI script.")
61 raise RuntimeError("This function is only intended to be called while running as a CGI script.")
62 import mercurial.hgweb.wsgicgi as wsgicgi
62 import mercurial.hgweb.wsgicgi as wsgicgi
63 from request import wsgiapplication
63 from request import wsgiapplication
64 def make_web_app():
64 def make_web_app():
65 return self
65 return self
66 wsgicgi.launch(wsgiapplication(make_web_app))
66 wsgicgi.launch(wsgiapplication(make_web_app))
67
67
68 def run_wsgi(self, req):
68 def run_wsgi(self, req):
69 def header(**map):
69 def header(**map):
70 header_file = cStringIO.StringIO(
70 header_file = cStringIO.StringIO(
71 ''.join(tmpl("header", encoding=util._encoding, **map)))
71 ''.join(tmpl("header", encoding=util._encoding, **map)))
72 msg = mimetools.Message(header_file, 0)
72 msg = mimetools.Message(header_file, 0)
73 req.header(msg.items())
73 req.header(msg.items())
74 yield header_file.read()
74 yield header_file.read()
75
75
76 def footer(**map):
76 def footer(**map):
77 yield tmpl("footer", **map)
77 yield tmpl("footer", **map)
78
78
79 def motd(**map):
79 def motd(**map):
80 if self.motd is not None:
80 if self.motd is not None:
81 yield self.motd
81 yield self.motd
82 else:
82 else:
83 yield config('web', 'motd', '')
83 yield config('web', 'motd', '')
84
84
85 parentui = self.parentui or ui.ui(report_untrusted=False)
85 parentui = self.parentui or ui.ui(report_untrusted=False)
86
86
87 def config(section, name, default=None, untrusted=True):
87 def config(section, name, default=None, untrusted=True):
88 return parentui.config(section, name, default, untrusted)
88 return parentui.config(section, name, default, untrusted)
89
89
90 url = req.env['REQUEST_URI'].split('?')[0]
90 url = req.env['REQUEST_URI'].split('?')[0]
91 if not url.endswith('/'):
91 if not url.endswith('/'):
92 url += '/'
92 url += '/'
93
93
94 staticurl = config('web', 'staticurl') or url + 'static/'
94 staticurl = config('web', 'staticurl') or url + 'static/'
95 if not staticurl.endswith('/'):
95 if not staticurl.endswith('/'):
96 staticurl += '/'
96 staticurl += '/'
97
97
98 style = self.style
98 style = self.style
99 if style is None:
99 if style is None:
100 style = config('web', 'style', '')
100 style = config('web', 'style', '')
101 if req.form.has_key('style'):
101 if req.form.has_key('style'):
102 style = req.form['style'][0]
102 style = req.form['style'][0]
103 if self.stripecount is None:
103 if self.stripecount is None:
104 self.stripecount = int(config('web', 'stripes', 1))
104 self.stripecount = int(config('web', 'stripes', 1))
105 mapfile = style_map(templater.templatepath(), style)
105 mapfile = style_map(templater.templatepath(), style)
106 tmpl = templater.templater(mapfile, templater.common_filters,
106 tmpl = templater.templater(mapfile, templater.common_filters,
107 defaults={"header": header,
107 defaults={"header": header,
108 "footer": footer,
108 "footer": footer,
109 "motd": motd,
109 "motd": motd,
110 "url": url,
110 "url": url,
111 "staticurl": staticurl})
111 "staticurl": staticurl})
112
112
113 def archivelist(ui, nodeid, url):
113 def archivelist(ui, nodeid, url):
114 allowed = ui.configlist("web", "allow_archive", untrusted=True)
114 allowed = ui.configlist("web", "allow_archive", untrusted=True)
115 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
115 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
116 if i[0] in allowed or ui.configbool("web", "allow" + i[0],
116 if i[0] in allowed or ui.configbool("web", "allow" + i[0],
117 untrusted=True):
117 untrusted=True):
118 yield {"type" : i[0], "extension": i[1],
118 yield {"type" : i[0], "extension": i[1],
119 "node": nodeid, "url": url}
119 "node": nodeid, "url": url}
120
120
121 def entries(sortcolumn="", descending=False, **map):
121 def entries(sortcolumn="", descending=False, **map):
122 def sessionvars(**map):
122 def sessionvars(**map):
123 fields = []
123 fields = []
124 if req.form.has_key('style'):
124 if req.form.has_key('style'):
125 style = req.form['style'][0]
125 style = req.form['style'][0]
126 if style != get('web', 'style', ''):
126 if style != get('web', 'style', ''):
127 fields.append(('style', style))
127 fields.append(('style', style))
128
128
129 separator = url[-1] == '?' and ';' or '?'
129 separator = url[-1] == '?' and ';' or '?'
130 for name, value in fields:
130 for name, value in fields:
131 yield dict(name=name, value=value, separator=separator)
131 yield dict(name=name, value=value, separator=separator)
132 separator = ';'
132 separator = ';'
133
133
134 rows = []
134 rows = []
135 parity = paritygen(self.stripecount)
135 parity = paritygen(self.stripecount)
136 for name, path in self.repos:
136 for name, path in self.repos:
137 u = ui.ui(parentui=parentui)
137 u = ui.ui(parentui=parentui)
138 try:
138 try:
139 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
139 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
140 except IOError:
140 except IOError:
141 pass
141 pass
142 def get(section, name, default=None):
142 def get(section, name, default=None):
143 return u.config(section, name, default, untrusted=True)
143 return u.config(section, name, default, untrusted=True)
144
144
145 if u.configbool("web", "hidden", untrusted=True):
146 continue
147
145 url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
148 url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
146 .replace("//", "/")) + '/'
149 .replace("//", "/")) + '/'
147
150
148 # update time with local timezone
151 # update time with local timezone
149 try:
152 try:
150 d = (get_mtime(path), util.makedate()[1])
153 d = (get_mtime(path), util.makedate()[1])
151 except OSError:
154 except OSError:
152 continue
155 continue
153
156
154 contact = (get("ui", "username") or # preferred
157 contact = (get("ui", "username") or # preferred
155 get("web", "contact") or # deprecated
158 get("web", "contact") or # deprecated
156 get("web", "author", "")) # also
159 get("web", "author", "")) # also
157 description = get("web", "description", "")
160 description = get("web", "description", "")
158 name = get("web", "name", name)
161 name = get("web", "name", name)
159 row = dict(contact=contact or "unknown",
162 row = dict(contact=contact or "unknown",
160 contact_sort=contact.upper() or "unknown",
163 contact_sort=contact.upper() or "unknown",
161 name=name,
164 name=name,
162 name_sort=name,
165 name_sort=name,
163 url=url,
166 url=url,
164 description=description or "unknown",
167 description=description or "unknown",
165 description_sort=description.upper() or "unknown",
168 description_sort=description.upper() or "unknown",
166 lastchange=d,
169 lastchange=d,
167 lastchange_sort=d[1]-d[0],
170 lastchange_sort=d[1]-d[0],
168 sessionvars=sessionvars,
171 sessionvars=sessionvars,
169 archives=archivelist(u, "tip", url))
172 archives=archivelist(u, "tip", url))
170 if (not sortcolumn
173 if (not sortcolumn
171 or (sortcolumn, descending) == self.repos_sorted):
174 or (sortcolumn, descending) == self.repos_sorted):
172 # fast path for unsorted output
175 # fast path for unsorted output
173 row['parity'] = parity.next()
176 row['parity'] = parity.next()
174 yield row
177 yield row
175 else:
178 else:
176 rows.append((row["%s_sort" % sortcolumn], row))
179 rows.append((row["%s_sort" % sortcolumn], row))
177 if rows:
180 if rows:
178 rows.sort()
181 rows.sort()
179 if descending:
182 if descending:
180 rows.reverse()
183 rows.reverse()
181 for key, row in rows:
184 for key, row in rows:
182 row['parity'] = parity.next()
185 row['parity'] = parity.next()
183 yield row
186 yield row
184
187
185 try:
188 try:
186 virtual = req.env.get("PATH_INFO", "").strip('/')
189 virtual = req.env.get("PATH_INFO", "").strip('/')
187 if virtual.startswith('static/'):
190 if virtual.startswith('static/'):
188 static = os.path.join(templater.templatepath(), 'static')
191 static = os.path.join(templater.templatepath(), 'static')
189 fname = virtual[7:]
192 fname = virtual[7:]
190 req.write(staticfile(static, fname, req) or
193 req.write(staticfile(static, fname, req) or
191 tmpl('error', error='%r not found' % fname))
194 tmpl('error', error='%r not found' % fname))
192 elif virtual:
195 elif virtual:
193 while virtual:
196 while virtual:
194 real = dict(self.repos).get(virtual)
197 real = dict(self.repos).get(virtual)
195 if real:
198 if real:
196 break
199 break
197 up = virtual.rfind('/')
200 up = virtual.rfind('/')
198 if up < 0:
201 if up < 0:
199 break
202 break
200 virtual = virtual[:up]
203 virtual = virtual[:up]
201 if real:
204 if real:
202 req.env['REPO_NAME'] = virtual
205 req.env['REPO_NAME'] = virtual
203 try:
206 try:
204 repo = hg.repository(parentui, real)
207 repo = hg.repository(parentui, real)
205 hgweb(repo).run_wsgi(req)
208 hgweb(repo).run_wsgi(req)
206 except IOError, inst:
209 except IOError, inst:
207 req.write(tmpl("error", error=inst.strerror))
210 req.write(tmpl("error", error=inst.strerror))
208 except hg.RepoError, inst:
211 except hg.RepoError, inst:
209 req.write(tmpl("error", error=str(inst)))
212 req.write(tmpl("error", error=str(inst)))
210 else:
213 else:
211 req.write(tmpl("notfound", repo=virtual))
214 req.write(tmpl("notfound", repo=virtual))
212 else:
215 else:
213 if req.form.has_key('static'):
216 if req.form.has_key('static'):
214 static = os.path.join(templater.templatepath(), "static")
217 static = os.path.join(templater.templatepath(), "static")
215 fname = req.form['static'][0]
218 fname = req.form['static'][0]
216 req.write(staticfile(static, fname, req)
219 req.write(staticfile(static, fname, req)
217 or tmpl("error", error="%r not found" % fname))
220 or tmpl("error", error="%r not found" % fname))
218 else:
221 else:
219 sortable = ["name", "description", "contact", "lastchange"]
222 sortable = ["name", "description", "contact", "lastchange"]
220 sortcolumn, descending = self.repos_sorted
223 sortcolumn, descending = self.repos_sorted
221 if req.form.has_key('sort'):
224 if req.form.has_key('sort'):
222 sortcolumn = req.form['sort'][0]
225 sortcolumn = req.form['sort'][0]
223 descending = sortcolumn.startswith('-')
226 descending = sortcolumn.startswith('-')
224 if descending:
227 if descending:
225 sortcolumn = sortcolumn[1:]
228 sortcolumn = sortcolumn[1:]
226 if sortcolumn not in sortable:
229 if sortcolumn not in sortable:
227 sortcolumn = ""
230 sortcolumn = ""
228
231
229 sort = [("sort_%s" % column,
232 sort = [("sort_%s" % column,
230 "%s%s" % ((not descending and column == sortcolumn)
233 "%s%s" % ((not descending and column == sortcolumn)
231 and "-" or "", column))
234 and "-" or "", column))
232 for column in sortable]
235 for column in sortable]
233 req.write(tmpl("index", entries=entries,
236 req.write(tmpl("index", entries=entries,
234 sortcolumn=sortcolumn, descending=descending,
237 sortcolumn=sortcolumn, descending=descending,
235 **dict(sort)))
238 **dict(sort)))
236 finally:
239 finally:
237 tmpl = None
240 tmpl = None
General Comments 0
You need to be logged in to leave comments. Login now