##// END OF EJS Templates
hgweb: generate HTML documentation...
Dan Villiom Podlaski Christiansen -
r18747:f5db3092 default
parent child Browse files
Show More
@@ -1,100 +1,102 b''
1 Mercurial allows you to customize output of commands through
1 Mercurial allows you to customize output of commands through
2 templates. You can either pass in a template from the command
2 templates. You can either pass in a template from the command
3 line, via the --template option, or select an existing
3 line, via the --template option, or select an existing
4 template-style (--style).
4 template-style (--style).
5
5
6 You can customize output for any "log-like" command: log,
6 You can customize output for any "log-like" command: log,
7 outgoing, incoming, tip, parents, heads and glog.
7 outgoing, incoming, tip, parents, heads and glog.
8
8
9 Four styles are packaged with Mercurial: default (the style used
9 Four styles are packaged with Mercurial: default (the style used
10 when no explicit preference is passed), compact, changelog,
10 when no explicit preference is passed), compact, changelog,
11 and xml.
11 and xml.
12 Usage::
12 Usage::
13
13
14 $ hg log -r1 --style changelog
14 $ hg log -r1 --style changelog
15
15
16 A template is a piece of text, with markup to invoke variable
16 A template is a piece of text, with markup to invoke variable
17 expansion::
17 expansion::
18
18
19 $ hg log -r1 --template "{node}\n"
19 $ hg log -r1 --template "{node}\n"
20 b56ce7b07c52de7d5fd79fb89701ea538af65746
20 b56ce7b07c52de7d5fd79fb89701ea538af65746
21
21
22 Strings in curly braces are called keywords. The availability of
22 Strings in curly braces are called keywords. The availability of
23 keywords depends on the exact context of the templater. These
23 keywords depends on the exact context of the templater. These
24 keywords are usually available for templating a log-like command:
24 keywords are usually available for templating a log-like command:
25
25
26 .. keywordsmarker
26 .. keywordsmarker
27
27
28 The "date" keyword does not produce human-readable output. If you
28 The "date" keyword does not produce human-readable output. If you
29 want to use a date in your output, you can use a filter to process
29 want to use a date in your output, you can use a filter to process
30 it. Filters are functions which return a string based on the input
30 it. Filters are functions which return a string based on the input
31 variable. Be sure to use the stringify filter first when you're
31 variable. Be sure to use the stringify filter first when you're
32 applying a string-input filter to a list-like input variable.
32 applying a string-input filter to a list-like input variable.
33 You can also use a chain of filters to get the desired output::
33 You can also use a chain of filters to get the desired output::
34
34
35 $ hg tip --template "{date|isodate}\n"
35 $ hg tip --template "{date|isodate}\n"
36 2008-08-21 18:22 +0000
36 2008-08-21 18:22 +0000
37
37
38 List of filters:
38 List of filters:
39
39
40 .. filtersmarker
40 .. filtersmarker
41
41
42 Note that a filter is nothing more than a function call, i.e.
42 Note that a filter is nothing more than a function call, i.e.
43 ``expr|filter`` is equivalent to ``filter(expr)``.
43 ``expr|filter`` is equivalent to ``filter(expr)``.
44
44
45 In addition to filters, there are some basic built-in functions:
45 In addition to filters, there are some basic built-in functions:
46
46
47 - date(date[, fmt])
47 - date(date[, fmt])
48
48
49 - fill(text[, width])
49 - fill(text[, width])
50
50
51 - get(dict, key)
51 - get(dict, key)
52
52
53 - if(expr, then[, else])
53 - if(expr, then[, else])
54
54
55 - ifeq(expr, expr, then[, else])
55 - ifeq(expr, expr, then[, else])
56
56
57 - join(list, sep)
57 - join(list, sep)
58
58
59 - label(label, expr)
59 - label(label, expr)
60
60
61 - sub(pat, repl, expr)
61 - sub(pat, repl, expr)
62
62
63 - rstdoc(text, style)
64
63 Also, for any expression that returns a list, there is a list operator:
65 Also, for any expression that returns a list, there is a list operator:
64
66
65 - expr % "{template}"
67 - expr % "{template}"
66
68
67 Some sample command line templates:
69 Some sample command line templates:
68
70
69 - Format lists, e.g. files::
71 - Format lists, e.g. files::
70
72
71 $ hg log -r 0 --template "files:\n{files % ' {file}\n'}"
73 $ hg log -r 0 --template "files:\n{files % ' {file}\n'}"
72
74
73 - Join the list of files with a ", "::
75 - Join the list of files with a ", "::
74
76
75 $ hg log -r 0 --template "files: {join(files, ', ')}\n"
77 $ hg log -r 0 --template "files: {join(files, ', ')}\n"
76
78
77 - Format date::
79 - Format date::
78
80
79 $ hg log -r 0 --template "{date(date, '%Y')}\n"
81 $ hg log -r 0 --template "{date(date, '%Y')}\n"
80
82
81 - Output the description set to a fill-width of 30::
83 - Output the description set to a fill-width of 30::
82
84
83 $ hg log -r 0 --template "{fill(desc, '30')}"
85 $ hg log -r 0 --template "{fill(desc, '30')}"
84
86
85 - Use a conditional to test for the default branch::
87 - Use a conditional to test for the default branch::
86
88
87 $ hg log -r 0 --template "{ifeq(branch, 'default', 'on the main branch',
89 $ hg log -r 0 --template "{ifeq(branch, 'default', 'on the main branch',
88 'on branch {branch}')}\n"
90 'on branch {branch}')}\n"
89
91
90 - Append a newline if not empty::
92 - Append a newline if not empty::
91
93
92 $ hg tip --template "{if(author, '{author}\n')}"
94 $ hg tip --template "{if(author, '{author}\n')}"
93
95
94 - Label the output for use with the color extension::
96 - Label the output for use with the color extension::
95
97
96 $ hg log -r 0 --template "{label('changeset.{phase}', node|short)}\n"
98 $ hg log -r 0 --template "{label('changeset.{phase}', node|short)}\n"
97
99
98 - Invert the firstline filter, i.e. everything but the first line::
100 - Invert the firstline filter, i.e. everything but the first line::
99
101
100 $ hg log -r 0 --template "{sub(r'^.*\n?\n?', '', desc)}\n"
102 $ hg log -r 0 --template "{sub(r'^.*\n?\n?', '', desc)}\n"
@@ -1,1003 +1,1001 b''
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import os, mimetypes, re, cgi, copy
8 import os, mimetypes, re, cgi, copy
9 import webutil
9 import webutil
10 from mercurial import error, encoding, archival, templater, templatefilters
10 from mercurial import error, encoding, archival, templater, templatefilters
11 from mercurial.node import short, hex, nullid
11 from mercurial.node import short, hex, nullid
12 from mercurial.util import binary
12 from mercurial.util import binary
13 from common import paritygen, staticfile, get_contact, ErrorResponse
13 from common import paritygen, staticfile, get_contact, ErrorResponse
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
15 from mercurial import graphmod, patch
15 from mercurial import graphmod, patch
16 from mercurial import help as helpmod
16 from mercurial import help as helpmod
17 from mercurial import scmutil
17 from mercurial import scmutil
18 from mercurial.i18n import _
18 from mercurial.i18n import _
19
19
20 # __all__ is populated with the allowed commands. Be sure to add to it if
20 # __all__ is populated with the allowed commands. Be sure to add to it if
21 # you're adding a new command, or the new command won't work.
21 # you're adding a new command, or the new command won't work.
22
22
23 __all__ = [
23 __all__ = [
24 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
24 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
25 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
25 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
26 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
26 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
27 ]
27 ]
28
28
29 def log(web, req, tmpl):
29 def log(web, req, tmpl):
30 if 'file' in req.form and req.form['file'][0]:
30 if 'file' in req.form and req.form['file'][0]:
31 return filelog(web, req, tmpl)
31 return filelog(web, req, tmpl)
32 else:
32 else:
33 return changelog(web, req, tmpl)
33 return changelog(web, req, tmpl)
34
34
35 def rawfile(web, req, tmpl):
35 def rawfile(web, req, tmpl):
36 guessmime = web.configbool('web', 'guessmime', False)
36 guessmime = web.configbool('web', 'guessmime', False)
37
37
38 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
38 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
39 if not path:
39 if not path:
40 content = manifest(web, req, tmpl)
40 content = manifest(web, req, tmpl)
41 req.respond(HTTP_OK, web.ctype)
41 req.respond(HTTP_OK, web.ctype)
42 return content
42 return content
43
43
44 try:
44 try:
45 fctx = webutil.filectx(web.repo, req)
45 fctx = webutil.filectx(web.repo, req)
46 except error.LookupError, inst:
46 except error.LookupError, inst:
47 try:
47 try:
48 content = manifest(web, req, tmpl)
48 content = manifest(web, req, tmpl)
49 req.respond(HTTP_OK, web.ctype)
49 req.respond(HTTP_OK, web.ctype)
50 return content
50 return content
51 except ErrorResponse:
51 except ErrorResponse:
52 raise inst
52 raise inst
53
53
54 path = fctx.path()
54 path = fctx.path()
55 text = fctx.data()
55 text = fctx.data()
56 mt = 'application/binary'
56 mt = 'application/binary'
57 if guessmime:
57 if guessmime:
58 mt = mimetypes.guess_type(path)[0]
58 mt = mimetypes.guess_type(path)[0]
59 if mt is None:
59 if mt is None:
60 mt = binary(text) and 'application/binary' or 'text/plain'
60 mt = binary(text) and 'application/binary' or 'text/plain'
61 if mt.startswith('text/'):
61 if mt.startswith('text/'):
62 mt += '; charset="%s"' % encoding.encoding
62 mt += '; charset="%s"' % encoding.encoding
63
63
64 req.respond(HTTP_OK, mt, path, body=text)
64 req.respond(HTTP_OK, mt, path, body=text)
65 return []
65 return []
66
66
67 def _filerevision(web, tmpl, fctx):
67 def _filerevision(web, tmpl, fctx):
68 f = fctx.path()
68 f = fctx.path()
69 text = fctx.data()
69 text = fctx.data()
70 parity = paritygen(web.stripecount)
70 parity = paritygen(web.stripecount)
71
71
72 if binary(text):
72 if binary(text):
73 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
73 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
74 text = '(binary:%s)' % mt
74 text = '(binary:%s)' % mt
75
75
76 def lines():
76 def lines():
77 for lineno, t in enumerate(text.splitlines(True)):
77 for lineno, t in enumerate(text.splitlines(True)):
78 yield {"line": t,
78 yield {"line": t,
79 "lineid": "l%d" % (lineno + 1),
79 "lineid": "l%d" % (lineno + 1),
80 "linenumber": "% 6d" % (lineno + 1),
80 "linenumber": "% 6d" % (lineno + 1),
81 "parity": parity.next()}
81 "parity": parity.next()}
82
82
83 return tmpl("filerevision",
83 return tmpl("filerevision",
84 file=f,
84 file=f,
85 path=webutil.up(f),
85 path=webutil.up(f),
86 text=lines(),
86 text=lines(),
87 rev=fctx.rev(),
87 rev=fctx.rev(),
88 node=fctx.hex(),
88 node=fctx.hex(),
89 author=fctx.user(),
89 author=fctx.user(),
90 date=fctx.date(),
90 date=fctx.date(),
91 desc=fctx.description(),
91 desc=fctx.description(),
92 extra=fctx.extra(),
92 extra=fctx.extra(),
93 branch=webutil.nodebranchnodefault(fctx),
93 branch=webutil.nodebranchnodefault(fctx),
94 parent=webutil.parents(fctx),
94 parent=webutil.parents(fctx),
95 child=webutil.children(fctx),
95 child=webutil.children(fctx),
96 rename=webutil.renamelink(fctx),
96 rename=webutil.renamelink(fctx),
97 permissions=fctx.manifest().flags(f))
97 permissions=fctx.manifest().flags(f))
98
98
99 def file(web, req, tmpl):
99 def file(web, req, tmpl):
100 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
100 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
101 if not path:
101 if not path:
102 return manifest(web, req, tmpl)
102 return manifest(web, req, tmpl)
103 try:
103 try:
104 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
104 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
105 except error.LookupError, inst:
105 except error.LookupError, inst:
106 try:
106 try:
107 return manifest(web, req, tmpl)
107 return manifest(web, req, tmpl)
108 except ErrorResponse:
108 except ErrorResponse:
109 raise inst
109 raise inst
110
110
111 def _search(web, req, tmpl):
111 def _search(web, req, tmpl):
112
112
113 query = req.form['rev'][0]
113 query = req.form['rev'][0]
114 revcount = web.maxchanges
114 revcount = web.maxchanges
115 if 'revcount' in req.form:
115 if 'revcount' in req.form:
116 revcount = int(req.form.get('revcount', [revcount])[0])
116 revcount = int(req.form.get('revcount', [revcount])[0])
117 revcount = max(revcount, 1)
117 revcount = max(revcount, 1)
118 tmpl.defaults['sessionvars']['revcount'] = revcount
118 tmpl.defaults['sessionvars']['revcount'] = revcount
119
119
120 lessvars = copy.copy(tmpl.defaults['sessionvars'])
120 lessvars = copy.copy(tmpl.defaults['sessionvars'])
121 lessvars['revcount'] = max(revcount / 2, 1)
121 lessvars['revcount'] = max(revcount / 2, 1)
122 lessvars['rev'] = query
122 lessvars['rev'] = query
123 morevars = copy.copy(tmpl.defaults['sessionvars'])
123 morevars = copy.copy(tmpl.defaults['sessionvars'])
124 morevars['revcount'] = revcount * 2
124 morevars['revcount'] = revcount * 2
125 morevars['rev'] = query
125 morevars['rev'] = query
126
126
127 def changelist(**map):
127 def changelist(**map):
128 count = 0
128 count = 0
129 lower = encoding.lower
129 lower = encoding.lower
130 qw = lower(query).split()
130 qw = lower(query).split()
131
131
132 def revgen():
132 def revgen():
133 cl = web.repo.changelog
133 cl = web.repo.changelog
134 for i in xrange(len(web.repo) - 1, 0, -100):
134 for i in xrange(len(web.repo) - 1, 0, -100):
135 l = []
135 l = []
136 for j in cl.revs(max(0, i - 100), i + 1):
136 for j in cl.revs(max(0, i - 100), i + 1):
137 ctx = web.repo[j]
137 ctx = web.repo[j]
138 l.append(ctx)
138 l.append(ctx)
139 l.reverse()
139 l.reverse()
140 for e in l:
140 for e in l:
141 yield e
141 yield e
142
142
143 for ctx in revgen():
143 for ctx in revgen():
144 miss = 0
144 miss = 0
145 for q in qw:
145 for q in qw:
146 if not (q in lower(ctx.user()) or
146 if not (q in lower(ctx.user()) or
147 q in lower(ctx.description()) or
147 q in lower(ctx.description()) or
148 q in lower(" ".join(ctx.files()))):
148 q in lower(" ".join(ctx.files()))):
149 miss = 1
149 miss = 1
150 break
150 break
151 if miss:
151 if miss:
152 continue
152 continue
153
153
154 count += 1
154 count += 1
155 n = ctx.node()
155 n = ctx.node()
156 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
156 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
157 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
157 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
158
158
159 yield tmpl('searchentry',
159 yield tmpl('searchentry',
160 parity=parity.next(),
160 parity=parity.next(),
161 author=ctx.user(),
161 author=ctx.user(),
162 parent=webutil.parents(ctx),
162 parent=webutil.parents(ctx),
163 child=webutil.children(ctx),
163 child=webutil.children(ctx),
164 changelogtag=showtags,
164 changelogtag=showtags,
165 desc=ctx.description(),
165 desc=ctx.description(),
166 extra=ctx.extra(),
166 extra=ctx.extra(),
167 date=ctx.date(),
167 date=ctx.date(),
168 files=files,
168 files=files,
169 rev=ctx.rev(),
169 rev=ctx.rev(),
170 node=hex(n),
170 node=hex(n),
171 tags=webutil.nodetagsdict(web.repo, n),
171 tags=webutil.nodetagsdict(web.repo, n),
172 bookmarks=webutil.nodebookmarksdict(web.repo, n),
172 bookmarks=webutil.nodebookmarksdict(web.repo, n),
173 inbranch=webutil.nodeinbranch(web.repo, ctx),
173 inbranch=webutil.nodeinbranch(web.repo, ctx),
174 branches=webutil.nodebranchdict(web.repo, ctx))
174 branches=webutil.nodebranchdict(web.repo, ctx))
175
175
176 if count >= revcount:
176 if count >= revcount:
177 break
177 break
178
178
179 tip = web.repo['tip']
179 tip = web.repo['tip']
180 parity = paritygen(web.stripecount)
180 parity = paritygen(web.stripecount)
181
181
182 return tmpl('search', query=query, node=tip.hex(),
182 return tmpl('search', query=query, node=tip.hex(),
183 entries=changelist, archives=web.archivelist("tip"),
183 entries=changelist, archives=web.archivelist("tip"),
184 morevars=morevars, lessvars=lessvars)
184 morevars=morevars, lessvars=lessvars)
185
185
186 def changelog(web, req, tmpl, shortlog=False):
186 def changelog(web, req, tmpl, shortlog=False):
187
187
188 if 'node' in req.form:
188 if 'node' in req.form:
189 ctx = webutil.changectx(web.repo, req)
189 ctx = webutil.changectx(web.repo, req)
190 else:
190 else:
191 if 'rev' in req.form:
191 if 'rev' in req.form:
192 hi = req.form['rev'][0]
192 hi = req.form['rev'][0]
193 else:
193 else:
194 hi = 'tip'
194 hi = 'tip'
195 try:
195 try:
196 ctx = web.repo[hi]
196 ctx = web.repo[hi]
197 except error.RepoError:
197 except error.RepoError:
198 return _search(web, req, tmpl) # XXX redirect to 404 page?
198 return _search(web, req, tmpl) # XXX redirect to 404 page?
199
199
200 def changelist(latestonly, **map):
200 def changelist(latestonly, **map):
201 l = [] # build a list in forward order for efficiency
201 l = [] # build a list in forward order for efficiency
202 revs = []
202 revs = []
203 if start < end:
203 if start < end:
204 revs = web.repo.changelog.revs(start, end - 1)
204 revs = web.repo.changelog.revs(start, end - 1)
205 if latestonly:
205 if latestonly:
206 for r in revs:
206 for r in revs:
207 pass
207 pass
208 revs = (r,)
208 revs = (r,)
209 for i in revs:
209 for i in revs:
210 ctx = web.repo[i]
210 ctx = web.repo[i]
211 n = ctx.node()
211 n = ctx.node()
212 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
212 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
213 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
213 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
214
214
215 l.append({"parity": parity.next(),
215 l.append({"parity": parity.next(),
216 "author": ctx.user(),
216 "author": ctx.user(),
217 "parent": webutil.parents(ctx, i - 1),
217 "parent": webutil.parents(ctx, i - 1),
218 "child": webutil.children(ctx, i + 1),
218 "child": webutil.children(ctx, i + 1),
219 "changelogtag": showtags,
219 "changelogtag": showtags,
220 "desc": ctx.description(),
220 "desc": ctx.description(),
221 "extra": ctx.extra(),
221 "extra": ctx.extra(),
222 "date": ctx.date(),
222 "date": ctx.date(),
223 "files": files,
223 "files": files,
224 "rev": i,
224 "rev": i,
225 "node": hex(n),
225 "node": hex(n),
226 "tags": webutil.nodetagsdict(web.repo, n),
226 "tags": webutil.nodetagsdict(web.repo, n),
227 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
227 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
228 "inbranch": webutil.nodeinbranch(web.repo, ctx),
228 "inbranch": webutil.nodeinbranch(web.repo, ctx),
229 "branches": webutil.nodebranchdict(web.repo, ctx)
229 "branches": webutil.nodebranchdict(web.repo, ctx)
230 })
230 })
231 for e in reversed(l):
231 for e in reversed(l):
232 yield e
232 yield e
233
233
234 revcount = shortlog and web.maxshortchanges or web.maxchanges
234 revcount = shortlog and web.maxshortchanges or web.maxchanges
235 if 'revcount' in req.form:
235 if 'revcount' in req.form:
236 revcount = int(req.form.get('revcount', [revcount])[0])
236 revcount = int(req.form.get('revcount', [revcount])[0])
237 revcount = max(revcount, 1)
237 revcount = max(revcount, 1)
238 tmpl.defaults['sessionvars']['revcount'] = revcount
238 tmpl.defaults['sessionvars']['revcount'] = revcount
239
239
240 lessvars = copy.copy(tmpl.defaults['sessionvars'])
240 lessvars = copy.copy(tmpl.defaults['sessionvars'])
241 lessvars['revcount'] = max(revcount / 2, 1)
241 lessvars['revcount'] = max(revcount / 2, 1)
242 morevars = copy.copy(tmpl.defaults['sessionvars'])
242 morevars = copy.copy(tmpl.defaults['sessionvars'])
243 morevars['revcount'] = revcount * 2
243 morevars['revcount'] = revcount * 2
244
244
245 count = len(web.repo)
245 count = len(web.repo)
246 pos = ctx.rev()
246 pos = ctx.rev()
247 start = max(0, pos - revcount + 1)
247 start = max(0, pos - revcount + 1)
248 end = min(count, start + revcount)
248 end = min(count, start + revcount)
249 pos = end - 1
249 pos = end - 1
250 parity = paritygen(web.stripecount, offset=start - end)
250 parity = paritygen(web.stripecount, offset=start - end)
251
251
252 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
252 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
253
253
254 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
254 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
255 node=ctx.hex(), rev=pos, changesets=count,
255 node=ctx.hex(), rev=pos, changesets=count,
256 entries=lambda **x: changelist(latestonly=False, **x),
256 entries=lambda **x: changelist(latestonly=False, **x),
257 latestentry=lambda **x: changelist(latestonly=True, **x),
257 latestentry=lambda **x: changelist(latestonly=True, **x),
258 archives=web.archivelist("tip"), revcount=revcount,
258 archives=web.archivelist("tip"), revcount=revcount,
259 morevars=morevars, lessvars=lessvars)
259 morevars=morevars, lessvars=lessvars)
260
260
261 def shortlog(web, req, tmpl):
261 def shortlog(web, req, tmpl):
262 return changelog(web, req, tmpl, shortlog = True)
262 return changelog(web, req, tmpl, shortlog = True)
263
263
264 def changeset(web, req, tmpl):
264 def changeset(web, req, tmpl):
265 ctx = webutil.changectx(web.repo, req)
265 ctx = webutil.changectx(web.repo, req)
266 basectx = webutil.basechangectx(web.repo, req)
266 basectx = webutil.basechangectx(web.repo, req)
267 if basectx is None:
267 if basectx is None:
268 basectx = ctx.p1()
268 basectx = ctx.p1()
269 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
269 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
270 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
270 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
271 ctx.node())
271 ctx.node())
272 showbranch = webutil.nodebranchnodefault(ctx)
272 showbranch = webutil.nodebranchnodefault(ctx)
273
273
274 files = []
274 files = []
275 parity = paritygen(web.stripecount)
275 parity = paritygen(web.stripecount)
276 for blockno, f in enumerate(ctx.files()):
276 for blockno, f in enumerate(ctx.files()):
277 template = f in ctx and 'filenodelink' or 'filenolink'
277 template = f in ctx and 'filenodelink' or 'filenolink'
278 files.append(tmpl(template,
278 files.append(tmpl(template,
279 node=ctx.hex(), file=f, blockno=blockno + 1,
279 node=ctx.hex(), file=f, blockno=blockno + 1,
280 parity=parity.next()))
280 parity=parity.next()))
281
281
282 style = web.config('web', 'style', 'paper')
282 style = web.config('web', 'style', 'paper')
283 if 'style' in req.form:
283 if 'style' in req.form:
284 style = req.form['style'][0]
284 style = req.form['style'][0]
285
285
286 parity = paritygen(web.stripecount)
286 parity = paritygen(web.stripecount)
287 diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
287 diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
288
288
289 parity = paritygen(web.stripecount)
289 parity = paritygen(web.stripecount)
290 diffstatgen = webutil.diffstatgen(ctx, basectx)
290 diffstatgen = webutil.diffstatgen(ctx, basectx)
291 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
291 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
292
292
293 return tmpl('changeset',
293 return tmpl('changeset',
294 diff=diffs,
294 diff=diffs,
295 rev=ctx.rev(),
295 rev=ctx.rev(),
296 node=ctx.hex(),
296 node=ctx.hex(),
297 parent=webutil.parents(ctx),
297 parent=webutil.parents(ctx),
298 child=webutil.children(ctx),
298 child=webutil.children(ctx),
299 basenode=basectx.hex(),
299 basenode=basectx.hex(),
300 changesettag=showtags,
300 changesettag=showtags,
301 changesetbookmark=showbookmarks,
301 changesetbookmark=showbookmarks,
302 changesetbranch=showbranch,
302 changesetbranch=showbranch,
303 author=ctx.user(),
303 author=ctx.user(),
304 desc=ctx.description(),
304 desc=ctx.description(),
305 extra=ctx.extra(),
305 extra=ctx.extra(),
306 date=ctx.date(),
306 date=ctx.date(),
307 files=files,
307 files=files,
308 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
308 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
309 diffstat=diffstat,
309 diffstat=diffstat,
310 archives=web.archivelist(ctx.hex()),
310 archives=web.archivelist(ctx.hex()),
311 tags=webutil.nodetagsdict(web.repo, ctx.node()),
311 tags=webutil.nodetagsdict(web.repo, ctx.node()),
312 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
312 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
313 branch=webutil.nodebranchnodefault(ctx),
313 branch=webutil.nodebranchnodefault(ctx),
314 inbranch=webutil.nodeinbranch(web.repo, ctx),
314 inbranch=webutil.nodeinbranch(web.repo, ctx),
315 branches=webutil.nodebranchdict(web.repo, ctx))
315 branches=webutil.nodebranchdict(web.repo, ctx))
316
316
317 rev = changeset
317 rev = changeset
318
318
319 def decodepath(path):
319 def decodepath(path):
320 """Hook for mapping a path in the repository to a path in the
320 """Hook for mapping a path in the repository to a path in the
321 working copy.
321 working copy.
322
322
323 Extensions (e.g., largefiles) can override this to remap files in
323 Extensions (e.g., largefiles) can override this to remap files in
324 the virtual file system presented by the manifest command below."""
324 the virtual file system presented by the manifest command below."""
325 return path
325 return path
326
326
327 def manifest(web, req, tmpl):
327 def manifest(web, req, tmpl):
328 ctx = webutil.changectx(web.repo, req)
328 ctx = webutil.changectx(web.repo, req)
329 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
329 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
330 mf = ctx.manifest()
330 mf = ctx.manifest()
331 node = ctx.node()
331 node = ctx.node()
332
332
333 files = {}
333 files = {}
334 dirs = {}
334 dirs = {}
335 parity = paritygen(web.stripecount)
335 parity = paritygen(web.stripecount)
336
336
337 if path and path[-1] != "/":
337 if path and path[-1] != "/":
338 path += "/"
338 path += "/"
339 l = len(path)
339 l = len(path)
340 abspath = "/" + path
340 abspath = "/" + path
341
341
342 for full, n in mf.iteritems():
342 for full, n in mf.iteritems():
343 # the virtual path (working copy path) used for the full
343 # the virtual path (working copy path) used for the full
344 # (repository) path
344 # (repository) path
345 f = decodepath(full)
345 f = decodepath(full)
346
346
347 if f[:l] != path:
347 if f[:l] != path:
348 continue
348 continue
349 remain = f[l:]
349 remain = f[l:]
350 elements = remain.split('/')
350 elements = remain.split('/')
351 if len(elements) == 1:
351 if len(elements) == 1:
352 files[remain] = full
352 files[remain] = full
353 else:
353 else:
354 h = dirs # need to retain ref to dirs (root)
354 h = dirs # need to retain ref to dirs (root)
355 for elem in elements[0:-1]:
355 for elem in elements[0:-1]:
356 if elem not in h:
356 if elem not in h:
357 h[elem] = {}
357 h[elem] = {}
358 h = h[elem]
358 h = h[elem]
359 if len(h) > 1:
359 if len(h) > 1:
360 break
360 break
361 h[None] = None # denotes files present
361 h[None] = None # denotes files present
362
362
363 if mf and not files and not dirs:
363 if mf and not files and not dirs:
364 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
364 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
365
365
366 def filelist(**map):
366 def filelist(**map):
367 for f in sorted(files):
367 for f in sorted(files):
368 full = files[f]
368 full = files[f]
369
369
370 fctx = ctx.filectx(full)
370 fctx = ctx.filectx(full)
371 yield {"file": full,
371 yield {"file": full,
372 "parity": parity.next(),
372 "parity": parity.next(),
373 "basename": f,
373 "basename": f,
374 "date": fctx.date(),
374 "date": fctx.date(),
375 "size": fctx.size(),
375 "size": fctx.size(),
376 "permissions": mf.flags(full)}
376 "permissions": mf.flags(full)}
377
377
378 def dirlist(**map):
378 def dirlist(**map):
379 for d in sorted(dirs):
379 for d in sorted(dirs):
380
380
381 emptydirs = []
381 emptydirs = []
382 h = dirs[d]
382 h = dirs[d]
383 while isinstance(h, dict) and len(h) == 1:
383 while isinstance(h, dict) and len(h) == 1:
384 k, v = h.items()[0]
384 k, v = h.items()[0]
385 if v:
385 if v:
386 emptydirs.append(k)
386 emptydirs.append(k)
387 h = v
387 h = v
388
388
389 path = "%s%s" % (abspath, d)
389 path = "%s%s" % (abspath, d)
390 yield {"parity": parity.next(),
390 yield {"parity": parity.next(),
391 "path": path,
391 "path": path,
392 "emptydirs": "/".join(emptydirs),
392 "emptydirs": "/".join(emptydirs),
393 "basename": d}
393 "basename": d}
394
394
395 return tmpl("manifest",
395 return tmpl("manifest",
396 rev=ctx.rev(),
396 rev=ctx.rev(),
397 node=hex(node),
397 node=hex(node),
398 path=abspath,
398 path=abspath,
399 up=webutil.up(abspath),
399 up=webutil.up(abspath),
400 upparity=parity.next(),
400 upparity=parity.next(),
401 fentries=filelist,
401 fentries=filelist,
402 dentries=dirlist,
402 dentries=dirlist,
403 archives=web.archivelist(hex(node)),
403 archives=web.archivelist(hex(node)),
404 tags=webutil.nodetagsdict(web.repo, node),
404 tags=webutil.nodetagsdict(web.repo, node),
405 bookmarks=webutil.nodebookmarksdict(web.repo, node),
405 bookmarks=webutil.nodebookmarksdict(web.repo, node),
406 inbranch=webutil.nodeinbranch(web.repo, ctx),
406 inbranch=webutil.nodeinbranch(web.repo, ctx),
407 branches=webutil.nodebranchdict(web.repo, ctx))
407 branches=webutil.nodebranchdict(web.repo, ctx))
408
408
409 def tags(web, req, tmpl):
409 def tags(web, req, tmpl):
410 i = list(reversed(web.repo.tagslist()))
410 i = list(reversed(web.repo.tagslist()))
411 parity = paritygen(web.stripecount)
411 parity = paritygen(web.stripecount)
412
412
413 def entries(notip, latestonly, **map):
413 def entries(notip, latestonly, **map):
414 t = i
414 t = i
415 if notip:
415 if notip:
416 t = [(k, n) for k, n in i if k != "tip"]
416 t = [(k, n) for k, n in i if k != "tip"]
417 if latestonly:
417 if latestonly:
418 t = t[:1]
418 t = t[:1]
419 for k, n in t:
419 for k, n in t:
420 yield {"parity": parity.next(),
420 yield {"parity": parity.next(),
421 "tag": k,
421 "tag": k,
422 "date": web.repo[n].date(),
422 "date": web.repo[n].date(),
423 "node": hex(n)}
423 "node": hex(n)}
424
424
425 return tmpl("tags",
425 return tmpl("tags",
426 node=hex(web.repo.changelog.tip()),
426 node=hex(web.repo.changelog.tip()),
427 entries=lambda **x: entries(False, False, **x),
427 entries=lambda **x: entries(False, False, **x),
428 entriesnotip=lambda **x: entries(True, False, **x),
428 entriesnotip=lambda **x: entries(True, False, **x),
429 latestentry=lambda **x: entries(True, True, **x))
429 latestentry=lambda **x: entries(True, True, **x))
430
430
431 def bookmarks(web, req, tmpl):
431 def bookmarks(web, req, tmpl):
432 i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
432 i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
433 parity = paritygen(web.stripecount)
433 parity = paritygen(web.stripecount)
434
434
435 def entries(latestonly, **map):
435 def entries(latestonly, **map):
436 if latestonly:
436 if latestonly:
437 t = [min(i)]
437 t = [min(i)]
438 else:
438 else:
439 t = sorted(i)
439 t = sorted(i)
440 for k, n in t:
440 for k, n in t:
441 yield {"parity": parity.next(),
441 yield {"parity": parity.next(),
442 "bookmark": k,
442 "bookmark": k,
443 "date": web.repo[n].date(),
443 "date": web.repo[n].date(),
444 "node": hex(n)}
444 "node": hex(n)}
445
445
446 return tmpl("bookmarks",
446 return tmpl("bookmarks",
447 node=hex(web.repo.changelog.tip()),
447 node=hex(web.repo.changelog.tip()),
448 entries=lambda **x: entries(latestonly=False, **x),
448 entries=lambda **x: entries(latestonly=False, **x),
449 latestentry=lambda **x: entries(latestonly=True, **x))
449 latestentry=lambda **x: entries(latestonly=True, **x))
450
450
451 def branches(web, req, tmpl):
451 def branches(web, req, tmpl):
452 tips = []
452 tips = []
453 heads = web.repo.heads()
453 heads = web.repo.heads()
454 parity = paritygen(web.stripecount)
454 parity = paritygen(web.stripecount)
455 sortkey = lambda ctx: (not ctx.closesbranch(), ctx.rev())
455 sortkey = lambda ctx: (not ctx.closesbranch(), ctx.rev())
456
456
457 def entries(limit, **map):
457 def entries(limit, **map):
458 count = 0
458 count = 0
459 if not tips:
459 if not tips:
460 for t, n in web.repo.branchtags().iteritems():
460 for t, n in web.repo.branchtags().iteritems():
461 tips.append(web.repo[n])
461 tips.append(web.repo[n])
462 for ctx in sorted(tips, key=sortkey, reverse=True):
462 for ctx in sorted(tips, key=sortkey, reverse=True):
463 if limit > 0 and count >= limit:
463 if limit > 0 and count >= limit:
464 return
464 return
465 count += 1
465 count += 1
466 if not web.repo.branchheads(ctx.branch()):
466 if not web.repo.branchheads(ctx.branch()):
467 status = 'closed'
467 status = 'closed'
468 elif ctx.node() not in heads:
468 elif ctx.node() not in heads:
469 status = 'inactive'
469 status = 'inactive'
470 else:
470 else:
471 status = 'open'
471 status = 'open'
472 yield {'parity': parity.next(),
472 yield {'parity': parity.next(),
473 'branch': ctx.branch(),
473 'branch': ctx.branch(),
474 'status': status,
474 'status': status,
475 'node': ctx.hex(),
475 'node': ctx.hex(),
476 'date': ctx.date()}
476 'date': ctx.date()}
477
477
478 return tmpl('branches', node=hex(web.repo.changelog.tip()),
478 return tmpl('branches', node=hex(web.repo.changelog.tip()),
479 entries=lambda **x: entries(0, **x),
479 entries=lambda **x: entries(0, **x),
480 latestentry=lambda **x: entries(1, **x))
480 latestentry=lambda **x: entries(1, **x))
481
481
482 def summary(web, req, tmpl):
482 def summary(web, req, tmpl):
483 i = reversed(web.repo.tagslist())
483 i = reversed(web.repo.tagslist())
484
484
485 def tagentries(**map):
485 def tagentries(**map):
486 parity = paritygen(web.stripecount)
486 parity = paritygen(web.stripecount)
487 count = 0
487 count = 0
488 for k, n in i:
488 for k, n in i:
489 if k == "tip": # skip tip
489 if k == "tip": # skip tip
490 continue
490 continue
491
491
492 count += 1
492 count += 1
493 if count > 10: # limit to 10 tags
493 if count > 10: # limit to 10 tags
494 break
494 break
495
495
496 yield tmpl("tagentry",
496 yield tmpl("tagentry",
497 parity=parity.next(),
497 parity=parity.next(),
498 tag=k,
498 tag=k,
499 node=hex(n),
499 node=hex(n),
500 date=web.repo[n].date())
500 date=web.repo[n].date())
501
501
502 def bookmarks(**map):
502 def bookmarks(**map):
503 parity = paritygen(web.stripecount)
503 parity = paritygen(web.stripecount)
504 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
504 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
505 for k, n in sorted(marks)[:10]: # limit to 10 bookmarks
505 for k, n in sorted(marks)[:10]: # limit to 10 bookmarks
506 yield {'parity': parity.next(),
506 yield {'parity': parity.next(),
507 'bookmark': k,
507 'bookmark': k,
508 'date': web.repo[n].date(),
508 'date': web.repo[n].date(),
509 'node': hex(n)}
509 'node': hex(n)}
510
510
511 def branches(**map):
511 def branches(**map):
512 parity = paritygen(web.stripecount)
512 parity = paritygen(web.stripecount)
513
513
514 b = web.repo.branchtags()
514 b = web.repo.branchtags()
515 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
515 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
516 for r, n, t in sorted(l):
516 for r, n, t in sorted(l):
517 yield {'parity': parity.next(),
517 yield {'parity': parity.next(),
518 'branch': t,
518 'branch': t,
519 'node': hex(n),
519 'node': hex(n),
520 'date': web.repo[n].date()}
520 'date': web.repo[n].date()}
521
521
522 def changelist(**map):
522 def changelist(**map):
523 parity = paritygen(web.stripecount, offset=start - end)
523 parity = paritygen(web.stripecount, offset=start - end)
524 l = [] # build a list in forward order for efficiency
524 l = [] # build a list in forward order for efficiency
525 revs = []
525 revs = []
526 if start < end:
526 if start < end:
527 revs = web.repo.changelog.revs(start, end - 1)
527 revs = web.repo.changelog.revs(start, end - 1)
528 for i in revs:
528 for i in revs:
529 ctx = web.repo[i]
529 ctx = web.repo[i]
530 n = ctx.node()
530 n = ctx.node()
531 hn = hex(n)
531 hn = hex(n)
532
532
533 l.append(tmpl(
533 l.append(tmpl(
534 'shortlogentry',
534 'shortlogentry',
535 parity=parity.next(),
535 parity=parity.next(),
536 author=ctx.user(),
536 author=ctx.user(),
537 desc=ctx.description(),
537 desc=ctx.description(),
538 extra=ctx.extra(),
538 extra=ctx.extra(),
539 date=ctx.date(),
539 date=ctx.date(),
540 rev=i,
540 rev=i,
541 node=hn,
541 node=hn,
542 tags=webutil.nodetagsdict(web.repo, n),
542 tags=webutil.nodetagsdict(web.repo, n),
543 bookmarks=webutil.nodebookmarksdict(web.repo, n),
543 bookmarks=webutil.nodebookmarksdict(web.repo, n),
544 inbranch=webutil.nodeinbranch(web.repo, ctx),
544 inbranch=webutil.nodeinbranch(web.repo, ctx),
545 branches=webutil.nodebranchdict(web.repo, ctx)))
545 branches=webutil.nodebranchdict(web.repo, ctx)))
546
546
547 l.reverse()
547 l.reverse()
548 yield l
548 yield l
549
549
550 tip = web.repo['tip']
550 tip = web.repo['tip']
551 count = len(web.repo)
551 count = len(web.repo)
552 start = max(0, count - web.maxchanges)
552 start = max(0, count - web.maxchanges)
553 end = min(count, start + web.maxchanges)
553 end = min(count, start + web.maxchanges)
554
554
555 return tmpl("summary",
555 return tmpl("summary",
556 desc=web.config("web", "description", "unknown"),
556 desc=web.config("web", "description", "unknown"),
557 owner=get_contact(web.config) or "unknown",
557 owner=get_contact(web.config) or "unknown",
558 lastchange=tip.date(),
558 lastchange=tip.date(),
559 tags=tagentries,
559 tags=tagentries,
560 bookmarks=bookmarks,
560 bookmarks=bookmarks,
561 branches=branches,
561 branches=branches,
562 shortlog=changelist,
562 shortlog=changelist,
563 node=tip.hex(),
563 node=tip.hex(),
564 archives=web.archivelist("tip"))
564 archives=web.archivelist("tip"))
565
565
566 def filediff(web, req, tmpl):
566 def filediff(web, req, tmpl):
567 fctx, ctx = None, None
567 fctx, ctx = None, None
568 try:
568 try:
569 fctx = webutil.filectx(web.repo, req)
569 fctx = webutil.filectx(web.repo, req)
570 except LookupError:
570 except LookupError:
571 ctx = webutil.changectx(web.repo, req)
571 ctx = webutil.changectx(web.repo, req)
572 path = webutil.cleanpath(web.repo, req.form['file'][0])
572 path = webutil.cleanpath(web.repo, req.form['file'][0])
573 if path not in ctx.files():
573 if path not in ctx.files():
574 raise
574 raise
575
575
576 if fctx is not None:
576 if fctx is not None:
577 n = fctx.node()
577 n = fctx.node()
578 path = fctx.path()
578 path = fctx.path()
579 ctx = fctx.changectx()
579 ctx = fctx.changectx()
580 else:
580 else:
581 n = ctx.node()
581 n = ctx.node()
582 # path already defined in except clause
582 # path already defined in except clause
583
583
584 parity = paritygen(web.stripecount)
584 parity = paritygen(web.stripecount)
585 style = web.config('web', 'style', 'paper')
585 style = web.config('web', 'style', 'paper')
586 if 'style' in req.form:
586 if 'style' in req.form:
587 style = req.form['style'][0]
587 style = req.form['style'][0]
588
588
589 diffs = webutil.diffs(web.repo, tmpl, ctx, None, [path], parity, style)
589 diffs = webutil.diffs(web.repo, tmpl, ctx, None, [path], parity, style)
590 rename = fctx and webutil.renamelink(fctx) or []
590 rename = fctx and webutil.renamelink(fctx) or []
591 ctx = fctx and fctx or ctx
591 ctx = fctx and fctx or ctx
592 return tmpl("filediff",
592 return tmpl("filediff",
593 file=path,
593 file=path,
594 node=hex(n),
594 node=hex(n),
595 rev=ctx.rev(),
595 rev=ctx.rev(),
596 date=ctx.date(),
596 date=ctx.date(),
597 desc=ctx.description(),
597 desc=ctx.description(),
598 extra=ctx.extra(),
598 extra=ctx.extra(),
599 author=ctx.user(),
599 author=ctx.user(),
600 rename=rename,
600 rename=rename,
601 branch=webutil.nodebranchnodefault(ctx),
601 branch=webutil.nodebranchnodefault(ctx),
602 parent=webutil.parents(ctx),
602 parent=webutil.parents(ctx),
603 child=webutil.children(ctx),
603 child=webutil.children(ctx),
604 diff=diffs)
604 diff=diffs)
605
605
606 diff = filediff
606 diff = filediff
607
607
608 def comparison(web, req, tmpl):
608 def comparison(web, req, tmpl):
609 ctx = webutil.changectx(web.repo, req)
609 ctx = webutil.changectx(web.repo, req)
610 if 'file' not in req.form:
610 if 'file' not in req.form:
611 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
611 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
612 path = webutil.cleanpath(web.repo, req.form['file'][0])
612 path = webutil.cleanpath(web.repo, req.form['file'][0])
613 rename = path in ctx and webutil.renamelink(ctx[path]) or []
613 rename = path in ctx and webutil.renamelink(ctx[path]) or []
614
614
615 parsecontext = lambda v: v == 'full' and -1 or int(v)
615 parsecontext = lambda v: v == 'full' and -1 or int(v)
616 if 'context' in req.form:
616 if 'context' in req.form:
617 context = parsecontext(req.form['context'][0])
617 context = parsecontext(req.form['context'][0])
618 else:
618 else:
619 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
619 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
620
620
621 def filelines(f):
621 def filelines(f):
622 if binary(f.data()):
622 if binary(f.data()):
623 mt = mimetypes.guess_type(f.path())[0]
623 mt = mimetypes.guess_type(f.path())[0]
624 if not mt:
624 if not mt:
625 mt = 'application/octet-stream'
625 mt = 'application/octet-stream'
626 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
626 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
627 return f.data().splitlines()
627 return f.data().splitlines()
628
628
629 if path in ctx:
629 if path in ctx:
630 fctx = ctx[path]
630 fctx = ctx[path]
631 rightrev = fctx.filerev()
631 rightrev = fctx.filerev()
632 rightnode = fctx.filenode()
632 rightnode = fctx.filenode()
633 rightlines = filelines(fctx)
633 rightlines = filelines(fctx)
634 parents = fctx.parents()
634 parents = fctx.parents()
635 if not parents:
635 if not parents:
636 leftrev = -1
636 leftrev = -1
637 leftnode = nullid
637 leftnode = nullid
638 leftlines = ()
638 leftlines = ()
639 else:
639 else:
640 pfctx = parents[0]
640 pfctx = parents[0]
641 leftrev = pfctx.filerev()
641 leftrev = pfctx.filerev()
642 leftnode = pfctx.filenode()
642 leftnode = pfctx.filenode()
643 leftlines = filelines(pfctx)
643 leftlines = filelines(pfctx)
644 else:
644 else:
645 rightrev = -1
645 rightrev = -1
646 rightnode = nullid
646 rightnode = nullid
647 rightlines = ()
647 rightlines = ()
648 fctx = ctx.parents()[0][path]
648 fctx = ctx.parents()[0][path]
649 leftrev = fctx.filerev()
649 leftrev = fctx.filerev()
650 leftnode = fctx.filenode()
650 leftnode = fctx.filenode()
651 leftlines = filelines(fctx)
651 leftlines = filelines(fctx)
652
652
653 comparison = webutil.compare(tmpl, context, leftlines, rightlines)
653 comparison = webutil.compare(tmpl, context, leftlines, rightlines)
654 return tmpl('filecomparison',
654 return tmpl('filecomparison',
655 file=path,
655 file=path,
656 node=hex(ctx.node()),
656 node=hex(ctx.node()),
657 rev=ctx.rev(),
657 rev=ctx.rev(),
658 date=ctx.date(),
658 date=ctx.date(),
659 desc=ctx.description(),
659 desc=ctx.description(),
660 extra=ctx.extra(),
660 extra=ctx.extra(),
661 author=ctx.user(),
661 author=ctx.user(),
662 rename=rename,
662 rename=rename,
663 branch=webutil.nodebranchnodefault(ctx),
663 branch=webutil.nodebranchnodefault(ctx),
664 parent=webutil.parents(fctx),
664 parent=webutil.parents(fctx),
665 child=webutil.children(fctx),
665 child=webutil.children(fctx),
666 leftrev=leftrev,
666 leftrev=leftrev,
667 leftnode=hex(leftnode),
667 leftnode=hex(leftnode),
668 rightrev=rightrev,
668 rightrev=rightrev,
669 rightnode=hex(rightnode),
669 rightnode=hex(rightnode),
670 comparison=comparison)
670 comparison=comparison)
671
671
672 def annotate(web, req, tmpl):
672 def annotate(web, req, tmpl):
673 fctx = webutil.filectx(web.repo, req)
673 fctx = webutil.filectx(web.repo, req)
674 f = fctx.path()
674 f = fctx.path()
675 parity = paritygen(web.stripecount)
675 parity = paritygen(web.stripecount)
676 diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
676 diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
677
677
678 def annotate(**map):
678 def annotate(**map):
679 last = None
679 last = None
680 if binary(fctx.data()):
680 if binary(fctx.data()):
681 mt = (mimetypes.guess_type(fctx.path())[0]
681 mt = (mimetypes.guess_type(fctx.path())[0]
682 or 'application/octet-stream')
682 or 'application/octet-stream')
683 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
683 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
684 '(binary:%s)' % mt)])
684 '(binary:%s)' % mt)])
685 else:
685 else:
686 lines = enumerate(fctx.annotate(follow=True, linenumber=True,
686 lines = enumerate(fctx.annotate(follow=True, linenumber=True,
687 diffopts=diffopts))
687 diffopts=diffopts))
688 for lineno, ((f, targetline), l) in lines:
688 for lineno, ((f, targetline), l) in lines:
689 fnode = f.filenode()
689 fnode = f.filenode()
690
690
691 if last != fnode:
691 if last != fnode:
692 last = fnode
692 last = fnode
693
693
694 yield {"parity": parity.next(),
694 yield {"parity": parity.next(),
695 "node": f.hex(),
695 "node": f.hex(),
696 "rev": f.rev(),
696 "rev": f.rev(),
697 "author": f.user(),
697 "author": f.user(),
698 "desc": f.description(),
698 "desc": f.description(),
699 "extra": f.extra(),
699 "extra": f.extra(),
700 "file": f.path(),
700 "file": f.path(),
701 "targetline": targetline,
701 "targetline": targetline,
702 "line": l,
702 "line": l,
703 "lineid": "l%d" % (lineno + 1),
703 "lineid": "l%d" % (lineno + 1),
704 "linenumber": "% 6d" % (lineno + 1),
704 "linenumber": "% 6d" % (lineno + 1),
705 "revdate": f.date()}
705 "revdate": f.date()}
706
706
707 return tmpl("fileannotate",
707 return tmpl("fileannotate",
708 file=f,
708 file=f,
709 annotate=annotate,
709 annotate=annotate,
710 path=webutil.up(f),
710 path=webutil.up(f),
711 rev=fctx.rev(),
711 rev=fctx.rev(),
712 node=fctx.hex(),
712 node=fctx.hex(),
713 author=fctx.user(),
713 author=fctx.user(),
714 date=fctx.date(),
714 date=fctx.date(),
715 desc=fctx.description(),
715 desc=fctx.description(),
716 extra=fctx.extra(),
716 extra=fctx.extra(),
717 rename=webutil.renamelink(fctx),
717 rename=webutil.renamelink(fctx),
718 branch=webutil.nodebranchnodefault(fctx),
718 branch=webutil.nodebranchnodefault(fctx),
719 parent=webutil.parents(fctx),
719 parent=webutil.parents(fctx),
720 child=webutil.children(fctx),
720 child=webutil.children(fctx),
721 permissions=fctx.manifest().flags(f))
721 permissions=fctx.manifest().flags(f))
722
722
723 def filelog(web, req, tmpl):
723 def filelog(web, req, tmpl):
724
724
725 try:
725 try:
726 fctx = webutil.filectx(web.repo, req)
726 fctx = webutil.filectx(web.repo, req)
727 f = fctx.path()
727 f = fctx.path()
728 fl = fctx.filelog()
728 fl = fctx.filelog()
729 except error.LookupError:
729 except error.LookupError:
730 f = webutil.cleanpath(web.repo, req.form['file'][0])
730 f = webutil.cleanpath(web.repo, req.form['file'][0])
731 fl = web.repo.file(f)
731 fl = web.repo.file(f)
732 numrevs = len(fl)
732 numrevs = len(fl)
733 if not numrevs: # file doesn't exist at all
733 if not numrevs: # file doesn't exist at all
734 raise
734 raise
735 rev = webutil.changectx(web.repo, req).rev()
735 rev = webutil.changectx(web.repo, req).rev()
736 first = fl.linkrev(0)
736 first = fl.linkrev(0)
737 if rev < first: # current rev is from before file existed
737 if rev < first: # current rev is from before file existed
738 raise
738 raise
739 frev = numrevs - 1
739 frev = numrevs - 1
740 while fl.linkrev(frev) > rev:
740 while fl.linkrev(frev) > rev:
741 frev -= 1
741 frev -= 1
742 fctx = web.repo.filectx(f, fl.linkrev(frev))
742 fctx = web.repo.filectx(f, fl.linkrev(frev))
743
743
744 revcount = web.maxshortchanges
744 revcount = web.maxshortchanges
745 if 'revcount' in req.form:
745 if 'revcount' in req.form:
746 revcount = int(req.form.get('revcount', [revcount])[0])
746 revcount = int(req.form.get('revcount', [revcount])[0])
747 revcount = max(revcount, 1)
747 revcount = max(revcount, 1)
748 tmpl.defaults['sessionvars']['revcount'] = revcount
748 tmpl.defaults['sessionvars']['revcount'] = revcount
749
749
750 lessvars = copy.copy(tmpl.defaults['sessionvars'])
750 lessvars = copy.copy(tmpl.defaults['sessionvars'])
751 lessvars['revcount'] = max(revcount / 2, 1)
751 lessvars['revcount'] = max(revcount / 2, 1)
752 morevars = copy.copy(tmpl.defaults['sessionvars'])
752 morevars = copy.copy(tmpl.defaults['sessionvars'])
753 morevars['revcount'] = revcount * 2
753 morevars['revcount'] = revcount * 2
754
754
755 count = fctx.filerev() + 1
755 count = fctx.filerev() + 1
756 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
756 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
757 end = min(count, start + revcount) # last rev on this page
757 end = min(count, start + revcount) # last rev on this page
758 parity = paritygen(web.stripecount, offset=start - end)
758 parity = paritygen(web.stripecount, offset=start - end)
759
759
760 def entries(latestonly, **map):
760 def entries(latestonly, **map):
761 l = []
761 l = []
762
762
763 repo = web.repo
763 repo = web.repo
764 revs = repo.changelog.revs(start, end - 1)
764 revs = repo.changelog.revs(start, end - 1)
765 if latestonly:
765 if latestonly:
766 for r in revs:
766 for r in revs:
767 pass
767 pass
768 revs = (r,)
768 revs = (r,)
769 for i in revs:
769 for i in revs:
770 iterfctx = fctx.filectx(i)
770 iterfctx = fctx.filectx(i)
771
771
772 l.append({"parity": parity.next(),
772 l.append({"parity": parity.next(),
773 "filerev": i,
773 "filerev": i,
774 "file": f,
774 "file": f,
775 "node": iterfctx.hex(),
775 "node": iterfctx.hex(),
776 "author": iterfctx.user(),
776 "author": iterfctx.user(),
777 "date": iterfctx.date(),
777 "date": iterfctx.date(),
778 "rename": webutil.renamelink(iterfctx),
778 "rename": webutil.renamelink(iterfctx),
779 "parent": webutil.parents(iterfctx),
779 "parent": webutil.parents(iterfctx),
780 "child": webutil.children(iterfctx),
780 "child": webutil.children(iterfctx),
781 "desc": iterfctx.description(),
781 "desc": iterfctx.description(),
782 "extra": iterfctx.extra(),
782 "extra": iterfctx.extra(),
783 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
783 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
784 "bookmarks": webutil.nodebookmarksdict(
784 "bookmarks": webutil.nodebookmarksdict(
785 repo, iterfctx.node()),
785 repo, iterfctx.node()),
786 "branch": webutil.nodebranchnodefault(iterfctx),
786 "branch": webutil.nodebranchnodefault(iterfctx),
787 "inbranch": webutil.nodeinbranch(repo, iterfctx),
787 "inbranch": webutil.nodeinbranch(repo, iterfctx),
788 "branches": webutil.nodebranchdict(repo, iterfctx)})
788 "branches": webutil.nodebranchdict(repo, iterfctx)})
789 for e in reversed(l):
789 for e in reversed(l):
790 yield e
790 yield e
791
791
792 revnav = webutil.filerevnav(web.repo, fctx.path())
792 revnav = webutil.filerevnav(web.repo, fctx.path())
793 nav = revnav.gen(end - 1, revcount, count)
793 nav = revnav.gen(end - 1, revcount, count)
794 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
794 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
795 entries=lambda **x: entries(latestonly=False, **x),
795 entries=lambda **x: entries(latestonly=False, **x),
796 latestentry=lambda **x: entries(latestonly=True, **x),
796 latestentry=lambda **x: entries(latestonly=True, **x),
797 revcount=revcount, morevars=morevars, lessvars=lessvars)
797 revcount=revcount, morevars=morevars, lessvars=lessvars)
798
798
799 def archive(web, req, tmpl):
799 def archive(web, req, tmpl):
800 type_ = req.form.get('type', [None])[0]
800 type_ = req.form.get('type', [None])[0]
801 allowed = web.configlist("web", "allow_archive")
801 allowed = web.configlist("web", "allow_archive")
802 key = req.form['node'][0]
802 key = req.form['node'][0]
803
803
804 if type_ not in web.archives:
804 if type_ not in web.archives:
805 msg = 'Unsupported archive type: %s' % type_
805 msg = 'Unsupported archive type: %s' % type_
806 raise ErrorResponse(HTTP_NOT_FOUND, msg)
806 raise ErrorResponse(HTTP_NOT_FOUND, msg)
807
807
808 if not ((type_ in allowed or
808 if not ((type_ in allowed or
809 web.configbool("web", "allow" + type_, False))):
809 web.configbool("web", "allow" + type_, False))):
810 msg = 'Archive type not allowed: %s' % type_
810 msg = 'Archive type not allowed: %s' % type_
811 raise ErrorResponse(HTTP_FORBIDDEN, msg)
811 raise ErrorResponse(HTTP_FORBIDDEN, msg)
812
812
813 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
813 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
814 cnode = web.repo.lookup(key)
814 cnode = web.repo.lookup(key)
815 arch_version = key
815 arch_version = key
816 if cnode == key or key == 'tip':
816 if cnode == key or key == 'tip':
817 arch_version = short(cnode)
817 arch_version = short(cnode)
818 name = "%s-%s" % (reponame, arch_version)
818 name = "%s-%s" % (reponame, arch_version)
819 mimetype, artype, extension, encoding = web.archive_specs[type_]
819 mimetype, artype, extension, encoding = web.archive_specs[type_]
820 headers = [
820 headers = [
821 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
821 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
822 ]
822 ]
823 if encoding:
823 if encoding:
824 headers.append(('Content-Encoding', encoding))
824 headers.append(('Content-Encoding', encoding))
825 req.headers.extend(headers)
825 req.headers.extend(headers)
826 req.respond(HTTP_OK, mimetype)
826 req.respond(HTTP_OK, mimetype)
827
827
828 ctx = webutil.changectx(web.repo, req)
828 ctx = webutil.changectx(web.repo, req)
829 archival.archive(web.repo, req, cnode, artype, prefix=name,
829 archival.archive(web.repo, req, cnode, artype, prefix=name,
830 matchfn=scmutil.match(ctx, []),
830 matchfn=scmutil.match(ctx, []),
831 subrepos=web.configbool("web", "archivesubrepos"))
831 subrepos=web.configbool("web", "archivesubrepos"))
832 return []
832 return []
833
833
834
834
835 def static(web, req, tmpl):
835 def static(web, req, tmpl):
836 fname = req.form['file'][0]
836 fname = req.form['file'][0]
837 # a repo owner may set web.static in .hg/hgrc to get any file
837 # a repo owner may set web.static in .hg/hgrc to get any file
838 # readable by the user running the CGI script
838 # readable by the user running the CGI script
839 static = web.config("web", "static", None, untrusted=False)
839 static = web.config("web", "static", None, untrusted=False)
840 if not static:
840 if not static:
841 tp = web.templatepath or templater.templatepath()
841 tp = web.templatepath or templater.templatepath()
842 if isinstance(tp, str):
842 if isinstance(tp, str):
843 tp = [tp]
843 tp = [tp]
844 static = [os.path.join(p, 'static') for p in tp]
844 static = [os.path.join(p, 'static') for p in tp]
845 staticfile(static, fname, req)
845 staticfile(static, fname, req)
846 return []
846 return []
847
847
848 def graph(web, req, tmpl):
848 def graph(web, req, tmpl):
849
849
850 ctx = webutil.changectx(web.repo, req)
850 ctx = webutil.changectx(web.repo, req)
851 rev = ctx.rev()
851 rev = ctx.rev()
852
852
853 bg_height = 39
853 bg_height = 39
854 revcount = web.maxshortchanges
854 revcount = web.maxshortchanges
855 if 'revcount' in req.form:
855 if 'revcount' in req.form:
856 revcount = int(req.form.get('revcount', [revcount])[0])
856 revcount = int(req.form.get('revcount', [revcount])[0])
857 revcount = max(revcount, 1)
857 revcount = max(revcount, 1)
858 tmpl.defaults['sessionvars']['revcount'] = revcount
858 tmpl.defaults['sessionvars']['revcount'] = revcount
859
859
860 lessvars = copy.copy(tmpl.defaults['sessionvars'])
860 lessvars = copy.copy(tmpl.defaults['sessionvars'])
861 lessvars['revcount'] = max(revcount / 2, 1)
861 lessvars['revcount'] = max(revcount / 2, 1)
862 morevars = copy.copy(tmpl.defaults['sessionvars'])
862 morevars = copy.copy(tmpl.defaults['sessionvars'])
863 morevars['revcount'] = revcount * 2
863 morevars['revcount'] = revcount * 2
864
864
865 count = len(web.repo)
865 count = len(web.repo)
866 pos = rev
866 pos = rev
867 start = max(0, pos - revcount + 1)
867 start = max(0, pos - revcount + 1)
868 end = min(count, start + revcount)
868 end = min(count, start + revcount)
869 pos = end - 1
869 pos = end - 1
870
870
871 uprev = min(max(0, count - 1), rev + revcount)
871 uprev = min(max(0, count - 1), rev + revcount)
872 downrev = max(0, rev - revcount)
872 downrev = max(0, rev - revcount)
873 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
873 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
874
874
875 tree = []
875 tree = []
876 if start < end:
876 if start < end:
877 revs = list(web.repo.changelog.revs(end - 1, start))
877 revs = list(web.repo.changelog.revs(end - 1, start))
878 dag = graphmod.dagwalker(web.repo, revs)
878 dag = graphmod.dagwalker(web.repo, revs)
879 tree = list(graphmod.colored(dag, web.repo))
879 tree = list(graphmod.colored(dag, web.repo))
880
880
881 def getcolumns(tree):
881 def getcolumns(tree):
882 cols = 0
882 cols = 0
883 for (id, type, ctx, vtx, edges) in tree:
883 for (id, type, ctx, vtx, edges) in tree:
884 if type != graphmod.CHANGESET:
884 if type != graphmod.CHANGESET:
885 continue
885 continue
886 cols = max(cols, max([edge[0] for edge in edges] or [0]),
886 cols = max(cols, max([edge[0] for edge in edges] or [0]),
887 max([edge[1] for edge in edges] or [0]))
887 max([edge[1] for edge in edges] or [0]))
888 return cols
888 return cols
889
889
890 def graphdata(usetuples, **map):
890 def graphdata(usetuples, **map):
891 data = []
891 data = []
892
892
893 row = 0
893 row = 0
894 for (id, type, ctx, vtx, edges) in tree:
894 for (id, type, ctx, vtx, edges) in tree:
895 if type != graphmod.CHANGESET:
895 if type != graphmod.CHANGESET:
896 continue
896 continue
897 node = str(ctx)
897 node = str(ctx)
898 age = templatefilters.age(ctx.date())
898 age = templatefilters.age(ctx.date())
899 desc = templatefilters.firstline(ctx.description())
899 desc = templatefilters.firstline(ctx.description())
900 desc = cgi.escape(templatefilters.nonempty(desc))
900 desc = cgi.escape(templatefilters.nonempty(desc))
901 user = cgi.escape(templatefilters.person(ctx.user()))
901 user = cgi.escape(templatefilters.person(ctx.user()))
902 branch = ctx.branch()
902 branch = ctx.branch()
903 try:
903 try:
904 branchnode = web.repo.branchtip(branch)
904 branchnode = web.repo.branchtip(branch)
905 except error.RepoLookupError:
905 except error.RepoLookupError:
906 branchnode = None
906 branchnode = None
907 branch = branch, branchnode == ctx.node()
907 branch = branch, branchnode == ctx.node()
908
908
909 if usetuples:
909 if usetuples:
910 data.append((node, vtx, edges, desc, user, age, branch,
910 data.append((node, vtx, edges, desc, user, age, branch,
911 ctx.tags(), ctx.bookmarks()))
911 ctx.tags(), ctx.bookmarks()))
912 else:
912 else:
913 edgedata = [dict(col=edge[0], nextcol=edge[1],
913 edgedata = [dict(col=edge[0], nextcol=edge[1],
914 color=(edge[2] - 1) % 6 + 1,
914 color=(edge[2] - 1) % 6 + 1,
915 width=edge[3], bcolor=edge[4])
915 width=edge[3], bcolor=edge[4])
916 for edge in edges]
916 for edge in edges]
917
917
918 data.append(
918 data.append(
919 dict(node=node,
919 dict(node=node,
920 col=vtx[0],
920 col=vtx[0],
921 color=(vtx[1] - 1) % 6 + 1,
921 color=(vtx[1] - 1) % 6 + 1,
922 edges=edgedata,
922 edges=edgedata,
923 row=row,
923 row=row,
924 nextrow=row + 1,
924 nextrow=row + 1,
925 desc=desc,
925 desc=desc,
926 user=user,
926 user=user,
927 age=age,
927 age=age,
928 bookmarks=webutil.nodebookmarksdict(
928 bookmarks=webutil.nodebookmarksdict(
929 web.repo, ctx.node()),
929 web.repo, ctx.node()),
930 branches=webutil.nodebranchdict(web.repo, ctx),
930 branches=webutil.nodebranchdict(web.repo, ctx),
931 inbranch=webutil.nodeinbranch(web.repo, ctx),
931 inbranch=webutil.nodeinbranch(web.repo, ctx),
932 tags=webutil.nodetagsdict(web.repo, ctx.node())))
932 tags=webutil.nodetagsdict(web.repo, ctx.node())))
933
933
934 row += 1
934 row += 1
935
935
936 return data
936 return data
937
937
938 cols = getcolumns(tree)
938 cols = getcolumns(tree)
939 rows = len(tree)
939 rows = len(tree)
940 canvasheight = (rows + 1) * bg_height - 27
940 canvasheight = (rows + 1) * bg_height - 27
941
941
942 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
942 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
943 lessvars=lessvars, morevars=morevars, downrev=downrev,
943 lessvars=lessvars, morevars=morevars, downrev=downrev,
944 cols=cols, rows=rows,
944 cols=cols, rows=rows,
945 canvaswidth=(cols + 1) * bg_height,
945 canvaswidth=(cols + 1) * bg_height,
946 truecanvasheight=rows * bg_height,
946 truecanvasheight=rows * bg_height,
947 canvasheight=canvasheight, bg_height=bg_height,
947 canvasheight=canvasheight, bg_height=bg_height,
948 jsdata=lambda **x: graphdata(True, **x),
948 jsdata=lambda **x: graphdata(True, **x),
949 nodes=lambda **x: graphdata(False, **x),
949 nodes=lambda **x: graphdata(False, **x),
950 node=ctx.hex(), changenav=changenav)
950 node=ctx.hex(), changenav=changenav)
951
951
952 def _getdoc(e):
952 def _getdoc(e):
953 doc = e[0].__doc__
953 doc = e[0].__doc__
954 if doc:
954 if doc:
955 doc = _(doc).split('\n')[0]
955 doc = _(doc).split('\n')[0]
956 else:
956 else:
957 doc = _('(no help text available)')
957 doc = _('(no help text available)')
958 return doc
958 return doc
959
959
960 def help(web, req, tmpl):
960 def help(web, req, tmpl):
961 from mercurial import commands # avoid cycle
961 from mercurial import commands # avoid cycle
962
962
963 topicname = req.form.get('node', [None])[0]
963 topicname = req.form.get('node', [None])[0]
964 if not topicname:
964 if not topicname:
965 def topics(**map):
965 def topics(**map):
966 for entries, summary, _ in helpmod.helptable:
966 for entries, summary, _ in helpmod.helptable:
967 yield {'topic': entries[0], 'summary': summary}
967 yield {'topic': entries[0], 'summary': summary}
968
968
969 early, other = [], []
969 early, other = [], []
970 primary = lambda s: s.split('|')[0]
970 primary = lambda s: s.split('|')[0]
971 for c, e in commands.table.iteritems():
971 for c, e in commands.table.iteritems():
972 doc = _getdoc(e)
972 doc = _getdoc(e)
973 if 'DEPRECATED' in doc or c.startswith('debug'):
973 if 'DEPRECATED' in doc or c.startswith('debug'):
974 continue
974 continue
975 cmd = primary(c)
975 cmd = primary(c)
976 if cmd.startswith('^'):
976 if cmd.startswith('^'):
977 early.append((cmd[1:], doc))
977 early.append((cmd[1:], doc))
978 else:
978 else:
979 other.append((cmd, doc))
979 other.append((cmd, doc))
980
980
981 early.sort()
981 early.sort()
982 other.sort()
982 other.sort()
983
983
984 def earlycommands(**map):
984 def earlycommands(**map):
985 for c, doc in early:
985 for c, doc in early:
986 yield {'topic': c, 'summary': doc}
986 yield {'topic': c, 'summary': doc}
987
987
988 def othercommands(**map):
988 def othercommands(**map):
989 for c, doc in other:
989 for c, doc in other:
990 yield {'topic': c, 'summary': doc}
990 yield {'topic': c, 'summary': doc}
991
991
992 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
992 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
993 othercommands=othercommands, title='Index')
993 othercommands=othercommands, title='Index')
994
994
995 u = webutil.wsgiui()
995 u = webutil.wsgiui()
996 u.pushbuffer()
997 u.verbose = True
996 u.verbose = True
998 try:
997 try:
999 commands.help_(u, topicname)
998 doc = helpmod.help_(u, topicname)
1000 except error.UnknownCommand:
999 except error.UnknownCommand:
1001 raise ErrorResponse(HTTP_NOT_FOUND)
1000 raise ErrorResponse(HTTP_NOT_FOUND)
1002 doc = u.popbuffer()
1003 return tmpl('help', topic=topicname, doc=doc)
1001 return tmpl('help', topic=topicname, doc=doc)
@@ -1,505 +1,517 b''
1 # templater.py - template expansion for output
1 # templater.py - template expansion for output
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 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 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import sys, os, re
9 import sys, os, re
10 import util, config, templatefilters, parser, error
10 import util, config, templatefilters, parser, error
11 import types
11 import types
12 import minirst
12
13
13 # template parsing
14 # template parsing
14
15
15 elements = {
16 elements = {
16 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
17 ",": (2, None, ("list", 2)),
18 ",": (2, None, ("list", 2)),
18 "|": (5, None, ("|", 5)),
19 "|": (5, None, ("|", 5)),
19 "%": (6, None, ("%", 6)),
20 "%": (6, None, ("%", 6)),
20 ")": (0, None, None),
21 ")": (0, None, None),
21 "symbol": (0, ("symbol",), None),
22 "symbol": (0, ("symbol",), None),
22 "string": (0, ("string",), None),
23 "string": (0, ("string",), None),
23 "end": (0, None, None),
24 "end": (0, None, None),
24 }
25 }
25
26
26 def tokenizer(data):
27 def tokenizer(data):
27 program, start, end = data
28 program, start, end = data
28 pos = start
29 pos = start
29 while pos < end:
30 while pos < end:
30 c = program[pos]
31 c = program[pos]
31 if c.isspace(): # skip inter-token whitespace
32 if c.isspace(): # skip inter-token whitespace
32 pass
33 pass
33 elif c in "(,)%|": # handle simple operators
34 elif c in "(,)%|": # handle simple operators
34 yield (c, None, pos)
35 yield (c, None, pos)
35 elif (c in '"\'' or c == 'r' and
36 elif (c in '"\'' or c == 'r' and
36 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
37 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
37 if c == 'r':
38 if c == 'r':
38 pos += 1
39 pos += 1
39 c = program[pos]
40 c = program[pos]
40 decode = False
41 decode = False
41 else:
42 else:
42 decode = True
43 decode = True
43 pos += 1
44 pos += 1
44 s = pos
45 s = pos
45 while pos < end: # find closing quote
46 while pos < end: # find closing quote
46 d = program[pos]
47 d = program[pos]
47 if decode and d == '\\': # skip over escaped characters
48 if decode and d == '\\': # skip over escaped characters
48 pos += 2
49 pos += 2
49 continue
50 continue
50 if d == c:
51 if d == c:
51 if not decode:
52 if not decode:
52 yield ('string', program[s:pos].replace('\\', r'\\'), s)
53 yield ('string', program[s:pos].replace('\\', r'\\'), s)
53 break
54 break
54 yield ('string', program[s:pos].decode('string-escape'), s)
55 yield ('string', program[s:pos].decode('string-escape'), s)
55 break
56 break
56 pos += 1
57 pos += 1
57 else:
58 else:
58 raise error.ParseError(_("unterminated string"), s)
59 raise error.ParseError(_("unterminated string"), s)
59 elif c.isalnum() or c in '_':
60 elif c.isalnum() or c in '_':
60 s = pos
61 s = pos
61 pos += 1
62 pos += 1
62 while pos < end: # find end of symbol
63 while pos < end: # find end of symbol
63 d = program[pos]
64 d = program[pos]
64 if not (d.isalnum() or d == "_"):
65 if not (d.isalnum() or d == "_"):
65 break
66 break
66 pos += 1
67 pos += 1
67 sym = program[s:pos]
68 sym = program[s:pos]
68 yield ('symbol', sym, s)
69 yield ('symbol', sym, s)
69 pos -= 1
70 pos -= 1
70 elif c == '}':
71 elif c == '}':
71 pos += 1
72 pos += 1
72 break
73 break
73 else:
74 else:
74 raise error.ParseError(_("syntax error"), pos)
75 raise error.ParseError(_("syntax error"), pos)
75 pos += 1
76 pos += 1
76 yield ('end', None, pos)
77 yield ('end', None, pos)
77
78
78 def compiletemplate(tmpl, context):
79 def compiletemplate(tmpl, context):
79 parsed = []
80 parsed = []
80 pos, stop = 0, len(tmpl)
81 pos, stop = 0, len(tmpl)
81 p = parser.parser(tokenizer, elements)
82 p = parser.parser(tokenizer, elements)
82
83
83 while pos < stop:
84 while pos < stop:
84 n = tmpl.find('{', pos)
85 n = tmpl.find('{', pos)
85 if n < 0:
86 if n < 0:
86 parsed.append(("string", tmpl[pos:]))
87 parsed.append(("string", tmpl[pos:]))
87 break
88 break
88 if n > 0 and tmpl[n - 1] == '\\':
89 if n > 0 and tmpl[n - 1] == '\\':
89 # escaped
90 # escaped
90 parsed.append(("string", tmpl[pos:n - 1] + "{"))
91 parsed.append(("string", tmpl[pos:n - 1] + "{"))
91 pos = n + 1
92 pos = n + 1
92 continue
93 continue
93 if n > pos:
94 if n > pos:
94 parsed.append(("string", tmpl[pos:n]))
95 parsed.append(("string", tmpl[pos:n]))
95
96
96 pd = [tmpl, n + 1, stop]
97 pd = [tmpl, n + 1, stop]
97 parseres, pos = p.parse(pd)
98 parseres, pos = p.parse(pd)
98 parsed.append(parseres)
99 parsed.append(parseres)
99
100
100 return [compileexp(e, context) for e in parsed]
101 return [compileexp(e, context) for e in parsed]
101
102
102 def compileexp(exp, context):
103 def compileexp(exp, context):
103 t = exp[0]
104 t = exp[0]
104 if t in methods:
105 if t in methods:
105 return methods[t](exp, context)
106 return methods[t](exp, context)
106 raise error.ParseError(_("unknown method '%s'") % t)
107 raise error.ParseError(_("unknown method '%s'") % t)
107
108
108 # template evaluation
109 # template evaluation
109
110
110 def getsymbol(exp):
111 def getsymbol(exp):
111 if exp[0] == 'symbol':
112 if exp[0] == 'symbol':
112 return exp[1]
113 return exp[1]
113 raise error.ParseError(_("expected a symbol"))
114 raise error.ParseError(_("expected a symbol"))
114
115
115 def getlist(x):
116 def getlist(x):
116 if not x:
117 if not x:
117 return []
118 return []
118 if x[0] == 'list':
119 if x[0] == 'list':
119 return getlist(x[1]) + [x[2]]
120 return getlist(x[1]) + [x[2]]
120 return [x]
121 return [x]
121
122
122 def getfilter(exp, context):
123 def getfilter(exp, context):
123 f = getsymbol(exp)
124 f = getsymbol(exp)
124 if f not in context._filters:
125 if f not in context._filters:
125 raise error.ParseError(_("unknown function '%s'") % f)
126 raise error.ParseError(_("unknown function '%s'") % f)
126 return context._filters[f]
127 return context._filters[f]
127
128
128 def gettemplate(exp, context):
129 def gettemplate(exp, context):
129 if exp[0] == 'string':
130 if exp[0] == 'string':
130 return compiletemplate(exp[1], context)
131 return compiletemplate(exp[1], context)
131 if exp[0] == 'symbol':
132 if exp[0] == 'symbol':
132 return context._load(exp[1])
133 return context._load(exp[1])
133 raise error.ParseError(_("expected template specifier"))
134 raise error.ParseError(_("expected template specifier"))
134
135
135 def runstring(context, mapping, data):
136 def runstring(context, mapping, data):
136 return data
137 return data
137
138
138 def runsymbol(context, mapping, key):
139 def runsymbol(context, mapping, key):
139 v = mapping.get(key)
140 v = mapping.get(key)
140 if v is None:
141 if v is None:
141 v = context._defaults.get(key, '')
142 v = context._defaults.get(key, '')
142 if util.safehasattr(v, '__call__'):
143 if util.safehasattr(v, '__call__'):
143 return v(**mapping)
144 return v(**mapping)
144 if isinstance(v, types.GeneratorType):
145 if isinstance(v, types.GeneratorType):
145 v = list(v)
146 v = list(v)
146 mapping[key] = v
147 mapping[key] = v
147 return v
148 return v
148 return v
149 return v
149
150
150 def buildfilter(exp, context):
151 def buildfilter(exp, context):
151 func, data = compileexp(exp[1], context)
152 func, data = compileexp(exp[1], context)
152 filt = getfilter(exp[2], context)
153 filt = getfilter(exp[2], context)
153 return (runfilter, (func, data, filt))
154 return (runfilter, (func, data, filt))
154
155
155 def runfilter(context, mapping, data):
156 def runfilter(context, mapping, data):
156 func, data, filt = data
157 func, data, filt = data
157 try:
158 try:
158 return filt(func(context, mapping, data))
159 return filt(func(context, mapping, data))
159 except (ValueError, AttributeError, TypeError):
160 except (ValueError, AttributeError, TypeError):
160 if isinstance(data, tuple):
161 if isinstance(data, tuple):
161 dt = data[1]
162 dt = data[1]
162 else:
163 else:
163 dt = data
164 dt = data
164 raise util.Abort(_("template filter '%s' is not compatible with "
165 raise util.Abort(_("template filter '%s' is not compatible with "
165 "keyword '%s'") % (filt.func_name, dt))
166 "keyword '%s'") % (filt.func_name, dt))
166
167
167 def buildmap(exp, context):
168 def buildmap(exp, context):
168 func, data = compileexp(exp[1], context)
169 func, data = compileexp(exp[1], context)
169 ctmpl = gettemplate(exp[2], context)
170 ctmpl = gettemplate(exp[2], context)
170 return (runmap, (func, data, ctmpl))
171 return (runmap, (func, data, ctmpl))
171
172
172 def runtemplate(context, mapping, template):
173 def runtemplate(context, mapping, template):
173 for func, data in template:
174 for func, data in template:
174 yield func(context, mapping, data)
175 yield func(context, mapping, data)
175
176
176 def runmap(context, mapping, data):
177 def runmap(context, mapping, data):
177 func, data, ctmpl = data
178 func, data, ctmpl = data
178 d = func(context, mapping, data)
179 d = func(context, mapping, data)
179 if util.safehasattr(d, '__call__'):
180 if util.safehasattr(d, '__call__'):
180 d = d()
181 d = d()
181
182
182 lm = mapping.copy()
183 lm = mapping.copy()
183
184
184 for i in d:
185 for i in d:
185 if isinstance(i, dict):
186 if isinstance(i, dict):
186 lm.update(i)
187 lm.update(i)
187 lm['originalnode'] = mapping.get('node')
188 lm['originalnode'] = mapping.get('node')
188 yield runtemplate(context, lm, ctmpl)
189 yield runtemplate(context, lm, ctmpl)
189 else:
190 else:
190 # v is not an iterable of dicts, this happen when 'key'
191 # v is not an iterable of dicts, this happen when 'key'
191 # has been fully expanded already and format is useless.
192 # has been fully expanded already and format is useless.
192 # If so, return the expanded value.
193 # If so, return the expanded value.
193 yield i
194 yield i
194
195
195 def buildfunc(exp, context):
196 def buildfunc(exp, context):
196 n = getsymbol(exp[1])
197 n = getsymbol(exp[1])
197 args = [compileexp(x, context) for x in getlist(exp[2])]
198 args = [compileexp(x, context) for x in getlist(exp[2])]
198 if n in funcs:
199 if n in funcs:
199 f = funcs[n]
200 f = funcs[n]
200 return (f, args)
201 return (f, args)
201 if n in templatefilters.funcs:
202 if n in templatefilters.funcs:
202 f = templatefilters.funcs[n]
203 f = templatefilters.funcs[n]
203 return (f, args)
204 return (f, args)
204 if n in context._filters:
205 if n in context._filters:
205 if len(args) != 1:
206 if len(args) != 1:
206 raise error.ParseError(_("filter %s expects one argument") % n)
207 raise error.ParseError(_("filter %s expects one argument") % n)
207 f = context._filters[n]
208 f = context._filters[n]
208 return (runfilter, (args[0][0], args[0][1], f))
209 return (runfilter, (args[0][0], args[0][1], f))
209
210
210 def get(context, mapping, args):
211 def get(context, mapping, args):
211 if len(args) != 2:
212 if len(args) != 2:
212 # i18n: "get" is a keyword
213 # i18n: "get" is a keyword
213 raise error.ParseError(_("get() expects two arguments"))
214 raise error.ParseError(_("get() expects two arguments"))
214
215
215 dictarg = args[0][0](context, mapping, args[0][1])
216 dictarg = args[0][0](context, mapping, args[0][1])
216 if not util.safehasattr(dictarg, 'get'):
217 if not util.safehasattr(dictarg, 'get'):
217 # i18n: "get" is a keyword
218 # i18n: "get" is a keyword
218 raise error.ParseError(_("get() expects a dict as first argument"))
219 raise error.ParseError(_("get() expects a dict as first argument"))
219
220
220 key = args[1][0](context, mapping, args[1][1])
221 key = args[1][0](context, mapping, args[1][1])
221 yield dictarg.get(key)
222 yield dictarg.get(key)
222
223
223 def join(context, mapping, args):
224 def join(context, mapping, args):
224 if not (1 <= len(args) <= 2):
225 if not (1 <= len(args) <= 2):
225 # i18n: "join" is a keyword
226 # i18n: "join" is a keyword
226 raise error.ParseError(_("join expects one or two arguments"))
227 raise error.ParseError(_("join expects one or two arguments"))
227
228
228 joinset = args[0][0](context, mapping, args[0][1])
229 joinset = args[0][0](context, mapping, args[0][1])
229 if util.safehasattr(joinset, '__call__'):
230 if util.safehasattr(joinset, '__call__'):
230 joinset = [x.values()[0] for x in joinset()]
231 joinset = [x.values()[0] for x in joinset()]
231
232
232 joiner = " "
233 joiner = " "
233 if len(args) > 1:
234 if len(args) > 1:
234 joiner = args[1][0](context, mapping, args[1][1])
235 joiner = args[1][0](context, mapping, args[1][1])
235
236
236 first = True
237 first = True
237 for x in joinset:
238 for x in joinset:
238 if first:
239 if first:
239 first = False
240 first = False
240 else:
241 else:
241 yield joiner
242 yield joiner
242 yield x
243 yield x
243
244
244 def sub(context, mapping, args):
245 def sub(context, mapping, args):
245 if len(args) != 3:
246 if len(args) != 3:
246 # i18n: "sub" is a keyword
247 # i18n: "sub" is a keyword
247 raise error.ParseError(_("sub expects three arguments"))
248 raise error.ParseError(_("sub expects three arguments"))
248
249
249 pat = stringify(args[0][0](context, mapping, args[0][1]))
250 pat = stringify(args[0][0](context, mapping, args[0][1]))
250 rpl = stringify(args[1][0](context, mapping, args[1][1]))
251 rpl = stringify(args[1][0](context, mapping, args[1][1]))
251 src = stringify(args[2][0](context, mapping, args[2][1]))
252 src = stringify(args[2][0](context, mapping, args[2][1]))
252 yield re.sub(pat, rpl, src)
253 yield re.sub(pat, rpl, src)
253
254
254 def if_(context, mapping, args):
255 def if_(context, mapping, args):
255 if not (2 <= len(args) <= 3):
256 if not (2 <= len(args) <= 3):
256 # i18n: "if" is a keyword
257 # i18n: "if" is a keyword
257 raise error.ParseError(_("if expects two or three arguments"))
258 raise error.ParseError(_("if expects two or three arguments"))
258
259
259 test = stringify(args[0][0](context, mapping, args[0][1]))
260 test = stringify(args[0][0](context, mapping, args[0][1]))
260 if test:
261 if test:
261 t = stringify(args[1][0](context, mapping, args[1][1]))
262 t = stringify(args[1][0](context, mapping, args[1][1]))
262 yield runtemplate(context, mapping, compiletemplate(t, context))
263 yield runtemplate(context, mapping, compiletemplate(t, context))
263 elif len(args) == 3:
264 elif len(args) == 3:
264 t = stringify(args[2][0](context, mapping, args[2][1]))
265 t = stringify(args[2][0](context, mapping, args[2][1]))
265 yield runtemplate(context, mapping, compiletemplate(t, context))
266 yield runtemplate(context, mapping, compiletemplate(t, context))
266
267
267 def ifeq(context, mapping, args):
268 def ifeq(context, mapping, args):
268 if not (3 <= len(args) <= 4):
269 if not (3 <= len(args) <= 4):
269 # i18n: "ifeq" is a keyword
270 # i18n: "ifeq" is a keyword
270 raise error.ParseError(_("ifeq expects three or four arguments"))
271 raise error.ParseError(_("ifeq expects three or four arguments"))
271
272
272 test = stringify(args[0][0](context, mapping, args[0][1]))
273 test = stringify(args[0][0](context, mapping, args[0][1]))
273 match = stringify(args[1][0](context, mapping, args[1][1]))
274 match = stringify(args[1][0](context, mapping, args[1][1]))
274 if test == match:
275 if test == match:
275 t = stringify(args[2][0](context, mapping, args[2][1]))
276 t = stringify(args[2][0](context, mapping, args[2][1]))
276 yield runtemplate(context, mapping, compiletemplate(t, context))
277 yield runtemplate(context, mapping, compiletemplate(t, context))
277 elif len(args) == 4:
278 elif len(args) == 4:
278 t = stringify(args[3][0](context, mapping, args[3][1]))
279 t = stringify(args[3][0](context, mapping, args[3][1]))
279 yield runtemplate(context, mapping, compiletemplate(t, context))
280 yield runtemplate(context, mapping, compiletemplate(t, context))
280
281
281 def label(context, mapping, args):
282 def label(context, mapping, args):
282 if len(args) != 2:
283 if len(args) != 2:
283 # i18n: "label" is a keyword
284 # i18n: "label" is a keyword
284 raise error.ParseError(_("label expects two arguments"))
285 raise error.ParseError(_("label expects two arguments"))
285
286
286 # ignore args[0] (the label string) since this is supposed to be a a no-op
287 # ignore args[0] (the label string) since this is supposed to be a a no-op
287 t = stringify(args[1][0](context, mapping, args[1][1]))
288 t = stringify(args[1][0](context, mapping, args[1][1]))
288 yield runtemplate(context, mapping, compiletemplate(t, context))
289 yield runtemplate(context, mapping, compiletemplate(t, context))
289
290
291 def rstdoc(context, mapping, args):
292 if len(args) != 2:
293 # i18n: "rstdoc" is a keyword
294 raise error.ParseError(_("rstdoc expects two arguments"))
295
296 text = stringify(args[0][0](context, mapping, args[0][1]))
297 style = stringify(args[1][0](context, mapping, args[1][1]))
298
299 return minirst.format(text, style=style)
300
290 methods = {
301 methods = {
291 "string": lambda e, c: (runstring, e[1]),
302 "string": lambda e, c: (runstring, e[1]),
292 "symbol": lambda e, c: (runsymbol, e[1]),
303 "symbol": lambda e, c: (runsymbol, e[1]),
293 "group": lambda e, c: compileexp(e[1], c),
304 "group": lambda e, c: compileexp(e[1], c),
294 # ".": buildmember,
305 # ".": buildmember,
295 "|": buildfilter,
306 "|": buildfilter,
296 "%": buildmap,
307 "%": buildmap,
297 "func": buildfunc,
308 "func": buildfunc,
298 }
309 }
299
310
300 funcs = {
311 funcs = {
301 "get": get,
312 "get": get,
302 "if": if_,
313 "if": if_,
303 "ifeq": ifeq,
314 "ifeq": ifeq,
304 "join": join,
315 "join": join,
305 "label": label,
316 "label": label,
317 "rstdoc": rstdoc,
306 "sub": sub,
318 "sub": sub,
307 }
319 }
308
320
309 # template engine
321 # template engine
310
322
311 path = ['templates', '../templates']
323 path = ['templates', '../templates']
312 stringify = templatefilters.stringify
324 stringify = templatefilters.stringify
313
325
314 def _flatten(thing):
326 def _flatten(thing):
315 '''yield a single stream from a possibly nested set of iterators'''
327 '''yield a single stream from a possibly nested set of iterators'''
316 if isinstance(thing, str):
328 if isinstance(thing, str):
317 yield thing
329 yield thing
318 elif not util.safehasattr(thing, '__iter__'):
330 elif not util.safehasattr(thing, '__iter__'):
319 if thing is not None:
331 if thing is not None:
320 yield str(thing)
332 yield str(thing)
321 else:
333 else:
322 for i in thing:
334 for i in thing:
323 if isinstance(i, str):
335 if isinstance(i, str):
324 yield i
336 yield i
325 elif not util.safehasattr(i, '__iter__'):
337 elif not util.safehasattr(i, '__iter__'):
326 if i is not None:
338 if i is not None:
327 yield str(i)
339 yield str(i)
328 elif i is not None:
340 elif i is not None:
329 for j in _flatten(i):
341 for j in _flatten(i):
330 yield j
342 yield j
331
343
332 def parsestring(s, quoted=True):
344 def parsestring(s, quoted=True):
333 '''parse a string using simple c-like syntax.
345 '''parse a string using simple c-like syntax.
334 string must be in quotes if quoted is True.'''
346 string must be in quotes if quoted is True.'''
335 if quoted:
347 if quoted:
336 if len(s) < 2 or s[0] != s[-1]:
348 if len(s) < 2 or s[0] != s[-1]:
337 raise SyntaxError(_('unmatched quotes'))
349 raise SyntaxError(_('unmatched quotes'))
338 return s[1:-1].decode('string_escape')
350 return s[1:-1].decode('string_escape')
339
351
340 return s.decode('string_escape')
352 return s.decode('string_escape')
341
353
342 class engine(object):
354 class engine(object):
343 '''template expansion engine.
355 '''template expansion engine.
344
356
345 template expansion works like this. a map file contains key=value
357 template expansion works like this. a map file contains key=value
346 pairs. if value is quoted, it is treated as string. otherwise, it
358 pairs. if value is quoted, it is treated as string. otherwise, it
347 is treated as name of template file.
359 is treated as name of template file.
348
360
349 templater is asked to expand a key in map. it looks up key, and
361 templater is asked to expand a key in map. it looks up key, and
350 looks for strings like this: {foo}. it expands {foo} by looking up
362 looks for strings like this: {foo}. it expands {foo} by looking up
351 foo in map, and substituting it. expansion is recursive: it stops
363 foo in map, and substituting it. expansion is recursive: it stops
352 when there is no more {foo} to replace.
364 when there is no more {foo} to replace.
353
365
354 expansion also allows formatting and filtering.
366 expansion also allows formatting and filtering.
355
367
356 format uses key to expand each item in list. syntax is
368 format uses key to expand each item in list. syntax is
357 {key%format}.
369 {key%format}.
358
370
359 filter uses function to transform value. syntax is
371 filter uses function to transform value. syntax is
360 {key|filter1|filter2|...}.'''
372 {key|filter1|filter2|...}.'''
361
373
362 def __init__(self, loader, filters={}, defaults={}):
374 def __init__(self, loader, filters={}, defaults={}):
363 self._loader = loader
375 self._loader = loader
364 self._filters = filters
376 self._filters = filters
365 self._defaults = defaults
377 self._defaults = defaults
366 self._cache = {}
378 self._cache = {}
367
379
368 def _load(self, t):
380 def _load(self, t):
369 '''load, parse, and cache a template'''
381 '''load, parse, and cache a template'''
370 if t not in self._cache:
382 if t not in self._cache:
371 self._cache[t] = compiletemplate(self._loader(t), self)
383 self._cache[t] = compiletemplate(self._loader(t), self)
372 return self._cache[t]
384 return self._cache[t]
373
385
374 def process(self, t, mapping):
386 def process(self, t, mapping):
375 '''Perform expansion. t is name of map element to expand.
387 '''Perform expansion. t is name of map element to expand.
376 mapping contains added elements for use during expansion. Is a
388 mapping contains added elements for use during expansion. Is a
377 generator.'''
389 generator.'''
378 return _flatten(runtemplate(self, mapping, self._load(t)))
390 return _flatten(runtemplate(self, mapping, self._load(t)))
379
391
380 engines = {'default': engine}
392 engines = {'default': engine}
381
393
382 class templater(object):
394 class templater(object):
383
395
384 def __init__(self, mapfile, filters={}, defaults={}, cache={},
396 def __init__(self, mapfile, filters={}, defaults={}, cache={},
385 minchunk=1024, maxchunk=65536):
397 minchunk=1024, maxchunk=65536):
386 '''set up template engine.
398 '''set up template engine.
387 mapfile is name of file to read map definitions from.
399 mapfile is name of file to read map definitions from.
388 filters is dict of functions. each transforms a value into another.
400 filters is dict of functions. each transforms a value into another.
389 defaults is dict of default map definitions.'''
401 defaults is dict of default map definitions.'''
390 self.mapfile = mapfile or 'template'
402 self.mapfile = mapfile or 'template'
391 self.cache = cache.copy()
403 self.cache = cache.copy()
392 self.map = {}
404 self.map = {}
393 self.base = (mapfile and os.path.dirname(mapfile)) or ''
405 self.base = (mapfile and os.path.dirname(mapfile)) or ''
394 self.filters = templatefilters.filters.copy()
406 self.filters = templatefilters.filters.copy()
395 self.filters.update(filters)
407 self.filters.update(filters)
396 self.defaults = defaults
408 self.defaults = defaults
397 self.minchunk, self.maxchunk = minchunk, maxchunk
409 self.minchunk, self.maxchunk = minchunk, maxchunk
398 self.ecache = {}
410 self.ecache = {}
399
411
400 if not mapfile:
412 if not mapfile:
401 return
413 return
402 if not os.path.exists(mapfile):
414 if not os.path.exists(mapfile):
403 raise util.Abort(_('style not found: %s') % mapfile)
415 raise util.Abort(_('style not found: %s') % mapfile)
404
416
405 conf = config.config()
417 conf = config.config()
406 conf.read(mapfile)
418 conf.read(mapfile)
407
419
408 for key, val in conf[''].items():
420 for key, val in conf[''].items():
409 if not val:
421 if not val:
410 raise SyntaxError(_('%s: missing value') % conf.source('', key))
422 raise SyntaxError(_('%s: missing value') % conf.source('', key))
411 if val[0] in "'\"":
423 if val[0] in "'\"":
412 try:
424 try:
413 self.cache[key] = parsestring(val)
425 self.cache[key] = parsestring(val)
414 except SyntaxError, inst:
426 except SyntaxError, inst:
415 raise SyntaxError('%s: %s' %
427 raise SyntaxError('%s: %s' %
416 (conf.source('', key), inst.args[0]))
428 (conf.source('', key), inst.args[0]))
417 else:
429 else:
418 val = 'default', val
430 val = 'default', val
419 if ':' in val[1]:
431 if ':' in val[1]:
420 val = val[1].split(':', 1)
432 val = val[1].split(':', 1)
421 self.map[key] = val[0], os.path.join(self.base, val[1])
433 self.map[key] = val[0], os.path.join(self.base, val[1])
422
434
423 def __contains__(self, key):
435 def __contains__(self, key):
424 return key in self.cache or key in self.map
436 return key in self.cache or key in self.map
425
437
426 def load(self, t):
438 def load(self, t):
427 '''Get the template for the given template name. Use a local cache.'''
439 '''Get the template for the given template name. Use a local cache.'''
428 if t not in self.cache:
440 if t not in self.cache:
429 try:
441 try:
430 self.cache[t] = util.readfile(self.map[t][1])
442 self.cache[t] = util.readfile(self.map[t][1])
431 except KeyError, inst:
443 except KeyError, inst:
432 raise util.Abort(_('"%s" not in template map') % inst.args[0])
444 raise util.Abort(_('"%s" not in template map') % inst.args[0])
433 except IOError, inst:
445 except IOError, inst:
434 raise IOError(inst.args[0], _('template file %s: %s') %
446 raise IOError(inst.args[0], _('template file %s: %s') %
435 (self.map[t][1], inst.args[1]))
447 (self.map[t][1], inst.args[1]))
436 return self.cache[t]
448 return self.cache[t]
437
449
438 def __call__(self, t, **mapping):
450 def __call__(self, t, **mapping):
439 ttype = t in self.map and self.map[t][0] or 'default'
451 ttype = t in self.map and self.map[t][0] or 'default'
440 if ttype not in self.ecache:
452 if ttype not in self.ecache:
441 self.ecache[ttype] = engines[ttype](self.load,
453 self.ecache[ttype] = engines[ttype](self.load,
442 self.filters, self.defaults)
454 self.filters, self.defaults)
443 proc = self.ecache[ttype]
455 proc = self.ecache[ttype]
444
456
445 stream = proc.process(t, mapping)
457 stream = proc.process(t, mapping)
446 if self.minchunk:
458 if self.minchunk:
447 stream = util.increasingchunks(stream, min=self.minchunk,
459 stream = util.increasingchunks(stream, min=self.minchunk,
448 max=self.maxchunk)
460 max=self.maxchunk)
449 return stream
461 return stream
450
462
451 def templatepath(name=None):
463 def templatepath(name=None):
452 '''return location of template file or directory (if no name).
464 '''return location of template file or directory (if no name).
453 returns None if not found.'''
465 returns None if not found.'''
454 normpaths = []
466 normpaths = []
455
467
456 # executable version (py2exe) doesn't support __file__
468 # executable version (py2exe) doesn't support __file__
457 if util.mainfrozen():
469 if util.mainfrozen():
458 module = sys.executable
470 module = sys.executable
459 else:
471 else:
460 module = __file__
472 module = __file__
461 for f in path:
473 for f in path:
462 if f.startswith('/'):
474 if f.startswith('/'):
463 p = f
475 p = f
464 else:
476 else:
465 fl = f.split('/')
477 fl = f.split('/')
466 p = os.path.join(os.path.dirname(module), *fl)
478 p = os.path.join(os.path.dirname(module), *fl)
467 if name:
479 if name:
468 p = os.path.join(p, name)
480 p = os.path.join(p, name)
469 if name and os.path.exists(p):
481 if name and os.path.exists(p):
470 return os.path.normpath(p)
482 return os.path.normpath(p)
471 elif os.path.isdir(p):
483 elif os.path.isdir(p):
472 normpaths.append(os.path.normpath(p))
484 normpaths.append(os.path.normpath(p))
473
485
474 return normpaths
486 return normpaths
475
487
476 def stylemap(styles, paths=None):
488 def stylemap(styles, paths=None):
477 """Return path to mapfile for a given style.
489 """Return path to mapfile for a given style.
478
490
479 Searches mapfile in the following locations:
491 Searches mapfile in the following locations:
480 1. templatepath/style/map
492 1. templatepath/style/map
481 2. templatepath/map-style
493 2. templatepath/map-style
482 3. templatepath/map
494 3. templatepath/map
483 """
495 """
484
496
485 if paths is None:
497 if paths is None:
486 paths = templatepath()
498 paths = templatepath()
487 elif isinstance(paths, str):
499 elif isinstance(paths, str):
488 paths = [paths]
500 paths = [paths]
489
501
490 if isinstance(styles, str):
502 if isinstance(styles, str):
491 styles = [styles]
503 styles = [styles]
492
504
493 for style in styles:
505 for style in styles:
494 if not style:
506 if not style:
495 continue
507 continue
496 locations = [os.path.join(style, 'map'), 'map-' + style]
508 locations = [os.path.join(style, 'map'), 'map-' + style]
497 locations.append('map')
509 locations.append('map')
498
510
499 for path in paths:
511 for path in paths:
500 for location in locations:
512 for location in locations:
501 mapfile = os.path.join(path, location)
513 mapfile = os.path.join(path, location)
502 if os.path.isfile(mapfile):
514 if os.path.isfile(mapfile):
503 return style, mapfile
515 return style, mapfile
504
516
505 raise RuntimeError("No hgweb templates found in %r" % paths)
517 raise RuntimeError("No hgweb templates found in %r" % paths)
@@ -1,34 +1,34 b''
1 {header}
1 {header}
2 <title>{repo|escape}: Branches</title>
2 <title>{repo|escape}: Branches</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url|urlescape}atom-tags" title="Atom feed for {repo|escape}"/>
4 href="{url|urlescape}atom-tags" title="Atom feed for {repo|escape}"/>
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url|urlescape}rss-tags" title="RSS feed for {repo|escape}"/>
6 href="{url|urlescape}rss-tags" title="RSS feed for {repo|escape}"/>
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="page_header">
10 <div class="page_header">
11 <a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a>
11 <a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a>
12 <a href="/">Mercurial</a> {pathdef%breadcrumb} / help
12 <a href="/">Mercurial</a> {pathdef%breadcrumb} / help
13 </div>
13 </div>
14
14
15 <div class="page_nav">
15 <div class="page_nav">
16 <a href="{url|urlescape}summary{sessionvars%urlparameter}">summary</a> |
16 <a href="{url|urlescape}summary{sessionvars%urlparameter}">summary</a> |
17 <a href="{url|urlescape}shortlog{sessionvars%urlparameter}">shortlog</a> |
17 <a href="{url|urlescape}shortlog{sessionvars%urlparameter}">shortlog</a> |
18 <a href="{url|urlescape}log{sessionvars%urlparameter}">changelog</a> |
18 <a href="{url|urlescape}log{sessionvars%urlparameter}">changelog</a> |
19 <a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a> |
19 <a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a> |
20 <a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a> |
20 <a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a> |
21 <a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a> |
21 <a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a> |
22 <a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a> |
22 <a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a> |
23 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a> |
23 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a> |
24 help
24 help
25 <br/>
25 <br/>
26 </div>
26 </div>
27
27
28 <div class="title">&nbsp;</div>
28 <div class="title">&nbsp;</div>
29
29
30 <pre>
30 <div id="doc">
31 {doc|escape}
31 {rstdoc(doc, "html")}
32 </pre>
32 </div>
33
33
34 {footer}
34 {footer}
@@ -1,38 +1,38 b''
1 {header}
1 {header}
2 <title>{repo|escape}: Branches</title>
2 <title>{repo|escape}: Branches</title>
3 <link rel="alternate" type="application/atom+xml" href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/>
3 <link rel="alternate" type="application/atom+xml" href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/>
4 <link rel="alternate" type="application/rss+xml" href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/>
4 <link rel="alternate" type="application/rss+xml" href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/>
5 </head>
5 </head>
6
6
7 <body>
7 <body>
8 <div id="container">
8 <div id="container">
9 <div class="page-header">
9 <div class="page-header">
10 <h1 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb} / help</h1>
10 <h1 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb} / help</h1>
11
11
12 <form action="{url|urlescape}log">
12 <form action="{url|urlescape}log">
13 {sessionvars%hiddenformentry}
13 {sessionvars%hiddenformentry}
14 <dl class="search">
14 <dl class="search">
15 <dt><label>Search: </label></dt>
15 <dt><label>Search: </label></dt>
16 <dd><input type="text" name="rev" /></dd>
16 <dd><input type="text" name="rev" /></dd>
17 </dl>
17 </dl>
18 </form>
18 </form>
19
19
20 <ul class="page-nav">
20 <ul class="page-nav">
21 <li><a href="{url|urlescape}summary{sessionvars%urlparameter}">summary</a></li>
21 <li><a href="{url|urlescape}summary{sessionvars%urlparameter}">summary</a></li>
22 <li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">shortlog</a></li>
22 <li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">shortlog</a></li>
23 <li><a href="{url|urlescape}changelog{sessionvars%urlparameter}">changelog</a></li>
23 <li><a href="{url|urlescape}changelog{sessionvars%urlparameter}">changelog</a></li>
24 <li><a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
24 <li><a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
25 <li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
25 <li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
26 <li><a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
26 <li><a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
27 <li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
27 <li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
28 <li><a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a></li>
28 <li><a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a></li>
29 <li class="current">help</li>
29 <li class="current">help</li>
30 </ul>
30 </ul>
31 </div>
31 </div>
32
32
33 <h2 class="no-link no-border">branches</h2>
33 <h2 class="no-link no-border">branches</h2>
34 <pre>
34 <div id="doc">
35 {doc|escape}
35 {rstdoc(doc, "html")}
36 </pre>
36 </div>
37
37
38 {footer}
38 {footer}
@@ -1,40 +1,40 b''
1 {header}
1 {header}
2 <title>Help: {topic}</title>
2 <title>Help: {topic}</title>
3 </head>
3 </head>
4 <body>
4 <body>
5
5
6 <div class="container">
6 <div class="container">
7 <div class="menu">
7 <div class="menu">
8 <div class="logo">
8 <div class="logo">
9 <a href="{logourl}">
9 <a href="{logourl}">
10 <img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
10 <img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
18 </ul>
18 </ul>
19 <ul>
19 <ul>
20 <li class="active"><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
20 <li class="active"><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
21 </ul>
21 </ul>
22 </div>
22 </div>
23
23
24 <div class="main">
24 <div class="main">
25 <h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
25 <h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
26 <h3>Help: {topic}</h3>
26 <h3>Help: {topic}</h3>
27
27
28 <form class="search" action="{url|urlescape}log">
28 <form class="search" action="{url|urlescape}log">
29 {sessionvars%hiddenformentry}
29 {sessionvars%hiddenformentry}
30 <p><input name="rev" id="search1" type="text" size="30" /></p>
30 <p><input name="rev" id="search1" type="text" size="30" /></p>
31 <div id="hint">find changesets by author, revision,
31 <div id="hint">find changesets by author, revision,
32 files, or words in the commit message</div>
32 files, or words in the commit message</div>
33 </form>
33 </form>
34 <pre>
34 <div id="doc">
35 {doc|escape}
35 {rstdoc(doc, "html")}
36 </pre>
36 </div>
37 </div>
37 </div>
38 </div>
38 </div>
39
39
40 {footer}
40 {footer}
@@ -1,1783 +1,1786 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge working directory with another revision
17 merge merge working directory with another revision
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 use "hg help" for the full list of commands or "hg -v" for details
26 use "hg help" for the full list of commands or "hg -v" for details
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge working directory with another revision
38 merge merge working directory with another revision
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 $ hg help
47 $ hg help
48 Mercurial Distributed SCM
48 Mercurial Distributed SCM
49
49
50 list of commands:
50 list of commands:
51
51
52 add add the specified files on the next commit
52 add add the specified files on the next commit
53 addremove add all new files, delete all missing files
53 addremove add all new files, delete all missing files
54 annotate show changeset information by line for each file
54 annotate show changeset information by line for each file
55 archive create an unversioned archive of a repository revision
55 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
56 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
57 bisect subdivision search of changesets
58 bookmarks track a line of development with movable markers
58 bookmarks track a line of development with movable markers
59 branch set or show the current branch name
59 branch set or show the current branch name
60 branches list repository named branches
60 branches list repository named branches
61 bundle create a changegroup file
61 bundle create a changegroup file
62 cat output the current or given revision of files
62 cat output the current or given revision of files
63 clone make a copy of an existing repository
63 clone make a copy of an existing repository
64 commit commit the specified files or all outstanding changes
64 commit commit the specified files or all outstanding changes
65 copy mark files as copied for the next commit
65 copy mark files as copied for the next commit
66 diff diff repository (or selected files)
66 diff diff repository (or selected files)
67 export dump the header and diffs for one or more changesets
67 export dump the header and diffs for one or more changesets
68 forget forget the specified files on the next commit
68 forget forget the specified files on the next commit
69 graft copy changes from other branches onto the current branch
69 graft copy changes from other branches onto the current branch
70 grep search for a pattern in specified files and revisions
70 grep search for a pattern in specified files and revisions
71 heads show current repository heads or show branch heads
71 heads show current repository heads or show branch heads
72 help show help for a given topic or a help overview
72 help show help for a given topic or a help overview
73 identify identify the working copy or specified revision
73 identify identify the working copy or specified revision
74 import import an ordered set of patches
74 import import an ordered set of patches
75 incoming show new changesets found in source
75 incoming show new changesets found in source
76 init create a new repository in the given directory
76 init create a new repository in the given directory
77 locate locate files matching specific patterns
77 locate locate files matching specific patterns
78 log show revision history of entire repository or files
78 log show revision history of entire repository or files
79 manifest output the current or given revision of the project manifest
79 manifest output the current or given revision of the project manifest
80 merge merge working directory with another revision
80 merge merge working directory with another revision
81 outgoing show changesets not found in the destination
81 outgoing show changesets not found in the destination
82 parents show the parents of the working directory or revision
82 parents show the parents of the working directory or revision
83 paths show aliases for remote repositories
83 paths show aliases for remote repositories
84 phase set or show the current phase name
84 phase set or show the current phase name
85 pull pull changes from the specified source
85 pull pull changes from the specified source
86 push push changes to the specified destination
86 push push changes to the specified destination
87 recover roll back an interrupted transaction
87 recover roll back an interrupted transaction
88 remove remove the specified files on the next commit
88 remove remove the specified files on the next commit
89 rename rename files; equivalent of copy + remove
89 rename rename files; equivalent of copy + remove
90 resolve redo merges or set/view the merge status of files
90 resolve redo merges or set/view the merge status of files
91 revert restore files to their checkout state
91 revert restore files to their checkout state
92 rollback roll back the last transaction (dangerous)
92 rollback roll back the last transaction (dangerous)
93 root print the root (top) of the current working directory
93 root print the root (top) of the current working directory
94 serve start stand-alone webserver
94 serve start stand-alone webserver
95 showconfig show combined config settings from all hgrc files
95 showconfig show combined config settings from all hgrc files
96 status show changed files in the working directory
96 status show changed files in the working directory
97 summary summarize working directory state
97 summary summarize working directory state
98 tag add one or more tags for the current or given revision
98 tag add one or more tags for the current or given revision
99 tags list repository tags
99 tags list repository tags
100 tip show the tip revision
100 tip show the tip revision
101 unbundle apply one or more changegroup files
101 unbundle apply one or more changegroup files
102 update update working directory (or switch revisions)
102 update update working directory (or switch revisions)
103 verify verify the integrity of the repository
103 verify verify the integrity of the repository
104 version output version and copyright information
104 version output version and copyright information
105
105
106 additional help topics:
106 additional help topics:
107
107
108 config Configuration Files
108 config Configuration Files
109 dates Date Formats
109 dates Date Formats
110 diffs Diff Formats
110 diffs Diff Formats
111 environment Environment Variables
111 environment Environment Variables
112 extensions Using Additional Features
112 extensions Using Additional Features
113 filesets Specifying File Sets
113 filesets Specifying File Sets
114 glossary Glossary
114 glossary Glossary
115 hgignore Syntax for Mercurial Ignore Files
115 hgignore Syntax for Mercurial Ignore Files
116 hgweb Configuring hgweb
116 hgweb Configuring hgweb
117 merge-tools Merge Tools
117 merge-tools Merge Tools
118 multirevs Specifying Multiple Revisions
118 multirevs Specifying Multiple Revisions
119 patterns File Name Patterns
119 patterns File Name Patterns
120 phases Working with Phases
120 phases Working with Phases
121 revisions Specifying Single Revisions
121 revisions Specifying Single Revisions
122 revsets Specifying Revision Sets
122 revsets Specifying Revision Sets
123 subrepos Subrepositories
123 subrepos Subrepositories
124 templating Template Usage
124 templating Template Usage
125 urls URL Paths
125 urls URL Paths
126
126
127 use "hg -v help" to show builtin aliases and global options
127 use "hg -v help" to show builtin aliases and global options
128
128
129 $ hg -q help
129 $ hg -q help
130 add add the specified files on the next commit
130 add add the specified files on the next commit
131 addremove add all new files, delete all missing files
131 addremove add all new files, delete all missing files
132 annotate show changeset information by line for each file
132 annotate show changeset information by line for each file
133 archive create an unversioned archive of a repository revision
133 archive create an unversioned archive of a repository revision
134 backout reverse effect of earlier changeset
134 backout reverse effect of earlier changeset
135 bisect subdivision search of changesets
135 bisect subdivision search of changesets
136 bookmarks track a line of development with movable markers
136 bookmarks track a line of development with movable markers
137 branch set or show the current branch name
137 branch set or show the current branch name
138 branches list repository named branches
138 branches list repository named branches
139 bundle create a changegroup file
139 bundle create a changegroup file
140 cat output the current or given revision of files
140 cat output the current or given revision of files
141 clone make a copy of an existing repository
141 clone make a copy of an existing repository
142 commit commit the specified files or all outstanding changes
142 commit commit the specified files or all outstanding changes
143 copy mark files as copied for the next commit
143 copy mark files as copied for the next commit
144 diff diff repository (or selected files)
144 diff diff repository (or selected files)
145 export dump the header and diffs for one or more changesets
145 export dump the header and diffs for one or more changesets
146 forget forget the specified files on the next commit
146 forget forget the specified files on the next commit
147 graft copy changes from other branches onto the current branch
147 graft copy changes from other branches onto the current branch
148 grep search for a pattern in specified files and revisions
148 grep search for a pattern in specified files and revisions
149 heads show current repository heads or show branch heads
149 heads show current repository heads or show branch heads
150 help show help for a given topic or a help overview
150 help show help for a given topic or a help overview
151 identify identify the working copy or specified revision
151 identify identify the working copy or specified revision
152 import import an ordered set of patches
152 import import an ordered set of patches
153 incoming show new changesets found in source
153 incoming show new changesets found in source
154 init create a new repository in the given directory
154 init create a new repository in the given directory
155 locate locate files matching specific patterns
155 locate locate files matching specific patterns
156 log show revision history of entire repository or files
156 log show revision history of entire repository or files
157 manifest output the current or given revision of the project manifest
157 manifest output the current or given revision of the project manifest
158 merge merge working directory with another revision
158 merge merge working directory with another revision
159 outgoing show changesets not found in the destination
159 outgoing show changesets not found in the destination
160 parents show the parents of the working directory or revision
160 parents show the parents of the working directory or revision
161 paths show aliases for remote repositories
161 paths show aliases for remote repositories
162 phase set or show the current phase name
162 phase set or show the current phase name
163 pull pull changes from the specified source
163 pull pull changes from the specified source
164 push push changes to the specified destination
164 push push changes to the specified destination
165 recover roll back an interrupted transaction
165 recover roll back an interrupted transaction
166 remove remove the specified files on the next commit
166 remove remove the specified files on the next commit
167 rename rename files; equivalent of copy + remove
167 rename rename files; equivalent of copy + remove
168 resolve redo merges or set/view the merge status of files
168 resolve redo merges or set/view the merge status of files
169 revert restore files to their checkout state
169 revert restore files to their checkout state
170 rollback roll back the last transaction (dangerous)
170 rollback roll back the last transaction (dangerous)
171 root print the root (top) of the current working directory
171 root print the root (top) of the current working directory
172 serve start stand-alone webserver
172 serve start stand-alone webserver
173 showconfig show combined config settings from all hgrc files
173 showconfig show combined config settings from all hgrc files
174 status show changed files in the working directory
174 status show changed files in the working directory
175 summary summarize working directory state
175 summary summarize working directory state
176 tag add one or more tags for the current or given revision
176 tag add one or more tags for the current or given revision
177 tags list repository tags
177 tags list repository tags
178 tip show the tip revision
178 tip show the tip revision
179 unbundle apply one or more changegroup files
179 unbundle apply one or more changegroup files
180 update update working directory (or switch revisions)
180 update update working directory (or switch revisions)
181 verify verify the integrity of the repository
181 verify verify the integrity of the repository
182 version output version and copyright information
182 version output version and copyright information
183
183
184 additional help topics:
184 additional help topics:
185
185
186 config Configuration Files
186 config Configuration Files
187 dates Date Formats
187 dates Date Formats
188 diffs Diff Formats
188 diffs Diff Formats
189 environment Environment Variables
189 environment Environment Variables
190 extensions Using Additional Features
190 extensions Using Additional Features
191 filesets Specifying File Sets
191 filesets Specifying File Sets
192 glossary Glossary
192 glossary Glossary
193 hgignore Syntax for Mercurial Ignore Files
193 hgignore Syntax for Mercurial Ignore Files
194 hgweb Configuring hgweb
194 hgweb Configuring hgweb
195 merge-tools Merge Tools
195 merge-tools Merge Tools
196 multirevs Specifying Multiple Revisions
196 multirevs Specifying Multiple Revisions
197 patterns File Name Patterns
197 patterns File Name Patterns
198 phases Working with Phases
198 phases Working with Phases
199 revisions Specifying Single Revisions
199 revisions Specifying Single Revisions
200 revsets Specifying Revision Sets
200 revsets Specifying Revision Sets
201 subrepos Subrepositories
201 subrepos Subrepositories
202 templating Template Usage
202 templating Template Usage
203 urls URL Paths
203 urls URL Paths
204
204
205 Test short command list with verbose option
205 Test short command list with verbose option
206
206
207 $ hg -v help shortlist
207 $ hg -v help shortlist
208 Mercurial Distributed SCM
208 Mercurial Distributed SCM
209
209
210 basic commands:
210 basic commands:
211
211
212 add add the specified files on the next commit
212 add add the specified files on the next commit
213 annotate, blame
213 annotate, blame
214 show changeset information by line for each file
214 show changeset information by line for each file
215 clone make a copy of an existing repository
215 clone make a copy of an existing repository
216 commit, ci commit the specified files or all outstanding changes
216 commit, ci commit the specified files or all outstanding changes
217 diff diff repository (or selected files)
217 diff diff repository (or selected files)
218 export dump the header and diffs for one or more changesets
218 export dump the header and diffs for one or more changesets
219 forget forget the specified files on the next commit
219 forget forget the specified files on the next commit
220 init create a new repository in the given directory
220 init create a new repository in the given directory
221 log, history show revision history of entire repository or files
221 log, history show revision history of entire repository or files
222 merge merge working directory with another revision
222 merge merge working directory with another revision
223 pull pull changes from the specified source
223 pull pull changes from the specified source
224 push push changes to the specified destination
224 push push changes to the specified destination
225 remove, rm remove the specified files on the next commit
225 remove, rm remove the specified files on the next commit
226 serve start stand-alone webserver
226 serve start stand-alone webserver
227 status, st show changed files in the working directory
227 status, st show changed files in the working directory
228 summary, sum summarize working directory state
228 summary, sum summarize working directory state
229 update, up, checkout, co
229 update, up, checkout, co
230 update working directory (or switch revisions)
230 update working directory (or switch revisions)
231
231
232 global options:
232 global options:
233
233
234 -R --repository REPO repository root directory or name of overlay bundle
234 -R --repository REPO repository root directory or name of overlay bundle
235 file
235 file
236 --cwd DIR change working directory
236 --cwd DIR change working directory
237 -y --noninteractive do not prompt, automatically pick the first choice for
237 -y --noninteractive do not prompt, automatically pick the first choice for
238 all prompts
238 all prompts
239 -q --quiet suppress output
239 -q --quiet suppress output
240 -v --verbose enable additional output
240 -v --verbose enable additional output
241 --config CONFIG [+] set/override config option (use 'section.name=value')
241 --config CONFIG [+] set/override config option (use 'section.name=value')
242 --debug enable debugging output
242 --debug enable debugging output
243 --debugger start debugger
243 --debugger start debugger
244 --encoding ENCODE set the charset encoding (default: ascii)
244 --encoding ENCODE set the charset encoding (default: ascii)
245 --encodingmode MODE set the charset encoding mode (default: strict)
245 --encodingmode MODE set the charset encoding mode (default: strict)
246 --traceback always print a traceback on exception
246 --traceback always print a traceback on exception
247 --time time how long the command takes
247 --time time how long the command takes
248 --profile print command execution profile
248 --profile print command execution profile
249 --version output version information and exit
249 --version output version information and exit
250 -h --help display help and exit
250 -h --help display help and exit
251 --hidden consider hidden changesets
251 --hidden consider hidden changesets
252
252
253 [+] marked option can be specified multiple times
253 [+] marked option can be specified multiple times
254
254
255 use "hg help" for the full list of commands
255 use "hg help" for the full list of commands
256
256
257 $ hg add -h
257 $ hg add -h
258 hg add [OPTION]... [FILE]...
258 hg add [OPTION]... [FILE]...
259
259
260 add the specified files on the next commit
260 add the specified files on the next commit
261
261
262 Schedule files to be version controlled and added to the repository.
262 Schedule files to be version controlled and added to the repository.
263
263
264 The files will be added to the repository at the next commit. To undo an
264 The files will be added to the repository at the next commit. To undo an
265 add before that, see "hg forget".
265 add before that, see "hg forget".
266
266
267 If no names are given, add all files to the repository.
267 If no names are given, add all files to the repository.
268
268
269 Returns 0 if all files are successfully added.
269 Returns 0 if all files are successfully added.
270
270
271 options:
271 options:
272
272
273 -I --include PATTERN [+] include names matching the given patterns
273 -I --include PATTERN [+] include names matching the given patterns
274 -X --exclude PATTERN [+] exclude names matching the given patterns
274 -X --exclude PATTERN [+] exclude names matching the given patterns
275 -S --subrepos recurse into subrepositories
275 -S --subrepos recurse into subrepositories
276 -n --dry-run do not perform actions, just print output
276 -n --dry-run do not perform actions, just print output
277
277
278 [+] marked option can be specified multiple times
278 [+] marked option can be specified multiple times
279
279
280 use "hg -v help add" to show more complete help and the global options
280 use "hg -v help add" to show more complete help and the global options
281
281
282 Verbose help for add
282 Verbose help for add
283
283
284 $ hg add -hv
284 $ hg add -hv
285 hg add [OPTION]... [FILE]...
285 hg add [OPTION]... [FILE]...
286
286
287 add the specified files on the next commit
287 add the specified files on the next commit
288
288
289 Schedule files to be version controlled and added to the repository.
289 Schedule files to be version controlled and added to the repository.
290
290
291 The files will be added to the repository at the next commit. To undo an
291 The files will be added to the repository at the next commit. To undo an
292 add before that, see "hg forget".
292 add before that, see "hg forget".
293
293
294 If no names are given, add all files to the repository.
294 If no names are given, add all files to the repository.
295
295
296 An example showing how new (unknown) files are added automatically by "hg
296 An example showing how new (unknown) files are added automatically by "hg
297 add":
297 add":
298
298
299 $ ls
299 $ ls
300 foo.c
300 foo.c
301 $ hg status
301 $ hg status
302 ? foo.c
302 ? foo.c
303 $ hg add
303 $ hg add
304 adding foo.c
304 adding foo.c
305 $ hg status
305 $ hg status
306 A foo.c
306 A foo.c
307
307
308 Returns 0 if all files are successfully added.
308 Returns 0 if all files are successfully added.
309
309
310 options:
310 options:
311
311
312 -I --include PATTERN [+] include names matching the given patterns
312 -I --include PATTERN [+] include names matching the given patterns
313 -X --exclude PATTERN [+] exclude names matching the given patterns
313 -X --exclude PATTERN [+] exclude names matching the given patterns
314 -S --subrepos recurse into subrepositories
314 -S --subrepos recurse into subrepositories
315 -n --dry-run do not perform actions, just print output
315 -n --dry-run do not perform actions, just print output
316
316
317 [+] marked option can be specified multiple times
317 [+] marked option can be specified multiple times
318
318
319 global options:
319 global options:
320
320
321 -R --repository REPO repository root directory or name of overlay bundle
321 -R --repository REPO repository root directory or name of overlay bundle
322 file
322 file
323 --cwd DIR change working directory
323 --cwd DIR change working directory
324 -y --noninteractive do not prompt, automatically pick the first choice for
324 -y --noninteractive do not prompt, automatically pick the first choice for
325 all prompts
325 all prompts
326 -q --quiet suppress output
326 -q --quiet suppress output
327 -v --verbose enable additional output
327 -v --verbose enable additional output
328 --config CONFIG [+] set/override config option (use 'section.name=value')
328 --config CONFIG [+] set/override config option (use 'section.name=value')
329 --debug enable debugging output
329 --debug enable debugging output
330 --debugger start debugger
330 --debugger start debugger
331 --encoding ENCODE set the charset encoding (default: ascii)
331 --encoding ENCODE set the charset encoding (default: ascii)
332 --encodingmode MODE set the charset encoding mode (default: strict)
332 --encodingmode MODE set the charset encoding mode (default: strict)
333 --traceback always print a traceback on exception
333 --traceback always print a traceback on exception
334 --time time how long the command takes
334 --time time how long the command takes
335 --profile print command execution profile
335 --profile print command execution profile
336 --version output version information and exit
336 --version output version information and exit
337 -h --help display help and exit
337 -h --help display help and exit
338 --hidden consider hidden changesets
338 --hidden consider hidden changesets
339
339
340 [+] marked option can be specified multiple times
340 [+] marked option can be specified multiple times
341
341
342 Test help option with version option
342 Test help option with version option
343
343
344 $ hg add -h --version
344 $ hg add -h --version
345 Mercurial Distributed SCM (version *) (glob)
345 Mercurial Distributed SCM (version *) (glob)
346 (see http://mercurial.selenic.com for more information)
346 (see http://mercurial.selenic.com for more information)
347
347
348 Copyright (C) 2005-2012 Matt Mackall and others
348 Copyright (C) 2005-2012 Matt Mackall and others
349 This is free software; see the source for copying conditions. There is NO
349 This is free software; see the source for copying conditions. There is NO
350 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
350 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
351
351
352 $ hg add --skjdfks
352 $ hg add --skjdfks
353 hg add: option --skjdfks not recognized
353 hg add: option --skjdfks not recognized
354 hg add [OPTION]... [FILE]...
354 hg add [OPTION]... [FILE]...
355
355
356 add the specified files on the next commit
356 add the specified files on the next commit
357
357
358 options:
358 options:
359
359
360 -I --include PATTERN [+] include names matching the given patterns
360 -I --include PATTERN [+] include names matching the given patterns
361 -X --exclude PATTERN [+] exclude names matching the given patterns
361 -X --exclude PATTERN [+] exclude names matching the given patterns
362 -S --subrepos recurse into subrepositories
362 -S --subrepos recurse into subrepositories
363 -n --dry-run do not perform actions, just print output
363 -n --dry-run do not perform actions, just print output
364
364
365 [+] marked option can be specified multiple times
365 [+] marked option can be specified multiple times
366
366
367 use "hg help add" to show the full help text
367 use "hg help add" to show the full help text
368 [255]
368 [255]
369
369
370 Test ambiguous command help
370 Test ambiguous command help
371
371
372 $ hg help ad
372 $ hg help ad
373 list of commands:
373 list of commands:
374
374
375 add add the specified files on the next commit
375 add add the specified files on the next commit
376 addremove add all new files, delete all missing files
376 addremove add all new files, delete all missing files
377
377
378 use "hg -v help ad" to show builtin aliases and global options
378 use "hg -v help ad" to show builtin aliases and global options
379
379
380 Test command without options
380 Test command without options
381
381
382 $ hg help verify
382 $ hg help verify
383 hg verify
383 hg verify
384
384
385 verify the integrity of the repository
385 verify the integrity of the repository
386
386
387 Verify the integrity of the current repository.
387 Verify the integrity of the current repository.
388
388
389 This will perform an extensive check of the repository's integrity,
389 This will perform an extensive check of the repository's integrity,
390 validating the hashes and checksums of each entry in the changelog,
390 validating the hashes and checksums of each entry in the changelog,
391 manifest, and tracked files, as well as the integrity of their crosslinks
391 manifest, and tracked files, as well as the integrity of their crosslinks
392 and indices.
392 and indices.
393
393
394 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption for more
394 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption for more
395 information about recovery from corruption of the repository.
395 information about recovery from corruption of the repository.
396
396
397 Returns 0 on success, 1 if errors are encountered.
397 Returns 0 on success, 1 if errors are encountered.
398
398
399 use "hg -v help verify" to show the global options
399 use "hg -v help verify" to show the global options
400
400
401 $ hg help diff
401 $ hg help diff
402 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
402 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
403
403
404 diff repository (or selected files)
404 diff repository (or selected files)
405
405
406 Show differences between revisions for the specified files.
406 Show differences between revisions for the specified files.
407
407
408 Differences between files are shown using the unified diff format.
408 Differences between files are shown using the unified diff format.
409
409
410 Note:
410 Note:
411 diff may generate unexpected results for merges, as it will default to
411 diff may generate unexpected results for merges, as it will default to
412 comparing against the working directory's first parent changeset if no
412 comparing against the working directory's first parent changeset if no
413 revisions are specified.
413 revisions are specified.
414
414
415 When two revision arguments are given, then changes are shown between
415 When two revision arguments are given, then changes are shown between
416 those revisions. If only one revision is specified then that revision is
416 those revisions. If only one revision is specified then that revision is
417 compared to the working directory, and, when no revisions are specified,
417 compared to the working directory, and, when no revisions are specified,
418 the working directory files are compared to its parent.
418 the working directory files are compared to its parent.
419
419
420 Alternatively you can specify -c/--change with a revision to see the
420 Alternatively you can specify -c/--change with a revision to see the
421 changes in that changeset relative to its first parent.
421 changes in that changeset relative to its first parent.
422
422
423 Without the -a/--text option, diff will avoid generating diffs of files it
423 Without the -a/--text option, diff will avoid generating diffs of files it
424 detects as binary. With -a, diff will generate a diff anyway, probably
424 detects as binary. With -a, diff will generate a diff anyway, probably
425 with undesirable results.
425 with undesirable results.
426
426
427 Use the -g/--git option to generate diffs in the git extended diff format.
427 Use the -g/--git option to generate diffs in the git extended diff format.
428 For more information, read "hg help diffs".
428 For more information, read "hg help diffs".
429
429
430 Returns 0 on success.
430 Returns 0 on success.
431
431
432 options:
432 options:
433
433
434 -r --rev REV [+] revision
434 -r --rev REV [+] revision
435 -c --change REV change made by revision
435 -c --change REV change made by revision
436 -a --text treat all files as text
436 -a --text treat all files as text
437 -g --git use git extended diff format
437 -g --git use git extended diff format
438 --nodates omit dates from diff headers
438 --nodates omit dates from diff headers
439 -p --show-function show which function each change is in
439 -p --show-function show which function each change is in
440 --reverse produce a diff that undoes the changes
440 --reverse produce a diff that undoes the changes
441 -w --ignore-all-space ignore white space when comparing lines
441 -w --ignore-all-space ignore white space when comparing lines
442 -b --ignore-space-change ignore changes in the amount of white space
442 -b --ignore-space-change ignore changes in the amount of white space
443 -B --ignore-blank-lines ignore changes whose lines are all blank
443 -B --ignore-blank-lines ignore changes whose lines are all blank
444 -U --unified NUM number of lines of context to show
444 -U --unified NUM number of lines of context to show
445 --stat output diffstat-style summary of changes
445 --stat output diffstat-style summary of changes
446 -I --include PATTERN [+] include names matching the given patterns
446 -I --include PATTERN [+] include names matching the given patterns
447 -X --exclude PATTERN [+] exclude names matching the given patterns
447 -X --exclude PATTERN [+] exclude names matching the given patterns
448 -S --subrepos recurse into subrepositories
448 -S --subrepos recurse into subrepositories
449
449
450 [+] marked option can be specified multiple times
450 [+] marked option can be specified multiple times
451
451
452 use "hg -v help diff" to show more complete help and the global options
452 use "hg -v help diff" to show more complete help and the global options
453
453
454 $ hg help status
454 $ hg help status
455 hg status [OPTION]... [FILE]...
455 hg status [OPTION]... [FILE]...
456
456
457 aliases: st
457 aliases: st
458
458
459 show changed files in the working directory
459 show changed files in the working directory
460
460
461 Show status of files in the repository. If names are given, only files
461 Show status of files in the repository. If names are given, only files
462 that match are shown. Files that are clean or ignored or the source of a
462 that match are shown. Files that are clean or ignored or the source of a
463 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
463 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
464 -C/--copies or -A/--all are given. Unless options described with "show
464 -C/--copies or -A/--all are given. Unless options described with "show
465 only ..." are given, the options -mardu are used.
465 only ..." are given, the options -mardu are used.
466
466
467 Option -q/--quiet hides untracked (unknown and ignored) files unless
467 Option -q/--quiet hides untracked (unknown and ignored) files unless
468 explicitly requested with -u/--unknown or -i/--ignored.
468 explicitly requested with -u/--unknown or -i/--ignored.
469
469
470 Note:
470 Note:
471 status may appear to disagree with diff if permissions have changed or
471 status may appear to disagree with diff if permissions have changed or
472 a merge has occurred. The standard diff format does not report
472 a merge has occurred. The standard diff format does not report
473 permission changes and diff only reports changes relative to one merge
473 permission changes and diff only reports changes relative to one merge
474 parent.
474 parent.
475
475
476 If one revision is given, it is used as the base revision. If two
476 If one revision is given, it is used as the base revision. If two
477 revisions are given, the differences between them are shown. The --change
477 revisions are given, the differences between them are shown. The --change
478 option can also be used as a shortcut to list the changed files of a
478 option can also be used as a shortcut to list the changed files of a
479 revision from its first parent.
479 revision from its first parent.
480
480
481 The codes used to show the status of files are:
481 The codes used to show the status of files are:
482
482
483 M = modified
483 M = modified
484 A = added
484 A = added
485 R = removed
485 R = removed
486 C = clean
486 C = clean
487 ! = missing (deleted by non-hg command, but still tracked)
487 ! = missing (deleted by non-hg command, but still tracked)
488 ? = not tracked
488 ? = not tracked
489 I = ignored
489 I = ignored
490 = origin of the previous file listed as A (added)
490 = origin of the previous file listed as A (added)
491
491
492 Returns 0 on success.
492 Returns 0 on success.
493
493
494 options:
494 options:
495
495
496 -A --all show status of all files
496 -A --all show status of all files
497 -m --modified show only modified files
497 -m --modified show only modified files
498 -a --added show only added files
498 -a --added show only added files
499 -r --removed show only removed files
499 -r --removed show only removed files
500 -d --deleted show only deleted (but tracked) files
500 -d --deleted show only deleted (but tracked) files
501 -c --clean show only files without changes
501 -c --clean show only files without changes
502 -u --unknown show only unknown (not tracked) files
502 -u --unknown show only unknown (not tracked) files
503 -i --ignored show only ignored files
503 -i --ignored show only ignored files
504 -n --no-status hide status prefix
504 -n --no-status hide status prefix
505 -C --copies show source of copied files
505 -C --copies show source of copied files
506 -0 --print0 end filenames with NUL, for use with xargs
506 -0 --print0 end filenames with NUL, for use with xargs
507 --rev REV [+] show difference from revision
507 --rev REV [+] show difference from revision
508 --change REV list the changed files of a revision
508 --change REV list the changed files of a revision
509 -I --include PATTERN [+] include names matching the given patterns
509 -I --include PATTERN [+] include names matching the given patterns
510 -X --exclude PATTERN [+] exclude names matching the given patterns
510 -X --exclude PATTERN [+] exclude names matching the given patterns
511 -S --subrepos recurse into subrepositories
511 -S --subrepos recurse into subrepositories
512
512
513 [+] marked option can be specified multiple times
513 [+] marked option can be specified multiple times
514
514
515 use "hg -v help status" to show more complete help and the global options
515 use "hg -v help status" to show more complete help and the global options
516
516
517 $ hg -q help status
517 $ hg -q help status
518 hg status [OPTION]... [FILE]...
518 hg status [OPTION]... [FILE]...
519
519
520 show changed files in the working directory
520 show changed files in the working directory
521
521
522 $ hg help foo
522 $ hg help foo
523 hg: unknown command 'foo'
523 hg: unknown command 'foo'
524 Mercurial Distributed SCM
524 Mercurial Distributed SCM
525
525
526 basic commands:
526 basic commands:
527
527
528 add add the specified files on the next commit
528 add add the specified files on the next commit
529 annotate show changeset information by line for each file
529 annotate show changeset information by line for each file
530 clone make a copy of an existing repository
530 clone make a copy of an existing repository
531 commit commit the specified files or all outstanding changes
531 commit commit the specified files or all outstanding changes
532 diff diff repository (or selected files)
532 diff diff repository (or selected files)
533 export dump the header and diffs for one or more changesets
533 export dump the header and diffs for one or more changesets
534 forget forget the specified files on the next commit
534 forget forget the specified files on the next commit
535 init create a new repository in the given directory
535 init create a new repository in the given directory
536 log show revision history of entire repository or files
536 log show revision history of entire repository or files
537 merge merge working directory with another revision
537 merge merge working directory with another revision
538 pull pull changes from the specified source
538 pull pull changes from the specified source
539 push push changes to the specified destination
539 push push changes to the specified destination
540 remove remove the specified files on the next commit
540 remove remove the specified files on the next commit
541 serve start stand-alone webserver
541 serve start stand-alone webserver
542 status show changed files in the working directory
542 status show changed files in the working directory
543 summary summarize working directory state
543 summary summarize working directory state
544 update update working directory (or switch revisions)
544 update update working directory (or switch revisions)
545
545
546 use "hg help" for the full list of commands or "hg -v" for details
546 use "hg help" for the full list of commands or "hg -v" for details
547 [255]
547 [255]
548
548
549 $ hg skjdfks
549 $ hg skjdfks
550 hg: unknown command 'skjdfks'
550 hg: unknown command 'skjdfks'
551 Mercurial Distributed SCM
551 Mercurial Distributed SCM
552
552
553 basic commands:
553 basic commands:
554
554
555 add add the specified files on the next commit
555 add add the specified files on the next commit
556 annotate show changeset information by line for each file
556 annotate show changeset information by line for each file
557 clone make a copy of an existing repository
557 clone make a copy of an existing repository
558 commit commit the specified files or all outstanding changes
558 commit commit the specified files or all outstanding changes
559 diff diff repository (or selected files)
559 diff diff repository (or selected files)
560 export dump the header and diffs for one or more changesets
560 export dump the header and diffs for one or more changesets
561 forget forget the specified files on the next commit
561 forget forget the specified files on the next commit
562 init create a new repository in the given directory
562 init create a new repository in the given directory
563 log show revision history of entire repository or files
563 log show revision history of entire repository or files
564 merge merge working directory with another revision
564 merge merge working directory with another revision
565 pull pull changes from the specified source
565 pull pull changes from the specified source
566 push push changes to the specified destination
566 push push changes to the specified destination
567 remove remove the specified files on the next commit
567 remove remove the specified files on the next commit
568 serve start stand-alone webserver
568 serve start stand-alone webserver
569 status show changed files in the working directory
569 status show changed files in the working directory
570 summary summarize working directory state
570 summary summarize working directory state
571 update update working directory (or switch revisions)
571 update update working directory (or switch revisions)
572
572
573 use "hg help" for the full list of commands or "hg -v" for details
573 use "hg help" for the full list of commands or "hg -v" for details
574 [255]
574 [255]
575
575
576 $ cat > helpext.py <<EOF
576 $ cat > helpext.py <<EOF
577 > import os
577 > import os
578 > from mercurial import commands
578 > from mercurial import commands
579 >
579 >
580 > def nohelp(ui, *args, **kwargs):
580 > def nohelp(ui, *args, **kwargs):
581 > pass
581 > pass
582 >
582 >
583 > cmdtable = {
583 > cmdtable = {
584 > "nohelp": (nohelp, [], "hg nohelp"),
584 > "nohelp": (nohelp, [], "hg nohelp"),
585 > }
585 > }
586 >
586 >
587 > commands.norepo += ' nohelp'
587 > commands.norepo += ' nohelp'
588 > EOF
588 > EOF
589 $ echo '[extensions]' >> $HGRCPATH
589 $ echo '[extensions]' >> $HGRCPATH
590 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
590 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
591
591
592 Test command with no help text
592 Test command with no help text
593
593
594 $ hg help nohelp
594 $ hg help nohelp
595 hg nohelp
595 hg nohelp
596
596
597 (no help text available)
597 (no help text available)
598
598
599 use "hg -v help nohelp" to show the global options
599 use "hg -v help nohelp" to show the global options
600
600
601 $ hg help -k nohelp
601 $ hg help -k nohelp
602 Commands:
602 Commands:
603
603
604 nohelp hg nohelp
604 nohelp hg nohelp
605
605
606 Extension Commands:
606 Extension Commands:
607
607
608 nohelp (no help text available)
608 nohelp (no help text available)
609
609
610 Test that default list of commands omits extension commands
610 Test that default list of commands omits extension commands
611
611
612 $ hg help
612 $ hg help
613 Mercurial Distributed SCM
613 Mercurial Distributed SCM
614
614
615 list of commands:
615 list of commands:
616
616
617 add add the specified files on the next commit
617 add add the specified files on the next commit
618 addremove add all new files, delete all missing files
618 addremove add all new files, delete all missing files
619 annotate show changeset information by line for each file
619 annotate show changeset information by line for each file
620 archive create an unversioned archive of a repository revision
620 archive create an unversioned archive of a repository revision
621 backout reverse effect of earlier changeset
621 backout reverse effect of earlier changeset
622 bisect subdivision search of changesets
622 bisect subdivision search of changesets
623 bookmarks track a line of development with movable markers
623 bookmarks track a line of development with movable markers
624 branch set or show the current branch name
624 branch set or show the current branch name
625 branches list repository named branches
625 branches list repository named branches
626 bundle create a changegroup file
626 bundle create a changegroup file
627 cat output the current or given revision of files
627 cat output the current or given revision of files
628 clone make a copy of an existing repository
628 clone make a copy of an existing repository
629 commit commit the specified files or all outstanding changes
629 commit commit the specified files or all outstanding changes
630 copy mark files as copied for the next commit
630 copy mark files as copied for the next commit
631 diff diff repository (or selected files)
631 diff diff repository (or selected files)
632 export dump the header and diffs for one or more changesets
632 export dump the header and diffs for one or more changesets
633 forget forget the specified files on the next commit
633 forget forget the specified files on the next commit
634 graft copy changes from other branches onto the current branch
634 graft copy changes from other branches onto the current branch
635 grep search for a pattern in specified files and revisions
635 grep search for a pattern in specified files and revisions
636 heads show current repository heads or show branch heads
636 heads show current repository heads or show branch heads
637 help show help for a given topic or a help overview
637 help show help for a given topic or a help overview
638 identify identify the working copy or specified revision
638 identify identify the working copy or specified revision
639 import import an ordered set of patches
639 import import an ordered set of patches
640 incoming show new changesets found in source
640 incoming show new changesets found in source
641 init create a new repository in the given directory
641 init create a new repository in the given directory
642 locate locate files matching specific patterns
642 locate locate files matching specific patterns
643 log show revision history of entire repository or files
643 log show revision history of entire repository or files
644 manifest output the current or given revision of the project manifest
644 manifest output the current or given revision of the project manifest
645 merge merge working directory with another revision
645 merge merge working directory with another revision
646 outgoing show changesets not found in the destination
646 outgoing show changesets not found in the destination
647 parents show the parents of the working directory or revision
647 parents show the parents of the working directory or revision
648 paths show aliases for remote repositories
648 paths show aliases for remote repositories
649 phase set or show the current phase name
649 phase set or show the current phase name
650 pull pull changes from the specified source
650 pull pull changes from the specified source
651 push push changes to the specified destination
651 push push changes to the specified destination
652 recover roll back an interrupted transaction
652 recover roll back an interrupted transaction
653 remove remove the specified files on the next commit
653 remove remove the specified files on the next commit
654 rename rename files; equivalent of copy + remove
654 rename rename files; equivalent of copy + remove
655 resolve redo merges or set/view the merge status of files
655 resolve redo merges or set/view the merge status of files
656 revert restore files to their checkout state
656 revert restore files to their checkout state
657 rollback roll back the last transaction (dangerous)
657 rollback roll back the last transaction (dangerous)
658 root print the root (top) of the current working directory
658 root print the root (top) of the current working directory
659 serve start stand-alone webserver
659 serve start stand-alone webserver
660 showconfig show combined config settings from all hgrc files
660 showconfig show combined config settings from all hgrc files
661 status show changed files in the working directory
661 status show changed files in the working directory
662 summary summarize working directory state
662 summary summarize working directory state
663 tag add one or more tags for the current or given revision
663 tag add one or more tags for the current or given revision
664 tags list repository tags
664 tags list repository tags
665 tip show the tip revision
665 tip show the tip revision
666 unbundle apply one or more changegroup files
666 unbundle apply one or more changegroup files
667 update update working directory (or switch revisions)
667 update update working directory (or switch revisions)
668 verify verify the integrity of the repository
668 verify verify the integrity of the repository
669 version output version and copyright information
669 version output version and copyright information
670
670
671 enabled extensions:
671 enabled extensions:
672
672
673 helpext (no help text available)
673 helpext (no help text available)
674
674
675 additional help topics:
675 additional help topics:
676
676
677 config Configuration Files
677 config Configuration Files
678 dates Date Formats
678 dates Date Formats
679 diffs Diff Formats
679 diffs Diff Formats
680 environment Environment Variables
680 environment Environment Variables
681 extensions Using Additional Features
681 extensions Using Additional Features
682 filesets Specifying File Sets
682 filesets Specifying File Sets
683 glossary Glossary
683 glossary Glossary
684 hgignore Syntax for Mercurial Ignore Files
684 hgignore Syntax for Mercurial Ignore Files
685 hgweb Configuring hgweb
685 hgweb Configuring hgweb
686 merge-tools Merge Tools
686 merge-tools Merge Tools
687 multirevs Specifying Multiple Revisions
687 multirevs Specifying Multiple Revisions
688 patterns File Name Patterns
688 patterns File Name Patterns
689 phases Working with Phases
689 phases Working with Phases
690 revisions Specifying Single Revisions
690 revisions Specifying Single Revisions
691 revsets Specifying Revision Sets
691 revsets Specifying Revision Sets
692 subrepos Subrepositories
692 subrepos Subrepositories
693 templating Template Usage
693 templating Template Usage
694 urls URL Paths
694 urls URL Paths
695
695
696 use "hg -v help" to show builtin aliases and global options
696 use "hg -v help" to show builtin aliases and global options
697
697
698
698
699
699
700 Test list of commands with command with no help text
700 Test list of commands with command with no help text
701
701
702 $ hg help helpext
702 $ hg help helpext
703 helpext extension - no help text available
703 helpext extension - no help text available
704
704
705 list of commands:
705 list of commands:
706
706
707 nohelp (no help text available)
707 nohelp (no help text available)
708
708
709 use "hg -v help helpext" to show builtin aliases and global options
709 use "hg -v help helpext" to show builtin aliases and global options
710
710
711 Test a help topic
711 Test a help topic
712
712
713 $ hg help revs
713 $ hg help revs
714 Specifying Single Revisions
714 Specifying Single Revisions
715
715
716 Mercurial supports several ways to specify individual revisions.
716 Mercurial supports several ways to specify individual revisions.
717
717
718 A plain integer is treated as a revision number. Negative integers are
718 A plain integer is treated as a revision number. Negative integers are
719 treated as sequential offsets from the tip, with -1 denoting the tip, -2
719 treated as sequential offsets from the tip, with -1 denoting the tip, -2
720 denoting the revision prior to the tip, and so forth.
720 denoting the revision prior to the tip, and so forth.
721
721
722 A 40-digit hexadecimal string is treated as a unique revision identifier.
722 A 40-digit hexadecimal string is treated as a unique revision identifier.
723
723
724 A hexadecimal string less than 40 characters long is treated as a unique
724 A hexadecimal string less than 40 characters long is treated as a unique
725 revision identifier and is referred to as a short-form identifier. A
725 revision identifier and is referred to as a short-form identifier. A
726 short-form identifier is only valid if it is the prefix of exactly one
726 short-form identifier is only valid if it is the prefix of exactly one
727 full-length identifier.
727 full-length identifier.
728
728
729 Any other string is treated as a bookmark, tag, or branch name. A bookmark
729 Any other string is treated as a bookmark, tag, or branch name. A bookmark
730 is a movable pointer to a revision. A tag is a permanent name associated
730 is a movable pointer to a revision. A tag is a permanent name associated
731 with a revision. A branch name denotes the tipmost revision of that
731 with a revision. A branch name denotes the tipmost revision of that
732 branch. Bookmark, tag, and branch names must not contain the ":"
732 branch. Bookmark, tag, and branch names must not contain the ":"
733 character.
733 character.
734
734
735 The reserved name "tip" always identifies the most recent revision.
735 The reserved name "tip" always identifies the most recent revision.
736
736
737 The reserved name "null" indicates the null revision. This is the revision
737 The reserved name "null" indicates the null revision. This is the revision
738 of an empty repository, and the parent of revision 0.
738 of an empty repository, and the parent of revision 0.
739
739
740 The reserved name "." indicates the working directory parent. If no
740 The reserved name "." indicates the working directory parent. If no
741 working directory is checked out, it is equivalent to null. If an
741 working directory is checked out, it is equivalent to null. If an
742 uncommitted merge is in progress, "." is the revision of the first parent.
742 uncommitted merge is in progress, "." is the revision of the first parent.
743
743
744 Test templating help
744 Test templating help
745
745
746 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
746 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
747 desc String. The text of the changeset description.
747 desc String. The text of the changeset description.
748 diffstat String. Statistics of changes with the following format:
748 diffstat String. Statistics of changes with the following format:
749 firstline Any text. Returns the first line of text.
749 firstline Any text. Returns the first line of text.
750 nonempty Any text. Returns '(none)' if the string is empty.
750 nonempty Any text. Returns '(none)' if the string is empty.
751
751
752 Test help hooks
752 Test help hooks
753
753
754 $ cat > helphook1.py <<EOF
754 $ cat > helphook1.py <<EOF
755 > from mercurial import help
755 > from mercurial import help
756 >
756 >
757 > def rewrite(topic, doc):
757 > def rewrite(topic, doc):
758 > return doc + '\nhelphook1\n'
758 > return doc + '\nhelphook1\n'
759 >
759 >
760 > def extsetup(ui):
760 > def extsetup(ui):
761 > help.addtopichook('revsets', rewrite)
761 > help.addtopichook('revsets', rewrite)
762 > EOF
762 > EOF
763 $ cat > helphook2.py <<EOF
763 $ cat > helphook2.py <<EOF
764 > from mercurial import help
764 > from mercurial import help
765 >
765 >
766 > def rewrite(topic, doc):
766 > def rewrite(topic, doc):
767 > return doc + '\nhelphook2\n'
767 > return doc + '\nhelphook2\n'
768 >
768 >
769 > def extsetup(ui):
769 > def extsetup(ui):
770 > help.addtopichook('revsets', rewrite)
770 > help.addtopichook('revsets', rewrite)
771 > EOF
771 > EOF
772 $ echo '[extensions]' >> $HGRCPATH
772 $ echo '[extensions]' >> $HGRCPATH
773 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
773 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
774 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
774 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
775 $ hg help revsets | grep helphook
775 $ hg help revsets | grep helphook
776 helphook1
776 helphook1
777 helphook2
777 helphook2
778
778
779 Test keyword search help
779 Test keyword search help
780
780
781 $ hg help -k clone
781 $ hg help -k clone
782 Topics:
782 Topics:
783
783
784 config Configuration Files
784 config Configuration Files
785 extensions Using Additional Features
785 extensions Using Additional Features
786 glossary Glossary
786 glossary Glossary
787 phases Working with Phases
787 phases Working with Phases
788 subrepos Subrepositories
788 subrepos Subrepositories
789 urls URL Paths
789 urls URL Paths
790
790
791 Commands:
791 Commands:
792
792
793 bookmarks track a line of development with movable markers
793 bookmarks track a line of development with movable markers
794 clone make a copy of an existing repository
794 clone make a copy of an existing repository
795 paths show aliases for remote repositories
795 paths show aliases for remote repositories
796 update update working directory (or switch revisions)
796 update update working directory (or switch revisions)
797
797
798 Extensions:
798 Extensions:
799
799
800 relink recreates hardlinks between repository clones
800 relink recreates hardlinks between repository clones
801
801
802 Extension Commands:
802 Extension Commands:
803
803
804 qclone clone main and patch repository at same time
804 qclone clone main and patch repository at same time
805
805
806 Test omit indicating for help
806 Test omit indicating for help
807
807
808 $ cat > addverboseitems.py <<EOF
808 $ cat > addverboseitems.py <<EOF
809 > '''extension to test omit indicating.
809 > '''extension to test omit indicating.
810 >
810 >
811 > This paragraph is never omitted (for extension)
811 > This paragraph is never omitted (for extension)
812 >
812 >
813 > .. container:: verbose
813 > .. container:: verbose
814 >
814 >
815 > This paragraph is omitted,
815 > This paragraph is omitted,
816 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for extension)
816 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for extension)
817 >
817 >
818 > This paragraph is never omitted, too (for extension)
818 > This paragraph is never omitted, too (for extension)
819 > '''
819 > '''
820 >
820 >
821 > from mercurial import help, commands
821 > from mercurial import help, commands
822 > testtopic = """This paragraph is never omitted (for topic).
822 > testtopic = """This paragraph is never omitted (for topic).
823 >
823 >
824 > .. container:: verbose
824 > .. container:: verbose
825 >
825 >
826 > This paragraph is omitted,
826 > This paragraph is omitted,
827 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for topic)
827 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for topic)
828 >
828 >
829 > This paragraph is never omitted, too (for topic)
829 > This paragraph is never omitted, too (for topic)
830 > """
830 > """
831 > def extsetup(ui):
831 > def extsetup(ui):
832 > help.helptable.append((["topic-containing-verbose"],
832 > help.helptable.append((["topic-containing-verbose"],
833 > "This is the topic to test omit indicating.",
833 > "This is the topic to test omit indicating.",
834 > lambda : testtopic))
834 > lambda : testtopic))
835 > EOF
835 > EOF
836 $ echo '[extensions]' >> $HGRCPATH
836 $ echo '[extensions]' >> $HGRCPATH
837 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
837 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
838 $ hg help addverboseitems
838 $ hg help addverboseitems
839 addverboseitems extension - extension to test omit indicating.
839 addverboseitems extension - extension to test omit indicating.
840
840
841 This paragraph is never omitted (for extension)
841 This paragraph is never omitted (for extension)
842
842
843 This paragraph is never omitted, too (for extension)
843 This paragraph is never omitted, too (for extension)
844
844
845 use "hg help -v addverboseitems" to show more complete help
845 use "hg help -v addverboseitems" to show more complete help
846
846
847 no commands defined
847 no commands defined
848 $ hg help -v addverboseitems
848 $ hg help -v addverboseitems
849 addverboseitems extension - extension to test omit indicating.
849 addverboseitems extension - extension to test omit indicating.
850
850
851 This paragraph is never omitted (for extension)
851 This paragraph is never omitted (for extension)
852
852
853 This paragraph is omitted, if "hg help" is invoked witout "-v" (for extension)
853 This paragraph is omitted, if "hg help" is invoked witout "-v" (for extension)
854
854
855 This paragraph is never omitted, too (for extension)
855 This paragraph is never omitted, too (for extension)
856
856
857 no commands defined
857 no commands defined
858 $ hg help topic-containing-verbose
858 $ hg help topic-containing-verbose
859 This is the topic to test omit indicating.
859 This is the topic to test omit indicating.
860
860
861 This paragraph is never omitted (for topic).
861 This paragraph is never omitted (for topic).
862
862
863 This paragraph is never omitted, too (for topic)
863 This paragraph is never omitted, too (for topic)
864
864
865 use "hg help -v topic-containing-verbose" to show more complete help
865 use "hg help -v topic-containing-verbose" to show more complete help
866 $ hg help -v topic-containing-verbose
866 $ hg help -v topic-containing-verbose
867 This is the topic to test omit indicating.
867 This is the topic to test omit indicating.
868
868
869 This paragraph is never omitted (for topic).
869 This paragraph is never omitted (for topic).
870
870
871 This paragraph is omitted, if "hg help" is invoked witout "-v" (for topic)
871 This paragraph is omitted, if "hg help" is invoked witout "-v" (for topic)
872
872
873 This paragraph is never omitted, too (for topic)
873 This paragraph is never omitted, too (for topic)
874
874
875 Test usage of section marks in help documents
875 Test usage of section marks in help documents
876
876
877 $ cd "$TESTDIR"/../doc
877 $ cd "$TESTDIR"/../doc
878 $ python check-seclevel.py
878 $ python check-seclevel.py
879 $ cd $TESTTMP
879 $ cd $TESTTMP
880
880
881 #if serve
881 #if serve
882
882
883 Test the help pages in hgweb.
883 Test the help pages in hgweb.
884
884
885 Dish up an empty repo; serve it cold.
885 Dish up an empty repo; serve it cold.
886
886
887 $ hg init "$TESTTMP/test"
887 $ hg init "$TESTTMP/test"
888 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
888 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
889 $ cat hg.pid >> $DAEMON_PIDS
889 $ cat hg.pid >> $DAEMON_PIDS
890
890
891 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help"
891 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help"
892 200 Script output follows
892 200 Script output follows
893
893
894 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
894 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
895 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
895 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
896 <head>
896 <head>
897 <link rel="icon" href="/static/hgicon.png" type="image/png" />
897 <link rel="icon" href="/static/hgicon.png" type="image/png" />
898 <meta name="robots" content="index, nofollow" />
898 <meta name="robots" content="index, nofollow" />
899 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
899 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
900 <script type="text/javascript" src="/static/mercurial.js"></script>
900 <script type="text/javascript" src="/static/mercurial.js"></script>
901
901
902 <title>Help: Index</title>
902 <title>Help: Index</title>
903 </head>
903 </head>
904 <body>
904 <body>
905
905
906 <div class="container">
906 <div class="container">
907 <div class="menu">
907 <div class="menu">
908 <div class="logo">
908 <div class="logo">
909 <a href="http://mercurial.selenic.com/">
909 <a href="http://mercurial.selenic.com/">
910 <img src="/static/hglogo.png" alt="mercurial" /></a>
910 <img src="/static/hglogo.png" alt="mercurial" /></a>
911 </div>
911 </div>
912 <ul>
912 <ul>
913 <li><a href="/shortlog">log</a></li>
913 <li><a href="/shortlog">log</a></li>
914 <li><a href="/graph">graph</a></li>
914 <li><a href="/graph">graph</a></li>
915 <li><a href="/tags">tags</a></li>
915 <li><a href="/tags">tags</a></li>
916 <li><a href="/bookmarks">bookmarks</a></li>
916 <li><a href="/bookmarks">bookmarks</a></li>
917 <li><a href="/branches">branches</a></li>
917 <li><a href="/branches">branches</a></li>
918 </ul>
918 </ul>
919 <ul>
919 <ul>
920 <li class="active">help</li>
920 <li class="active">help</li>
921 </ul>
921 </ul>
922 </div>
922 </div>
923
923
924 <div class="main">
924 <div class="main">
925 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
925 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
926 <form class="search" action="/log">
926 <form class="search" action="/log">
927
927
928 <p><input name="rev" id="search1" type="text" size="30" /></p>
928 <p><input name="rev" id="search1" type="text" size="30" /></p>
929 <div id="hint">find changesets by author, revision,
929 <div id="hint">find changesets by author, revision,
930 files, or words in the commit message</div>
930 files, or words in the commit message</div>
931 </form>
931 </form>
932 <table class="bigtable">
932 <table class="bigtable">
933 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
933 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
934
934
935 <tr><td>
935 <tr><td>
936 <a href="/help/config">
936 <a href="/help/config">
937 config
937 config
938 </a>
938 </a>
939 </td><td>
939 </td><td>
940 Configuration Files
940 Configuration Files
941 </td></tr>
941 </td></tr>
942 <tr><td>
942 <tr><td>
943 <a href="/help/dates">
943 <a href="/help/dates">
944 dates
944 dates
945 </a>
945 </a>
946 </td><td>
946 </td><td>
947 Date Formats
947 Date Formats
948 </td></tr>
948 </td></tr>
949 <tr><td>
949 <tr><td>
950 <a href="/help/diffs">
950 <a href="/help/diffs">
951 diffs
951 diffs
952 </a>
952 </a>
953 </td><td>
953 </td><td>
954 Diff Formats
954 Diff Formats
955 </td></tr>
955 </td></tr>
956 <tr><td>
956 <tr><td>
957 <a href="/help/environment">
957 <a href="/help/environment">
958 environment
958 environment
959 </a>
959 </a>
960 </td><td>
960 </td><td>
961 Environment Variables
961 Environment Variables
962 </td></tr>
962 </td></tr>
963 <tr><td>
963 <tr><td>
964 <a href="/help/extensions">
964 <a href="/help/extensions">
965 extensions
965 extensions
966 </a>
966 </a>
967 </td><td>
967 </td><td>
968 Using Additional Features
968 Using Additional Features
969 </td></tr>
969 </td></tr>
970 <tr><td>
970 <tr><td>
971 <a href="/help/filesets">
971 <a href="/help/filesets">
972 filesets
972 filesets
973 </a>
973 </a>
974 </td><td>
974 </td><td>
975 Specifying File Sets
975 Specifying File Sets
976 </td></tr>
976 </td></tr>
977 <tr><td>
977 <tr><td>
978 <a href="/help/glossary">
978 <a href="/help/glossary">
979 glossary
979 glossary
980 </a>
980 </a>
981 </td><td>
981 </td><td>
982 Glossary
982 Glossary
983 </td></tr>
983 </td></tr>
984 <tr><td>
984 <tr><td>
985 <a href="/help/hgignore">
985 <a href="/help/hgignore">
986 hgignore
986 hgignore
987 </a>
987 </a>
988 </td><td>
988 </td><td>
989 Syntax for Mercurial Ignore Files
989 Syntax for Mercurial Ignore Files
990 </td></tr>
990 </td></tr>
991 <tr><td>
991 <tr><td>
992 <a href="/help/hgweb">
992 <a href="/help/hgweb">
993 hgweb
993 hgweb
994 </a>
994 </a>
995 </td><td>
995 </td><td>
996 Configuring hgweb
996 Configuring hgweb
997 </td></tr>
997 </td></tr>
998 <tr><td>
998 <tr><td>
999 <a href="/help/merge-tools">
999 <a href="/help/merge-tools">
1000 merge-tools
1000 merge-tools
1001 </a>
1001 </a>
1002 </td><td>
1002 </td><td>
1003 Merge Tools
1003 Merge Tools
1004 </td></tr>
1004 </td></tr>
1005 <tr><td>
1005 <tr><td>
1006 <a href="/help/multirevs">
1006 <a href="/help/multirevs">
1007 multirevs
1007 multirevs
1008 </a>
1008 </a>
1009 </td><td>
1009 </td><td>
1010 Specifying Multiple Revisions
1010 Specifying Multiple Revisions
1011 </td></tr>
1011 </td></tr>
1012 <tr><td>
1012 <tr><td>
1013 <a href="/help/patterns">
1013 <a href="/help/patterns">
1014 patterns
1014 patterns
1015 </a>
1015 </a>
1016 </td><td>
1016 </td><td>
1017 File Name Patterns
1017 File Name Patterns
1018 </td></tr>
1018 </td></tr>
1019 <tr><td>
1019 <tr><td>
1020 <a href="/help/phases">
1020 <a href="/help/phases">
1021 phases
1021 phases
1022 </a>
1022 </a>
1023 </td><td>
1023 </td><td>
1024 Working with Phases
1024 Working with Phases
1025 </td></tr>
1025 </td></tr>
1026 <tr><td>
1026 <tr><td>
1027 <a href="/help/revisions">
1027 <a href="/help/revisions">
1028 revisions
1028 revisions
1029 </a>
1029 </a>
1030 </td><td>
1030 </td><td>
1031 Specifying Single Revisions
1031 Specifying Single Revisions
1032 </td></tr>
1032 </td></tr>
1033 <tr><td>
1033 <tr><td>
1034 <a href="/help/revsets">
1034 <a href="/help/revsets">
1035 revsets
1035 revsets
1036 </a>
1036 </a>
1037 </td><td>
1037 </td><td>
1038 Specifying Revision Sets
1038 Specifying Revision Sets
1039 </td></tr>
1039 </td></tr>
1040 <tr><td>
1040 <tr><td>
1041 <a href="/help/subrepos">
1041 <a href="/help/subrepos">
1042 subrepos
1042 subrepos
1043 </a>
1043 </a>
1044 </td><td>
1044 </td><td>
1045 Subrepositories
1045 Subrepositories
1046 </td></tr>
1046 </td></tr>
1047 <tr><td>
1047 <tr><td>
1048 <a href="/help/templating">
1048 <a href="/help/templating">
1049 templating
1049 templating
1050 </a>
1050 </a>
1051 </td><td>
1051 </td><td>
1052 Template Usage
1052 Template Usage
1053 </td></tr>
1053 </td></tr>
1054 <tr><td>
1054 <tr><td>
1055 <a href="/help/urls">
1055 <a href="/help/urls">
1056 urls
1056 urls
1057 </a>
1057 </a>
1058 </td><td>
1058 </td><td>
1059 URL Paths
1059 URL Paths
1060 </td></tr>
1060 </td></tr>
1061 <tr><td>
1061 <tr><td>
1062 <a href="/help/topic-containing-verbose">
1062 <a href="/help/topic-containing-verbose">
1063 topic-containing-verbose
1063 topic-containing-verbose
1064 </a>
1064 </a>
1065 </td><td>
1065 </td><td>
1066 This is the topic to test omit indicating.
1066 This is the topic to test omit indicating.
1067 </td></tr>
1067 </td></tr>
1068
1068
1069 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1069 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1070
1070
1071 <tr><td>
1071 <tr><td>
1072 <a href="/help/add">
1072 <a href="/help/add">
1073 add
1073 add
1074 </a>
1074 </a>
1075 </td><td>
1075 </td><td>
1076 add the specified files on the next commit
1076 add the specified files on the next commit
1077 </td></tr>
1077 </td></tr>
1078 <tr><td>
1078 <tr><td>
1079 <a href="/help/annotate">
1079 <a href="/help/annotate">
1080 annotate
1080 annotate
1081 </a>
1081 </a>
1082 </td><td>
1082 </td><td>
1083 show changeset information by line for each file
1083 show changeset information by line for each file
1084 </td></tr>
1084 </td></tr>
1085 <tr><td>
1085 <tr><td>
1086 <a href="/help/clone">
1086 <a href="/help/clone">
1087 clone
1087 clone
1088 </a>
1088 </a>
1089 </td><td>
1089 </td><td>
1090 make a copy of an existing repository
1090 make a copy of an existing repository
1091 </td></tr>
1091 </td></tr>
1092 <tr><td>
1092 <tr><td>
1093 <a href="/help/commit">
1093 <a href="/help/commit">
1094 commit
1094 commit
1095 </a>
1095 </a>
1096 </td><td>
1096 </td><td>
1097 commit the specified files or all outstanding changes
1097 commit the specified files or all outstanding changes
1098 </td></tr>
1098 </td></tr>
1099 <tr><td>
1099 <tr><td>
1100 <a href="/help/diff">
1100 <a href="/help/diff">
1101 diff
1101 diff
1102 </a>
1102 </a>
1103 </td><td>
1103 </td><td>
1104 diff repository (or selected files)
1104 diff repository (or selected files)
1105 </td></tr>
1105 </td></tr>
1106 <tr><td>
1106 <tr><td>
1107 <a href="/help/export">
1107 <a href="/help/export">
1108 export
1108 export
1109 </a>
1109 </a>
1110 </td><td>
1110 </td><td>
1111 dump the header and diffs for one or more changesets
1111 dump the header and diffs for one or more changesets
1112 </td></tr>
1112 </td></tr>
1113 <tr><td>
1113 <tr><td>
1114 <a href="/help/forget">
1114 <a href="/help/forget">
1115 forget
1115 forget
1116 </a>
1116 </a>
1117 </td><td>
1117 </td><td>
1118 forget the specified files on the next commit
1118 forget the specified files on the next commit
1119 </td></tr>
1119 </td></tr>
1120 <tr><td>
1120 <tr><td>
1121 <a href="/help/init">
1121 <a href="/help/init">
1122 init
1122 init
1123 </a>
1123 </a>
1124 </td><td>
1124 </td><td>
1125 create a new repository in the given directory
1125 create a new repository in the given directory
1126 </td></tr>
1126 </td></tr>
1127 <tr><td>
1127 <tr><td>
1128 <a href="/help/log">
1128 <a href="/help/log">
1129 log
1129 log
1130 </a>
1130 </a>
1131 </td><td>
1131 </td><td>
1132 show revision history of entire repository or files
1132 show revision history of entire repository or files
1133 </td></tr>
1133 </td></tr>
1134 <tr><td>
1134 <tr><td>
1135 <a href="/help/merge">
1135 <a href="/help/merge">
1136 merge
1136 merge
1137 </a>
1137 </a>
1138 </td><td>
1138 </td><td>
1139 merge working directory with another revision
1139 merge working directory with another revision
1140 </td></tr>
1140 </td></tr>
1141 <tr><td>
1141 <tr><td>
1142 <a href="/help/pull">
1142 <a href="/help/pull">
1143 pull
1143 pull
1144 </a>
1144 </a>
1145 </td><td>
1145 </td><td>
1146 pull changes from the specified source
1146 pull changes from the specified source
1147 </td></tr>
1147 </td></tr>
1148 <tr><td>
1148 <tr><td>
1149 <a href="/help/push">
1149 <a href="/help/push">
1150 push
1150 push
1151 </a>
1151 </a>
1152 </td><td>
1152 </td><td>
1153 push changes to the specified destination
1153 push changes to the specified destination
1154 </td></tr>
1154 </td></tr>
1155 <tr><td>
1155 <tr><td>
1156 <a href="/help/remove">
1156 <a href="/help/remove">
1157 remove
1157 remove
1158 </a>
1158 </a>
1159 </td><td>
1159 </td><td>
1160 remove the specified files on the next commit
1160 remove the specified files on the next commit
1161 </td></tr>
1161 </td></tr>
1162 <tr><td>
1162 <tr><td>
1163 <a href="/help/serve">
1163 <a href="/help/serve">
1164 serve
1164 serve
1165 </a>
1165 </a>
1166 </td><td>
1166 </td><td>
1167 start stand-alone webserver
1167 start stand-alone webserver
1168 </td></tr>
1168 </td></tr>
1169 <tr><td>
1169 <tr><td>
1170 <a href="/help/status">
1170 <a href="/help/status">
1171 status
1171 status
1172 </a>
1172 </a>
1173 </td><td>
1173 </td><td>
1174 show changed files in the working directory
1174 show changed files in the working directory
1175 </td></tr>
1175 </td></tr>
1176 <tr><td>
1176 <tr><td>
1177 <a href="/help/summary">
1177 <a href="/help/summary">
1178 summary
1178 summary
1179 </a>
1179 </a>
1180 </td><td>
1180 </td><td>
1181 summarize working directory state
1181 summarize working directory state
1182 </td></tr>
1182 </td></tr>
1183 <tr><td>
1183 <tr><td>
1184 <a href="/help/update">
1184 <a href="/help/update">
1185 update
1185 update
1186 </a>
1186 </a>
1187 </td><td>
1187 </td><td>
1188 update working directory (or switch revisions)
1188 update working directory (or switch revisions)
1189 </td></tr>
1189 </td></tr>
1190
1190
1191 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1191 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1192
1192
1193 <tr><td>
1193 <tr><td>
1194 <a href="/help/addremove">
1194 <a href="/help/addremove">
1195 addremove
1195 addremove
1196 </a>
1196 </a>
1197 </td><td>
1197 </td><td>
1198 add all new files, delete all missing files
1198 add all new files, delete all missing files
1199 </td></tr>
1199 </td></tr>
1200 <tr><td>
1200 <tr><td>
1201 <a href="/help/archive">
1201 <a href="/help/archive">
1202 archive
1202 archive
1203 </a>
1203 </a>
1204 </td><td>
1204 </td><td>
1205 create an unversioned archive of a repository revision
1205 create an unversioned archive of a repository revision
1206 </td></tr>
1206 </td></tr>
1207 <tr><td>
1207 <tr><td>
1208 <a href="/help/backout">
1208 <a href="/help/backout">
1209 backout
1209 backout
1210 </a>
1210 </a>
1211 </td><td>
1211 </td><td>
1212 reverse effect of earlier changeset
1212 reverse effect of earlier changeset
1213 </td></tr>
1213 </td></tr>
1214 <tr><td>
1214 <tr><td>
1215 <a href="/help/bisect">
1215 <a href="/help/bisect">
1216 bisect
1216 bisect
1217 </a>
1217 </a>
1218 </td><td>
1218 </td><td>
1219 subdivision search of changesets
1219 subdivision search of changesets
1220 </td></tr>
1220 </td></tr>
1221 <tr><td>
1221 <tr><td>
1222 <a href="/help/bookmarks">
1222 <a href="/help/bookmarks">
1223 bookmarks
1223 bookmarks
1224 </a>
1224 </a>
1225 </td><td>
1225 </td><td>
1226 track a line of development with movable markers
1226 track a line of development with movable markers
1227 </td></tr>
1227 </td></tr>
1228 <tr><td>
1228 <tr><td>
1229 <a href="/help/branch">
1229 <a href="/help/branch">
1230 branch
1230 branch
1231 </a>
1231 </a>
1232 </td><td>
1232 </td><td>
1233 set or show the current branch name
1233 set or show the current branch name
1234 </td></tr>
1234 </td></tr>
1235 <tr><td>
1235 <tr><td>
1236 <a href="/help/branches">
1236 <a href="/help/branches">
1237 branches
1237 branches
1238 </a>
1238 </a>
1239 </td><td>
1239 </td><td>
1240 list repository named branches
1240 list repository named branches
1241 </td></tr>
1241 </td></tr>
1242 <tr><td>
1242 <tr><td>
1243 <a href="/help/bundle">
1243 <a href="/help/bundle">
1244 bundle
1244 bundle
1245 </a>
1245 </a>
1246 </td><td>
1246 </td><td>
1247 create a changegroup file
1247 create a changegroup file
1248 </td></tr>
1248 </td></tr>
1249 <tr><td>
1249 <tr><td>
1250 <a href="/help/cat">
1250 <a href="/help/cat">
1251 cat
1251 cat
1252 </a>
1252 </a>
1253 </td><td>
1253 </td><td>
1254 output the current or given revision of files
1254 output the current or given revision of files
1255 </td></tr>
1255 </td></tr>
1256 <tr><td>
1256 <tr><td>
1257 <a href="/help/copy">
1257 <a href="/help/copy">
1258 copy
1258 copy
1259 </a>
1259 </a>
1260 </td><td>
1260 </td><td>
1261 mark files as copied for the next commit
1261 mark files as copied for the next commit
1262 </td></tr>
1262 </td></tr>
1263 <tr><td>
1263 <tr><td>
1264 <a href="/help/graft">
1264 <a href="/help/graft">
1265 graft
1265 graft
1266 </a>
1266 </a>
1267 </td><td>
1267 </td><td>
1268 copy changes from other branches onto the current branch
1268 copy changes from other branches onto the current branch
1269 </td></tr>
1269 </td></tr>
1270 <tr><td>
1270 <tr><td>
1271 <a href="/help/grep">
1271 <a href="/help/grep">
1272 grep
1272 grep
1273 </a>
1273 </a>
1274 </td><td>
1274 </td><td>
1275 search for a pattern in specified files and revisions
1275 search for a pattern in specified files and revisions
1276 </td></tr>
1276 </td></tr>
1277 <tr><td>
1277 <tr><td>
1278 <a href="/help/heads">
1278 <a href="/help/heads">
1279 heads
1279 heads
1280 </a>
1280 </a>
1281 </td><td>
1281 </td><td>
1282 show current repository heads or show branch heads
1282 show current repository heads or show branch heads
1283 </td></tr>
1283 </td></tr>
1284 <tr><td>
1284 <tr><td>
1285 <a href="/help/help">
1285 <a href="/help/help">
1286 help
1286 help
1287 </a>
1287 </a>
1288 </td><td>
1288 </td><td>
1289 show help for a given topic or a help overview
1289 show help for a given topic or a help overview
1290 </td></tr>
1290 </td></tr>
1291 <tr><td>
1291 <tr><td>
1292 <a href="/help/identify">
1292 <a href="/help/identify">
1293 identify
1293 identify
1294 </a>
1294 </a>
1295 </td><td>
1295 </td><td>
1296 identify the working copy or specified revision
1296 identify the working copy or specified revision
1297 </td></tr>
1297 </td></tr>
1298 <tr><td>
1298 <tr><td>
1299 <a href="/help/import">
1299 <a href="/help/import">
1300 import
1300 import
1301 </a>
1301 </a>
1302 </td><td>
1302 </td><td>
1303 import an ordered set of patches
1303 import an ordered set of patches
1304 </td></tr>
1304 </td></tr>
1305 <tr><td>
1305 <tr><td>
1306 <a href="/help/incoming">
1306 <a href="/help/incoming">
1307 incoming
1307 incoming
1308 </a>
1308 </a>
1309 </td><td>
1309 </td><td>
1310 show new changesets found in source
1310 show new changesets found in source
1311 </td></tr>
1311 </td></tr>
1312 <tr><td>
1312 <tr><td>
1313 <a href="/help/locate">
1313 <a href="/help/locate">
1314 locate
1314 locate
1315 </a>
1315 </a>
1316 </td><td>
1316 </td><td>
1317 locate files matching specific patterns
1317 locate files matching specific patterns
1318 </td></tr>
1318 </td></tr>
1319 <tr><td>
1319 <tr><td>
1320 <a href="/help/manifest">
1320 <a href="/help/manifest">
1321 manifest
1321 manifest
1322 </a>
1322 </a>
1323 </td><td>
1323 </td><td>
1324 output the current or given revision of the project manifest
1324 output the current or given revision of the project manifest
1325 </td></tr>
1325 </td></tr>
1326 <tr><td>
1326 <tr><td>
1327 <a href="/help/nohelp">
1327 <a href="/help/nohelp">
1328 nohelp
1328 nohelp
1329 </a>
1329 </a>
1330 </td><td>
1330 </td><td>
1331 (no help text available)
1331 (no help text available)
1332 </td></tr>
1332 </td></tr>
1333 <tr><td>
1333 <tr><td>
1334 <a href="/help/outgoing">
1334 <a href="/help/outgoing">
1335 outgoing
1335 outgoing
1336 </a>
1336 </a>
1337 </td><td>
1337 </td><td>
1338 show changesets not found in the destination
1338 show changesets not found in the destination
1339 </td></tr>
1339 </td></tr>
1340 <tr><td>
1340 <tr><td>
1341 <a href="/help/parents">
1341 <a href="/help/parents">
1342 parents
1342 parents
1343 </a>
1343 </a>
1344 </td><td>
1344 </td><td>
1345 show the parents of the working directory or revision
1345 show the parents of the working directory or revision
1346 </td></tr>
1346 </td></tr>
1347 <tr><td>
1347 <tr><td>
1348 <a href="/help/paths">
1348 <a href="/help/paths">
1349 paths
1349 paths
1350 </a>
1350 </a>
1351 </td><td>
1351 </td><td>
1352 show aliases for remote repositories
1352 show aliases for remote repositories
1353 </td></tr>
1353 </td></tr>
1354 <tr><td>
1354 <tr><td>
1355 <a href="/help/phase">
1355 <a href="/help/phase">
1356 phase
1356 phase
1357 </a>
1357 </a>
1358 </td><td>
1358 </td><td>
1359 set or show the current phase name
1359 set or show the current phase name
1360 </td></tr>
1360 </td></tr>
1361 <tr><td>
1361 <tr><td>
1362 <a href="/help/recover">
1362 <a href="/help/recover">
1363 recover
1363 recover
1364 </a>
1364 </a>
1365 </td><td>
1365 </td><td>
1366 roll back an interrupted transaction
1366 roll back an interrupted transaction
1367 </td></tr>
1367 </td></tr>
1368 <tr><td>
1368 <tr><td>
1369 <a href="/help/rename">
1369 <a href="/help/rename">
1370 rename
1370 rename
1371 </a>
1371 </a>
1372 </td><td>
1372 </td><td>
1373 rename files; equivalent of copy + remove
1373 rename files; equivalent of copy + remove
1374 </td></tr>
1374 </td></tr>
1375 <tr><td>
1375 <tr><td>
1376 <a href="/help/resolve">
1376 <a href="/help/resolve">
1377 resolve
1377 resolve
1378 </a>
1378 </a>
1379 </td><td>
1379 </td><td>
1380 redo merges or set/view the merge status of files
1380 redo merges or set/view the merge status of files
1381 </td></tr>
1381 </td></tr>
1382 <tr><td>
1382 <tr><td>
1383 <a href="/help/revert">
1383 <a href="/help/revert">
1384 revert
1384 revert
1385 </a>
1385 </a>
1386 </td><td>
1386 </td><td>
1387 restore files to their checkout state
1387 restore files to their checkout state
1388 </td></tr>
1388 </td></tr>
1389 <tr><td>
1389 <tr><td>
1390 <a href="/help/rollback">
1390 <a href="/help/rollback">
1391 rollback
1391 rollback
1392 </a>
1392 </a>
1393 </td><td>
1393 </td><td>
1394 roll back the last transaction (dangerous)
1394 roll back the last transaction (dangerous)
1395 </td></tr>
1395 </td></tr>
1396 <tr><td>
1396 <tr><td>
1397 <a href="/help/root">
1397 <a href="/help/root">
1398 root
1398 root
1399 </a>
1399 </a>
1400 </td><td>
1400 </td><td>
1401 print the root (top) of the current working directory
1401 print the root (top) of the current working directory
1402 </td></tr>
1402 </td></tr>
1403 <tr><td>
1403 <tr><td>
1404 <a href="/help/showconfig">
1404 <a href="/help/showconfig">
1405 showconfig
1405 showconfig
1406 </a>
1406 </a>
1407 </td><td>
1407 </td><td>
1408 show combined config settings from all hgrc files
1408 show combined config settings from all hgrc files
1409 </td></tr>
1409 </td></tr>
1410 <tr><td>
1410 <tr><td>
1411 <a href="/help/tag">
1411 <a href="/help/tag">
1412 tag
1412 tag
1413 </a>
1413 </a>
1414 </td><td>
1414 </td><td>
1415 add one or more tags for the current or given revision
1415 add one or more tags for the current or given revision
1416 </td></tr>
1416 </td></tr>
1417 <tr><td>
1417 <tr><td>
1418 <a href="/help/tags">
1418 <a href="/help/tags">
1419 tags
1419 tags
1420 </a>
1420 </a>
1421 </td><td>
1421 </td><td>
1422 list repository tags
1422 list repository tags
1423 </td></tr>
1423 </td></tr>
1424 <tr><td>
1424 <tr><td>
1425 <a href="/help/tip">
1425 <a href="/help/tip">
1426 tip
1426 tip
1427 </a>
1427 </a>
1428 </td><td>
1428 </td><td>
1429 show the tip revision
1429 show the tip revision
1430 </td></tr>
1430 </td></tr>
1431 <tr><td>
1431 <tr><td>
1432 <a href="/help/unbundle">
1432 <a href="/help/unbundle">
1433 unbundle
1433 unbundle
1434 </a>
1434 </a>
1435 </td><td>
1435 </td><td>
1436 apply one or more changegroup files
1436 apply one or more changegroup files
1437 </td></tr>
1437 </td></tr>
1438 <tr><td>
1438 <tr><td>
1439 <a href="/help/verify">
1439 <a href="/help/verify">
1440 verify
1440 verify
1441 </a>
1441 </a>
1442 </td><td>
1442 </td><td>
1443 verify the integrity of the repository
1443 verify the integrity of the repository
1444 </td></tr>
1444 </td></tr>
1445 <tr><td>
1445 <tr><td>
1446 <a href="/help/version">
1446 <a href="/help/version">
1447 version
1447 version
1448 </a>
1448 </a>
1449 </td><td>
1449 </td><td>
1450 output version and copyright information
1450 output version and copyright information
1451 </td></tr>
1451 </td></tr>
1452 </table>
1452 </table>
1453 </div>
1453 </div>
1454 </div>
1454 </div>
1455
1455
1456 <script type="text/javascript">process_dates()</script>
1456 <script type="text/javascript">process_dates()</script>
1457
1457
1458
1458
1459 </body>
1459 </body>
1460 </html>
1460 </html>
1461
1461
1462
1462
1463 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/add"
1463 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/add"
1464 200 Script output follows
1464 200 Script output follows
1465
1465
1466 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1466 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1467 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1467 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1468 <head>
1468 <head>
1469 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1469 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1470 <meta name="robots" content="index, nofollow" />
1470 <meta name="robots" content="index, nofollow" />
1471 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1471 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1472 <script type="text/javascript" src="/static/mercurial.js"></script>
1472 <script type="text/javascript" src="/static/mercurial.js"></script>
1473
1473
1474 <title>Help: add</title>
1474 <title>Help: add</title>
1475 </head>
1475 </head>
1476 <body>
1476 <body>
1477
1477
1478 <div class="container">
1478 <div class="container">
1479 <div class="menu">
1479 <div class="menu">
1480 <div class="logo">
1480 <div class="logo">
1481 <a href="http://mercurial.selenic.com/">
1481 <a href="http://mercurial.selenic.com/">
1482 <img src="/static/hglogo.png" alt="mercurial" /></a>
1482 <img src="/static/hglogo.png" alt="mercurial" /></a>
1483 </div>
1483 </div>
1484 <ul>
1484 <ul>
1485 <li><a href="/shortlog">log</a></li>
1485 <li><a href="/shortlog">log</a></li>
1486 <li><a href="/graph">graph</a></li>
1486 <li><a href="/graph">graph</a></li>
1487 <li><a href="/tags">tags</a></li>
1487 <li><a href="/tags">tags</a></li>
1488 <li><a href="/bookmarks">bookmarks</a></li>
1488 <li><a href="/bookmarks">bookmarks</a></li>
1489 <li><a href="/branches">branches</a></li>
1489 <li><a href="/branches">branches</a></li>
1490 </ul>
1490 </ul>
1491 <ul>
1491 <ul>
1492 <li class="active"><a href="/help">help</a></li>
1492 <li class="active"><a href="/help">help</a></li>
1493 </ul>
1493 </ul>
1494 </div>
1494 </div>
1495
1495
1496 <div class="main">
1496 <div class="main">
1497 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1497 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1498 <h3>Help: add</h3>
1498 <h3>Help: add</h3>
1499
1499
1500 <form class="search" action="/log">
1500 <form class="search" action="/log">
1501
1501
1502 <p><input name="rev" id="search1" type="text" size="30" /></p>
1502 <p><input name="rev" id="search1" type="text" size="30" /></p>
1503 <div id="hint">find changesets by author, revision,
1503 <div id="hint">find changesets by author, revision,
1504 files, or words in the commit message</div>
1504 files, or words in the commit message</div>
1505 </form>
1505 </form>
1506 <pre>
1506 <div id="doc">
1507 <p>
1507 hg add [OPTION]... [FILE]...
1508 hg add [OPTION]... [FILE]...
1508
1509 </p>
1510 <p>
1509 add the specified files on the next commit
1511 add the specified files on the next commit
1510
1512 </p>
1511 Schedule files to be version controlled and added to the repository.
1513 <p>
1512
1514 Schedule files to be version controlled and added to the
1513 The files will be added to the repository at the next commit. To undo an
1515 repository.
1514 add before that, see &quot;hg forget&quot;.
1516 </p>
1515
1517 <p>
1516 If no names are given, add all files to the repository.
1518 The files will be added to the repository at the next commit. To
1517
1519 undo an add before that, see "hg forget".
1518 An example showing how new (unknown) files are added automatically by &quot;hg
1520 </p>
1519 add&quot;:
1521 <p>
1520
1522 If no names are given, add all files to the repository.
1521 $ ls
1523 </p>
1522 foo.c
1524 <p>
1523 $ hg status
1525 Returns 0 if all files are successfully added.
1524 ? foo.c
1526 </p>
1525 $ hg add
1527 <p>
1526 adding foo.c
1527 $ hg status
1528 A foo.c
1529
1530 Returns 0 if all files are successfully added.
1531
1532 options:
1528 options:
1529 </p>
1530 <table>
1531 <tr><th>-I</th><th>--include PATTERN [+]</th><th>include names matching the given patterns</th></tr>
1532 <tr><td>-X</td><td>--exclude PATTERN [+]</td><td>exclude names matching the given patterns</td></tr>
1533 <tr><td>-S</td><td>--subrepos</td><td>recurse into subrepositories</td></tr>
1534 <tr><td>-n</td><td>--dry-run</td><td>do not perform actions, just print output</td></tr>
1535 </table>
1536 <p>
1537 [+] marked option can be specified multiple times
1538 </p>
1539 <p>
1540 global options:
1541 </p>
1542 <table>
1543 <tr><th>-R</th><th>--repository REPO</th><th>repository root directory or name of overlay bundle file</th></tr>
1544 <tr><td></td><td>--cwd DIR</td><td>change working directory</td></tr>
1545 <tr><td>-y</td><td>--noninteractive</td><td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1546 <tr><td>-q</td><td>--quiet</td><td>suppress output</td></tr>
1547 <tr><td>-v</td><td>--verbose</td><td>enable additional output</td></tr>
1548 <tr><td></td><td>--config CONFIG [+]</td><td>set/override config option (use 'section.name=value')</td></tr>
1549 <tr><td></td><td>--debug</td><td>enable debugging output</td></tr>
1550 <tr><td></td><td>--debugger</td><td>start debugger</td></tr>
1551 <tr><td></td><td>--encoding ENCODE</td><td>set the charset encoding (default: ascii)</td></tr>
1552 <tr><td></td><td>--encodingmode MODE</td><td>set the charset encoding mode (default: strict)</td></tr>
1553 <tr><td></td><td>--traceback</td><td>always print a traceback on exception</td></tr>
1554 <tr><td></td><td>--time</td><td>time how long the command takes</td></tr>
1555 <tr><td></td><td>--profile</td><td>print command execution profile</td></tr>
1556 <tr><td></td><td>--version</td><td>output version information and exit</td></tr>
1557 <tr><td>-h</td><td>--help</td><td>display help and exit</td></tr>
1558 <tr><td></td><td>--hidden</td><td>consider hidden changesets</td></tr>
1559 </table>
1560 <p>
1561 [+] marked option can be specified multiple times
1562 </p>
1533
1563
1534 -I --include PATTERN [+] include names matching the given patterns
1564 </div>
1535 -X --exclude PATTERN [+] exclude names matching the given patterns
1536 -S --subrepos recurse into subrepositories
1537 -n --dry-run do not perform actions, just print output
1538
1539 [+] marked option can be specified multiple times
1540
1541 global options:
1542
1543 -R --repository REPO repository root directory or name of overlay bundle
1544 file
1545 --cwd DIR change working directory
1546 -y --noninteractive do not prompt, automatically pick the first choice for
1547 all prompts
1548 -q --quiet suppress output
1549 -v --verbose enable additional output
1550 --config CONFIG [+] set/override config option (use 'section.name=value')
1551 --debug enable debugging output
1552 --debugger start debugger
1553 --encoding ENCODE set the charset encoding (default: ascii)
1554 --encodingmode MODE set the charset encoding mode (default: strict)
1555 --traceback always print a traceback on exception
1556 --time time how long the command takes
1557 --profile print command execution profile
1558 --version output version information and exit
1559 -h --help display help and exit
1560 --hidden consider hidden changesets
1561
1562 [+] marked option can be specified multiple times
1563
1564 </pre>
1565 </div>
1565 </div>
1566 </div>
1566 </div>
1567
1567
1568 <script type="text/javascript">process_dates()</script>
1568 <script type="text/javascript">process_dates()</script>
1569
1569
1570
1570
1571 </body>
1571 </body>
1572 </html>
1572 </html>
1573
1573
1574
1574
1575 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/remove"
1575 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/remove"
1576 200 Script output follows
1576 200 Script output follows
1577
1577
1578 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1578 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1579 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1579 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1580 <head>
1580 <head>
1581 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1581 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1582 <meta name="robots" content="index, nofollow" />
1582 <meta name="robots" content="index, nofollow" />
1583 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1583 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1584 <script type="text/javascript" src="/static/mercurial.js"></script>
1584 <script type="text/javascript" src="/static/mercurial.js"></script>
1585
1585
1586 <title>Help: remove</title>
1586 <title>Help: remove</title>
1587 </head>
1587 </head>
1588 <body>
1588 <body>
1589
1589
1590 <div class="container">
1590 <div class="container">
1591 <div class="menu">
1591 <div class="menu">
1592 <div class="logo">
1592 <div class="logo">
1593 <a href="http://mercurial.selenic.com/">
1593 <a href="http://mercurial.selenic.com/">
1594 <img src="/static/hglogo.png" alt="mercurial" /></a>
1594 <img src="/static/hglogo.png" alt="mercurial" /></a>
1595 </div>
1595 </div>
1596 <ul>
1596 <ul>
1597 <li><a href="/shortlog">log</a></li>
1597 <li><a href="/shortlog">log</a></li>
1598 <li><a href="/graph">graph</a></li>
1598 <li><a href="/graph">graph</a></li>
1599 <li><a href="/tags">tags</a></li>
1599 <li><a href="/tags">tags</a></li>
1600 <li><a href="/bookmarks">bookmarks</a></li>
1600 <li><a href="/bookmarks">bookmarks</a></li>
1601 <li><a href="/branches">branches</a></li>
1601 <li><a href="/branches">branches</a></li>
1602 </ul>
1602 </ul>
1603 <ul>
1603 <ul>
1604 <li class="active"><a href="/help">help</a></li>
1604 <li class="active"><a href="/help">help</a></li>
1605 </ul>
1605 </ul>
1606 </div>
1606 </div>
1607
1607
1608 <div class="main">
1608 <div class="main">
1609 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1609 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1610 <h3>Help: remove</h3>
1610 <h3>Help: remove</h3>
1611
1611
1612 <form class="search" action="/log">
1612 <form class="search" action="/log">
1613
1613
1614 <p><input name="rev" id="search1" type="text" size="30" /></p>
1614 <p><input name="rev" id="search1" type="text" size="30" /></p>
1615 <div id="hint">find changesets by author, revision,
1615 <div id="hint">find changesets by author, revision,
1616 files, or words in the commit message</div>
1616 files, or words in the commit message</div>
1617 </form>
1617 </form>
1618 <pre>
1618 <div id="doc">
1619 <p>
1619 hg remove [OPTION]... FILE...
1620 hg remove [OPTION]... FILE...
1620
1621 </p>
1622 <p>
1621 aliases: rm
1623 aliases: rm
1622
1624 </p>
1625 <p>
1623 remove the specified files on the next commit
1626 remove the specified files on the next commit
1624
1627 </p>
1625 Schedule the indicated files for removal from the current branch.
1628 <p>
1626
1629 Schedule the indicated files for removal from the current branch.
1627 This command schedules the files to be removed at the next commit. To undo
1630 </p>
1628 a remove before that, see &quot;hg revert&quot;. To undo added files, see &quot;hg
1631 <p>
1629 forget&quot;.
1632 This command schedules the files to be removed at the next commit.
1630
1633 To undo a remove before that, see "hg revert". To undo added
1631 -A/--after can be used to remove only files that have already been
1634 files, see "hg forget".
1632 deleted, -f/--force can be used to force deletion, and -Af can be used to
1635 </p>
1633 remove files from the next revision without deleting them from the working
1636 <p>
1634 directory.
1637 Returns 0 on success, 1 if any warnings encountered.
1635
1638 </p>
1636 The following table details the behavior of remove for different file
1639 <p>
1637 states (columns) and option combinations (rows). The file states are Added
1640 options:
1638 [A], Clean [C], Modified [M] and Missing [!] (as reported by &quot;hg status&quot;).
1641 </p>
1639 The actions are Warn, Remove (from branch) and Delete (from disk):
1642 <table>
1640
1643 <tr><th>-A</th><th>--after</th><th>record delete for missing files</th></tr>
1641 A C M !
1644 <tr><td>-f</td><td>--force</td><td>remove (and delete) file even if added or modified</td></tr>
1642 --------------
1645 <tr><td>-I</td><td>--include PATTERN [+]</td><td>include names matching the given patterns</td></tr>
1643 none W RD W R
1646 <tr><td>-X</td><td>--exclude PATTERN [+]</td><td>exclude names matching the given patterns</td></tr>
1644 -f R RD RD R
1647 </table>
1645 -A W W W R
1648 <p>
1646 -Af R R R R
1649 [+] marked option can be specified multiple times
1647
1650 </p>
1648 Note that remove never deletes files in Added [A] state from the working
1651 <p>
1649 directory, not even if option --force is specified.
1652 global options:
1653 </p>
1654 <table>
1655 <tr><th>-R</th><th>--repository REPO</th><th>repository root directory or name of overlay bundle file</th></tr>
1656 <tr><td></td><td>--cwd DIR</td><td>change working directory</td></tr>
1657 <tr><td>-y</td><td>--noninteractive</td><td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1658 <tr><td>-q</td><td>--quiet</td><td>suppress output</td></tr>
1659 <tr><td>-v</td><td>--verbose</td><td>enable additional output</td></tr>
1660 <tr><td></td><td>--config CONFIG [+]</td><td>set/override config option (use 'section.name=value')</td></tr>
1661 <tr><td></td><td>--debug</td><td>enable debugging output</td></tr>
1662 <tr><td></td><td>--debugger</td><td>start debugger</td></tr>
1663 <tr><td></td><td>--encoding ENCODE</td><td>set the charset encoding (default: ascii)</td></tr>
1664 <tr><td></td><td>--encodingmode MODE</td><td>set the charset encoding mode (default: strict)</td></tr>
1665 <tr><td></td><td>--traceback</td><td>always print a traceback on exception</td></tr>
1666 <tr><td></td><td>--time</td><td>time how long the command takes</td></tr>
1667 <tr><td></td><td>--profile</td><td>print command execution profile</td></tr>
1668 <tr><td></td><td>--version</td><td>output version information and exit</td></tr>
1669 <tr><td>-h</td><td>--help</td><td>display help and exit</td></tr>
1670 <tr><td></td><td>--hidden</td><td>consider hidden changesets</td></tr>
1671 </table>
1672 <p>
1673 [+] marked option can be specified multiple times
1674 </p>
1650
1675
1651 Returns 0 on success, 1 if any warnings encountered.
1676 </div>
1652
1653 options:
1654
1655 -A --after record delete for missing files
1656 -f --force remove (and delete) file even if added or modified
1657 -I --include PATTERN [+] include names matching the given patterns
1658 -X --exclude PATTERN [+] exclude names matching the given patterns
1659
1660 [+] marked option can be specified multiple times
1661
1662 global options:
1663
1664 -R --repository REPO repository root directory or name of overlay bundle
1665 file
1666 --cwd DIR change working directory
1667 -y --noninteractive do not prompt, automatically pick the first choice for
1668 all prompts
1669 -q --quiet suppress output
1670 -v --verbose enable additional output
1671 --config CONFIG [+] set/override config option (use 'section.name=value')
1672 --debug enable debugging output
1673 --debugger start debugger
1674 --encoding ENCODE set the charset encoding (default: ascii)
1675 --encodingmode MODE set the charset encoding mode (default: strict)
1676 --traceback always print a traceback on exception
1677 --time time how long the command takes
1678 --profile print command execution profile
1679 --version output version information and exit
1680 -h --help display help and exit
1681 --hidden consider hidden changesets
1682
1683 [+] marked option can be specified multiple times
1684
1685 </pre>
1686 </div>
1677 </div>
1687 </div>
1678 </div>
1688
1679
1689 <script type="text/javascript">process_dates()</script>
1680 <script type="text/javascript">process_dates()</script>
1690
1681
1691
1682
1692 </body>
1683 </body>
1693 </html>
1684 </html>
1694
1685
1695
1686
1696 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/revisions"
1687 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/revisions"
1697 200 Script output follows
1688 200 Script output follows
1698
1689
1699 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1690 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1700 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1691 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1701 <head>
1692 <head>
1702 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1693 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1703 <meta name="robots" content="index, nofollow" />
1694 <meta name="robots" content="index, nofollow" />
1704 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1695 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1705 <script type="text/javascript" src="/static/mercurial.js"></script>
1696 <script type="text/javascript" src="/static/mercurial.js"></script>
1706
1697
1707 <title>Help: revisions</title>
1698 <title>Help: revisions</title>
1708 </head>
1699 </head>
1709 <body>
1700 <body>
1710
1701
1711 <div class="container">
1702 <div class="container">
1712 <div class="menu">
1703 <div class="menu">
1713 <div class="logo">
1704 <div class="logo">
1714 <a href="http://mercurial.selenic.com/">
1705 <a href="http://mercurial.selenic.com/">
1715 <img src="/static/hglogo.png" alt="mercurial" /></a>
1706 <img src="/static/hglogo.png" alt="mercurial" /></a>
1716 </div>
1707 </div>
1717 <ul>
1708 <ul>
1718 <li><a href="/shortlog">log</a></li>
1709 <li><a href="/shortlog">log</a></li>
1719 <li><a href="/graph">graph</a></li>
1710 <li><a href="/graph">graph</a></li>
1720 <li><a href="/tags">tags</a></li>
1711 <li><a href="/tags">tags</a></li>
1721 <li><a href="/bookmarks">bookmarks</a></li>
1712 <li><a href="/bookmarks">bookmarks</a></li>
1722 <li><a href="/branches">branches</a></li>
1713 <li><a href="/branches">branches</a></li>
1723 </ul>
1714 </ul>
1724 <ul>
1715 <ul>
1725 <li class="active"><a href="/help">help</a></li>
1716 <li class="active"><a href="/help">help</a></li>
1726 </ul>
1717 </ul>
1727 </div>
1718 </div>
1728
1719
1729 <div class="main">
1720 <div class="main">
1730 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1721 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1731 <h3>Help: revisions</h3>
1722 <h3>Help: revisions</h3>
1732
1723
1733 <form class="search" action="/log">
1724 <form class="search" action="/log">
1734
1725
1735 <p><input name="rev" id="search1" type="text" size="30" /></p>
1726 <p><input name="rev" id="search1" type="text" size="30" /></p>
1736 <div id="hint">find changesets by author, revision,
1727 <div id="hint">find changesets by author, revision,
1737 files, or words in the commit message</div>
1728 files, or words in the commit message</div>
1738 </form>
1729 </form>
1739 <pre>
1730 <div id="doc">
1731 <p>
1740 Specifying Single Revisions
1732 Specifying Single Revisions
1741
1733 </p>
1742 Mercurial supports several ways to specify individual revisions.
1734 <p>
1743
1735 Mercurial supports several ways to specify individual revisions.
1744 A plain integer is treated as a revision number. Negative integers are
1736 </p>
1745 treated as sequential offsets from the tip, with -1 denoting the tip, -2
1737 <p>
1746 denoting the revision prior to the tip, and so forth.
1738 A plain integer is treated as a revision number. Negative integers are
1747
1739 treated as sequential offsets from the tip, with -1 denoting the tip,
1748 A 40-digit hexadecimal string is treated as a unique revision identifier.
1740 -2 denoting the revision prior to the tip, and so forth.
1749
1741 </p>
1750 A hexadecimal string less than 40 characters long is treated as a unique
1742 <p>
1751 revision identifier and is referred to as a short-form identifier. A
1743 A 40-digit hexadecimal string is treated as a unique revision
1752 short-form identifier is only valid if it is the prefix of exactly one
1744 identifier.
1753 full-length identifier.
1745 </p>
1746 <p>
1747 A hexadecimal string less than 40 characters long is treated as a
1748 unique revision identifier and is referred to as a short-form
1749 identifier. A short-form identifier is only valid if it is the prefix
1750 of exactly one full-length identifier.
1751 </p>
1752 <p>
1753 Any other string is treated as a bookmark, tag, or branch name. A
1754 bookmark is a movable pointer to a revision. A tag is a permanent name
1755 associated with a revision. A branch name denotes the tipmost revision
1756 of that branch. Bookmark, tag, and branch names must not contain the ":"
1757 character.
1758 </p>
1759 <p>
1760 The reserved name "tip" always identifies the most recent revision.
1761 </p>
1762 <p>
1763 The reserved name "null" indicates the null revision. This is the
1764 revision of an empty repository, and the parent of revision 0.
1765 </p>
1766 <p>
1767 The reserved name "." indicates the working directory parent. If no
1768 working directory is checked out, it is equivalent to null. If an
1769 uncommitted merge is in progress, "." is the revision of the first
1770 parent.
1771 </p>
1754
1772
1755 Any other string is treated as a bookmark, tag, or branch name. A bookmark
1773 </div>
1756 is a movable pointer to a revision. A tag is a permanent name associated
1757 with a revision. A branch name denotes the tipmost revision of that
1758 branch. Bookmark, tag, and branch names must not contain the &quot;:&quot;
1759 character.
1760
1761 The reserved name &quot;tip&quot; always identifies the most recent revision.
1762
1763 The reserved name &quot;null&quot; indicates the null revision. This is the revision
1764 of an empty repository, and the parent of revision 0.
1765
1766 The reserved name &quot;.&quot; indicates the working directory parent. If no
1767 working directory is checked out, it is equivalent to null. If an
1768 uncommitted merge is in progress, &quot;.&quot; is the revision of the first parent.
1769
1770 </pre>
1771 </div>
1774 </div>
1772 </div>
1775 </div>
1773
1776
1774 <script type="text/javascript">process_dates()</script>
1777 <script type="text/javascript">process_dates()</script>
1775
1778
1776
1779
1777 </body>
1780 </body>
1778 </html>
1781 </html>
1779
1782
1780
1783
1781 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1784 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1782
1785
1783 #endif
1786 #endif
General Comments 0
You need to be logged in to leave comments. Login now