##// END OF EJS Templates
hgweb: add a "web/logoimg" setting to customize the web logo image...
Angel Ezquerra -
r14913:44382887 default
parent child Browse files
Show More
@@ -1,302 +1,304 b''
1 # hgweb/hgweb_mod.py - Web interface for a repository.
1 # hgweb/hgweb_mod.py - Web interface for a repository.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 import os
9 import os
10 from mercurial import ui, hg, hook, error, encoding, templater
10 from mercurial import ui, hg, hook, error, encoding, templater
11 from common import get_stat, ErrorResponse, permhooks, caching
11 from common import get_stat, ErrorResponse, permhooks, caching
12 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
12 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
13 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
13 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
14 from request import wsgirequest
14 from request import wsgirequest
15 import webcommands, protocol, webutil
15 import webcommands, protocol, webutil
16
16
17 perms = {
17 perms = {
18 'changegroup': 'pull',
18 'changegroup': 'pull',
19 'changegroupsubset': 'pull',
19 'changegroupsubset': 'pull',
20 'getbundle': 'pull',
20 'getbundle': 'pull',
21 'stream_out': 'pull',
21 'stream_out': 'pull',
22 'listkeys': 'pull',
22 'listkeys': 'pull',
23 'unbundle': 'push',
23 'unbundle': 'push',
24 'pushkey': 'push',
24 'pushkey': 'push',
25 }
25 }
26
26
27 class hgweb(object):
27 class hgweb(object):
28 def __init__(self, repo, name=None, baseui=None):
28 def __init__(self, repo, name=None, baseui=None):
29 if isinstance(repo, str):
29 if isinstance(repo, str):
30 if baseui:
30 if baseui:
31 u = baseui.copy()
31 u = baseui.copy()
32 else:
32 else:
33 u = ui.ui()
33 u = ui.ui()
34 self.repo = hg.repository(u, repo)
34 self.repo = hg.repository(u, repo)
35 else:
35 else:
36 self.repo = repo
36 self.repo = repo
37
37
38 self.repo.ui.setconfig('ui', 'report_untrusted', 'off')
38 self.repo.ui.setconfig('ui', 'report_untrusted', 'off')
39 self.repo.ui.setconfig('ui', 'interactive', 'off')
39 self.repo.ui.setconfig('ui', 'interactive', 'off')
40 hook.redirect(True)
40 hook.redirect(True)
41 self.mtime = -1
41 self.mtime = -1
42 self.size = -1
42 self.size = -1
43 self.reponame = name
43 self.reponame = name
44 self.archives = 'zip', 'gz', 'bz2'
44 self.archives = 'zip', 'gz', 'bz2'
45 self.stripecount = 1
45 self.stripecount = 1
46 # a repo owner may set web.templates in .hg/hgrc to get any file
46 # a repo owner may set web.templates in .hg/hgrc to get any file
47 # readable by the user running the CGI script
47 # readable by the user running the CGI script
48 self.templatepath = self.config('web', 'templates')
48 self.templatepath = self.config('web', 'templates')
49
49
50 # The CGI scripts are often run by a user different from the repo owner.
50 # The CGI scripts are often run by a user different from the repo owner.
51 # Trust the settings from the .hg/hgrc files by default.
51 # Trust the settings from the .hg/hgrc files by default.
52 def config(self, section, name, default=None, untrusted=True):
52 def config(self, section, name, default=None, untrusted=True):
53 return self.repo.ui.config(section, name, default,
53 return self.repo.ui.config(section, name, default,
54 untrusted=untrusted)
54 untrusted=untrusted)
55
55
56 def configbool(self, section, name, default=False, untrusted=True):
56 def configbool(self, section, name, default=False, untrusted=True):
57 return self.repo.ui.configbool(section, name, default,
57 return self.repo.ui.configbool(section, name, default,
58 untrusted=untrusted)
58 untrusted=untrusted)
59
59
60 def configlist(self, section, name, default=None, untrusted=True):
60 def configlist(self, section, name, default=None, untrusted=True):
61 return self.repo.ui.configlist(section, name, default,
61 return self.repo.ui.configlist(section, name, default,
62 untrusted=untrusted)
62 untrusted=untrusted)
63
63
64 def refresh(self, request=None):
64 def refresh(self, request=None):
65 if request:
65 if request:
66 self.repo.ui.environ = request.env
66 self.repo.ui.environ = request.env
67 st = get_stat(self.repo.spath)
67 st = get_stat(self.repo.spath)
68 # compare changelog size in addition to mtime to catch
68 # compare changelog size in addition to mtime to catch
69 # rollbacks made less than a second ago
69 # rollbacks made less than a second ago
70 if st.st_mtime != self.mtime or st.st_size != self.size:
70 if st.st_mtime != self.mtime or st.st_size != self.size:
71 self.mtime = st.st_mtime
71 self.mtime = st.st_mtime
72 self.size = st.st_size
72 self.size = st.st_size
73 self.repo = hg.repository(self.repo.ui, self.repo.root)
73 self.repo = hg.repository(self.repo.ui, self.repo.root)
74 self.maxchanges = int(self.config("web", "maxchanges", 10))
74 self.maxchanges = int(self.config("web", "maxchanges", 10))
75 self.stripecount = int(self.config("web", "stripes", 1))
75 self.stripecount = int(self.config("web", "stripes", 1))
76 self.maxshortchanges = int(self.config("web", "maxshortchanges", 60))
76 self.maxshortchanges = int(self.config("web", "maxshortchanges", 60))
77 self.maxfiles = int(self.config("web", "maxfiles", 10))
77 self.maxfiles = int(self.config("web", "maxfiles", 10))
78 self.allowpull = self.configbool("web", "allowpull", True)
78 self.allowpull = self.configbool("web", "allowpull", True)
79 encoding.encoding = self.config("web", "encoding",
79 encoding.encoding = self.config("web", "encoding",
80 encoding.encoding)
80 encoding.encoding)
81
81
82 def run(self):
82 def run(self):
83 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
83 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
84 raise RuntimeError("This function is only intended to be "
84 raise RuntimeError("This function is only intended to be "
85 "called while running as a CGI script.")
85 "called while running as a CGI script.")
86 import mercurial.hgweb.wsgicgi as wsgicgi
86 import mercurial.hgweb.wsgicgi as wsgicgi
87 wsgicgi.launch(self)
87 wsgicgi.launch(self)
88
88
89 def __call__(self, env, respond):
89 def __call__(self, env, respond):
90 req = wsgirequest(env, respond)
90 req = wsgirequest(env, respond)
91 return self.run_wsgi(req)
91 return self.run_wsgi(req)
92
92
93 def run_wsgi(self, req):
93 def run_wsgi(self, req):
94
94
95 self.refresh(req)
95 self.refresh(req)
96
96
97 # work with CGI variables to create coherent structure
97 # work with CGI variables to create coherent structure
98 # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
98 # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
99
99
100 req.url = req.env['SCRIPT_NAME']
100 req.url = req.env['SCRIPT_NAME']
101 if not req.url.endswith('/'):
101 if not req.url.endswith('/'):
102 req.url += '/'
102 req.url += '/'
103 if 'REPO_NAME' in req.env:
103 if 'REPO_NAME' in req.env:
104 req.url += req.env['REPO_NAME'] + '/'
104 req.url += req.env['REPO_NAME'] + '/'
105
105
106 if 'PATH_INFO' in req.env:
106 if 'PATH_INFO' in req.env:
107 parts = req.env['PATH_INFO'].strip('/').split('/')
107 parts = req.env['PATH_INFO'].strip('/').split('/')
108 repo_parts = req.env.get('REPO_NAME', '').split('/')
108 repo_parts = req.env.get('REPO_NAME', '').split('/')
109 if parts[:len(repo_parts)] == repo_parts:
109 if parts[:len(repo_parts)] == repo_parts:
110 parts = parts[len(repo_parts):]
110 parts = parts[len(repo_parts):]
111 query = '/'.join(parts)
111 query = '/'.join(parts)
112 else:
112 else:
113 query = req.env['QUERY_STRING'].split('&', 1)[0]
113 query = req.env['QUERY_STRING'].split('&', 1)[0]
114 query = query.split(';', 1)[0]
114 query = query.split(';', 1)[0]
115
115
116 # process this if it's a protocol request
116 # process this if it's a protocol request
117 # protocol bits don't need to create any URLs
117 # protocol bits don't need to create any URLs
118 # and the clients always use the old URL structure
118 # and the clients always use the old URL structure
119
119
120 cmd = req.form.get('cmd', [''])[0]
120 cmd = req.form.get('cmd', [''])[0]
121 if protocol.iscmd(cmd):
121 if protocol.iscmd(cmd):
122 try:
122 try:
123 if query:
123 if query:
124 raise ErrorResponse(HTTP_NOT_FOUND)
124 raise ErrorResponse(HTTP_NOT_FOUND)
125 if cmd in perms:
125 if cmd in perms:
126 self.check_perm(req, perms[cmd])
126 self.check_perm(req, perms[cmd])
127 return protocol.call(self.repo, req, cmd)
127 return protocol.call(self.repo, req, cmd)
128 except ErrorResponse, inst:
128 except ErrorResponse, inst:
129 # A client that sends unbundle without 100-continue will
129 # A client that sends unbundle without 100-continue will
130 # break if we respond early.
130 # break if we respond early.
131 if (cmd == 'unbundle' and
131 if (cmd == 'unbundle' and
132 req.env.get('HTTP_EXPECT',
132 req.env.get('HTTP_EXPECT',
133 '').lower() != '100-continue'):
133 '').lower() != '100-continue'):
134 req.drain()
134 req.drain()
135 req.respond(inst, protocol.HGTYPE)
135 req.respond(inst, protocol.HGTYPE)
136 return '0\n%s\n' % inst.message
136 return '0\n%s\n' % inst.message
137
137
138 # translate user-visible url structure to internal structure
138 # translate user-visible url structure to internal structure
139
139
140 args = query.split('/', 2)
140 args = query.split('/', 2)
141 if 'cmd' not in req.form and args and args[0]:
141 if 'cmd' not in req.form and args and args[0]:
142
142
143 cmd = args.pop(0)
143 cmd = args.pop(0)
144 style = cmd.rfind('-')
144 style = cmd.rfind('-')
145 if style != -1:
145 if style != -1:
146 req.form['style'] = [cmd[:style]]
146 req.form['style'] = [cmd[:style]]
147 cmd = cmd[style + 1:]
147 cmd = cmd[style + 1:]
148
148
149 # avoid accepting e.g. style parameter as command
149 # avoid accepting e.g. style parameter as command
150 if hasattr(webcommands, cmd):
150 if hasattr(webcommands, cmd):
151 req.form['cmd'] = [cmd]
151 req.form['cmd'] = [cmd]
152 else:
152 else:
153 cmd = ''
153 cmd = ''
154
154
155 if cmd == 'static':
155 if cmd == 'static':
156 req.form['file'] = ['/'.join(args)]
156 req.form['file'] = ['/'.join(args)]
157 else:
157 else:
158 if args and args[0]:
158 if args and args[0]:
159 node = args.pop(0)
159 node = args.pop(0)
160 req.form['node'] = [node]
160 req.form['node'] = [node]
161 if args:
161 if args:
162 req.form['file'] = args
162 req.form['file'] = args
163
163
164 ua = req.env.get('HTTP_USER_AGENT', '')
164 ua = req.env.get('HTTP_USER_AGENT', '')
165 if cmd == 'rev' and 'mercurial' in ua:
165 if cmd == 'rev' and 'mercurial' in ua:
166 req.form['style'] = ['raw']
166 req.form['style'] = ['raw']
167
167
168 if cmd == 'archive':
168 if cmd == 'archive':
169 fn = req.form['node'][0]
169 fn = req.form['node'][0]
170 for type_, spec in self.archive_specs.iteritems():
170 for type_, spec in self.archive_specs.iteritems():
171 ext = spec[2]
171 ext = spec[2]
172 if fn.endswith(ext):
172 if fn.endswith(ext):
173 req.form['node'] = [fn[:-len(ext)]]
173 req.form['node'] = [fn[:-len(ext)]]
174 req.form['type'] = [type_]
174 req.form['type'] = [type_]
175
175
176 # process the web interface request
176 # process the web interface request
177
177
178 try:
178 try:
179 tmpl = self.templater(req)
179 tmpl = self.templater(req)
180 ctype = tmpl('mimetype', encoding=encoding.encoding)
180 ctype = tmpl('mimetype', encoding=encoding.encoding)
181 ctype = templater.stringify(ctype)
181 ctype = templater.stringify(ctype)
182
182
183 # check read permissions non-static content
183 # check read permissions non-static content
184 if cmd != 'static':
184 if cmd != 'static':
185 self.check_perm(req, None)
185 self.check_perm(req, None)
186
186
187 if cmd == '':
187 if cmd == '':
188 req.form['cmd'] = [tmpl.cache['default']]
188 req.form['cmd'] = [tmpl.cache['default']]
189 cmd = req.form['cmd'][0]
189 cmd = req.form['cmd'][0]
190
190
191 if self.configbool('web', 'cache', True):
191 if self.configbool('web', 'cache', True):
192 caching(self, req) # sets ETag header or raises NOT_MODIFIED
192 caching(self, req) # sets ETag header or raises NOT_MODIFIED
193 if cmd not in webcommands.__all__:
193 if cmd not in webcommands.__all__:
194 msg = 'no such method: %s' % cmd
194 msg = 'no such method: %s' % cmd
195 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
195 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
196 elif cmd == 'file' and 'raw' in req.form.get('style', []):
196 elif cmd == 'file' and 'raw' in req.form.get('style', []):
197 self.ctype = ctype
197 self.ctype = ctype
198 content = webcommands.rawfile(self, req, tmpl)
198 content = webcommands.rawfile(self, req, tmpl)
199 else:
199 else:
200 content = getattr(webcommands, cmd)(self, req, tmpl)
200 content = getattr(webcommands, cmd)(self, req, tmpl)
201 req.respond(HTTP_OK, ctype)
201 req.respond(HTTP_OK, ctype)
202
202
203 return content
203 return content
204
204
205 except error.LookupError, err:
205 except error.LookupError, err:
206 req.respond(HTTP_NOT_FOUND, ctype)
206 req.respond(HTTP_NOT_FOUND, ctype)
207 msg = str(err)
207 msg = str(err)
208 if 'manifest' not in msg:
208 if 'manifest' not in msg:
209 msg = 'revision not found: %s' % err.name
209 msg = 'revision not found: %s' % err.name
210 return tmpl('error', error=msg)
210 return tmpl('error', error=msg)
211 except (error.RepoError, error.RevlogError), inst:
211 except (error.RepoError, error.RevlogError), inst:
212 req.respond(HTTP_SERVER_ERROR, ctype)
212 req.respond(HTTP_SERVER_ERROR, ctype)
213 return tmpl('error', error=str(inst))
213 return tmpl('error', error=str(inst))
214 except ErrorResponse, inst:
214 except ErrorResponse, inst:
215 req.respond(inst, ctype)
215 req.respond(inst, ctype)
216 if inst.code == HTTP_NOT_MODIFIED:
216 if inst.code == HTTP_NOT_MODIFIED:
217 # Not allowed to return a body on a 304
217 # Not allowed to return a body on a 304
218 return ['']
218 return ['']
219 return tmpl('error', error=inst.message)
219 return tmpl('error', error=inst.message)
220
220
221 def templater(self, req):
221 def templater(self, req):
222
222
223 # determine scheme, port and server name
223 # determine scheme, port and server name
224 # this is needed to create absolute urls
224 # this is needed to create absolute urls
225
225
226 proto = req.env.get('wsgi.url_scheme')
226 proto = req.env.get('wsgi.url_scheme')
227 if proto == 'https':
227 if proto == 'https':
228 proto = 'https'
228 proto = 'https'
229 default_port = "443"
229 default_port = "443"
230 else:
230 else:
231 proto = 'http'
231 proto = 'http'
232 default_port = "80"
232 default_port = "80"
233
233
234 port = req.env["SERVER_PORT"]
234 port = req.env["SERVER_PORT"]
235 port = port != default_port and (":" + port) or ""
235 port = port != default_port and (":" + port) or ""
236 urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
236 urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
237 logourl = self.config("web", "logourl", "http://mercurial.selenic.com/")
237 logourl = self.config("web", "logourl", "http://mercurial.selenic.com/")
238 logoimg = self.config("web", "logoimg", "hglogo.png")
238 staticurl = self.config("web", "staticurl") or req.url + 'static/'
239 staticurl = self.config("web", "staticurl") or req.url + 'static/'
239 if not staticurl.endswith('/'):
240 if not staticurl.endswith('/'):
240 staticurl += '/'
241 staticurl += '/'
241
242
242 # some functions for the templater
243 # some functions for the templater
243
244
244 def header(**map):
245 def header(**map):
245 yield tmpl('header', encoding=encoding.encoding, **map)
246 yield tmpl('header', encoding=encoding.encoding, **map)
246
247
247 def footer(**map):
248 def footer(**map):
248 yield tmpl("footer", **map)
249 yield tmpl("footer", **map)
249
250
250 def motd(**map):
251 def motd(**map):
251 yield self.config("web", "motd", "")
252 yield self.config("web", "motd", "")
252
253
253 # figure out which style to use
254 # figure out which style to use
254
255
255 vars = {}
256 vars = {}
256 styles = (
257 styles = (
257 req.form.get('style', [None])[0],
258 req.form.get('style', [None])[0],
258 self.config('web', 'style'),
259 self.config('web', 'style'),
259 'paper',
260 'paper',
260 )
261 )
261 style, mapfile = templater.stylemap(styles, self.templatepath)
262 style, mapfile = templater.stylemap(styles, self.templatepath)
262 if style == styles[0]:
263 if style == styles[0]:
263 vars['style'] = style
264 vars['style'] = style
264
265
265 start = req.url[-1] == '?' and '&' or '?'
266 start = req.url[-1] == '?' and '&' or '?'
266 sessionvars = webutil.sessionvars(vars, start)
267 sessionvars = webutil.sessionvars(vars, start)
267
268
268 if not self.reponame:
269 if not self.reponame:
269 self.reponame = (self.config("web", "name")
270 self.reponame = (self.config("web", "name")
270 or req.env.get('REPO_NAME')
271 or req.env.get('REPO_NAME')
271 or req.url.strip('/') or self.repo.root)
272 or req.url.strip('/') or self.repo.root)
272
273
273 # create the templater
274 # create the templater
274
275
275 tmpl = templater.templater(mapfile,
276 tmpl = templater.templater(mapfile,
276 defaults={"url": req.url,
277 defaults={"url": req.url,
277 "logourl": logourl,
278 "logourl": logourl,
279 "logoimg": logoimg,
278 "staticurl": staticurl,
280 "staticurl": staticurl,
279 "urlbase": urlbase,
281 "urlbase": urlbase,
280 "repo": self.reponame,
282 "repo": self.reponame,
281 "header": header,
283 "header": header,
282 "footer": footer,
284 "footer": footer,
283 "motd": motd,
285 "motd": motd,
284 "sessionvars": sessionvars
286 "sessionvars": sessionvars
285 })
287 })
286 return tmpl
288 return tmpl
287
289
288 def archivelist(self, nodeid):
290 def archivelist(self, nodeid):
289 allowed = self.configlist("web", "allow_archive")
291 allowed = self.configlist("web", "allow_archive")
290 for i, spec in self.archive_specs.iteritems():
292 for i, spec in self.archive_specs.iteritems():
291 if i in allowed or self.configbool("web", "allow" + i):
293 if i in allowed or self.configbool("web", "allow" + i):
292 yield {"type" : i, "extension" : spec[2], "node" : nodeid}
294 yield {"type" : i, "extension" : spec[2], "node" : nodeid}
293
295
294 archive_specs = {
296 archive_specs = {
295 'bz2': ('application/x-bzip2', 'tbz2', '.tar.bz2', None),
297 'bz2': ('application/x-bzip2', 'tbz2', '.tar.bz2', None),
296 'gz': ('application/x-gzip', 'tgz', '.tar.gz', None),
298 'gz': ('application/x-gzip', 'tgz', '.tar.gz', None),
297 'zip': ('application/zip', 'zip', '.zip', None),
299 'zip': ('application/zip', 'zip', '.zip', None),
298 }
300 }
299
301
300 def check_perm(self, req, op):
302 def check_perm(self, req, op):
301 for hook in permhooks:
303 for hook in permhooks:
302 hook(self, req, op)
304 hook(self, req, op)
@@ -1,371 +1,373 b''
1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 import os, re, time
9 import os, re, time
10 from mercurial.i18n import _
10 from mercurial.i18n import _
11 from mercurial import ui, hg, scmutil, util, templater
11 from mercurial import ui, hg, scmutil, util, templater
12 from mercurial import error, encoding
12 from mercurial import error, encoding
13 from common import ErrorResponse, get_mtime, staticfile, paritygen, \
13 from common import ErrorResponse, get_mtime, staticfile, paritygen, \
14 get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
14 get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
15 from hgweb_mod import hgweb
15 from hgweb_mod import hgweb
16 from request import wsgirequest
16 from request import wsgirequest
17 import webutil
17 import webutil
18
18
19 def cleannames(items):
19 def cleannames(items):
20 return [(util.pconvert(name).strip('/'), path) for name, path in items]
20 return [(util.pconvert(name).strip('/'), path) for name, path in items]
21
21
22 def findrepos(paths):
22 def findrepos(paths):
23 repos = []
23 repos = []
24 for prefix, root in cleannames(paths):
24 for prefix, root in cleannames(paths):
25 roothead, roottail = os.path.split(root)
25 roothead, roottail = os.path.split(root)
26 # "foo = /bar/*" makes every subrepo of /bar/ to be
26 # "foo = /bar/*" makes every subrepo of /bar/ to be
27 # mounted as foo/subrepo
27 # mounted as foo/subrepo
28 # and "foo = /bar/**" also recurses into the subdirectories,
28 # and "foo = /bar/**" also recurses into the subdirectories,
29 # remember to use it without working dir.
29 # remember to use it without working dir.
30 try:
30 try:
31 recurse = {'*': False, '**': True}[roottail]
31 recurse = {'*': False, '**': True}[roottail]
32 except KeyError:
32 except KeyError:
33 repos.append((prefix, root))
33 repos.append((prefix, root))
34 continue
34 continue
35 roothead = os.path.normpath(os.path.abspath(roothead))
35 roothead = os.path.normpath(os.path.abspath(roothead))
36 paths = scmutil.walkrepos(roothead, followsym=True, recurse=recurse)
36 paths = scmutil.walkrepos(roothead, followsym=True, recurse=recurse)
37 repos.extend(urlrepos(prefix, roothead, paths))
37 repos.extend(urlrepos(prefix, roothead, paths))
38 return repos
38 return repos
39
39
40 def urlrepos(prefix, roothead, paths):
40 def urlrepos(prefix, roothead, paths):
41 """yield url paths and filesystem paths from a list of repo paths
41 """yield url paths and filesystem paths from a list of repo paths
42
42
43 >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
43 >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
44 >>> conv(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
44 >>> conv(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
45 [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
45 [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
46 >>> conv(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
46 >>> conv(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
47 [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
47 [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
48 """
48 """
49 for path in paths:
49 for path in paths:
50 path = os.path.normpath(path)
50 path = os.path.normpath(path)
51 yield (prefix + '/' +
51 yield (prefix + '/' +
52 util.pconvert(path[len(roothead):]).lstrip('/')).strip('/'), path
52 util.pconvert(path[len(roothead):]).lstrip('/')).strip('/'), path
53
53
54 class hgwebdir(object):
54 class hgwebdir(object):
55 refreshinterval = 20
55 refreshinterval = 20
56
56
57 def __init__(self, conf, baseui=None):
57 def __init__(self, conf, baseui=None):
58 self.conf = conf
58 self.conf = conf
59 self.baseui = baseui
59 self.baseui = baseui
60 self.lastrefresh = 0
60 self.lastrefresh = 0
61 self.motd = None
61 self.motd = None
62 self.refresh()
62 self.refresh()
63
63
64 def refresh(self):
64 def refresh(self):
65 if self.lastrefresh + self.refreshinterval > time.time():
65 if self.lastrefresh + self.refreshinterval > time.time():
66 return
66 return
67
67
68 if self.baseui:
68 if self.baseui:
69 u = self.baseui.copy()
69 u = self.baseui.copy()
70 else:
70 else:
71 u = ui.ui()
71 u = ui.ui()
72 u.setconfig('ui', 'report_untrusted', 'off')
72 u.setconfig('ui', 'report_untrusted', 'off')
73 u.setconfig('ui', 'interactive', 'off')
73 u.setconfig('ui', 'interactive', 'off')
74
74
75 if not isinstance(self.conf, (dict, list, tuple)):
75 if not isinstance(self.conf, (dict, list, tuple)):
76 map = {'paths': 'hgweb-paths'}
76 map = {'paths': 'hgweb-paths'}
77 if not os.path.exists(self.conf):
77 if not os.path.exists(self.conf):
78 raise util.Abort(_('config file %s not found!') % self.conf)
78 raise util.Abort(_('config file %s not found!') % self.conf)
79 u.readconfig(self.conf, remap=map, trust=True)
79 u.readconfig(self.conf, remap=map, trust=True)
80 paths = []
80 paths = []
81 for name, ignored in u.configitems('hgweb-paths'):
81 for name, ignored in u.configitems('hgweb-paths'):
82 for path in u.configlist('hgweb-paths', name):
82 for path in u.configlist('hgweb-paths', name):
83 paths.append((name, path))
83 paths.append((name, path))
84 elif isinstance(self.conf, (list, tuple)):
84 elif isinstance(self.conf, (list, tuple)):
85 paths = self.conf
85 paths = self.conf
86 elif isinstance(self.conf, dict):
86 elif isinstance(self.conf, dict):
87 paths = self.conf.items()
87 paths = self.conf.items()
88
88
89 repos = findrepos(paths)
89 repos = findrepos(paths)
90 for prefix, root in u.configitems('collections'):
90 for prefix, root in u.configitems('collections'):
91 prefix = util.pconvert(prefix)
91 prefix = util.pconvert(prefix)
92 for path in scmutil.walkrepos(root, followsym=True):
92 for path in scmutil.walkrepos(root, followsym=True):
93 repo = os.path.normpath(path)
93 repo = os.path.normpath(path)
94 name = util.pconvert(repo)
94 name = util.pconvert(repo)
95 if name.startswith(prefix):
95 if name.startswith(prefix):
96 name = name[len(prefix):]
96 name = name[len(prefix):]
97 repos.append((name.lstrip('/'), repo))
97 repos.append((name.lstrip('/'), repo))
98
98
99 self.repos = repos
99 self.repos = repos
100 self.ui = u
100 self.ui = u
101 encoding.encoding = self.ui.config('web', 'encoding',
101 encoding.encoding = self.ui.config('web', 'encoding',
102 encoding.encoding)
102 encoding.encoding)
103 self.style = self.ui.config('web', 'style', 'paper')
103 self.style = self.ui.config('web', 'style', 'paper')
104 self.templatepath = self.ui.config('web', 'templates', None)
104 self.templatepath = self.ui.config('web', 'templates', None)
105 self.stripecount = self.ui.config('web', 'stripes', 1)
105 self.stripecount = self.ui.config('web', 'stripes', 1)
106 if self.stripecount:
106 if self.stripecount:
107 self.stripecount = int(self.stripecount)
107 self.stripecount = int(self.stripecount)
108 self._baseurl = self.ui.config('web', 'baseurl')
108 self._baseurl = self.ui.config('web', 'baseurl')
109 self.lastrefresh = time.time()
109 self.lastrefresh = time.time()
110
110
111 def run(self):
111 def run(self):
112 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
112 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
113 raise RuntimeError("This function is only intended to be "
113 raise RuntimeError("This function is only intended to be "
114 "called while running as a CGI script.")
114 "called while running as a CGI script.")
115 import mercurial.hgweb.wsgicgi as wsgicgi
115 import mercurial.hgweb.wsgicgi as wsgicgi
116 wsgicgi.launch(self)
116 wsgicgi.launch(self)
117
117
118 def __call__(self, env, respond):
118 def __call__(self, env, respond):
119 req = wsgirequest(env, respond)
119 req = wsgirequest(env, respond)
120 return self.run_wsgi(req)
120 return self.run_wsgi(req)
121
121
122 def read_allowed(self, ui, req):
122 def read_allowed(self, ui, req):
123 """Check allow_read and deny_read config options of a repo's ui object
123 """Check allow_read and deny_read config options of a repo's ui object
124 to determine user permissions. By default, with neither option set (or
124 to determine user permissions. By default, with neither option set (or
125 both empty), allow all users to read the repo. There are two ways a
125 both empty), allow all users to read the repo. There are two ways a
126 user can be denied read access: (1) deny_read is not empty, and the
126 user can be denied read access: (1) deny_read is not empty, and the
127 user is unauthenticated or deny_read contains user (or *), and (2)
127 user is unauthenticated or deny_read contains user (or *), and (2)
128 allow_read is not empty and the user is not in allow_read. Return True
128 allow_read is not empty and the user is not in allow_read. Return True
129 if user is allowed to read the repo, else return False."""
129 if user is allowed to read the repo, else return False."""
130
130
131 user = req.env.get('REMOTE_USER')
131 user = req.env.get('REMOTE_USER')
132
132
133 deny_read = ui.configlist('web', 'deny_read', untrusted=True)
133 deny_read = ui.configlist('web', 'deny_read', untrusted=True)
134 if deny_read and (not user or deny_read == ['*'] or user in deny_read):
134 if deny_read and (not user or deny_read == ['*'] or user in deny_read):
135 return False
135 return False
136
136
137 allow_read = ui.configlist('web', 'allow_read', untrusted=True)
137 allow_read = ui.configlist('web', 'allow_read', untrusted=True)
138 # by default, allow reading if no allow_read option has been set
138 # by default, allow reading if no allow_read option has been set
139 if (not allow_read) or (allow_read == ['*']) or (user in allow_read):
139 if (not allow_read) or (allow_read == ['*']) or (user in allow_read):
140 return True
140 return True
141
141
142 return False
142 return False
143
143
144 def run_wsgi(self, req):
144 def run_wsgi(self, req):
145 try:
145 try:
146 try:
146 try:
147 self.refresh()
147 self.refresh()
148
148
149 virtual = req.env.get("PATH_INFO", "").strip('/')
149 virtual = req.env.get("PATH_INFO", "").strip('/')
150 tmpl = self.templater(req)
150 tmpl = self.templater(req)
151 ctype = tmpl('mimetype', encoding=encoding.encoding)
151 ctype = tmpl('mimetype', encoding=encoding.encoding)
152 ctype = templater.stringify(ctype)
152 ctype = templater.stringify(ctype)
153
153
154 # a static file
154 # a static file
155 if virtual.startswith('static/') or 'static' in req.form:
155 if virtual.startswith('static/') or 'static' in req.form:
156 if virtual.startswith('static/'):
156 if virtual.startswith('static/'):
157 fname = virtual[7:]
157 fname = virtual[7:]
158 else:
158 else:
159 fname = req.form['static'][0]
159 fname = req.form['static'][0]
160 static = templater.templatepath('static')
160 static = templater.templatepath('static')
161 return (staticfile(static, fname, req),)
161 return (staticfile(static, fname, req),)
162
162
163 # top-level index
163 # top-level index
164 elif not virtual:
164 elif not virtual:
165 req.respond(HTTP_OK, ctype)
165 req.respond(HTTP_OK, ctype)
166 return self.makeindex(req, tmpl)
166 return self.makeindex(req, tmpl)
167
167
168 # nested indexes and hgwebs
168 # nested indexes and hgwebs
169
169
170 repos = dict(self.repos)
170 repos = dict(self.repos)
171 virtualrepo = virtual
171 virtualrepo = virtual
172 while virtualrepo:
172 while virtualrepo:
173 real = repos.get(virtualrepo)
173 real = repos.get(virtualrepo)
174 if real:
174 if real:
175 req.env['REPO_NAME'] = virtualrepo
175 req.env['REPO_NAME'] = virtualrepo
176 try:
176 try:
177 repo = hg.repository(self.ui, real)
177 repo = hg.repository(self.ui, real)
178 return hgweb(repo).run_wsgi(req)
178 return hgweb(repo).run_wsgi(req)
179 except IOError, inst:
179 except IOError, inst:
180 msg = inst.strerror
180 msg = inst.strerror
181 raise ErrorResponse(HTTP_SERVER_ERROR, msg)
181 raise ErrorResponse(HTTP_SERVER_ERROR, msg)
182 except error.RepoError, inst:
182 except error.RepoError, inst:
183 raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
183 raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
184
184
185 up = virtualrepo.rfind('/')
185 up = virtualrepo.rfind('/')
186 if up < 0:
186 if up < 0:
187 break
187 break
188 virtualrepo = virtualrepo[:up]
188 virtualrepo = virtualrepo[:up]
189
189
190 # browse subdirectories
190 # browse subdirectories
191 subdir = virtual + '/'
191 subdir = virtual + '/'
192 if [r for r in repos if r.startswith(subdir)]:
192 if [r for r in repos if r.startswith(subdir)]:
193 req.respond(HTTP_OK, ctype)
193 req.respond(HTTP_OK, ctype)
194 return self.makeindex(req, tmpl, subdir)
194 return self.makeindex(req, tmpl, subdir)
195
195
196 # prefixes not found
196 # prefixes not found
197 req.respond(HTTP_NOT_FOUND, ctype)
197 req.respond(HTTP_NOT_FOUND, ctype)
198 return tmpl("notfound", repo=virtual)
198 return tmpl("notfound", repo=virtual)
199
199
200 except ErrorResponse, err:
200 except ErrorResponse, err:
201 req.respond(err, ctype)
201 req.respond(err, ctype)
202 return tmpl('error', error=err.message or '')
202 return tmpl('error', error=err.message or '')
203 finally:
203 finally:
204 tmpl = None
204 tmpl = None
205
205
206 def makeindex(self, req, tmpl, subdir=""):
206 def makeindex(self, req, tmpl, subdir=""):
207
207
208 def archivelist(ui, nodeid, url):
208 def archivelist(ui, nodeid, url):
209 allowed = ui.configlist("web", "allow_archive", untrusted=True)
209 allowed = ui.configlist("web", "allow_archive", untrusted=True)
210 archives = []
210 archives = []
211 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
211 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
212 if i[0] in allowed or ui.configbool("web", "allow" + i[0],
212 if i[0] in allowed or ui.configbool("web", "allow" + i[0],
213 untrusted=True):
213 untrusted=True):
214 archives.append({"type" : i[0], "extension": i[1],
214 archives.append({"type" : i[0], "extension": i[1],
215 "node": nodeid, "url": url})
215 "node": nodeid, "url": url})
216 return archives
216 return archives
217
217
218 def rawentries(subdir="", **map):
218 def rawentries(subdir="", **map):
219
219
220 descend = self.ui.configbool('web', 'descend', True)
220 descend = self.ui.configbool('web', 'descend', True)
221 for name, path in self.repos:
221 for name, path in self.repos:
222
222
223 if not name.startswith(subdir):
223 if not name.startswith(subdir):
224 continue
224 continue
225 name = name[len(subdir):]
225 name = name[len(subdir):]
226 if not descend and '/' in name:
226 if not descend and '/' in name:
227 continue
227 continue
228
228
229 u = self.ui.copy()
229 u = self.ui.copy()
230 try:
230 try:
231 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
231 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
232 except Exception, e:
232 except Exception, e:
233 u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
233 u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
234 continue
234 continue
235 def get(section, name, default=None):
235 def get(section, name, default=None):
236 return u.config(section, name, default, untrusted=True)
236 return u.config(section, name, default, untrusted=True)
237
237
238 if u.configbool("web", "hidden", untrusted=True):
238 if u.configbool("web", "hidden", untrusted=True):
239 continue
239 continue
240
240
241 if not self.read_allowed(u, req):
241 if not self.read_allowed(u, req):
242 continue
242 continue
243
243
244 parts = [name]
244 parts = [name]
245 if 'PATH_INFO' in req.env:
245 if 'PATH_INFO' in req.env:
246 parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
246 parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
247 if req.env['SCRIPT_NAME']:
247 if req.env['SCRIPT_NAME']:
248 parts.insert(0, req.env['SCRIPT_NAME'])
248 parts.insert(0, req.env['SCRIPT_NAME'])
249 url = re.sub(r'/+', '/', '/'.join(parts) + '/')
249 url = re.sub(r'/+', '/', '/'.join(parts) + '/')
250
250
251 # update time with local timezone
251 # update time with local timezone
252 try:
252 try:
253 r = hg.repository(self.ui, path)
253 r = hg.repository(self.ui, path)
254 except IOError:
254 except IOError:
255 u.warn(_('error accessing repository at %s\n') % path)
255 u.warn(_('error accessing repository at %s\n') % path)
256 continue
256 continue
257 except error.RepoError:
257 except error.RepoError:
258 u.warn(_('error accessing repository at %s\n') % path)
258 u.warn(_('error accessing repository at %s\n') % path)
259 continue
259 continue
260 try:
260 try:
261 d = (get_mtime(r.spath), util.makedate()[1])
261 d = (get_mtime(r.spath), util.makedate()[1])
262 except OSError:
262 except OSError:
263 continue
263 continue
264
264
265 contact = get_contact(get)
265 contact = get_contact(get)
266 description = get("web", "description", "")
266 description = get("web", "description", "")
267 name = get("web", "name", name)
267 name = get("web", "name", name)
268 row = dict(contact=contact or "unknown",
268 row = dict(contact=contact or "unknown",
269 contact_sort=contact.upper() or "unknown",
269 contact_sort=contact.upper() or "unknown",
270 name=name,
270 name=name,
271 name_sort=name,
271 name_sort=name,
272 url=url,
272 url=url,
273 description=description or "unknown",
273 description=description or "unknown",
274 description_sort=description.upper() or "unknown",
274 description_sort=description.upper() or "unknown",
275 lastchange=d,
275 lastchange=d,
276 lastchange_sort=d[1]-d[0],
276 lastchange_sort=d[1]-d[0],
277 archives=archivelist(u, "tip", url))
277 archives=archivelist(u, "tip", url))
278 yield row
278 yield row
279
279
280 sortdefault = None, False
280 sortdefault = None, False
281 def entries(sortcolumn="", descending=False, subdir="", **map):
281 def entries(sortcolumn="", descending=False, subdir="", **map):
282 rows = rawentries(subdir=subdir, **map)
282 rows = rawentries(subdir=subdir, **map)
283
283
284 if sortcolumn and sortdefault != (sortcolumn, descending):
284 if sortcolumn and sortdefault != (sortcolumn, descending):
285 sortkey = '%s_sort' % sortcolumn
285 sortkey = '%s_sort' % sortcolumn
286 rows = sorted(rows, key=lambda x: x[sortkey],
286 rows = sorted(rows, key=lambda x: x[sortkey],
287 reverse=descending)
287 reverse=descending)
288 for row, parity in zip(rows, paritygen(self.stripecount)):
288 for row, parity in zip(rows, paritygen(self.stripecount)):
289 row['parity'] = parity
289 row['parity'] = parity
290 yield row
290 yield row
291
291
292 self.refresh()
292 self.refresh()
293 sortable = ["name", "description", "contact", "lastchange"]
293 sortable = ["name", "description", "contact", "lastchange"]
294 sortcolumn, descending = sortdefault
294 sortcolumn, descending = sortdefault
295 if 'sort' in req.form:
295 if 'sort' in req.form:
296 sortcolumn = req.form['sort'][0]
296 sortcolumn = req.form['sort'][0]
297 descending = sortcolumn.startswith('-')
297 descending = sortcolumn.startswith('-')
298 if descending:
298 if descending:
299 sortcolumn = sortcolumn[1:]
299 sortcolumn = sortcolumn[1:]
300 if sortcolumn not in sortable:
300 if sortcolumn not in sortable:
301 sortcolumn = ""
301 sortcolumn = ""
302
302
303 sort = [("sort_%s" % column,
303 sort = [("sort_%s" % column,
304 "%s%s" % ((not descending and column == sortcolumn)
304 "%s%s" % ((not descending and column == sortcolumn)
305 and "-" or "", column))
305 and "-" or "", column))
306 for column in sortable]
306 for column in sortable]
307
307
308 self.refresh()
308 self.refresh()
309 self.updatereqenv(req.env)
309 self.updatereqenv(req.env)
310
310
311 return tmpl("index", entries=entries, subdir=subdir,
311 return tmpl("index", entries=entries, subdir=subdir,
312 sortcolumn=sortcolumn, descending=descending,
312 sortcolumn=sortcolumn, descending=descending,
313 **dict(sort))
313 **dict(sort))
314
314
315 def templater(self, req):
315 def templater(self, req):
316
316
317 def header(**map):
317 def header(**map):
318 yield tmpl('header', encoding=encoding.encoding, **map)
318 yield tmpl('header', encoding=encoding.encoding, **map)
319
319
320 def footer(**map):
320 def footer(**map):
321 yield tmpl("footer", **map)
321 yield tmpl("footer", **map)
322
322
323 def motd(**map):
323 def motd(**map):
324 if self.motd is not None:
324 if self.motd is not None:
325 yield self.motd
325 yield self.motd
326 else:
326 else:
327 yield config('web', 'motd', '')
327 yield config('web', 'motd', '')
328
328
329 def config(section, name, default=None, untrusted=True):
329 def config(section, name, default=None, untrusted=True):
330 return self.ui.config(section, name, default, untrusted)
330 return self.ui.config(section, name, default, untrusted)
331
331
332 self.updatereqenv(req.env)
332 self.updatereqenv(req.env)
333
333
334 url = req.env.get('SCRIPT_NAME', '')
334 url = req.env.get('SCRIPT_NAME', '')
335 if not url.endswith('/'):
335 if not url.endswith('/'):
336 url += '/'
336 url += '/'
337
337
338 vars = {}
338 vars = {}
339 styles = (
339 styles = (
340 req.form.get('style', [None])[0],
340 req.form.get('style', [None])[0],
341 config('web', 'style'),
341 config('web', 'style'),
342 'paper'
342 'paper'
343 )
343 )
344 style, mapfile = templater.stylemap(styles, self.templatepath)
344 style, mapfile = templater.stylemap(styles, self.templatepath)
345 if style == styles[0]:
345 if style == styles[0]:
346 vars['style'] = style
346 vars['style'] = style
347
347
348 start = url[-1] == '?' and '&' or '?'
348 start = url[-1] == '?' and '&' or '?'
349 sessionvars = webutil.sessionvars(vars, start)
349 sessionvars = webutil.sessionvars(vars, start)
350 logourl = config('web', 'logourl', 'http://mercurial.selenic.com/')
350 logourl = config('web', 'logourl', 'http://mercurial.selenic.com/')
351 logoimg = config('web', 'logoimg', 'hglogo.png')
351 staticurl = config('web', 'staticurl') or url + 'static/'
352 staticurl = config('web', 'staticurl') or url + 'static/'
352 if not staticurl.endswith('/'):
353 if not staticurl.endswith('/'):
353 staticurl += '/'
354 staticurl += '/'
354
355
355 tmpl = templater.templater(mapfile,
356 tmpl = templater.templater(mapfile,
356 defaults={"header": header,
357 defaults={"header": header,
357 "footer": footer,
358 "footer": footer,
358 "motd": motd,
359 "motd": motd,
359 "url": url,
360 "url": url,
360 "logourl": logourl,
361 "logourl": logourl,
362 "logoimg": logoimg,
361 "staticurl": staticurl,
363 "staticurl": staticurl,
362 "sessionvars": sessionvars})
364 "sessionvars": sessionvars})
363 return tmpl
365 return tmpl
364
366
365 def updatereqenv(self, env):
367 def updatereqenv(self, env):
366 if self._baseurl is not None:
368 if self._baseurl is not None:
367 u = util.url(self._baseurl)
369 u = util.url(self._baseurl)
368 env['SERVER_NAME'] = u.host
370 env['SERVER_NAME'] = u.host
369 if u.port:
371 if u.port:
370 env['SERVER_PORT'] = u.port
372 env['SERVER_PORT'] = u.port
371 env['SCRIPT_NAME'] = '/' + u.path
373 env['SCRIPT_NAME'] = '/' + u.path
@@ -1,23 +1,23 b''
1 <script type="text/javascript">process_dates()</script>
1 <script type="text/javascript">process_dates()</script>
2 <div class="page-footer">
2 <div class="page-footer">
3 <p>Mercurial Repository: {repo|escape}</p>
3 <p>Mercurial Repository: {repo|escape}</p>
4 <ul class="rss-logo">
4 <ul class="rss-logo">
5 <li><a href="{url}rss-log">RSS</a></li>
5 <li><a href="{url}rss-log">RSS</a></li>
6 <li><a href="{url}atom-log">Atom</a></li>
6 <li><a href="{url}atom-log">Atom</a></li>
7 </ul>
7 </ul>
8 {motd}
8 {motd}
9 </div>
9 </div>
10
10
11 <div id="powered-by">
11 <div id="powered-by">
12 <p><a href="{logourl}" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
12 <p><a href="{logourl}" title="Mercurial"><img src="{staticurl}{logoimg}" width=75 height=90 border=0 alt="mercurial"></a></p>
13 </div>
13 </div>
14
14
15 <div id="corner-top-left"></div>
15 <div id="corner-top-left"></div>
16 <div id="corner-top-right"></div>
16 <div id="corner-top-right"></div>
17 <div id="corner-bottom-left"></div>
17 <div id="corner-bottom-left"></div>
18 <div id="corner-bottom-right"></div>
18 <div id="corner-bottom-right"></div>
19
19
20 </div>
20 </div>
21
21
22 </body>
22 </body>
23 </html>
23 </html>
@@ -1,39 +1,39 b''
1 {header}
1 {header}
2 <title>{repo|escape}: Mercurial repositories index</title>
2 <title>{repo|escape}: Mercurial repositories index</title>
3 </head>
3 </head>
4
4
5 <body>
5 <body>
6 <div id="container">
6 <div id="container">
7 <div class="page-header">
7 <div class="page-header">
8 <h1>Mercurial Repositories</h1>
8 <h1>Mercurial Repositories</h1>
9 <ul class="page-nav">
9 <ul class="page-nav">
10 </ul>
10 </ul>
11 </div>
11 </div>
12
12
13 <table cellspacing="0">
13 <table cellspacing="0">
14 <tr>
14 <tr>
15 <td><a href="?sort={sort_name}">Name</a></td>
15 <td><a href="?sort={sort_name}">Name</a></td>
16 <td><a href="?sort={sort_description}">Description</a></td>
16 <td><a href="?sort={sort_description}">Description</a></td>
17 <td><a href="?sort={sort_contact}">Contact</a></td>
17 <td><a href="?sort={sort_contact}">Contact</a></td>
18 <td><a href="?sort={sort_lastchange}">Last modified</a></td>
18 <td><a href="?sort={sort_lastchange}">Last modified</a></td>
19 <td>&nbsp;</td>
19 <td>&nbsp;</td>
20 <td>&nbsp;</td>
20 <td>&nbsp;</td>
21 </tr>
21 </tr>
22 {entries%indexentry}
22 {entries%indexentry}
23 </table>
23 </table>
24 <div class="page-footer">
24 <div class="page-footer">
25 {motd}
25 {motd}
26 </div>
26 </div>
27
27
28 <div id="powered-by">
28 <div id="powered-by">
29 <p><a href="{logourl}" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
29 <p><a href="{logourl}" title="Mercurial"><img src="{staticurl}{logoimg}" width=75 height=90 border=0 alt="mercurial"></a></p>
30 </div>
30 </div>
31
31
32 <div id="corner-top-left"></div>
32 <div id="corner-top-left"></div>
33 <div id="corner-top-right"></div>
33 <div id="corner-top-right"></div>
34 <div id="corner-bottom-left"></div>
34 <div id="corner-bottom-left"></div>
35 <div id="corner-bottom-right"></div>
35 <div id="corner-bottom-right"></div>
36
36
37 </div>
37 </div>
38 </body>
38 </body>
39 </html>
39 </html>
@@ -1,49 +1,49 b''
1 {header}
1 {header}
2 <title>{repo|escape}: bookmarks</title>
2 <title>{repo|escape}: bookmarks</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-bookmarks" title="Atom feed for {repo|escape}: bookmarks" />
4 href="{url}atom-bookmarks" title="Atom feed for {repo|escape}: bookmarks" />
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url}rss-bookmarks" title="RSS feed for {repo|escape}: bookmarks" />
6 href="{url}rss-bookmarks" title="RSS feed for {repo|escape}: bookmarks" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li class="active">bookmarks</li>
20 <li class="active">bookmarks</li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
24 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
25 </ul>
25 </ul>
26 </div>
26 </div>
27
27
28 <div class="main">
28 <div class="main">
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
30 <h3>bookmarks</h3>
30 <h3>bookmarks</h3>
31
31
32 <form class="search" action="{url}log">
32 <form class="search" action="{url}log">
33 {sessionvars%hiddenformentry}
33 {sessionvars%hiddenformentry}
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
35 <div id="hint">find changesets by author, revision,
35 <div id="hint">find changesets by author, revision,
36 files, or words in the commit message</div>
36 files, or words in the commit message</div>
37 </form>
37 </form>
38
38
39 <table class="bigtable">
39 <table class="bigtable">
40 <tr>
40 <tr>
41 <th>bookmark</th>
41 <th>bookmark</th>
42 <th>node</th>
42 <th>node</th>
43 </tr>
43 </tr>
44 {entries%bookmarkentry}
44 {entries%bookmarkentry}
45 </table>
45 </table>
46 </div>
46 </div>
47 </div>
47 </div>
48
48
49 {footer}
49 {footer}
@@ -1,60 +1,60 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}atom-tags" title="Atom feed for {repo|escape}: branches" />
4 href="{url}atom-tags" title="Atom feed for {repo|escape}: branches" />
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url}rss-tags" title="RSS feed for {repo|escape}: branches" />
6 href="{url}rss-tags" title="RSS feed for {repo|escape}: branches" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li class="active">branches</li>
21 <li class="active">branches</li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
24 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
25 </ul>
25 </ul>
26 </div>
26 </div>
27
27
28 <div class="main">
28 <div class="main">
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
30 <h3>branches</h3>
30 <h3>branches</h3>
31
31
32 <form class="search" action="{url}log">
32 <form class="search" action="{url}log">
33 {sessionvars%hiddenformentry}
33 {sessionvars%hiddenformentry}
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
35 <div id="hint">find changesets by author, revision,
35 <div id="hint">find changesets by author, revision,
36 files, or words in the commit message</div>
36 files, or words in the commit message</div>
37 </form>
37 </form>
38
38
39 <table class="bigtable">
39 <table class="bigtable">
40 <tr>
40 <tr>
41 <th>branch</th>
41 <th>branch</th>
42 <th>node</th>
42 <th>node</th>
43 </tr>
43 </tr>
44 {entries %
44 {entries %
45 ' <tr class="tagEntry parity{parity}">
45 ' <tr class="tagEntry parity{parity}">
46 <td>
46 <td>
47 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
47 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
48 {branch|escape}
48 {branch|escape}
49 </a>
49 </a>
50 </td>
50 </td>
51 <td class="node">
51 <td class="node">
52 {node|short}
52 {node|short}
53 </td>
53 </td>
54 </tr>'
54 </tr>'
55 }
55 }
56 </table>
56 </table>
57 </div>
57 </div>
58 </div>
58 </div>
59
59
60 {footer}
60 {footer}
@@ -1,87 +1,87 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {node|short}</title>
2 <title>{repo|escape}: {node|short}</title>
3 </head>
3 </head>
4 <body>
4 <body>
5 <div class="container">
5 <div class="container">
6 <div class="menu">
6 <div class="menu">
7 <div class="logo">
7 <div class="logo">
8 <a href="{logourl}">
8 <a href="{logourl}">
9 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
9 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
10 </div>
10 </div>
11 <ul>
11 <ul>
12 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
12 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
13 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
14 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
15 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
16 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 </ul>
17 </ul>
18 <ul>
18 <ul>
19 <li class="active">changeset</li>
19 <li class="active">changeset</li>
20 <li><a href="{url}raw-rev/{node|short}{sessionvars%urlparameter}">raw</a></li>
20 <li><a href="{url}raw-rev/{node|short}{sessionvars%urlparameter}">raw</a></li>
21 <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">browse</a></li>
21 <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">browse</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 {archives%archiveentry}
24 {archives%archiveentry}
25 </ul>
25 </ul>
26 <ul>
26 <ul>
27 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
27 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
28 </ul>
28 </ul>
29 </div>
29 </div>
30
30
31 <div class="main">
31 <div class="main">
32
32
33 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
33 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
34 <h3>changeset {rev}:{node|short} {changesetbranch%changelogbranchname} {changesettag} {changesetbookmark}</h3>
34 <h3>changeset {rev}:{node|short} {changesetbranch%changelogbranchname} {changesettag} {changesetbookmark}</h3>
35
35
36 <form class="search" action="{url}log">
36 <form class="search" action="{url}log">
37 {sessionvars%hiddenformentry}
37 {sessionvars%hiddenformentry}
38 <p><input name="rev" id="search1" type="text" size="30" /></p>
38 <p><input name="rev" id="search1" type="text" size="30" /></p>
39 <div id="hint">find changesets by author, revision,
39 <div id="hint">find changesets by author, revision,
40 files, or words in the commit message</div>
40 files, or words in the commit message</div>
41 </form>
41 </form>
42
42
43 <div class="description">{desc|strip|escape|nonempty}</div>
43 <div class="description">{desc|strip|escape|nonempty}</div>
44
44
45 <table id="changesetEntry">
45 <table id="changesetEntry">
46 <tr>
46 <tr>
47 <th class="author">author</th>
47 <th class="author">author</th>
48 <td class="author">{author|obfuscate}</td>
48 <td class="author">{author|obfuscate}</td>
49 </tr>
49 </tr>
50 <tr>
50 <tr>
51 <th class="date">date</th>
51 <th class="date">date</th>
52 <td class="date age">{date|date}</td></tr>
52 <td class="date age">{date|date}</td></tr>
53 <tr>
53 <tr>
54 <th class="author">parents</th>
54 <th class="author">parents</th>
55 <td class="author">{parent%changesetparent}</td>
55 <td class="author">{parent%changesetparent}</td>
56 </tr>
56 </tr>
57 <tr>
57 <tr>
58 <th class="author">children</th>
58 <th class="author">children</th>
59 <td class="author">{child%changesetchild}</td>
59 <td class="author">{child%changesetchild}</td>
60 </tr>
60 </tr>
61 <tr>
61 <tr>
62 <th class="files">files</th>
62 <th class="files">files</th>
63 <td class="files">{files}</td>
63 <td class="files">{files}</td>
64 </tr>
64 </tr>
65 <tr>
65 <tr>
66 <th class="diffstat">diffstat</th>
66 <th class="diffstat">diffstat</th>
67 <td class="diffstat">
67 <td class="diffstat">
68 {diffsummary}
68 {diffsummary}
69 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
69 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
70 <div id="diffstatdetails" style="display:none;">
70 <div id="diffstatdetails" style="display:none;">
71 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
71 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
72 <p>
72 <p>
73 <table>{diffstat}</table>
73 <table>{diffstat}</table>
74 </div>
74 </div>
75 </td>
75 </td>
76 </tr>
76 </tr>
77 </table>
77 </table>
78
78
79 <div class="overflow">
79 <div class="overflow">
80 <div class="sourcefirst"> line diff</div>
80 <div class="sourcefirst"> line diff</div>
81
81
82 {diff}
82 {diff}
83 </div>
83 </div>
84
84
85 </div>
85 </div>
86 </div>
86 </div>
87 {footer}
87 {footer}
@@ -1,45 +1,45 b''
1 {header}
1 {header}
2 <title>{repo|escape}: error</title>
2 <title>{repo|escape}: error</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}hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
10 <img src="{staticurl}{logoimg}" width=75 height=90 border=0 alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
18 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
18 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
19 </ul>
19 </ul>
20 </div>
20 </div>
21
21
22 <div class="main">
22 <div class="main">
23
23
24 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
24 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
25 <h3>error</h3>
25 <h3>error</h3>
26
26
27 <form class="search" action="{url}log">
27 <form class="search" action="{url}log">
28 {sessionvars%hiddenformentry}
28 {sessionvars%hiddenformentry}
29 <p><input name="rev" id="search1" type="text" size="30"></p>
29 <p><input name="rev" id="search1" type="text" size="30"></p>
30 <div id="hint">find changesets by author, revision,
30 <div id="hint">find changesets by author, revision,
31 files, or words in the commit message</div>
31 files, or words in the commit message</div>
32 </form>
32 </form>
33
33
34 <div class="description">
34 <div class="description">
35 <p>
35 <p>
36 An error occurred while processing your request:
36 An error occurred while processing your request:
37 </p>
37 </p>
38 <p>
38 <p>
39 {error|escape}
39 {error|escape}
40 </p>
40 </p>
41 </div>
41 </div>
42 </div>
42 </div>
43 </div>
43 </div>
44
44
45 {footer}
45 {footer}
@@ -1,82 +1,82 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {file|escape} annotate</title>
2 <title>{repo|escape}: {file|escape} annotate</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}hglogo.png" alt="mercurial" /></a>
10 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
18 </ul>
18 </ul>
19
19
20 <ul>
20 <ul>
21 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
21 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
22 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
22 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
23 </ul>
23 </ul>
24 <ul>
24 <ul>
25 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
25 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
26 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
26 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
27 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
27 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
28 <li class="active">annotate</li>
28 <li class="active">annotate</li>
29 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
29 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
30 <li><a href="{url}raw-annotate/{node|short}/{file|urlescape}">raw</a></li>
30 <li><a href="{url}raw-annotate/{node|short}/{file|urlescape}">raw</a></li>
31 </ul>
31 </ul>
32 <ul>
32 <ul>
33 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
33 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
34 </ul>
34 </ul>
35 </div>
35 </div>
36
36
37 <div class="main">
37 <div class="main">
38 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
38 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
39 <h3>annotate {file|escape} @ {rev}:{node|short}</h3>
39 <h3>annotate {file|escape} @ {rev}:{node|short}</h3>
40
40
41 <form class="search" action="{url}log">
41 <form class="search" action="{url}log">
42 {sessionvars%hiddenformentry}
42 {sessionvars%hiddenformentry}
43 <p><input name="rev" id="search1" type="text" size="30" /></p>
43 <p><input name="rev" id="search1" type="text" size="30" /></p>
44 <div id="hint">find changesets by author, revision,
44 <div id="hint">find changesets by author, revision,
45 files, or words in the commit message</div>
45 files, or words in the commit message</div>
46 </form>
46 </form>
47
47
48 <div class="description">{desc|strip|escape|nonempty}</div>
48 <div class="description">{desc|strip|escape|nonempty}</div>
49
49
50 <table id="changesetEntry">
50 <table id="changesetEntry">
51 <tr>
51 <tr>
52 <th class="author">author</th>
52 <th class="author">author</th>
53 <td class="author">{author|obfuscate}</td>
53 <td class="author">{author|obfuscate}</td>
54 </tr>
54 </tr>
55 <tr>
55 <tr>
56 <th class="date">date</th>
56 <th class="date">date</th>
57 <td class="date age">{date|date}</td>
57 <td class="date age">{date|date}</td>
58 </tr>
58 </tr>
59 <tr>
59 <tr>
60 <th class="author">parents</th>
60 <th class="author">parents</th>
61 <td class="author">{parent%filerevparent}</td>
61 <td class="author">{parent%filerevparent}</td>
62 </tr>
62 </tr>
63 <tr>
63 <tr>
64 <th class="author">children</th>
64 <th class="author">children</th>
65 <td class="author">{child%filerevchild}</td>
65 <td class="author">{child%filerevchild}</td>
66 </tr>
66 </tr>
67 {changesettag}
67 {changesettag}
68 </table>
68 </table>
69
69
70 <div class="overflow">
70 <div class="overflow">
71 <table class="bigtable">
71 <table class="bigtable">
72 <tr>
72 <tr>
73 <th class="annotate">rev</th>
73 <th class="annotate">rev</th>
74 <th class="line">&nbsp;&nbsp;line source</th>
74 <th class="line">&nbsp;&nbsp;line source</th>
75 </tr>
75 </tr>
76 {annotate%annotateline}
76 {annotate%annotateline}
77 </table>
77 </table>
78 </div>
78 </div>
79 </div>
79 </div>
80 </div>
80 </div>
81
81
82 {footer}
82 {footer}
@@ -1,77 +1,77 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {file|escape} diff</title>
2 <title>{repo|escape}: {file|escape} diff</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}hglogo.png" alt="mercurial" /></a>
10 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
18 </ul>
18 </ul>
19 <ul>
19 <ul>
20 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
20 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
21 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
21 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
24 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
25 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
25 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
26 <li class="active">diff</li>
26 <li class="active">diff</li>
27 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
27 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
28 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
28 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
29 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
29 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
30 </ul>
30 </ul>
31 <ul>
31 <ul>
32 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
32 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
33 </ul>
33 </ul>
34 </div>
34 </div>
35
35
36 <div class="main">
36 <div class="main">
37 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
37 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
38 <h3>diff {file|escape} @ {rev}:{node|short}</h3>
38 <h3>diff {file|escape} @ {rev}:{node|short}</h3>
39
39
40 <form class="search" action="{url}log">
40 <form class="search" action="{url}log">
41 <p>{sessionvars%hiddenformentry}</p>
41 <p>{sessionvars%hiddenformentry}</p>
42 <p><input name="rev" id="search1" type="text" size="30" /></p>
42 <p><input name="rev" id="search1" type="text" size="30" /></p>
43 <div id="hint">find changesets by author, revision,
43 <div id="hint">find changesets by author, revision,
44 files, or words in the commit message</div>
44 files, or words in the commit message</div>
45 </form>
45 </form>
46
46
47 <div class="description">{desc|strip|escape|nonempty}</div>
47 <div class="description">{desc|strip|escape|nonempty}</div>
48
48
49 <table id="changesetEntry">
49 <table id="changesetEntry">
50 <tr>
50 <tr>
51 <th>author</th>
51 <th>author</th>
52 <td>{author|obfuscate}</td>
52 <td>{author|obfuscate}</td>
53 </tr>
53 </tr>
54 <tr>
54 <tr>
55 <th>date</th>
55 <th>date</th>
56 <td class="date age">{date|date}</td>
56 <td class="date age">{date|date}</td>
57 </tr>
57 </tr>
58 <tr>
58 <tr>
59 <th>parents</th>
59 <th>parents</th>
60 <td>{parent%filerevparent}</td>
60 <td>{parent%filerevparent}</td>
61 </tr>
61 </tr>
62 <tr>
62 <tr>
63 <th>children</th>
63 <th>children</th>
64 <td>{child%filerevchild}</td>
64 <td>{child%filerevchild}</td>
65 </tr>
65 </tr>
66 {changesettag}
66 {changesettag}
67 </table>
67 </table>
68
68
69 <div class="overflow">
69 <div class="overflow">
70 <div class="sourcefirst"> line diff</div>
70 <div class="sourcefirst"> line diff</div>
71
71
72 {diff}
72 {diff}
73 </div>
73 </div>
74 </div>
74 </div>
75 </div>
75 </div>
76
76
77 {footer}
77 {footer}
@@ -1,73 +1,73 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {file|escape} history</title>
2 <title>{repo|escape}: {file|escape} history</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-log/tip/{file|urlescape}" title="Atom feed for {repo|escape}:{file}" />
4 href="{url}atom-log/tip/{file|urlescape}" title="Atom feed for {repo|escape}:{file}" />
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url}rss-log/tip/{file|urlescape}" title="RSS feed for {repo|escape}:{file}" />
6 href="{url}rss-log/tip/{file|urlescape}" title="RSS feed for {repo|escape}:{file}" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
17 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
24 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
25 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
25 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
26 </ul>
26 </ul>
27 <ul>
27 <ul>
28 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
28 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
29 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
29 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
30 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
30 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
31 <li class="active">file log</li>
31 <li class="active">file log</li>
32 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
32 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
33 </ul>
33 </ul>
34 <ul>
34 <ul>
35 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
35 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
36 </ul>
36 </ul>
37 </div>
37 </div>
38
38
39 <div class="main">
39 <div class="main">
40 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
40 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
41 <h3>log {file|escape}</h3>
41 <h3>log {file|escape}</h3>
42
42
43 <form class="search" action="{url}log">
43 <form class="search" action="{url}log">
44 {sessionvars%hiddenformentry}
44 {sessionvars%hiddenformentry}
45 <p><input name="rev" id="search1" type="text" size="30" /></p>
45 <p><input name="rev" id="search1" type="text" size="30" /></p>
46 <div id="hint">find changesets by author, revision,
46 <div id="hint">find changesets by author, revision,
47 files, or words in the commit message</div>
47 files, or words in the commit message</div>
48 </form>
48 </form>
49
49
50 <div class="navigate">
50 <div class="navigate">
51 <a href="{url}log/{node|short}/{file|urlescape}{lessvars%urlparameter}">less</a>
51 <a href="{url}log/{node|short}/{file|urlescape}{lessvars%urlparameter}">less</a>
52 <a href="{url}log/{node|short}/{file|urlescape}{morevars%urlparameter}">more</a>
52 <a href="{url}log/{node|short}/{file|urlescape}{morevars%urlparameter}">more</a>
53 | {nav%filenav}</div>
53 | {nav%filenav}</div>
54
54
55 <table class="bigtable">
55 <table class="bigtable">
56 <tr>
56 <tr>
57 <th class="age">age</th>
57 <th class="age">age</th>
58 <th class="author">author</th>
58 <th class="author">author</th>
59 <th class="description">description</th>
59 <th class="description">description</th>
60 </tr>
60 </tr>
61 {entries%filelogentry}
61 {entries%filelogentry}
62 </table>
62 </table>
63
63
64 <div class="navigate">
64 <div class="navigate">
65 <a href="{url}log/{node|short}/{file|urlescape}{lessvars%urlparameter}">less</a>
65 <a href="{url}log/{node|short}/{file|urlescape}{lessvars%urlparameter}">less</a>
66 <a href="{url}log/{node|short}/{file|urlescape}{morevars%urlparameter}">more</a>
66 <a href="{url}log/{node|short}/{file|urlescape}{morevars%urlparameter}">more</a>
67 | {nav%filenav}
67 | {nav%filenav}
68 </div>
68 </div>
69
69
70 </div>
70 </div>
71 </div>
71 </div>
72
72
73 {footer}
73 {footer}
@@ -1,76 +1,76 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {node|short} {file|escape}</title>
2 <title>{repo|escape}: {node|short} {file|escape}</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}hglogo.png" alt="mercurial" /></a>
10 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
16 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 </ul>
17 </ul>
18 <ul>
18 <ul>
19 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
19 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
20 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
20 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
21 </ul>
21 </ul>
22 <ul>
22 <ul>
23 <li class="active">file</li>
23 <li class="active">file</li>
24 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
24 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
25 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
25 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
26 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
26 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
27 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
27 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
28 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
28 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
29 </ul>
29 </ul>
30 <ul>
30 <ul>
31 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
31 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
32 </ul>
32 </ul>
33 </div>
33 </div>
34
34
35 <div class="main">
35 <div class="main">
36 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
36 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
37 <h3>view {file|escape} @ {rev}:{node|short}</h3>
37 <h3>view {file|escape} @ {rev}:{node|short}</h3>
38
38
39 <form class="search" action="{url}log">
39 <form class="search" action="{url}log">
40 {sessionvars%hiddenformentry}
40 {sessionvars%hiddenformentry}
41 <p><input name="rev" id="search1" type="text" size="30" /></p>
41 <p><input name="rev" id="search1" type="text" size="30" /></p>
42 <div id="hint">find changesets by author, revision,
42 <div id="hint">find changesets by author, revision,
43 files, or words in the commit message</div>
43 files, or words in the commit message</div>
44 </form>
44 </form>
45
45
46 <div class="description">{desc|strip|escape|nonempty}</div>
46 <div class="description">{desc|strip|escape|nonempty}</div>
47
47
48 <table id="changesetEntry">
48 <table id="changesetEntry">
49 <tr>
49 <tr>
50 <th class="author">author</th>
50 <th class="author">author</th>
51 <td class="author">{author|obfuscate}</td>
51 <td class="author">{author|obfuscate}</td>
52 </tr>
52 </tr>
53 <tr>
53 <tr>
54 <th class="date">date</th>
54 <th class="date">date</th>
55 <td class="date age">{date|date}</td>
55 <td class="date age">{date|date}</td>
56 </tr>
56 </tr>
57 <tr>
57 <tr>
58 <th class="author">parents</th>
58 <th class="author">parents</th>
59 <td class="author">{parent%filerevparent}</td>
59 <td class="author">{parent%filerevparent}</td>
60 </tr>
60 </tr>
61 <tr>
61 <tr>
62 <th class="author">children</th>
62 <th class="author">children</th>
63 <td class="author">{child%filerevchild}</td>
63 <td class="author">{child%filerevchild}</td>
64 </tr>
64 </tr>
65 {changesettag}
65 {changesettag}
66 </table>
66 </table>
67
67
68 <div class="overflow">
68 <div class="overflow">
69 <div class="sourcefirst"> line source</div>
69 <div class="sourcefirst"> line source</div>
70 {text%fileline}
70 {text%fileline}
71 <div class="sourcelast"></div>
71 <div class="sourcelast"></div>
72 </div>
72 </div>
73 </div>
73 </div>
74 </div>
74 </div>
75
75
76 {footer}
76 {footer}
@@ -1,141 +1,141 b''
1 {header}
1 {header}
2 <title>{repo|escape}: revision graph</title>
2 <title>{repo|escape}: revision graph</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-log" title="Atom feed for {repo|escape}: log" />
4 href="{url}atom-log" title="Atom feed for {repo|escape}: log" />
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url}rss-log" title="RSS feed for {repo|escape}: log" />
6 href="{url}rss-log" title="RSS feed for {repo|escape}: log" />
7 <!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
7 <!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
8 </head>
8 </head>
9 <body>
9 <body>
10
10
11 <div class="container">
11 <div class="container">
12 <div class="menu">
12 <div class="menu">
13 <div class="logo">
13 <div class="logo">
14 <a href="{logourl}">
14 <a href="{logourl}">
15 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
15 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
16 </div>
16 </div>
17 <ul>
17 <ul>
18 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
19 <li class="active">graph</li>
19 <li class="active">graph</li>
20 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
21 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
22 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
23 </ul>
23 </ul>
24 <ul>
24 <ul>
25 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
25 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
26 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
26 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
27 </ul>
27 </ul>
28 <ul>
28 <ul>
29 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
29 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
30 </ul>
30 </ul>
31 </div>
31 </div>
32
32
33 <div class="main">
33 <div class="main">
34 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
34 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
35 <h3>graph</h3>
35 <h3>graph</h3>
36
36
37 <form class="search" action="{url}log">
37 <form class="search" action="{url}log">
38 {sessionvars%hiddenformentry}
38 {sessionvars%hiddenformentry}
39 <p><input name="rev" id="search1" type="text" size="30" /></p>
39 <p><input name="rev" id="search1" type="text" size="30" /></p>
40 <div id="hint">find changesets by author, revision,
40 <div id="hint">find changesets by author, revision,
41 files, or words in the commit message</div>
41 files, or words in the commit message</div>
42 </form>
42 </form>
43
43
44 <div class="navigate">
44 <div class="navigate">
45 <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
45 <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
46 <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
46 <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
47 | rev {rev}: {changenav%navgraph}
47 | rev {rev}: {changenav%navgraph}
48 </div>
48 </div>
49
49
50 <noscript><p>The revision graph only works with JavaScript-enabled browsers.</p></noscript>
50 <noscript><p>The revision graph only works with JavaScript-enabled browsers.</p></noscript>
51
51
52 <div id="wrapper">
52 <div id="wrapper">
53 <ul id="nodebgs"></ul>
53 <ul id="nodebgs"></ul>
54 <canvas id="graph" width="480" height="{canvasheight}"></canvas>
54 <canvas id="graph" width="480" height="{canvasheight}"></canvas>
55 <ul id="graphnodes"></ul>
55 <ul id="graphnodes"></ul>
56 </div>
56 </div>
57
57
58 <script type="text/javascript">
58 <script type="text/javascript">
59 <!-- hide script content
59 <!-- hide script content
60
60
61 var data = {jsdata|json};
61 var data = {jsdata|json};
62 var graph = new Graph();
62 var graph = new Graph();
63 graph.scale({bg_height});
63 graph.scale({bg_height});
64
64
65 graph.edge = function(x0, y0, x1, y1, color) \{
65 graph.edge = function(x0, y0, x1, y1, color) \{
66
66
67 this.setColor(color, 0.0, 0.65);
67 this.setColor(color, 0.0, 0.65);
68 this.ctx.beginPath();
68 this.ctx.beginPath();
69 this.ctx.moveTo(x0, y0);
69 this.ctx.moveTo(x0, y0);
70 this.ctx.lineTo(x1, y1);
70 this.ctx.lineTo(x1, y1);
71 this.ctx.stroke();
71 this.ctx.stroke();
72
72
73 }
73 }
74
74
75 var revlink = '<li style="_STYLE"><span class="desc">';
75 var revlink = '<li style="_STYLE"><span class="desc">';
76 revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
76 revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
77 revlink += '</span>_TAGS<span class="info">_DATE, by _USER</span></li>';
77 revlink += '</span>_TAGS<span class="info">_DATE, by _USER</span></li>';
78
78
79 graph.vertex = function(x, y, color, parity, cur) \{
79 graph.vertex = function(x, y, color, parity, cur) \{
80
80
81 this.ctx.beginPath();
81 this.ctx.beginPath();
82 color = this.setColor(color, 0.25, 0.75);
82 color = this.setColor(color, 0.25, 0.75);
83 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
83 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
84 this.ctx.fill();
84 this.ctx.fill();
85
85
86 var bg = '<li class="bg parity' + parity + '"></li>';
86 var bg = '<li class="bg parity' + parity + '"></li>';
87 var left = (this.columns + 1) * this.bg_height;
87 var left = (this.columns + 1) * this.bg_height;
88 var nstyle = 'padding-left: ' + left + 'px;';
88 var nstyle = 'padding-left: ' + left + 'px;';
89 var item = revlink.replace(/_STYLE/, nstyle);
89 var item = revlink.replace(/_STYLE/, nstyle);
90 item = item.replace(/_PARITY/, 'parity' + parity);
90 item = item.replace(/_PARITY/, 'parity' + parity);
91 item = item.replace(/_NODEID/, cur[0]);
91 item = item.replace(/_NODEID/, cur[0]);
92 item = item.replace(/_NODEID/, cur[0]);
92 item = item.replace(/_NODEID/, cur[0]);
93 item = item.replace(/_DESC/, cur[3]);
93 item = item.replace(/_DESC/, cur[3]);
94 item = item.replace(/_USER/, cur[4]);
94 item = item.replace(/_USER/, cur[4]);
95 item = item.replace(/_DATE/, cur[5]);
95 item = item.replace(/_DATE/, cur[5]);
96
96
97 var tagspan = '';
97 var tagspan = '';
98 if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) \{
98 if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) \{
99 tagspan = '<span class="logtags">';
99 tagspan = '<span class="logtags">';
100 if (cur[6][1]) \{
100 if (cur[6][1]) \{
101 tagspan += '<span class="branchhead" title="' + cur[6][0] + '">';
101 tagspan += '<span class="branchhead" title="' + cur[6][0] + '">';
102 tagspan += cur[6][0] + '</span> ';
102 tagspan += cur[6][0] + '</span> ';
103 } else if (!cur[6][1] && cur[6][0] != 'default') \{
103 } else if (!cur[6][1] && cur[6][0] != 'default') \{
104 tagspan += '<span class="branchname" title="' + cur[6][0] + '">';
104 tagspan += '<span class="branchname" title="' + cur[6][0] + '">';
105 tagspan += cur[6][0] + '</span> ';
105 tagspan += cur[6][0] + '</span> ';
106 }
106 }
107 if (cur[7].length) \{
107 if (cur[7].length) \{
108 for (var t in cur[7]) \{
108 for (var t in cur[7]) \{
109 var tag = cur[7][t];
109 var tag = cur[7][t];
110 tagspan += '<span class="tag">' + tag + '</span> ';
110 tagspan += '<span class="tag">' + tag + '</span> ';
111 }
111 }
112 }
112 }
113 if (cur[8].length) \{
113 if (cur[8].length) \{
114 for (var b in cur[8]) \{
114 for (var b in cur[8]) \{
115 var bookmark = cur[8][b];
115 var bookmark = cur[8][b];
116 tagspan += '<span class="tag">' + bookmark + '</span> ';
116 tagspan += '<span class="tag">' + bookmark + '</span> ';
117 }
117 }
118 }
118 }
119 tagspan += '</span>';
119 tagspan += '</span>';
120 }
120 }
121
121
122 item = item.replace(/_TAGS/, tagspan);
122 item = item.replace(/_TAGS/, tagspan);
123 return [bg, item];
123 return [bg, item];
124
124
125 }
125 }
126
126
127 graph.render(data);
127 graph.render(data);
128
128
129 // stop hiding script -->
129 // stop hiding script -->
130 </script>
130 </script>
131
131
132 <div class="navigate">
132 <div class="navigate">
133 <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
133 <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
134 <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
134 <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
135 | rev {rev}: {changenav%navgraph}
135 | rev {rev}: {changenav%navgraph}
136 </div>
136 </div>
137
137
138 </div>
138 </div>
139 </div>
139 </div>
140
140
141 {footer}
141 {footer}
@@ -1,44 +1,44 b''
1 {header}
1 {header}
2 <title>Help: {topic}</title>
2 <title>Help: {topic}</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-tags" title="Atom feed for {repo|escape}" />
4 href="{url}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}rss-tags" title="RSS feed for {repo|escape}" />
6 href="{url}rss-tags" title="RSS feed for {repo|escape}" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li class="active">help</li>
24 <li class="active">help</li>
25 </ul>
25 </ul>
26 </div>
26 </div>
27
27
28 <div class="main">
28 <div class="main">
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
30 <h3>Help: {topic}</h3>
30 <h3>Help: {topic}</h3>
31
31
32 <form class="search" action="{url}log">
32 <form class="search" action="{url}log">
33 {sessionvars%hiddenformentry}
33 {sessionvars%hiddenformentry}
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
35 <div id="hint">find changesets by author, revision,
35 <div id="hint">find changesets by author, revision,
36 files, or words in the commit message</div>
36 files, or words in the commit message</div>
37 </form>
37 </form>
38 <pre>
38 <pre>
39 {doc|escape}
39 {doc|escape}
40 </pre>
40 </pre>
41 </div>
41 </div>
42 </div>
42 </div>
43
43
44 {footer}
44 {footer}
@@ -1,49 +1,49 b''
1 {header}
1 {header}
2 <title>Help: {title}</title>
2 <title>Help: {title}</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-tags" title="Atom feed for {repo|escape}" />
4 href="{url}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}rss-tags" title="RSS feed for {repo|escape}" />
6 href="{url}rss-tags" title="RSS feed for {repo|escape}" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li class="active">help</li>
24 <li class="active">help</li>
25 </ul>
25 </ul>
26 </div>
26 </div>
27
27
28 <div class="main">
28 <div class="main">
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
30 <form class="search" action="{url}log">
30 <form class="search" action="{url}log">
31 {sessionvars%hiddenformentry}
31 {sessionvars%hiddenformentry}
32 <p><input name="rev" id="search1" type="text" size="30" /></p>
32 <p><input name="rev" id="search1" type="text" size="30" /></p>
33 <div id="hint">find changesets by author, revision,
33 <div id="hint">find changesets by author, revision,
34 files, or words in the commit message</div>
34 files, or words in the commit message</div>
35 </form>
35 </form>
36 <table class="bigtable">
36 <table class="bigtable">
37 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
37 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
38 {topics % helpentry}
38 {topics % helpentry}
39
39
40 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
40 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
41 {earlycommands % helpentry}
41 {earlycommands % helpentry}
42
42
43 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
43 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
44 {othercommands % helpentry}
44 {othercommands % helpentry}
45 </table>
45 </table>
46 </div>
46 </div>
47 </div>
47 </div>
48
48
49 {footer}
49 {footer}
@@ -1,26 +1,26 b''
1 {header}
1 {header}
2 <title>Mercurial repositories index</title>
2 <title>Mercurial repositories index</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 <a href="{logourl}">
8 <a href="{logourl}">
9 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
9 <img src="{staticurl}{logoimg}" width=75 height=90 border=0 alt="mercurial" /></a>
10 </div>
10 </div>
11 <div class="main">
11 <div class="main">
12 <h2>Mercurial Repositories</h2>
12 <h2>Mercurial Repositories</h2>
13
13
14 <table class="bigtable">
14 <table class="bigtable">
15 <tr>
15 <tr>
16 <th><a href="?sort={sort_name}">Name</a></th>
16 <th><a href="?sort={sort_name}">Name</a></th>
17 <th><a href="?sort={sort_description}">Description</a></th>
17 <th><a href="?sort={sort_description}">Description</a></th>
18 <th><a href="?sort={sort_contact}">Contact</a></th>
18 <th><a href="?sort={sort_contact}">Contact</a></th>
19 <th><a href="?sort={sort_lastchange}">Last modified</a></th>
19 <th><a href="?sort={sort_lastchange}">Last modified</a></th>
20 <th>&nbsp;</th>
20 <th>&nbsp;</th>
21 </tr>
21 </tr>
22 {entries%indexentry}
22 {entries%indexentry}
23 </table>
23 </table>
24 </div>
24 </div>
25 </div>
25 </div>
26 {footer}
26 {footer}
@@ -1,58 +1,58 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {node|short} {path|escape}</title>
2 <title>{repo|escape}: {node|short} {path|escape}</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}hglogo.png" alt="mercurial" /></a>
10 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
18 </ul>
18 </ul>
19 <ul>
19 <ul>
20 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
20 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
21 <li class="active">browse</li>
21 <li class="active">browse</li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 {archives%archiveentry}
24 {archives%archiveentry}
25 </ul>
25 </ul>
26 <ul>
26 <ul>
27 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
27 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
28 </ul>
28 </ul>
29 </div>
29 </div>
30
30
31 <div class="main">
31 <div class="main">
32 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
32 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
33 <h3>directory {path|escape} @ {rev}:{node|short} {tags%changelogtag}</h3>
33 <h3>directory {path|escape} @ {rev}:{node|short} {tags%changelogtag}</h3>
34
34
35 <form class="search" action="{url}log">
35 <form class="search" action="{url}log">
36 {sessionvars%hiddenformentry}
36 {sessionvars%hiddenformentry}
37 <p><input name="rev" id="search1" type="text" size="30" /></p>
37 <p><input name="rev" id="search1" type="text" size="30" /></p>
38 <div id="hint">find changesets by author, revision,
38 <div id="hint">find changesets by author, revision,
39 files, or words in the commit message</div>
39 files, or words in the commit message</div>
40 </form>
40 </form>
41
41
42 <table class="bigtable">
42 <table class="bigtable">
43 <tr>
43 <tr>
44 <th class="name">name</th>
44 <th class="name">name</th>
45 <th class="size">size</th>
45 <th class="size">size</th>
46 <th class="permissions">permissions</th>
46 <th class="permissions">permissions</th>
47 </tr>
47 </tr>
48 <tr class="fileline parity{upparity}">
48 <tr class="fileline parity{upparity}">
49 <td class="name"><a href="{url}file/{node|short}{up|urlescape}{sessionvars%urlparameter}">[up]</a></td>
49 <td class="name"><a href="{url}file/{node|short}{up|urlescape}{sessionvars%urlparameter}">[up]</a></td>
50 <td class="size"></td>
50 <td class="size"></td>
51 <td class="permissions">drwxr-xr-x</td>
51 <td class="permissions">drwxr-xr-x</td>
52 </tr>
52 </tr>
53 {dentries%direntry}
53 {dentries%direntry}
54 {fentries%fileentry}
54 {fentries%fileentry}
55 </table>
55 </table>
56 </div>
56 </div>
57 </div>
57 </div>
58 {footer}
58 {footer}
@@ -1,55 +1,55 b''
1 {header}
1 {header}
2 <title>{repo|escape}: searching for {query|escape}</title>
2 <title>{repo|escape}: searching for {query|escape}</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}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
10 <img src="{staticurl}{logoimg}" width=75 height=90 border=0 alt="mercurial"></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
18 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
18 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
19 </ul>
19 </ul>
20 </div>
20 </div>
21
21
22 <div class="main">
22 <div class="main">
23 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
23 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
24 <h3>searching for '{query|escape}'</h3>
24 <h3>searching for '{query|escape}'</h3>
25
25
26 <form class="search" action="{url}log">
26 <form class="search" action="{url}log">
27 {sessionvars%hiddenformentry}
27 {sessionvars%hiddenformentry}
28 <p><input name="rev" id="search1" type="text" size="30"></p>
28 <p><input name="rev" id="search1" type="text" size="30"></p>
29 <div id="hint">find changesets by author, revision,
29 <div id="hint">find changesets by author, revision,
30 files, or words in the commit message</div>
30 files, or words in the commit message</div>
31 </form>
31 </form>
32
32
33 <div class="navigate">
33 <div class="navigate">
34 <a href="{url}search/{lessvars%urlparameter}">less</a>
34 <a href="{url}search/{lessvars%urlparameter}">less</a>
35 <a href="{url}search/{morevars%urlparameter}">more</a>
35 <a href="{url}search/{morevars%urlparameter}">more</a>
36 </div>
36 </div>
37
37
38 <table class="bigtable">
38 <table class="bigtable">
39 <tr>
39 <tr>
40 <th class="age">age</th>
40 <th class="age">age</th>
41 <th class="author">author</th>
41 <th class="author">author</th>
42 <th class="description">description</th>
42 <th class="description">description</th>
43 </tr>
43 </tr>
44 {entries}
44 {entries}
45 </table>
45 </table>
46
46
47 <div class="navigate">
47 <div class="navigate">
48 <a href="{url}search/{lessvars%urlparameter}">less</a>
48 <a href="{url}search/{lessvars%urlparameter}">less</a>
49 <a href="{url}search/{morevars%urlparameter}">more</a>
49 <a href="{url}search/{morevars%urlparameter}">more</a>
50 </div>
50 </div>
51
51
52 </div>
52 </div>
53 </div>
53 </div>
54
54
55 {footer}
55 {footer}
@@ -1,70 +1,70 b''
1 {header}
1 {header}
2 <title>{repo|escape}: log</title>
2 <title>{repo|escape}: log</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-log" title="Atom feed for {repo|escape}" />
4 href="{url}atom-log" 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}rss-log" title="RSS feed for {repo|escape}" />
6 href="{url}rss-log" title="RSS feed for {repo|escape}" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li class="active">log</li>
17 <li class="active">log</li>
18 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
19 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
24 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
25 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
25 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
26 </ul>
26 </ul>
27 <ul>
27 <ul>
28 {archives%archiveentry}
28 {archives%archiveentry}
29 </ul>
29 </ul>
30 <ul>
30 <ul>
31 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
31 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
32 </ul>
32 </ul>
33 </div>
33 </div>
34
34
35 <div class="main">
35 <div class="main">
36 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
36 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
37 <h3>log</h3>
37 <h3>log</h3>
38
38
39 <form class="search" action="{url}log">
39 <form class="search" action="{url}log">
40 {sessionvars%hiddenformentry}
40 {sessionvars%hiddenformentry}
41 <p><input name="rev" id="search1" type="text" size="30" /></p>
41 <p><input name="rev" id="search1" type="text" size="30" /></p>
42 <div id="hint">find changesets by author, revision,
42 <div id="hint">find changesets by author, revision,
43 files, or words in the commit message</div>
43 files, or words in the commit message</div>
44 </form>
44 </form>
45
45
46 <div class="navigate">
46 <div class="navigate">
47 <a href="{url}shortlog/{rev}{lessvars%urlparameter}">less</a>
47 <a href="{url}shortlog/{rev}{lessvars%urlparameter}">less</a>
48 <a href="{url}shortlog/{rev}{morevars%urlparameter}">more</a>
48 <a href="{url}shortlog/{rev}{morevars%urlparameter}">more</a>
49 | rev {rev}: {changenav%navshort}
49 | rev {rev}: {changenav%navshort}
50 </div>
50 </div>
51
51
52 <table class="bigtable">
52 <table class="bigtable">
53 <tr>
53 <tr>
54 <th class="age">age</th>
54 <th class="age">age</th>
55 <th class="author">author</th>
55 <th class="author">author</th>
56 <th class="description">description</th>
56 <th class="description">description</th>
57 </tr>
57 </tr>
58 {entries%shortlogentry}
58 {entries%shortlogentry}
59 </table>
59 </table>
60
60
61 <div class="navigate">
61 <div class="navigate">
62 <a href="{url}shortlog/{rev}{lessvars%urlparameter}">less</a>
62 <a href="{url}shortlog/{rev}{lessvars%urlparameter}">less</a>
63 <a href="{url}shortlog/{rev}{morevars%urlparameter}">more</a>
63 <a href="{url}shortlog/{rev}{morevars%urlparameter}">more</a>
64 | rev {rev}: {changenav%navshort}
64 | rev {rev}: {changenav%navshort}
65 </div>
65 </div>
66
66
67 </div>
67 </div>
68 </div>
68 </div>
69
69
70 {footer}
70 {footer}
@@ -1,49 +1,49 b''
1 {header}
1 {header}
2 <title>{repo|escape}: tags</title>
2 <title>{repo|escape}: tags</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-tags" title="Atom feed for {repo|escape}: tags" />
4 href="{url}atom-tags" title="Atom feed for {repo|escape}: tags" />
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url}rss-tags" title="RSS feed for {repo|escape}: tags" />
6 href="{url}rss-tags" title="RSS feed for {repo|escape}: tags" />
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="container">
10 <div class="container">
11 <div class="menu">
11 <div class="menu">
12 <div class="logo">
12 <div class="logo">
13 <a href="{logourl}">
13 <a href="{logourl}">
14 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
14 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
15 </div>
15 </div>
16 <ul>
16 <ul>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
17 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
18 <li><a href="{url}graph{sessionvars%urlparameter}">graph</a></li>
19 <li class="active">tags</li>
19 <li class="active">tags</li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
20 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
24 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
25 </ul>
25 </ul>
26 </div>
26 </div>
27
27
28 <div class="main">
28 <div class="main">
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
29 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
30 <h3>tags</h3>
30 <h3>tags</h3>
31
31
32 <form class="search" action="{url}log">
32 <form class="search" action="{url}log">
33 {sessionvars%hiddenformentry}
33 {sessionvars%hiddenformentry}
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
34 <p><input name="rev" id="search1" type="text" size="30" /></p>
35 <div id="hint">find changesets by author, revision,
35 <div id="hint">find changesets by author, revision,
36 files, or words in the commit message</div>
36 files, or words in the commit message</div>
37 </form>
37 </form>
38
38
39 <table class="bigtable">
39 <table class="bigtable">
40 <tr>
40 <tr>
41 <th>tag</th>
41 <th>tag</th>
42 <th>node</th>
42 <th>node</th>
43 </tr>
43 </tr>
44 {entries%tagentry}
44 {entries%tagentry}
45 </table>
45 </table>
46 </div>
46 </div>
47 </div>
47 </div>
48
48
49 {footer}
49 {footer}
@@ -1,9 +1,9 b''
1 <script type="text/javascript">process_dates()</script>
1 <script type="text/javascript">process_dates()</script>
2 {motd}
2 {motd}
3 <div class="logo">
3 <div class="logo">
4 <a href="{logourl}">
4 <a href="{logourl}">
5 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
5 <img src="{staticurl}{logoimg}" width=75 height=90 border=0 alt="mercurial"></a>
6 </div>
6 </div>
7
7
8 </body>
8 </body>
9 </html>
9 </html>
General Comments 0
You need to be logged in to leave comments. Login now