##// END OF EJS Templates
templatefilters: add filter to convert date to local date (issue1674)...
Henrik Stuart -
r8591:08c93b07 default
parent child Browse files
Show More
@@ -1,420 +1,421 b''
1 # help.py - help data for mercurial
1 # help.py - help data for mercurial
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 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, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 from i18n import _
8 from i18n import _
9
9
10 helptable = (
10 helptable = (
11 (["dates"], _("Date Formats"),
11 (["dates"], _("Date Formats"),
12 _(r'''
12 _(r'''
13 Some commands allow the user to specify a date, e.g.:
13 Some commands allow the user to specify a date, e.g.:
14 * backout, commit, import, tag: Specify the commit date.
14 * backout, commit, import, tag: Specify the commit date.
15 * log, revert, update: Select revision(s) by date.
15 * log, revert, update: Select revision(s) by date.
16
16
17 Many date formats are valid. Here are some examples:
17 Many date formats are valid. Here are some examples:
18
18
19 "Wed Dec 6 13:18:29 2006" (local timezone assumed)
19 "Wed Dec 6 13:18:29 2006" (local timezone assumed)
20 "Dec 6 13:18 -0600" (year assumed, time offset provided)
20 "Dec 6 13:18 -0600" (year assumed, time offset provided)
21 "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
21 "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
22 "Dec 6" (midnight)
22 "Dec 6" (midnight)
23 "13:18" (today assumed)
23 "13:18" (today assumed)
24 "3:39" (3:39AM assumed)
24 "3:39" (3:39AM assumed)
25 "3:39pm" (15:39)
25 "3:39pm" (15:39)
26 "2006-12-06 13:18:29" (ISO 8601 format)
26 "2006-12-06 13:18:29" (ISO 8601 format)
27 "2006-12-6 13:18"
27 "2006-12-6 13:18"
28 "2006-12-6"
28 "2006-12-6"
29 "12-6"
29 "12-6"
30 "12/6"
30 "12/6"
31 "12/6/6" (Dec 6 2006)
31 "12/6/6" (Dec 6 2006)
32
32
33 Lastly, there is Mercurial's internal format:
33 Lastly, there is Mercurial's internal format:
34
34
35 "1165432709 0" (Wed Dec 6 13:18:29 2006 UTC)
35 "1165432709 0" (Wed Dec 6 13:18:29 2006 UTC)
36
36
37 This is the internal representation format for dates. unixtime is
37 This is the internal representation format for dates. unixtime is
38 the number of seconds since the epoch (1970-01-01 00:00 UTC).
38 the number of seconds since the epoch (1970-01-01 00:00 UTC).
39 offset is the offset of the local timezone, in seconds west of UTC
39 offset is the offset of the local timezone, in seconds west of UTC
40 (negative if the timezone is east of UTC).
40 (negative if the timezone is east of UTC).
41
41
42 The log command also accepts date ranges:
42 The log command also accepts date ranges:
43
43
44 "<{datetime}" - at or before a given date/time
44 "<{datetime}" - at or before a given date/time
45 ">{datetime}" - on or after a given date/time
45 ">{datetime}" - on or after a given date/time
46 "{datetime} to {datetime}" - a date range, inclusive
46 "{datetime} to {datetime}" - a date range, inclusive
47 "-{days}" - within a given number of days of today
47 "-{days}" - within a given number of days of today
48 ''')),
48 ''')),
49
49
50 (["patterns"], _("File Name Patterns"),
50 (["patterns"], _("File Name Patterns"),
51 _(r'''
51 _(r'''
52 Mercurial accepts several notations for identifying one or more
52 Mercurial accepts several notations for identifying one or more
53 files at a time.
53 files at a time.
54
54
55 By default, Mercurial treats filenames as shell-style extended
55 By default, Mercurial treats filenames as shell-style extended
56 glob patterns.
56 glob patterns.
57
57
58 Alternate pattern notations must be specified explicitly.
58 Alternate pattern notations must be specified explicitly.
59
59
60 To use a plain path name without any pattern matching, start it
60 To use a plain path name without any pattern matching, start it
61 with "path:". These path names must completely match starting at
61 with "path:". These path names must completely match starting at
62 the current repository root.
62 the current repository root.
63
63
64 To use an extended glob, start a name with "glob:". Globs are
64 To use an extended glob, start a name with "glob:". Globs are
65 rooted at the current directory; a glob such as "*.c" will only
65 rooted at the current directory; a glob such as "*.c" will only
66 match files in the current directory ending with ".c".
66 match files in the current directory ending with ".c".
67
67
68 The supported glob syntax extensions are "**" to match any string
68 The supported glob syntax extensions are "**" to match any string
69 across path separators and "{a,b}" to mean "a or b".
69 across path separators and "{a,b}" to mean "a or b".
70
70
71 To use a Perl/Python regular expression, start a name with "re:".
71 To use a Perl/Python regular expression, start a name with "re:".
72 Regexp pattern matching is anchored at the root of the repository.
72 Regexp pattern matching is anchored at the root of the repository.
73
73
74 Plain examples:
74 Plain examples:
75
75
76 path:foo/bar a name bar in a directory named foo in the root of
76 path:foo/bar a name bar in a directory named foo in the root of
77 the repository
77 the repository
78 path:path:name a file or directory named "path:name"
78 path:path:name a file or directory named "path:name"
79
79
80 Glob examples:
80 Glob examples:
81
81
82 glob:*.c any name ending in ".c" in the current directory
82 glob:*.c any name ending in ".c" in the current directory
83 *.c any name ending in ".c" in the current directory
83 *.c any name ending in ".c" in the current directory
84 **.c any name ending in ".c" in any subdirectory of the
84 **.c any name ending in ".c" in any subdirectory of the
85 current directory including itself.
85 current directory including itself.
86 foo/*.c any name ending in ".c" in the directory foo
86 foo/*.c any name ending in ".c" in the directory foo
87 foo/**.c any name ending in ".c" in any subdirectory of foo
87 foo/**.c any name ending in ".c" in any subdirectory of foo
88 including itself.
88 including itself.
89
89
90 Regexp examples:
90 Regexp examples:
91
91
92 re:.*\.c$ any name ending in ".c", anywhere in the repository
92 re:.*\.c$ any name ending in ".c", anywhere in the repository
93
93
94 ''')),
94 ''')),
95
95
96 (['environment', 'env'], _('Environment Variables'),
96 (['environment', 'env'], _('Environment Variables'),
97 _(r'''
97 _(r'''
98 HG::
98 HG::
99 Path to the 'hg' executable, automatically passed when running
99 Path to the 'hg' executable, automatically passed when running
100 hooks, extensions or external tools. If unset or empty, this is
100 hooks, extensions or external tools. If unset or empty, this is
101 the hg executable's name if it's frozen, or an executable named
101 the hg executable's name if it's frozen, or an executable named
102 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on
102 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on
103 Windows) is searched.
103 Windows) is searched.
104
104
105 HGEDITOR::
105 HGEDITOR::
106 This is the name of the editor to run when committing. See EDITOR.
106 This is the name of the editor to run when committing. See EDITOR.
107
107
108 (deprecated, use .hgrc)
108 (deprecated, use .hgrc)
109
109
110 HGENCODING::
110 HGENCODING::
111 This overrides the default locale setting detected by Mercurial.
111 This overrides the default locale setting detected by Mercurial.
112 This setting is used to convert data including usernames,
112 This setting is used to convert data including usernames,
113 changeset descriptions, tag names, and branches. This setting can
113 changeset descriptions, tag names, and branches. This setting can
114 be overridden with the --encoding command-line option.
114 be overridden with the --encoding command-line option.
115
115
116 HGENCODINGMODE::
116 HGENCODINGMODE::
117 This sets Mercurial's behavior for handling unknown characters
117 This sets Mercurial's behavior for handling unknown characters
118 while transcoding user input. The default is "strict", which
118 while transcoding user input. The default is "strict", which
119 causes Mercurial to abort if it can't map a character. Other
119 causes Mercurial to abort if it can't map a character. Other
120 settings include "replace", which replaces unknown characters, and
120 settings include "replace", which replaces unknown characters, and
121 "ignore", which drops them. This setting can be overridden with
121 "ignore", which drops them. This setting can be overridden with
122 the --encodingmode command-line option.
122 the --encodingmode command-line option.
123
123
124 HGMERGE::
124 HGMERGE::
125 An executable to use for resolving merge conflicts. The program
125 An executable to use for resolving merge conflicts. The program
126 will be executed with three arguments: local file, remote file,
126 will be executed with three arguments: local file, remote file,
127 ancestor file.
127 ancestor file.
128
128
129 (deprecated, use .hgrc)
129 (deprecated, use .hgrc)
130
130
131 HGRCPATH::
131 HGRCPATH::
132 A list of files or directories to search for hgrc files. Item
132 A list of files or directories to search for hgrc files. Item
133 separator is ":" on Unix, ";" on Windows. If HGRCPATH is not set,
133 separator is ":" on Unix, ";" on Windows. If HGRCPATH is not set,
134 platform default search path is used. If empty, only the .hg/hgrc
134 platform default search path is used. If empty, only the .hg/hgrc
135 from the current repository is read.
135 from the current repository is read.
136
136
137 For each element in HGRCPATH:
137 For each element in HGRCPATH:
138 * if it's a directory, all files ending with .rc are added
138 * if it's a directory, all files ending with .rc are added
139 * otherwise, the file itself will be added
139 * otherwise, the file itself will be added
140
140
141 HGUSER::
141 HGUSER::
142 This is the string used as the author of a commit. If not set,
142 This is the string used as the author of a commit. If not set,
143 available values will be considered in this order:
143 available values will be considered in this order:
144
144
145 * HGUSER (deprecated)
145 * HGUSER (deprecated)
146 * hgrc files from the HGRCPATH
146 * hgrc files from the HGRCPATH
147 * EMAIL
147 * EMAIL
148 * interactive prompt
148 * interactive prompt
149 * LOGNAME (with '@hostname' appended)
149 * LOGNAME (with '@hostname' appended)
150
150
151 (deprecated, use .hgrc)
151 (deprecated, use .hgrc)
152
152
153 EMAIL::
153 EMAIL::
154 May be used as the author of a commit; see HGUSER.
154 May be used as the author of a commit; see HGUSER.
155
155
156 LOGNAME::
156 LOGNAME::
157 May be used as the author of a commit; see HGUSER.
157 May be used as the author of a commit; see HGUSER.
158
158
159 VISUAL::
159 VISUAL::
160 This is the name of the editor to use when committing. See EDITOR.
160 This is the name of the editor to use when committing. See EDITOR.
161
161
162 EDITOR::
162 EDITOR::
163 Sometimes Mercurial needs to open a text file in an editor for a
163 Sometimes Mercurial needs to open a text file in an editor for a
164 user to modify, for example when writing commit messages. The
164 user to modify, for example when writing commit messages. The
165 editor it uses is determined by looking at the environment
165 editor it uses is determined by looking at the environment
166 variables HGEDITOR, VISUAL and EDITOR, in that order. The first
166 variables HGEDITOR, VISUAL and EDITOR, in that order. The first
167 non-empty one is chosen. If all of them are empty, the editor
167 non-empty one is chosen. If all of them are empty, the editor
168 defaults to 'vi'.
168 defaults to 'vi'.
169
169
170 PYTHONPATH::
170 PYTHONPATH::
171 This is used by Python to find imported modules and may need to be
171 This is used by Python to find imported modules and may need to be
172 set appropriately if this Mercurial is not installed system-wide.
172 set appropriately if this Mercurial is not installed system-wide.
173 ''')),
173 ''')),
174
174
175 (['revs', 'revisions'], _('Specifying Single Revisions'),
175 (['revs', 'revisions'], _('Specifying Single Revisions'),
176 _(r'''
176 _(r'''
177 Mercurial supports several ways to specify individual revisions.
177 Mercurial supports several ways to specify individual revisions.
178
178
179 A plain integer is treated as a revision number. Negative integers
179 A plain integer is treated as a revision number. Negative integers
180 are treated as topological offsets from the tip, with -1 denoting
180 are treated as topological offsets from the tip, with -1 denoting
181 the tip. As such, negative numbers are only useful if you've
181 the tip. As such, negative numbers are only useful if you've
182 memorized your local tree numbers and want to save typing a single
182 memorized your local tree numbers and want to save typing a single
183 digit. This editor suggests copy and paste.
183 digit. This editor suggests copy and paste.
184
184
185 A 40-digit hexadecimal string is treated as a unique revision
185 A 40-digit hexadecimal string is treated as a unique revision
186 identifier.
186 identifier.
187
187
188 A hexadecimal string less than 40 characters long is treated as a
188 A hexadecimal string less than 40 characters long is treated as a
189 unique revision identifier, and referred to as a short-form
189 unique revision identifier, and referred to as a short-form
190 identifier. A short-form identifier is only valid if it is the
190 identifier. A short-form identifier is only valid if it is the
191 prefix of exactly one full-length identifier.
191 prefix of exactly one full-length identifier.
192
192
193 Any other string is treated as a tag name, which is a symbolic
193 Any other string is treated as a tag name, which is a symbolic
194 name associated with a revision identifier. Tag names may not
194 name associated with a revision identifier. Tag names may not
195 contain the ":" character.
195 contain the ":" character.
196
196
197 The reserved name "tip" is a special tag that always identifies
197 The reserved name "tip" is a special tag that always identifies
198 the most recent revision.
198 the most recent revision.
199
199
200 The reserved name "null" indicates the null revision. This is the
200 The reserved name "null" indicates the null revision. This is the
201 revision of an empty repository, and the parent of revision 0.
201 revision of an empty repository, and the parent of revision 0.
202
202
203 The reserved name "." indicates the working directory parent. If
203 The reserved name "." indicates the working directory parent. If
204 no working directory is checked out, it is equivalent to null. If
204 no working directory is checked out, it is equivalent to null. If
205 an uncommitted merge is in progress, "." is the revision of the
205 an uncommitted merge is in progress, "." is the revision of the
206 first parent.
206 first parent.
207 ''')),
207 ''')),
208
208
209 (['mrevs', 'multirevs'], _('Specifying Multiple Revisions'),
209 (['mrevs', 'multirevs'], _('Specifying Multiple Revisions'),
210 _(r'''
210 _(r'''
211 When Mercurial accepts more than one revision, they may be
211 When Mercurial accepts more than one revision, they may be
212 specified individually, or provided as a topologically continuous
212 specified individually, or provided as a topologically continuous
213 range, separated by the ":" character.
213 range, separated by the ":" character.
214
214
215 The syntax of range notation is [BEGIN]:[END], where BEGIN and END
215 The syntax of range notation is [BEGIN]:[END], where BEGIN and END
216 are revision identifiers. Both BEGIN and END are optional. If
216 are revision identifiers. Both BEGIN and END are optional. If
217 BEGIN is not specified, it defaults to revision number 0. If END
217 BEGIN is not specified, it defaults to revision number 0. If END
218 is not specified, it defaults to the tip. The range ":" thus means
218 is not specified, it defaults to the tip. The range ":" thus means
219 "all revisions".
219 "all revisions".
220
220
221 If BEGIN is greater than END, revisions are treated in reverse
221 If BEGIN is greater than END, revisions are treated in reverse
222 order.
222 order.
223
223
224 A range acts as a closed interval. This means that a range of 3:5
224 A range acts as a closed interval. This means that a range of 3:5
225 gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
225 gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
226 ''')),
226 ''')),
227
227
228 (['diffs'], _('Diff Formats'),
228 (['diffs'], _('Diff Formats'),
229 _(r'''
229 _(r'''
230 Mercurial's default format for showing changes between two
230 Mercurial's default format for showing changes between two
231 versions of a file is compatible with the unified format of GNU
231 versions of a file is compatible with the unified format of GNU
232 diff, which can be used by GNU patch and many other standard
232 diff, which can be used by GNU patch and many other standard
233 tools.
233 tools.
234
234
235 While this standard format is often enough, it does not encode the
235 While this standard format is often enough, it does not encode the
236 following information:
236 following information:
237
237
238 - executable status and other permission bits
238 - executable status and other permission bits
239 - copy or rename information
239 - copy or rename information
240 - changes in binary files
240 - changes in binary files
241 - creation or deletion of empty files
241 - creation or deletion of empty files
242
242
243 Mercurial also supports the extended diff format from the git VCS
243 Mercurial also supports the extended diff format from the git VCS
244 which addresses these limitations. The git diff format is not
244 which addresses these limitations. The git diff format is not
245 produced by default because a few widespread tools still do not
245 produced by default because a few widespread tools still do not
246 understand this format.
246 understand this format.
247
247
248 This means that when generating diffs from a Mercurial repository
248 This means that when generating diffs from a Mercurial repository
249 (e.g. with "hg export"), you should be careful about things like
249 (e.g. with "hg export"), you should be careful about things like
250 file copies and renames or other things mentioned above, because
250 file copies and renames or other things mentioned above, because
251 when applying a standard diff to a different repository, this
251 when applying a standard diff to a different repository, this
252 extra information is lost. Mercurial's internal operations (like
252 extra information is lost. Mercurial's internal operations (like
253 push and pull) are not affected by this, because they use an
253 push and pull) are not affected by this, because they use an
254 internal binary format for communicating changes.
254 internal binary format for communicating changes.
255
255
256 To make Mercurial produce the git extended diff format, use the
256 To make Mercurial produce the git extended diff format, use the
257 --git option available for many commands, or set 'git = True' in
257 --git option available for many commands, or set 'git = True' in
258 the [diff] section of your hgrc. You do not need to set this
258 the [diff] section of your hgrc. You do not need to set this
259 option when importing diffs in this format or using them in the mq
259 option when importing diffs in this format or using them in the mq
260 extension.
260 extension.
261 ''')),
261 ''')),
262 (['templating'], _('Template Usage'),
262 (['templating'], _('Template Usage'),
263 _(r'''
263 _(r'''
264 Mercurial allows you to customize output of commands through
264 Mercurial allows you to customize output of commands through
265 templates. You can either pass in a template from the command
265 templates. You can either pass in a template from the command
266 line, via the --template option, or select an existing
266 line, via the --template option, or select an existing
267 template-style (--style).
267 template-style (--style).
268
268
269 You can customize output for any "log-like" command: log,
269 You can customize output for any "log-like" command: log,
270 outgoing, incoming, tip, parents, heads and glog.
270 outgoing, incoming, tip, parents, heads and glog.
271
271
272 Three styles are packaged with Mercurial: default (the style used
272 Three styles are packaged with Mercurial: default (the style used
273 when no explicit preference is passed), compact and changelog.
273 when no explicit preference is passed), compact and changelog.
274 Usage:
274 Usage:
275
275
276 $ hg log -r1 --style changelog
276 $ hg log -r1 --style changelog
277
277
278 A template is a piece of text, with markup to invoke variable
278 A template is a piece of text, with markup to invoke variable
279 expansion:
279 expansion:
280
280
281 $ hg log -r1 --template "{node}\n"
281 $ hg log -r1 --template "{node}\n"
282 b56ce7b07c52de7d5fd79fb89701ea538af65746
282 b56ce7b07c52de7d5fd79fb89701ea538af65746
283
283
284 Strings in curly braces are called keywords. The availability of
284 Strings in curly braces are called keywords. The availability of
285 keywords depends on the exact context of the templater. These
285 keywords depends on the exact context of the templater. These
286 keywords are usually available for templating a log-like command:
286 keywords are usually available for templating a log-like command:
287
287
288 - author: String. The unmodified author of the changeset.
288 - author: String. The unmodified author of the changeset.
289 - branches: String. The name of the branch on which the changeset
289 - branches: String. The name of the branch on which the changeset
290 was committed. Will be empty if the branch name was default.
290 was committed. Will be empty if the branch name was default.
291 - date: Date information. The date when the changeset was committed.
291 - date: Date information. The date when the changeset was committed.
292 - desc: String. The text of the changeset description.
292 - desc: String. The text of the changeset description.
293 - diffstat: String. Statistics of changes with the following
293 - diffstat: String. Statistics of changes with the following
294 format: "modified files: +added/-removed lines"
294 format: "modified files: +added/-removed lines"
295 - files: List of strings. All files modified, added, or removed by
295 - files: List of strings. All files modified, added, or removed by
296 this changeset.
296 this changeset.
297 - file_adds: List of strings. Files added by this changeset.
297 - file_adds: List of strings. Files added by this changeset.
298 - file_mods: List of strings. Files modified by this changeset.
298 - file_mods: List of strings. Files modified by this changeset.
299 - file_dels: List of strings. Files removed by this changeset.
299 - file_dels: List of strings. Files removed by this changeset.
300 - node: String. The changeset identification hash, as a
300 - node: String. The changeset identification hash, as a
301 40-character hexadecimal string.
301 40-character hexadecimal string.
302 - parents: List of strings. The parents of the changeset.
302 - parents: List of strings. The parents of the changeset.
303 - rev: Integer. The repository-local changeset revision number.
303 - rev: Integer. The repository-local changeset revision number.
304 - tags: List of strings. Any tags associated with the changeset.
304 - tags: List of strings. Any tags associated with the changeset.
305
305
306 The "date" keyword does not produce human-readable output. If you
306 The "date" keyword does not produce human-readable output. If you
307 want to use a date in your output, you can use a filter to process
307 want to use a date in your output, you can use a filter to process
308 it. Filters are functions which return a string based on the input
308 it. Filters are functions which return a string based on the input
309 variable. You can also use a chain of filters to get the desired
309 variable. You can also use a chain of filters to get the desired
310 output:
310 output:
311
311
312 $ hg tip --template "{date|isodate}\n"
312 $ hg tip --template "{date|isodate}\n"
313 2008-08-21 18:22 +0000
313 2008-08-21 18:22 +0000
314
314
315 List of filters:
315 List of filters:
316
316
317 - addbreaks: Any text. Add an XHTML "<br />" tag before the end of
317 - addbreaks: Any text. Add an XHTML "<br />" tag before the end of
318 every line except the last.
318 every line except the last.
319 - age: Date. Returns a human-readable date/time difference between
319 - age: Date. Returns a human-readable date/time difference between
320 the given date/time and the current date/time.
320 the given date/time and the current date/time.
321 - basename: Any text. Treats the text as a path, and returns the
321 - basename: Any text. Treats the text as a path, and returns the
322 last component of the path after splitting by the path
322 last component of the path after splitting by the path
323 separator (ignoring trailing seprators). For example,
323 separator (ignoring trailing seprators). For example,
324 "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "bar".
324 "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "bar".
325 - stripdir: Treat the text as path and strip a directory level, if
325 - stripdir: Treat the text as path and strip a directory level, if
326 possible. For example, "foo" and "foo/bar" becomes "foo".
326 possible. For example, "foo" and "foo/bar" becomes "foo".
327 - date: Date. Returns a date in a Unix date format, including
327 - date: Date. Returns a date in a Unix date format, including
328 the timezone: "Mon Sep 04 15:13:13 2006 0700".
328 the timezone: "Mon Sep 04 15:13:13 2006 0700".
329 - domain: Any text. Finds the first string that looks like an
329 - domain: Any text. Finds the first string that looks like an
330 email address, and extracts just the domain component.
330 email address, and extracts just the domain component.
331 Example: 'User <user@example.com>' becomes 'example.com'.
331 Example: 'User <user@example.com>' becomes 'example.com'.
332 - email: Any text. Extracts the first string that looks like an
332 - email: Any text. Extracts the first string that looks like an
333 email address. Example: 'User <user@example.com>' becomes
333 email address. Example: 'User <user@example.com>' becomes
334 'user@example.com'.
334 'user@example.com'.
335 - escape: Any text. Replaces the special XML/XHTML characters "&",
335 - escape: Any text. Replaces the special XML/XHTML characters "&",
336 "<" and ">" with XML entities.
336 "<" and ">" with XML entities.
337 - fill68: Any text. Wraps the text to fit in 68 columns.
337 - fill68: Any text. Wraps the text to fit in 68 columns.
338 - fill76: Any text. Wraps the text to fit in 76 columns.
338 - fill76: Any text. Wraps the text to fit in 76 columns.
339 - firstline: Any text. Returns the first line of text.
339 - firstline: Any text. Returns the first line of text.
340 - nonempty: Any text. Returns '(none)' if the string is empty.
340 - nonempty: Any text. Returns '(none)' if the string is empty.
341 - hgdate: Date. Returns the date as a pair of numbers:
341 - hgdate: Date. Returns the date as a pair of numbers:
342 "1157407993 25200" (Unix timestamp, timezone offset).
342 "1157407993 25200" (Unix timestamp, timezone offset).
343 - isodate: Date. Returns the date in ISO 8601 format.
343 - isodate: Date. Returns the date in ISO 8601 format.
344 - localdate: Date. Converts a date to local date.
344 - obfuscate: Any text. Returns the input text rendered as a
345 - obfuscate: Any text. Returns the input text rendered as a
345 sequence of XML entities.
346 sequence of XML entities.
346 - person: Any text. Returns the text before an email address.
347 - person: Any text. Returns the text before an email address.
347 - rfc822date: Date. Returns a date using the same format used
348 - rfc822date: Date. Returns a date using the same format used
348 in email headers.
349 in email headers.
349 - short: Changeset hash. Returns the short form of a changeset
350 - short: Changeset hash. Returns the short form of a changeset
350 hash, i.e. a 12-byte hexadecimal string.
351 hash, i.e. a 12-byte hexadecimal string.
351 - shortdate: Date. Returns a date like "2006-09-18".
352 - shortdate: Date. Returns a date like "2006-09-18".
352 - strip: Any text. Strips all leading and trailing whitespace.
353 - strip: Any text. Strips all leading and trailing whitespace.
353 - tabindent: Any text. Returns the text, with every line except
354 - tabindent: Any text. Returns the text, with every line except
354 the first starting with a tab character.
355 the first starting with a tab character.
355 - urlescape: Any text. Escapes all "special" characters. For
356 - urlescape: Any text. Escapes all "special" characters. For
356 example, "foo bar" becomes "foo%20bar".
357 example, "foo bar" becomes "foo%20bar".
357 - user: Any text. Returns the user portion of an email address.
358 - user: Any text. Returns the user portion of an email address.
358 ''')),
359 ''')),
359
360
360 (['urls'], _('URL Paths'),
361 (['urls'], _('URL Paths'),
361 _(r'''
362 _(r'''
362 Valid URLs are of the form:
363 Valid URLs are of the form:
363
364
364 local/filesystem/path (or file://local/filesystem/path)
365 local/filesystem/path (or file://local/filesystem/path)
365 http://[user[:pass]@]host[:port]/[path]
366 http://[user[:pass]@]host[:port]/[path]
366 https://[user[:pass]@]host[:port]/[path]
367 https://[user[:pass]@]host[:port]/[path]
367 ssh://[user[:pass]@]host[:port]/[path]
368 ssh://[user[:pass]@]host[:port]/[path]
368
369
369 Paths in the local filesystem can either point to Mercurial
370 Paths in the local filesystem can either point to Mercurial
370 repositories or to bundle files (as created by 'hg bundle' or
371 repositories or to bundle files (as created by 'hg bundle' or
371 'hg incoming --bundle').
372 'hg incoming --bundle').
372
373
373 An optional identifier after # indicates a particular branch, tag,
374 An optional identifier after # indicates a particular branch, tag,
374 or changeset to use from the remote repository.
375 or changeset to use from the remote repository.
375
376
376 Some features, such as pushing to http:// and https:// URLs are
377 Some features, such as pushing to http:// and https:// URLs are
377 only possible if the feature is explicitly enabled on the remote
378 only possible if the feature is explicitly enabled on the remote
378 Mercurial server.
379 Mercurial server.
379
380
380 Some notes about using SSH with Mercurial:
381 Some notes about using SSH with Mercurial:
381 - SSH requires an accessible shell account on the destination
382 - SSH requires an accessible shell account on the destination
382 machine and a copy of hg in the remote path or specified with as
383 machine and a copy of hg in the remote path or specified with as
383 remotecmd.
384 remotecmd.
384 - path is relative to the remote user's home directory by default.
385 - path is relative to the remote user's home directory by default.
385 Use an extra slash at the start of a path to specify an absolute path:
386 Use an extra slash at the start of a path to specify an absolute path:
386 ssh://example.com//tmp/repository
387 ssh://example.com//tmp/repository
387 - Mercurial doesn't use its own compression via SSH; the right
388 - Mercurial doesn't use its own compression via SSH; the right
388 thing to do is to configure it in your ~/.ssh/config, e.g.:
389 thing to do is to configure it in your ~/.ssh/config, e.g.:
389 Host *.mylocalnetwork.example.com
390 Host *.mylocalnetwork.example.com
390 Compression no
391 Compression no
391 Host *
392 Host *
392 Compression yes
393 Compression yes
393 Alternatively specify "ssh -C" as your ssh command in your hgrc
394 Alternatively specify "ssh -C" as your ssh command in your hgrc
394 or with the --ssh command line option.
395 or with the --ssh command line option.
395
396
396 These URLs can all be stored in your hgrc with path aliases under
397 These URLs can all be stored in your hgrc with path aliases under
397 the [paths] section like so:
398 the [paths] section like so:
398 [paths]
399 [paths]
399 alias1 = URL1
400 alias1 = URL1
400 alias2 = URL2
401 alias2 = URL2
401 ...
402 ...
402
403
403 You can then use the alias for any command that uses a URL (for
404 You can then use the alias for any command that uses a URL (for
404 example 'hg pull alias1' would pull from the 'alias1' path).
405 example 'hg pull alias1' would pull from the 'alias1' path).
405
406
406 Two path aliases are special because they are used as defaults
407 Two path aliases are special because they are used as defaults
407 when you do not provide the URL to a command:
408 when you do not provide the URL to a command:
408
409
409 default:
410 default:
410 When you create a repository with hg clone, the clone command
411 When you create a repository with hg clone, the clone command
411 saves the location of the source repository as the new
412 saves the location of the source repository as the new
412 repository's 'default' path. This is then used when you omit
413 repository's 'default' path. This is then used when you omit
413 path from push- and pull-like commands (including incoming and
414 path from push- and pull-like commands (including incoming and
414 outgoing).
415 outgoing).
415
416
416 default-push:
417 default-push:
417 The push command will look for a path named 'default-push', and
418 The push command will look for a path named 'default-push', and
418 prefer it over 'default' if both are defined.
419 prefer it over 'default' if both are defined.
419 ''')),
420 ''')),
420 )
421 )
@@ -1,209 +1,210 b''
1 # template-filters.py - common template expansion filters
1 # template-filters.py - common template expansion filters
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 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, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 import cgi, re, os, time, urllib, textwrap
8 import cgi, re, os, time, urllib, textwrap
9 import util, encoding
9 import util, encoding
10
10
11 def stringify(thing):
11 def stringify(thing):
12 '''turn nested template iterator into string.'''
12 '''turn nested template iterator into string.'''
13 if hasattr(thing, '__iter__') and not isinstance(thing, str):
13 if hasattr(thing, '__iter__') and not isinstance(thing, str):
14 return "".join([stringify(t) for t in thing if t is not None])
14 return "".join([stringify(t) for t in thing if t is not None])
15 return str(thing)
15 return str(thing)
16
16
17 agescales = [("second", 1),
17 agescales = [("second", 1),
18 ("minute", 60),
18 ("minute", 60),
19 ("hour", 3600),
19 ("hour", 3600),
20 ("day", 3600 * 24),
20 ("day", 3600 * 24),
21 ("week", 3600 * 24 * 7),
21 ("week", 3600 * 24 * 7),
22 ("month", 3600 * 24 * 30),
22 ("month", 3600 * 24 * 30),
23 ("year", 3600 * 24 * 365)]
23 ("year", 3600 * 24 * 365)]
24
24
25 agescales.reverse()
25 agescales.reverse()
26
26
27 def age(date):
27 def age(date):
28 '''turn a (timestamp, tzoff) tuple into an age string.'''
28 '''turn a (timestamp, tzoff) tuple into an age string.'''
29
29
30 def plural(t, c):
30 def plural(t, c):
31 if c == 1:
31 if c == 1:
32 return t
32 return t
33 return t + "s"
33 return t + "s"
34 def fmt(t, c):
34 def fmt(t, c):
35 return "%d %s" % (c, plural(t, c))
35 return "%d %s" % (c, plural(t, c))
36
36
37 now = time.time()
37 now = time.time()
38 then = date[0]
38 then = date[0]
39 if then > now:
39 if then > now:
40 return 'in the future'
40 return 'in the future'
41
41
42 delta = max(1, int(now - then))
42 delta = max(1, int(now - then))
43 for t, s in agescales:
43 for t, s in agescales:
44 n = delta / s
44 n = delta / s
45 if n >= 2 or s == 1:
45 if n >= 2 or s == 1:
46 return fmt(t, n)
46 return fmt(t, n)
47
47
48 para_re = None
48 para_re = None
49 space_re = None
49 space_re = None
50
50
51 def fill(text, width):
51 def fill(text, width):
52 '''fill many paragraphs.'''
52 '''fill many paragraphs.'''
53 global para_re, space_re
53 global para_re, space_re
54 if para_re is None:
54 if para_re is None:
55 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
55 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
56 space_re = re.compile(r' +')
56 space_re = re.compile(r' +')
57
57
58 def findparas():
58 def findparas():
59 start = 0
59 start = 0
60 while True:
60 while True:
61 m = para_re.search(text, start)
61 m = para_re.search(text, start)
62 if not m:
62 if not m:
63 w = len(text)
63 w = len(text)
64 while w > start and text[w-1].isspace(): w -= 1
64 while w > start and text[w-1].isspace(): w -= 1
65 yield text[start:w], text[w:]
65 yield text[start:w], text[w:]
66 break
66 break
67 yield text[start:m.start(0)], m.group(1)
67 yield text[start:m.start(0)], m.group(1)
68 start = m.end(1)
68 start = m.end(1)
69
69
70 return "".join([space_re.sub(' ', textwrap.fill(para, width)) + rest
70 return "".join([space_re.sub(' ', textwrap.fill(para, width)) + rest
71 for para, rest in findparas()])
71 for para, rest in findparas()])
72
72
73 def firstline(text):
73 def firstline(text):
74 '''return the first line of text'''
74 '''return the first line of text'''
75 try:
75 try:
76 return text.splitlines(1)[0].rstrip('\r\n')
76 return text.splitlines(1)[0].rstrip('\r\n')
77 except IndexError:
77 except IndexError:
78 return ''
78 return ''
79
79
80 def nl2br(text):
80 def nl2br(text):
81 '''replace raw newlines with xhtml line breaks.'''
81 '''replace raw newlines with xhtml line breaks.'''
82 return text.replace('\n', '<br/>\n')
82 return text.replace('\n', '<br/>\n')
83
83
84 def obfuscate(text):
84 def obfuscate(text):
85 text = unicode(text, encoding.encoding, 'replace')
85 text = unicode(text, encoding.encoding, 'replace')
86 return ''.join(['&#%d;' % ord(c) for c in text])
86 return ''.join(['&#%d;' % ord(c) for c in text])
87
87
88 def domain(author):
88 def domain(author):
89 '''get domain of author, or empty string if none.'''
89 '''get domain of author, or empty string if none.'''
90 f = author.find('@')
90 f = author.find('@')
91 if f == -1: return ''
91 if f == -1: return ''
92 author = author[f+1:]
92 author = author[f+1:]
93 f = author.find('>')
93 f = author.find('>')
94 if f >= 0: author = author[:f]
94 if f >= 0: author = author[:f]
95 return author
95 return author
96
96
97 def person(author):
97 def person(author):
98 '''get name of author, or else username.'''
98 '''get name of author, or else username.'''
99 f = author.find('<')
99 f = author.find('<')
100 if f == -1: return util.shortuser(author)
100 if f == -1: return util.shortuser(author)
101 return author[:f].rstrip()
101 return author[:f].rstrip()
102
102
103 def indent(text, prefix):
103 def indent(text, prefix):
104 '''indent each non-empty line of text after first with prefix.'''
104 '''indent each non-empty line of text after first with prefix.'''
105 lines = text.splitlines()
105 lines = text.splitlines()
106 num_lines = len(lines)
106 num_lines = len(lines)
107 def indenter():
107 def indenter():
108 for i in xrange(num_lines):
108 for i in xrange(num_lines):
109 l = lines[i]
109 l = lines[i]
110 if i and l.strip():
110 if i and l.strip():
111 yield prefix
111 yield prefix
112 yield l
112 yield l
113 if i < num_lines - 1 or text.endswith('\n'):
113 if i < num_lines - 1 or text.endswith('\n'):
114 yield '\n'
114 yield '\n'
115 return "".join(indenter())
115 return "".join(indenter())
116
116
117 def permissions(flags):
117 def permissions(flags):
118 if "l" in flags:
118 if "l" in flags:
119 return "lrwxrwxrwx"
119 return "lrwxrwxrwx"
120 if "x" in flags:
120 if "x" in flags:
121 return "-rwxr-xr-x"
121 return "-rwxr-xr-x"
122 return "-rw-r--r--"
122 return "-rw-r--r--"
123
123
124 def xmlescape(text):
124 def xmlescape(text):
125 text = (text
125 text = (text
126 .replace('&', '&amp;')
126 .replace('&', '&amp;')
127 .replace('<', '&lt;')
127 .replace('<', '&lt;')
128 .replace('>', '&gt;')
128 .replace('>', '&gt;')
129 .replace('"', '&quot;')
129 .replace('"', '&quot;')
130 .replace("'", '&#39;')) # &apos; invalid in HTML
130 .replace("'", '&#39;')) # &apos; invalid in HTML
131 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
131 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
132
132
133 _escapes = [
133 _escapes = [
134 ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
134 ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
135 ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
135 ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
136 ]
136 ]
137
137
138 def jsonescape(s):
138 def jsonescape(s):
139 for k, v in _escapes:
139 for k, v in _escapes:
140 s = s.replace(k, v)
140 s = s.replace(k, v)
141 return s
141 return s
142
142
143 def json(obj):
143 def json(obj):
144 if obj is None or obj is False or obj is True:
144 if obj is None or obj is False or obj is True:
145 return {None: 'null', False: 'false', True: 'true'}[obj]
145 return {None: 'null', False: 'false', True: 'true'}[obj]
146 elif isinstance(obj, int) or isinstance(obj, float):
146 elif isinstance(obj, int) or isinstance(obj, float):
147 return str(obj)
147 return str(obj)
148 elif isinstance(obj, str):
148 elif isinstance(obj, str):
149 return '"%s"' % jsonescape(obj)
149 return '"%s"' % jsonescape(obj)
150 elif isinstance(obj, unicode):
150 elif isinstance(obj, unicode):
151 return json(obj.encode('utf-8'))
151 return json(obj.encode('utf-8'))
152 elif hasattr(obj, 'keys'):
152 elif hasattr(obj, 'keys'):
153 out = []
153 out = []
154 for k, v in obj.iteritems():
154 for k, v in obj.iteritems():
155 s = '%s: %s' % (json(k), json(v))
155 s = '%s: %s' % (json(k), json(v))
156 out.append(s)
156 out.append(s)
157 return '{' + ', '.join(out) + '}'
157 return '{' + ', '.join(out) + '}'
158 elif hasattr(obj, '__iter__'):
158 elif hasattr(obj, '__iter__'):
159 out = []
159 out = []
160 for i in obj:
160 for i in obj:
161 out.append(json(i))
161 out.append(json(i))
162 return '[' + ', '.join(out) + ']'
162 return '[' + ', '.join(out) + ']'
163 else:
163 else:
164 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
164 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
165
165
166 def stripdir(text):
166 def stripdir(text):
167 '''Treat the text as path and strip a directory level, if possible.'''
167 '''Treat the text as path and strip a directory level, if possible.'''
168 dir = os.path.dirname(text)
168 dir = os.path.dirname(text)
169 if dir == "":
169 if dir == "":
170 return os.path.basename(text)
170 return os.path.basename(text)
171 else:
171 else:
172 return dir
172 return dir
173
173
174 def nonempty(str):
174 def nonempty(str):
175 return str or "(none)"
175 return str or "(none)"
176
176
177 filters = {
177 filters = {
178 "addbreaks": nl2br,
178 "addbreaks": nl2br,
179 "basename": os.path.basename,
179 "basename": os.path.basename,
180 "stripdir": stripdir,
180 "stripdir": stripdir,
181 "age": age,
181 "age": age,
182 "date": lambda x: util.datestr(x),
182 "date": lambda x: util.datestr(x),
183 "domain": domain,
183 "domain": domain,
184 "email": util.email,
184 "email": util.email,
185 "escape": lambda x: cgi.escape(x, True),
185 "escape": lambda x: cgi.escape(x, True),
186 "fill68": lambda x: fill(x, width=68),
186 "fill68": lambda x: fill(x, width=68),
187 "fill76": lambda x: fill(x, width=76),
187 "fill76": lambda x: fill(x, width=76),
188 "firstline": firstline,
188 "firstline": firstline,
189 "tabindent": lambda x: indent(x, '\t'),
189 "tabindent": lambda x: indent(x, '\t'),
190 "hgdate": lambda x: "%d %d" % x,
190 "hgdate": lambda x: "%d %d" % x,
191 "isodate": lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2'),
191 "isodate": lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2'),
192 "isodatesec": lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2'),
192 "isodatesec": lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2'),
193 "json": json,
193 "json": json,
194 "jsonescape": jsonescape,
194 "jsonescape": jsonescape,
195 "localdate": lambda x: (x[0], util.makedate()[1]),
195 "nonempty": nonempty,
196 "nonempty": nonempty,
196 "obfuscate": obfuscate,
197 "obfuscate": obfuscate,
197 "permissions": permissions,
198 "permissions": permissions,
198 "person": person,
199 "person": person,
199 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2"),
200 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2"),
200 "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2"),
201 "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2"),
201 "short": lambda x: x[:12],
202 "short": lambda x: x[:12],
202 "shortdate": util.shortdate,
203 "shortdate": util.shortdate,
203 "stringify": stringify,
204 "stringify": stringify,
204 "strip": lambda x: x.strip(),
205 "strip": lambda x: x.strip(),
205 "urlescape": lambda x: urllib.quote(x),
206 "urlescape": lambda x: urllib.quote(x),
206 "user": lambda x: util.shortuser(x),
207 "user": lambda x: util.shortuser(x),
207 "stringescape": lambda x: x.encode('string_escape'),
208 "stringescape": lambda x: x.encode('string_escape'),
208 "xmlescape": xmlescape,
209 "xmlescape": xmlescape,
209 }
210 }
General Comments 0
You need to be logged in to leave comments. Login now