##// END OF EJS Templates
hgweb: fixes traceback for invalid files by removing top-level template...
wujek srujek -
r17302:5c64ce61 stable
parent child Browse files
Show More
@@ -1,936 +1,972 b''
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import os, mimetypes, re, cgi, copy
8 import os, mimetypes, re, cgi, copy
9 import webutil
9 import webutil
10 from mercurial import error, encoding, archival, templater, templatefilters
10 from mercurial import error, encoding, archival, templater, templatefilters
11 from mercurial.node import short, hex
11 from mercurial.node import short, hex, nullid
12 from mercurial.util import binary
12 from mercurial.util import binary
13 from common import paritygen, staticfile, get_contact, ErrorResponse
13 from common import paritygen, staticfile, get_contact, ErrorResponse
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
15 from mercurial import graphmod, patch
15 from mercurial import graphmod, patch
16 from mercurial import help as helpmod
16 from mercurial import help as helpmod
17 from mercurial.i18n import _
17 from mercurial.i18n import _
18
18
19 # __all__ is populated with the allowed commands. Be sure to add to it if
19 # __all__ is populated with the allowed commands. Be sure to add to it if
20 # you're adding a new command, or the new command won't work.
20 # you're adding a new command, or the new command won't work.
21
21
22 __all__ = [
22 __all__ = [
23 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
23 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
24 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
24 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
25 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
25 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
26 ]
26 ]
27
27
28 def log(web, req, tmpl):
28 def log(web, req, tmpl):
29 if 'file' in req.form and req.form['file'][0]:
29 if 'file' in req.form and req.form['file'][0]:
30 return filelog(web, req, tmpl)
30 return filelog(web, req, tmpl)
31 else:
31 else:
32 return changelog(web, req, tmpl)
32 return changelog(web, req, tmpl)
33
33
34 def rawfile(web, req, tmpl):
34 def rawfile(web, req, tmpl):
35 guessmime = web.configbool('web', 'guessmime', False)
35 guessmime = web.configbool('web', 'guessmime', False)
36
36
37 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
37 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
38 if not path:
38 if not path:
39 content = manifest(web, req, tmpl)
39 content = manifest(web, req, tmpl)
40 req.respond(HTTP_OK, web.ctype)
40 req.respond(HTTP_OK, web.ctype)
41 return content
41 return content
42
42
43 try:
43 try:
44 fctx = webutil.filectx(web.repo, req)
44 fctx = webutil.filectx(web.repo, req)
45 except error.LookupError, inst:
45 except error.LookupError, inst:
46 try:
46 try:
47 content = manifest(web, req, tmpl)
47 content = manifest(web, req, tmpl)
48 req.respond(HTTP_OK, web.ctype)
48 req.respond(HTTP_OK, web.ctype)
49 return content
49 return content
50 except ErrorResponse:
50 except ErrorResponse:
51 raise inst
51 raise inst
52
52
53 path = fctx.path()
53 path = fctx.path()
54 text = fctx.data()
54 text = fctx.data()
55 mt = 'application/binary'
55 mt = 'application/binary'
56 if guessmime:
56 if guessmime:
57 mt = mimetypes.guess_type(path)[0]
57 mt = mimetypes.guess_type(path)[0]
58 if mt is None:
58 if mt is None:
59 mt = binary(text) and 'application/binary' or 'text/plain'
59 mt = binary(text) and 'application/binary' or 'text/plain'
60 if mt.startswith('text/'):
60 if mt.startswith('text/'):
61 mt += '; charset="%s"' % encoding.encoding
61 mt += '; charset="%s"' % encoding.encoding
62
62
63 req.respond(HTTP_OK, mt, path, len(text))
63 req.respond(HTTP_OK, mt, path, len(text))
64 return [text]
64 return [text]
65
65
66 def _filerevision(web, tmpl, fctx):
66 def _filerevision(web, tmpl, fctx):
67 f = fctx.path()
67 f = fctx.path()
68 text = fctx.data()
68 text = fctx.data()
69 parity = paritygen(web.stripecount)
69 parity = paritygen(web.stripecount)
70
70
71 if binary(text):
71 if binary(text):
72 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
72 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
73 text = '(binary:%s)' % mt
73 text = '(binary:%s)' % mt
74
74
75 def lines():
75 def lines():
76 for lineno, t in enumerate(text.splitlines(True)):
76 for lineno, t in enumerate(text.splitlines(True)):
77 yield {"line": t,
77 yield {"line": t,
78 "lineid": "l%d" % (lineno + 1),
78 "lineid": "l%d" % (lineno + 1),
79 "linenumber": "% 6d" % (lineno + 1),
79 "linenumber": "% 6d" % (lineno + 1),
80 "parity": parity.next()}
80 "parity": parity.next()}
81
81
82 return tmpl("filerevision",
82 return tmpl("filerevision",
83 file=f,
83 file=f,
84 path=webutil.up(f),
84 path=webutil.up(f),
85 text=lines(),
85 text=lines(),
86 rev=fctx.rev(),
86 rev=fctx.rev(),
87 node=fctx.hex(),
87 node=fctx.hex(),
88 author=fctx.user(),
88 author=fctx.user(),
89 date=fctx.date(),
89 date=fctx.date(),
90 desc=fctx.description(),
90 desc=fctx.description(),
91 branch=webutil.nodebranchnodefault(fctx),
91 branch=webutil.nodebranchnodefault(fctx),
92 parent=webutil.parents(fctx),
92 parent=webutil.parents(fctx),
93 child=webutil.children(fctx),
93 child=webutil.children(fctx),
94 rename=webutil.renamelink(fctx),
94 rename=webutil.renamelink(fctx),
95 permissions=fctx.manifest().flags(f))
95 permissions=fctx.manifest().flags(f))
96
96
97 def file(web, req, tmpl):
97 def file(web, req, tmpl):
98 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
98 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
99 if not path:
99 if not path:
100 return manifest(web, req, tmpl)
100 return manifest(web, req, tmpl)
101 try:
101 try:
102 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
102 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
103 except error.LookupError, inst:
103 except error.LookupError, inst:
104 try:
104 try:
105 return manifest(web, req, tmpl)
105 return manifest(web, req, tmpl)
106 except ErrorResponse:
106 except ErrorResponse:
107 raise inst
107 raise inst
108
108
109 def _search(web, req, tmpl):
109 def _search(web, req, tmpl):
110
110
111 query = req.form['rev'][0]
111 query = req.form['rev'][0]
112 revcount = web.maxchanges
112 revcount = web.maxchanges
113 if 'revcount' in req.form:
113 if 'revcount' in req.form:
114 revcount = int(req.form.get('revcount', [revcount])[0])
114 revcount = int(req.form.get('revcount', [revcount])[0])
115 revcount = max(revcount, 1)
115 revcount = max(revcount, 1)
116 tmpl.defaults['sessionvars']['revcount'] = revcount
116 tmpl.defaults['sessionvars']['revcount'] = revcount
117
117
118 lessvars = copy.copy(tmpl.defaults['sessionvars'])
118 lessvars = copy.copy(tmpl.defaults['sessionvars'])
119 lessvars['revcount'] = max(revcount / 2, 1)
119 lessvars['revcount'] = max(revcount / 2, 1)
120 lessvars['rev'] = query
120 lessvars['rev'] = query
121 morevars = copy.copy(tmpl.defaults['sessionvars'])
121 morevars = copy.copy(tmpl.defaults['sessionvars'])
122 morevars['revcount'] = revcount * 2
122 morevars['revcount'] = revcount * 2
123 morevars['rev'] = query
123 morevars['rev'] = query
124
124
125 def changelist(**map):
125 def changelist(**map):
126 count = 0
126 count = 0
127 lower = encoding.lower
127 lower = encoding.lower
128 qw = lower(query).split()
128 qw = lower(query).split()
129
129
130 def revgen():
130 def revgen():
131 for i in xrange(len(web.repo) - 1, 0, -100):
131 for i in xrange(len(web.repo) - 1, 0, -100):
132 l = []
132 l = []
133 for j in xrange(max(0, i - 100), i + 1):
133 for j in xrange(max(0, i - 100), i + 1):
134 ctx = web.repo[j]
134 ctx = web.repo[j]
135 l.append(ctx)
135 l.append(ctx)
136 l.reverse()
136 l.reverse()
137 for e in l:
137 for e in l:
138 yield e
138 yield e
139
139
140 for ctx in revgen():
140 for ctx in revgen():
141 miss = 0
141 miss = 0
142 for q in qw:
142 for q in qw:
143 if not (q in lower(ctx.user()) or
143 if not (q in lower(ctx.user()) or
144 q in lower(ctx.description()) or
144 q in lower(ctx.description()) or
145 q in lower(" ".join(ctx.files()))):
145 q in lower(" ".join(ctx.files()))):
146 miss = 1
146 miss = 1
147 break
147 break
148 if miss:
148 if miss:
149 continue
149 continue
150
150
151 count += 1
151 count += 1
152 n = ctx.node()
152 n = ctx.node()
153 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
153 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
154 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
154 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
155
155
156 yield tmpl('searchentry',
156 yield tmpl('searchentry',
157 parity=parity.next(),
157 parity=parity.next(),
158 author=ctx.user(),
158 author=ctx.user(),
159 parent=webutil.parents(ctx),
159 parent=webutil.parents(ctx),
160 child=webutil.children(ctx),
160 child=webutil.children(ctx),
161 changelogtag=showtags,
161 changelogtag=showtags,
162 desc=ctx.description(),
162 desc=ctx.description(),
163 date=ctx.date(),
163 date=ctx.date(),
164 files=files,
164 files=files,
165 rev=ctx.rev(),
165 rev=ctx.rev(),
166 node=hex(n),
166 node=hex(n),
167 tags=webutil.nodetagsdict(web.repo, n),
167 tags=webutil.nodetagsdict(web.repo, n),
168 bookmarks=webutil.nodebookmarksdict(web.repo, n),
168 bookmarks=webutil.nodebookmarksdict(web.repo, n),
169 inbranch=webutil.nodeinbranch(web.repo, ctx),
169 inbranch=webutil.nodeinbranch(web.repo, ctx),
170 branches=webutil.nodebranchdict(web.repo, ctx))
170 branches=webutil.nodebranchdict(web.repo, ctx))
171
171
172 if count >= revcount:
172 if count >= revcount:
173 break
173 break
174
174
175 tip = web.repo['tip']
175 tip = web.repo['tip']
176 parity = paritygen(web.stripecount)
176 parity = paritygen(web.stripecount)
177
177
178 return tmpl('search', query=query, node=tip.hex(),
178 return tmpl('search', query=query, node=tip.hex(),
179 entries=changelist, archives=web.archivelist("tip"),
179 entries=changelist, archives=web.archivelist("tip"),
180 morevars=morevars, lessvars=lessvars)
180 morevars=morevars, lessvars=lessvars)
181
181
182 def changelog(web, req, tmpl, shortlog=False):
182 def changelog(web, req, tmpl, shortlog=False):
183
183
184 if 'node' in req.form:
184 if 'node' in req.form:
185 ctx = webutil.changectx(web.repo, req)
185 ctx = webutil.changectx(web.repo, req)
186 else:
186 else:
187 if 'rev' in req.form:
187 if 'rev' in req.form:
188 hi = req.form['rev'][0]
188 hi = req.form['rev'][0]
189 else:
189 else:
190 hi = len(web.repo) - 1
190 hi = len(web.repo) - 1
191 try:
191 try:
192 ctx = web.repo[hi]
192 ctx = web.repo[hi]
193 except error.RepoError:
193 except error.RepoError:
194 return _search(web, req, tmpl) # XXX redirect to 404 page?
194 return _search(web, req, tmpl) # XXX redirect to 404 page?
195
195
196 def changelist(limit=0, **map):
196 def changelist(limit=0, **map):
197 l = [] # build a list in forward order for efficiency
197 l = [] # build a list in forward order for efficiency
198 for i in xrange(start, end):
198 for i in xrange(start, end):
199 ctx = web.repo[i]
199 ctx = web.repo[i]
200 n = ctx.node()
200 n = ctx.node()
201 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
201 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
202 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
202 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
203
203
204 l.insert(0, {"parity": parity.next(),
204 l.insert(0, {"parity": parity.next(),
205 "author": ctx.user(),
205 "author": ctx.user(),
206 "parent": webutil.parents(ctx, i - 1),
206 "parent": webutil.parents(ctx, i - 1),
207 "child": webutil.children(ctx, i + 1),
207 "child": webutil.children(ctx, i + 1),
208 "changelogtag": showtags,
208 "changelogtag": showtags,
209 "desc": ctx.description(),
209 "desc": ctx.description(),
210 "date": ctx.date(),
210 "date": ctx.date(),
211 "files": files,
211 "files": files,
212 "rev": i,
212 "rev": i,
213 "node": hex(n),
213 "node": hex(n),
214 "tags": webutil.nodetagsdict(web.repo, n),
214 "tags": webutil.nodetagsdict(web.repo, n),
215 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
215 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
216 "inbranch": webutil.nodeinbranch(web.repo, ctx),
216 "inbranch": webutil.nodeinbranch(web.repo, ctx),
217 "branches": webutil.nodebranchdict(web.repo, ctx)
217 "branches": webutil.nodebranchdict(web.repo, ctx)
218 })
218 })
219
219
220 if limit > 0:
220 if limit > 0:
221 l = l[:limit]
221 l = l[:limit]
222
222
223 for e in l:
223 for e in l:
224 yield e
224 yield e
225
225
226 revcount = shortlog and web.maxshortchanges or web.maxchanges
226 revcount = shortlog and web.maxshortchanges or web.maxchanges
227 if 'revcount' in req.form:
227 if 'revcount' in req.form:
228 revcount = int(req.form.get('revcount', [revcount])[0])
228 revcount = int(req.form.get('revcount', [revcount])[0])
229 revcount = max(revcount, 1)
229 revcount = max(revcount, 1)
230 tmpl.defaults['sessionvars']['revcount'] = revcount
230 tmpl.defaults['sessionvars']['revcount'] = revcount
231
231
232 lessvars = copy.copy(tmpl.defaults['sessionvars'])
232 lessvars = copy.copy(tmpl.defaults['sessionvars'])
233 lessvars['revcount'] = max(revcount / 2, 1)
233 lessvars['revcount'] = max(revcount / 2, 1)
234 morevars = copy.copy(tmpl.defaults['sessionvars'])
234 morevars = copy.copy(tmpl.defaults['sessionvars'])
235 morevars['revcount'] = revcount * 2
235 morevars['revcount'] = revcount * 2
236
236
237 count = len(web.repo)
237 count = len(web.repo)
238 pos = ctx.rev()
238 pos = ctx.rev()
239 start = max(0, pos - revcount + 1)
239 start = max(0, pos - revcount + 1)
240 end = min(count, start + revcount)
240 end = min(count, start + revcount)
241 pos = end - 1
241 pos = end - 1
242 parity = paritygen(web.stripecount, offset=start - end)
242 parity = paritygen(web.stripecount, offset=start - end)
243
243
244 changenav = webutil.revnavgen(pos, revcount, count, web.repo.changectx)
244 changenav = webutil.revnavgen(pos, revcount, count, web.repo.changectx)
245
245
246 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
246 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
247 node=ctx.hex(), rev=pos, changesets=count,
247 node=ctx.hex(), rev=pos, changesets=count,
248 entries=lambda **x: changelist(limit=0,**x),
248 entries=lambda **x: changelist(limit=0,**x),
249 latestentry=lambda **x: changelist(limit=1,**x),
249 latestentry=lambda **x: changelist(limit=1,**x),
250 archives=web.archivelist("tip"), revcount=revcount,
250 archives=web.archivelist("tip"), revcount=revcount,
251 morevars=morevars, lessvars=lessvars)
251 morevars=morevars, lessvars=lessvars)
252
252
253 def shortlog(web, req, tmpl):
253 def shortlog(web, req, tmpl):
254 return changelog(web, req, tmpl, shortlog = True)
254 return changelog(web, req, tmpl, shortlog = True)
255
255
256 def changeset(web, req, tmpl):
256 def changeset(web, req, tmpl):
257 ctx = webutil.changectx(web.repo, req)
257 ctx = webutil.changectx(web.repo, req)
258 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
258 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
259 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
259 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
260 ctx.node())
260 ctx.node())
261 showbranch = webutil.nodebranchnodefault(ctx)
261 showbranch = webutil.nodebranchnodefault(ctx)
262
262
263 files = []
263 files = []
264 parity = paritygen(web.stripecount)
264 parity = paritygen(web.stripecount)
265 for blockno, f in enumerate(ctx.files()):
265 for blockno, f in enumerate(ctx.files()):
266 template = f in ctx and 'filenodelink' or 'filenolink'
266 template = f in ctx and 'filenodelink' or 'filenolink'
267 files.append(tmpl(template,
267 files.append(tmpl(template,
268 node=ctx.hex(), file=f, blockno=blockno + 1,
268 node=ctx.hex(), file=f, blockno=blockno + 1,
269 parity=parity.next()))
269 parity=parity.next()))
270
270
271 style = web.config('web', 'style', 'paper')
271 style = web.config('web', 'style', 'paper')
272 if 'style' in req.form:
272 if 'style' in req.form:
273 style = req.form['style'][0]
273 style = req.form['style'][0]
274
274
275 parity = paritygen(web.stripecount)
275 parity = paritygen(web.stripecount)
276 diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
276 diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
277
277
278 parity = paritygen(web.stripecount)
278 parity = paritygen(web.stripecount)
279 diffstatgen = webutil.diffstatgen(ctx)
279 diffstatgen = webutil.diffstatgen(ctx)
280 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
280 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
281
281
282 return tmpl('changeset',
282 return tmpl('changeset',
283 diff=diffs,
283 diff=diffs,
284 rev=ctx.rev(),
284 rev=ctx.rev(),
285 node=ctx.hex(),
285 node=ctx.hex(),
286 parent=webutil.parents(ctx),
286 parent=webutil.parents(ctx),
287 child=webutil.children(ctx),
287 child=webutil.children(ctx),
288 changesettag=showtags,
288 changesettag=showtags,
289 changesetbookmark=showbookmarks,
289 changesetbookmark=showbookmarks,
290 changesetbranch=showbranch,
290 changesetbranch=showbranch,
291 author=ctx.user(),
291 author=ctx.user(),
292 desc=ctx.description(),
292 desc=ctx.description(),
293 date=ctx.date(),
293 date=ctx.date(),
294 files=files,
294 files=files,
295 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
295 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
296 diffstat=diffstat,
296 diffstat=diffstat,
297 archives=web.archivelist(ctx.hex()),
297 archives=web.archivelist(ctx.hex()),
298 tags=webutil.nodetagsdict(web.repo, ctx.node()),
298 tags=webutil.nodetagsdict(web.repo, ctx.node()),
299 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
299 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
300 branch=webutil.nodebranchnodefault(ctx),
300 branch=webutil.nodebranchnodefault(ctx),
301 inbranch=webutil.nodeinbranch(web.repo, ctx),
301 inbranch=webutil.nodeinbranch(web.repo, ctx),
302 branches=webutil.nodebranchdict(web.repo, ctx))
302 branches=webutil.nodebranchdict(web.repo, ctx))
303
303
304 rev = changeset
304 rev = changeset
305
305
306 def decodepath(path):
306 def decodepath(path):
307 """Hook for mapping a path in the repository to a path in the
307 """Hook for mapping a path in the repository to a path in the
308 working copy.
308 working copy.
309
309
310 Extensions (e.g., largefiles) can override this to remap files in
310 Extensions (e.g., largefiles) can override this to remap files in
311 the virtual file system presented by the manifest command below."""
311 the virtual file system presented by the manifest command below."""
312 return path
312 return path
313
313
314 def manifest(web, req, tmpl):
314 def manifest(web, req, tmpl):
315 ctx = webutil.changectx(web.repo, req)
315 ctx = webutil.changectx(web.repo, req)
316 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
316 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
317 mf = ctx.manifest()
317 mf = ctx.manifest()
318 node = ctx.node()
318 node = ctx.node()
319
319
320 files = {}
320 files = {}
321 dirs = {}
321 dirs = {}
322 parity = paritygen(web.stripecount)
322 parity = paritygen(web.stripecount)
323
323
324 if path and path[-1] != "/":
324 if path and path[-1] != "/":
325 path += "/"
325 path += "/"
326 l = len(path)
326 l = len(path)
327 abspath = "/" + path
327 abspath = "/" + path
328
328
329 for full, n in mf.iteritems():
329 for full, n in mf.iteritems():
330 # the virtual path (working copy path) used for the full
330 # the virtual path (working copy path) used for the full
331 # (repository) path
331 # (repository) path
332 f = decodepath(full)
332 f = decodepath(full)
333
333
334 if f[:l] != path:
334 if f[:l] != path:
335 continue
335 continue
336 remain = f[l:]
336 remain = f[l:]
337 elements = remain.split('/')
337 elements = remain.split('/')
338 if len(elements) == 1:
338 if len(elements) == 1:
339 files[remain] = full
339 files[remain] = full
340 else:
340 else:
341 h = dirs # need to retain ref to dirs (root)
341 h = dirs # need to retain ref to dirs (root)
342 for elem in elements[0:-1]:
342 for elem in elements[0:-1]:
343 if elem not in h:
343 if elem not in h:
344 h[elem] = {}
344 h[elem] = {}
345 h = h[elem]
345 h = h[elem]
346 if len(h) > 1:
346 if len(h) > 1:
347 break
347 break
348 h[None] = None # denotes files present
348 h[None] = None # denotes files present
349
349
350 if mf and not files and not dirs:
350 if mf and not files and not dirs:
351 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
351 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
352
352
353 def filelist(**map):
353 def filelist(**map):
354 for f in sorted(files):
354 for f in sorted(files):
355 full = files[f]
355 full = files[f]
356
356
357 fctx = ctx.filectx(full)
357 fctx = ctx.filectx(full)
358 yield {"file": full,
358 yield {"file": full,
359 "parity": parity.next(),
359 "parity": parity.next(),
360 "basename": f,
360 "basename": f,
361 "date": fctx.date(),
361 "date": fctx.date(),
362 "size": fctx.size(),
362 "size": fctx.size(),
363 "permissions": mf.flags(full)}
363 "permissions": mf.flags(full)}
364
364
365 def dirlist(**map):
365 def dirlist(**map):
366 for d in sorted(dirs):
366 for d in sorted(dirs):
367
367
368 emptydirs = []
368 emptydirs = []
369 h = dirs[d]
369 h = dirs[d]
370 while isinstance(h, dict) and len(h) == 1:
370 while isinstance(h, dict) and len(h) == 1:
371 k, v = h.items()[0]
371 k, v = h.items()[0]
372 if v:
372 if v:
373 emptydirs.append(k)
373 emptydirs.append(k)
374 h = v
374 h = v
375
375
376 path = "%s%s" % (abspath, d)
376 path = "%s%s" % (abspath, d)
377 yield {"parity": parity.next(),
377 yield {"parity": parity.next(),
378 "path": path,
378 "path": path,
379 "emptydirs": "/".join(emptydirs),
379 "emptydirs": "/".join(emptydirs),
380 "basename": d}
380 "basename": d}
381
381
382 return tmpl("manifest",
382 return tmpl("manifest",
383 rev=ctx.rev(),
383 rev=ctx.rev(),
384 node=hex(node),
384 node=hex(node),
385 path=abspath,
385 path=abspath,
386 up=webutil.up(abspath),
386 up=webutil.up(abspath),
387 upparity=parity.next(),
387 upparity=parity.next(),
388 fentries=filelist,
388 fentries=filelist,
389 dentries=dirlist,
389 dentries=dirlist,
390 archives=web.archivelist(hex(node)),
390 archives=web.archivelist(hex(node)),
391 tags=webutil.nodetagsdict(web.repo, node),
391 tags=webutil.nodetagsdict(web.repo, node),
392 bookmarks=webutil.nodebookmarksdict(web.repo, node),
392 bookmarks=webutil.nodebookmarksdict(web.repo, node),
393 inbranch=webutil.nodeinbranch(web.repo, ctx),
393 inbranch=webutil.nodeinbranch(web.repo, ctx),
394 branches=webutil.nodebranchdict(web.repo, ctx))
394 branches=webutil.nodebranchdict(web.repo, ctx))
395
395
396 def tags(web, req, tmpl):
396 def tags(web, req, tmpl):
397 i = reversed(web.repo.tagslist())
397 i = reversed(web.repo.tagslist())
398 parity = paritygen(web.stripecount)
398 parity = paritygen(web.stripecount)
399
399
400 def entries(notip=False, limit=0, **map):
400 def entries(notip=False, limit=0, **map):
401 count = 0
401 count = 0
402 for k, n in i:
402 for k, n in i:
403 if notip and k == "tip":
403 if notip and k == "tip":
404 continue
404 continue
405 if limit > 0 and count >= limit:
405 if limit > 0 and count >= limit:
406 continue
406 continue
407 count = count + 1
407 count = count + 1
408 yield {"parity": parity.next(),
408 yield {"parity": parity.next(),
409 "tag": k,
409 "tag": k,
410 "date": web.repo[n].date(),
410 "date": web.repo[n].date(),
411 "node": hex(n)}
411 "node": hex(n)}
412
412
413 return tmpl("tags",
413 return tmpl("tags",
414 node=hex(web.repo.changelog.tip()),
414 node=hex(web.repo.changelog.tip()),
415 entries=lambda **x: entries(False, 0, **x),
415 entries=lambda **x: entries(False, 0, **x),
416 entriesnotip=lambda **x: entries(True, 0, **x),
416 entriesnotip=lambda **x: entries(True, 0, **x),
417 latestentry=lambda **x: entries(True, 1, **x))
417 latestentry=lambda **x: entries(True, 1, **x))
418
418
419 def bookmarks(web, req, tmpl):
419 def bookmarks(web, req, tmpl):
420 i = web.repo._bookmarks.items()
420 i = web.repo._bookmarks.items()
421 parity = paritygen(web.stripecount)
421 parity = paritygen(web.stripecount)
422
422
423 def entries(limit=0, **map):
423 def entries(limit=0, **map):
424 count = 0
424 count = 0
425 for k, n in sorted(i):
425 for k, n in sorted(i):
426 if limit > 0 and count >= limit:
426 if limit > 0 and count >= limit:
427 continue
427 continue
428 count = count + 1
428 count = count + 1
429 yield {"parity": parity.next(),
429 yield {"parity": parity.next(),
430 "bookmark": k,
430 "bookmark": k,
431 "date": web.repo[n].date(),
431 "date": web.repo[n].date(),
432 "node": hex(n)}
432 "node": hex(n)}
433
433
434 return tmpl("bookmarks",
434 return tmpl("bookmarks",
435 node=hex(web.repo.changelog.tip()),
435 node=hex(web.repo.changelog.tip()),
436 entries=lambda **x: entries(0, **x),
436 entries=lambda **x: entries(0, **x),
437 latestentry=lambda **x: entries(1, **x))
437 latestentry=lambda **x: entries(1, **x))
438
438
439 def branches(web, req, tmpl):
439 def branches(web, req, tmpl):
440 tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
440 tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
441 heads = web.repo.heads()
441 heads = web.repo.heads()
442 parity = paritygen(web.stripecount)
442 parity = paritygen(web.stripecount)
443 sortkey = lambda ctx: (not ctx.closesbranch(), ctx.rev())
443 sortkey = lambda ctx: (not ctx.closesbranch(), ctx.rev())
444
444
445 def entries(limit, **map):
445 def entries(limit, **map):
446 count = 0
446 count = 0
447 for ctx in sorted(tips, key=sortkey, reverse=True):
447 for ctx in sorted(tips, key=sortkey, reverse=True):
448 if limit > 0 and count >= limit:
448 if limit > 0 and count >= limit:
449 return
449 return
450 count += 1
450 count += 1
451 if not web.repo.branchheads(ctx.branch()):
451 if not web.repo.branchheads(ctx.branch()):
452 status = 'closed'
452 status = 'closed'
453 elif ctx.node() not in heads:
453 elif ctx.node() not in heads:
454 status = 'inactive'
454 status = 'inactive'
455 else:
455 else:
456 status = 'open'
456 status = 'open'
457 yield {'parity': parity.next(),
457 yield {'parity': parity.next(),
458 'branch': ctx.branch(),
458 'branch': ctx.branch(),
459 'status': status,
459 'status': status,
460 'node': ctx.hex(),
460 'node': ctx.hex(),
461 'date': ctx.date()}
461 'date': ctx.date()}
462
462
463 return tmpl('branches', node=hex(web.repo.changelog.tip()),
463 return tmpl('branches', node=hex(web.repo.changelog.tip()),
464 entries=lambda **x: entries(0, **x),
464 entries=lambda **x: entries(0, **x),
465 latestentry=lambda **x: entries(1, **x))
465 latestentry=lambda **x: entries(1, **x))
466
466
467 def summary(web, req, tmpl):
467 def summary(web, req, tmpl):
468 i = reversed(web.repo.tagslist())
468 i = reversed(web.repo.tagslist())
469
469
470 def tagentries(**map):
470 def tagentries(**map):
471 parity = paritygen(web.stripecount)
471 parity = paritygen(web.stripecount)
472 count = 0
472 count = 0
473 for k, n in i:
473 for k, n in i:
474 if k == "tip": # skip tip
474 if k == "tip": # skip tip
475 continue
475 continue
476
476
477 count += 1
477 count += 1
478 if count > 10: # limit to 10 tags
478 if count > 10: # limit to 10 tags
479 break
479 break
480
480
481 yield tmpl("tagentry",
481 yield tmpl("tagentry",
482 parity=parity.next(),
482 parity=parity.next(),
483 tag=k,
483 tag=k,
484 node=hex(n),
484 node=hex(n),
485 date=web.repo[n].date())
485 date=web.repo[n].date())
486
486
487 def bookmarks(**map):
487 def bookmarks(**map):
488 parity = paritygen(web.stripecount)
488 parity = paritygen(web.stripecount)
489 b = web.repo._bookmarks.items()
489 b = web.repo._bookmarks.items()
490 for k, n in sorted(b)[:10]: # limit to 10 bookmarks
490 for k, n in sorted(b)[:10]: # limit to 10 bookmarks
491 yield {'parity': parity.next(),
491 yield {'parity': parity.next(),
492 'bookmark': k,
492 'bookmark': k,
493 'date': web.repo[n].date(),
493 'date': web.repo[n].date(),
494 'node': hex(n)}
494 'node': hex(n)}
495
495
496 def branches(**map):
496 def branches(**map):
497 parity = paritygen(web.stripecount)
497 parity = paritygen(web.stripecount)
498
498
499 b = web.repo.branchtags()
499 b = web.repo.branchtags()
500 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
500 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
501 for r, n, t in sorted(l):
501 for r, n, t in sorted(l):
502 yield {'parity': parity.next(),
502 yield {'parity': parity.next(),
503 'branch': t,
503 'branch': t,
504 'node': hex(n),
504 'node': hex(n),
505 'date': web.repo[n].date()}
505 'date': web.repo[n].date()}
506
506
507 def changelist(**map):
507 def changelist(**map):
508 parity = paritygen(web.stripecount, offset=start - end)
508 parity = paritygen(web.stripecount, offset=start - end)
509 l = [] # build a list in forward order for efficiency
509 l = [] # build a list in forward order for efficiency
510 for i in xrange(start, end):
510 for i in xrange(start, end):
511 ctx = web.repo[i]
511 ctx = web.repo[i]
512 n = ctx.node()
512 n = ctx.node()
513 hn = hex(n)
513 hn = hex(n)
514
514
515 l.insert(0, tmpl(
515 l.insert(0, tmpl(
516 'shortlogentry',
516 'shortlogentry',
517 parity=parity.next(),
517 parity=parity.next(),
518 author=ctx.user(),
518 author=ctx.user(),
519 desc=ctx.description(),
519 desc=ctx.description(),
520 date=ctx.date(),
520 date=ctx.date(),
521 rev=i,
521 rev=i,
522 node=hn,
522 node=hn,
523 tags=webutil.nodetagsdict(web.repo, n),
523 tags=webutil.nodetagsdict(web.repo, n),
524 bookmarks=webutil.nodebookmarksdict(web.repo, n),
524 bookmarks=webutil.nodebookmarksdict(web.repo, n),
525 inbranch=webutil.nodeinbranch(web.repo, ctx),
525 inbranch=webutil.nodeinbranch(web.repo, ctx),
526 branches=webutil.nodebranchdict(web.repo, ctx)))
526 branches=webutil.nodebranchdict(web.repo, ctx)))
527
527
528 yield l
528 yield l
529
529
530 tip = web.repo['tip']
530 tip = web.repo['tip']
531 count = len(web.repo)
531 count = len(web.repo)
532 start = max(0, count - web.maxchanges)
532 start = max(0, count - web.maxchanges)
533 end = min(count, start + web.maxchanges)
533 end = min(count, start + web.maxchanges)
534
534
535 return tmpl("summary",
535 return tmpl("summary",
536 desc=web.config("web", "description", "unknown"),
536 desc=web.config("web", "description", "unknown"),
537 owner=get_contact(web.config) or "unknown",
537 owner=get_contact(web.config) or "unknown",
538 lastchange=tip.date(),
538 lastchange=tip.date(),
539 tags=tagentries,
539 tags=tagentries,
540 bookmarks=bookmarks,
540 bookmarks=bookmarks,
541 branches=branches,
541 branches=branches,
542 shortlog=changelist,
542 shortlog=changelist,
543 node=tip.hex(),
543 node=tip.hex(),
544 archives=web.archivelist("tip"))
544 archives=web.archivelist("tip"))
545
545
546 def filediff(web, req, tmpl):
546 def filediff(web, req, tmpl):
547 fctx, ctx = None, None
547 fctx, ctx = None, None
548 try:
548 try:
549 fctx = webutil.filectx(web.repo, req)
549 fctx = webutil.filectx(web.repo, req)
550 except LookupError:
550 except LookupError:
551 ctx = webutil.changectx(web.repo, req)
551 ctx = webutil.changectx(web.repo, req)
552 path = webutil.cleanpath(web.repo, req.form['file'][0])
552 path = webutil.cleanpath(web.repo, req.form['file'][0])
553 if path not in ctx.files():
553 if path not in ctx.files():
554 raise
554 raise
555
555
556 if fctx is not None:
556 if fctx is not None:
557 n = fctx.node()
557 n = fctx.node()
558 path = fctx.path()
558 path = fctx.path()
559 ctx = fctx.changectx()
559 ctx = fctx.changectx()
560 else:
560 else:
561 n = ctx.node()
561 n = ctx.node()
562 # path already defined in except clause
562 # path already defined in except clause
563
563
564 parity = paritygen(web.stripecount)
564 parity = paritygen(web.stripecount)
565 style = web.config('web', 'style', 'paper')
565 style = web.config('web', 'style', 'paper')
566 if 'style' in req.form:
566 if 'style' in req.form:
567 style = req.form['style'][0]
567 style = req.form['style'][0]
568
568
569 diffs = webutil.diffs(web.repo, tmpl, ctx, [path], parity, style)
569 diffs = webutil.diffs(web.repo, tmpl, ctx, [path], parity, style)
570 rename = fctx and webutil.renamelink(fctx) or []
570 rename = fctx and webutil.renamelink(fctx) or []
571 ctx = fctx and fctx or ctx
571 ctx = fctx and fctx or ctx
572 return tmpl("filediff",
572 return tmpl("filediff",
573 file=path,
573 file=path,
574 node=hex(n),
574 node=hex(n),
575 rev=ctx.rev(),
575 rev=ctx.rev(),
576 date=ctx.date(),
576 date=ctx.date(),
577 desc=ctx.description(),
577 desc=ctx.description(),
578 author=ctx.user(),
578 author=ctx.user(),
579 rename=rename,
579 rename=rename,
580 branch=webutil.nodebranchnodefault(ctx),
580 branch=webutil.nodebranchnodefault(ctx),
581 parent=webutil.parents(ctx),
581 parent=webutil.parents(ctx),
582 child=webutil.children(ctx),
582 child=webutil.children(ctx),
583 diff=diffs)
583 diff=diffs)
584
584
585 diff = filediff
585 diff = filediff
586
586
587 def comparison(web, req, tmpl):
587 def comparison(web, req, tmpl):
588 ctx = webutil.changectx(web.repo, req)
588 ctx = webutil.changectx(web.repo, req)
589 if 'file' not in req.form:
589 if 'file' not in req.form:
590 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
590 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
591 path = webutil.cleanpath(web.repo, req.form['file'][0])
591 path = webutil.cleanpath(web.repo, req.form['file'][0])
592 rename = path in ctx and webutil.renamelink(ctx[path]) or []
592 rename = path in ctx and webutil.renamelink(ctx[path]) or []
593
593
594 parsecontext = lambda v: v == 'full' and -1 or int(v)
594 parsecontext = lambda v: v == 'full' and -1 or int(v)
595 if 'context' in req.form:
595 if 'context' in req.form:
596 context = parsecontext(req.form['context'][0])
596 context = parsecontext(req.form['context'][0])
597 else:
597 else:
598 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
598 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
599
599
600 comparison = webutil.compare(tmpl, ctx, path, context)
600 def filelines(f):
601 if binary(f.data()):
602 mt = mimetypes.guess_type(f.path())[0]
603 if not mt:
604 mt = 'application/octet-stream'
605 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
606 return f.data().splitlines()
607
608 if path in ctx:
609 fctx = ctx[path]
610 rightrev = fctx.filerev()
611 rightnode = fctx.filenode()
612 rightlines = filelines(fctx)
613 parents = fctx.parents()
614 if not parents:
615 leftrev = -1
616 leftnode = nullid
617 leftlines = ()
618 else:
619 pfctx = parents[0]
620 leftrev = pfctx.filerev()
621 leftnode = pfctx.filenode()
622 leftlines = filelines(pfctx)
623 else:
624 rightrev = -1
625 rightnode = nullid
626 rightlines = ()
627 fctx = ctx.parents()[0][path]
628 leftrev = fctx.filerev()
629 leftnode = fctx.filenode()
630 leftlines = filelines(fctx)
631
632 comparison = webutil.compare(tmpl, context, leftlines, rightlines)
601 return tmpl('filecomparison',
633 return tmpl('filecomparison',
602 file=path,
634 file=path,
603 node=hex(ctx.node()),
635 node=hex(ctx.node()),
604 rev=ctx.rev(),
636 rev=ctx.rev(),
605 date=ctx.date(),
637 date=ctx.date(),
606 desc=ctx.description(),
638 desc=ctx.description(),
607 author=ctx.user(),
639 author=ctx.user(),
608 rename=rename,
640 rename=rename,
609 branch=webutil.nodebranchnodefault(ctx),
641 branch=webutil.nodebranchnodefault(ctx),
610 parent=webutil.parents(ctx),
642 parent=webutil.parents(ctx),
611 child=webutil.children(ctx),
643 child=webutil.children(ctx),
644 leftrev=leftrev,
645 leftnode=hex(leftnode),
646 rightrev=rightrev,
647 rightnode=hex(rightnode),
612 comparison=comparison)
648 comparison=comparison)
613
649
614 def annotate(web, req, tmpl):
650 def annotate(web, req, tmpl):
615 fctx = webutil.filectx(web.repo, req)
651 fctx = webutil.filectx(web.repo, req)
616 f = fctx.path()
652 f = fctx.path()
617 parity = paritygen(web.stripecount)
653 parity = paritygen(web.stripecount)
618 diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
654 diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
619
655
620 def annotate(**map):
656 def annotate(**map):
621 last = None
657 last = None
622 if binary(fctx.data()):
658 if binary(fctx.data()):
623 mt = (mimetypes.guess_type(fctx.path())[0]
659 mt = (mimetypes.guess_type(fctx.path())[0]
624 or 'application/octet-stream')
660 or 'application/octet-stream')
625 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
661 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
626 '(binary:%s)' % mt)])
662 '(binary:%s)' % mt)])
627 else:
663 else:
628 lines = enumerate(fctx.annotate(follow=True, linenumber=True,
664 lines = enumerate(fctx.annotate(follow=True, linenumber=True,
629 diffopts=diffopts))
665 diffopts=diffopts))
630 for lineno, ((f, targetline), l) in lines:
666 for lineno, ((f, targetline), l) in lines:
631 fnode = f.filenode()
667 fnode = f.filenode()
632
668
633 if last != fnode:
669 if last != fnode:
634 last = fnode
670 last = fnode
635
671
636 yield {"parity": parity.next(),
672 yield {"parity": parity.next(),
637 "node": f.hex(),
673 "node": f.hex(),
638 "rev": f.rev(),
674 "rev": f.rev(),
639 "author": f.user(),
675 "author": f.user(),
640 "desc": f.description(),
676 "desc": f.description(),
641 "file": f.path(),
677 "file": f.path(),
642 "targetline": targetline,
678 "targetline": targetline,
643 "line": l,
679 "line": l,
644 "lineid": "l%d" % (lineno + 1),
680 "lineid": "l%d" % (lineno + 1),
645 "linenumber": "% 6d" % (lineno + 1),
681 "linenumber": "% 6d" % (lineno + 1),
646 "revdate": f.date()}
682 "revdate": f.date()}
647
683
648 return tmpl("fileannotate",
684 return tmpl("fileannotate",
649 file=f,
685 file=f,
650 annotate=annotate,
686 annotate=annotate,
651 path=webutil.up(f),
687 path=webutil.up(f),
652 rev=fctx.rev(),
688 rev=fctx.rev(),
653 node=fctx.hex(),
689 node=fctx.hex(),
654 author=fctx.user(),
690 author=fctx.user(),
655 date=fctx.date(),
691 date=fctx.date(),
656 desc=fctx.description(),
692 desc=fctx.description(),
657 rename=webutil.renamelink(fctx),
693 rename=webutil.renamelink(fctx),
658 branch=webutil.nodebranchnodefault(fctx),
694 branch=webutil.nodebranchnodefault(fctx),
659 parent=webutil.parents(fctx),
695 parent=webutil.parents(fctx),
660 child=webutil.children(fctx),
696 child=webutil.children(fctx),
661 permissions=fctx.manifest().flags(f))
697 permissions=fctx.manifest().flags(f))
662
698
663 def filelog(web, req, tmpl):
699 def filelog(web, req, tmpl):
664
700
665 try:
701 try:
666 fctx = webutil.filectx(web.repo, req)
702 fctx = webutil.filectx(web.repo, req)
667 f = fctx.path()
703 f = fctx.path()
668 fl = fctx.filelog()
704 fl = fctx.filelog()
669 except error.LookupError:
705 except error.LookupError:
670 f = webutil.cleanpath(web.repo, req.form['file'][0])
706 f = webutil.cleanpath(web.repo, req.form['file'][0])
671 fl = web.repo.file(f)
707 fl = web.repo.file(f)
672 numrevs = len(fl)
708 numrevs = len(fl)
673 if not numrevs: # file doesn't exist at all
709 if not numrevs: # file doesn't exist at all
674 raise
710 raise
675 rev = webutil.changectx(web.repo, req).rev()
711 rev = webutil.changectx(web.repo, req).rev()
676 first = fl.linkrev(0)
712 first = fl.linkrev(0)
677 if rev < first: # current rev is from before file existed
713 if rev < first: # current rev is from before file existed
678 raise
714 raise
679 frev = numrevs - 1
715 frev = numrevs - 1
680 while fl.linkrev(frev) > rev:
716 while fl.linkrev(frev) > rev:
681 frev -= 1
717 frev -= 1
682 fctx = web.repo.filectx(f, fl.linkrev(frev))
718 fctx = web.repo.filectx(f, fl.linkrev(frev))
683
719
684 revcount = web.maxshortchanges
720 revcount = web.maxshortchanges
685 if 'revcount' in req.form:
721 if 'revcount' in req.form:
686 revcount = int(req.form.get('revcount', [revcount])[0])
722 revcount = int(req.form.get('revcount', [revcount])[0])
687 revcount = max(revcount, 1)
723 revcount = max(revcount, 1)
688 tmpl.defaults['sessionvars']['revcount'] = revcount
724 tmpl.defaults['sessionvars']['revcount'] = revcount
689
725
690 lessvars = copy.copy(tmpl.defaults['sessionvars'])
726 lessvars = copy.copy(tmpl.defaults['sessionvars'])
691 lessvars['revcount'] = max(revcount / 2, 1)
727 lessvars['revcount'] = max(revcount / 2, 1)
692 morevars = copy.copy(tmpl.defaults['sessionvars'])
728 morevars = copy.copy(tmpl.defaults['sessionvars'])
693 morevars['revcount'] = revcount * 2
729 morevars['revcount'] = revcount * 2
694
730
695 count = fctx.filerev() + 1
731 count = fctx.filerev() + 1
696 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
732 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
697 end = min(count, start + revcount) # last rev on this page
733 end = min(count, start + revcount) # last rev on this page
698 parity = paritygen(web.stripecount, offset=start - end)
734 parity = paritygen(web.stripecount, offset=start - end)
699
735
700 def entries(limit=0, **map):
736 def entries(limit=0, **map):
701 l = []
737 l = []
702
738
703 repo = web.repo
739 repo = web.repo
704 for i in xrange(start, end):
740 for i in xrange(start, end):
705 iterfctx = fctx.filectx(i)
741 iterfctx = fctx.filectx(i)
706
742
707 l.insert(0, {"parity": parity.next(),
743 l.insert(0, {"parity": parity.next(),
708 "filerev": i,
744 "filerev": i,
709 "file": f,
745 "file": f,
710 "node": iterfctx.hex(),
746 "node": iterfctx.hex(),
711 "author": iterfctx.user(),
747 "author": iterfctx.user(),
712 "date": iterfctx.date(),
748 "date": iterfctx.date(),
713 "rename": webutil.renamelink(iterfctx),
749 "rename": webutil.renamelink(iterfctx),
714 "parent": webutil.parents(iterfctx),
750 "parent": webutil.parents(iterfctx),
715 "child": webutil.children(iterfctx),
751 "child": webutil.children(iterfctx),
716 "desc": iterfctx.description(),
752 "desc": iterfctx.description(),
717 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
753 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
718 "bookmarks": webutil.nodebookmarksdict(
754 "bookmarks": webutil.nodebookmarksdict(
719 repo, iterfctx.node()),
755 repo, iterfctx.node()),
720 "branch": webutil.nodebranchnodefault(iterfctx),
756 "branch": webutil.nodebranchnodefault(iterfctx),
721 "inbranch": webutil.nodeinbranch(repo, iterfctx),
757 "inbranch": webutil.nodeinbranch(repo, iterfctx),
722 "branches": webutil.nodebranchdict(repo, iterfctx)})
758 "branches": webutil.nodebranchdict(repo, iterfctx)})
723
759
724 if limit > 0:
760 if limit > 0:
725 l = l[:limit]
761 l = l[:limit]
726
762
727 for e in l:
763 for e in l:
728 yield e
764 yield e
729
765
730 nodefunc = lambda x: fctx.filectx(fileid=x)
766 nodefunc = lambda x: fctx.filectx(fileid=x)
731 nav = webutil.revnavgen(end - 1, revcount, count, nodefunc)
767 nav = webutil.revnavgen(end - 1, revcount, count, nodefunc)
732 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
768 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
733 entries=lambda **x: entries(limit=0, **x),
769 entries=lambda **x: entries(limit=0, **x),
734 latestentry=lambda **x: entries(limit=1, **x),
770 latestentry=lambda **x: entries(limit=1, **x),
735 revcount=revcount, morevars=morevars, lessvars=lessvars)
771 revcount=revcount, morevars=morevars, lessvars=lessvars)
736
772
737 def archive(web, req, tmpl):
773 def archive(web, req, tmpl):
738 type_ = req.form.get('type', [None])[0]
774 type_ = req.form.get('type', [None])[0]
739 allowed = web.configlist("web", "allow_archive")
775 allowed = web.configlist("web", "allow_archive")
740 key = req.form['node'][0]
776 key = req.form['node'][0]
741
777
742 if type_ not in web.archives:
778 if type_ not in web.archives:
743 msg = 'Unsupported archive type: %s' % type_
779 msg = 'Unsupported archive type: %s' % type_
744 raise ErrorResponse(HTTP_NOT_FOUND, msg)
780 raise ErrorResponse(HTTP_NOT_FOUND, msg)
745
781
746 if not ((type_ in allowed or
782 if not ((type_ in allowed or
747 web.configbool("web", "allow" + type_, False))):
783 web.configbool("web", "allow" + type_, False))):
748 msg = 'Archive type not allowed: %s' % type_
784 msg = 'Archive type not allowed: %s' % type_
749 raise ErrorResponse(HTTP_FORBIDDEN, msg)
785 raise ErrorResponse(HTTP_FORBIDDEN, msg)
750
786
751 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
787 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
752 cnode = web.repo.lookup(key)
788 cnode = web.repo.lookup(key)
753 arch_version = key
789 arch_version = key
754 if cnode == key or key == 'tip':
790 if cnode == key or key == 'tip':
755 arch_version = short(cnode)
791 arch_version = short(cnode)
756 name = "%s-%s" % (reponame, arch_version)
792 name = "%s-%s" % (reponame, arch_version)
757 mimetype, artype, extension, encoding = web.archive_specs[type_]
793 mimetype, artype, extension, encoding = web.archive_specs[type_]
758 headers = [
794 headers = [
759 ('Content-Type', mimetype),
795 ('Content-Type', mimetype),
760 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
796 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
761 ]
797 ]
762 if encoding:
798 if encoding:
763 headers.append(('Content-Encoding', encoding))
799 headers.append(('Content-Encoding', encoding))
764 req.header(headers)
800 req.header(headers)
765 req.respond(HTTP_OK)
801 req.respond(HTTP_OK)
766 archival.archive(web.repo, req, cnode, artype, prefix=name)
802 archival.archive(web.repo, req, cnode, artype, prefix=name)
767 return []
803 return []
768
804
769
805
770 def static(web, req, tmpl):
806 def static(web, req, tmpl):
771 fname = req.form['file'][0]
807 fname = req.form['file'][0]
772 # a repo owner may set web.static in .hg/hgrc to get any file
808 # a repo owner may set web.static in .hg/hgrc to get any file
773 # readable by the user running the CGI script
809 # readable by the user running the CGI script
774 static = web.config("web", "static", None, untrusted=False)
810 static = web.config("web", "static", None, untrusted=False)
775 if not static:
811 if not static:
776 tp = web.templatepath or templater.templatepath()
812 tp = web.templatepath or templater.templatepath()
777 if isinstance(tp, str):
813 if isinstance(tp, str):
778 tp = [tp]
814 tp = [tp]
779 static = [os.path.join(p, 'static') for p in tp]
815 static = [os.path.join(p, 'static') for p in tp]
780 return [staticfile(static, fname, req)]
816 return [staticfile(static, fname, req)]
781
817
782 def graph(web, req, tmpl):
818 def graph(web, req, tmpl):
783
819
784 rev = webutil.changectx(web.repo, req).rev()
820 rev = webutil.changectx(web.repo, req).rev()
785 bg_height = 39
821 bg_height = 39
786 revcount = web.maxshortchanges
822 revcount = web.maxshortchanges
787 if 'revcount' in req.form:
823 if 'revcount' in req.form:
788 revcount = int(req.form.get('revcount', [revcount])[0])
824 revcount = int(req.form.get('revcount', [revcount])[0])
789 revcount = max(revcount, 1)
825 revcount = max(revcount, 1)
790 tmpl.defaults['sessionvars']['revcount'] = revcount
826 tmpl.defaults['sessionvars']['revcount'] = revcount
791
827
792 lessvars = copy.copy(tmpl.defaults['sessionvars'])
828 lessvars = copy.copy(tmpl.defaults['sessionvars'])
793 lessvars['revcount'] = max(revcount / 2, 1)
829 lessvars['revcount'] = max(revcount / 2, 1)
794 morevars = copy.copy(tmpl.defaults['sessionvars'])
830 morevars = copy.copy(tmpl.defaults['sessionvars'])
795 morevars['revcount'] = revcount * 2
831 morevars['revcount'] = revcount * 2
796
832
797 max_rev = len(web.repo) - 1
833 max_rev = len(web.repo) - 1
798 revcount = min(max_rev, revcount)
834 revcount = min(max_rev, revcount)
799 revnode = web.repo.changelog.node(rev)
835 revnode = web.repo.changelog.node(rev)
800 revnode_hex = hex(revnode)
836 revnode_hex = hex(revnode)
801 uprev = min(max_rev, rev + revcount)
837 uprev = min(max_rev, rev + revcount)
802 downrev = max(0, rev - revcount)
838 downrev = max(0, rev - revcount)
803 count = len(web.repo)
839 count = len(web.repo)
804 changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
840 changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
805 startrev = rev
841 startrev = rev
806 # if starting revision is less than 60 set it to uprev
842 # if starting revision is less than 60 set it to uprev
807 if rev < web.maxshortchanges:
843 if rev < web.maxshortchanges:
808 startrev = uprev
844 startrev = uprev
809
845
810 dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1))
846 dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1))
811 tree = list(graphmod.colored(dag, web.repo))
847 tree = list(graphmod.colored(dag, web.repo))
812
848
813 def getcolumns(tree):
849 def getcolumns(tree):
814 cols = 0
850 cols = 0
815 for (id, type, ctx, vtx, edges) in tree:
851 for (id, type, ctx, vtx, edges) in tree:
816 if type != graphmod.CHANGESET:
852 if type != graphmod.CHANGESET:
817 continue
853 continue
818 cols = max(cols, max([edge[0] for edge in edges] or [0]),
854 cols = max(cols, max([edge[0] for edge in edges] or [0]),
819 max([edge[1] for edge in edges] or [0]))
855 max([edge[1] for edge in edges] or [0]))
820 return cols
856 return cols
821
857
822 def graphdata(usetuples, **map):
858 def graphdata(usetuples, **map):
823 data = []
859 data = []
824
860
825 row = 0
861 row = 0
826 for (id, type, ctx, vtx, edges) in tree:
862 for (id, type, ctx, vtx, edges) in tree:
827 if type != graphmod.CHANGESET:
863 if type != graphmod.CHANGESET:
828 continue
864 continue
829 node = str(ctx)
865 node = str(ctx)
830 age = templatefilters.age(ctx.date())
866 age = templatefilters.age(ctx.date())
831 desc = templatefilters.firstline(ctx.description())
867 desc = templatefilters.firstline(ctx.description())
832 desc = cgi.escape(templatefilters.nonempty(desc))
868 desc = cgi.escape(templatefilters.nonempty(desc))
833 user = cgi.escape(templatefilters.person(ctx.user()))
869 user = cgi.escape(templatefilters.person(ctx.user()))
834 branch = ctx.branch()
870 branch = ctx.branch()
835 try:
871 try:
836 branchnode = web.repo.branchtip(branch)
872 branchnode = web.repo.branchtip(branch)
837 except error.RepoLookupError:
873 except error.RepoLookupError:
838 branchnode = None
874 branchnode = None
839 branch = branch, branchnode == ctx.node()
875 branch = branch, branchnode == ctx.node()
840
876
841 if usetuples:
877 if usetuples:
842 data.append((node, vtx, edges, desc, user, age, branch,
878 data.append((node, vtx, edges, desc, user, age, branch,
843 ctx.tags(), ctx.bookmarks()))
879 ctx.tags(), ctx.bookmarks()))
844 else:
880 else:
845 edgedata = [dict(col=edge[0], nextcol=edge[1],
881 edgedata = [dict(col=edge[0], nextcol=edge[1],
846 color=(edge[2] - 1) % 6 + 1,
882 color=(edge[2] - 1) % 6 + 1,
847 width=edge[3], bcolor=edge[4])
883 width=edge[3], bcolor=edge[4])
848 for edge in edges]
884 for edge in edges]
849
885
850 data.append(
886 data.append(
851 dict(node=node,
887 dict(node=node,
852 col=vtx[0],
888 col=vtx[0],
853 color=(vtx[1] - 1) % 6 + 1,
889 color=(vtx[1] - 1) % 6 + 1,
854 edges=edgedata,
890 edges=edgedata,
855 row=row,
891 row=row,
856 nextrow=row + 1,
892 nextrow=row + 1,
857 desc=desc,
893 desc=desc,
858 user=user,
894 user=user,
859 age=age,
895 age=age,
860 bookmarks=webutil.nodebookmarksdict(
896 bookmarks=webutil.nodebookmarksdict(
861 web.repo, ctx.node()),
897 web.repo, ctx.node()),
862 branches=webutil.nodebranchdict(web.repo, ctx),
898 branches=webutil.nodebranchdict(web.repo, ctx),
863 inbranch=webutil.nodeinbranch(web.repo, ctx),
899 inbranch=webutil.nodeinbranch(web.repo, ctx),
864 tags=webutil.nodetagsdict(web.repo, ctx.node())))
900 tags=webutil.nodetagsdict(web.repo, ctx.node())))
865
901
866 row += 1
902 row += 1
867
903
868 return data
904 return data
869
905
870 cols = getcolumns(tree)
906 cols = getcolumns(tree)
871 rows = len(tree)
907 rows = len(tree)
872 canvasheight = (rows + 1) * bg_height - 27
908 canvasheight = (rows + 1) * bg_height - 27
873
909
874 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
910 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
875 lessvars=lessvars, morevars=morevars, downrev=downrev,
911 lessvars=lessvars, morevars=morevars, downrev=downrev,
876 cols=cols, rows=rows,
912 cols=cols, rows=rows,
877 canvaswidth=(cols + 1) * bg_height,
913 canvaswidth=(cols + 1) * bg_height,
878 truecanvasheight=rows * bg_height,
914 truecanvasheight=rows * bg_height,
879 canvasheight=canvasheight, bg_height=bg_height,
915 canvasheight=canvasheight, bg_height=bg_height,
880 jsdata=lambda **x: graphdata(True, **x),
916 jsdata=lambda **x: graphdata(True, **x),
881 nodes=lambda **x: graphdata(False, **x),
917 nodes=lambda **x: graphdata(False, **x),
882 node=revnode_hex, changenav=changenav)
918 node=revnode_hex, changenav=changenav)
883
919
884 def _getdoc(e):
920 def _getdoc(e):
885 doc = e[0].__doc__
921 doc = e[0].__doc__
886 if doc:
922 if doc:
887 doc = _(doc).split('\n')[0]
923 doc = _(doc).split('\n')[0]
888 else:
924 else:
889 doc = _('(no help text available)')
925 doc = _('(no help text available)')
890 return doc
926 return doc
891
927
892 def help(web, req, tmpl):
928 def help(web, req, tmpl):
893 from mercurial import commands # avoid cycle
929 from mercurial import commands # avoid cycle
894
930
895 topicname = req.form.get('node', [None])[0]
931 topicname = req.form.get('node', [None])[0]
896 if not topicname:
932 if not topicname:
897 def topics(**map):
933 def topics(**map):
898 for entries, summary, _ in helpmod.helptable:
934 for entries, summary, _ in helpmod.helptable:
899 entries = sorted(entries, key=len)
935 entries = sorted(entries, key=len)
900 yield {'topic': entries[-1], 'summary': summary}
936 yield {'topic': entries[-1], 'summary': summary}
901
937
902 early, other = [], []
938 early, other = [], []
903 primary = lambda s: s.split('|')[0]
939 primary = lambda s: s.split('|')[0]
904 for c, e in commands.table.iteritems():
940 for c, e in commands.table.iteritems():
905 doc = _getdoc(e)
941 doc = _getdoc(e)
906 if 'DEPRECATED' in doc or c.startswith('debug'):
942 if 'DEPRECATED' in doc or c.startswith('debug'):
907 continue
943 continue
908 cmd = primary(c)
944 cmd = primary(c)
909 if cmd.startswith('^'):
945 if cmd.startswith('^'):
910 early.append((cmd[1:], doc))
946 early.append((cmd[1:], doc))
911 else:
947 else:
912 other.append((cmd, doc))
948 other.append((cmd, doc))
913
949
914 early.sort()
950 early.sort()
915 other.sort()
951 other.sort()
916
952
917 def earlycommands(**map):
953 def earlycommands(**map):
918 for c, doc in early:
954 for c, doc in early:
919 yield {'topic': c, 'summary': doc}
955 yield {'topic': c, 'summary': doc}
920
956
921 def othercommands(**map):
957 def othercommands(**map):
922 for c, doc in other:
958 for c, doc in other:
923 yield {'topic': c, 'summary': doc}
959 yield {'topic': c, 'summary': doc}
924
960
925 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
961 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
926 othercommands=othercommands, title='Index')
962 othercommands=othercommands, title='Index')
927
963
928 u = webutil.wsgiui()
964 u = webutil.wsgiui()
929 u.pushbuffer()
965 u.pushbuffer()
930 u.verbose = True
966 u.verbose = True
931 try:
967 try:
932 commands.help_(u, topicname)
968 commands.help_(u, topicname)
933 except error.UnknownCommand:
969 except error.UnknownCommand:
934 raise ErrorResponse(HTTP_NOT_FOUND)
970 raise ErrorResponse(HTTP_NOT_FOUND)
935 doc = u.popbuffer()
971 doc = u.popbuffer()
936 return tmpl('help', topic=topicname, doc=doc)
972 return tmpl('help', topic=topicname, doc=doc)
@@ -1,370 +1,331 b''
1 # hgweb/webutil.py - utility library for the web interface.
1 # hgweb/webutil.py - utility library for the web interface.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 import os, mimetypes, copy
9 import os, copy
10 from mercurial import match, patch, scmutil, error, ui, util
10 from mercurial import match, patch, scmutil, error, ui, util
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12 from mercurial.node import hex, nullid
12 from mercurial.node import hex, nullid
13 from common import ErrorResponse
13 from common import ErrorResponse
14 from common import HTTP_NOT_FOUND
14 from common import HTTP_NOT_FOUND
15 import difflib
15 import difflib
16
16
17 def up(p):
17 def up(p):
18 if p[0] != "/":
18 if p[0] != "/":
19 p = "/" + p
19 p = "/" + p
20 if p[-1] == "/":
20 if p[-1] == "/":
21 p = p[:-1]
21 p = p[:-1]
22 up = os.path.dirname(p)
22 up = os.path.dirname(p)
23 if up == "/":
23 if up == "/":
24 return "/"
24 return "/"
25 return up + "/"
25 return up + "/"
26
26
27 def revnavgen(pos, pagelen, limit, nodefunc):
27 def revnavgen(pos, pagelen, limit, nodefunc):
28 def seq(factor, limit=None):
28 def seq(factor, limit=None):
29 if limit:
29 if limit:
30 yield limit
30 yield limit
31 if limit >= 20 and limit <= 40:
31 if limit >= 20 and limit <= 40:
32 yield 50
32 yield 50
33 else:
33 else:
34 yield 1 * factor
34 yield 1 * factor
35 yield 3 * factor
35 yield 3 * factor
36 for f in seq(factor * 10):
36 for f in seq(factor * 10):
37 yield f
37 yield f
38
38
39 navbefore = []
39 navbefore = []
40 navafter = []
40 navafter = []
41
41
42 last = 0
42 last = 0
43 for f in seq(1, pagelen):
43 for f in seq(1, pagelen):
44 if f < pagelen or f <= last:
44 if f < pagelen or f <= last:
45 continue
45 continue
46 if f > limit:
46 if f > limit:
47 break
47 break
48 last = f
48 last = f
49 if pos + f < limit:
49 if pos + f < limit:
50 navafter.append(("+%d" % f, hex(nodefunc(pos + f).node())))
50 navafter.append(("+%d" % f, hex(nodefunc(pos + f).node())))
51 if pos - f >= 0:
51 if pos - f >= 0:
52 navbefore.insert(0, ("-%d" % f, hex(nodefunc(pos - f).node())))
52 navbefore.insert(0, ("-%d" % f, hex(nodefunc(pos - f).node())))
53
53
54 navafter.append(("tip", "tip"))
54 navafter.append(("tip", "tip"))
55 try:
55 try:
56 navbefore.insert(0, ("(0)", hex(nodefunc('0').node())))
56 navbefore.insert(0, ("(0)", hex(nodefunc('0').node())))
57 except error.RepoError:
57 except error.RepoError:
58 pass
58 pass
59
59
60 def gen(l):
60 def gen(l):
61 def f(**map):
61 def f(**map):
62 for label, node in l:
62 for label, node in l:
63 yield {"label": label, "node": node}
63 yield {"label": label, "node": node}
64 return f
64 return f
65
65
66 return (dict(before=gen(navbefore), after=gen(navafter)),)
66 return (dict(before=gen(navbefore), after=gen(navafter)),)
67
67
68 def _siblings(siblings=[], hiderev=None):
68 def _siblings(siblings=[], hiderev=None):
69 siblings = [s for s in siblings if s.node() != nullid]
69 siblings = [s for s in siblings if s.node() != nullid]
70 if len(siblings) == 1 and siblings[0].rev() == hiderev:
70 if len(siblings) == 1 and siblings[0].rev() == hiderev:
71 return
71 return
72 for s in siblings:
72 for s in siblings:
73 d = {'node': s.hex(), 'rev': s.rev()}
73 d = {'node': s.hex(), 'rev': s.rev()}
74 d['user'] = s.user()
74 d['user'] = s.user()
75 d['date'] = s.date()
75 d['date'] = s.date()
76 d['description'] = s.description()
76 d['description'] = s.description()
77 d['branch'] = s.branch()
77 d['branch'] = s.branch()
78 if util.safehasattr(s, 'path'):
78 if util.safehasattr(s, 'path'):
79 d['file'] = s.path()
79 d['file'] = s.path()
80 yield d
80 yield d
81
81
82 def parents(ctx, hide=None):
82 def parents(ctx, hide=None):
83 return _siblings(ctx.parents(), hide)
83 return _siblings(ctx.parents(), hide)
84
84
85 def children(ctx, hide=None):
85 def children(ctx, hide=None):
86 return _siblings(ctx.children(), hide)
86 return _siblings(ctx.children(), hide)
87
87
88 def renamelink(fctx):
88 def renamelink(fctx):
89 r = fctx.renamed()
89 r = fctx.renamed()
90 if r:
90 if r:
91 return [dict(file=r[0], node=hex(r[1]))]
91 return [dict(file=r[0], node=hex(r[1]))]
92 return []
92 return []
93
93
94 def nodetagsdict(repo, node):
94 def nodetagsdict(repo, node):
95 return [{"name": i} for i in repo.nodetags(node)]
95 return [{"name": i} for i in repo.nodetags(node)]
96
96
97 def nodebookmarksdict(repo, node):
97 def nodebookmarksdict(repo, node):
98 return [{"name": i} for i in repo.nodebookmarks(node)]
98 return [{"name": i} for i in repo.nodebookmarks(node)]
99
99
100 def nodebranchdict(repo, ctx):
100 def nodebranchdict(repo, ctx):
101 branches = []
101 branches = []
102 branch = ctx.branch()
102 branch = ctx.branch()
103 # If this is an empty repo, ctx.node() == nullid,
103 # If this is an empty repo, ctx.node() == nullid,
104 # ctx.branch() == 'default'.
104 # ctx.branch() == 'default'.
105 try:
105 try:
106 branchnode = repo.branchtip(branch)
106 branchnode = repo.branchtip(branch)
107 except error.RepoLookupError:
107 except error.RepoLookupError:
108 branchnode = None
108 branchnode = None
109 if branchnode == ctx.node():
109 if branchnode == ctx.node():
110 branches.append({"name": branch})
110 branches.append({"name": branch})
111 return branches
111 return branches
112
112
113 def nodeinbranch(repo, ctx):
113 def nodeinbranch(repo, ctx):
114 branches = []
114 branches = []
115 branch = ctx.branch()
115 branch = ctx.branch()
116 try:
116 try:
117 branchnode = repo.branchtip(branch)
117 branchnode = repo.branchtip(branch)
118 except error.RepoLookupError:
118 except error.RepoLookupError:
119 branchnode = None
119 branchnode = None
120 if branch != 'default' and branchnode != ctx.node():
120 if branch != 'default' and branchnode != ctx.node():
121 branches.append({"name": branch})
121 branches.append({"name": branch})
122 return branches
122 return branches
123
123
124 def nodebranchnodefault(ctx):
124 def nodebranchnodefault(ctx):
125 branches = []
125 branches = []
126 branch = ctx.branch()
126 branch = ctx.branch()
127 if branch != 'default':
127 if branch != 'default':
128 branches.append({"name": branch})
128 branches.append({"name": branch})
129 return branches
129 return branches
130
130
131 def showtag(repo, tmpl, t1, node=nullid, **args):
131 def showtag(repo, tmpl, t1, node=nullid, **args):
132 for t in repo.nodetags(node):
132 for t in repo.nodetags(node):
133 yield tmpl(t1, tag=t, **args)
133 yield tmpl(t1, tag=t, **args)
134
134
135 def showbookmark(repo, tmpl, t1, node=nullid, **args):
135 def showbookmark(repo, tmpl, t1, node=nullid, **args):
136 for t in repo.nodebookmarks(node):
136 for t in repo.nodebookmarks(node):
137 yield tmpl(t1, bookmark=t, **args)
137 yield tmpl(t1, bookmark=t, **args)
138
138
139 def cleanpath(repo, path):
139 def cleanpath(repo, path):
140 path = path.lstrip('/')
140 path = path.lstrip('/')
141 return scmutil.canonpath(repo.root, '', path)
141 return scmutil.canonpath(repo.root, '', path)
142
142
143 def changectx(repo, req):
143 def changectx(repo, req):
144 changeid = "tip"
144 changeid = "tip"
145 if 'node' in req.form:
145 if 'node' in req.form:
146 changeid = req.form['node'][0]
146 changeid = req.form['node'][0]
147 elif 'manifest' in req.form:
147 elif 'manifest' in req.form:
148 changeid = req.form['manifest'][0]
148 changeid = req.form['manifest'][0]
149
149
150 try:
150 try:
151 ctx = repo[changeid]
151 ctx = repo[changeid]
152 except error.RepoError:
152 except error.RepoError:
153 man = repo.manifest
153 man = repo.manifest
154 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
154 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
155
155
156 return ctx
156 return ctx
157
157
158 def filectx(repo, req):
158 def filectx(repo, req):
159 if 'file' not in req.form:
159 if 'file' not in req.form:
160 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
160 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
161 path = cleanpath(repo, req.form['file'][0])
161 path = cleanpath(repo, req.form['file'][0])
162 if 'node' in req.form:
162 if 'node' in req.form:
163 changeid = req.form['node'][0]
163 changeid = req.form['node'][0]
164 elif 'filenode' in req.form:
164 elif 'filenode' in req.form:
165 changeid = req.form['filenode'][0]
165 changeid = req.form['filenode'][0]
166 else:
166 else:
167 raise ErrorResponse(HTTP_NOT_FOUND, 'node or filenode not given')
167 raise ErrorResponse(HTTP_NOT_FOUND, 'node or filenode not given')
168 try:
168 try:
169 fctx = repo[changeid][path]
169 fctx = repo[changeid][path]
170 except error.RepoError:
170 except error.RepoError:
171 fctx = repo.filectx(path, fileid=changeid)
171 fctx = repo.filectx(path, fileid=changeid)
172
172
173 return fctx
173 return fctx
174
174
175 def listfilediffs(tmpl, files, node, max):
175 def listfilediffs(tmpl, files, node, max):
176 for f in files[:max]:
176 for f in files[:max]:
177 yield tmpl('filedifflink', node=hex(node), file=f)
177 yield tmpl('filedifflink', node=hex(node), file=f)
178 if len(files) > max:
178 if len(files) > max:
179 yield tmpl('fileellipses')
179 yield tmpl('fileellipses')
180
180
181 def diffs(repo, tmpl, ctx, files, parity, style):
181 def diffs(repo, tmpl, ctx, files, parity, style):
182
182
183 def countgen():
183 def countgen():
184 start = 1
184 start = 1
185 while True:
185 while True:
186 yield start
186 yield start
187 start += 1
187 start += 1
188
188
189 blockcount = countgen()
189 blockcount = countgen()
190 def prettyprintlines(diff, blockno):
190 def prettyprintlines(diff, blockno):
191 for lineno, l in enumerate(diff.splitlines(True)):
191 for lineno, l in enumerate(diff.splitlines(True)):
192 lineno = "%d.%d" % (blockno, lineno + 1)
192 lineno = "%d.%d" % (blockno, lineno + 1)
193 if l.startswith('+'):
193 if l.startswith('+'):
194 ltype = "difflineplus"
194 ltype = "difflineplus"
195 elif l.startswith('-'):
195 elif l.startswith('-'):
196 ltype = "difflineminus"
196 ltype = "difflineminus"
197 elif l.startswith('@'):
197 elif l.startswith('@'):
198 ltype = "difflineat"
198 ltype = "difflineat"
199 else:
199 else:
200 ltype = "diffline"
200 ltype = "diffline"
201 yield tmpl(ltype,
201 yield tmpl(ltype,
202 line=l,
202 line=l,
203 lineid="l%s" % lineno,
203 lineid="l%s" % lineno,
204 linenumber="% 8s" % lineno)
204 linenumber="% 8s" % lineno)
205
205
206 if files:
206 if files:
207 m = match.exact(repo.root, repo.getcwd(), files)
207 m = match.exact(repo.root, repo.getcwd(), files)
208 else:
208 else:
209 m = match.always(repo.root, repo.getcwd())
209 m = match.always(repo.root, repo.getcwd())
210
210
211 diffopts = patch.diffopts(repo.ui, untrusted=True)
211 diffopts = patch.diffopts(repo.ui, untrusted=True)
212 parents = ctx.parents()
212 parents = ctx.parents()
213 node1 = parents and parents[0].node() or nullid
213 node1 = parents and parents[0].node() or nullid
214 node2 = ctx.node()
214 node2 = ctx.node()
215
215
216 block = []
216 block = []
217 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
217 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
218 if chunk.startswith('diff') and block:
218 if chunk.startswith('diff') and block:
219 blockno = blockcount.next()
219 blockno = blockcount.next()
220 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
220 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
221 lines=prettyprintlines(''.join(block), blockno))
221 lines=prettyprintlines(''.join(block), blockno))
222 block = []
222 block = []
223 if chunk.startswith('diff') and style != 'raw':
223 if chunk.startswith('diff') and style != 'raw':
224 chunk = ''.join(chunk.splitlines(True)[1:])
224 chunk = ''.join(chunk.splitlines(True)[1:])
225 block.append(chunk)
225 block.append(chunk)
226 blockno = blockcount.next()
226 blockno = blockcount.next()
227 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
227 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
228 lines=prettyprintlines(''.join(block), blockno))
228 lines=prettyprintlines(''.join(block), blockno))
229
229
230 def compare(tmpl, ctx, path, context):
230 def compare(tmpl, context, leftlines, rightlines):
231 '''Generator function that provides side-by-side comparison data.'''
231 '''Generator function that provides side-by-side comparison data.'''
232
232
233 def filelines(f):
234 if util.binary(f.data()):
235 mt = mimetypes.guess_type(f.path())[0]
236 if not mt:
237 mt = 'application/octet-stream'
238 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
239 return f.data().splitlines()
240
241 def compline(type, leftlineno, leftline, rightlineno, rightline):
233 def compline(type, leftlineno, leftline, rightlineno, rightline):
242 lineid = leftlineno and ("l%s" % leftlineno) or ''
234 lineid = leftlineno and ("l%s" % leftlineno) or ''
243 lineid += rightlineno and ("r%s" % rightlineno) or ''
235 lineid += rightlineno and ("r%s" % rightlineno) or ''
244 return tmpl('comparisonline',
236 return tmpl('comparisonline',
245 type=type,
237 type=type,
246 lineid=lineid,
238 lineid=lineid,
247 leftlinenumber="% 6s" % (leftlineno or ''),
239 leftlinenumber="% 6s" % (leftlineno or ''),
248 leftline=leftline or '',
240 leftline=leftline or '',
249 rightlinenumber="% 6s" % (rightlineno or ''),
241 rightlinenumber="% 6s" % (rightlineno or ''),
250 rightline=rightline or '')
242 rightline=rightline or '')
251
243
252 def getblock(opcodes):
244 def getblock(opcodes):
253 for type, llo, lhi, rlo, rhi in opcodes:
245 for type, llo, lhi, rlo, rhi in opcodes:
254 len1 = lhi - llo
246 len1 = lhi - llo
255 len2 = rhi - rlo
247 len2 = rhi - rlo
256 count = min(len1, len2)
248 count = min(len1, len2)
257 for i in xrange(count):
249 for i in xrange(count):
258 yield compline(type=type,
250 yield compline(type=type,
259 leftlineno=llo + i + 1,
251 leftlineno=llo + i + 1,
260 leftline=leftlines[llo + i],
252 leftline=leftlines[llo + i],
261 rightlineno=rlo + i + 1,
253 rightlineno=rlo + i + 1,
262 rightline=rightlines[rlo + i])
254 rightline=rightlines[rlo + i])
263 if len1 > len2:
255 if len1 > len2:
264 for i in xrange(llo + count, lhi):
256 for i in xrange(llo + count, lhi):
265 yield compline(type=type,
257 yield compline(type=type,
266 leftlineno=i + 1,
258 leftlineno=i + 1,
267 leftline=leftlines[i],
259 leftline=leftlines[i],
268 rightlineno=None,
260 rightlineno=None,
269 rightline=None)
261 rightline=None)
270 elif len2 > len1:
262 elif len2 > len1:
271 for i in xrange(rlo + count, rhi):
263 for i in xrange(rlo + count, rhi):
272 yield compline(type=type,
264 yield compline(type=type,
273 leftlineno=None,
265 leftlineno=None,
274 leftline=None,
266 leftline=None,
275 rightlineno=i + 1,
267 rightlineno=i + 1,
276 rightline=rightlines[i])
268 rightline=rightlines[i])
277
269
278 if path in ctx:
279 fctx = ctx[path]
280 rightrev = fctx.filerev()
281 rightnode = fctx.filenode()
282 rightlines = filelines(fctx)
283 parents = fctx.parents()
284 if not parents:
285 leftrev = -1
286 leftnode = nullid
287 leftlines = ()
288 else:
289 pfctx = parents[0]
290 leftrev = pfctx.filerev()
291 leftnode = pfctx.filenode()
292 leftlines = filelines(pfctx)
293 else:
294 rightrev = -1
295 rightnode = nullid
296 rightlines = ()
297 fctx = ctx.parents()[0][path]
298 leftrev = fctx.filerev()
299 leftnode = fctx.filenode()
300 leftlines = filelines(fctx)
301
302 s = difflib.SequenceMatcher(None, leftlines, rightlines)
270 s = difflib.SequenceMatcher(None, leftlines, rightlines)
303 if context < 0:
271 if context < 0:
304 blocks = [tmpl('comparisonblock', lines=getblock(s.get_opcodes()))]
272 yield tmpl('comparisonblock', lines=getblock(s.get_opcodes()))
305 else:
273 else:
306 blocks = (tmpl('comparisonblock', lines=getblock(oc))
274 for oc in s.get_grouped_opcodes(n=context):
307 for oc in s.get_grouped_opcodes(n=context))
275 yield tmpl('comparisonblock', lines=getblock(oc))
308
309 yield tmpl('comparison',
310 leftrev=leftrev,
311 leftnode=hex(leftnode),
312 rightrev=rightrev,
313 rightnode=hex(rightnode),
314 blocks=blocks)
315
276
316 def diffstatgen(ctx):
277 def diffstatgen(ctx):
317 '''Generator function that provides the diffstat data.'''
278 '''Generator function that provides the diffstat data.'''
318
279
319 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
280 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
320 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
281 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
321 while True:
282 while True:
322 yield stats, maxname, maxtotal, addtotal, removetotal, binary
283 yield stats, maxname, maxtotal, addtotal, removetotal, binary
323
284
324 def diffsummary(statgen):
285 def diffsummary(statgen):
325 '''Return a short summary of the diff.'''
286 '''Return a short summary of the diff.'''
326
287
327 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
288 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
328 return _(' %d files changed, %d insertions(+), %d deletions(-)\n') % (
289 return _(' %d files changed, %d insertions(+), %d deletions(-)\n') % (
329 len(stats), addtotal, removetotal)
290 len(stats), addtotal, removetotal)
330
291
331 def diffstat(tmpl, ctx, statgen, parity):
292 def diffstat(tmpl, ctx, statgen, parity):
332 '''Return a diffstat template for each file in the diff.'''
293 '''Return a diffstat template for each file in the diff.'''
333
294
334 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
295 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
335 files = ctx.files()
296 files = ctx.files()
336
297
337 def pct(i):
298 def pct(i):
338 if maxtotal == 0:
299 if maxtotal == 0:
339 return 0
300 return 0
340 return (float(i) / maxtotal) * 100
301 return (float(i) / maxtotal) * 100
341
302
342 fileno = 0
303 fileno = 0
343 for filename, adds, removes, isbinary in stats:
304 for filename, adds, removes, isbinary in stats:
344 template = filename in files and 'diffstatlink' or 'diffstatnolink'
305 template = filename in files and 'diffstatlink' or 'diffstatnolink'
345 total = adds + removes
306 total = adds + removes
346 fileno += 1
307 fileno += 1
347 yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
308 yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
348 total=total, addpct=pct(adds), removepct=pct(removes),
309 total=total, addpct=pct(adds), removepct=pct(removes),
349 parity=parity.next())
310 parity=parity.next())
350
311
351 class sessionvars(object):
312 class sessionvars(object):
352 def __init__(self, vars, start='?'):
313 def __init__(self, vars, start='?'):
353 self.start = start
314 self.start = start
354 self.vars = vars
315 self.vars = vars
355 def __getitem__(self, key):
316 def __getitem__(self, key):
356 return self.vars[key]
317 return self.vars[key]
357 def __setitem__(self, key, value):
318 def __setitem__(self, key, value):
358 self.vars[key] = value
319 self.vars[key] = value
359 def __copy__(self):
320 def __copy__(self):
360 return sessionvars(copy.copy(self.vars), self.start)
321 return sessionvars(copy.copy(self.vars), self.start)
361 def __iter__(self):
322 def __iter__(self):
362 separator = self.start
323 separator = self.start
363 for key, value in self.vars.iteritems():
324 for key, value in self.vars.iteritems():
364 yield {'name': key, 'value': str(value), 'separator': separator}
325 yield {'name': key, 'value': str(value), 'separator': separator}
365 separator = '&'
326 separator = '&'
366
327
367 class wsgiui(ui.ui):
328 class wsgiui(ui.ui):
368 # default termwidth breaks under mod_wsgi
329 # default termwidth breaks under mod_wsgi
369 def termwidth(self):
330 def termwidth(self):
370 return 80
331 return 80
@@ -1,235 +1,225 b''
1 default = 'shortlog'
1 default = 'shortlog'
2
2
3 mimetype = 'text/html; charset={encoding}'
3 mimetype = 'text/html; charset={encoding}'
4 header = header.tmpl
4 header = header.tmpl
5 footer = ../paper/footer.tmpl
5 footer = ../paper/footer.tmpl
6 search = ../paper/search.tmpl
6 search = ../paper/search.tmpl
7
7
8 changelog = ../paper/shortlog.tmpl
8 changelog = ../paper/shortlog.tmpl
9 shortlog = ../paper/shortlog.tmpl
9 shortlog = ../paper/shortlog.tmpl
10 shortlogentry = ../paper/shortlogentry.tmpl
10 shortlogentry = ../paper/shortlogentry.tmpl
11 graph = ../paper/graph.tmpl
11 graph = ../paper/graph.tmpl
12
12
13 help = ../paper/help.tmpl
13 help = ../paper/help.tmpl
14 helptopics = ../paper/helptopics.tmpl
14 helptopics = ../paper/helptopics.tmpl
15
15
16 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
16 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
17
17
18 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
20 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
20 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
21 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
21 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
22 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
22 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
23 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
23 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
24 filenolink = '{file|escape} '
24 filenolink = '{file|escape} '
25 fileellipses = '...'
25 fileellipses = '...'
26 diffstatlink = ../paper/diffstat.tmpl
26 diffstatlink = ../paper/diffstat.tmpl
27 diffstatnolink = ../paper/diffstat.tmpl
27 diffstatnolink = ../paper/diffstat.tmpl
28 changelogentry = ../paper/shortlogentry.tmpl
28 changelogentry = ../paper/shortlogentry.tmpl
29 searchentry = ../paper/shortlogentry.tmpl
29 searchentry = ../paper/shortlogentry.tmpl
30 changeset = ../paper/changeset.tmpl
30 changeset = ../paper/changeset.tmpl
31 manifest = ../paper/manifest.tmpl
31 manifest = ../paper/manifest.tmpl
32
32
33 nav = '{before%naventry} {after%naventry}'
33 nav = '{before%naventry} {after%naventry}'
34 navshort = '{before%navshortentry}{after%navshortentry}'
34 navshort = '{before%navshortentry}{after%navshortentry}'
35 navgraph = '{before%navgraphentry}{after%navgraphentry}'
35 navgraph = '{before%navgraphentry}{after%navgraphentry}'
36 filenav = '{before%filenaventry}{after%filenaventry}'
36 filenav = '{before%filenaventry}{after%filenaventry}'
37
37
38 direntry = '
38 direntry = '
39 <tr class="fileline parity{parity}">
39 <tr class="fileline parity{parity}">
40 <td class="name">
40 <td class="name">
41 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
41 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
42 <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
42 <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
43 </a>
43 </a>
44 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
44 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
45 {emptydirs|escape}
45 {emptydirs|escape}
46 </a>
46 </a>
47 </td>
47 </td>
48 <td class="size"></td>
48 <td class="size"></td>
49 <td class="permissions">drwxr-xr-x</td>
49 <td class="permissions">drwxr-xr-x</td>
50 </tr>'
50 </tr>'
51
51
52 fileentry = '
52 fileentry = '
53 <tr class="fileline parity{parity}">
53 <tr class="fileline parity{parity}">
54 <td class="filename">
54 <td class="filename">
55 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
55 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
56 <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
56 <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
57 </a>
57 </a>
58 </td>
58 </td>
59 <td class="size">{size}</td>
59 <td class="size">{size}</td>
60 <td class="permissions">{permissions|permissions}</td>
60 <td class="permissions">{permissions|permissions}</td>
61 </tr>'
61 </tr>'
62
62
63 filerevision = ../paper/filerevision.tmpl
63 filerevision = ../paper/filerevision.tmpl
64 fileannotate = ../paper/fileannotate.tmpl
64 fileannotate = ../paper/fileannotate.tmpl
65 filediff = ../paper/filediff.tmpl
65 filediff = ../paper/filediff.tmpl
66 filecomparison = ../paper/filecomparison.tmpl
66 filecomparison = ../paper/filecomparison.tmpl
67 filelog = ../paper/filelog.tmpl
67 filelog = ../paper/filelog.tmpl
68 fileline = '
68 fileline = '
69 <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
69 <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
70 filelogentry = ../paper/filelogentry.tmpl
70 filelogentry = ../paper/filelogentry.tmpl
71
71
72 annotateline = '
72 annotateline = '
73 <tr class="parity{parity}">
73 <tr class="parity{parity}">
74 <td class="annotate">
74 <td class="annotate">
75 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}"
75 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}"
76 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
76 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
77 </td>
77 </td>
78 <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
78 <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
79 </tr>'
79 </tr>'
80
80
81 diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
81 diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
82 difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
82 difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
83 difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
83 difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
84 difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
84 difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
85 diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
85 diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
86
86
87 comparison = '
88 <table class="bigtable">
89 <thead class="header">
90 <tr>
91 <th>{leftrev}:{leftnode|short}</th>
92 <th>{rightrev}:{rightnode|short}</th>
93 </tr>
94 </thead>
95 {blocks}
96 </table>'
97 comparisonblock ='
87 comparisonblock ='
98 <tbody class="block">
88 <tbody class="block">
99 {lines}
89 {lines}
100 </tbody>'
90 </tbody>'
101 comparisonline = '
91 comparisonline = '
102 <tr>
92 <tr>
103 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
93 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
104 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
94 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
105 </tr>'
95 </tr>'
106
96
107 changelogparent = '
97 changelogparent = '
108 <tr>
98 <tr>
109 <th class="parent">parent {rev}:</th>
99 <th class="parent">parent {rev}:</th>
110 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
100 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
111 </tr>'
101 </tr>'
112
102
113 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
103 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
114
104
115 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
105 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
116 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
106 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
117
107
118 filerename = '{file|escape}@'
108 filerename = '{file|escape}@'
119 filelogrename = '
109 filelogrename = '
120 <span class="base">
110 <span class="base">
121 base
111 base
122 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
112 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
123 {file|escape}@{node|short}
113 {file|escape}@{node|short}
124 </a>
114 </a>
125 </span>'
115 </span>'
126 fileannotateparent = '
116 fileannotateparent = '
127 <tr>
117 <tr>
128 <td class="metatag">parent:</td>
118 <td class="metatag">parent:</td>
129 <td>
119 <td>
130 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
120 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
131 {rename%filerename}{node|short}
121 {rename%filerename}{node|short}
132 </a>
122 </a>
133 </td>
123 </td>
134 </tr>'
124 </tr>'
135 changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
125 changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
136 changelogchild = '
126 changelogchild = '
137 <tr>
127 <tr>
138 <th class="child">child</th>
128 <th class="child">child</th>
139 <td class="child">
129 <td class="child">
140 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
130 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
141 {node|short}
131 {node|short}
142 </a>
132 </a>
143 </td>
133 </td>
144 </tr>'
134 </tr>'
145 fileannotatechild = '
135 fileannotatechild = '
146 <tr>
136 <tr>
147 <td class="metatag">child:</td>
137 <td class="metatag">child:</td>
148 <td>
138 <td>
149 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
139 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
150 {node|short}
140 {node|short}
151 </a>
141 </a>
152 </td>
142 </td>
153 </tr>'
143 </tr>'
154 tags = ../paper/tags.tmpl
144 tags = ../paper/tags.tmpl
155 tagentry = '
145 tagentry = '
156 <tr class="tagEntry parity{parity}">
146 <tr class="tagEntry parity{parity}">
157 <td>
147 <td>
158 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
148 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
159 {tag|escape}
149 {tag|escape}
160 </a>
150 </a>
161 </td>
151 </td>
162 <td class="node">
152 <td class="node">
163 {node|short}
153 {node|short}
164 </td>
154 </td>
165 </tr>'
155 </tr>'
166 bookmarks = ../paper/bookmarks.tmpl
156 bookmarks = ../paper/bookmarks.tmpl
167 bookmarkentry = '
157 bookmarkentry = '
168 <tr class="tagEntry parity{parity}">
158 <tr class="tagEntry parity{parity}">
169 <td>
159 <td>
170 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
160 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
171 {bookmark|escape}
161 {bookmark|escape}
172 </a>
162 </a>
173 </td>
163 </td>
174 <td class="node">
164 <td class="node">
175 {node|short}
165 {node|short}
176 </td>
166 </td>
177 </tr>'
167 </tr>'
178 branches = ../paper/branches.tmpl
168 branches = ../paper/branches.tmpl
179 branchentry = '
169 branchentry = '
180 <tr class="tagEntry parity{parity}">
170 <tr class="tagEntry parity{parity}">
181 <td>
171 <td>
182 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
172 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
183 {branch|escape}
173 {branch|escape}
184 </a>
174 </a>
185 </td>
175 </td>
186 <td class="node">
176 <td class="node">
187 {node|short}
177 {node|short}
188 </td>
178 </td>
189 </tr>'
179 </tr>'
190 changelogtag = '<span class="tag">{name|escape}</span> '
180 changelogtag = '<span class="tag">{name|escape}</span> '
191 changesettag = '<span class="tag">{tag|escape}</span> '
181 changesettag = '<span class="tag">{tag|escape}</span> '
192 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
182 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
193 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
183 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
194 changelogbranchname = '<span class="branchname">{name|escape}</span> '
184 changelogbranchname = '<span class="branchname">{name|escape}</span> '
195
185
196 filediffparent = '
186 filediffparent = '
197 <tr>
187 <tr>
198 <th class="parent">parent {rev}:</th>
188 <th class="parent">parent {rev}:</th>
199 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
189 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
200 </tr>'
190 </tr>'
201 filelogparent = '
191 filelogparent = '
202 <tr>
192 <tr>
203 <th>parent {rev}:</th>
193 <th>parent {rev}:</th>
204 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
194 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
205 </tr>'
195 </tr>'
206 filediffchild = '
196 filediffchild = '
207 <tr>
197 <tr>
208 <th class="child">child {rev}:</th>
198 <th class="child">child {rev}:</th>
209 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
199 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
210 </td>
200 </td>
211 </tr>'
201 </tr>'
212 filelogchild = '
202 filelogchild = '
213 <tr>
203 <tr>
214 <th>child {rev}:</th>
204 <th>child {rev}:</th>
215 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
205 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
216 </tr>'
206 </tr>'
217
207
218 indexentry = '
208 indexentry = '
219 <tr class="parity{parity}">
209 <tr class="parity{parity}">
220 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
210 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
221 <td>{description}</td>
211 <td>{description}</td>
222 <td>{contact|obfuscate}</td>
212 <td>{contact|obfuscate}</td>
223 <td class="age">{lastchange|rfc822date}</td>
213 <td class="age">{lastchange|rfc822date}</td>
224 <td class="indexlinks">{archives%indexarchiveentry}</td>
214 <td class="indexlinks">{archives%indexarchiveentry}</td>
225 </tr>\n'
215 </tr>\n'
226 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
216 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
227 index = ../paper/index.tmpl
217 index = ../paper/index.tmpl
228 archiveentry = '
218 archiveentry = '
229 <li>
219 <li>
230 <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
220 <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
231 </li>'
221 </li>'
232 notfound = ../paper/notfound.tmpl
222 notfound = ../paper/notfound.tmpl
233 error = ../paper/error.tmpl
223 error = ../paper/error.tmpl
234 urlparameter = '{separator}{name}={value|urlescape}'
224 urlparameter = '{separator}{name}={value|urlescape}'
235 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
225 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
@@ -1,63 +1,71 b''
1 {header}
1 {header}
2 <title>{repo|escape}: comparison {file|escape}</title>
2 <title>{repo|escape}: comparison {file|escape}</title>
3 <link rel="alternate" type="application/atom+xml"
3 <link rel="alternate" type="application/atom+xml"
4 href="{url}atom-log" title="Atom feed for {repo|escape}"/>
4 href="{url}atom-log" title="Atom feed for {repo|escape}"/>
5 <link rel="alternate" type="application/rss+xml"
5 <link rel="alternate" type="application/rss+xml"
6 href="{url}rss-log" title="RSS feed for {repo|escape}"/>
6 href="{url}rss-log" title="RSS feed for {repo|escape}"/>
7 </head>
7 </head>
8 <body>
8 <body>
9
9
10 <div class="page_header">
10 <div class="page_header">
11 <a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / comparison
11 <a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / comparison
12 </div>
12 </div>
13
13
14 <div class="page_nav">
14 <div class="page_nav">
15 <a href="{url}summary{sessionvars%urlparameter}">summary</a> |
15 <a href="{url}summary{sessionvars%urlparameter}">summary</a> |
16 <a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
16 <a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
17 <a href="{url}log{sessionvars%urlparameter}">changelog</a> |
17 <a href="{url}log{sessionvars%urlparameter}">changelog</a> |
18 <a href="{url}graph{sessionvars%urlparameter}">graph</a> |
18 <a href="{url}graph{sessionvars%urlparameter}">graph</a> |
19 <a href="{url}tags{sessionvars%urlparameter}">tags</a> |
19 <a href="{url}tags{sessionvars%urlparameter}">tags</a> |
20 <a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a> |
20 <a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a> |
21 <a href="{url}branches{sessionvars%urlparameter}">branches</a> |
21 <a href="{url}branches{sessionvars%urlparameter}">branches</a> |
22 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a> |
22 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a> |
23 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
23 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
24 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
24 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
25 <a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a> |
25 <a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a> |
26 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
26 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
29 comparison |
29 comparison |
30 <a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a> |
30 <a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a> |
31 <a href="{url}help{sessionvars%urlparameter}">help</a>
31 <a href="{url}help{sessionvars%urlparameter}">help</a>
32 <br/>
32 <br/>
33 </div>
33 </div>
34
34
35 <div class="title">{file|escape}</div>
35 <div class="title">{file|escape}</div>
36
36
37 <table>
37 <table>
38 {branch%filerevbranch}
38 {branch%filerevbranch}
39 <tr>
39 <tr>
40 <td>changeset {rev}</td>
40 <td>changeset {rev}</td>
41 <td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
41 <td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>
42 {parent%filecompparent}
42 {parent%filecompparent}
43 {child%filecompchild}
43 {child%filecompchild}
44 </table>
44 </table>
45
45
46 <div class="list_head"></div>
46 <div class="list_head"></div>
47
47
48 <div class="page_body">
48 <div class="page_body">
49
49
50 <div class="legend">
50 <div class="legend">
51 <span class="legendinfo equal">equal</span>
51 <span class="legendinfo equal">equal</span>
52 <span class="legendinfo delete">deleted</span>
52 <span class="legendinfo delete">deleted</span>
53 <span class="legendinfo insert">inserted</span>
53 <span class="legendinfo insert">inserted</span>
54 <span class="legendinfo replace">replaced</span>
54 <span class="legendinfo replace">replaced</span>
55 </div>
55 </div>
56
56
57 <div class="comparison">
57 <div class="comparison">
58 {comparison}
58 <table style="border-collapse:collapse;">
59 <thead class="header">
60 <tr>
61 <th>{leftrev}:{leftnode|short}</th>
62 <th>{rightrev}:{rightnode|short}</th>
63 </tr>
64 </thead>
65 {comparison}
66 </table>
59 </div>
67 </div>
60
68
61 </div>
69 </div>
62
70
63 {footer}
71 {footer}
@@ -1,312 +1,302 b''
1 default = 'summary'
1 default = 'summary'
2 mimetype = 'text/html; charset={encoding}'
2 mimetype = 'text/html; charset={encoding}'
3 header = header.tmpl
3 header = header.tmpl
4 footer = footer.tmpl
4 footer = footer.tmpl
5 search = search.tmpl
5 search = search.tmpl
6 changelog = changelog.tmpl
6 changelog = changelog.tmpl
7 summary = summary.tmpl
7 summary = summary.tmpl
8 error = error.tmpl
8 error = error.tmpl
9 notfound = notfound.tmpl
9 notfound = notfound.tmpl
10
10
11 help = help.tmpl
11 help = help.tmpl
12 helptopics = helptopics.tmpl
12 helptopics = helptopics.tmpl
13
13
14 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
14 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
15
15
16 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
16 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
19 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
20 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
20 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
21 filenodelink = '
21 filenodelink = '
22 <tr class="parity{parity}">
22 <tr class="parity{parity}">
23 <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
23 <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
24 <td></td>
24 <td></td>
25 <td class="link">
25 <td class="link">
26 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
26 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
29 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
29 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
30 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
30 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
31 </td>
31 </td>
32 </tr>'
32 </tr>'
33 filenolink = '
33 filenolink = '
34 <tr class="parity{parity}">
34 <tr class="parity{parity}">
35 <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
35 <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
36 <td></td>
36 <td></td>
37 <td class="link">
37 <td class="link">
38 file |
38 file |
39 annotate |
39 annotate |
40 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
40 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
41 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
41 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
42 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
42 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
43 </td>
43 </td>
44 </tr>'
44 </tr>'
45
45
46 nav = '{before%naventry} {after%naventry}'
46 nav = '{before%naventry} {after%naventry}'
47 navshort = '{before%navshortentry}{after%navshortentry}'
47 navshort = '{before%navshortentry}{after%navshortentry}'
48 navgraph = '{before%navgraphentry}{after%navgraphentry}'
48 navgraph = '{before%navgraphentry}{after%navgraphentry}'
49 filenav = '{before%filenaventry}{after%filenaventry}'
49 filenav = '{before%filenaventry}{after%filenaventry}'
50
50
51 fileellipses = '...'
51 fileellipses = '...'
52 changelogentry = changelogentry.tmpl
52 changelogentry = changelogentry.tmpl
53 searchentry = changelogentry.tmpl
53 searchentry = changelogentry.tmpl
54 changeset = changeset.tmpl
54 changeset = changeset.tmpl
55 manifest = manifest.tmpl
55 manifest = manifest.tmpl
56 direntry = '
56 direntry = '
57 <tr class="parity{parity}">
57 <tr class="parity{parity}">
58 <td style="font-family:monospace">drwxr-xr-x</td>
58 <td style="font-family:monospace">drwxr-xr-x</td>
59 <td style="font-family:monospace"></td>
59 <td style="font-family:monospace"></td>
60 <td style="font-family:monospace"></td>
60 <td style="font-family:monospace"></td>
61 <td>
61 <td>
62 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
62 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
63 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a>
63 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a>
64 </td>
64 </td>
65 <td class="link">
65 <td class="link">
66 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a>
66 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a>
67 </td>
67 </td>
68 </tr>'
68 </tr>'
69 fileentry = '
69 fileentry = '
70 <tr class="parity{parity}">
70 <tr class="parity{parity}">
71 <td style="font-family:monospace">{permissions|permissions}</td>
71 <td style="font-family:monospace">{permissions|permissions}</td>
72 <td style="font-family:monospace" align=right>{date|isodate}</td>
72 <td style="font-family:monospace" align=right>{date|isodate}</td>
73 <td style="font-family:monospace" align=right>{size}</td>
73 <td style="font-family:monospace" align=right>{size}</td>
74 <td class="list">
74 <td class="list">
75 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
75 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
76 </td>
76 </td>
77 <td class="link">
77 <td class="link">
78 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
78 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
79 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
79 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
80 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
80 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
81 </td>
81 </td>
82 </tr>'
82 </tr>'
83 filerevision = filerevision.tmpl
83 filerevision = filerevision.tmpl
84 fileannotate = fileannotate.tmpl
84 fileannotate = fileannotate.tmpl
85 filediff = filediff.tmpl
85 filediff = filediff.tmpl
86 filecomparison = filecomparison.tmpl
86 filecomparison = filecomparison.tmpl
87 filelog = filelog.tmpl
87 filelog = filelog.tmpl
88 fileline = '
88 fileline = '
89 <div style="font-family:monospace" class="parity{parity}">
89 <div style="font-family:monospace" class="parity{parity}">
90 <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
90 <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
91 </div>'
91 </div>'
92 annotateline = '
92 annotateline = '
93 <tr style="font-family:monospace" class="parity{parity}">
93 <tr style="font-family:monospace" class="parity{parity}">
94 <td class="linenr" style="text-align: right;">
94 <td class="linenr" style="text-align: right;">
95 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
95 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
96 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
96 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
97 </td>
97 </td>
98 <td><pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a></pre></td>
98 <td><pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a></pre></td>
99 <td><pre>{line|escape}</pre></td>
99 <td><pre>{line|escape}</pre></td>
100 </tr>'
100 </tr>'
101 difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
101 difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
102 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
102 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
103 difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
103 difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
104 diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
104 diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
105
105
106 comparison = '
107 <table style="border-collapse:collapse;">
108 <thead class="header">
109 <tr>
110 <th>{leftrev}:{leftnode|short}</th>
111 <th>{rightrev}:{rightnode|short}</th>
112 </tr>
113 </thead>
114 {blocks}
115 </table>'
116 comparisonblock ='
106 comparisonblock ='
117 <tbody class="block">
107 <tbody class="block">
118 {lines}
108 {lines}
119 </tbody>'
109 </tbody>'
120 comparisonline = '
110 comparisonline = '
121 <tr style="font-family:monospace">
111 <tr style="font-family:monospace">
122 <td class="{type}"><pre><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</pre></td>
112 <td class="{type}"><pre><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</pre></td>
123 <td class="{type}"><pre><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</pre></td>
113 <td class="{type}"><pre><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</pre></td>
124 </tr>'
114 </tr>'
125
115
126 changelogparent = '
116 changelogparent = '
127 <tr>
117 <tr>
128 <th class="parent">parent {rev}:</th>
118 <th class="parent">parent {rev}:</th>
129 <td class="parent">
119 <td class="parent">
130 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
120 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
131 </td>
121 </td>
132 </tr>'
122 </tr>'
133 changesetbranch = '<tr><td>branch</td><td>{name}</td></tr>'
123 changesetbranch = '<tr><td>branch</td><td>{name}</td></tr>'
134 changesetparent = '
124 changesetparent = '
135 <tr>
125 <tr>
136 <td>parent {rev}</td>
126 <td>parent {rev}</td>
137 <td style="font-family:monospace">
127 <td style="font-family:monospace">
138 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
128 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
139 </td>
129 </td>
140 </tr>'
130 </tr>'
141 filerevbranch = '<tr><td>branch</td><td>{name}</td></tr>'
131 filerevbranch = '<tr><td>branch</td><td>{name}</td></tr>'
142 filerevparent = '
132 filerevparent = '
143 <tr>
133 <tr>
144 <td>parent {rev}</td>
134 <td>parent {rev}</td>
145 <td style="font-family:monospace">
135 <td style="font-family:monospace">
146 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
136 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
147 {rename%filerename}{node|short}
137 {rename%filerename}{node|short}
148 </a>
138 </a>
149 </td>
139 </td>
150 </tr>'
140 </tr>'
151 filerename = '{file|escape}@'
141 filerename = '{file|escape}@'
152 filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
142 filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
153 fileannotateparent = '
143 fileannotateparent = '
154 <tr>
144 <tr>
155 <td>parent {rev}</td>
145 <td>parent {rev}</td>
156 <td style="font-family:monospace">
146 <td style="font-family:monospace">
157 <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
147 <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
158 {rename%filerename}{node|short}
148 {rename%filerename}{node|short}
159 </a>
149 </a>
160 </td>
150 </td>
161 </tr>'
151 </tr>'
162 changelogchild = '
152 changelogchild = '
163 <tr>
153 <tr>
164 <th class="child">child {rev}:</th>
154 <th class="child">child {rev}:</th>
165 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
155 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
166 </tr>'
156 </tr>'
167 changesetchild = '
157 changesetchild = '
168 <tr>
158 <tr>
169 <td>child {rev}</td>
159 <td>child {rev}</td>
170 <td style="font-family:monospace">
160 <td style="font-family:monospace">
171 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
161 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
172 </td>
162 </td>
173 </tr>'
163 </tr>'
174 filerevchild = '
164 filerevchild = '
175 <tr>
165 <tr>
176 <td>child {rev}</td>
166 <td>child {rev}</td>
177 <td style="font-family:monospace">
167 <td style="font-family:monospace">
178 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
168 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
179 </tr>'
169 </tr>'
180 fileannotatechild = '
170 fileannotatechild = '
181 <tr>
171 <tr>
182 <td>child {rev}</td>
172 <td>child {rev}</td>
183 <td style="font-family:monospace">
173 <td style="font-family:monospace">
184 <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
174 <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
185 </tr>'
175 </tr>'
186 tags = tags.tmpl
176 tags = tags.tmpl
187 tagentry = '
177 tagentry = '
188 <tr class="parity{parity}">
178 <tr class="parity{parity}">
189 <td class="age"><i class="age">{date|rfc822date}</i></td>
179 <td class="age"><i class="age">{date|rfc822date}</i></td>
190 <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
180 <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
191 <td class="link">
181 <td class="link">
192 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
182 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
193 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
183 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
194 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
184 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
195 </td>
185 </td>
196 </tr>'
186 </tr>'
197 bookmarks = bookmarks.tmpl
187 bookmarks = bookmarks.tmpl
198 bookmarkentry = '
188 bookmarkentry = '
199 <tr class="parity{parity}">
189 <tr class="parity{parity}">
200 <td class="age"><i class="age">{date|rfc822date}</i></td>
190 <td class="age"><i class="age">{date|rfc822date}</i></td>
201 <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td>
191 <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td>
202 <td class="link">
192 <td class="link">
203 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
193 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
204 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
194 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
205 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
195 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
206 </td>
196 </td>
207 </tr>'
197 </tr>'
208 branches = branches.tmpl
198 branches = branches.tmpl
209 branchentry = '
199 branchentry = '
210 <tr class="parity{parity}">
200 <tr class="parity{parity}">
211 <td class="age"><i class="age">{date|rfc822date}</i></td>
201 <td class="age"><i class="age">{date|rfc822date}</i></td>
212 <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td>
202 <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td>
213 <td class="{status}">{branch|escape}</td>
203 <td class="{status}">{branch|escape}</td>
214 <td class="link">
204 <td class="link">
215 <a href="{url}changeset/{node|short}{sessionvars%urlparameter}">changeset</a> |
205 <a href="{url}changeset/{node|short}{sessionvars%urlparameter}">changeset</a> |
216 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
206 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
217 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
207 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
218 </td>
208 </td>
219 </tr>'
209 </tr>'
220 diffblock = '<pre>{lines}</pre>'
210 diffblock = '<pre>{lines}</pre>'
221 filediffparent = '
211 filediffparent = '
222 <tr>
212 <tr>
223 <td>parent {rev}</td>
213 <td>parent {rev}</td>
224 <td style="font-family:monospace">
214 <td style="font-family:monospace">
225 <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
215 <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
226 {node|short}
216 {node|short}
227 </a>
217 </a>
228 </td>
218 </td>
229 </tr>'
219 </tr>'
230 filecompparent = '
220 filecompparent = '
231 <tr>
221 <tr>
232 <td>parent {rev}</td>
222 <td>parent {rev}</td>
233 <td style="font-family:monospace">
223 <td style="font-family:monospace">
234 <a class="list" href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
224 <a class="list" href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
235 {node|short}
225 {node|short}
236 </a>
226 </a>
237 </td>
227 </td>
238 </tr>'
228 </tr>'
239 filelogparent = '
229 filelogparent = '
240 <tr>
230 <tr>
241 <td align="right">parent {rev}:&nbsp;</td>
231 <td align="right">parent {rev}:&nbsp;</td>
242 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
232 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
243 </tr>'
233 </tr>'
244 filediffchild = '
234 filediffchild = '
245 <tr>
235 <tr>
246 <td>child {rev}</td>
236 <td>child {rev}</td>
247 <td style="font-family:monospace">
237 <td style="font-family:monospace">
248 <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
238 <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
249 </td>
239 </td>
250 </tr>'
240 </tr>'
251 filecompchild = '
241 filecompchild = '
252 <tr>
242 <tr>
253 <td>child {rev}</td>
243 <td>child {rev}</td>
254 <td style="font-family:monospace">
244 <td style="font-family:monospace">
255 <a class="list" href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
245 <a class="list" href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
256 </td>
246 </td>
257 </tr>'
247 </tr>'
258 filelogchild = '
248 filelogchild = '
259 <tr>
249 <tr>
260 <td align="right">child {rev}:&nbsp;</td>
250 <td align="right">child {rev}:&nbsp;</td>
261 <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
251 <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
262 </tr>'
252 </tr>'
263 shortlog = shortlog.tmpl
253 shortlog = shortlog.tmpl
264 graph = graph.tmpl
254 graph = graph.tmpl
265 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
255 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
266 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
256 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
267 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
257 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
268 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
258 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
269 shortlogentry = '
259 shortlogentry = '
270 <tr class="parity{parity}">
260 <tr class="parity{parity}">
271 <td class="age"><i class="age">{date|rfc822date}</i></td>
261 <td class="age"><i class="age">{date|rfc822date}</i></td>
272 <td><i>{author|person}</i></td>
262 <td><i>{author|person}</i></td>
273 <td>
263 <td>
274 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
264 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
275 <b>{desc|strip|firstline|escape|nonempty}</b>
265 <b>{desc|strip|firstline|escape|nonempty}</b>
276 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
266 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
277 </a>
267 </a>
278 </td>
268 </td>
279 <td class="link" nowrap>
269 <td class="link" nowrap>
280 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
270 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
281 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
271 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
282 </td>
272 </td>
283 </tr>'
273 </tr>'
284 filelogentry = '
274 filelogentry = '
285 <tr class="parity{parity}">
275 <tr class="parity{parity}">
286 <td class="age"><i class="age">{date|rfc822date}</i></td>
276 <td class="age"><i class="age">{date|rfc822date}</i></td>
287 <td>
277 <td>
288 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
278 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
289 <b>{desc|strip|firstline|escape|nonempty}</b>
279 <b>{desc|strip|firstline|escape|nonempty}</b>
290 </a>
280 </a>
291 </td>
281 </td>
292 <td class="link">
282 <td class="link">
293 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> {rename%filelogrename}</td>
283 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> {rename%filelogrename}</td>
294 </tr>'
284 </tr>'
295 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
285 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
296 indexentry = '
286 indexentry = '
297 <tr class="parity{parity}">
287 <tr class="parity{parity}">
298 <td>
288 <td>
299 <a class="list" href="{url}{sessionvars%urlparameter}">
289 <a class="list" href="{url}{sessionvars%urlparameter}">
300 <b>{name|escape}</b>
290 <b>{name|escape}</b>
301 </a>
291 </a>
302 </td>
292 </td>
303 <td>{description}</td>
293 <td>{description}</td>
304 <td>{contact|obfuscate}</td>
294 <td>{contact|obfuscate}</td>
305 <td class="age">{lastchange|rfc822date}</td>
295 <td class="age">{lastchange|rfc822date}</td>
306 <td class="indexlinks">{archives%indexarchiveentry}</td>
296 <td class="indexlinks">{archives%indexarchiveentry}</td>
307 <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td>
297 <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td>
308 </tr>\n'
298 </tr>\n'
309 indexarchiveentry = ' <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
299 indexarchiveentry = ' <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
310 index = index.tmpl
300 index = index.tmpl
311 urlparameter = '{separator}{name}={value|urlescape}'
301 urlparameter = '{separator}{name}={value|urlescape}'
312 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
302 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
@@ -1,64 +1,72 b''
1 {header}
1 {header}
2 <title>{repo|escape}: comparison {file|escape}</title>
2 <title>{repo|escape}: comparison {file|escape}</title>
3 <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
3 <link rel="alternate" type="application/atom+xml" href="{url}atom-log" title="Atom feed for {repo|escape}"/>
4 <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
4 <link rel="alternate" type="application/rss+xml" href="{url}rss-log" title="RSS feed for {repo|escape}"/>
5 </head>
5 </head>
6
6
7 <body>
7 <body>
8 <div id="container">
8 <div id="container">
9 <div class="page-header">
9 <div class="page-header">
10 <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file comparison</h1>
10 <h1><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file comparison</h1>
11
11
12 <form action="{url}log">
12 <form action="{url}log">
13 {sessionvars%hiddenformentry}
13 {sessionvars%hiddenformentry}
14 <dl class="search">
14 <dl class="search">
15 <dt><label>Search: </label></dt>
15 <dt><label>Search: </label></dt>
16 <dd><input type="text" name="rev" /></dd>
16 <dd><input type="text" name="rev" /></dd>
17 </dl>
17 </dl>
18 </form>
18 </form>
19
19
20 <ul class="page-nav">
20 <ul class="page-nav">
21 <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
21 <li><a href="{url}summary{sessionvars%urlparameter}">summary</a></li>
22 <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
22 <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
23 <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
23 <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
24 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
24 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
25 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
25 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
26 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
26 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
27 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
27 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
28 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
28 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
29 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
29 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
30 </ul>
30 </ul>
31 </div>
31 </div>
32
32
33 <ul class="submenu">
33 <ul class="submenu">
34 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
34 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
35 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a></li>
35 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a></li>
36 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
36 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
37 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
37 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
38 <li class="current">comparison</li>
38 <li class="current">comparison</li>
39 <li><a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a></li>
39 <li><a href="{url}raw-diff/{node|short}/{file|urlescape}">raw</a></li>
40 </ul>
40 </ul>
41
41
42 <h2 class="no-link no-border">comparison: {file|escape}</h2>
42 <h2 class="no-link no-border">comparison: {file|escape}</h2>
43 <h3 class="changeset">{file|escape}</h3>
43 <h3 class="changeset">{file|escape}</h3>
44
44
45 <dl class="overview">
45 <dl class="overview">
46 {branch%filerevbranch}
46 {branch%filerevbranch}
47 <dt>changeset {rev}</dt>
47 <dt>changeset {rev}</dt>
48 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
48 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
49 {parent%filecompparent}
49 {parent%filecompparent}
50 {child%filecompchild}
50 {child%filecompchild}
51 </dl>
51 </dl>
52
52
53 <div class="legend">
53 <div class="legend">
54 <span class="legendinfo equal">equal</span>
54 <span class="legendinfo equal">equal</span>
55 <span class="legendinfo delete">deleted</span>
55 <span class="legendinfo delete">deleted</span>
56 <span class="legendinfo insert">inserted</span>
56 <span class="legendinfo insert">inserted</span>
57 <span class="legendinfo replace">replaced</span>
57 <span class="legendinfo replace">replaced</span>
58 </div>
58 </div>
59
59
60 <div class="comparison">
60 <div class="comparison">
61 {comparison}
61 <table class="bigtable">
62 <thead class="header">
63 <tr>
64 <th>{leftrev}:{leftnode|short}</th>
65 <th>{rightrev}:{rightnode|short}</th>
66 </tr>
67 </thead>
68 {comparison}
69 </table>
62 </div>
70 </div>
63
71
64 {footer}
72 {footer}
@@ -1,270 +1,260 b''
1 default = 'summary'
1 default = 'summary'
2 mimetype = 'text/html; charset={encoding}'
2 mimetype = 'text/html; charset={encoding}'
3 header = header.tmpl
3 header = header.tmpl
4 footer = footer.tmpl
4 footer = footer.tmpl
5 search = search.tmpl
5 search = search.tmpl
6 changelog = changelog.tmpl
6 changelog = changelog.tmpl
7 summary = summary.tmpl
7 summary = summary.tmpl
8 error = error.tmpl
8 error = error.tmpl
9 notfound = notfound.tmpl
9 notfound = notfound.tmpl
10
10
11 help = help.tmpl
11 help = help.tmpl
12 helptopics = helptopics.tmpl
12 helptopics = helptopics.tmpl
13
13
14 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
14 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
15
15
16 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
16 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a>'
19 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a>'
20 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
20 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
21 filenodelink = '
21 filenodelink = '
22 <tr class="parity{parity}">
22 <tr class="parity{parity}">
23 <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
23 <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
24 <td></td>
24 <td></td>
25 <td>
25 <td>
26 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
26 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
29 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
29 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
30 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
30 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
31 </td>
31 </td>
32 </tr>'
32 </tr>'
33 filenolink = '
33 filenolink = '
34 <tr class="parity{parity}">
34 <tr class="parity{parity}">
35 <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
35 <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
36 <td></td>
36 <td></td>
37 <td>
37 <td>
38 file |
38 file |
39 annotate |
39 annotate |
40 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
40 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
41 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
41 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
42 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
42 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
43 </td>
43 </td>
44 </tr>'
44 </tr>'
45
45
46 nav = '{before%naventry} {after%naventry}'
46 nav = '{before%naventry} {after%naventry}'
47 navshort = '{before%navshortentry}{after%navshortentry}'
47 navshort = '{before%navshortentry}{after%navshortentry}'
48 navgraph = '{before%navgraphentry}{after%navgraphentry}'
48 navgraph = '{before%navgraphentry}{after%navgraphentry}'
49 filenav = '{before%filenaventry}{after%filenaventry}'
49 filenav = '{before%filenaventry}{after%filenaventry}'
50
50
51 fileellipses = '...'
51 fileellipses = '...'
52 changelogentry = changelogentry.tmpl
52 changelogentry = changelogentry.tmpl
53 searchentry = changelogentry.tmpl
53 searchentry = changelogentry.tmpl
54 changeset = changeset.tmpl
54 changeset = changeset.tmpl
55 manifest = manifest.tmpl
55 manifest = manifest.tmpl
56 direntry = '
56 direntry = '
57 <tr class="parity{parity}">
57 <tr class="parity{parity}">
58 <td>drwxr-xr-x</td>
58 <td>drwxr-xr-x</td>
59 <td></td>
59 <td></td>
60 <td></td>
60 <td></td>
61 <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
61 <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
62 <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></td>
62 <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></td>
63 </tr>'
63 </tr>'
64 fileentry = '
64 fileentry = '
65 <tr class="parity{parity}">
65 <tr class="parity{parity}">
66 <td>{permissions|permissions}</td>
66 <td>{permissions|permissions}</td>
67 <td>{date|isodate}</td>
67 <td>{date|isodate}</td>
68 <td>{size}</td>
68 <td>{size}</td>
69 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
69 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
70 <td>
70 <td>
71 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
71 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
72 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
72 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
73 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
73 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
74 </td>
74 </td>
75 </tr>'
75 </tr>'
76 filerevision = filerevision.tmpl
76 filerevision = filerevision.tmpl
77 fileannotate = fileannotate.tmpl
77 fileannotate = fileannotate.tmpl
78 filediff = filediff.tmpl
78 filediff = filediff.tmpl
79 filecomparison = filecomparison.tmpl
79 filecomparison = filecomparison.tmpl
80 filelog = filelog.tmpl
80 filelog = filelog.tmpl
81 fileline = '
81 fileline = '
82 <div style="font-family:monospace" class="parity{parity}">
82 <div style="font-family:monospace" class="parity{parity}">
83 <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
83 <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
84 </div>'
84 </div>'
85 annotateline = '
85 annotateline = '
86 <tr class="parity{parity}">
86 <tr class="parity{parity}">
87 <td class="linenr">
87 <td class="linenr">
88 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
88 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
89 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
89 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
90 </td>
90 </td>
91 <td class="lineno">
91 <td class="lineno">
92 <a href="#{lineid}" id="{lineid}">{linenumber}</a>
92 <a href="#{lineid}" id="{lineid}">{linenumber}</a>
93 </td>
93 </td>
94 <td class="source">{line|escape}</td>
94 <td class="source">{line|escape}</td>
95 </tr>'
95 </tr>'
96 difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
96 difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
97 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
97 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
98 difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
98 difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
99 diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
99 diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
100
100
101 comparison = '
102 <table class="bigtable">
103 <thead class="header">
104 <tr>
105 <th>{leftrev}:{leftnode|short}</th>
106 <th>{rightrev}:{rightnode|short}</th>
107 </tr>
108 </thead>
109 {blocks}
110 </table>'
111 comparisonblock ='
101 comparisonblock ='
112 <tbody class="block">
102 <tbody class="block">
113 {lines}
103 {lines}
114 </tbody>'
104 </tbody>'
115 comparisonline = '
105 comparisonline = '
116 <tr>
106 <tr>
117 <td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
107 <td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
118 <td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
108 <td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
119 </tr>'
109 </tr>'
120
110
121 changelogparent = '
111 changelogparent = '
122 <tr>
112 <tr>
123 <th class="parent">parent {rev}:</th>
113 <th class="parent">parent {rev}:</th>
124 <td class="parent">
114 <td class="parent">
125 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
115 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
126 </td>
116 </td>
127 </tr>'
117 </tr>'
128 changesetbranch = '<dt>branch</dt><dd>{name}</dd>'
118 changesetbranch = '<dt>branch</dt><dd>{name}</dd>'
129 changesetparent = '
119 changesetparent = '
130 <dt>parent {rev}</dt>
120 <dt>parent {rev}</dt>
131 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
121 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
132 filerevbranch = '<dt>branch</dt><dd>{name}</dd>'
122 filerevbranch = '<dt>branch</dt><dd>{name}</dd>'
133 filerevparent = '
123 filerevparent = '
134 <dt>parent {rev}</dt>
124 <dt>parent {rev}</dt>
135 <dd>
125 <dd>
136 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
126 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
137 {rename%filerename}{node|short}
127 {rename%filerename}{node|short}
138 </a>
128 </a>
139 </dd>'
129 </dd>'
140 filerename = '{file|escape}@'
130 filerename = '{file|escape}@'
141 filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
131 filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
142 fileannotateparent = '
132 fileannotateparent = '
143 <dt>parent {rev}</dt>
133 <dt>parent {rev}</dt>
144 <dd>
134 <dd>
145 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
135 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
146 {rename%filerename}{node|short}
136 {rename%filerename}{node|short}
147 </a>
137 </a>
148 </dd>'
138 </dd>'
149 changelogchild = '
139 changelogchild = '
150 <dt>child {rev}:</dt>
140 <dt>child {rev}:</dt>
151 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
141 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
152 changesetchild = '
142 changesetchild = '
153 <dt>child {rev}</dt>
143 <dt>child {rev}</dt>
154 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
144 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
155 filerevchild = '
145 filerevchild = '
156 <dt>child {rev}</dt>
146 <dt>child {rev}</dt>
157 <dd>
147 <dd>
158 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
148 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
159 </dd>'
149 </dd>'
160 fileannotatechild = '
150 fileannotatechild = '
161 <dt>child {rev}</dt>
151 <dt>child {rev}</dt>
162 <dd>
152 <dd>
163 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
153 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
164 </dd>'
154 </dd>'
165 tags = tags.tmpl
155 tags = tags.tmpl
166 tagentry = '
156 tagentry = '
167 <tr class="parity{parity}">
157 <tr class="parity{parity}">
168 <td class="nowrap age">{date|rfc822date}</td>
158 <td class="nowrap age">{date|rfc822date}</td>
169 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td>
159 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td>
170 <td class="nowrap">
160 <td class="nowrap">
171 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
161 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
172 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
162 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
173 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
163 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
174 </td>
164 </td>
175 </tr>'
165 </tr>'
176 bookmarks = bookmarks.tmpl
166 bookmarks = bookmarks.tmpl
177 bookmarkentry = '
167 bookmarkentry = '
178 <tr class="parity{parity}">
168 <tr class="parity{parity}">
179 <td class="nowrap date">{date|rfc822date}</td>
169 <td class="nowrap date">{date|rfc822date}</td>
180 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{bookmark|escape}</a></td>
170 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{bookmark|escape}</a></td>
181 <td class="nowrap">
171 <td class="nowrap">
182 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
172 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
183 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
173 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
184 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
174 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
185 </td>
175 </td>
186 </tr>'
176 </tr>'
187 branches = branches.tmpl
177 branches = branches.tmpl
188 branchentry = '
178 branchentry = '
189 <tr class="parity{parity}">
179 <tr class="parity{parity}">
190 <td class="nowrap age">{date|rfc822date}</td>
180 <td class="nowrap age">{date|rfc822date}</td>
191 <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
181 <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
192 <td class="{status}">{branch|escape}</td>
182 <td class="{status}">{branch|escape}</td>
193 <td class="nowrap">
183 <td class="nowrap">
194 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
184 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
195 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
185 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
196 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
186 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
197 </td>
187 </td>
198 </tr>'
188 </tr>'
199 diffblock = '<pre>{lines}</pre>'
189 diffblock = '<pre>{lines}</pre>'
200 filediffparent = '
190 filediffparent = '
201 <dt>parent {rev}</dt>
191 <dt>parent {rev}</dt>
202 <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
192 <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
203 filecompparent = '
193 filecompparent = '
204 <dt>parent {rev}</dt>
194 <dt>parent {rev}</dt>
205 <dd><a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
195 <dd><a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
206 filelogparent = '
196 filelogparent = '
207 <tr>
197 <tr>
208 <td align="right">parent {rev}:&nbsp;</td>
198 <td align="right">parent {rev}:&nbsp;</td>
209 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
199 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
210 </tr>'
200 </tr>'
211 filediffchild = '
201 filediffchild = '
212 <dt>child {rev}</dt>
202 <dt>child {rev}</dt>
213 <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
203 <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
214 filecompchild = '
204 filecompchild = '
215 <dt>child {rev}</dt>
205 <dt>child {rev}</dt>
216 <dd><a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
206 <dd><a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
217 filelogchild = '
207 filelogchild = '
218 <tr>
208 <tr>
219 <td align="right">child {rev}:&nbsp;</td>
209 <td align="right">child {rev}:&nbsp;</td>
220 <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
210 <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
221 </tr>'
211 </tr>'
222 shortlog = shortlog.tmpl
212 shortlog = shortlog.tmpl
223 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
213 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
224 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
214 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
225 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
215 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
226 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
216 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
227 shortlogentry = '
217 shortlogentry = '
228 <tr class="parity{parity}">
218 <tr class="parity{parity}">
229 <td class="nowrap age">{date|rfc822date}</td>
219 <td class="nowrap age">{date|rfc822date}</td>
230 <td>{author|person}</td>
220 <td>{author|person}</td>
231 <td>
221 <td>
232 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
222 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
233 {desc|strip|firstline|escape|nonempty}
223 {desc|strip|firstline|escape|nonempty}
234 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
224 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
235 </a>
225 </a>
236 </td>
226 </td>
237 <td class="nowrap">
227 <td class="nowrap">
238 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
228 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
239 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
229 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
240 </td>
230 </td>
241 </tr>'
231 </tr>'
242 filelogentry = '
232 filelogentry = '
243 <tr class="parity{parity}">
233 <tr class="parity{parity}">
244 <td class="nowrap age">{date|rfc822date}</td>
234 <td class="nowrap age">{date|rfc822date}</td>
245 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
235 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
246 <td class="nowrap">
236 <td class="nowrap">
247 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
237 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
248 {rename%filelogrename}
238 {rename%filelogrename}
249 </td>
239 </td>
250 </tr>'
240 </tr>'
251 archiveentry = '<li><a href="{url}archive/{node|short}{extension}">{type|escape}</a></li>'
241 archiveentry = '<li><a href="{url}archive/{node|short}{extension}">{type|escape}</a></li>'
252 indexentry = '
242 indexentry = '
253 <tr class="parity{parity}">
243 <tr class="parity{parity}">
254 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
244 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
255 <td>{description}</td>
245 <td>{description}</td>
256 <td>{contact|obfuscate}</td>
246 <td>{contact|obfuscate}</td>
257 <td class="age">{lastchange|rfc822date}</td>
247 <td class="age">{lastchange|rfc822date}</td>
258 <td class="indexlinks">{archives%indexarchiveentry}</td>
248 <td class="indexlinks">{archives%indexarchiveentry}</td>
259 <td>
249 <td>
260 <div class="rss_logo">
250 <div class="rss_logo">
261 <a href="{url}rss-log">RSS</a>
251 <a href="{url}rss-log">RSS</a>
262 <a href="{url}atom-log">Atom</a>
252 <a href="{url}atom-log">Atom</a>
263 </div>
253 </div>
264 </td>
254 </td>
265 </tr>\n'
255 </tr>\n'
266 indexarchiveentry = '<a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
256 indexarchiveentry = '<a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
267 index = index.tmpl
257 index = index.tmpl
268 urlparameter = '{separator}{name}={value|urlescape}'
258 urlparameter = '{separator}{name}={value|urlescape}'
269 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
259 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
270 graph = graph.tmpl
260 graph = graph.tmpl
@@ -1,85 +1,93 b''
1 {header}
1 {header}
2 <title>{repo|escape}: {file|escape} comparison</title>
2 <title>{repo|escape}: {file|escape} comparison</title>
3 </head>
3 </head>
4 <body>
4 <body>
5
5
6 <div class="container">
6 <div class="container">
7 <div class="menu">
7 <div class="menu">
8 <div class="logo">
8 <div class="logo">
9 <a href="{logourl}">
9 <a href="{logourl}">
10 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
10 <img src="{staticurl}{logoimg}" alt="mercurial" /></a>
11 </div>
11 </div>
12 <ul>
12 <ul>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
16 <li><a href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
17 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
18 </ul>
18 </ul>
19 <ul>
19 <ul>
20 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
20 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
21 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
21 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
22 </ul>
22 </ul>
23 <ul>
23 <ul>
24 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
24 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
25 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
25 <li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
26 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
26 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
27 <li class="active">comparison</li>
27 <li class="active">comparison</li>
28 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
28 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
29 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
29 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
30 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
30 <li><a href="{url}raw-file/{node|short}/{file|urlescape}">raw</a></li>
31 </ul>
31 </ul>
32 <ul>
32 <ul>
33 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
33 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
34 </ul>
34 </ul>
35 </div>
35 </div>
36
36
37 <div class="main">
37 <div class="main">
38 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
38 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
39 <h3>comparison {file|escape} @ {rev}:{node|short}</h3>
39 <h3>comparison {file|escape} @ {rev}:{node|short}</h3>
40
40
41 <form class="search" action="{url}log">
41 <form class="search" action="{url}log">
42 <p>{sessionvars%hiddenformentry}</p>
42 <p>{sessionvars%hiddenformentry}</p>
43 <p><input name="rev" id="search1" type="text" size="30" /></p>
43 <p><input name="rev" id="search1" type="text" size="30" /></p>
44 <div id="hint">find changesets by author, revision,
44 <div id="hint">find changesets by author, revision,
45 files, or words in the commit message</div>
45 files, or words in the commit message</div>
46 </form>
46 </form>
47
47
48 <div class="description">{desc|strip|escape|nonempty}</div>
48 <div class="description">{desc|strip|escape|nonempty}</div>
49
49
50 <table id="changesetEntry">
50 <table id="changesetEntry">
51 <tr>
51 <tr>
52 <th>author</th>
52 <th>author</th>
53 <td>{author|obfuscate}</td>
53 <td>{author|obfuscate}</td>
54 </tr>
54 </tr>
55 <tr>
55 <tr>
56 <th>date</th>
56 <th>date</th>
57 <td class="date age">{date|rfc822date}</td>
57 <td class="date age">{date|rfc822date}</td>
58 </tr>
58 </tr>
59 <tr>
59 <tr>
60 <th>parents</th>
60 <th>parents</th>
61 <td>{parent%filerevparent}</td>
61 <td>{parent%filerevparent}</td>
62 </tr>
62 </tr>
63 <tr>
63 <tr>
64 <th>children</th>
64 <th>children</th>
65 <td>{child%filerevchild}</td>
65 <td>{child%filerevchild}</td>
66 </tr>
66 </tr>
67 {changesettag}
67 {changesettag}
68 </table>
68 </table>
69
69
70 <div class="overflow">
70 <div class="overflow">
71 <div class="sourcefirst"> comparison</div>
71 <div class="sourcefirst"> comparison</div>
72 <div class="legend">
72 <div class="legend">
73 <span class="legendinfo equal">equal</span>
73 <span class="legendinfo equal">equal</span>
74 <span class="legendinfo delete">deleted</span>
74 <span class="legendinfo delete">deleted</span>
75 <span class="legendinfo insert">inserted</span>
75 <span class="legendinfo insert">inserted</span>
76 <span class="legendinfo replace">replaced</span>
76 <span class="legendinfo replace">replaced</span>
77 </div>
77 </div>
78
78
79 {comparison}
79 <table class="bigtable">
80 <thead class="header">
81 <tr>
82 <th>{leftrev}:{leftnode|short}</th>
83 <th>{rightrev}:{rightnode|short}</th>
84 </tr>
85 </thead>
86 {comparison}
87 </table>
80
88
81 </div>
89 </div>
82 </div>
90 </div>
83 </div>
91 </div>
84
92
85 {footer}
93 {footer}
@@ -1,234 +1,224 b''
1 default = 'shortlog'
1 default = 'shortlog'
2
2
3 mimetype = 'text/html; charset={encoding}'
3 mimetype = 'text/html; charset={encoding}'
4 header = header.tmpl
4 header = header.tmpl
5 footer = footer.tmpl
5 footer = footer.tmpl
6 search = search.tmpl
6 search = search.tmpl
7
7
8 changelog = shortlog.tmpl
8 changelog = shortlog.tmpl
9 shortlog = shortlog.tmpl
9 shortlog = shortlog.tmpl
10 shortlogentry = shortlogentry.tmpl
10 shortlogentry = shortlogentry.tmpl
11 graph = graph.tmpl
11 graph = graph.tmpl
12 help = help.tmpl
12 help = help.tmpl
13 helptopics = helptopics.tmpl
13 helptopics = helptopics.tmpl
14
14
15 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
15 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
16
16
17 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
20 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
20 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
21 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
21 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
22 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
22 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
23 filenolink = '{file|escape} '
23 filenolink = '{file|escape} '
24 fileellipses = '...'
24 fileellipses = '...'
25 diffstatlink = diffstat.tmpl
25 diffstatlink = diffstat.tmpl
26 diffstatnolink = diffstat.tmpl
26 diffstatnolink = diffstat.tmpl
27 changelogentry = shortlogentry.tmpl
27 changelogentry = shortlogentry.tmpl
28 searchentry = shortlogentry.tmpl
28 searchentry = shortlogentry.tmpl
29 changeset = changeset.tmpl
29 changeset = changeset.tmpl
30 manifest = manifest.tmpl
30 manifest = manifest.tmpl
31
31
32 nav = '{before%naventry} {after%naventry}'
32 nav = '{before%naventry} {after%naventry}'
33 navshort = '{before%navshortentry}{after%navshortentry}'
33 navshort = '{before%navshortentry}{after%navshortentry}'
34 navgraph = '{before%navgraphentry}{after%navgraphentry}'
34 navgraph = '{before%navgraphentry}{after%navgraphentry}'
35 filenav = '{before%filenaventry}{after%filenaventry}'
35 filenav = '{before%filenaventry}{after%filenaventry}'
36
36
37 direntry = '
37 direntry = '
38 <tr class="fileline parity{parity}">
38 <tr class="fileline parity{parity}">
39 <td class="name">
39 <td class="name">
40 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
40 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
41 <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
41 <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
42 </a>
42 </a>
43 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
43 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
44 {emptydirs|escape}
44 {emptydirs|escape}
45 </a>
45 </a>
46 </td>
46 </td>
47 <td class="size"></td>
47 <td class="size"></td>
48 <td class="permissions">drwxr-xr-x</td>
48 <td class="permissions">drwxr-xr-x</td>
49 </tr>'
49 </tr>'
50
50
51 fileentry = '
51 fileentry = '
52 <tr class="fileline parity{parity}">
52 <tr class="fileline parity{parity}">
53 <td class="filename">
53 <td class="filename">
54 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
54 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
55 <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
55 <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
56 </a>
56 </a>
57 </td>
57 </td>
58 <td class="size">{size}</td>
58 <td class="size">{size}</td>
59 <td class="permissions">{permissions|permissions}</td>
59 <td class="permissions">{permissions|permissions}</td>
60 </tr>'
60 </tr>'
61
61
62 filerevision = filerevision.tmpl
62 filerevision = filerevision.tmpl
63 fileannotate = fileannotate.tmpl
63 fileannotate = fileannotate.tmpl
64 filediff = filediff.tmpl
64 filediff = filediff.tmpl
65 filecomparison = filecomparison.tmpl
65 filecomparison = filecomparison.tmpl
66 filelog = filelog.tmpl
66 filelog = filelog.tmpl
67 fileline = '
67 fileline = '
68 <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
68 <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
69 filelogentry = filelogentry.tmpl
69 filelogentry = filelogentry.tmpl
70
70
71 annotateline = '
71 annotateline = '
72 <tr class="parity{parity}">
72 <tr class="parity{parity}">
73 <td class="annotate">
73 <td class="annotate">
74 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
74 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
75 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
75 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
76 </td>
76 </td>
77 <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
77 <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
78 </tr>'
78 </tr>'
79
79
80 diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
80 diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
81 difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
81 difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
82 difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
82 difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
83 difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
83 difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
84 diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
84 diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
85
85
86 comparison = '
87 <table class="bigtable">
88 <thead class="header">
89 <tr>
90 <th>{leftrev}:{leftnode|short}</th>
91 <th>{rightrev}:{rightnode|short}</th>
92 </tr>
93 </thead>
94 {blocks}
95 </table>'
96 comparisonblock ='
86 comparisonblock ='
97 <tbody class="block">
87 <tbody class="block">
98 {lines}
88 {lines}
99 </tbody>'
89 </tbody>'
100 comparisonline = '
90 comparisonline = '
101 <tr>
91 <tr>
102 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
92 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
103 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
93 <td class="source {type}"><a href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
104 </tr>'
94 </tr>'
105
95
106 changelogparent = '
96 changelogparent = '
107 <tr>
97 <tr>
108 <th class="parent">parent {rev}:</th>
98 <th class="parent">parent {rev}:</th>
109 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
99 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
110 </tr>'
100 </tr>'
111
101
112 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
102 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
113
103
114 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
104 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
115 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
105 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
116
106
117 filerename = '{file|escape}@'
107 filerename = '{file|escape}@'
118 filelogrename = '
108 filelogrename = '
119 <span class="base">
109 <span class="base">
120 base
110 base
121 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
111 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
122 {file|escape}@{node|short}
112 {file|escape}@{node|short}
123 </a>
113 </a>
124 </span>'
114 </span>'
125 fileannotateparent = '
115 fileannotateparent = '
126 <tr>
116 <tr>
127 <td class="metatag">parent:</td>
117 <td class="metatag">parent:</td>
128 <td>
118 <td>
129 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
119 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
130 {rename%filerename}{node|short}
120 {rename%filerename}{node|short}
131 </a>
121 </a>
132 </td>
122 </td>
133 </tr>'
123 </tr>'
134 changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
124 changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
135 changelogchild = '
125 changelogchild = '
136 <tr>
126 <tr>
137 <th class="child">child</th>
127 <th class="child">child</th>
138 <td class="child">
128 <td class="child">
139 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
129 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
140 {node|short}
130 {node|short}
141 </a>
131 </a>
142 </td>
132 </td>
143 </tr>'
133 </tr>'
144 fileannotatechild = '
134 fileannotatechild = '
145 <tr>
135 <tr>
146 <td class="metatag">child:</td>
136 <td class="metatag">child:</td>
147 <td>
137 <td>
148 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
138 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
149 {node|short}
139 {node|short}
150 </a>
140 </a>
151 </td>
141 </td>
152 </tr>'
142 </tr>'
153 tags = tags.tmpl
143 tags = tags.tmpl
154 tagentry = '
144 tagentry = '
155 <tr class="tagEntry parity{parity}">
145 <tr class="tagEntry parity{parity}">
156 <td>
146 <td>
157 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
147 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
158 {tag|escape}
148 {tag|escape}
159 </a>
149 </a>
160 </td>
150 </td>
161 <td class="node">
151 <td class="node">
162 {node|short}
152 {node|short}
163 </td>
153 </td>
164 </tr>'
154 </tr>'
165 bookmarks = bookmarks.tmpl
155 bookmarks = bookmarks.tmpl
166 bookmarkentry = '
156 bookmarkentry = '
167 <tr class="tagEntry parity{parity}">
157 <tr class="tagEntry parity{parity}">
168 <td>
158 <td>
169 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
159 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
170 {bookmark|escape}
160 {bookmark|escape}
171 </a>
161 </a>
172 </td>
162 </td>
173 <td class="node">
163 <td class="node">
174 {node|short}
164 {node|short}
175 </td>
165 </td>
176 </tr>'
166 </tr>'
177 branches = branches.tmpl
167 branches = branches.tmpl
178 branchentry = '
168 branchentry = '
179 <tr class="tagEntry parity{parity}">
169 <tr class="tagEntry parity{parity}">
180 <td>
170 <td>
181 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
171 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
182 {branch|escape}
172 {branch|escape}
183 </a>
173 </a>
184 </td>
174 </td>
185 <td class="node">
175 <td class="node">
186 {node|short}
176 {node|short}
187 </td>
177 </td>
188 </tr>'
178 </tr>'
189 changelogtag = '<span class="tag">{name|escape}</span> '
179 changelogtag = '<span class="tag">{name|escape}</span> '
190 changesettag = '<span class="tag">{tag|escape}</span> '
180 changesettag = '<span class="tag">{tag|escape}</span> '
191 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
181 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
192 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
182 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
193 changelogbranchname = '<span class="branchname">{name|escape}</span> '
183 changelogbranchname = '<span class="branchname">{name|escape}</span> '
194
184
195 filediffparent = '
185 filediffparent = '
196 <tr>
186 <tr>
197 <th class="parent">parent {rev}:</th>
187 <th class="parent">parent {rev}:</th>
198 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
188 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
199 </tr>'
189 </tr>'
200 filelogparent = '
190 filelogparent = '
201 <tr>
191 <tr>
202 <th>parent {rev}:</th>
192 <th>parent {rev}:</th>
203 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
193 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
204 </tr>'
194 </tr>'
205 filediffchild = '
195 filediffchild = '
206 <tr>
196 <tr>
207 <th class="child">child {rev}:</th>
197 <th class="child">child {rev}:</th>
208 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
198 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
209 </td>
199 </td>
210 </tr>'
200 </tr>'
211 filelogchild = '
201 filelogchild = '
212 <tr>
202 <tr>
213 <th>child {rev}:</th>
203 <th>child {rev}:</th>
214 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
204 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
215 </tr>'
205 </tr>'
216
206
217 indexentry = '
207 indexentry = '
218 <tr class="parity{parity}">
208 <tr class="parity{parity}">
219 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
209 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
220 <td>{description}</td>
210 <td>{description}</td>
221 <td>{contact|obfuscate}</td>
211 <td>{contact|obfuscate}</td>
222 <td class="age">{lastchange|rfc822date}</td>
212 <td class="age">{lastchange|rfc822date}</td>
223 <td class="indexlinks">{archives%indexarchiveentry}</td>
213 <td class="indexlinks">{archives%indexarchiveentry}</td>
224 </tr>\n'
214 </tr>\n'
225 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
215 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
226 index = index.tmpl
216 index = index.tmpl
227 archiveentry = '
217 archiveentry = '
228 <li>
218 <li>
229 <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
219 <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
230 </li>'
220 </li>'
231 notfound = notfound.tmpl
221 notfound = notfound.tmpl
232 error = error.tmpl
222 error = error.tmpl
233 urlparameter = '{separator}{name}={value|urlescape}'
223 urlparameter = '{separator}{name}={value|urlescape}'
234 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
224 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
@@ -1,989 +1,986 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 setting up repo
3 setting up repo
4
4
5 $ hg init test
5 $ hg init test
6 $ cd test
6 $ cd test
7 $ echo a > a
7 $ echo a > a
8 $ echo b > b
8 $ echo b > b
9 $ hg ci -Ama
9 $ hg ci -Ama
10 adding a
10 adding a
11 adding b
11 adding b
12
12
13 change permissions for git diffs
13 change permissions for git diffs
14
14
15 $ hg import -q --bypass - <<EOF
15 $ hg import -q --bypass - <<EOF
16 > # HG changeset patch
16 > # HG changeset patch
17 > # User test
17 > # User test
18 > # Date 0 0
18 > # Date 0 0
19 > b
19 > b
20 >
20 >
21 > diff --git a/a b/a
21 > diff --git a/a b/a
22 > old mode 100644
22 > old mode 100644
23 > new mode 100755
23 > new mode 100755
24 > diff --git a/b b/b
24 > diff --git a/b b/b
25 > deleted file mode 100644
25 > deleted file mode 100644
26 > --- a/b
26 > --- a/b
27 > +++ /dev/null
27 > +++ /dev/null
28 > @@ -1,1 +0,0 @@
28 > @@ -1,1 +0,0 @@
29 > -b
29 > -b
30 > EOF
30 > EOF
31
31
32 set up hgweb
32 set up hgweb
33
33
34 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
34 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
35 $ cat hg.pid >> $DAEMON_PIDS
35 $ cat hg.pid >> $DAEMON_PIDS
36
36
37 revision
37 revision
38
38
39 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
39 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
40 200 Script output follows
40 200 Script output follows
41
41
42 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
42 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
43 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
43 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
44 <head>
44 <head>
45 <link rel="icon" href="/static/hgicon.png" type="image/png" />
45 <link rel="icon" href="/static/hgicon.png" type="image/png" />
46 <meta name="robots" content="index, nofollow" />
46 <meta name="robots" content="index, nofollow" />
47 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
47 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
48 <script type="text/javascript" src="/static/mercurial.js"></script>
48 <script type="text/javascript" src="/static/mercurial.js"></script>
49
49
50 <title>test: 0cd96de13884</title>
50 <title>test: 0cd96de13884</title>
51 </head>
51 </head>
52 <body>
52 <body>
53 <div class="container">
53 <div class="container">
54 <div class="menu">
54 <div class="menu">
55 <div class="logo">
55 <div class="logo">
56 <a href="http://mercurial.selenic.com/">
56 <a href="http://mercurial.selenic.com/">
57 <img src="/static/hglogo.png" alt="mercurial" /></a>
57 <img src="/static/hglogo.png" alt="mercurial" /></a>
58 </div>
58 </div>
59 <ul>
59 <ul>
60 <li><a href="/shortlog/0cd96de13884">log</a></li>
60 <li><a href="/shortlog/0cd96de13884">log</a></li>
61 <li><a href="/graph/0cd96de13884">graph</a></li>
61 <li><a href="/graph/0cd96de13884">graph</a></li>
62 <li><a href="/tags">tags</a></li>
62 <li><a href="/tags">tags</a></li>
63 <li><a href="/bookmarks">bookmarks</a></li>
63 <li><a href="/bookmarks">bookmarks</a></li>
64 <li><a href="/branches">branches</a></li>
64 <li><a href="/branches">branches</a></li>
65 </ul>
65 </ul>
66 <ul>
66 <ul>
67 <li class="active">changeset</li>
67 <li class="active">changeset</li>
68 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
68 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
69 <li><a href="/file/0cd96de13884">browse</a></li>
69 <li><a href="/file/0cd96de13884">browse</a></li>
70 </ul>
70 </ul>
71 <ul>
71 <ul>
72
72
73 </ul>
73 </ul>
74 <ul>
74 <ul>
75 <li><a href="/help">help</a></li>
75 <li><a href="/help">help</a></li>
76 </ul>
76 </ul>
77 </div>
77 </div>
78
78
79 <div class="main">
79 <div class="main">
80
80
81 <h2><a href="/">test</a></h2>
81 <h2><a href="/">test</a></h2>
82 <h3>changeset 0:0cd96de13884 </h3>
82 <h3>changeset 0:0cd96de13884 </h3>
83
83
84 <form class="search" action="/log">
84 <form class="search" action="/log">
85
85
86 <p><input name="rev" id="search1" type="text" size="30" /></p>
86 <p><input name="rev" id="search1" type="text" size="30" /></p>
87 <div id="hint">find changesets by author, revision,
87 <div id="hint">find changesets by author, revision,
88 files, or words in the commit message</div>
88 files, or words in the commit message</div>
89 </form>
89 </form>
90
90
91 <div class="description">a</div>
91 <div class="description">a</div>
92
92
93 <table id="changesetEntry">
93 <table id="changesetEntry">
94 <tr>
94 <tr>
95 <th class="author">author</th>
95 <th class="author">author</th>
96 <td class="author">&#116;&#101;&#115;&#116;</td>
96 <td class="author">&#116;&#101;&#115;&#116;</td>
97 </tr>
97 </tr>
98 <tr>
98 <tr>
99 <th class="date">date</th>
99 <th class="date">date</th>
100 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
100 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
101 <tr>
101 <tr>
102 <th class="author">parents</th>
102 <th class="author">parents</th>
103 <td class="author"></td>
103 <td class="author"></td>
104 </tr>
104 </tr>
105 <tr>
105 <tr>
106 <th class="author">children</th>
106 <th class="author">children</th>
107 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
107 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
108 </tr>
108 </tr>
109 <tr>
109 <tr>
110 <th class="files">files</th>
110 <th class="files">files</th>
111 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
111 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
112 </tr>
112 </tr>
113 <tr>
113 <tr>
114 <th class="diffstat">diffstat</th>
114 <th class="diffstat">diffstat</th>
115 <td class="diffstat">
115 <td class="diffstat">
116 2 files changed, 2 insertions(+), 0 deletions(-)
116 2 files changed, 2 insertions(+), 0 deletions(-)
117
117
118 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
118 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
119 <div id="diffstatdetails" style="display:none;">
119 <div id="diffstatdetails" style="display:none;">
120 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
120 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
121 <p>
121 <p>
122 <table> <tr class="parity0">
122 <table> <tr class="parity0">
123 <td class="diffstat-file"><a href="#l1.1">a</a></td>
123 <td class="diffstat-file"><a href="#l1.1">a</a></td>
124 <td class="diffstat-total" align="right">1</td>
124 <td class="diffstat-total" align="right">1</td>
125 <td class="diffstat-graph">
125 <td class="diffstat-graph">
126 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
126 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
127 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
127 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
128 </td>
128 </td>
129 </tr>
129 </tr>
130 <tr class="parity1">
130 <tr class="parity1">
131 <td class="diffstat-file"><a href="#l2.1">b</a></td>
131 <td class="diffstat-file"><a href="#l2.1">b</a></td>
132 <td class="diffstat-total" align="right">1</td>
132 <td class="diffstat-total" align="right">1</td>
133 <td class="diffstat-graph">
133 <td class="diffstat-graph">
134 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
134 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
135 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
135 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
136 </td>
136 </td>
137 </tr>
137 </tr>
138 </table>
138 </table>
139 </div>
139 </div>
140 </td>
140 </td>
141 </tr>
141 </tr>
142 </table>
142 </table>
143
143
144 <div class="overflow">
144 <div class="overflow">
145 <div class="sourcefirst"> line diff</div>
145 <div class="sourcefirst"> line diff</div>
146
146
147 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
147 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
148 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000
148 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000
149 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
149 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
150 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+a
150 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+a
151 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
151 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
152 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000
152 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000
153 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
153 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
154 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+b
154 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+b
155 </span></pre></div>
155 </span></pre></div>
156 </div>
156 </div>
157
157
158 </div>
158 </div>
159 </div>
159 </div>
160 <script type="text/javascript">process_dates()</script>
160 <script type="text/javascript">process_dates()</script>
161
161
162
162
163 </body>
163 </body>
164 </html>
164 </html>
165
165
166
166
167 raw revision
167 raw revision
168
168
169 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
169 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
170 200 Script output follows
170 200 Script output follows
171
171
172
172
173 # HG changeset patch
173 # HG changeset patch
174 # User test
174 # User test
175 # Date 0 0
175 # Date 0 0
176 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
176 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
177
177
178 a
178 a
179
179
180 diff -r 000000000000 -r 0cd96de13884 a
180 diff -r 000000000000 -r 0cd96de13884 a
181 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
181 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
182 +++ b/a Thu Jan 01 00:00:00 1970 +0000
182 +++ b/a Thu Jan 01 00:00:00 1970 +0000
183 @@ -0,0 +1,1 @@
183 @@ -0,0 +1,1 @@
184 +a
184 +a
185 diff -r 000000000000 -r 0cd96de13884 b
185 diff -r 000000000000 -r 0cd96de13884 b
186 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
186 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
187 +++ b/b Thu Jan 01 00:00:00 1970 +0000
187 +++ b/b Thu Jan 01 00:00:00 1970 +0000
188 @@ -0,0 +1,1 @@
188 @@ -0,0 +1,1 @@
189 +b
189 +b
190
190
191
191
192 diff removed file
192 diff removed file
193
193
194 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/b'
194 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/b'
195 200 Script output follows
195 200 Script output follows
196
196
197 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
197 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
198 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
198 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
199 <head>
199 <head>
200 <link rel="icon" href="/static/hgicon.png" type="image/png" />
200 <link rel="icon" href="/static/hgicon.png" type="image/png" />
201 <meta name="robots" content="index, nofollow" />
201 <meta name="robots" content="index, nofollow" />
202 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
202 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
203 <script type="text/javascript" src="/static/mercurial.js"></script>
203 <script type="text/javascript" src="/static/mercurial.js"></script>
204
204
205 <title>test: b diff</title>
205 <title>test: b diff</title>
206 </head>
206 </head>
207 <body>
207 <body>
208
208
209 <div class="container">
209 <div class="container">
210 <div class="menu">
210 <div class="menu">
211 <div class="logo">
211 <div class="logo">
212 <a href="http://mercurial.selenic.com/">
212 <a href="http://mercurial.selenic.com/">
213 <img src="/static/hglogo.png" alt="mercurial" /></a>
213 <img src="/static/hglogo.png" alt="mercurial" /></a>
214 </div>
214 </div>
215 <ul>
215 <ul>
216 <li><a href="/shortlog/559edbd9ed20">log</a></li>
216 <li><a href="/shortlog/559edbd9ed20">log</a></li>
217 <li><a href="/graph/559edbd9ed20">graph</a></li>
217 <li><a href="/graph/559edbd9ed20">graph</a></li>
218 <li><a href="/tags">tags</a></li>
218 <li><a href="/tags">tags</a></li>
219 <li><a href="/bookmarks">bookmarks</a></li>
219 <li><a href="/bookmarks">bookmarks</a></li>
220 <li><a href="/branches">branches</a></li>
220 <li><a href="/branches">branches</a></li>
221 </ul>
221 </ul>
222 <ul>
222 <ul>
223 <li><a href="/rev/559edbd9ed20">changeset</a></li>
223 <li><a href="/rev/559edbd9ed20">changeset</a></li>
224 <li><a href="/file/559edbd9ed20">browse</a></li>
224 <li><a href="/file/559edbd9ed20">browse</a></li>
225 </ul>
225 </ul>
226 <ul>
226 <ul>
227 <li><a href="/file/559edbd9ed20/b">file</a></li>
227 <li><a href="/file/559edbd9ed20/b">file</a></li>
228 <li><a href="/file/tip/b">latest</a></li>
228 <li><a href="/file/tip/b">latest</a></li>
229 <li class="active">diff</li>
229 <li class="active">diff</li>
230 <li><a href="/comparison/559edbd9ed20/b">comparison</a></li>
230 <li><a href="/comparison/559edbd9ed20/b">comparison</a></li>
231 <li><a href="/annotate/559edbd9ed20/b">annotate</a></li>
231 <li><a href="/annotate/559edbd9ed20/b">annotate</a></li>
232 <li><a href="/log/559edbd9ed20/b">file log</a></li>
232 <li><a href="/log/559edbd9ed20/b">file log</a></li>
233 <li><a href="/raw-file/559edbd9ed20/b">raw</a></li>
233 <li><a href="/raw-file/559edbd9ed20/b">raw</a></li>
234 </ul>
234 </ul>
235 <ul>
235 <ul>
236 <li><a href="/help">help</a></li>
236 <li><a href="/help">help</a></li>
237 </ul>
237 </ul>
238 </div>
238 </div>
239
239
240 <div class="main">
240 <div class="main">
241 <h2><a href="/">test</a></h2>
241 <h2><a href="/">test</a></h2>
242 <h3>diff b @ 1:559edbd9ed20</h3>
242 <h3>diff b @ 1:559edbd9ed20</h3>
243
243
244 <form class="search" action="/log">
244 <form class="search" action="/log">
245 <p></p>
245 <p></p>
246 <p><input name="rev" id="search1" type="text" size="30" /></p>
246 <p><input name="rev" id="search1" type="text" size="30" /></p>
247 <div id="hint">find changesets by author, revision,
247 <div id="hint">find changesets by author, revision,
248 files, or words in the commit message</div>
248 files, or words in the commit message</div>
249 </form>
249 </form>
250
250
251 <div class="description">b</div>
251 <div class="description">b</div>
252
252
253 <table id="changesetEntry">
253 <table id="changesetEntry">
254 <tr>
254 <tr>
255 <th>author</th>
255 <th>author</th>
256 <td>&#116;&#101;&#115;&#116;</td>
256 <td>&#116;&#101;&#115;&#116;</td>
257 </tr>
257 </tr>
258 <tr>
258 <tr>
259 <th>date</th>
259 <th>date</th>
260 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
260 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
261 </tr>
261 </tr>
262 <tr>
262 <tr>
263 <th>parents</th>
263 <th>parents</th>
264 <td><a href="/file/0cd96de13884/b">0cd96de13884</a> </td>
264 <td><a href="/file/0cd96de13884/b">0cd96de13884</a> </td>
265 </tr>
265 </tr>
266 <tr>
266 <tr>
267 <th>children</th>
267 <th>children</th>
268 <td></td>
268 <td></td>
269 </tr>
269 </tr>
270
270
271 </table>
271 </table>
272
272
273 <div class="overflow">
273 <div class="overflow">
274 <div class="sourcefirst"> line diff</div>
274 <div class="sourcefirst"> line diff</div>
275
275
276 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- a/b Thu Jan 01 00:00:00 1970 +0000
276 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- a/b Thu Jan 01 00:00:00 1970 +0000
277 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
277 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
278 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -1,1 +0,0 @@
278 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -1,1 +0,0 @@
279 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="minusline">-b
279 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="minusline">-b
280 </span></pre></div>
280 </span></pre></div>
281 </div>
281 </div>
282 </div>
282 </div>
283 </div>
283 </div>
284
284
285 <script type="text/javascript">process_dates()</script>
285 <script type="text/javascript">process_dates()</script>
286
286
287
287
288 </body>
288 </body>
289 </html>
289 </html>
290
290
291
291
292 set up hgweb with git diffs
292 set up hgweb with git diffs
293
293
294 $ "$TESTDIR/killdaemons.py"
294 $ "$TESTDIR/killdaemons.py"
295 $ hg serve --config 'diff.git=1' -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
295 $ hg serve --config 'diff.git=1' -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
296 $ cat hg.pid >> $DAEMON_PIDS
296 $ cat hg.pid >> $DAEMON_PIDS
297
297
298 revision
298 revision
299
299
300 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
300 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
301 200 Script output follows
301 200 Script output follows
302
302
303 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
303 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
304 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
304 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
305 <head>
305 <head>
306 <link rel="icon" href="/static/hgicon.png" type="image/png" />
306 <link rel="icon" href="/static/hgicon.png" type="image/png" />
307 <meta name="robots" content="index, nofollow" />
307 <meta name="robots" content="index, nofollow" />
308 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
308 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
309 <script type="text/javascript" src="/static/mercurial.js"></script>
309 <script type="text/javascript" src="/static/mercurial.js"></script>
310
310
311 <title>test: 0cd96de13884</title>
311 <title>test: 0cd96de13884</title>
312 </head>
312 </head>
313 <body>
313 <body>
314 <div class="container">
314 <div class="container">
315 <div class="menu">
315 <div class="menu">
316 <div class="logo">
316 <div class="logo">
317 <a href="http://mercurial.selenic.com/">
317 <a href="http://mercurial.selenic.com/">
318 <img src="/static/hglogo.png" alt="mercurial" /></a>
318 <img src="/static/hglogo.png" alt="mercurial" /></a>
319 </div>
319 </div>
320 <ul>
320 <ul>
321 <li><a href="/shortlog/0cd96de13884">log</a></li>
321 <li><a href="/shortlog/0cd96de13884">log</a></li>
322 <li><a href="/graph/0cd96de13884">graph</a></li>
322 <li><a href="/graph/0cd96de13884">graph</a></li>
323 <li><a href="/tags">tags</a></li>
323 <li><a href="/tags">tags</a></li>
324 <li><a href="/bookmarks">bookmarks</a></li>
324 <li><a href="/bookmarks">bookmarks</a></li>
325 <li><a href="/branches">branches</a></li>
325 <li><a href="/branches">branches</a></li>
326 </ul>
326 </ul>
327 <ul>
327 <ul>
328 <li class="active">changeset</li>
328 <li class="active">changeset</li>
329 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
329 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
330 <li><a href="/file/0cd96de13884">browse</a></li>
330 <li><a href="/file/0cd96de13884">browse</a></li>
331 </ul>
331 </ul>
332 <ul>
332 <ul>
333
333
334 </ul>
334 </ul>
335 <ul>
335 <ul>
336 <li><a href="/help">help</a></li>
336 <li><a href="/help">help</a></li>
337 </ul>
337 </ul>
338 </div>
338 </div>
339
339
340 <div class="main">
340 <div class="main">
341
341
342 <h2><a href="/">test</a></h2>
342 <h2><a href="/">test</a></h2>
343 <h3>changeset 0:0cd96de13884 </h3>
343 <h3>changeset 0:0cd96de13884 </h3>
344
344
345 <form class="search" action="/log">
345 <form class="search" action="/log">
346
346
347 <p><input name="rev" id="search1" type="text" size="30" /></p>
347 <p><input name="rev" id="search1" type="text" size="30" /></p>
348 <div id="hint">find changesets by author, revision,
348 <div id="hint">find changesets by author, revision,
349 files, or words in the commit message</div>
349 files, or words in the commit message</div>
350 </form>
350 </form>
351
351
352 <div class="description">a</div>
352 <div class="description">a</div>
353
353
354 <table id="changesetEntry">
354 <table id="changesetEntry">
355 <tr>
355 <tr>
356 <th class="author">author</th>
356 <th class="author">author</th>
357 <td class="author">&#116;&#101;&#115;&#116;</td>
357 <td class="author">&#116;&#101;&#115;&#116;</td>
358 </tr>
358 </tr>
359 <tr>
359 <tr>
360 <th class="date">date</th>
360 <th class="date">date</th>
361 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
361 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
362 <tr>
362 <tr>
363 <th class="author">parents</th>
363 <th class="author">parents</th>
364 <td class="author"></td>
364 <td class="author"></td>
365 </tr>
365 </tr>
366 <tr>
366 <tr>
367 <th class="author">children</th>
367 <th class="author">children</th>
368 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
368 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
369 </tr>
369 </tr>
370 <tr>
370 <tr>
371 <th class="files">files</th>
371 <th class="files">files</th>
372 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
372 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
373 </tr>
373 </tr>
374 <tr>
374 <tr>
375 <th class="diffstat">diffstat</th>
375 <th class="diffstat">diffstat</th>
376 <td class="diffstat">
376 <td class="diffstat">
377 2 files changed, 2 insertions(+), 0 deletions(-)
377 2 files changed, 2 insertions(+), 0 deletions(-)
378
378
379 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
379 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
380 <div id="diffstatdetails" style="display:none;">
380 <div id="diffstatdetails" style="display:none;">
381 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
381 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
382 <p>
382 <p>
383 <table> <tr class="parity0">
383 <table> <tr class="parity0">
384 <td class="diffstat-file"><a href="#l1.1">a</a></td>
384 <td class="diffstat-file"><a href="#l1.1">a</a></td>
385 <td class="diffstat-total" align="right">1</td>
385 <td class="diffstat-total" align="right">1</td>
386 <td class="diffstat-graph">
386 <td class="diffstat-graph">
387 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
387 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
388 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
388 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
389 </td>
389 </td>
390 </tr>
390 </tr>
391 <tr class="parity1">
391 <tr class="parity1">
392 <td class="diffstat-file"><a href="#l2.1">b</a></td>
392 <td class="diffstat-file"><a href="#l2.1">b</a></td>
393 <td class="diffstat-total" align="right">1</td>
393 <td class="diffstat-total" align="right">1</td>
394 <td class="diffstat-graph">
394 <td class="diffstat-graph">
395 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
395 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
396 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
396 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
397 </td>
397 </td>
398 </tr>
398 </tr>
399 </table>
399 </table>
400 </div>
400 </div>
401 </td>
401 </td>
402 </tr>
402 </tr>
403 </table>
403 </table>
404
404
405 <div class="overflow">
405 <div class="overflow">
406 <div class="sourcefirst"> line diff</div>
406 <div class="sourcefirst"> line diff</div>
407
407
408 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> new file mode 100644
408 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> new file mode 100644
409 <a href="#l1.2" id="l1.2"> 1.2</a> <span class="minusline">--- /dev/null
409 <a href="#l1.2" id="l1.2"> 1.2</a> <span class="minusline">--- /dev/null
410 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="plusline">+++ b/a
410 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="plusline">+++ b/a
411 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="atline">@@ -0,0 +1,1 @@
411 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="atline">@@ -0,0 +1,1 @@
412 </span><a href="#l1.5" id="l1.5"> 1.5</a> <span class="plusline">+a
412 </span><a href="#l1.5" id="l1.5"> 1.5</a> <span class="plusline">+a
413 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> new file mode 100644
413 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> new file mode 100644
414 <a href="#l2.2" id="l2.2"> 2.2</a> <span class="minusline">--- /dev/null
414 <a href="#l2.2" id="l2.2"> 2.2</a> <span class="minusline">--- /dev/null
415 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="plusline">+++ b/b
415 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="plusline">+++ b/b
416 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="atline">@@ -0,0 +1,1 @@
416 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="atline">@@ -0,0 +1,1 @@
417 </span><a href="#l2.5" id="l2.5"> 2.5</a> <span class="plusline">+b
417 </span><a href="#l2.5" id="l2.5"> 2.5</a> <span class="plusline">+b
418 </span></pre></div>
418 </span></pre></div>
419 </div>
419 </div>
420
420
421 </div>
421 </div>
422 </div>
422 </div>
423 <script type="text/javascript">process_dates()</script>
423 <script type="text/javascript">process_dates()</script>
424
424
425
425
426 </body>
426 </body>
427 </html>
427 </html>
428
428
429
429
430 revision
430 revision
431
431
432 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
432 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
433 200 Script output follows
433 200 Script output follows
434
434
435
435
436 # HG changeset patch
436 # HG changeset patch
437 # User test
437 # User test
438 # Date 0 0
438 # Date 0 0
439 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
439 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
440
440
441 a
441 a
442
442
443 diff --git a/a b/a
443 diff --git a/a b/a
444 new file mode 100644
444 new file mode 100644
445 --- /dev/null
445 --- /dev/null
446 +++ b/a
446 +++ b/a
447 @@ -0,0 +1,1 @@
447 @@ -0,0 +1,1 @@
448 +a
448 +a
449 diff --git a/b b/b
449 diff --git a/b b/b
450 new file mode 100644
450 new file mode 100644
451 --- /dev/null
451 --- /dev/null
452 +++ b/b
452 +++ b/b
453 @@ -0,0 +1,1 @@
453 @@ -0,0 +1,1 @@
454 +b
454 +b
455
455
456
456
457 diff removed file
457 diff removed file
458
458
459 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/a'
459 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/a'
460 200 Script output follows
460 200 Script output follows
461
461
462 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
462 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
463 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
463 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
464 <head>
464 <head>
465 <link rel="icon" href="/static/hgicon.png" type="image/png" />
465 <link rel="icon" href="/static/hgicon.png" type="image/png" />
466 <meta name="robots" content="index, nofollow" />
466 <meta name="robots" content="index, nofollow" />
467 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
467 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
468 <script type="text/javascript" src="/static/mercurial.js"></script>
468 <script type="text/javascript" src="/static/mercurial.js"></script>
469
469
470 <title>test: a diff</title>
470 <title>test: a diff</title>
471 </head>
471 </head>
472 <body>
472 <body>
473
473
474 <div class="container">
474 <div class="container">
475 <div class="menu">
475 <div class="menu">
476 <div class="logo">
476 <div class="logo">
477 <a href="http://mercurial.selenic.com/">
477 <a href="http://mercurial.selenic.com/">
478 <img src="/static/hglogo.png" alt="mercurial" /></a>
478 <img src="/static/hglogo.png" alt="mercurial" /></a>
479 </div>
479 </div>
480 <ul>
480 <ul>
481 <li><a href="/shortlog/559edbd9ed20">log</a></li>
481 <li><a href="/shortlog/559edbd9ed20">log</a></li>
482 <li><a href="/graph/559edbd9ed20">graph</a></li>
482 <li><a href="/graph/559edbd9ed20">graph</a></li>
483 <li><a href="/tags">tags</a></li>
483 <li><a href="/tags">tags</a></li>
484 <li><a href="/bookmarks">bookmarks</a></li>
484 <li><a href="/bookmarks">bookmarks</a></li>
485 <li><a href="/branches">branches</a></li>
485 <li><a href="/branches">branches</a></li>
486 </ul>
486 </ul>
487 <ul>
487 <ul>
488 <li><a href="/rev/559edbd9ed20">changeset</a></li>
488 <li><a href="/rev/559edbd9ed20">changeset</a></li>
489 <li><a href="/file/559edbd9ed20">browse</a></li>
489 <li><a href="/file/559edbd9ed20">browse</a></li>
490 </ul>
490 </ul>
491 <ul>
491 <ul>
492 <li><a href="/file/559edbd9ed20/a">file</a></li>
492 <li><a href="/file/559edbd9ed20/a">file</a></li>
493 <li><a href="/file/tip/a">latest</a></li>
493 <li><a href="/file/tip/a">latest</a></li>
494 <li class="active">diff</li>
494 <li class="active">diff</li>
495 <li><a href="/comparison/559edbd9ed20/a">comparison</a></li>
495 <li><a href="/comparison/559edbd9ed20/a">comparison</a></li>
496 <li><a href="/annotate/559edbd9ed20/a">annotate</a></li>
496 <li><a href="/annotate/559edbd9ed20/a">annotate</a></li>
497 <li><a href="/log/559edbd9ed20/a">file log</a></li>
497 <li><a href="/log/559edbd9ed20/a">file log</a></li>
498 <li><a href="/raw-file/559edbd9ed20/a">raw</a></li>
498 <li><a href="/raw-file/559edbd9ed20/a">raw</a></li>
499 </ul>
499 </ul>
500 <ul>
500 <ul>
501 <li><a href="/help">help</a></li>
501 <li><a href="/help">help</a></li>
502 </ul>
502 </ul>
503 </div>
503 </div>
504
504
505 <div class="main">
505 <div class="main">
506 <h2><a href="/">test</a></h2>
506 <h2><a href="/">test</a></h2>
507 <h3>diff a @ 1:559edbd9ed20</h3>
507 <h3>diff a @ 1:559edbd9ed20</h3>
508
508
509 <form class="search" action="/log">
509 <form class="search" action="/log">
510 <p></p>
510 <p></p>
511 <p><input name="rev" id="search1" type="text" size="30" /></p>
511 <p><input name="rev" id="search1" type="text" size="30" /></p>
512 <div id="hint">find changesets by author, revision,
512 <div id="hint">find changesets by author, revision,
513 files, or words in the commit message</div>
513 files, or words in the commit message</div>
514 </form>
514 </form>
515
515
516 <div class="description">b</div>
516 <div class="description">b</div>
517
517
518 <table id="changesetEntry">
518 <table id="changesetEntry">
519 <tr>
519 <tr>
520 <th>author</th>
520 <th>author</th>
521 <td>&#116;&#101;&#115;&#116;</td>
521 <td>&#116;&#101;&#115;&#116;</td>
522 </tr>
522 </tr>
523 <tr>
523 <tr>
524 <th>date</th>
524 <th>date</th>
525 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
525 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
526 </tr>
526 </tr>
527 <tr>
527 <tr>
528 <th>parents</th>
528 <th>parents</th>
529 <td></td>
529 <td></td>
530 </tr>
530 </tr>
531 <tr>
531 <tr>
532 <th>children</th>
532 <th>children</th>
533 <td></td>
533 <td></td>
534 </tr>
534 </tr>
535
535
536 </table>
536 </table>
537
537
538 <div class="overflow">
538 <div class="overflow">
539 <div class="sourcefirst"> line diff</div>
539 <div class="sourcefirst"> line diff</div>
540
540
541 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> old mode 100644
541 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> old mode 100644
542 <a href="#l1.2" id="l1.2"> 1.2</a> new mode 100755
542 <a href="#l1.2" id="l1.2"> 1.2</a> new mode 100755
543 </pre></div>
543 </pre></div>
544 </div>
544 </div>
545 </div>
545 </div>
546 </div>
546 </div>
547
547
548 <script type="text/javascript">process_dates()</script>
548 <script type="text/javascript">process_dates()</script>
549
549
550
550
551 </body>
551 </body>
552 </html>
552 </html>
553
553
554
554
555 comparison new file
555 comparison new file
556
556
557 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/0/a'
557 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/0/a'
558 200 Script output follows
558 200 Script output follows
559
559
560 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
560 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
561 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
561 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
562 <head>
562 <head>
563 <link rel="icon" href="/static/hgicon.png" type="image/png" />
563 <link rel="icon" href="/static/hgicon.png" type="image/png" />
564 <meta name="robots" content="index, nofollow" />
564 <meta name="robots" content="index, nofollow" />
565 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
565 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
566 <script type="text/javascript" src="/static/mercurial.js"></script>
566 <script type="text/javascript" src="/static/mercurial.js"></script>
567
567
568 <title>test: a comparison</title>
568 <title>test: a comparison</title>
569 </head>
569 </head>
570 <body>
570 <body>
571
571
572 <div class="container">
572 <div class="container">
573 <div class="menu">
573 <div class="menu">
574 <div class="logo">
574 <div class="logo">
575 <a href="http://mercurial.selenic.com/">
575 <a href="http://mercurial.selenic.com/">
576 <img src="/static/hglogo.png" alt="mercurial" /></a>
576 <img src="/static/hglogo.png" alt="mercurial" /></a>
577 </div>
577 </div>
578 <ul>
578 <ul>
579 <li><a href="/shortlog/0cd96de13884">log</a></li>
579 <li><a href="/shortlog/0cd96de13884">log</a></li>
580 <li><a href="/graph/0cd96de13884">graph</a></li>
580 <li><a href="/graph/0cd96de13884">graph</a></li>
581 <li><a href="/tags">tags</a></li>
581 <li><a href="/tags">tags</a></li>
582 <li><a href="/bookmarks">bookmarks</a></li>
582 <li><a href="/bookmarks">bookmarks</a></li>
583 <li><a href="/branches">branches</a></li>
583 <li><a href="/branches">branches</a></li>
584 </ul>
584 </ul>
585 <ul>
585 <ul>
586 <li><a href="/rev/0cd96de13884">changeset</a></li>
586 <li><a href="/rev/0cd96de13884">changeset</a></li>
587 <li><a href="/file/0cd96de13884">browse</a></li>
587 <li><a href="/file/0cd96de13884">browse</a></li>
588 </ul>
588 </ul>
589 <ul>
589 <ul>
590 <li><a href="/file/0cd96de13884/a">file</a></li>
590 <li><a href="/file/0cd96de13884/a">file</a></li>
591 <li><a href="/file/tip/a">latest</a></li>
591 <li><a href="/file/tip/a">latest</a></li>
592 <li><a href="/diff/0cd96de13884/a">diff</a></li>
592 <li><a href="/diff/0cd96de13884/a">diff</a></li>
593 <li class="active">comparison</li>
593 <li class="active">comparison</li>
594 <li><a href="/annotate/0cd96de13884/a">annotate</a></li>
594 <li><a href="/annotate/0cd96de13884/a">annotate</a></li>
595 <li><a href="/log/0cd96de13884/a">file log</a></li>
595 <li><a href="/log/0cd96de13884/a">file log</a></li>
596 <li><a href="/raw-file/0cd96de13884/a">raw</a></li>
596 <li><a href="/raw-file/0cd96de13884/a">raw</a></li>
597 </ul>
597 </ul>
598 <ul>
598 <ul>
599 <li><a href="/help">help</a></li>
599 <li><a href="/help">help</a></li>
600 </ul>
600 </ul>
601 </div>
601 </div>
602
602
603 <div class="main">
603 <div class="main">
604 <h2><a href="/">test</a></h2>
604 <h2><a href="/">test</a></h2>
605 <h3>comparison a @ 0:0cd96de13884</h3>
605 <h3>comparison a @ 0:0cd96de13884</h3>
606
606
607 <form class="search" action="/log">
607 <form class="search" action="/log">
608 <p></p>
608 <p></p>
609 <p><input name="rev" id="search1" type="text" size="30" /></p>
609 <p><input name="rev" id="search1" type="text" size="30" /></p>
610 <div id="hint">find changesets by author, revision,
610 <div id="hint">find changesets by author, revision,
611 files, or words in the commit message</div>
611 files, or words in the commit message</div>
612 </form>
612 </form>
613
613
614 <div class="description">a</div>
614 <div class="description">a</div>
615
615
616 <table id="changesetEntry">
616 <table id="changesetEntry">
617 <tr>
617 <tr>
618 <th>author</th>
618 <th>author</th>
619 <td>&#116;&#101;&#115;&#116;</td>
619 <td>&#116;&#101;&#115;&#116;</td>
620 </tr>
620 </tr>
621 <tr>
621 <tr>
622 <th>date</th>
622 <th>date</th>
623 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
623 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
624 </tr>
624 </tr>
625 <tr>
625 <tr>
626 <th>parents</th>
626 <th>parents</th>
627 <td></td>
627 <td></td>
628 </tr>
628 </tr>
629 <tr>
629 <tr>
630 <th>children</th>
630 <th>children</th>
631 <td><a href="/file/559edbd9ed20/a">559edbd9ed20</a> </td>
631 <td><a href="/file/559edbd9ed20/a">559edbd9ed20</a> </td>
632 </tr>
632 </tr>
633
633
634 </table>
634 </table>
635
635
636 <div class="overflow">
636 <div class="overflow">
637 <div class="sourcefirst"> comparison</div>
637 <div class="sourcefirst"> comparison</div>
638 <div class="legend">
638 <div class="legend">
639 <span class="legendinfo equal">equal</span>
639 <span class="legendinfo equal">equal</span>
640 <span class="legendinfo delete">deleted</span>
640 <span class="legendinfo delete">deleted</span>
641 <span class="legendinfo insert">inserted</span>
641 <span class="legendinfo insert">inserted</span>
642 <span class="legendinfo replace">replaced</span>
642 <span class="legendinfo replace">replaced</span>
643 </div>
643 </div>
644
644
645
646 <table class="bigtable">
645 <table class="bigtable">
647 <thead class="header">
646 <thead class="header">
648 <tr>
647 <tr>
649 <th>-1:000000000000</th>
648 <th>-1:000000000000</th>
650 <th>0:b789fdd96dc2</th>
649 <th>0:b789fdd96dc2</th>
651 </tr>
650 </tr>
652 </thead>
651 </thead>
653
652
654 <tbody class="block">
653 <tbody class="block">
655
654
656 <tr>
655 <tr>
657 <td class="source insert"><a href="#r1" id="r1"> </a> </td>
656 <td class="source insert"><a href="#r1" id="r1"> </a> </td>
658 <td class="source insert"><a href="#r1" id="r1"> 1</a> a</td>
657 <td class="source insert"><a href="#r1" id="r1"> 1</a> a</td>
659 </tr>
658 </tr>
660 </tbody>
659 </tbody>
661 </table>
660 </table>
662
661
663 </div>
662 </div>
664 </div>
663 </div>
665 </div>
664 </div>
666
665
667 <script type="text/javascript">process_dates()</script>
666 <script type="text/javascript">process_dates()</script>
668
667
669
668
670 </body>
669 </body>
671 </html>
670 </html>
672
671
673
672
674 comparison existing file
673 comparison existing file
675
674
676 $ hg up
675 $ hg up
677 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
676 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
678 $ echo a >> a
677 $ echo a >> a
679 $ hg ci -mc
678 $ hg ci -mc
680 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
679 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
681 200 Script output follows
680 200 Script output follows
682
681
683 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
682 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
684 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
683 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
685 <head>
684 <head>
686 <link rel="icon" href="/static/hgicon.png" type="image/png" />
685 <link rel="icon" href="/static/hgicon.png" type="image/png" />
687 <meta name="robots" content="index, nofollow" />
686 <meta name="robots" content="index, nofollow" />
688 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
687 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
689 <script type="text/javascript" src="/static/mercurial.js"></script>
688 <script type="text/javascript" src="/static/mercurial.js"></script>
690
689
691 <title>test: a comparison</title>
690 <title>test: a comparison</title>
692 </head>
691 </head>
693 <body>
692 <body>
694
693
695 <div class="container">
694 <div class="container">
696 <div class="menu">
695 <div class="menu">
697 <div class="logo">
696 <div class="logo">
698 <a href="http://mercurial.selenic.com/">
697 <a href="http://mercurial.selenic.com/">
699 <img src="/static/hglogo.png" alt="mercurial" /></a>
698 <img src="/static/hglogo.png" alt="mercurial" /></a>
700 </div>
699 </div>
701 <ul>
700 <ul>
702 <li><a href="/shortlog/d73db4d812ff">log</a></li>
701 <li><a href="/shortlog/d73db4d812ff">log</a></li>
703 <li><a href="/graph/d73db4d812ff">graph</a></li>
702 <li><a href="/graph/d73db4d812ff">graph</a></li>
704 <li><a href="/tags">tags</a></li>
703 <li><a href="/tags">tags</a></li>
705 <li><a href="/bookmarks">bookmarks</a></li>
704 <li><a href="/bookmarks">bookmarks</a></li>
706 <li><a href="/branches">branches</a></li>
705 <li><a href="/branches">branches</a></li>
707 </ul>
706 </ul>
708 <ul>
707 <ul>
709 <li><a href="/rev/d73db4d812ff">changeset</a></li>
708 <li><a href="/rev/d73db4d812ff">changeset</a></li>
710 <li><a href="/file/d73db4d812ff">browse</a></li>
709 <li><a href="/file/d73db4d812ff">browse</a></li>
711 </ul>
710 </ul>
712 <ul>
711 <ul>
713 <li><a href="/file/d73db4d812ff/a">file</a></li>
712 <li><a href="/file/d73db4d812ff/a">file</a></li>
714 <li><a href="/file/tip/a">latest</a></li>
713 <li><a href="/file/tip/a">latest</a></li>
715 <li><a href="/diff/d73db4d812ff/a">diff</a></li>
714 <li><a href="/diff/d73db4d812ff/a">diff</a></li>
716 <li class="active">comparison</li>
715 <li class="active">comparison</li>
717 <li><a href="/annotate/d73db4d812ff/a">annotate</a></li>
716 <li><a href="/annotate/d73db4d812ff/a">annotate</a></li>
718 <li><a href="/log/d73db4d812ff/a">file log</a></li>
717 <li><a href="/log/d73db4d812ff/a">file log</a></li>
719 <li><a href="/raw-file/d73db4d812ff/a">raw</a></li>
718 <li><a href="/raw-file/d73db4d812ff/a">raw</a></li>
720 </ul>
719 </ul>
721 <ul>
720 <ul>
722 <li><a href="/help">help</a></li>
721 <li><a href="/help">help</a></li>
723 </ul>
722 </ul>
724 </div>
723 </div>
725
724
726 <div class="main">
725 <div class="main">
727 <h2><a href="/">test</a></h2>
726 <h2><a href="/">test</a></h2>
728 <h3>comparison a @ 2:d73db4d812ff</h3>
727 <h3>comparison a @ 2:d73db4d812ff</h3>
729
728
730 <form class="search" action="/log">
729 <form class="search" action="/log">
731 <p></p>
730 <p></p>
732 <p><input name="rev" id="search1" type="text" size="30" /></p>
731 <p><input name="rev" id="search1" type="text" size="30" /></p>
733 <div id="hint">find changesets by author, revision,
732 <div id="hint">find changesets by author, revision,
734 files, or words in the commit message</div>
733 files, or words in the commit message</div>
735 </form>
734 </form>
736
735
737 <div class="description">c</div>
736 <div class="description">c</div>
738
737
739 <table id="changesetEntry">
738 <table id="changesetEntry">
740 <tr>
739 <tr>
741 <th>author</th>
740 <th>author</th>
742 <td>&#116;&#101;&#115;&#116;</td>
741 <td>&#116;&#101;&#115;&#116;</td>
743 </tr>
742 </tr>
744 <tr>
743 <tr>
745 <th>date</th>
744 <th>date</th>
746 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
745 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
747 </tr>
746 </tr>
748 <tr>
747 <tr>
749 <th>parents</th>
748 <th>parents</th>
750 <td><a href="/file/559edbd9ed20/a">559edbd9ed20</a> </td>
749 <td><a href="/file/559edbd9ed20/a">559edbd9ed20</a> </td>
751 </tr>
750 </tr>
752 <tr>
751 <tr>
753 <th>children</th>
752 <th>children</th>
754 <td></td>
753 <td></td>
755 </tr>
754 </tr>
756
755
757 </table>
756 </table>
758
757
759 <div class="overflow">
758 <div class="overflow">
760 <div class="sourcefirst"> comparison</div>
759 <div class="sourcefirst"> comparison</div>
761 <div class="legend">
760 <div class="legend">
762 <span class="legendinfo equal">equal</span>
761 <span class="legendinfo equal">equal</span>
763 <span class="legendinfo delete">deleted</span>
762 <span class="legendinfo delete">deleted</span>
764 <span class="legendinfo insert">inserted</span>
763 <span class="legendinfo insert">inserted</span>
765 <span class="legendinfo replace">replaced</span>
764 <span class="legendinfo replace">replaced</span>
766 </div>
765 </div>
767
766
768
769 <table class="bigtable">
767 <table class="bigtable">
770 <thead class="header">
768 <thead class="header">
771 <tr>
769 <tr>
772 <th>0:b789fdd96dc2</th>
770 <th>0:b789fdd96dc2</th>
773 <th>1:a80d06849b33</th>
771 <th>1:a80d06849b33</th>
774 </tr>
772 </tr>
775 </thead>
773 </thead>
776
774
777 <tbody class="block">
775 <tbody class="block">
778
776
779 <tr>
777 <tr>
780 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
778 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
781 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
779 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
782 </tr>
780 </tr>
783 <tr>
781 <tr>
784 <td class="source insert"><a href="#r2" id="r2"> </a> </td>
782 <td class="source insert"><a href="#r2" id="r2"> </a> </td>
785 <td class="source insert"><a href="#r2" id="r2"> 2</a> a</td>
783 <td class="source insert"><a href="#r2" id="r2"> 2</a> a</td>
786 </tr>
784 </tr>
787 </tbody>
785 </tbody>
788 </table>
786 </table>
789
787
790 </div>
788 </div>
791 </div>
789 </div>
792 </div>
790 </div>
793
791
794 <script type="text/javascript">process_dates()</script>
792 <script type="text/javascript">process_dates()</script>
795
793
796
794
797 </body>
795 </body>
798 </html>
796 </html>
799
797
800
798
801 comparison removed file
799 comparison removed file
802
800
803 $ hg rm a
801 $ hg rm a
804 $ hg ci -md
802 $ hg ci -md
805 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
803 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
806 200 Script output follows
804 200 Script output follows
807
805
808 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
806 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
809 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
807 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
810 <head>
808 <head>
811 <link rel="icon" href="/static/hgicon.png" type="image/png" />
809 <link rel="icon" href="/static/hgicon.png" type="image/png" />
812 <meta name="robots" content="index, nofollow" />
810 <meta name="robots" content="index, nofollow" />
813 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
811 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
814 <script type="text/javascript" src="/static/mercurial.js"></script>
812 <script type="text/javascript" src="/static/mercurial.js"></script>
815
813
816 <title>test: a comparison</title>
814 <title>test: a comparison</title>
817 </head>
815 </head>
818 <body>
816 <body>
819
817
820 <div class="container">
818 <div class="container">
821 <div class="menu">
819 <div class="menu">
822 <div class="logo">
820 <div class="logo">
823 <a href="http://mercurial.selenic.com/">
821 <a href="http://mercurial.selenic.com/">
824 <img src="/static/hglogo.png" alt="mercurial" /></a>
822 <img src="/static/hglogo.png" alt="mercurial" /></a>
825 </div>
823 </div>
826 <ul>
824 <ul>
827 <li><a href="/shortlog/20e80271eb7a">log</a></li>
825 <li><a href="/shortlog/20e80271eb7a">log</a></li>
828 <li><a href="/graph/20e80271eb7a">graph</a></li>
826 <li><a href="/graph/20e80271eb7a">graph</a></li>
829 <li><a href="/tags">tags</a></li>
827 <li><a href="/tags">tags</a></li>
830 <li><a href="/bookmarks">bookmarks</a></li>
828 <li><a href="/bookmarks">bookmarks</a></li>
831 <li><a href="/branches">branches</a></li>
829 <li><a href="/branches">branches</a></li>
832 </ul>
830 </ul>
833 <ul>
831 <ul>
834 <li><a href="/rev/20e80271eb7a">changeset</a></li>
832 <li><a href="/rev/20e80271eb7a">changeset</a></li>
835 <li><a href="/file/20e80271eb7a">browse</a></li>
833 <li><a href="/file/20e80271eb7a">browse</a></li>
836 </ul>
834 </ul>
837 <ul>
835 <ul>
838 <li><a href="/file/20e80271eb7a/a">file</a></li>
836 <li><a href="/file/20e80271eb7a/a">file</a></li>
839 <li><a href="/file/tip/a">latest</a></li>
837 <li><a href="/file/tip/a">latest</a></li>
840 <li><a href="/diff/20e80271eb7a/a">diff</a></li>
838 <li><a href="/diff/20e80271eb7a/a">diff</a></li>
841 <li class="active">comparison</li>
839 <li class="active">comparison</li>
842 <li><a href="/annotate/20e80271eb7a/a">annotate</a></li>
840 <li><a href="/annotate/20e80271eb7a/a">annotate</a></li>
843 <li><a href="/log/20e80271eb7a/a">file log</a></li>
841 <li><a href="/log/20e80271eb7a/a">file log</a></li>
844 <li><a href="/raw-file/20e80271eb7a/a">raw</a></li>
842 <li><a href="/raw-file/20e80271eb7a/a">raw</a></li>
845 </ul>
843 </ul>
846 <ul>
844 <ul>
847 <li><a href="/help">help</a></li>
845 <li><a href="/help">help</a></li>
848 </ul>
846 </ul>
849 </div>
847 </div>
850
848
851 <div class="main">
849 <div class="main">
852 <h2><a href="/">test</a></h2>
850 <h2><a href="/">test</a></h2>
853 <h3>comparison a @ 3:20e80271eb7a</h3>
851 <h3>comparison a @ 3:20e80271eb7a</h3>
854
852
855 <form class="search" action="/log">
853 <form class="search" action="/log">
856 <p></p>
854 <p></p>
857 <p><input name="rev" id="search1" type="text" size="30" /></p>
855 <p><input name="rev" id="search1" type="text" size="30" /></p>
858 <div id="hint">find changesets by author, revision,
856 <div id="hint">find changesets by author, revision,
859 files, or words in the commit message</div>
857 files, or words in the commit message</div>
860 </form>
858 </form>
861
859
862 <div class="description">d</div>
860 <div class="description">d</div>
863
861
864 <table id="changesetEntry">
862 <table id="changesetEntry">
865 <tr>
863 <tr>
866 <th>author</th>
864 <th>author</th>
867 <td>&#116;&#101;&#115;&#116;</td>
865 <td>&#116;&#101;&#115;&#116;</td>
868 </tr>
866 </tr>
869 <tr>
867 <tr>
870 <th>date</th>
868 <th>date</th>
871 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
869 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
872 </tr>
870 </tr>
873 <tr>
871 <tr>
874 <th>parents</th>
872 <th>parents</th>
875 <td><a href="/file/d73db4d812ff/a">d73db4d812ff</a> </td>
873 <td><a href="/file/d73db4d812ff/a">d73db4d812ff</a> </td>
876 </tr>
874 </tr>
877 <tr>
875 <tr>
878 <th>children</th>
876 <th>children</th>
879 <td></td>
877 <td></td>
880 </tr>
878 </tr>
881
879
882 </table>
880 </table>
883
881
884 <div class="overflow">
882 <div class="overflow">
885 <div class="sourcefirst"> comparison</div>
883 <div class="sourcefirst"> comparison</div>
886 <div class="legend">
884 <div class="legend">
887 <span class="legendinfo equal">equal</span>
885 <span class="legendinfo equal">equal</span>
888 <span class="legendinfo delete">deleted</span>
886 <span class="legendinfo delete">deleted</span>
889 <span class="legendinfo insert">inserted</span>
887 <span class="legendinfo insert">inserted</span>
890 <span class="legendinfo replace">replaced</span>
888 <span class="legendinfo replace">replaced</span>
891 </div>
889 </div>
892
890
893
894 <table class="bigtable">
891 <table class="bigtable">
895 <thead class="header">
892 <thead class="header">
896 <tr>
893 <tr>
897 <th>1:a80d06849b33</th>
894 <th>1:a80d06849b33</th>
898 <th>-1:000000000000</th>
895 <th>-1:000000000000</th>
899 </tr>
896 </tr>
900 </thead>
897 </thead>
901
898
902 <tbody class="block">
899 <tbody class="block">
903
900
904 <tr>
901 <tr>
905 <td class="source delete"><a href="#l1" id="l1"> 1</a> a</td>
902 <td class="source delete"><a href="#l1" id="l1"> 1</a> a</td>
906 <td class="source delete"><a href="#l1" id="l1"> </a> </td>
903 <td class="source delete"><a href="#l1" id="l1"> </a> </td>
907 </tr>
904 </tr>
908 <tr>
905 <tr>
909 <td class="source delete"><a href="#l2" id="l2"> 2</a> a</td>
906 <td class="source delete"><a href="#l2" id="l2"> 2</a> a</td>
910 <td class="source delete"><a href="#l2" id="l2"> </a> </td>
907 <td class="source delete"><a href="#l2" id="l2"> </a> </td>
911 </tr>
908 </tr>
912 </tbody>
909 </tbody>
913 </table>
910 </table>
914
911
915 </div>
912 </div>
916 </div>
913 </div>
917 </div>
914 </div>
918
915
919 <script type="text/javascript">process_dates()</script>
916 <script type="text/javascript">process_dates()</script>
920
917
921
918
922 </body>
919 </body>
923 </html>
920 </html>
924
921
925
922
926 $ cd ..
923 $ cd ..
927
924
928 test import rev as raw-rev
925 test import rev as raw-rev
929
926
930 $ hg clone -r0 test test1
927 $ hg clone -r0 test test1
931 adding changesets
928 adding changesets
932 adding manifests
929 adding manifests
933 adding file changes
930 adding file changes
934 added 1 changesets with 2 changes to 2 files
931 added 1 changesets with 2 changes to 2 files
935 updating to branch default
932 updating to branch default
936 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
933 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
937 $ cd test1
934 $ cd test1
938 $ hg import -q --bypass --exact http://localhost:$HGPORT/rev/1
935 $ hg import -q --bypass --exact http://localhost:$HGPORT/rev/1
939
936
940 raw revision with diff block numbers
937 raw revision with diff block numbers
941
938
942 $ "$TESTDIR/killdaemons.py"
939 $ "$TESTDIR/killdaemons.py"
943 $ cat <<EOF > .hg/hgrc
940 $ cat <<EOF > .hg/hgrc
944 > [web]
941 > [web]
945 > templates = rawdiff
942 > templates = rawdiff
946 > EOF
943 > EOF
947 $ mkdir rawdiff
944 $ mkdir rawdiff
948 $ cat <<EOF > rawdiff/map
945 $ cat <<EOF > rawdiff/map
949 > mimetype = 'text/plain; charset={encoding}'
946 > mimetype = 'text/plain; charset={encoding}'
950 > changeset = '{diff}'
947 > changeset = '{diff}'
951 > difflineplus = '{line}'
948 > difflineplus = '{line}'
952 > difflineminus = '{line}'
949 > difflineminus = '{line}'
953 > difflineat = '{line}'
950 > difflineat = '{line}'
954 > diffline = '{line}'
951 > diffline = '{line}'
955 > filenodelink = ''
952 > filenodelink = ''
956 > filenolink = ''
953 > filenolink = ''
957 > fileline = '{line}'
954 > fileline = '{line}'
958 > diffblock = 'Block: {blockno}\n{lines}\n'
955 > diffblock = 'Block: {blockno}\n{lines}\n'
959 > EOF
956 > EOF
960 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
957 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
961 $ cat hg.pid >> $DAEMON_PIDS
958 $ cat hg.pid >> $DAEMON_PIDS
962 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
959 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
963 200 Script output follows
960 200 Script output follows
964
961
965 Block: 1
962 Block: 1
966 diff -r 000000000000 -r 0cd96de13884 a
963 diff -r 000000000000 -r 0cd96de13884 a
967 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
964 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
968 +++ b/a Thu Jan 01 00:00:00 1970 +0000
965 +++ b/a Thu Jan 01 00:00:00 1970 +0000
969 @@ -0,0 +1,1 @@
966 @@ -0,0 +1,1 @@
970 +a
967 +a
971
968
972 Block: 2
969 Block: 2
973 diff -r 000000000000 -r 0cd96de13884 b
970 diff -r 000000000000 -r 0cd96de13884 b
974 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
971 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
975 +++ b/b Thu Jan 01 00:00:00 1970 +0000
972 +++ b/b Thu Jan 01 00:00:00 1970 +0000
976 @@ -0,0 +1,1 @@
973 @@ -0,0 +1,1 @@
977 +b
974 +b
978
975
979 $ "$TESTDIR/killdaemons.py"
976 $ "$TESTDIR/killdaemons.py"
980 $ rm .hg/hgrc rawdiff/map
977 $ rm .hg/hgrc rawdiff/map
981 $ rmdir rawdiff
978 $ rmdir rawdiff
982 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
979 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
983 $ cat hg.pid >> $DAEMON_PIDS
980 $ cat hg.pid >> $DAEMON_PIDS
984
981
985 errors
982 errors
986
983
987 $ cat ../test/errors.log
984 $ cat ../test/errors.log
988
985
989 $ cd ..
986 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now