##// END OF EJS Templates
hgweb: map Abort to 403 error to report inaccessible path for example...
Yuya Nishihara -
r39506:17ca967e default
parent child Browse files
Show More
@@ -1,471 +1,475 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 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 import contextlib
11 import contextlib
12 import os
12 import os
13
13
14 from .common import (
14 from .common import (
15 ErrorResponse,
15 ErrorResponse,
16 HTTP_BAD_REQUEST,
16 HTTP_BAD_REQUEST,
17 cspvalues,
17 cspvalues,
18 permhooks,
18 permhooks,
19 statusmessage,
19 statusmessage,
20 )
20 )
21
21
22 from .. import (
22 from .. import (
23 encoding,
23 encoding,
24 error,
24 error,
25 formatter,
25 formatter,
26 hg,
26 hg,
27 hook,
27 hook,
28 profiling,
28 profiling,
29 pycompat,
29 pycompat,
30 registrar,
30 registrar,
31 repoview,
31 repoview,
32 templatefilters,
32 templatefilters,
33 templater,
33 templater,
34 templateutil,
34 templateutil,
35 ui as uimod,
35 ui as uimod,
36 util,
36 util,
37 wireprotoserver,
37 wireprotoserver,
38 )
38 )
39
39
40 from . import (
40 from . import (
41 request as requestmod,
41 request as requestmod,
42 webcommands,
42 webcommands,
43 webutil,
43 webutil,
44 wsgicgi,
44 wsgicgi,
45 )
45 )
46
46
47 def getstyle(req, configfn, templatepath):
47 def getstyle(req, configfn, templatepath):
48 styles = (
48 styles = (
49 req.qsparams.get('style', None),
49 req.qsparams.get('style', None),
50 configfn('web', 'style'),
50 configfn('web', 'style'),
51 'paper',
51 'paper',
52 )
52 )
53 return styles, templater.stylemap(styles, templatepath)
53 return styles, templater.stylemap(styles, templatepath)
54
54
55 def makebreadcrumb(url, prefix=''):
55 def makebreadcrumb(url, prefix=''):
56 '''Return a 'URL breadcrumb' list
56 '''Return a 'URL breadcrumb' list
57
57
58 A 'URL breadcrumb' is a list of URL-name pairs,
58 A 'URL breadcrumb' is a list of URL-name pairs,
59 corresponding to each of the path items on a URL.
59 corresponding to each of the path items on a URL.
60 This can be used to create path navigation entries.
60 This can be used to create path navigation entries.
61 '''
61 '''
62 if url.endswith('/'):
62 if url.endswith('/'):
63 url = url[:-1]
63 url = url[:-1]
64 if prefix:
64 if prefix:
65 url = '/' + prefix + url
65 url = '/' + prefix + url
66 relpath = url
66 relpath = url
67 if relpath.startswith('/'):
67 if relpath.startswith('/'):
68 relpath = relpath[1:]
68 relpath = relpath[1:]
69
69
70 breadcrumb = []
70 breadcrumb = []
71 urlel = url
71 urlel = url
72 pathitems = [''] + relpath.split('/')
72 pathitems = [''] + relpath.split('/')
73 for pathel in reversed(pathitems):
73 for pathel in reversed(pathitems):
74 if not pathel or not urlel:
74 if not pathel or not urlel:
75 break
75 break
76 breadcrumb.append({'url': urlel, 'name': pathel})
76 breadcrumb.append({'url': urlel, 'name': pathel})
77 urlel = os.path.dirname(urlel)
77 urlel = os.path.dirname(urlel)
78 return templateutil.mappinglist(reversed(breadcrumb))
78 return templateutil.mappinglist(reversed(breadcrumb))
79
79
80 class requestcontext(object):
80 class requestcontext(object):
81 """Holds state/context for an individual request.
81 """Holds state/context for an individual request.
82
82
83 Servers can be multi-threaded. Holding state on the WSGI application
83 Servers can be multi-threaded. Holding state on the WSGI application
84 is prone to race conditions. Instances of this class exist to hold
84 is prone to race conditions. Instances of this class exist to hold
85 mutable and race-free state for requests.
85 mutable and race-free state for requests.
86 """
86 """
87 def __init__(self, app, repo, req, res):
87 def __init__(self, app, repo, req, res):
88 self.repo = repo
88 self.repo = repo
89 self.reponame = app.reponame
89 self.reponame = app.reponame
90 self.req = req
90 self.req = req
91 self.res = res
91 self.res = res
92
92
93 self.maxchanges = self.configint('web', 'maxchanges')
93 self.maxchanges = self.configint('web', 'maxchanges')
94 self.stripecount = self.configint('web', 'stripes')
94 self.stripecount = self.configint('web', 'stripes')
95 self.maxshortchanges = self.configint('web', 'maxshortchanges')
95 self.maxshortchanges = self.configint('web', 'maxshortchanges')
96 self.maxfiles = self.configint('web', 'maxfiles')
96 self.maxfiles = self.configint('web', 'maxfiles')
97 self.allowpull = self.configbool('web', 'allow-pull')
97 self.allowpull = self.configbool('web', 'allow-pull')
98
98
99 # we use untrusted=False to prevent a repo owner from using
99 # we use untrusted=False to prevent a repo owner from using
100 # web.templates in .hg/hgrc to get access to any file readable
100 # web.templates in .hg/hgrc to get access to any file readable
101 # by the user running the CGI script
101 # by the user running the CGI script
102 self.templatepath = self.config('web', 'templates', untrusted=False)
102 self.templatepath = self.config('web', 'templates', untrusted=False)
103
103
104 # This object is more expensive to build than simple config values.
104 # This object is more expensive to build than simple config values.
105 # It is shared across requests. The app will replace the object
105 # It is shared across requests. The app will replace the object
106 # if it is updated. Since this is a reference and nothing should
106 # if it is updated. Since this is a reference and nothing should
107 # modify the underlying object, it should be constant for the lifetime
107 # modify the underlying object, it should be constant for the lifetime
108 # of the request.
108 # of the request.
109 self.websubtable = app.websubtable
109 self.websubtable = app.websubtable
110
110
111 self.csp, self.nonce = cspvalues(self.repo.ui)
111 self.csp, self.nonce = cspvalues(self.repo.ui)
112
112
113 # Trust the settings from the .hg/hgrc files by default.
113 # Trust the settings from the .hg/hgrc files by default.
114 def config(self, section, name, default=uimod._unset, untrusted=True):
114 def config(self, section, name, default=uimod._unset, untrusted=True):
115 return self.repo.ui.config(section, name, default,
115 return self.repo.ui.config(section, name, default,
116 untrusted=untrusted)
116 untrusted=untrusted)
117
117
118 def configbool(self, section, name, default=uimod._unset, untrusted=True):
118 def configbool(self, section, name, default=uimod._unset, untrusted=True):
119 return self.repo.ui.configbool(section, name, default,
119 return self.repo.ui.configbool(section, name, default,
120 untrusted=untrusted)
120 untrusted=untrusted)
121
121
122 def configint(self, section, name, default=uimod._unset, untrusted=True):
122 def configint(self, section, name, default=uimod._unset, untrusted=True):
123 return self.repo.ui.configint(section, name, default,
123 return self.repo.ui.configint(section, name, default,
124 untrusted=untrusted)
124 untrusted=untrusted)
125
125
126 def configlist(self, section, name, default=uimod._unset, untrusted=True):
126 def configlist(self, section, name, default=uimod._unset, untrusted=True):
127 return self.repo.ui.configlist(section, name, default,
127 return self.repo.ui.configlist(section, name, default,
128 untrusted=untrusted)
128 untrusted=untrusted)
129
129
130 def archivelist(self, nodeid):
130 def archivelist(self, nodeid):
131 return webutil.archivelist(self.repo.ui, nodeid)
131 return webutil.archivelist(self.repo.ui, nodeid)
132
132
133 def templater(self, req):
133 def templater(self, req):
134 # determine scheme, port and server name
134 # determine scheme, port and server name
135 # this is needed to create absolute urls
135 # this is needed to create absolute urls
136 logourl = self.config('web', 'logourl')
136 logourl = self.config('web', 'logourl')
137 logoimg = self.config('web', 'logoimg')
137 logoimg = self.config('web', 'logoimg')
138 staticurl = (self.config('web', 'staticurl')
138 staticurl = (self.config('web', 'staticurl')
139 or req.apppath.rstrip('/') + '/static/')
139 or req.apppath.rstrip('/') + '/static/')
140 if not staticurl.endswith('/'):
140 if not staticurl.endswith('/'):
141 staticurl += '/'
141 staticurl += '/'
142
142
143 # figure out which style to use
143 # figure out which style to use
144
144
145 vars = {}
145 vars = {}
146 styles, (style, mapfile) = getstyle(req, self.config,
146 styles, (style, mapfile) = getstyle(req, self.config,
147 self.templatepath)
147 self.templatepath)
148 if style == styles[0]:
148 if style == styles[0]:
149 vars['style'] = style
149 vars['style'] = style
150
150
151 sessionvars = webutil.sessionvars(vars, '?')
151 sessionvars = webutil.sessionvars(vars, '?')
152
152
153 if not self.reponame:
153 if not self.reponame:
154 self.reponame = (self.config('web', 'name', '')
154 self.reponame = (self.config('web', 'name', '')
155 or req.reponame
155 or req.reponame
156 or req.apppath
156 or req.apppath
157 or self.repo.root)
157 or self.repo.root)
158
158
159 filters = {}
159 filters = {}
160 templatefilter = registrar.templatefilter(filters)
160 templatefilter = registrar.templatefilter(filters)
161 @templatefilter('websub', intype=bytes)
161 @templatefilter('websub', intype=bytes)
162 def websubfilter(text):
162 def websubfilter(text):
163 return templatefilters.websub(text, self.websubtable)
163 return templatefilters.websub(text, self.websubtable)
164
164
165 # create the templater
165 # create the templater
166 # TODO: export all keywords: defaults = templatekw.keywords.copy()
166 # TODO: export all keywords: defaults = templatekw.keywords.copy()
167 defaults = {
167 defaults = {
168 'url': req.apppath + '/',
168 'url': req.apppath + '/',
169 'logourl': logourl,
169 'logourl': logourl,
170 'logoimg': logoimg,
170 'logoimg': logoimg,
171 'staticurl': staticurl,
171 'staticurl': staticurl,
172 'urlbase': req.advertisedbaseurl,
172 'urlbase': req.advertisedbaseurl,
173 'repo': self.reponame,
173 'repo': self.reponame,
174 'encoding': encoding.encoding,
174 'encoding': encoding.encoding,
175 'sessionvars': sessionvars,
175 'sessionvars': sessionvars,
176 'pathdef': makebreadcrumb(req.apppath),
176 'pathdef': makebreadcrumb(req.apppath),
177 'style': style,
177 'style': style,
178 'nonce': self.nonce,
178 'nonce': self.nonce,
179 }
179 }
180 templatekeyword = registrar.templatekeyword(defaults)
180 templatekeyword = registrar.templatekeyword(defaults)
181 @templatekeyword('motd', requires=())
181 @templatekeyword('motd', requires=())
182 def motd(context, mapping):
182 def motd(context, mapping):
183 yield self.config('web', 'motd')
183 yield self.config('web', 'motd')
184
184
185 tres = formatter.templateresources(self.repo.ui, self.repo)
185 tres = formatter.templateresources(self.repo.ui, self.repo)
186 tmpl = templater.templater.frommapfile(mapfile,
186 tmpl = templater.templater.frommapfile(mapfile,
187 filters=filters,
187 filters=filters,
188 defaults=defaults,
188 defaults=defaults,
189 resources=tres)
189 resources=tres)
190 return tmpl
190 return tmpl
191
191
192 def sendtemplate(self, name, **kwargs):
192 def sendtemplate(self, name, **kwargs):
193 """Helper function to send a response generated from a template."""
193 """Helper function to send a response generated from a template."""
194 kwargs = pycompat.byteskwargs(kwargs)
194 kwargs = pycompat.byteskwargs(kwargs)
195 self.res.setbodygen(self.tmpl.generate(name, kwargs))
195 self.res.setbodygen(self.tmpl.generate(name, kwargs))
196 return self.res.sendresponse()
196 return self.res.sendresponse()
197
197
198 class hgweb(object):
198 class hgweb(object):
199 """HTTP server for individual repositories.
199 """HTTP server for individual repositories.
200
200
201 Instances of this class serve HTTP responses for a particular
201 Instances of this class serve HTTP responses for a particular
202 repository.
202 repository.
203
203
204 Instances are typically used as WSGI applications.
204 Instances are typically used as WSGI applications.
205
205
206 Some servers are multi-threaded. On these servers, there may
206 Some servers are multi-threaded. On these servers, there may
207 be multiple active threads inside __call__.
207 be multiple active threads inside __call__.
208 """
208 """
209 def __init__(self, repo, name=None, baseui=None):
209 def __init__(self, repo, name=None, baseui=None):
210 if isinstance(repo, bytes):
210 if isinstance(repo, bytes):
211 if baseui:
211 if baseui:
212 u = baseui.copy()
212 u = baseui.copy()
213 else:
213 else:
214 u = uimod.ui.load()
214 u = uimod.ui.load()
215 r = hg.repository(u, repo)
215 r = hg.repository(u, repo)
216 else:
216 else:
217 # we trust caller to give us a private copy
217 # we trust caller to give us a private copy
218 r = repo
218 r = repo
219
219
220 r.ui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
220 r.ui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
221 r.baseui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
221 r.baseui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
222 r.ui.setconfig('ui', 'nontty', 'true', 'hgweb')
222 r.ui.setconfig('ui', 'nontty', 'true', 'hgweb')
223 r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
223 r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
224 # resolve file patterns relative to repo root
224 # resolve file patterns relative to repo root
225 r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
225 r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
226 r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
226 r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
227 # it's unlikely that we can replace signal handlers in WSGI server,
227 # it's unlikely that we can replace signal handlers in WSGI server,
228 # and mod_wsgi issues a big warning. a plain hgweb process (with no
228 # and mod_wsgi issues a big warning. a plain hgweb process (with no
229 # threading) could replace signal handlers, but we don't bother
229 # threading) could replace signal handlers, but we don't bother
230 # conditionally enabling it.
230 # conditionally enabling it.
231 r.ui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb')
231 r.ui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb')
232 r.baseui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb')
232 r.baseui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb')
233 # displaying bundling progress bar while serving feel wrong and may
233 # displaying bundling progress bar while serving feel wrong and may
234 # break some wsgi implementation.
234 # break some wsgi implementation.
235 r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
235 r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
236 r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
236 r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
237 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
237 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
238 self._lastrepo = self._repos[0]
238 self._lastrepo = self._repos[0]
239 hook.redirect(True)
239 hook.redirect(True)
240 self.reponame = name
240 self.reponame = name
241
241
242 def _webifyrepo(self, repo):
242 def _webifyrepo(self, repo):
243 repo = getwebview(repo)
243 repo = getwebview(repo)
244 self.websubtable = webutil.getwebsubs(repo)
244 self.websubtable = webutil.getwebsubs(repo)
245 return repo
245 return repo
246
246
247 @contextlib.contextmanager
247 @contextlib.contextmanager
248 def _obtainrepo(self):
248 def _obtainrepo(self):
249 """Obtain a repo unique to the caller.
249 """Obtain a repo unique to the caller.
250
250
251 Internally we maintain a stack of cachedlocalrepo instances
251 Internally we maintain a stack of cachedlocalrepo instances
252 to be handed out. If one is available, we pop it and return it,
252 to be handed out. If one is available, we pop it and return it,
253 ensuring it is up to date in the process. If one is not available,
253 ensuring it is up to date in the process. If one is not available,
254 we clone the most recently used repo instance and return it.
254 we clone the most recently used repo instance and return it.
255
255
256 It is currently possible for the stack to grow without bounds
256 It is currently possible for the stack to grow without bounds
257 if the server allows infinite threads. However, servers should
257 if the server allows infinite threads. However, servers should
258 have a thread limit, thus establishing our limit.
258 have a thread limit, thus establishing our limit.
259 """
259 """
260 if self._repos:
260 if self._repos:
261 cached = self._repos.pop()
261 cached = self._repos.pop()
262 r, created = cached.fetch()
262 r, created = cached.fetch()
263 else:
263 else:
264 cached = self._lastrepo.copy()
264 cached = self._lastrepo.copy()
265 r, created = cached.fetch()
265 r, created = cached.fetch()
266 if created:
266 if created:
267 r = self._webifyrepo(r)
267 r = self._webifyrepo(r)
268
268
269 self._lastrepo = cached
269 self._lastrepo = cached
270 self.mtime = cached.mtime
270 self.mtime = cached.mtime
271 try:
271 try:
272 yield r
272 yield r
273 finally:
273 finally:
274 self._repos.append(cached)
274 self._repos.append(cached)
275
275
276 def run(self):
276 def run(self):
277 """Start a server from CGI environment.
277 """Start a server from CGI environment.
278
278
279 Modern servers should be using WSGI and should avoid this
279 Modern servers should be using WSGI and should avoid this
280 method, if possible.
280 method, if possible.
281 """
281 """
282 if not encoding.environ.get('GATEWAY_INTERFACE',
282 if not encoding.environ.get('GATEWAY_INTERFACE',
283 '').startswith("CGI/1."):
283 '').startswith("CGI/1."):
284 raise RuntimeError("This function is only intended to be "
284 raise RuntimeError("This function is only intended to be "
285 "called while running as a CGI script.")
285 "called while running as a CGI script.")
286 wsgicgi.launch(self)
286 wsgicgi.launch(self)
287
287
288 def __call__(self, env, respond):
288 def __call__(self, env, respond):
289 """Run the WSGI application.
289 """Run the WSGI application.
290
290
291 This may be called by multiple threads.
291 This may be called by multiple threads.
292 """
292 """
293 req = requestmod.parserequestfromenv(env)
293 req = requestmod.parserequestfromenv(env)
294 res = requestmod.wsgiresponse(req, respond)
294 res = requestmod.wsgiresponse(req, respond)
295
295
296 return self.run_wsgi(req, res)
296 return self.run_wsgi(req, res)
297
297
298 def run_wsgi(self, req, res):
298 def run_wsgi(self, req, res):
299 """Internal method to run the WSGI application.
299 """Internal method to run the WSGI application.
300
300
301 This is typically only called by Mercurial. External consumers
301 This is typically only called by Mercurial. External consumers
302 should be using instances of this class as the WSGI application.
302 should be using instances of this class as the WSGI application.
303 """
303 """
304 with self._obtainrepo() as repo:
304 with self._obtainrepo() as repo:
305 profile = repo.ui.configbool('profiling', 'enabled')
305 profile = repo.ui.configbool('profiling', 'enabled')
306 with profiling.profile(repo.ui, enabled=profile):
306 with profiling.profile(repo.ui, enabled=profile):
307 for r in self._runwsgi(req, res, repo):
307 for r in self._runwsgi(req, res, repo):
308 yield r
308 yield r
309
309
310 def _runwsgi(self, req, res, repo):
310 def _runwsgi(self, req, res, repo):
311 rctx = requestcontext(self, repo, req, res)
311 rctx = requestcontext(self, repo, req, res)
312
312
313 # This state is global across all threads.
313 # This state is global across all threads.
314 encoding.encoding = rctx.config('web', 'encoding')
314 encoding.encoding = rctx.config('web', 'encoding')
315 rctx.repo.ui.environ = req.rawenv
315 rctx.repo.ui.environ = req.rawenv
316
316
317 if rctx.csp:
317 if rctx.csp:
318 # hgwebdir may have added CSP header. Since we generate our own,
318 # hgwebdir may have added CSP header. Since we generate our own,
319 # replace it.
319 # replace it.
320 res.headers['Content-Security-Policy'] = rctx.csp
320 res.headers['Content-Security-Policy'] = rctx.csp
321
321
322 # /api/* is reserved for various API implementations. Dispatch
322 # /api/* is reserved for various API implementations. Dispatch
323 # accordingly. But URL paths can conflict with subrepos and virtual
323 # accordingly. But URL paths can conflict with subrepos and virtual
324 # repos in hgwebdir. So until we have a workaround for this, only
324 # repos in hgwebdir. So until we have a workaround for this, only
325 # expose the URLs if the feature is enabled.
325 # expose the URLs if the feature is enabled.
326 apienabled = rctx.repo.ui.configbool('experimental', 'web.apiserver')
326 apienabled = rctx.repo.ui.configbool('experimental', 'web.apiserver')
327 if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api':
327 if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api':
328 wireprotoserver.handlewsgiapirequest(rctx, req, res,
328 wireprotoserver.handlewsgiapirequest(rctx, req, res,
329 self.check_perm)
329 self.check_perm)
330 return res.sendresponse()
330 return res.sendresponse()
331
331
332 handled = wireprotoserver.handlewsgirequest(
332 handled = wireprotoserver.handlewsgirequest(
333 rctx, req, res, self.check_perm)
333 rctx, req, res, self.check_perm)
334 if handled:
334 if handled:
335 return res.sendresponse()
335 return res.sendresponse()
336
336
337 # Old implementations of hgweb supported dispatching the request via
337 # Old implementations of hgweb supported dispatching the request via
338 # the initial query string parameter instead of using PATH_INFO.
338 # the initial query string parameter instead of using PATH_INFO.
339 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
339 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
340 # a value), we use it. Otherwise fall back to the query string.
340 # a value), we use it. Otherwise fall back to the query string.
341 if req.dispatchpath is not None:
341 if req.dispatchpath is not None:
342 query = req.dispatchpath
342 query = req.dispatchpath
343 else:
343 else:
344 query = req.querystring.partition('&')[0].partition(';')[0]
344 query = req.querystring.partition('&')[0].partition(';')[0]
345
345
346 # translate user-visible url structure to internal structure
346 # translate user-visible url structure to internal structure
347
347
348 args = query.split('/', 2)
348 args = query.split('/', 2)
349 if 'cmd' not in req.qsparams and args and args[0]:
349 if 'cmd' not in req.qsparams and args and args[0]:
350 cmd = args.pop(0)
350 cmd = args.pop(0)
351 style = cmd.rfind('-')
351 style = cmd.rfind('-')
352 if style != -1:
352 if style != -1:
353 req.qsparams['style'] = cmd[:style]
353 req.qsparams['style'] = cmd[:style]
354 cmd = cmd[style + 1:]
354 cmd = cmd[style + 1:]
355
355
356 # avoid accepting e.g. style parameter as command
356 # avoid accepting e.g. style parameter as command
357 if util.safehasattr(webcommands, cmd):
357 if util.safehasattr(webcommands, cmd):
358 req.qsparams['cmd'] = cmd
358 req.qsparams['cmd'] = cmd
359
359
360 if cmd == 'static':
360 if cmd == 'static':
361 req.qsparams['file'] = '/'.join(args)
361 req.qsparams['file'] = '/'.join(args)
362 else:
362 else:
363 if args and args[0]:
363 if args and args[0]:
364 node = args.pop(0).replace('%2F', '/')
364 node = args.pop(0).replace('%2F', '/')
365 req.qsparams['node'] = node
365 req.qsparams['node'] = node
366 if args:
366 if args:
367 if 'file' in req.qsparams:
367 if 'file' in req.qsparams:
368 del req.qsparams['file']
368 del req.qsparams['file']
369 for a in args:
369 for a in args:
370 req.qsparams.add('file', a)
370 req.qsparams.add('file', a)
371
371
372 ua = req.headers.get('User-Agent', '')
372 ua = req.headers.get('User-Agent', '')
373 if cmd == 'rev' and 'mercurial' in ua:
373 if cmd == 'rev' and 'mercurial' in ua:
374 req.qsparams['style'] = 'raw'
374 req.qsparams['style'] = 'raw'
375
375
376 if cmd == 'archive':
376 if cmd == 'archive':
377 fn = req.qsparams['node']
377 fn = req.qsparams['node']
378 for type_, spec in webutil.archivespecs.iteritems():
378 for type_, spec in webutil.archivespecs.iteritems():
379 ext = spec[2]
379 ext = spec[2]
380 if fn.endswith(ext):
380 if fn.endswith(ext):
381 req.qsparams['node'] = fn[:-len(ext)]
381 req.qsparams['node'] = fn[:-len(ext)]
382 req.qsparams['type'] = type_
382 req.qsparams['type'] = type_
383 else:
383 else:
384 cmd = req.qsparams.get('cmd', '')
384 cmd = req.qsparams.get('cmd', '')
385
385
386 # process the web interface request
386 # process the web interface request
387
387
388 try:
388 try:
389 rctx.tmpl = rctx.templater(req)
389 rctx.tmpl = rctx.templater(req)
390 ctype = rctx.tmpl.render('mimetype',
390 ctype = rctx.tmpl.render('mimetype',
391 {'encoding': encoding.encoding})
391 {'encoding': encoding.encoding})
392
392
393 # check read permissions non-static content
393 # check read permissions non-static content
394 if cmd != 'static':
394 if cmd != 'static':
395 self.check_perm(rctx, req, None)
395 self.check_perm(rctx, req, None)
396
396
397 if cmd == '':
397 if cmd == '':
398 req.qsparams['cmd'] = rctx.tmpl.render('default', {})
398 req.qsparams['cmd'] = rctx.tmpl.render('default', {})
399 cmd = req.qsparams['cmd']
399 cmd = req.qsparams['cmd']
400
400
401 # Don't enable caching if using a CSP nonce because then it wouldn't
401 # Don't enable caching if using a CSP nonce because then it wouldn't
402 # be a nonce.
402 # be a nonce.
403 if rctx.configbool('web', 'cache') and not rctx.nonce:
403 if rctx.configbool('web', 'cache') and not rctx.nonce:
404 tag = 'W/"%d"' % self.mtime
404 tag = 'W/"%d"' % self.mtime
405 if req.headers.get('If-None-Match') == tag:
405 if req.headers.get('If-None-Match') == tag:
406 res.status = '304 Not Modified'
406 res.status = '304 Not Modified'
407 # Content-Type may be defined globally. It isn't valid on a
407 # Content-Type may be defined globally. It isn't valid on a
408 # 304, so discard it.
408 # 304, so discard it.
409 try:
409 try:
410 del res.headers[b'Content-Type']
410 del res.headers[b'Content-Type']
411 except KeyError:
411 except KeyError:
412 pass
412 pass
413 # Response body not allowed on 304.
413 # Response body not allowed on 304.
414 res.setbodybytes('')
414 res.setbodybytes('')
415 return res.sendresponse()
415 return res.sendresponse()
416
416
417 res.headers['ETag'] = tag
417 res.headers['ETag'] = tag
418
418
419 if cmd not in webcommands.__all__:
419 if cmd not in webcommands.__all__:
420 msg = 'no such method: %s' % cmd
420 msg = 'no such method: %s' % cmd
421 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
421 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
422 else:
422 else:
423 # Set some globals appropriate for web handlers. Commands can
423 # Set some globals appropriate for web handlers. Commands can
424 # override easily enough.
424 # override easily enough.
425 res.status = '200 Script output follows'
425 res.status = '200 Script output follows'
426 res.headers['Content-Type'] = ctype
426 res.headers['Content-Type'] = ctype
427 return getattr(webcommands, cmd)(rctx)
427 return getattr(webcommands, cmd)(rctx)
428
428
429 except (error.LookupError, error.RepoLookupError) as err:
429 except (error.LookupError, error.RepoLookupError) as err:
430 msg = pycompat.bytestr(err)
430 msg = pycompat.bytestr(err)
431 if (util.safehasattr(err, 'name') and
431 if (util.safehasattr(err, 'name') and
432 not isinstance(err, error.ManifestLookupError)):
432 not isinstance(err, error.ManifestLookupError)):
433 msg = 'revision not found: %s' % err.name
433 msg = 'revision not found: %s' % err.name
434
434
435 res.status = '404 Not Found'
435 res.status = '404 Not Found'
436 res.headers['Content-Type'] = ctype
436 res.headers['Content-Type'] = ctype
437 return rctx.sendtemplate('error', error=msg)
437 return rctx.sendtemplate('error', error=msg)
438 except (error.RepoError, error.RevlogError) as e:
438 except (error.RepoError, error.RevlogError) as e:
439 res.status = '500 Internal Server Error'
439 res.status = '500 Internal Server Error'
440 res.headers['Content-Type'] = ctype
440 res.headers['Content-Type'] = ctype
441 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
441 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
442 except error.Abort as e:
443 res.status = '403 Forbidden'
444 res.headers['Content-Type'] = ctype
445 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
442 except ErrorResponse as e:
446 except ErrorResponse as e:
443 for k, v in e.headers:
447 for k, v in e.headers:
444 res.headers[k] = v
448 res.headers[k] = v
445 res.status = statusmessage(e.code, pycompat.bytestr(e))
449 res.status = statusmessage(e.code, pycompat.bytestr(e))
446 res.headers['Content-Type'] = ctype
450 res.headers['Content-Type'] = ctype
447 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
451 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
448
452
449 def check_perm(self, rctx, req, op):
453 def check_perm(self, rctx, req, op):
450 for permhook in permhooks:
454 for permhook in permhooks:
451 permhook(rctx, req, op)
455 permhook(rctx, req, op)
452
456
453 def getwebview(repo):
457 def getwebview(repo):
454 """The 'web.view' config controls changeset filter to hgweb. Possible
458 """The 'web.view' config controls changeset filter to hgweb. Possible
455 values are ``served``, ``visible`` and ``all``. Default is ``served``.
459 values are ``served``, ``visible`` and ``all``. Default is ``served``.
456 The ``served`` filter only shows changesets that can be pulled from the
460 The ``served`` filter only shows changesets that can be pulled from the
457 hgweb instance. The``visible`` filter includes secret changesets but
461 hgweb instance. The``visible`` filter includes secret changesets but
458 still excludes "hidden" one.
462 still excludes "hidden" one.
459
463
460 See the repoview module for details.
464 See the repoview module for details.
461
465
462 The option has been around undocumented since Mercurial 2.5, but no
466 The option has been around undocumented since Mercurial 2.5, but no
463 user ever asked about it. So we better keep it undocumented for now."""
467 user ever asked about it. So we better keep it undocumented for now."""
464 # experimental config: web.view
468 # experimental config: web.view
465 viewconfig = repo.ui.config('web', 'view', untrusted=True)
469 viewconfig = repo.ui.config('web', 'view', untrusted=True)
466 if viewconfig == 'all':
470 if viewconfig == 'all':
467 return repo.unfiltered()
471 return repo.unfiltered()
468 elif viewconfig in repoview.filtertable:
472 elif viewconfig in repoview.filtertable:
469 return repo.filtered(viewconfig)
473 return repo.filtered(viewconfig)
470 else:
474 else:
471 return repo.filtered('served')
475 return repo.filtered('served')
@@ -1,1745 +1,1791 b''
1 #require serve
1 #require serve
2
2
3 hide outer repo and work in dir without '.hg'
3 hide outer repo and work in dir without '.hg'
4 $ hg init
4 $ hg init
5 $ mkdir dir
5 $ mkdir dir
6 $ cd dir
6 $ cd dir
7
7
8 Tests some basic hgwebdir functionality. Tests setting up paths and
8 Tests some basic hgwebdir functionality. Tests setting up paths and
9 collection, different forms of 404s and the subdirectory support.
9 collection, different forms of 404s and the subdirectory support.
10
10
11 $ mkdir webdir
11 $ mkdir webdir
12 $ cd webdir
12 $ cd webdir
13 $ hg init a
13 $ hg init a
14 $ echo a > a/a
14 $ echo a > a/a
15 $ hg --cwd a ci -Ama -d'1 0'
15 $ hg --cwd a ci -Ama -d'1 0'
16 adding a
16 adding a
17
17
18 create a mercurial queue repository
18 create a mercurial queue repository
19
19
20 $ hg --cwd a qinit --config extensions.hgext.mq= -c
20 $ hg --cwd a qinit --config extensions.hgext.mq= -c
21 $ hg init b
21 $ hg init b
22 $ echo b > b/b
22 $ echo b > b/b
23 $ hg --cwd b ci -Amb -d'2 0'
23 $ hg --cwd b ci -Amb -d'2 0'
24 adding b
24 adding b
25
25
26 create a nested repository
26 create a nested repository
27
27
28 $ cd b
28 $ cd b
29 $ hg init d
29 $ hg init d
30 $ echo d > d/d
30 $ echo d > d/d
31 $ hg --cwd d ci -Amd -d'3 0'
31 $ hg --cwd d ci -Amd -d'3 0'
32 adding d
32 adding d
33 $ cd ..
33 $ cd ..
34 $ hg init c
34 $ hg init c
35 $ echo c > c/c
35 $ echo c > c/c
36 $ hg --cwd c ci -Amc -d'3 0'
36 $ hg --cwd c ci -Amc -d'3 0'
37 adding c
37 adding c
38
38
39 create a subdirectory containing repositories and subrepositories
39 create a subdirectory containing repositories and subrepositories
40
40
41 $ mkdir notrepo
41 $ mkdir notrepo
42 $ cd notrepo
42 $ cd notrepo
43 $ hg init e
43 $ hg init e
44 $ echo e > e/e
44 $ echo e > e/e
45 $ hg --cwd e ci -Ame -d'4 0'
45 $ hg --cwd e ci -Ame -d'4 0'
46 adding e
46 adding e
47 $ hg init e/e2
47 $ hg init e/e2
48 $ echo e2 > e/e2/e2
48 $ echo e2 > e/e2/e2
49 $ hg --cwd e/e2 ci -Ame2 -d '4 0'
49 $ hg --cwd e/e2 ci -Ame2 -d '4 0'
50 adding e2
50 adding e2
51 $ hg init f
51 $ hg init f
52 $ echo f > f/f
52 $ echo f > f/f
53 $ hg --cwd f ci -Amf -d'4 0'
53 $ hg --cwd f ci -Amf -d'4 0'
54 adding f
54 adding f
55 $ hg init f/f2
55 $ hg init f/f2
56 $ echo f2 > f/f2/f2
56 $ echo f2 > f/f2/f2
57 $ hg --cwd f/f2 ci -Amf2 -d '4 0'
57 $ hg --cwd f/f2 ci -Amf2 -d '4 0'
58 adding f2
58 adding f2
59 $ echo 'f2 = f2' > f/.hgsub
59 $ echo 'f2 = f2' > f/.hgsub
60 $ hg -R f ci -Am 'add subrepo' -d'4 0'
60 $ hg -R f ci -Am 'add subrepo' -d'4 0'
61 adding .hgsub
61 adding .hgsub
62 $ cat >> f/.hg/hgrc << EOF
62 $ cat >> f/.hg/hgrc << EOF
63 > [web]
63 > [web]
64 > name = fancy name for repo f
64 > name = fancy name for repo f
65 > labels = foo, bar
65 > labels = foo, bar
66 > EOF
66 > EOF
67 $ cd ..
67 $ cd ..
68
68
69 add file under the directory which could be shadowed by another repository
70
71 $ mkdir notrepo/f/f3
72 $ echo f3/file > notrepo/f/f3/file
73 $ hg -R notrepo/f ci -Am 'f3/file'
74 adding f3/file
75 $ hg -R notrepo/f update null
76 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
77 $ hg init notrepo/f/f3
78 $ cat <<'EOF' > notrepo/f/f3/.hg/hgrc
79 > [web]
80 > hidden = true
81 > EOF
82
69 create repository without .hg/store
83 create repository without .hg/store
70
84
71 $ hg init nostore
85 $ hg init nostore
72 $ rm -R nostore/.hg/store
86 $ rm -R nostore/.hg/store
73 $ root=`pwd`
87 $ root=`pwd`
74 $ cd ..
88 $ cd ..
75
89
76 serve
90 serve
77 $ cat > paths.conf <<EOF
91 $ cat > paths.conf <<EOF
78 > [paths]
92 > [paths]
79 > a=$root/a
93 > a=$root/a
80 > b=$root/b
94 > b=$root/b
81 > EOF
95 > EOF
82 $ hg serve -p $HGPORT -d --pid-file=hg.pid --webdir-conf paths.conf \
96 $ hg serve -p $HGPORT -d --pid-file=hg.pid --webdir-conf paths.conf \
83 > -A access-paths.log -E error-paths-1.log
97 > -A access-paths.log -E error-paths-1.log
84 $ cat hg.pid >> $DAEMON_PIDS
98 $ cat hg.pid >> $DAEMON_PIDS
85
99
86 should give a 404 - file does not exist
100 should give a 404 - file does not exist
87
101
88 $ get-with-headers.py localhost:$HGPORT 'a/file/tip/bork?style=raw'
102 $ get-with-headers.py localhost:$HGPORT 'a/file/tip/bork?style=raw'
89 404 Not Found
103 404 Not Found
90
104
91
105
92 error: bork@8580ff50825a: not found in manifest
106 error: bork@8580ff50825a: not found in manifest
93 [1]
107 [1]
94
108
95 should succeed
109 should succeed
96
110
97 $ get-with-headers.py localhost:$HGPORT '?style=raw'
111 $ get-with-headers.py localhost:$HGPORT '?style=raw'
98 200 Script output follows
112 200 Script output follows
99
113
100
114
101 /a/
115 /a/
102 /b/
116 /b/
103
117
104 $ get-with-headers.py localhost:$HGPORT '?style=json'
118 $ get-with-headers.py localhost:$HGPORT '?style=json'
105 200 Script output follows
119 200 Script output follows
106
120
107 {
121 {
108 "entries": [{
122 "entries": [{
109 "name": "a",
123 "name": "a",
110 "description": "unknown",
124 "description": "unknown",
111 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
125 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
112 "lastchange": [*, *], (glob)
126 "lastchange": [*, *], (glob)
113 "labels": []
127 "labels": []
114 }, {
128 }, {
115 "name": "b",
129 "name": "b",
116 "description": "unknown",
130 "description": "unknown",
117 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
131 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
118 "lastchange": [*, *], (glob)
132 "lastchange": [*, *], (glob)
119 "labels": []
133 "labels": []
120 }]
134 }]
121 } (no-eol)
135 } (no-eol)
122
136
123 $ get-with-headers.py localhost:$HGPORT 'a/file/tip/a?style=raw'
137 $ get-with-headers.py localhost:$HGPORT 'a/file/tip/a?style=raw'
124 200 Script output follows
138 200 Script output follows
125
139
126 a
140 a
127 $ get-with-headers.py localhost:$HGPORT 'b/file/tip/b?style=raw'
141 $ get-with-headers.py localhost:$HGPORT 'b/file/tip/b?style=raw'
128 200 Script output follows
142 200 Script output follows
129
143
130 b
144 b
131
145
132 should give a 404 - repo is not published
146 should give a 404 - repo is not published
133
147
134 $ get-with-headers.py localhost:$HGPORT 'c/file/tip/c?style=raw'
148 $ get-with-headers.py localhost:$HGPORT 'c/file/tip/c?style=raw'
135 404 Not Found
149 404 Not Found
136
150
137
151
138 error: repository c/file/tip/c not found
152 error: repository c/file/tip/c not found
139 [1]
153 [1]
140
154
141 atom-log without basedir
155 atom-log without basedir
142
156
143 $ get-with-headers.py localhost:$HGPORT 'a/atom-log' | grep '<link'
157 $ get-with-headers.py localhost:$HGPORT 'a/atom-log' | grep '<link'
144 <link rel="self" href="http://*:$HGPORT/a/atom-log"/> (glob)
158 <link rel="self" href="http://*:$HGPORT/a/atom-log"/> (glob)
145 <link rel="alternate" href="http://*:$HGPORT/a/"/> (glob)
159 <link rel="alternate" href="http://*:$HGPORT/a/"/> (glob)
146 <link href="http://*:$HGPORT/a/rev/8580ff50825a"/> (glob)
160 <link href="http://*:$HGPORT/a/rev/8580ff50825a"/> (glob)
147
161
148 rss-log without basedir
162 rss-log without basedir
149
163
150 $ get-with-headers.py localhost:$HGPORT 'a/rss-log' | grep '<guid'
164 $ get-with-headers.py localhost:$HGPORT 'a/rss-log' | grep '<guid'
151 <guid isPermaLink="true">http://*:$HGPORT/a/rev/8580ff50825a</guid> (glob)
165 <guid isPermaLink="true">http://*:$HGPORT/a/rev/8580ff50825a</guid> (glob)
152 $ cat > paths.conf <<EOF
166 $ cat > paths.conf <<EOF
153 > [paths]
167 > [paths]
154 > t/a/=$root/a
168 > t/a/=$root/a
155 > b=$root/b
169 > b=$root/b
156 > coll=$root/*
170 > coll=$root/*
157 > rcoll=$root/**
171 > rcoll=$root/**
158 > star=*
172 > star=*
159 > starstar=**
173 > starstar=**
160 > astar=webdir/a/*
174 > astar=webdir/a/*
161 > EOF
175 > EOF
162 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
176 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
163 > -A access-paths.log -E error-paths-2.log
177 > -A access-paths.log -E error-paths-2.log
164 $ cat hg.pid >> $DAEMON_PIDS
178 $ cat hg.pid >> $DAEMON_PIDS
165
179
166 should succeed, slashy names
180 should succeed, slashy names
167
181
168 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
182 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
169 200 Script output follows
183 200 Script output follows
170
184
171
185
172 /t/a/
186 /t/a/
173 /b/
187 /b/
174 /coll/a/
188 /coll/a/
175 /coll/a/.hg/patches/
189 /coll/a/.hg/patches/
176 /coll/b/
190 /coll/b/
177 /coll/c/
191 /coll/c/
178 /coll/notrepo/e/
192 /coll/notrepo/e/
179 /coll/notrepo/f/
193 /coll/notrepo/f/
180 /rcoll/a/
194 /rcoll/a/
181 /rcoll/a/.hg/patches/
195 /rcoll/a/.hg/patches/
182 /rcoll/b/
196 /rcoll/b/
183 /rcoll/b/d/
197 /rcoll/b/d/
184 /rcoll/c/
198 /rcoll/c/
185 /rcoll/notrepo/e/
199 /rcoll/notrepo/e/
186 /rcoll/notrepo/e/e2/
200 /rcoll/notrepo/e/e2/
187 /rcoll/notrepo/f/
201 /rcoll/notrepo/f/
188 /rcoll/notrepo/f/f2/
202 /rcoll/notrepo/f/f2/
189 /star/webdir/a/
203 /star/webdir/a/
190 /star/webdir/a/.hg/patches/
204 /star/webdir/a/.hg/patches/
191 /star/webdir/b/
205 /star/webdir/b/
192 /star/webdir/c/
206 /star/webdir/c/
193 /star/webdir/notrepo/e/
207 /star/webdir/notrepo/e/
194 /star/webdir/notrepo/f/
208 /star/webdir/notrepo/f/
195 /starstar/webdir/a/
209 /starstar/webdir/a/
196 /starstar/webdir/a/.hg/patches/
210 /starstar/webdir/a/.hg/patches/
197 /starstar/webdir/b/
211 /starstar/webdir/b/
198 /starstar/webdir/b/d/
212 /starstar/webdir/b/d/
199 /starstar/webdir/c/
213 /starstar/webdir/c/
200 /starstar/webdir/notrepo/e/
214 /starstar/webdir/notrepo/e/
201 /starstar/webdir/notrepo/e/e2/
215 /starstar/webdir/notrepo/e/e2/
202 /starstar/webdir/notrepo/f/
216 /starstar/webdir/notrepo/f/
203 /starstar/webdir/notrepo/f/f2/
217 /starstar/webdir/notrepo/f/f2/
204 /astar/
218 /astar/
205 /astar/.hg/patches/
219 /astar/.hg/patches/
206
220
207
221
208 $ get-with-headers.py localhost:$HGPORT1 '?style=json'
222 $ get-with-headers.py localhost:$HGPORT1 '?style=json'
209 200 Script output follows
223 200 Script output follows
210
224
211 {
225 {
212 "entries": [{
226 "entries": [{
213 "name": "t/a",
227 "name": "t/a",
214 "description": "unknown",
228 "description": "unknown",
215 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
229 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
216 "lastchange": [*, *], (glob)
230 "lastchange": [*, *], (glob)
217 "labels": []
231 "labels": []
218 }, {
232 }, {
219 "name": "b",
233 "name": "b",
220 "description": "unknown",
234 "description": "unknown",
221 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
235 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
222 "lastchange": [*, *], (glob)
236 "lastchange": [*, *], (glob)
223 "labels": []
237 "labels": []
224 }, {
238 }, {
225 "name": "coll/a",
239 "name": "coll/a",
226 "description": "unknown",
240 "description": "unknown",
227 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
241 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
228 "lastchange": [*, *], (glob)
242 "lastchange": [*, *], (glob)
229 "labels": []
243 "labels": []
230 }, {
244 }, {
231 "name": "coll/a/.hg/patches",
245 "name": "coll/a/.hg/patches",
232 "description": "unknown",
246 "description": "unknown",
233 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
247 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
234 "lastchange": [*, *], (glob)
248 "lastchange": [*, *], (glob)
235 "labels": []
249 "labels": []
236 }, {
250 }, {
237 "name": "coll/b",
251 "name": "coll/b",
238 "description": "unknown",
252 "description": "unknown",
239 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
253 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
240 "lastchange": [*, *], (glob)
254 "lastchange": [*, *], (glob)
241 "labels": []
255 "labels": []
242 }, {
256 }, {
243 "name": "coll/c",
257 "name": "coll/c",
244 "description": "unknown",
258 "description": "unknown",
245 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
259 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
246 "lastchange": [*, *], (glob)
260 "lastchange": [*, *], (glob)
247 "labels": []
261 "labels": []
248 }, {
262 }, {
249 "name": "coll/notrepo/e",
263 "name": "coll/notrepo/e",
250 "description": "unknown",
264 "description": "unknown",
251 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
265 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
252 "lastchange": [*, *], (glob)
266 "lastchange": [*, *], (glob)
253 "labels": []
267 "labels": []
254 }, {
268 }, {
255 "name": "fancy name for repo f",
269 "name": "fancy name for repo f",
256 "description": "unknown",
270 "description": "unknown",
257 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
271 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
258 "lastchange": [*, *], (glob)
272 "lastchange": [*, *], (glob)
259 "labels": ["foo", "bar"]
273 "labels": ["foo", "bar"]
260 }, {
274 }, {
261 "name": "rcoll/a",
275 "name": "rcoll/a",
262 "description": "unknown",
276 "description": "unknown",
263 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
277 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
264 "lastchange": [*, *], (glob)
278 "lastchange": [*, *], (glob)
265 "labels": []
279 "labels": []
266 }, {
280 }, {
267 "name": "rcoll/a/.hg/patches",
281 "name": "rcoll/a/.hg/patches",
268 "description": "unknown",
282 "description": "unknown",
269 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
283 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
270 "lastchange": [*, *], (glob)
284 "lastchange": [*, *], (glob)
271 "labels": []
285 "labels": []
272 }, {
286 }, {
273 "name": "rcoll/b",
287 "name": "rcoll/b",
274 "description": "unknown",
288 "description": "unknown",
275 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
289 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
276 "lastchange": [*, *], (glob)
290 "lastchange": [*, *], (glob)
277 "labels": []
291 "labels": []
278 }, {
292 }, {
279 "name": "rcoll/b/d",
293 "name": "rcoll/b/d",
280 "description": "unknown",
294 "description": "unknown",
281 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
295 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
282 "lastchange": [*, *], (glob)
296 "lastchange": [*, *], (glob)
283 "labels": []
297 "labels": []
284 }, {
298 }, {
285 "name": "rcoll/c",
299 "name": "rcoll/c",
286 "description": "unknown",
300 "description": "unknown",
287 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
301 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
288 "lastchange": [*, *], (glob)
302 "lastchange": [*, *], (glob)
289 "labels": []
303 "labels": []
290 }, {
304 }, {
291 "name": "rcoll/notrepo/e",
305 "name": "rcoll/notrepo/e",
292 "description": "unknown",
306 "description": "unknown",
293 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
307 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
294 "lastchange": [*, *], (glob)
308 "lastchange": [*, *], (glob)
295 "labels": []
309 "labels": []
296 }, {
310 }, {
297 "name": "rcoll/notrepo/e/e2",
311 "name": "rcoll/notrepo/e/e2",
298 "description": "unknown",
312 "description": "unknown",
299 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
313 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
300 "lastchange": [*, *], (glob)
314 "lastchange": [*, *], (glob)
301 "labels": []
315 "labels": []
302 }, {
316 }, {
303 "name": "fancy name for repo f",
317 "name": "fancy name for repo f",
304 "description": "unknown",
318 "description": "unknown",
305 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
319 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
306 "lastchange": [*, *], (glob)
320 "lastchange": [*, *], (glob)
307 "labels": ["foo", "bar"]
321 "labels": ["foo", "bar"]
308 }, {
322 }, {
309 "name": "rcoll/notrepo/f/f2",
323 "name": "rcoll/notrepo/f/f2",
310 "description": "unknown",
324 "description": "unknown",
311 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
325 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
312 "lastchange": [*, *], (glob)
326 "lastchange": [*, *], (glob)
313 "labels": []
327 "labels": []
314 }, {
328 }, {
315 "name": "star/webdir/a",
329 "name": "star/webdir/a",
316 "description": "unknown",
330 "description": "unknown",
317 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
331 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
318 "lastchange": [*, *], (glob)
332 "lastchange": [*, *], (glob)
319 "labels": []
333 "labels": []
320 }, {
334 }, {
321 "name": "star/webdir/a/.hg/patches",
335 "name": "star/webdir/a/.hg/patches",
322 "description": "unknown",
336 "description": "unknown",
323 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
337 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
324 "lastchange": [*, *], (glob)
338 "lastchange": [*, *], (glob)
325 "labels": []
339 "labels": []
326 }, {
340 }, {
327 "name": "star/webdir/b",
341 "name": "star/webdir/b",
328 "description": "unknown",
342 "description": "unknown",
329 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
343 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
330 "lastchange": [*, *], (glob)
344 "lastchange": [*, *], (glob)
331 "labels": []
345 "labels": []
332 }, {
346 }, {
333 "name": "star/webdir/c",
347 "name": "star/webdir/c",
334 "description": "unknown",
348 "description": "unknown",
335 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
349 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
336 "lastchange": [*, *], (glob)
350 "lastchange": [*, *], (glob)
337 "labels": []
351 "labels": []
338 }, {
352 }, {
339 "name": "star/webdir/notrepo/e",
353 "name": "star/webdir/notrepo/e",
340 "description": "unknown",
354 "description": "unknown",
341 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
355 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
342 "lastchange": [*, *], (glob)
356 "lastchange": [*, *], (glob)
343 "labels": []
357 "labels": []
344 }, {
358 }, {
345 "name": "fancy name for repo f",
359 "name": "fancy name for repo f",
346 "description": "unknown",
360 "description": "unknown",
347 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
361 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
348 "lastchange": [*, *], (glob)
362 "lastchange": [*, *], (glob)
349 "labels": ["foo", "bar"]
363 "labels": ["foo", "bar"]
350 }, {
364 }, {
351 "name": "starstar/webdir/a",
365 "name": "starstar/webdir/a",
352 "description": "unknown",
366 "description": "unknown",
353 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
367 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
354 "lastchange": [*, *], (glob)
368 "lastchange": [*, *], (glob)
355 "labels": []
369 "labels": []
356 }, {
370 }, {
357 "name": "starstar/webdir/a/.hg/patches",
371 "name": "starstar/webdir/a/.hg/patches",
358 "description": "unknown",
372 "description": "unknown",
359 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
373 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
360 "lastchange": [*, *], (glob)
374 "lastchange": [*, *], (glob)
361 "labels": []
375 "labels": []
362 }, {
376 }, {
363 "name": "starstar/webdir/b",
377 "name": "starstar/webdir/b",
364 "description": "unknown",
378 "description": "unknown",
365 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
379 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
366 "lastchange": [*, *], (glob)
380 "lastchange": [*, *], (glob)
367 "labels": []
381 "labels": []
368 }, {
382 }, {
369 "name": "starstar/webdir/b/d",
383 "name": "starstar/webdir/b/d",
370 "description": "unknown",
384 "description": "unknown",
371 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
385 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
372 "lastchange": [*, *], (glob)
386 "lastchange": [*, *], (glob)
373 "labels": []
387 "labels": []
374 }, {
388 }, {
375 "name": "starstar/webdir/c",
389 "name": "starstar/webdir/c",
376 "description": "unknown",
390 "description": "unknown",
377 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
391 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
378 "lastchange": [*, *], (glob)
392 "lastchange": [*, *], (glob)
379 "labels": []
393 "labels": []
380 }, {
394 }, {
381 "name": "starstar/webdir/notrepo/e",
395 "name": "starstar/webdir/notrepo/e",
382 "description": "unknown",
396 "description": "unknown",
383 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
397 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
384 "lastchange": [*, *], (glob)
398 "lastchange": [*, *], (glob)
385 "labels": []
399 "labels": []
386 }, {
400 }, {
387 "name": "starstar/webdir/notrepo/e/e2",
401 "name": "starstar/webdir/notrepo/e/e2",
388 "description": "unknown",
402 "description": "unknown",
389 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
403 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
390 "lastchange": [*, *], (glob)
404 "lastchange": [*, *], (glob)
391 "labels": []
405 "labels": []
392 }, {
406 }, {
393 "name": "fancy name for repo f",
407 "name": "fancy name for repo f",
394 "description": "unknown",
408 "description": "unknown",
395 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
409 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
396 "lastchange": [*, *], (glob)
410 "lastchange": [*, *], (glob)
397 "labels": ["foo", "bar"]
411 "labels": ["foo", "bar"]
398 }, {
412 }, {
399 "name": "starstar/webdir/notrepo/f/f2",
413 "name": "starstar/webdir/notrepo/f/f2",
400 "description": "unknown",
414 "description": "unknown",
401 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
415 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
402 "lastchange": [*, *], (glob)
416 "lastchange": [*, *], (glob)
403 "labels": []
417 "labels": []
404 }, {
418 }, {
405 "name": "astar",
419 "name": "astar",
406 "description": "unknown",
420 "description": "unknown",
407 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
421 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
408 "lastchange": [*, *], (glob)
422 "lastchange": [*, *], (glob)
409 "labels": []
423 "labels": []
410 }, {
424 }, {
411 "name": "astar/.hg/patches",
425 "name": "astar/.hg/patches",
412 "description": "unknown",
426 "description": "unknown",
413 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
427 "contact": "Foo Bar \u003cfoo.bar@example.com\u003e",
414 "lastchange": [*, *], (glob)
428 "lastchange": [*, *], (glob)
415 "labels": []
429 "labels": []
416 }]
430 }]
417 } (no-eol)
431 } (no-eol)
418
432
419 $ get-with-headers.py localhost:$HGPORT1 '?style=paper'
433 $ get-with-headers.py localhost:$HGPORT1 '?style=paper'
420 200 Script output follows
434 200 Script output follows
421
435
422 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
436 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
423 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
437 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
424 <head>
438 <head>
425 <link rel="icon" href="/static/hgicon.png" type="image/png" />
439 <link rel="icon" href="/static/hgicon.png" type="image/png" />
426 <meta name="robots" content="index, nofollow" />
440 <meta name="robots" content="index, nofollow" />
427 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
441 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
428 <script type="text/javascript" src="/static/mercurial.js"></script>
442 <script type="text/javascript" src="/static/mercurial.js"></script>
429
443
430 <title>Mercurial repositories index</title>
444 <title>Mercurial repositories index</title>
431 </head>
445 </head>
432 <body>
446 <body>
433
447
434 <div class="container">
448 <div class="container">
435 <div class="menu">
449 <div class="menu">
436 <a href="https://mercurial-scm.org/">
450 <a href="https://mercurial-scm.org/">
437 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
451 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
438 </div>
452 </div>
439 <div class="main">
453 <div class="main">
440 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
454 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
441
455
442 <table class="bigtable">
456 <table class="bigtable">
443 <thead>
457 <thead>
444 <tr>
458 <tr>
445 <th><a href="?sort=name">Name</a></th>
459 <th><a href="?sort=name">Name</a></th>
446 <th><a href="?sort=description">Description</a></th>
460 <th><a href="?sort=description">Description</a></th>
447 <th><a href="?sort=contact">Contact</a></th>
461 <th><a href="?sort=contact">Contact</a></th>
448 <th><a href="?sort=lastchange">Last modified</a></th>
462 <th><a href="?sort=lastchange">Last modified</a></th>
449 <th>&nbsp;</th>
463 <th>&nbsp;</th>
450 <th>&nbsp;</th>
464 <th>&nbsp;</th>
451 </tr>
465 </tr>
452 </thead>
466 </thead>
453 <tbody class="stripes2">
467 <tbody class="stripes2">
454
468
455 <tr>
469 <tr>
456 <td><a href="/t/a/?style=paper">t/a</a></td>
470 <td><a href="/t/a/?style=paper">t/a</a></td>
457 <td>unknown</td>
471 <td>unknown</td>
458 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
472 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
459 <td class="age">*</td> (glob)
473 <td class="age">*</td> (glob)
460 <td class="indexlinks"></td>
474 <td class="indexlinks"></td>
461 <td>
475 <td>
462 <a href="/t/a/atom-log" title="subscribe to repository atom feed">
476 <a href="/t/a/atom-log" title="subscribe to repository atom feed">
463 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
477 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
464 </a>
478 </a>
465 </td>
479 </td>
466 </tr>
480 </tr>
467
481
468 <tr>
482 <tr>
469 <td><a href="/b/?style=paper">b</a></td>
483 <td><a href="/b/?style=paper">b</a></td>
470 <td>unknown</td>
484 <td>unknown</td>
471 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
485 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
472 <td class="age">*</td> (glob)
486 <td class="age">*</td> (glob)
473 <td class="indexlinks"></td>
487 <td class="indexlinks"></td>
474 <td>
488 <td>
475 <a href="/b/atom-log" title="subscribe to repository atom feed">
489 <a href="/b/atom-log" title="subscribe to repository atom feed">
476 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
490 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
477 </a>
491 </a>
478 </td>
492 </td>
479 </tr>
493 </tr>
480
494
481 <tr>
495 <tr>
482 <td><a href="/coll/a/?style=paper">coll/a</a></td>
496 <td><a href="/coll/a/?style=paper">coll/a</a></td>
483 <td>unknown</td>
497 <td>unknown</td>
484 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
498 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
485 <td class="age">*</td> (glob)
499 <td class="age">*</td> (glob)
486 <td class="indexlinks"></td>
500 <td class="indexlinks"></td>
487 <td>
501 <td>
488 <a href="/coll/a/atom-log" title="subscribe to repository atom feed">
502 <a href="/coll/a/atom-log" title="subscribe to repository atom feed">
489 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
503 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
490 </a>
504 </a>
491 </td>
505 </td>
492 </tr>
506 </tr>
493
507
494 <tr>
508 <tr>
495 <td><a href="/coll/a/.hg/patches/?style=paper">coll/a/.hg/patches</a></td>
509 <td><a href="/coll/a/.hg/patches/?style=paper">coll/a/.hg/patches</a></td>
496 <td>unknown</td>
510 <td>unknown</td>
497 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
511 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
498 <td class="age">*</td> (glob)
512 <td class="age">*</td> (glob)
499 <td class="indexlinks"></td>
513 <td class="indexlinks"></td>
500 <td>
514 <td>
501 <a href="/coll/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
515 <a href="/coll/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
502 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
516 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
503 </a>
517 </a>
504 </td>
518 </td>
505 </tr>
519 </tr>
506
520
507 <tr>
521 <tr>
508 <td><a href="/coll/b/?style=paper">coll/b</a></td>
522 <td><a href="/coll/b/?style=paper">coll/b</a></td>
509 <td>unknown</td>
523 <td>unknown</td>
510 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
524 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
511 <td class="age">*</td> (glob)
525 <td class="age">*</td> (glob)
512 <td class="indexlinks"></td>
526 <td class="indexlinks"></td>
513 <td>
527 <td>
514 <a href="/coll/b/atom-log" title="subscribe to repository atom feed">
528 <a href="/coll/b/atom-log" title="subscribe to repository atom feed">
515 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
529 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
516 </a>
530 </a>
517 </td>
531 </td>
518 </tr>
532 </tr>
519
533
520 <tr>
534 <tr>
521 <td><a href="/coll/c/?style=paper">coll/c</a></td>
535 <td><a href="/coll/c/?style=paper">coll/c</a></td>
522 <td>unknown</td>
536 <td>unknown</td>
523 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
537 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
524 <td class="age">*</td> (glob)
538 <td class="age">*</td> (glob)
525 <td class="indexlinks"></td>
539 <td class="indexlinks"></td>
526 <td>
540 <td>
527 <a href="/coll/c/atom-log" title="subscribe to repository atom feed">
541 <a href="/coll/c/atom-log" title="subscribe to repository atom feed">
528 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
542 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
529 </a>
543 </a>
530 </td>
544 </td>
531 </tr>
545 </tr>
532
546
533 <tr>
547 <tr>
534 <td><a href="/coll/notrepo/e/?style=paper">coll/notrepo/e</a></td>
548 <td><a href="/coll/notrepo/e/?style=paper">coll/notrepo/e</a></td>
535 <td>unknown</td>
549 <td>unknown</td>
536 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
550 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
537 <td class="age">*</td> (glob)
551 <td class="age">*</td> (glob)
538 <td class="indexlinks"></td>
552 <td class="indexlinks"></td>
539 <td>
553 <td>
540 <a href="/coll/notrepo/e/atom-log" title="subscribe to repository atom feed">
554 <a href="/coll/notrepo/e/atom-log" title="subscribe to repository atom feed">
541 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
555 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
542 </a>
556 </a>
543 </td>
557 </td>
544 </tr>
558 </tr>
545
559
546 <tr>
560 <tr>
547 <td><a href="/coll/notrepo/f/?style=paper">fancy name for repo f</a></td>
561 <td><a href="/coll/notrepo/f/?style=paper">fancy name for repo f</a></td>
548 <td>unknown</td>
562 <td>unknown</td>
549 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
563 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
550 <td class="age">*</td> (glob)
564 <td class="age">*</td> (glob)
551 <td class="indexlinks"></td>
565 <td class="indexlinks"></td>
552 <td>
566 <td>
553 <a href="/coll/notrepo/f/atom-log" title="subscribe to repository atom feed">
567 <a href="/coll/notrepo/f/atom-log" title="subscribe to repository atom feed">
554 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
568 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
555 </a>
569 </a>
556 </td>
570 </td>
557 </tr>
571 </tr>
558
572
559 <tr>
573 <tr>
560 <td><a href="/rcoll/a/?style=paper">rcoll/a</a></td>
574 <td><a href="/rcoll/a/?style=paper">rcoll/a</a></td>
561 <td>unknown</td>
575 <td>unknown</td>
562 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
576 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
563 <td class="age">*</td> (glob)
577 <td class="age">*</td> (glob)
564 <td class="indexlinks"></td>
578 <td class="indexlinks"></td>
565 <td>
579 <td>
566 <a href="/rcoll/a/atom-log" title="subscribe to repository atom feed">
580 <a href="/rcoll/a/atom-log" title="subscribe to repository atom feed">
567 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
581 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
568 </a>
582 </a>
569 </td>
583 </td>
570 </tr>
584 </tr>
571
585
572 <tr>
586 <tr>
573 <td><a href="/rcoll/a/.hg/patches/?style=paper">rcoll/a/.hg/patches</a></td>
587 <td><a href="/rcoll/a/.hg/patches/?style=paper">rcoll/a/.hg/patches</a></td>
574 <td>unknown</td>
588 <td>unknown</td>
575 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
589 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
576 <td class="age">*</td> (glob)
590 <td class="age">*</td> (glob)
577 <td class="indexlinks"></td>
591 <td class="indexlinks"></td>
578 <td>
592 <td>
579 <a href="/rcoll/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
593 <a href="/rcoll/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
580 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
594 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
581 </a>
595 </a>
582 </td>
596 </td>
583 </tr>
597 </tr>
584
598
585 <tr>
599 <tr>
586 <td><a href="/rcoll/b/?style=paper">rcoll/b</a></td>
600 <td><a href="/rcoll/b/?style=paper">rcoll/b</a></td>
587 <td>unknown</td>
601 <td>unknown</td>
588 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
602 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
589 <td class="age">*</td> (glob)
603 <td class="age">*</td> (glob)
590 <td class="indexlinks"></td>
604 <td class="indexlinks"></td>
591 <td>
605 <td>
592 <a href="/rcoll/b/atom-log" title="subscribe to repository atom feed">
606 <a href="/rcoll/b/atom-log" title="subscribe to repository atom feed">
593 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
607 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
594 </a>
608 </a>
595 </td>
609 </td>
596 </tr>
610 </tr>
597
611
598 <tr>
612 <tr>
599 <td><a href="/rcoll/b/d/?style=paper">rcoll/b/d</a></td>
613 <td><a href="/rcoll/b/d/?style=paper">rcoll/b/d</a></td>
600 <td>unknown</td>
614 <td>unknown</td>
601 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
615 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
602 <td class="age">*</td> (glob)
616 <td class="age">*</td> (glob)
603 <td class="indexlinks"></td>
617 <td class="indexlinks"></td>
604 <td>
618 <td>
605 <a href="/rcoll/b/d/atom-log" title="subscribe to repository atom feed">
619 <a href="/rcoll/b/d/atom-log" title="subscribe to repository atom feed">
606 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
620 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
607 </a>
621 </a>
608 </td>
622 </td>
609 </tr>
623 </tr>
610
624
611 <tr>
625 <tr>
612 <td><a href="/rcoll/c/?style=paper">rcoll/c</a></td>
626 <td><a href="/rcoll/c/?style=paper">rcoll/c</a></td>
613 <td>unknown</td>
627 <td>unknown</td>
614 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
628 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
615 <td class="age">*</td> (glob)
629 <td class="age">*</td> (glob)
616 <td class="indexlinks"></td>
630 <td class="indexlinks"></td>
617 <td>
631 <td>
618 <a href="/rcoll/c/atom-log" title="subscribe to repository atom feed">
632 <a href="/rcoll/c/atom-log" title="subscribe to repository atom feed">
619 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
633 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
620 </a>
634 </a>
621 </td>
635 </td>
622 </tr>
636 </tr>
623
637
624 <tr>
638 <tr>
625 <td><a href="/rcoll/notrepo/e/?style=paper">rcoll/notrepo/e</a></td>
639 <td><a href="/rcoll/notrepo/e/?style=paper">rcoll/notrepo/e</a></td>
626 <td>unknown</td>
640 <td>unknown</td>
627 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
641 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
628 <td class="age">*</td> (glob)
642 <td class="age">*</td> (glob)
629 <td class="indexlinks"></td>
643 <td class="indexlinks"></td>
630 <td>
644 <td>
631 <a href="/rcoll/notrepo/e/atom-log" title="subscribe to repository atom feed">
645 <a href="/rcoll/notrepo/e/atom-log" title="subscribe to repository atom feed">
632 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
646 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
633 </a>
647 </a>
634 </td>
648 </td>
635 </tr>
649 </tr>
636
650
637 <tr>
651 <tr>
638 <td><a href="/rcoll/notrepo/e/e2/?style=paper">rcoll/notrepo/e/e2</a></td>
652 <td><a href="/rcoll/notrepo/e/e2/?style=paper">rcoll/notrepo/e/e2</a></td>
639 <td>unknown</td>
653 <td>unknown</td>
640 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
654 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
641 <td class="age">*</td> (glob)
655 <td class="age">*</td> (glob)
642 <td class="indexlinks"></td>
656 <td class="indexlinks"></td>
643 <td>
657 <td>
644 <a href="/rcoll/notrepo/e/e2/atom-log" title="subscribe to repository atom feed">
658 <a href="/rcoll/notrepo/e/e2/atom-log" title="subscribe to repository atom feed">
645 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
659 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
646 </a>
660 </a>
647 </td>
661 </td>
648 </tr>
662 </tr>
649
663
650 <tr>
664 <tr>
651 <td><a href="/rcoll/notrepo/f/?style=paper">fancy name for repo f</a></td>
665 <td><a href="/rcoll/notrepo/f/?style=paper">fancy name for repo f</a></td>
652 <td>unknown</td>
666 <td>unknown</td>
653 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
667 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
654 <td class="age">*</td> (glob)
668 <td class="age">*</td> (glob)
655 <td class="indexlinks"></td>
669 <td class="indexlinks"></td>
656 <td>
670 <td>
657 <a href="/rcoll/notrepo/f/atom-log" title="subscribe to repository atom feed">
671 <a href="/rcoll/notrepo/f/atom-log" title="subscribe to repository atom feed">
658 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
672 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
659 </a>
673 </a>
660 </td>
674 </td>
661 </tr>
675 </tr>
662
676
663 <tr>
677 <tr>
664 <td><a href="/rcoll/notrepo/f/f2/?style=paper">rcoll/notrepo/f/f2</a></td>
678 <td><a href="/rcoll/notrepo/f/f2/?style=paper">rcoll/notrepo/f/f2</a></td>
665 <td>unknown</td>
679 <td>unknown</td>
666 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
680 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
667 <td class="age">*</td> (glob)
681 <td class="age">*</td> (glob)
668 <td class="indexlinks"></td>
682 <td class="indexlinks"></td>
669 <td>
683 <td>
670 <a href="/rcoll/notrepo/f/f2/atom-log" title="subscribe to repository atom feed">
684 <a href="/rcoll/notrepo/f/f2/atom-log" title="subscribe to repository atom feed">
671 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
685 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
672 </a>
686 </a>
673 </td>
687 </td>
674 </tr>
688 </tr>
675
689
676 <tr>
690 <tr>
677 <td><a href="/star/webdir/a/?style=paper">star/webdir/a</a></td>
691 <td><a href="/star/webdir/a/?style=paper">star/webdir/a</a></td>
678 <td>unknown</td>
692 <td>unknown</td>
679 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
693 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
680 <td class="age">*</td> (glob)
694 <td class="age">*</td> (glob)
681 <td class="indexlinks"></td>
695 <td class="indexlinks"></td>
682 <td>
696 <td>
683 <a href="/star/webdir/a/atom-log" title="subscribe to repository atom feed">
697 <a href="/star/webdir/a/atom-log" title="subscribe to repository atom feed">
684 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
698 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
685 </a>
699 </a>
686 </td>
700 </td>
687 </tr>
701 </tr>
688
702
689 <tr>
703 <tr>
690 <td><a href="/star/webdir/a/.hg/patches/?style=paper">star/webdir/a/.hg/patches</a></td>
704 <td><a href="/star/webdir/a/.hg/patches/?style=paper">star/webdir/a/.hg/patches</a></td>
691 <td>unknown</td>
705 <td>unknown</td>
692 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
706 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
693 <td class="age">*</td> (glob)
707 <td class="age">*</td> (glob)
694 <td class="indexlinks"></td>
708 <td class="indexlinks"></td>
695 <td>
709 <td>
696 <a href="/star/webdir/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
710 <a href="/star/webdir/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
697 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
711 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
698 </a>
712 </a>
699 </td>
713 </td>
700 </tr>
714 </tr>
701
715
702 <tr>
716 <tr>
703 <td><a href="/star/webdir/b/?style=paper">star/webdir/b</a></td>
717 <td><a href="/star/webdir/b/?style=paper">star/webdir/b</a></td>
704 <td>unknown</td>
718 <td>unknown</td>
705 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
719 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
706 <td class="age">*</td> (glob)
720 <td class="age">*</td> (glob)
707 <td class="indexlinks"></td>
721 <td class="indexlinks"></td>
708 <td>
722 <td>
709 <a href="/star/webdir/b/atom-log" title="subscribe to repository atom feed">
723 <a href="/star/webdir/b/atom-log" title="subscribe to repository atom feed">
710 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
724 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
711 </a>
725 </a>
712 </td>
726 </td>
713 </tr>
727 </tr>
714
728
715 <tr>
729 <tr>
716 <td><a href="/star/webdir/c/?style=paper">star/webdir/c</a></td>
730 <td><a href="/star/webdir/c/?style=paper">star/webdir/c</a></td>
717 <td>unknown</td>
731 <td>unknown</td>
718 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
732 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
719 <td class="age">*</td> (glob)
733 <td class="age">*</td> (glob)
720 <td class="indexlinks"></td>
734 <td class="indexlinks"></td>
721 <td>
735 <td>
722 <a href="/star/webdir/c/atom-log" title="subscribe to repository atom feed">
736 <a href="/star/webdir/c/atom-log" title="subscribe to repository atom feed">
723 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
737 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
724 </a>
738 </a>
725 </td>
739 </td>
726 </tr>
740 </tr>
727
741
728 <tr>
742 <tr>
729 <td><a href="/star/webdir/notrepo/e/?style=paper">star/webdir/notrepo/e</a></td>
743 <td><a href="/star/webdir/notrepo/e/?style=paper">star/webdir/notrepo/e</a></td>
730 <td>unknown</td>
744 <td>unknown</td>
731 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
745 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
732 <td class="age">*</td> (glob)
746 <td class="age">*</td> (glob)
733 <td class="indexlinks"></td>
747 <td class="indexlinks"></td>
734 <td>
748 <td>
735 <a href="/star/webdir/notrepo/e/atom-log" title="subscribe to repository atom feed">
749 <a href="/star/webdir/notrepo/e/atom-log" title="subscribe to repository atom feed">
736 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
750 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
737 </a>
751 </a>
738 </td>
752 </td>
739 </tr>
753 </tr>
740
754
741 <tr>
755 <tr>
742 <td><a href="/star/webdir/notrepo/f/?style=paper">fancy name for repo f</a></td>
756 <td><a href="/star/webdir/notrepo/f/?style=paper">fancy name for repo f</a></td>
743 <td>unknown</td>
757 <td>unknown</td>
744 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
758 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
745 <td class="age">*</td> (glob)
759 <td class="age">*</td> (glob)
746 <td class="indexlinks"></td>
760 <td class="indexlinks"></td>
747 <td>
761 <td>
748 <a href="/star/webdir/notrepo/f/atom-log" title="subscribe to repository atom feed">
762 <a href="/star/webdir/notrepo/f/atom-log" title="subscribe to repository atom feed">
749 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
763 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
750 </a>
764 </a>
751 </td>
765 </td>
752 </tr>
766 </tr>
753
767
754 <tr>
768 <tr>
755 <td><a href="/starstar/webdir/a/?style=paper">starstar/webdir/a</a></td>
769 <td><a href="/starstar/webdir/a/?style=paper">starstar/webdir/a</a></td>
756 <td>unknown</td>
770 <td>unknown</td>
757 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
771 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
758 <td class="age">*</td> (glob)
772 <td class="age">*</td> (glob)
759 <td class="indexlinks"></td>
773 <td class="indexlinks"></td>
760 <td>
774 <td>
761 <a href="/starstar/webdir/a/atom-log" title="subscribe to repository atom feed">
775 <a href="/starstar/webdir/a/atom-log" title="subscribe to repository atom feed">
762 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
776 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
763 </a>
777 </a>
764 </td>
778 </td>
765 </tr>
779 </tr>
766
780
767 <tr>
781 <tr>
768 <td><a href="/starstar/webdir/a/.hg/patches/?style=paper">starstar/webdir/a/.hg/patches</a></td>
782 <td><a href="/starstar/webdir/a/.hg/patches/?style=paper">starstar/webdir/a/.hg/patches</a></td>
769 <td>unknown</td>
783 <td>unknown</td>
770 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
784 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
771 <td class="age">*</td> (glob)
785 <td class="age">*</td> (glob)
772 <td class="indexlinks"></td>
786 <td class="indexlinks"></td>
773 <td>
787 <td>
774 <a href="/starstar/webdir/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
788 <a href="/starstar/webdir/a/.hg/patches/atom-log" title="subscribe to repository atom feed">
775 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
789 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
776 </a>
790 </a>
777 </td>
791 </td>
778 </tr>
792 </tr>
779
793
780 <tr>
794 <tr>
781 <td><a href="/starstar/webdir/b/?style=paper">starstar/webdir/b</a></td>
795 <td><a href="/starstar/webdir/b/?style=paper">starstar/webdir/b</a></td>
782 <td>unknown</td>
796 <td>unknown</td>
783 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
797 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
784 <td class="age">*</td> (glob)
798 <td class="age">*</td> (glob)
785 <td class="indexlinks"></td>
799 <td class="indexlinks"></td>
786 <td>
800 <td>
787 <a href="/starstar/webdir/b/atom-log" title="subscribe to repository atom feed">
801 <a href="/starstar/webdir/b/atom-log" title="subscribe to repository atom feed">
788 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
802 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
789 </a>
803 </a>
790 </td>
804 </td>
791 </tr>
805 </tr>
792
806
793 <tr>
807 <tr>
794 <td><a href="/starstar/webdir/b/d/?style=paper">starstar/webdir/b/d</a></td>
808 <td><a href="/starstar/webdir/b/d/?style=paper">starstar/webdir/b/d</a></td>
795 <td>unknown</td>
809 <td>unknown</td>
796 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
810 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
797 <td class="age">*</td> (glob)
811 <td class="age">*</td> (glob)
798 <td class="indexlinks"></td>
812 <td class="indexlinks"></td>
799 <td>
813 <td>
800 <a href="/starstar/webdir/b/d/atom-log" title="subscribe to repository atom feed">
814 <a href="/starstar/webdir/b/d/atom-log" title="subscribe to repository atom feed">
801 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
815 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
802 </a>
816 </a>
803 </td>
817 </td>
804 </tr>
818 </tr>
805
819
806 <tr>
820 <tr>
807 <td><a href="/starstar/webdir/c/?style=paper">starstar/webdir/c</a></td>
821 <td><a href="/starstar/webdir/c/?style=paper">starstar/webdir/c</a></td>
808 <td>unknown</td>
822 <td>unknown</td>
809 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
823 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
810 <td class="age">*</td> (glob)
824 <td class="age">*</td> (glob)
811 <td class="indexlinks"></td>
825 <td class="indexlinks"></td>
812 <td>
826 <td>
813 <a href="/starstar/webdir/c/atom-log" title="subscribe to repository atom feed">
827 <a href="/starstar/webdir/c/atom-log" title="subscribe to repository atom feed">
814 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
828 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
815 </a>
829 </a>
816 </td>
830 </td>
817 </tr>
831 </tr>
818
832
819 <tr>
833 <tr>
820 <td><a href="/starstar/webdir/notrepo/e/?style=paper">starstar/webdir/notrepo/e</a></td>
834 <td><a href="/starstar/webdir/notrepo/e/?style=paper">starstar/webdir/notrepo/e</a></td>
821 <td>unknown</td>
835 <td>unknown</td>
822 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
836 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
823 <td class="age">*</td> (glob)
837 <td class="age">*</td> (glob)
824 <td class="indexlinks"></td>
838 <td class="indexlinks"></td>
825 <td>
839 <td>
826 <a href="/starstar/webdir/notrepo/e/atom-log" title="subscribe to repository atom feed">
840 <a href="/starstar/webdir/notrepo/e/atom-log" title="subscribe to repository atom feed">
827 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
841 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
828 </a>
842 </a>
829 </td>
843 </td>
830 </tr>
844 </tr>
831
845
832 <tr>
846 <tr>
833 <td><a href="/starstar/webdir/notrepo/e/e2/?style=paper">starstar/webdir/notrepo/e/e2</a></td>
847 <td><a href="/starstar/webdir/notrepo/e/e2/?style=paper">starstar/webdir/notrepo/e/e2</a></td>
834 <td>unknown</td>
848 <td>unknown</td>
835 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
849 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
836 <td class="age">*</td> (glob)
850 <td class="age">*</td> (glob)
837 <td class="indexlinks"></td>
851 <td class="indexlinks"></td>
838 <td>
852 <td>
839 <a href="/starstar/webdir/notrepo/e/e2/atom-log" title="subscribe to repository atom feed">
853 <a href="/starstar/webdir/notrepo/e/e2/atom-log" title="subscribe to repository atom feed">
840 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
854 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
841 </a>
855 </a>
842 </td>
856 </td>
843 </tr>
857 </tr>
844
858
845 <tr>
859 <tr>
846 <td><a href="/starstar/webdir/notrepo/f/?style=paper">fancy name for repo f</a></td>
860 <td><a href="/starstar/webdir/notrepo/f/?style=paper">fancy name for repo f</a></td>
847 <td>unknown</td>
861 <td>unknown</td>
848 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
862 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
849 <td class="age">*</td> (glob)
863 <td class="age">*</td> (glob)
850 <td class="indexlinks"></td>
864 <td class="indexlinks"></td>
851 <td>
865 <td>
852 <a href="/starstar/webdir/notrepo/f/atom-log" title="subscribe to repository atom feed">
866 <a href="/starstar/webdir/notrepo/f/atom-log" title="subscribe to repository atom feed">
853 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
867 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
854 </a>
868 </a>
855 </td>
869 </td>
856 </tr>
870 </tr>
857
871
858 <tr>
872 <tr>
859 <td><a href="/starstar/webdir/notrepo/f/f2/?style=paper">starstar/webdir/notrepo/f/f2</a></td>
873 <td><a href="/starstar/webdir/notrepo/f/f2/?style=paper">starstar/webdir/notrepo/f/f2</a></td>
860 <td>unknown</td>
874 <td>unknown</td>
861 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
875 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
862 <td class="age">*</td> (glob)
876 <td class="age">*</td> (glob)
863 <td class="indexlinks"></td>
877 <td class="indexlinks"></td>
864 <td>
878 <td>
865 <a href="/starstar/webdir/notrepo/f/f2/atom-log" title="subscribe to repository atom feed">
879 <a href="/starstar/webdir/notrepo/f/f2/atom-log" title="subscribe to repository atom feed">
866 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
880 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
867 </a>
881 </a>
868 </td>
882 </td>
869 </tr>
883 </tr>
870
884
871 <tr>
885 <tr>
872 <td><a href="/astar/?style=paper">astar</a></td>
886 <td><a href="/astar/?style=paper">astar</a></td>
873 <td>unknown</td>
887 <td>unknown</td>
874 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
888 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
875 <td class="age">*</td> (glob)
889 <td class="age">*</td> (glob)
876 <td class="indexlinks"></td>
890 <td class="indexlinks"></td>
877 <td>
891 <td>
878 <a href="/astar/atom-log" title="subscribe to repository atom feed">
892 <a href="/astar/atom-log" title="subscribe to repository atom feed">
879 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
893 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
880 </a>
894 </a>
881 </td>
895 </td>
882 </tr>
896 </tr>
883
897
884 <tr>
898 <tr>
885 <td><a href="/astar/.hg/patches/?style=paper">astar/.hg/patches</a></td>
899 <td><a href="/astar/.hg/patches/?style=paper">astar/.hg/patches</a></td>
886 <td>unknown</td>
900 <td>unknown</td>
887 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
901 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
888 <td class="age">*</td> (glob)
902 <td class="age">*</td> (glob)
889 <td class="indexlinks"></td>
903 <td class="indexlinks"></td>
890 <td>
904 <td>
891 <a href="/astar/.hg/patches/atom-log" title="subscribe to repository atom feed">
905 <a href="/astar/.hg/patches/atom-log" title="subscribe to repository atom feed">
892 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
906 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
893 </a>
907 </a>
894 </td>
908 </td>
895 </tr>
909 </tr>
896
910
897 </tbody>
911 </tbody>
898 </table>
912 </table>
899 </div>
913 </div>
900 </div>
914 </div>
901
915
902
916
903 </body>
917 </body>
904 </html>
918 </html>
905
919
906 $ get-with-headers.py localhost:$HGPORT1 't?style=raw'
920 $ get-with-headers.py localhost:$HGPORT1 't?style=raw'
907 200 Script output follows
921 200 Script output follows
908
922
909
923
910 /t/a/
924 /t/a/
911
925
912 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
926 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
913 200 Script output follows
927 200 Script output follows
914
928
915
929
916 /t/a/
930 /t/a/
917
931
918 $ get-with-headers.py localhost:$HGPORT1 't/?style=paper'
932 $ get-with-headers.py localhost:$HGPORT1 't/?style=paper'
919 200 Script output follows
933 200 Script output follows
920
934
921 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
935 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
922 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
936 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
923 <head>
937 <head>
924 <link rel="icon" href="/static/hgicon.png" type="image/png" />
938 <link rel="icon" href="/static/hgicon.png" type="image/png" />
925 <meta name="robots" content="index, nofollow" />
939 <meta name="robots" content="index, nofollow" />
926 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
940 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
927 <script type="text/javascript" src="/static/mercurial.js"></script>
941 <script type="text/javascript" src="/static/mercurial.js"></script>
928
942
929 <title>Mercurial repositories index</title>
943 <title>Mercurial repositories index</title>
930 </head>
944 </head>
931 <body>
945 <body>
932
946
933 <div class="container">
947 <div class="container">
934 <div class="menu">
948 <div class="menu">
935 <a href="https://mercurial-scm.org/">
949 <a href="https://mercurial-scm.org/">
936 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
950 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
937 </div>
951 </div>
938 <div class="main">
952 <div class="main">
939 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/t">t</a> </h2>
953 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/t">t</a> </h2>
940
954
941 <table class="bigtable">
955 <table class="bigtable">
942 <thead>
956 <thead>
943 <tr>
957 <tr>
944 <th><a href="?sort=name">Name</a></th>
958 <th><a href="?sort=name">Name</a></th>
945 <th><a href="?sort=description">Description</a></th>
959 <th><a href="?sort=description">Description</a></th>
946 <th><a href="?sort=contact">Contact</a></th>
960 <th><a href="?sort=contact">Contact</a></th>
947 <th><a href="?sort=lastchange">Last modified</a></th>
961 <th><a href="?sort=lastchange">Last modified</a></th>
948 <th>&nbsp;</th>
962 <th>&nbsp;</th>
949 <th>&nbsp;</th>
963 <th>&nbsp;</th>
950 </tr>
964 </tr>
951 </thead>
965 </thead>
952 <tbody class="stripes2">
966 <tbody class="stripes2">
953
967
954 <tr>
968 <tr>
955 <td><a href="/t/a/?style=paper">a</a></td>
969 <td><a href="/t/a/?style=paper">a</a></td>
956 <td>unknown</td>
970 <td>unknown</td>
957 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
971 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
958 <td class="age">*</td> (glob)
972 <td class="age">*</td> (glob)
959 <td class="indexlinks"></td>
973 <td class="indexlinks"></td>
960 <td>
974 <td>
961 <a href="/t/a/atom-log" title="subscribe to repository atom feed">
975 <a href="/t/a/atom-log" title="subscribe to repository atom feed">
962 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
976 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="subscribe to repository atom feed">
963 </a>
977 </a>
964 </td>
978 </td>
965 </tr>
979 </tr>
966
980
967 </tbody>
981 </tbody>
968 </table>
982 </table>
969 </div>
983 </div>
970 </div>
984 </div>
971
985
972
986
973 </body>
987 </body>
974 </html>
988 </html>
975
989
976 $ get-with-headers.py localhost:$HGPORT1 't/a?style=atom'
990 $ get-with-headers.py localhost:$HGPORT1 't/a?style=atom'
977 200 Script output follows
991 200 Script output follows
978
992
979 <?xml version="1.0" encoding="ascii"?>
993 <?xml version="1.0" encoding="ascii"?>
980 <feed xmlns="http://www.w3.org/2005/Atom">
994 <feed xmlns="http://www.w3.org/2005/Atom">
981 <!-- Changelog -->
995 <!-- Changelog -->
982 <id>http://*:$HGPORT1/t/a/</id> (glob)
996 <id>http://*:$HGPORT1/t/a/</id> (glob)
983 <link rel="self" href="http://*:$HGPORT1/t/a/atom-log"/> (glob)
997 <link rel="self" href="http://*:$HGPORT1/t/a/atom-log"/> (glob)
984 <link rel="alternate" href="http://*:$HGPORT1/t/a/"/> (glob)
998 <link rel="alternate" href="http://*:$HGPORT1/t/a/"/> (glob)
985 <title>t/a Changelog</title>
999 <title>t/a Changelog</title>
986 <updated>1970-01-01T00:00:01+00:00</updated>
1000 <updated>1970-01-01T00:00:01+00:00</updated>
987
1001
988 <entry>
1002 <entry>
989 <title>[default] a</title>
1003 <title>[default] a</title>
990 <id>http://*:$HGPORT1/t/a/#changeset-8580ff50825a50c8f716709acdf8de0deddcd6ab</id> (glob)
1004 <id>http://*:$HGPORT1/t/a/#changeset-8580ff50825a50c8f716709acdf8de0deddcd6ab</id> (glob)
991 <link href="http://*:$HGPORT1/t/a/rev/8580ff50825a"/> (glob)
1005 <link href="http://*:$HGPORT1/t/a/rev/8580ff50825a"/> (glob)
992 <author>
1006 <author>
993 <name>test</name>
1007 <name>test</name>
994 <email>&#116;&#101;&#115;&#116;</email>
1008 <email>&#116;&#101;&#115;&#116;</email>
995 </author>
1009 </author>
996 <updated>1970-01-01T00:00:01+00:00</updated>
1010 <updated>1970-01-01T00:00:01+00:00</updated>
997 <published>1970-01-01T00:00:01+00:00</published>
1011 <published>1970-01-01T00:00:01+00:00</published>
998 <content type="xhtml">
1012 <content type="xhtml">
999 <table xmlns="http://www.w3.org/1999/xhtml">
1013 <table xmlns="http://www.w3.org/1999/xhtml">
1000 <tr>
1014 <tr>
1001 <th style="text-align:left;">changeset</th>
1015 <th style="text-align:left;">changeset</th>
1002 <td>8580ff50825a</td>
1016 <td>8580ff50825a</td>
1003 </tr>
1017 </tr>
1004 <tr>
1018 <tr>
1005 <th style="text-align:left;">branch</th>
1019 <th style="text-align:left;">branch</th>
1006 <td>default</td>
1020 <td>default</td>
1007 </tr>
1021 </tr>
1008 <tr>
1022 <tr>
1009 <th style="text-align:left;">bookmark</th>
1023 <th style="text-align:left;">bookmark</th>
1010 <td></td>
1024 <td></td>
1011 </tr>
1025 </tr>
1012 <tr>
1026 <tr>
1013 <th style="text-align:left;">tag</th>
1027 <th style="text-align:left;">tag</th>
1014 <td>tip</td>
1028 <td>tip</td>
1015 </tr>
1029 </tr>
1016 <tr>
1030 <tr>
1017 <th style="text-align:left;">user</th>
1031 <th style="text-align:left;">user</th>
1018 <td>&#116;&#101;&#115;&#116;</td>
1032 <td>&#116;&#101;&#115;&#116;</td>
1019 </tr>
1033 </tr>
1020 <tr>
1034 <tr>
1021 <th style="text-align:left;vertical-align:top;">description</th>
1035 <th style="text-align:left;vertical-align:top;">description</th>
1022 <td>a</td>
1036 <td>a</td>
1023 </tr>
1037 </tr>
1024 <tr>
1038 <tr>
1025 <th style="text-align:left;vertical-align:top;">files</th>
1039 <th style="text-align:left;vertical-align:top;">files</th>
1026 <td>a<br /></td>
1040 <td>a<br /></td>
1027 </tr>
1041 </tr>
1028 </table>
1042 </table>
1029 </content>
1043 </content>
1030 </entry>
1044 </entry>
1031
1045
1032 </feed>
1046 </feed>
1033 $ get-with-headers.py localhost:$HGPORT1 't/a/?style=atom'
1047 $ get-with-headers.py localhost:$HGPORT1 't/a/?style=atom'
1034 200 Script output follows
1048 200 Script output follows
1035
1049
1036 <?xml version="1.0" encoding="ascii"?>
1050 <?xml version="1.0" encoding="ascii"?>
1037 <feed xmlns="http://www.w3.org/2005/Atom">
1051 <feed xmlns="http://www.w3.org/2005/Atom">
1038 <!-- Changelog -->
1052 <!-- Changelog -->
1039 <id>http://*:$HGPORT1/t/a/</id> (glob)
1053 <id>http://*:$HGPORT1/t/a/</id> (glob)
1040 <link rel="self" href="http://*:$HGPORT1/t/a/atom-log"/> (glob)
1054 <link rel="self" href="http://*:$HGPORT1/t/a/atom-log"/> (glob)
1041 <link rel="alternate" href="http://*:$HGPORT1/t/a/"/> (glob)
1055 <link rel="alternate" href="http://*:$HGPORT1/t/a/"/> (glob)
1042 <title>t/a Changelog</title>
1056 <title>t/a Changelog</title>
1043 <updated>1970-01-01T00:00:01+00:00</updated>
1057 <updated>1970-01-01T00:00:01+00:00</updated>
1044
1058
1045 <entry>
1059 <entry>
1046 <title>[default] a</title>
1060 <title>[default] a</title>
1047 <id>http://*:$HGPORT1/t/a/#changeset-8580ff50825a50c8f716709acdf8de0deddcd6ab</id> (glob)
1061 <id>http://*:$HGPORT1/t/a/#changeset-8580ff50825a50c8f716709acdf8de0deddcd6ab</id> (glob)
1048 <link href="http://*:$HGPORT1/t/a/rev/8580ff50825a"/> (glob)
1062 <link href="http://*:$HGPORT1/t/a/rev/8580ff50825a"/> (glob)
1049 <author>
1063 <author>
1050 <name>test</name>
1064 <name>test</name>
1051 <email>&#116;&#101;&#115;&#116;</email>
1065 <email>&#116;&#101;&#115;&#116;</email>
1052 </author>
1066 </author>
1053 <updated>1970-01-01T00:00:01+00:00</updated>
1067 <updated>1970-01-01T00:00:01+00:00</updated>
1054 <published>1970-01-01T00:00:01+00:00</published>
1068 <published>1970-01-01T00:00:01+00:00</published>
1055 <content type="xhtml">
1069 <content type="xhtml">
1056 <table xmlns="http://www.w3.org/1999/xhtml">
1070 <table xmlns="http://www.w3.org/1999/xhtml">
1057 <tr>
1071 <tr>
1058 <th style="text-align:left;">changeset</th>
1072 <th style="text-align:left;">changeset</th>
1059 <td>8580ff50825a</td>
1073 <td>8580ff50825a</td>
1060 </tr>
1074 </tr>
1061 <tr>
1075 <tr>
1062 <th style="text-align:left;">branch</th>
1076 <th style="text-align:left;">branch</th>
1063 <td>default</td>
1077 <td>default</td>
1064 </tr>
1078 </tr>
1065 <tr>
1079 <tr>
1066 <th style="text-align:left;">bookmark</th>
1080 <th style="text-align:left;">bookmark</th>
1067 <td></td>
1081 <td></td>
1068 </tr>
1082 </tr>
1069 <tr>
1083 <tr>
1070 <th style="text-align:left;">tag</th>
1084 <th style="text-align:left;">tag</th>
1071 <td>tip</td>
1085 <td>tip</td>
1072 </tr>
1086 </tr>
1073 <tr>
1087 <tr>
1074 <th style="text-align:left;">user</th>
1088 <th style="text-align:left;">user</th>
1075 <td>&#116;&#101;&#115;&#116;</td>
1089 <td>&#116;&#101;&#115;&#116;</td>
1076 </tr>
1090 </tr>
1077 <tr>
1091 <tr>
1078 <th style="text-align:left;vertical-align:top;">description</th>
1092 <th style="text-align:left;vertical-align:top;">description</th>
1079 <td>a</td>
1093 <td>a</td>
1080 </tr>
1094 </tr>
1081 <tr>
1095 <tr>
1082 <th style="text-align:left;vertical-align:top;">files</th>
1096 <th style="text-align:left;vertical-align:top;">files</th>
1083 <td>a<br /></td>
1097 <td>a<br /></td>
1084 </tr>
1098 </tr>
1085 </table>
1099 </table>
1086 </content>
1100 </content>
1087 </entry>
1101 </entry>
1088
1102
1089 </feed>
1103 </feed>
1090 $ get-with-headers.py localhost:$HGPORT1 't/a/file/tip/a?style=raw'
1104 $ get-with-headers.py localhost:$HGPORT1 't/a/file/tip/a?style=raw'
1091 200 Script output follows
1105 200 Script output follows
1092
1106
1093 a
1107 a
1094
1108
1095 Test [paths] '*' extension
1109 Test [paths] '*' extension
1096
1110
1097 $ get-with-headers.py localhost:$HGPORT1 'coll/?style=raw'
1111 $ get-with-headers.py localhost:$HGPORT1 'coll/?style=raw'
1098 200 Script output follows
1112 200 Script output follows
1099
1113
1100
1114
1101 /coll/a/
1115 /coll/a/
1102 /coll/a/.hg/patches/
1116 /coll/a/.hg/patches/
1103 /coll/b/
1117 /coll/b/
1104 /coll/c/
1118 /coll/c/
1105 /coll/notrepo/e/
1119 /coll/notrepo/e/
1106 /coll/notrepo/f/
1120 /coll/notrepo/f/
1107
1121
1108 $ get-with-headers.py localhost:$HGPORT1 'coll/a/file/tip/a?style=raw'
1122 $ get-with-headers.py localhost:$HGPORT1 'coll/a/file/tip/a?style=raw'
1109 200 Script output follows
1123 200 Script output follows
1110
1124
1111 a
1125 a
1112
1126
1113 Test [paths] '**' extension
1127 Test [paths] '**' extension
1114
1128
1115 $ get-with-headers.py localhost:$HGPORT1 'rcoll/?style=raw'
1129 $ get-with-headers.py localhost:$HGPORT1 'rcoll/?style=raw'
1116 200 Script output follows
1130 200 Script output follows
1117
1131
1118
1132
1119 /rcoll/a/
1133 /rcoll/a/
1120 /rcoll/a/.hg/patches/
1134 /rcoll/a/.hg/patches/
1121 /rcoll/b/
1135 /rcoll/b/
1122 /rcoll/b/d/
1136 /rcoll/b/d/
1123 /rcoll/c/
1137 /rcoll/c/
1124 /rcoll/notrepo/e/
1138 /rcoll/notrepo/e/
1125 /rcoll/notrepo/e/e2/
1139 /rcoll/notrepo/e/e2/
1126 /rcoll/notrepo/f/
1140 /rcoll/notrepo/f/
1127 /rcoll/notrepo/f/f2/
1141 /rcoll/notrepo/f/f2/
1128
1142
1129 $ get-with-headers.py localhost:$HGPORT1 'rcoll/b/d/file/tip/d?style=raw'
1143 $ get-with-headers.py localhost:$HGPORT1 'rcoll/b/d/file/tip/d?style=raw'
1130 200 Script output follows
1144 200 Script output follows
1131
1145
1132 d
1146 d
1133
1147
1134 Test collapse = True
1148 Test collapse = True
1135
1149
1136 $ killdaemons.py
1150 $ killdaemons.py
1137 $ cat >> paths.conf <<EOF
1151 $ cat >> paths.conf <<EOF
1138 > [web]
1152 > [web]
1139 > collapse=true
1153 > collapse=true
1140 > descend = true
1154 > descend = true
1141 > EOF
1155 > EOF
1142 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1156 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1143 > -A access-paths.log -E error-paths-3.log
1157 > -A access-paths.log -E error-paths-3.log
1144 $ cat hg.pid >> $DAEMON_PIDS
1158 $ cat hg.pid >> $DAEMON_PIDS
1145 $ get-with-headers.py localhost:$HGPORT1 'coll/?style=raw'
1159 $ get-with-headers.py localhost:$HGPORT1 'coll/?style=raw'
1146 200 Script output follows
1160 200 Script output follows
1147
1161
1148
1162
1149 /coll/a/
1163 /coll/a/
1150 /coll/a/.hg/patches/
1164 /coll/a/.hg/patches/
1151 /coll/b/
1165 /coll/b/
1152 /coll/c/
1166 /coll/c/
1153 /coll/notrepo/
1167 /coll/notrepo/
1154
1168
1155 $ get-with-headers.py localhost:$HGPORT1 'coll/a/file/tip/a?style=raw'
1169 $ get-with-headers.py localhost:$HGPORT1 'coll/a/file/tip/a?style=raw'
1156 200 Script output follows
1170 200 Script output follows
1157
1171
1158 a
1172 a
1159 $ get-with-headers.py localhost:$HGPORT1 'rcoll/?style=raw'
1173 $ get-with-headers.py localhost:$HGPORT1 'rcoll/?style=raw'
1160 200 Script output follows
1174 200 Script output follows
1161
1175
1162
1176
1163 /rcoll/a/
1177 /rcoll/a/
1164 /rcoll/a/.hg/patches/
1178 /rcoll/a/.hg/patches/
1165 /rcoll/b/
1179 /rcoll/b/
1166 /rcoll/b/d/
1180 /rcoll/b/d/
1167 /rcoll/c/
1181 /rcoll/c/
1168 /rcoll/notrepo/
1182 /rcoll/notrepo/
1169
1183
1170 $ get-with-headers.py localhost:$HGPORT1 'rcoll/b/d/file/tip/d?style=raw'
1184 $ get-with-headers.py localhost:$HGPORT1 'rcoll/b/d/file/tip/d?style=raw'
1171 200 Script output follows
1185 200 Script output follows
1172
1186
1173 d
1187 d
1174
1188
1175 Test intermediate directories
1189 Test intermediate directories
1176
1190
1177 Hide the subrepo parent
1191 Hide the subrepo parent
1178
1192
1179 $ cp $root/notrepo/f/.hg/hgrc $root/notrepo/f/.hg/hgrc.bak
1193 $ cp $root/notrepo/f/.hg/hgrc $root/notrepo/f/.hg/hgrc.bak
1180 $ cat >> $root/notrepo/f/.hg/hgrc << EOF
1194 $ cat >> $root/notrepo/f/.hg/hgrc << EOF
1181 > [web]
1195 > [web]
1182 > hidden = True
1196 > hidden = True
1183 > EOF
1197 > EOF
1184
1198
1185 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/?style=raw'
1199 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/?style=raw'
1186 200 Script output follows
1200 200 Script output follows
1187
1201
1188
1202
1189 /rcoll/notrepo/e/
1203 /rcoll/notrepo/e/
1190 /rcoll/notrepo/e/e2/
1204 /rcoll/notrepo/e/e2/
1191
1205
1192
1206
1193 Subrepo parent not hidden
1207 Subrepo parent not hidden
1194 $ mv $root/notrepo/f/.hg/hgrc.bak $root/notrepo/f/.hg/hgrc
1208 $ mv $root/notrepo/f/.hg/hgrc.bak $root/notrepo/f/.hg/hgrc
1195
1209
1196 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/?style=raw'
1210 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/?style=raw'
1197 200 Script output follows
1211 200 Script output follows
1198
1212
1199
1213
1200 /rcoll/notrepo/e/
1214 /rcoll/notrepo/e/
1201 /rcoll/notrepo/e/e2/
1215 /rcoll/notrepo/e/e2/
1202 /rcoll/notrepo/f/
1216 /rcoll/notrepo/f/
1203 /rcoll/notrepo/f/f2/
1217 /rcoll/notrepo/f/f2/
1204
1218
1205
1219
1206 Test repositories inside intermediate directories
1220 Test repositories inside intermediate directories
1207
1221
1208 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/e/file/tip/e?style=raw'
1222 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/e/file/tip/e?style=raw'
1209 200 Script output follows
1223 200 Script output follows
1210
1224
1211 e
1225 e
1212
1226
1213 Test subrepositories inside intermediate directories
1227 Test subrepositories inside intermediate directories
1214
1228
1215 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/f2/file/tip/f2?style=raw'
1229 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/f2/file/tip/f2?style=raw'
1216 200 Script output follows
1230 200 Script output follows
1217
1231
1218 f2
1232 f2
1219
1233
1234 Test accessing file that is shadowed by another repository
1235
1236 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/file/tip/f3/file?style=raw'
1237 403 Forbidden
1238
1239
1240 error: path 'f3/file' is inside nested repo 'f3'
1241 [1]
1242
1243 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/file/ffffffffffff/f3/file?style=raw'
1244 403 Forbidden
1245
1246
1247 error: path 'f3/file' is inside nested repo 'f3'
1248 [1]
1249
1250 Test accessing invalid paths:
1251
1252 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/file/tip/..?style=raw'
1253 403 Forbidden
1254
1255
1256 error: .. not under root '$TESTTMP/dir/webdir/notrepo/f'
1257 [1]
1258
1259 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/file/tip/.hg/hgrc?style=raw'
1260 403 Forbidden
1261
1262
1263 error: path contains illegal component: .hg/hgrc
1264 [1]
1265
1220 Test descend = False
1266 Test descend = False
1221
1267
1222 $ killdaemons.py
1268 $ killdaemons.py
1223 $ cat >> paths.conf <<EOF
1269 $ cat >> paths.conf <<EOF
1224 > descend=false
1270 > descend=false
1225 > EOF
1271 > EOF
1226 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1272 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1227 > -A access-paths.log -E error-paths-4.log
1273 > -A access-paths.log -E error-paths-4.log
1228 $ cat hg.pid >> $DAEMON_PIDS
1274 $ cat hg.pid >> $DAEMON_PIDS
1229 $ get-with-headers.py localhost:$HGPORT1 'coll/?style=raw'
1275 $ get-with-headers.py localhost:$HGPORT1 'coll/?style=raw'
1230 200 Script output follows
1276 200 Script output follows
1231
1277
1232
1278
1233 /coll/a/
1279 /coll/a/
1234 /coll/b/
1280 /coll/b/
1235 /coll/c/
1281 /coll/c/
1236
1282
1237 $ get-with-headers.py localhost:$HGPORT1 'coll/a/file/tip/a?style=raw'
1283 $ get-with-headers.py localhost:$HGPORT1 'coll/a/file/tip/a?style=raw'
1238 200 Script output follows
1284 200 Script output follows
1239
1285
1240 a
1286 a
1241 $ get-with-headers.py localhost:$HGPORT1 'rcoll/?style=raw'
1287 $ get-with-headers.py localhost:$HGPORT1 'rcoll/?style=raw'
1242 200 Script output follows
1288 200 Script output follows
1243
1289
1244
1290
1245 /rcoll/a/
1291 /rcoll/a/
1246 /rcoll/b/
1292 /rcoll/b/
1247 /rcoll/c/
1293 /rcoll/c/
1248
1294
1249 $ get-with-headers.py localhost:$HGPORT1 'rcoll/b/d/file/tip/d?style=raw'
1295 $ get-with-headers.py localhost:$HGPORT1 'rcoll/b/d/file/tip/d?style=raw'
1250 200 Script output follows
1296 200 Script output follows
1251
1297
1252 d
1298 d
1253
1299
1254 Test intermediate directories
1300 Test intermediate directories
1255
1301
1256 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/?style=raw'
1302 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/?style=raw'
1257 200 Script output follows
1303 200 Script output follows
1258
1304
1259
1305
1260 /rcoll/notrepo/e/
1306 /rcoll/notrepo/e/
1261 /rcoll/notrepo/f/
1307 /rcoll/notrepo/f/
1262
1308
1263
1309
1264 Test repositories inside intermediate directories
1310 Test repositories inside intermediate directories
1265
1311
1266 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/e/file/tip/e?style=raw'
1312 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/e/file/tip/e?style=raw'
1267 200 Script output follows
1313 200 Script output follows
1268
1314
1269 e
1315 e
1270
1316
1271 Test subrepositories inside intermediate directories
1317 Test subrepositories inside intermediate directories
1272
1318
1273 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/f2/file/tip/f2?style=raw'
1319 $ get-with-headers.py localhost:$HGPORT1 'rcoll/notrepo/f/f2/file/tip/f2?style=raw'
1274 200 Script output follows
1320 200 Script output follows
1275
1321
1276 f2
1322 f2
1277
1323
1278 Test [paths] '*' in a repo root
1324 Test [paths] '*' in a repo root
1279
1325
1280 $ hg id http://localhost:$HGPORT1/astar
1326 $ hg id http://localhost:$HGPORT1/astar
1281 8580ff50825a
1327 8580ff50825a
1282
1328
1283 $ killdaemons.py
1329 $ killdaemons.py
1284 $ cat > paths.conf <<EOF
1330 $ cat > paths.conf <<EOF
1285 > [paths]
1331 > [paths]
1286 > t/a = $root/a
1332 > t/a = $root/a
1287 > t/b = $root/b
1333 > t/b = $root/b
1288 > c = $root/c
1334 > c = $root/c
1289 > EOF
1335 > EOF
1290 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1336 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1291 > -A access-paths.log -E error-paths-5.log
1337 > -A access-paths.log -E error-paths-5.log
1292 $ cat hg.pid >> $DAEMON_PIDS
1338 $ cat hg.pid >> $DAEMON_PIDS
1293 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1339 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1294 200 Script output follows
1340 200 Script output follows
1295
1341
1296
1342
1297 /t/a/
1343 /t/a/
1298 /t/b/
1344 /t/b/
1299 /c/
1345 /c/
1300
1346
1301 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
1347 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
1302 200 Script output follows
1348 200 Script output follows
1303
1349
1304
1350
1305 /t/a/
1351 /t/a/
1306 /t/b/
1352 /t/b/
1307
1353
1308
1354
1309 Test collapse = True
1355 Test collapse = True
1310
1356
1311 $ killdaemons.py
1357 $ killdaemons.py
1312 $ cat >> paths.conf <<EOF
1358 $ cat >> paths.conf <<EOF
1313 > [web]
1359 > [web]
1314 > collapse=true
1360 > collapse=true
1315 > EOF
1361 > EOF
1316 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1362 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1317 > -A access-paths.log -E error-paths-6.log
1363 > -A access-paths.log -E error-paths-6.log
1318 $ cat hg.pid >> $DAEMON_PIDS
1364 $ cat hg.pid >> $DAEMON_PIDS
1319 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1365 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1320 200 Script output follows
1366 200 Script output follows
1321
1367
1322
1368
1323 /t/
1369 /t/
1324 /c/
1370 /c/
1325
1371
1326 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
1372 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
1327 200 Script output follows
1373 200 Script output follows
1328
1374
1329
1375
1330 /t/a/
1376 /t/a/
1331 /t/b/
1377 /t/b/
1332
1378
1333
1379
1334 test descend = False
1380 test descend = False
1335
1381
1336 $ killdaemons.py
1382 $ killdaemons.py
1337 $ cat >> paths.conf <<EOF
1383 $ cat >> paths.conf <<EOF
1338 > descend=false
1384 > descend=false
1339 > EOF
1385 > EOF
1340 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1386 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1341 > -A access-paths.log -E error-paths-7.log
1387 > -A access-paths.log -E error-paths-7.log
1342 $ cat hg.pid >> $DAEMON_PIDS
1388 $ cat hg.pid >> $DAEMON_PIDS
1343 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1389 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1344 200 Script output follows
1390 200 Script output follows
1345
1391
1346
1392
1347 /c/
1393 /c/
1348
1394
1349 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
1395 $ get-with-headers.py localhost:$HGPORT1 't/?style=raw'
1350 200 Script output follows
1396 200 Script output follows
1351
1397
1352
1398
1353 /t/a/
1399 /t/a/
1354 /t/b/
1400 /t/b/
1355
1401
1356 $ killdaemons.py
1402 $ killdaemons.py
1357 $ cat > paths.conf <<EOF
1403 $ cat > paths.conf <<EOF
1358 > [paths]
1404 > [paths]
1359 > nostore = $root/nostore
1405 > nostore = $root/nostore
1360 > inexistent = $root/inexistent
1406 > inexistent = $root/inexistent
1361 > EOF
1407 > EOF
1362 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1408 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
1363 > -A access-paths.log -E error-paths-8.log
1409 > -A access-paths.log -E error-paths-8.log
1364 $ cat hg.pid >> $DAEMON_PIDS
1410 $ cat hg.pid >> $DAEMON_PIDS
1365
1411
1366 test inexistent and inaccessible repo should be ignored silently
1412 test inexistent and inaccessible repo should be ignored silently
1367
1413
1368 $ get-with-headers.py localhost:$HGPORT1 ''
1414 $ get-with-headers.py localhost:$HGPORT1 ''
1369 200 Script output follows
1415 200 Script output follows
1370
1416
1371 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1417 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1372 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1418 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1373 <head>
1419 <head>
1374 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1420 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1375 <meta name="robots" content="index, nofollow" />
1421 <meta name="robots" content="index, nofollow" />
1376 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1422 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1377 <script type="text/javascript" src="/static/mercurial.js"></script>
1423 <script type="text/javascript" src="/static/mercurial.js"></script>
1378
1424
1379 <title>Mercurial repositories index</title>
1425 <title>Mercurial repositories index</title>
1380 </head>
1426 </head>
1381 <body>
1427 <body>
1382
1428
1383 <div class="container">
1429 <div class="container">
1384 <div class="menu">
1430 <div class="menu">
1385 <a href="https://mercurial-scm.org/">
1431 <a href="https://mercurial-scm.org/">
1386 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
1432 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
1387 </div>
1433 </div>
1388 <div class="main">
1434 <div class="main">
1389 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1435 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1390
1436
1391 <table class="bigtable">
1437 <table class="bigtable">
1392 <thead>
1438 <thead>
1393 <tr>
1439 <tr>
1394 <th><a href="?sort=name">Name</a></th>
1440 <th><a href="?sort=name">Name</a></th>
1395 <th><a href="?sort=description">Description</a></th>
1441 <th><a href="?sort=description">Description</a></th>
1396 <th><a href="?sort=contact">Contact</a></th>
1442 <th><a href="?sort=contact">Contact</a></th>
1397 <th><a href="?sort=lastchange">Last modified</a></th>
1443 <th><a href="?sort=lastchange">Last modified</a></th>
1398 <th>&nbsp;</th>
1444 <th>&nbsp;</th>
1399 <th>&nbsp;</th>
1445 <th>&nbsp;</th>
1400 </tr>
1446 </tr>
1401 </thead>
1447 </thead>
1402 <tbody class="stripes2">
1448 <tbody class="stripes2">
1403
1449
1404 </tbody>
1450 </tbody>
1405 </table>
1451 </table>
1406 </div>
1452 </div>
1407 </div>
1453 </div>
1408
1454
1409
1455
1410 </body>
1456 </body>
1411 </html>
1457 </html>
1412
1458
1413
1459
1414 test listening address/port specified by web-conf (issue4699):
1460 test listening address/port specified by web-conf (issue4699):
1415
1461
1416 $ killdaemons.py
1462 $ killdaemons.py
1417 $ cat >> paths.conf <<EOF
1463 $ cat >> paths.conf <<EOF
1418 > [web]
1464 > [web]
1419 > address = localhost
1465 > address = localhost
1420 > port = $HGPORT1
1466 > port = $HGPORT1
1421 > EOF
1467 > EOF
1422 $ hg serve -d --pid-file=hg.pid --web-conf paths.conf \
1468 $ hg serve -d --pid-file=hg.pid --web-conf paths.conf \
1423 > -A access-paths.log -E error-paths-9.log
1469 > -A access-paths.log -E error-paths-9.log
1424 listening at http://*:$HGPORT1/ (bound to *$LOCALIP*:$HGPORT1) (glob) (?)
1470 listening at http://*:$HGPORT1/ (bound to *$LOCALIP*:$HGPORT1) (glob) (?)
1425 $ cat hg.pid >> $DAEMON_PIDS
1471 $ cat hg.pid >> $DAEMON_PIDS
1426 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1472 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1427 200 Script output follows
1473 200 Script output follows
1428
1474
1429
1475
1430
1476
1431 test --port option overrides web.port:
1477 test --port option overrides web.port:
1432
1478
1433 $ killdaemons.py
1479 $ killdaemons.py
1434 $ hg serve -p $HGPORT2 -d -v --pid-file=hg.pid --web-conf paths.conf \
1480 $ hg serve -p $HGPORT2 -d -v --pid-file=hg.pid --web-conf paths.conf \
1435 > -A access-paths.log -E error-paths-10.log
1481 > -A access-paths.log -E error-paths-10.log
1436 listening at http://*:$HGPORT2/ (bound to *$LOCALIP*:$HGPORT2) (glob) (?)
1482 listening at http://*:$HGPORT2/ (bound to *$LOCALIP*:$HGPORT2) (glob) (?)
1437 $ cat hg.pid >> $DAEMON_PIDS
1483 $ cat hg.pid >> $DAEMON_PIDS
1438 $ get-with-headers.py localhost:$HGPORT2 '?style=raw'
1484 $ get-with-headers.py localhost:$HGPORT2 '?style=raw'
1439 200 Script output follows
1485 200 Script output follows
1440
1486
1441
1487
1442
1488
1443
1489
1444 $ killdaemons.py
1490 $ killdaemons.py
1445 $ cat > collections.conf <<EOF
1491 $ cat > collections.conf <<EOF
1446 > [collections]
1492 > [collections]
1447 > $root=$root
1493 > $root=$root
1448 > EOF
1494 > EOF
1449 $ hg serve --config web.baseurl=http://hg.example.com:8080/ -p $HGPORT2 -d \
1495 $ hg serve --config web.baseurl=http://hg.example.com:8080/ -p $HGPORT2 -d \
1450 > --pid-file=hg.pid --webdir-conf collections.conf \
1496 > --pid-file=hg.pid --webdir-conf collections.conf \
1451 > -A access-collections.log -E error-collections.log
1497 > -A access-collections.log -E error-collections.log
1452 $ cat hg.pid >> $DAEMON_PIDS
1498 $ cat hg.pid >> $DAEMON_PIDS
1453
1499
1454 collections: should succeed
1500 collections: should succeed
1455
1501
1456 $ get-with-headers.py localhost:$HGPORT2 '?style=raw'
1502 $ get-with-headers.py localhost:$HGPORT2 '?style=raw'
1457 200 Script output follows
1503 200 Script output follows
1458
1504
1459
1505
1460 /a/
1506 /a/
1461 /a/.hg/patches/
1507 /a/.hg/patches/
1462 /b/
1508 /b/
1463 /c/
1509 /c/
1464 /notrepo/e/
1510 /notrepo/e/
1465 /notrepo/f/
1511 /notrepo/f/
1466
1512
1467 $ get-with-headers.py localhost:$HGPORT2 'a/file/tip/a?style=raw'
1513 $ get-with-headers.py localhost:$HGPORT2 'a/file/tip/a?style=raw'
1468 200 Script output follows
1514 200 Script output follows
1469
1515
1470 a
1516 a
1471 $ get-with-headers.py localhost:$HGPORT2 'b/file/tip/b?style=raw'
1517 $ get-with-headers.py localhost:$HGPORT2 'b/file/tip/b?style=raw'
1472 200 Script output follows
1518 200 Script output follows
1473
1519
1474 b
1520 b
1475 $ get-with-headers.py localhost:$HGPORT2 'c/file/tip/c?style=raw'
1521 $ get-with-headers.py localhost:$HGPORT2 'c/file/tip/c?style=raw'
1476 200 Script output follows
1522 200 Script output follows
1477
1523
1478 c
1524 c
1479
1525
1480 atom-log with basedir /
1526 atom-log with basedir /
1481
1527
1482 $ get-with-headers.py localhost:$HGPORT2 'a/atom-log' | grep '<link'
1528 $ get-with-headers.py localhost:$HGPORT2 'a/atom-log' | grep '<link'
1483 <link rel="self" href="http://hg.example.com:8080/a/atom-log"/>
1529 <link rel="self" href="http://hg.example.com:8080/a/atom-log"/>
1484 <link rel="alternate" href="http://hg.example.com:8080/a/"/>
1530 <link rel="alternate" href="http://hg.example.com:8080/a/"/>
1485 <link href="http://hg.example.com:8080/a/rev/8580ff50825a"/>
1531 <link href="http://hg.example.com:8080/a/rev/8580ff50825a"/>
1486
1532
1487 rss-log with basedir /
1533 rss-log with basedir /
1488
1534
1489 $ get-with-headers.py localhost:$HGPORT2 'a/rss-log' | grep '<guid'
1535 $ get-with-headers.py localhost:$HGPORT2 'a/rss-log' | grep '<guid'
1490 <guid isPermaLink="true">http://hg.example.com:8080/a/rev/8580ff50825a</guid>
1536 <guid isPermaLink="true">http://hg.example.com:8080/a/rev/8580ff50825a</guid>
1491 $ killdaemons.py
1537 $ killdaemons.py
1492 $ hg serve --config web.baseurl=http://hg.example.com:8080/foo/ -p $HGPORT2 -d \
1538 $ hg serve --config web.baseurl=http://hg.example.com:8080/foo/ -p $HGPORT2 -d \
1493 > --pid-file=hg.pid --webdir-conf collections.conf \
1539 > --pid-file=hg.pid --webdir-conf collections.conf \
1494 > -A access-collections-2.log -E error-collections-2.log
1540 > -A access-collections-2.log -E error-collections-2.log
1495 $ cat hg.pid >> $DAEMON_PIDS
1541 $ cat hg.pid >> $DAEMON_PIDS
1496
1542
1497 atom-log with basedir /foo/
1543 atom-log with basedir /foo/
1498
1544
1499 $ get-with-headers.py localhost:$HGPORT2 'a/atom-log' | grep '<link'
1545 $ get-with-headers.py localhost:$HGPORT2 'a/atom-log' | grep '<link'
1500 <link rel="self" href="http://hg.example.com:8080/foo/a/atom-log"/>
1546 <link rel="self" href="http://hg.example.com:8080/foo/a/atom-log"/>
1501 <link rel="alternate" href="http://hg.example.com:8080/foo/a/"/>
1547 <link rel="alternate" href="http://hg.example.com:8080/foo/a/"/>
1502 <link href="http://hg.example.com:8080/foo/a/rev/8580ff50825a"/>
1548 <link href="http://hg.example.com:8080/foo/a/rev/8580ff50825a"/>
1503
1549
1504 rss-log with basedir /foo/
1550 rss-log with basedir /foo/
1505
1551
1506 $ get-with-headers.py localhost:$HGPORT2 'a/rss-log' | grep '<guid'
1552 $ get-with-headers.py localhost:$HGPORT2 'a/rss-log' | grep '<guid'
1507 <guid isPermaLink="true">http://hg.example.com:8080/foo/a/rev/8580ff50825a</guid>
1553 <guid isPermaLink="true">http://hg.example.com:8080/foo/a/rev/8580ff50825a</guid>
1508
1554
1509 Path refreshing works as expected
1555 Path refreshing works as expected
1510
1556
1511 $ killdaemons.py
1557 $ killdaemons.py
1512 $ mkdir $root/refreshtest
1558 $ mkdir $root/refreshtest
1513 $ hg init $root/refreshtest/a
1559 $ hg init $root/refreshtest/a
1514 $ cat > paths.conf << EOF
1560 $ cat > paths.conf << EOF
1515 > [paths]
1561 > [paths]
1516 > / = $root/refreshtest/*
1562 > / = $root/refreshtest/*
1517 > EOF
1563 > EOF
1518 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1564 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1519 $ cat hg.pid >> $DAEMON_PIDS
1565 $ cat hg.pid >> $DAEMON_PIDS
1520
1566
1521 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1567 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1522 200 Script output follows
1568 200 Script output follows
1523
1569
1524
1570
1525 /a/
1571 /a/
1526
1572
1527
1573
1528 By default refreshing occurs every 20s and a new repo won't be listed
1574 By default refreshing occurs every 20s and a new repo won't be listed
1529 immediately.
1575 immediately.
1530
1576
1531 $ hg init $root/refreshtest/b
1577 $ hg init $root/refreshtest/b
1532 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1578 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1533 200 Script output follows
1579 200 Script output follows
1534
1580
1535
1581
1536 /a/
1582 /a/
1537
1583
1538
1584
1539 Restart the server with no refresh interval. New repo should appear
1585 Restart the server with no refresh interval. New repo should appear
1540 immediately.
1586 immediately.
1541
1587
1542 $ killdaemons.py
1588 $ killdaemons.py
1543 $ cat > paths.conf << EOF
1589 $ cat > paths.conf << EOF
1544 > [web]
1590 > [web]
1545 > refreshinterval = -1
1591 > refreshinterval = -1
1546 > [paths]
1592 > [paths]
1547 > / = $root/refreshtest/*
1593 > / = $root/refreshtest/*
1548 > EOF
1594 > EOF
1549 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1595 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1550 $ cat hg.pid >> $DAEMON_PIDS
1596 $ cat hg.pid >> $DAEMON_PIDS
1551
1597
1552 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1598 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1553 200 Script output follows
1599 200 Script output follows
1554
1600
1555
1601
1556 /a/
1602 /a/
1557 /b/
1603 /b/
1558
1604
1559
1605
1560 $ hg init $root/refreshtest/c
1606 $ hg init $root/refreshtest/c
1561 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1607 $ get-with-headers.py localhost:$HGPORT1 '?style=raw'
1562 200 Script output follows
1608 200 Script output follows
1563
1609
1564
1610
1565 /a/
1611 /a/
1566 /b/
1612 /b/
1567 /c/
1613 /c/
1568
1614
1569 $ killdaemons.py
1615 $ killdaemons.py
1570 $ cat > paths.conf << EOF
1616 $ cat > paths.conf << EOF
1571 > [paths]
1617 > [paths]
1572 > /dir1/a_repo = $root/a
1618 > /dir1/a_repo = $root/a
1573 > /dir1/a_repo/b_repo = $root/b
1619 > /dir1/a_repo/b_repo = $root/b
1574 > /dir1/dir2/index = $root/b
1620 > /dir1/dir2/index = $root/b
1575 > EOF
1621 > EOF
1576 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1622 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1577 $ cat hg.pid >> $DAEMON_PIDS
1623 $ cat hg.pid >> $DAEMON_PIDS
1578
1624
1579 $ echo 'index file' > $root/a/index
1625 $ echo 'index file' > $root/a/index
1580 $ hg --cwd $root/a ci -Am 'add index file'
1626 $ hg --cwd $root/a ci -Am 'add index file'
1581 adding index
1627 adding index
1582
1628
1583 $ get-with-headers.py localhost:$HGPORT1 '' | grep 'a_repo'
1629 $ get-with-headers.py localhost:$HGPORT1 '' | grep 'a_repo'
1584 <td><a href="/dir1/a_repo/">dir1/a_repo</a></td>
1630 <td><a href="/dir1/a_repo/">dir1/a_repo</a></td>
1585 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1631 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1586 <td><a href="/dir1/a_repo/b_repo/">dir1/a_repo/b_repo</a></td>
1632 <td><a href="/dir1/a_repo/b_repo/">dir1/a_repo/b_repo</a></td>
1587 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1633 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1588
1634
1589 $ get-with-headers.py localhost:$HGPORT1 'index' | grep 'a_repo'
1635 $ get-with-headers.py localhost:$HGPORT1 'index' | grep 'a_repo'
1590 <td><a href="/dir1/a_repo/">dir1/a_repo</a></td>
1636 <td><a href="/dir1/a_repo/">dir1/a_repo</a></td>
1591 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1637 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1592 <td><a href="/dir1/a_repo/b_repo/">dir1/a_repo/b_repo</a></td>
1638 <td><a href="/dir1/a_repo/b_repo/">dir1/a_repo/b_repo</a></td>
1593 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1639 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1594
1640
1595 $ get-with-headers.py localhost:$HGPORT1 'dir1' | grep 'a_repo'
1641 $ get-with-headers.py localhost:$HGPORT1 'dir1' | grep 'a_repo'
1596 <td><a href="/dir1/a_repo/">a_repo</a></td>
1642 <td><a href="/dir1/a_repo/">a_repo</a></td>
1597 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1643 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1598 <td><a href="/dir1/a_repo/b_repo/">a_repo/b_repo</a></td>
1644 <td><a href="/dir1/a_repo/b_repo/">a_repo/b_repo</a></td>
1599 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1645 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1600
1646
1601 $ get-with-headers.py localhost:$HGPORT1 'dir1/index' | grep 'a_repo'
1647 $ get-with-headers.py localhost:$HGPORT1 'dir1/index' | grep 'a_repo'
1602 <td><a href="/dir1/a_repo/">a_repo</a></td>
1648 <td><a href="/dir1/a_repo/">a_repo</a></td>
1603 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1649 <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
1604 <td><a href="/dir1/a_repo/b_repo/">a_repo/b_repo</a></td>
1650 <td><a href="/dir1/a_repo/b_repo/">a_repo/b_repo</a></td>
1605 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1651 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1606
1652
1607 $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo' | grep 'a_repo'
1653 $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo' | grep 'a_repo'
1608 <link rel="icon" href="/dir1/a_repo/static/hgicon.png" type="image/png" />
1654 <link rel="icon" href="/dir1/a_repo/static/hgicon.png" type="image/png" />
1609 <link rel="stylesheet" href="/dir1/a_repo/static/style-paper.css" type="text/css" />
1655 <link rel="stylesheet" href="/dir1/a_repo/static/style-paper.css" type="text/css" />
1610 <script type="text/javascript" src="/dir1/a_repo/static/mercurial.js"></script>
1656 <script type="text/javascript" src="/dir1/a_repo/static/mercurial.js"></script>
1611 <title>dir1/a_repo: log</title>
1657 <title>dir1/a_repo: log</title>
1612 href="/dir1/a_repo/atom-log" title="Atom feed for dir1/a_repo" />
1658 href="/dir1/a_repo/atom-log" title="Atom feed for dir1/a_repo" />
1613 href="/dir1/a_repo/rss-log" title="RSS feed for dir1/a_repo" />
1659 href="/dir1/a_repo/rss-log" title="RSS feed for dir1/a_repo" />
1614 <img src="/dir1/a_repo/static/hglogo.png" alt="mercurial" /></a>
1660 <img src="/dir1/a_repo/static/hglogo.png" alt="mercurial" /></a>
1615 <li><a href="/dir1/a_repo/graph/tip">graph</a></li>
1661 <li><a href="/dir1/a_repo/graph/tip">graph</a></li>
1616 <li><a href="/dir1/a_repo/tags">tags</a></li>
1662 <li><a href="/dir1/a_repo/tags">tags</a></li>
1617 <li><a href="/dir1/a_repo/bookmarks">bookmarks</a></li>
1663 <li><a href="/dir1/a_repo/bookmarks">bookmarks</a></li>
1618 <li><a href="/dir1/a_repo/branches">branches</a></li>
1664 <li><a href="/dir1/a_repo/branches">branches</a></li>
1619 <li><a href="/dir1/a_repo/rev/tip">changeset</a></li>
1665 <li><a href="/dir1/a_repo/rev/tip">changeset</a></li>
1620 <li><a href="/dir1/a_repo/file/tip">browse</a></li>
1666 <li><a href="/dir1/a_repo/file/tip">browse</a></li>
1621 <li><a href="/dir1/a_repo/help">help</a></li>
1667 <li><a href="/dir1/a_repo/help">help</a></li>
1622 <a href="/dir1/a_repo/atom-log" title="subscribe to atom feed">
1668 <a href="/dir1/a_repo/atom-log" title="subscribe to atom feed">
1623 <img class="atom-logo" src="/dir1/a_repo/static/feed-icon-14x14.png" alt="atom feed" />
1669 <img class="atom-logo" src="/dir1/a_repo/static/feed-icon-14x14.png" alt="atom feed" />
1624 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/a_repo">a_repo</a> </h2>
1670 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/a_repo">a_repo</a> </h2>
1625 <form class="search" action="/dir1/a_repo/log">
1671 <form class="search" action="/dir1/a_repo/log">
1626 number or hash, or <a href="/dir1/a_repo/help/revsets">revset expression</a>.</div>
1672 number or hash, or <a href="/dir1/a_repo/help/revsets">revset expression</a>.</div>
1627 <a href="/dir1/a_repo/shortlog/tip?revcount=30">less</a>
1673 <a href="/dir1/a_repo/shortlog/tip?revcount=30">less</a>
1628 <a href="/dir1/a_repo/shortlog/tip?revcount=120">more</a>
1674 <a href="/dir1/a_repo/shortlog/tip?revcount=120">more</a>
1629 | rev 1: <a href="/dir1/a_repo/shortlog/8580ff50825a">(0)</a> <a href="/dir1/a_repo/shortlog/tip">tip</a>
1675 | rev 1: <a href="/dir1/a_repo/shortlog/8580ff50825a">(0)</a> <a href="/dir1/a_repo/shortlog/tip">tip</a>
1630 <a href="/dir1/a_repo/rev/71a89161f014">add index file</a>
1676 <a href="/dir1/a_repo/rev/71a89161f014">add index file</a>
1631 <a href="/dir1/a_repo/rev/8580ff50825a">a</a>
1677 <a href="/dir1/a_repo/rev/8580ff50825a">a</a>
1632 <a href="/dir1/a_repo/shortlog/tip?revcount=30">less</a>
1678 <a href="/dir1/a_repo/shortlog/tip?revcount=30">less</a>
1633 <a href="/dir1/a_repo/shortlog/tip?revcount=120">more</a>
1679 <a href="/dir1/a_repo/shortlog/tip?revcount=120">more</a>
1634 | rev 1: <a href="/dir1/a_repo/shortlog/8580ff50825a">(0)</a> <a href="/dir1/a_repo/shortlog/tip">tip</a>
1680 | rev 1: <a href="/dir1/a_repo/shortlog/8580ff50825a">(0)</a> <a href="/dir1/a_repo/shortlog/tip">tip</a>
1635 '/dir1/a_repo/shortlog/%next%',
1681 '/dir1/a_repo/shortlog/%next%',
1636
1682
1637 $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/index' | grep 'a_repo'
1683 $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/index' | grep 'a_repo'
1638 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/a_repo">a_repo</a> </h2>
1684 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/a_repo">a_repo</a> </h2>
1639 <td><a href="/dir1/a_repo/b_repo/">b_repo</a></td>
1685 <td><a href="/dir1/a_repo/b_repo/">b_repo</a></td>
1640 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1686 <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
1641
1687
1642 Files named 'index' are not blocked
1688 Files named 'index' are not blocked
1643
1689
1644 $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/raw-file/tip/index'
1690 $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/raw-file/tip/index'
1645 200 Script output follows
1691 200 Script output follows
1646
1692
1647 index file
1693 index file
1648
1694
1649 Repos named 'index' take precedence over the index file
1695 Repos named 'index' take precedence over the index file
1650
1696
1651 $ get-with-headers.py localhost:$HGPORT1 'dir1/dir2/index' | grep 'index'
1697 $ get-with-headers.py localhost:$HGPORT1 'dir1/dir2/index' | grep 'index'
1652 <link rel="icon" href="/dir1/dir2/index/static/hgicon.png" type="image/png" />
1698 <link rel="icon" href="/dir1/dir2/index/static/hgicon.png" type="image/png" />
1653 <meta name="robots" content="index, nofollow" />
1699 <meta name="robots" content="index, nofollow" />
1654 <link rel="stylesheet" href="/dir1/dir2/index/static/style-paper.css" type="text/css" />
1700 <link rel="stylesheet" href="/dir1/dir2/index/static/style-paper.css" type="text/css" />
1655 <script type="text/javascript" src="/dir1/dir2/index/static/mercurial.js"></script>
1701 <script type="text/javascript" src="/dir1/dir2/index/static/mercurial.js"></script>
1656 <title>dir1/dir2/index: log</title>
1702 <title>dir1/dir2/index: log</title>
1657 href="/dir1/dir2/index/atom-log" title="Atom feed for dir1/dir2/index" />
1703 href="/dir1/dir2/index/atom-log" title="Atom feed for dir1/dir2/index" />
1658 href="/dir1/dir2/index/rss-log" title="RSS feed for dir1/dir2/index" />
1704 href="/dir1/dir2/index/rss-log" title="RSS feed for dir1/dir2/index" />
1659 <img src="/dir1/dir2/index/static/hglogo.png" alt="mercurial" /></a>
1705 <img src="/dir1/dir2/index/static/hglogo.png" alt="mercurial" /></a>
1660 <li><a href="/dir1/dir2/index/graph/tip">graph</a></li>
1706 <li><a href="/dir1/dir2/index/graph/tip">graph</a></li>
1661 <li><a href="/dir1/dir2/index/tags">tags</a></li>
1707 <li><a href="/dir1/dir2/index/tags">tags</a></li>
1662 <li><a href="/dir1/dir2/index/bookmarks">bookmarks</a></li>
1708 <li><a href="/dir1/dir2/index/bookmarks">bookmarks</a></li>
1663 <li><a href="/dir1/dir2/index/branches">branches</a></li>
1709 <li><a href="/dir1/dir2/index/branches">branches</a></li>
1664 <li><a href="/dir1/dir2/index/rev/tip">changeset</a></li>
1710 <li><a href="/dir1/dir2/index/rev/tip">changeset</a></li>
1665 <li><a href="/dir1/dir2/index/file/tip">browse</a></li>
1711 <li><a href="/dir1/dir2/index/file/tip">browse</a></li>
1666 <li><a href="/dir1/dir2/index/help">help</a></li>
1712 <li><a href="/dir1/dir2/index/help">help</a></li>
1667 <a href="/dir1/dir2/index/atom-log" title="subscribe to atom feed">
1713 <a href="/dir1/dir2/index/atom-log" title="subscribe to atom feed">
1668 <img class="atom-logo" src="/dir1/dir2/index/static/feed-icon-14x14.png" alt="atom feed" />
1714 <img class="atom-logo" src="/dir1/dir2/index/static/feed-icon-14x14.png" alt="atom feed" />
1669 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/dir2">dir2</a> &gt; <a href="/dir1/dir2/index">index</a> </h2>
1715 <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/dir2">dir2</a> &gt; <a href="/dir1/dir2/index">index</a> </h2>
1670 <form class="search" action="/dir1/dir2/index/log">
1716 <form class="search" action="/dir1/dir2/index/log">
1671 number or hash, or <a href="/dir1/dir2/index/help/revsets">revset expression</a>.</div>
1717 number or hash, or <a href="/dir1/dir2/index/help/revsets">revset expression</a>.</div>
1672 <a href="/dir1/dir2/index/shortlog/tip?revcount=30">less</a>
1718 <a href="/dir1/dir2/index/shortlog/tip?revcount=30">less</a>
1673 <a href="/dir1/dir2/index/shortlog/tip?revcount=120">more</a>
1719 <a href="/dir1/dir2/index/shortlog/tip?revcount=120">more</a>
1674 | rev 0: <a href="/dir1/dir2/index/shortlog/39505516671b">(0)</a> <a href="/dir1/dir2/index/shortlog/tip">tip</a>
1720 | rev 0: <a href="/dir1/dir2/index/shortlog/39505516671b">(0)</a> <a href="/dir1/dir2/index/shortlog/tip">tip</a>
1675 <a href="/dir1/dir2/index/rev/39505516671b">b</a>
1721 <a href="/dir1/dir2/index/rev/39505516671b">b</a>
1676 <a href="/dir1/dir2/index/shortlog/tip?revcount=30">less</a>
1722 <a href="/dir1/dir2/index/shortlog/tip?revcount=30">less</a>
1677 <a href="/dir1/dir2/index/shortlog/tip?revcount=120">more</a>
1723 <a href="/dir1/dir2/index/shortlog/tip?revcount=120">more</a>
1678 | rev 0: <a href="/dir1/dir2/index/shortlog/39505516671b">(0)</a> <a href="/dir1/dir2/index/shortlog/tip">tip</a>
1724 | rev 0: <a href="/dir1/dir2/index/shortlog/39505516671b">(0)</a> <a href="/dir1/dir2/index/shortlog/tip">tip</a>
1679 '/dir1/dir2/index/shortlog/%next%',
1725 '/dir1/dir2/index/shortlog/%next%',
1680
1726
1681 $ killdaemons.py
1727 $ killdaemons.py
1682
1728
1683 $ cat > paths.conf << EOF
1729 $ cat > paths.conf << EOF
1684 > [paths]
1730 > [paths]
1685 > / = $root/a
1731 > / = $root/a
1686 > EOF
1732 > EOF
1687 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1733 $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
1688 $ cat hg.pid >> $DAEMON_PIDS
1734 $ cat hg.pid >> $DAEMON_PIDS
1689
1735
1690 $ hg id http://localhost:$HGPORT1
1736 $ hg id http://localhost:$HGPORT1
1691 71a89161f014
1737 71a89161f014
1692
1738
1693 $ get-with-headers.py localhost:$HGPORT1 '' | grep 'index'
1739 $ get-with-headers.py localhost:$HGPORT1 '' | grep 'index'
1694 <meta name="robots" content="index, nofollow" />
1740 <meta name="robots" content="index, nofollow" />
1695 <a href="/rev/71a89161f014">add index file</a>
1741 <a href="/rev/71a89161f014">add index file</a>
1696
1742
1697 $ killdaemons.py
1743 $ killdaemons.py
1698
1744
1699 paths errors 1
1745 paths errors 1
1700
1746
1701 $ cat error-paths-1.log
1747 $ cat error-paths-1.log
1702
1748
1703 paths errors 2
1749 paths errors 2
1704
1750
1705 $ cat error-paths-2.log
1751 $ cat error-paths-2.log
1706
1752
1707 paths errors 3
1753 paths errors 3
1708
1754
1709 $ cat error-paths-3.log
1755 $ cat error-paths-3.log
1710
1756
1711 paths errors 4
1757 paths errors 4
1712
1758
1713 $ cat error-paths-4.log
1759 $ cat error-paths-4.log
1714
1760
1715 paths errors 5
1761 paths errors 5
1716
1762
1717 $ cat error-paths-5.log
1763 $ cat error-paths-5.log
1718
1764
1719 paths errors 6
1765 paths errors 6
1720
1766
1721 $ cat error-paths-6.log
1767 $ cat error-paths-6.log
1722
1768
1723 paths errors 7
1769 paths errors 7
1724
1770
1725 $ cat error-paths-7.log
1771 $ cat error-paths-7.log
1726
1772
1727 paths errors 8
1773 paths errors 8
1728
1774
1729 $ cat error-paths-8.log
1775 $ cat error-paths-8.log
1730
1776
1731 paths errors 9
1777 paths errors 9
1732
1778
1733 $ cat error-paths-9.log
1779 $ cat error-paths-9.log
1734
1780
1735 paths errors 10
1781 paths errors 10
1736
1782
1737 $ cat error-paths-10.log
1783 $ cat error-paths-10.log
1738
1784
1739 collections errors
1785 collections errors
1740
1786
1741 $ cat error-collections.log
1787 $ cat error-collections.log
1742
1788
1743 collections errors 2
1789 collections errors 2
1744
1790
1745 $ cat error-collections-2.log
1791 $ cat error-collections-2.log
General Comments 0
You need to be logged in to leave comments. Login now