##// END OF EJS Templates
coal/paper: display tags and branch in filelog page
Benoit Allard -
r7409:0fa3b667 default
parent child Browse files
Show More
@@ -1,657 +1,661 b''
1 1 #
2 2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import os, mimetypes, re, cgi, copy
9 9 import webutil
10 10 from mercurial import revlog, archival, templatefilters
11 11 from mercurial.node import short, hex, nullid
12 12 from mercurial.util import binary, datestr
13 13 from mercurial.repo import RepoError
14 14 from common import paritygen, staticfile, get_contact, ErrorResponse
15 15 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
16 16 from mercurial import graphmod, util
17 17
18 18 # __all__ is populated with the allowed commands. Be sure to add to it if
19 19 # you're adding a new command, or the new command won't work.
20 20
21 21 __all__ = [
22 22 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
23 23 'manifest', 'tags', 'summary', 'filediff', 'diff', 'annotate', 'filelog',
24 24 'archive', 'static', 'graph',
25 25 ]
26 26
27 27 def log(web, req, tmpl):
28 28 if 'file' in req.form and req.form['file'][0]:
29 29 return filelog(web, req, tmpl)
30 30 else:
31 31 return changelog(web, req, tmpl)
32 32
33 33 def rawfile(web, req, tmpl):
34 34 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
35 35 if not path:
36 36 content = manifest(web, req, tmpl)
37 37 req.respond(HTTP_OK, web.ctype)
38 38 return content
39 39
40 40 try:
41 41 fctx = webutil.filectx(web.repo, req)
42 42 except revlog.LookupError, inst:
43 43 try:
44 44 content = manifest(web, req, tmpl)
45 45 req.respond(HTTP_OK, web.ctype)
46 46 return content
47 47 except ErrorResponse:
48 48 raise inst
49 49
50 50 path = fctx.path()
51 51 text = fctx.data()
52 52 mt = mimetypes.guess_type(path)[0]
53 53 if mt is None:
54 54 mt = binary(text) and 'application/octet-stream' or 'text/plain'
55 55
56 56 req.respond(HTTP_OK, mt, path, len(text))
57 57 return [text]
58 58
59 59 def _filerevision(web, tmpl, fctx):
60 60 f = fctx.path()
61 61 text = fctx.data()
62 62 parity = paritygen(web.stripecount)
63 63
64 64 if binary(text):
65 65 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
66 66 text = '(binary:%s)' % mt
67 67
68 68 def lines():
69 69 for lineno, t in enumerate(text.splitlines(1)):
70 70 yield {"line": t,
71 71 "lineid": "l%d" % (lineno + 1),
72 72 "linenumber": "% 6d" % (lineno + 1),
73 73 "parity": parity.next()}
74 74
75 75 return tmpl("filerevision",
76 76 file=f,
77 77 path=webutil.up(f),
78 78 text=lines(),
79 79 rev=fctx.rev(),
80 80 node=hex(fctx.node()),
81 81 author=fctx.user(),
82 82 date=fctx.date(),
83 83 desc=fctx.description(),
84 84 branch=webutil.nodebranchnodefault(fctx),
85 85 parent=webutil.siblings(fctx.parents()),
86 86 child=webutil.siblings(fctx.children()),
87 87 rename=webutil.renamelink(fctx),
88 88 permissions=fctx.manifest().flags(f))
89 89
90 90 def file(web, req, tmpl):
91 91 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
92 92 if not path:
93 93 return manifest(web, req, tmpl)
94 94 try:
95 95 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
96 96 except revlog.LookupError, inst:
97 97 try:
98 98 return manifest(web, req, tmpl)
99 99 except ErrorResponse:
100 100 raise inst
101 101
102 102 def _search(web, tmpl, query):
103 103
104 104 def changelist(**map):
105 105 cl = web.repo.changelog
106 106 count = 0
107 107 qw = query.lower().split()
108 108
109 109 def revgen():
110 110 for i in xrange(len(cl) - 1, 0, -100):
111 111 l = []
112 112 for j in xrange(max(0, i - 100), i + 1):
113 113 ctx = web.repo[j]
114 114 l.append(ctx)
115 115 l.reverse()
116 116 for e in l:
117 117 yield e
118 118
119 119 for ctx in revgen():
120 120 miss = 0
121 121 for q in qw:
122 122 if not (q in ctx.user().lower() or
123 123 q in ctx.description().lower() or
124 124 q in " ".join(ctx.files()).lower()):
125 125 miss = 1
126 126 break
127 127 if miss:
128 128 continue
129 129
130 130 count += 1
131 131 n = ctx.node()
132 132 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
133 133 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
134 134
135 135 yield tmpl('searchentry',
136 136 parity=parity.next(),
137 137 author=ctx.user(),
138 138 parent=webutil.siblings(ctx.parents()),
139 139 child=webutil.siblings(ctx.children()),
140 140 changelogtag=showtags,
141 141 desc=ctx.description(),
142 142 date=ctx.date(),
143 143 files=files,
144 144 rev=ctx.rev(),
145 145 node=hex(n),
146 146 tags=webutil.nodetagsdict(web.repo, n),
147 147 inbranch=webutil.nodeinbranch(web.repo, ctx),
148 148 branches=webutil.nodebranchdict(web.repo, ctx))
149 149
150 150 if count >= web.maxchanges:
151 151 break
152 152
153 153 cl = web.repo.changelog
154 154 parity = paritygen(web.stripecount)
155 155
156 156 return tmpl('search',
157 157 query=query,
158 158 node=hex(cl.tip()),
159 159 entries=changelist,
160 160 archives=web.archivelist("tip"))
161 161
162 162 def changelog(web, req, tmpl, shortlog = False):
163 163 if 'node' in req.form:
164 164 ctx = webutil.changectx(web.repo, req)
165 165 else:
166 166 if 'rev' in req.form:
167 167 hi = req.form['rev'][0]
168 168 else:
169 169 hi = len(web.repo) - 1
170 170 try:
171 171 ctx = web.repo[hi]
172 172 except RepoError:
173 173 return _search(web, tmpl, hi) # XXX redirect to 404 page?
174 174
175 175 def changelist(limit=0, **map):
176 176 cl = web.repo.changelog
177 177 l = [] # build a list in forward order for efficiency
178 178 for i in xrange(start, end):
179 179 ctx = web.repo[i]
180 180 n = ctx.node()
181 181 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
182 182 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
183 183
184 184 l.insert(0, {"parity": parity.next(),
185 185 "author": ctx.user(),
186 186 "parent": webutil.siblings(ctx.parents(), i - 1),
187 187 "child": webutil.siblings(ctx.children(), i + 1),
188 188 "changelogtag": showtags,
189 189 "desc": ctx.description(),
190 190 "date": ctx.date(),
191 191 "files": files,
192 192 "rev": i,
193 193 "node": hex(n),
194 194 "tags": webutil.nodetagsdict(web.repo, n),
195 195 "inbranch": webutil.nodeinbranch(web.repo, ctx),
196 196 "branches": webutil.nodebranchdict(web.repo, ctx)
197 197 })
198 198
199 199 if limit > 0:
200 200 l = l[:limit]
201 201
202 202 for e in l:
203 203 yield e
204 204
205 205 maxchanges = shortlog and web.maxshortchanges or web.maxchanges
206 206 cl = web.repo.changelog
207 207 count = len(cl)
208 208 pos = ctx.rev()
209 209 start = max(0, pos - maxchanges + 1)
210 210 end = min(count, start + maxchanges)
211 211 pos = end - 1
212 212 parity = paritygen(web.stripecount, offset=start-end)
213 213
214 214 changenav = webutil.revnavgen(pos, maxchanges, count, web.repo.changectx)
215 215
216 216 return tmpl(shortlog and 'shortlog' or 'changelog',
217 217 changenav=changenav,
218 218 node=hex(ctx.node()),
219 219 rev=pos, changesets=count,
220 220 entries=lambda **x: changelist(limit=0,**x),
221 221 latestentry=lambda **x: changelist(limit=1,**x),
222 222 archives=web.archivelist("tip"))
223 223
224 224 def shortlog(web, req, tmpl):
225 225 return changelog(web, req, tmpl, shortlog = True)
226 226
227 227 def changeset(web, req, tmpl):
228 228 ctx = webutil.changectx(web.repo, req)
229 229 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
230 230 parents = ctx.parents()
231 231
232 232 files = []
233 233 parity = paritygen(web.stripecount)
234 234 for f in ctx.files():
235 235 template = f in ctx and 'filenodelink' or 'filenolink'
236 236 files.append(tmpl(template,
237 237 node=ctx.hex(), file=f,
238 238 parity=parity.next()))
239 239
240 240 parity = paritygen(web.stripecount)
241 241 diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity)
242 242 return tmpl('changeset',
243 243 diff=diffs,
244 244 rev=ctx.rev(),
245 245 node=ctx.hex(),
246 246 parent=webutil.siblings(parents),
247 247 child=webutil.siblings(ctx.children()),
248 248 changesettag=showtags,
249 249 author=ctx.user(),
250 250 desc=ctx.description(),
251 251 date=ctx.date(),
252 252 files=files,
253 253 archives=web.archivelist(ctx.hex()),
254 254 tags=webutil.nodetagsdict(web.repo, ctx.node()),
255 255 branch=webutil.nodebranchnodefault(ctx),
256 256 inbranch=webutil.nodeinbranch(web.repo, ctx),
257 257 branches=webutil.nodebranchdict(web.repo, ctx))
258 258
259 259 rev = changeset
260 260
261 261 def manifest(web, req, tmpl):
262 262 ctx = webutil.changectx(web.repo, req)
263 263 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
264 264 mf = ctx.manifest()
265 265 node = ctx.node()
266 266
267 267 files = {}
268 268 dirs = {}
269 269 parity = paritygen(web.stripecount)
270 270
271 271 if path and path[-1] != "/":
272 272 path += "/"
273 273 l = len(path)
274 274 abspath = "/" + path
275 275
276 276 for f, n in mf.items():
277 277 if f[:l] != path:
278 278 continue
279 279 remain = f[l:]
280 280 elements = remain.split('/')
281 281 if len(elements) == 1:
282 282 files[remain] = f
283 283 else:
284 284 h = dirs # need to retain ref to dirs (root)
285 285 for elem in elements[0:-1]:
286 286 if elem not in h:
287 287 h[elem] = {}
288 288 h = h[elem]
289 289 if len(h) > 1:
290 290 break
291 291 h[None] = None # denotes files present
292 292
293 293 if not files and not dirs:
294 294 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
295 295
296 296 def filelist(**map):
297 297 for f in util.sort(files):
298 298 full = files[f]
299 299
300 300 fctx = ctx.filectx(full)
301 301 yield {"file": full,
302 302 "parity": parity.next(),
303 303 "basename": f,
304 304 "date": fctx.date(),
305 305 "size": fctx.size(),
306 306 "permissions": mf.flags(full)}
307 307
308 308 def dirlist(**map):
309 309 for d in util.sort(dirs):
310 310
311 311 emptydirs = []
312 312 h = dirs[d]
313 313 while isinstance(h, dict) and len(h) == 1:
314 314 k,v = h.items()[0]
315 315 if v:
316 316 emptydirs.append(k)
317 317 h = v
318 318
319 319 path = "%s%s" % (abspath, d)
320 320 yield {"parity": parity.next(),
321 321 "path": path,
322 322 "emptydirs": "/".join(emptydirs),
323 323 "basename": d}
324 324
325 325 return tmpl("manifest",
326 326 rev=ctx.rev(),
327 327 node=hex(node),
328 328 path=abspath,
329 329 up=webutil.up(abspath),
330 330 upparity=parity.next(),
331 331 fentries=filelist,
332 332 dentries=dirlist,
333 333 archives=web.archivelist(hex(node)),
334 334 tags=webutil.nodetagsdict(web.repo, node),
335 335 inbranch=webutil.nodeinbranch(web.repo, ctx),
336 336 branches=webutil.nodebranchdict(web.repo, ctx))
337 337
338 338 def tags(web, req, tmpl):
339 339 i = web.repo.tagslist()
340 340 i.reverse()
341 341 parity = paritygen(web.stripecount)
342 342
343 343 def entries(notip=False,limit=0, **map):
344 344 count = 0
345 345 for k, n in i:
346 346 if notip and k == "tip":
347 347 continue
348 348 if limit > 0 and count >= limit:
349 349 continue
350 350 count = count + 1
351 351 yield {"parity": parity.next(),
352 352 "tag": k,
353 353 "date": web.repo[n].date(),
354 354 "node": hex(n)}
355 355
356 356 return tmpl("tags",
357 357 node=hex(web.repo.changelog.tip()),
358 358 entries=lambda **x: entries(False,0, **x),
359 359 entriesnotip=lambda **x: entries(True,0, **x),
360 360 latestentry=lambda **x: entries(True,1, **x))
361 361
362 362 def summary(web, req, tmpl):
363 363 i = web.repo.tagslist()
364 364 i.reverse()
365 365
366 366 def tagentries(**map):
367 367 parity = paritygen(web.stripecount)
368 368 count = 0
369 369 for k, n in i:
370 370 if k == "tip": # skip tip
371 371 continue
372 372
373 373 count += 1
374 374 if count > 10: # limit to 10 tags
375 375 break
376 376
377 377 yield tmpl("tagentry",
378 378 parity=parity.next(),
379 379 tag=k,
380 380 node=hex(n),
381 381 date=web.repo[n].date())
382 382
383 383 def branches(**map):
384 384 parity = paritygen(web.stripecount)
385 385
386 386 b = web.repo.branchtags()
387 387 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.items()]
388 388 for r,n,t in util.sort(l):
389 389 yield {'parity': parity.next(),
390 390 'branch': t,
391 391 'node': hex(n),
392 392 'date': web.repo[n].date()}
393 393
394 394 def changelist(**map):
395 395 parity = paritygen(web.stripecount, offset=start-end)
396 396 l = [] # build a list in forward order for efficiency
397 397 for i in xrange(start, end):
398 398 ctx = web.repo[i]
399 399 n = ctx.node()
400 400 hn = hex(n)
401 401
402 402 l.insert(0, tmpl(
403 403 'shortlogentry',
404 404 parity=parity.next(),
405 405 author=ctx.user(),
406 406 desc=ctx.description(),
407 407 date=ctx.date(),
408 408 rev=i,
409 409 node=hn,
410 410 tags=webutil.nodetagsdict(web.repo, n),
411 411 inbranch=webutil.nodeinbranch(web.repo, ctx),
412 412 branches=webutil.nodebranchdict(web.repo, ctx)))
413 413
414 414 yield l
415 415
416 416 cl = web.repo.changelog
417 417 count = len(cl)
418 418 start = max(0, count - web.maxchanges)
419 419 end = min(count, start + web.maxchanges)
420 420
421 421 return tmpl("summary",
422 422 desc=web.config("web", "description", "unknown"),
423 423 owner=get_contact(web.config) or "unknown",
424 424 lastchange=cl.read(cl.tip())[2],
425 425 tags=tagentries,
426 426 branches=branches,
427 427 shortlog=changelist,
428 428 node=hex(cl.tip()),
429 429 archives=web.archivelist("tip"))
430 430
431 431 def filediff(web, req, tmpl):
432 432 fctx, ctx = None, None
433 433 try:
434 434 fctx = webutil.filectx(web.repo, req)
435 435 except LookupError:
436 436 ctx = webutil.changectx(web.repo, req)
437 437 path = webutil.cleanpath(web.repo, req.form['file'][0])
438 438 if path not in ctx.files():
439 439 raise
440 440
441 441 if fctx is not None:
442 442 n = fctx.node()
443 443 path = fctx.path()
444 444 parents = fctx.parents()
445 445 p1 = parents and parents[0].node() or nullid
446 446 else:
447 447 n = ctx.node()
448 448 # path already defined in except clause
449 449 parents = ctx.parents()
450 450
451 451 parity = paritygen(web.stripecount)
452 452 diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity)
453 453 rename = fctx and webutil.renamelink(fctx) or []
454 454 ctx = fctx and fctx or ctx
455 455 return tmpl("filediff",
456 456 file=path,
457 457 node=hex(n),
458 458 rev=ctx.rev(),
459 459 date=ctx.date(),
460 460 desc=ctx.description(),
461 461 author=ctx.user(),
462 462 rename=rename,
463 463 branch=webutil.nodebranchnodefault(ctx),
464 464 parent=webutil.siblings(parents),
465 465 child=webutil.siblings(ctx.children()),
466 466 diff=diffs)
467 467
468 468 diff = filediff
469 469
470 470 def annotate(web, req, tmpl):
471 471 fctx = webutil.filectx(web.repo, req)
472 472 f = fctx.path()
473 473 parity = paritygen(web.stripecount)
474 474
475 475 def annotate(**map):
476 476 last = None
477 477 if binary(fctx.data()):
478 478 mt = (mimetypes.guess_type(fctx.path())[0]
479 479 or 'application/octet-stream')
480 480 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
481 481 '(binary:%s)' % mt)])
482 482 else:
483 483 lines = enumerate(fctx.annotate(follow=True, linenumber=True))
484 484 for lineno, ((f, targetline), l) in lines:
485 485 fnode = f.filenode()
486 486
487 487 if last != fnode:
488 488 last = fnode
489 489
490 490 yield {"parity": parity.next(),
491 491 "node": hex(f.node()),
492 492 "rev": f.rev(),
493 493 "author": f.user(),
494 494 "desc": f.description(),
495 495 "file": f.path(),
496 496 "targetline": targetline,
497 497 "line": l,
498 498 "lineid": "l%d" % (lineno + 1),
499 499 "linenumber": "% 6d" % (lineno + 1)}
500 500
501 501 return tmpl("fileannotate",
502 502 file=f,
503 503 annotate=annotate,
504 504 path=webutil.up(f),
505 505 rev=fctx.rev(),
506 506 node=hex(fctx.node()),
507 507 author=fctx.user(),
508 508 date=fctx.date(),
509 509 desc=fctx.description(),
510 510 rename=webutil.renamelink(fctx),
511 511 branch=webutil.nodebranchnodefault(fctx),
512 512 parent=webutil.siblings(fctx.parents()),
513 513 child=webutil.siblings(fctx.children()),
514 514 permissions=fctx.manifest().flags(f))
515 515
516 516 def filelog(web, req, tmpl):
517 517
518 518 try:
519 519 fctx = webutil.filectx(web.repo, req)
520 520 f = fctx.path()
521 521 fl = fctx.filelog()
522 522 except revlog.LookupError:
523 523 f = webutil.cleanpath(web.repo, req.form['file'][0])
524 524 fl = web.repo.file(f)
525 525 numrevs = len(fl)
526 526 if not numrevs: # file doesn't exist at all
527 527 raise
528 528 rev = webutil.changectx(web.repo, req).rev()
529 529 first = fl.linkrev(0)
530 530 if rev < first: # current rev is from before file existed
531 531 raise
532 532 frev = numrevs - 1
533 533 while fl.linkrev(frev) > rev:
534 534 frev -= 1
535 535 fctx = web.repo.filectx(f, fl.linkrev(frev))
536 536
537 537 count = fctx.filerev() + 1
538 538 pagelen = web.maxshortchanges
539 539 start = max(0, fctx.filerev() - pagelen + 1) # first rev on this page
540 540 end = min(count, start + pagelen) # last rev on this page
541 541 parity = paritygen(web.stripecount, offset=start-end)
542 542
543 543 def entries(limit=0, **map):
544 544 l = []
545 545
546 546 for i in xrange(start, end):
547 547 ctx = fctx.filectx(i)
548 548
549 549 l.insert(0, {"parity": parity.next(),
550 550 "filerev": i,
551 551 "file": f,
552 552 "node": hex(ctx.node()),
553 553 "author": ctx.user(),
554 554 "date": ctx.date(),
555 555 "rename": webutil.renamelink(fctx),
556 556 "parent": webutil.siblings(fctx.parents()),
557 557 "child": webutil.siblings(fctx.children()),
558 "desc": ctx.description()})
558 "desc": ctx.description(),
559 "tags": webutil.nodetagsdict(web.repo, ctx.node()),
560 "branch": webutil.nodebranchnodefault(ctx),
561 "inbranch": webutil.nodeinbranch(web.repo, ctx),
562 "branches": webutil.nodebranchdict(web.repo, ctx)})
559 563
560 564 if limit > 0:
561 565 l = l[:limit]
562 566
563 567 for e in l:
564 568 yield e
565 569
566 570 nodefunc = lambda x: fctx.filectx(fileid=x)
567 571 nav = webutil.revnavgen(end - 1, pagelen, count, nodefunc)
568 572 return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
569 573 entries=lambda **x: entries(limit=0, **x),
570 574 latestentry=lambda **x: entries(limit=1, **x))
571 575
572 576
573 577 def archive(web, req, tmpl):
574 578 type_ = req.form.get('type', [None])[0]
575 579 allowed = web.configlist("web", "allow_archive")
576 580 key = req.form['node'][0]
577 581
578 582 if type_ not in web.archives:
579 583 msg = 'Unsupported archive type: %s' % type_
580 584 raise ErrorResponse(HTTP_NOT_FOUND, msg)
581 585
582 586 if not ((type_ in allowed or
583 587 web.configbool("web", "allow" + type_, False))):
584 588 msg = 'Archive type not allowed: %s' % type_
585 589 raise ErrorResponse(HTTP_FORBIDDEN, msg)
586 590
587 591 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
588 592 cnode = web.repo.lookup(key)
589 593 arch_version = key
590 594 if cnode == key or key == 'tip':
591 595 arch_version = short(cnode)
592 596 name = "%s-%s" % (reponame, arch_version)
593 597 mimetype, artype, extension, encoding = web.archive_specs[type_]
594 598 headers = [
595 599 ('Content-Type', mimetype),
596 600 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
597 601 ]
598 602 if encoding:
599 603 headers.append(('Content-Encoding', encoding))
600 604 req.header(headers)
601 605 req.respond(HTTP_OK)
602 606 archival.archive(web.repo, req, cnode, artype, prefix=name)
603 607 return []
604 608
605 609
606 610 def static(web, req, tmpl):
607 611 fname = req.form['file'][0]
608 612 # a repo owner may set web.static in .hg/hgrc to get any file
609 613 # readable by the user running the CGI script
610 614 static = web.config("web", "static", None, untrusted=False)
611 615 if not static:
612 616 tp = web.templatepath
613 617 if isinstance(tp, str):
614 618 tp = [tp]
615 619 static = [os.path.join(p, 'static') for p in tp]
616 620 return [staticfile(static, fname, req)]
617 621
618 622 def graph(web, req, tmpl):
619 623 rev = webutil.changectx(web.repo, req).rev()
620 624 bg_height = 39
621 625
622 626 revcount = 25
623 627 if 'revcount' in req.form:
624 628 revcount = int(req.form.get('revcount', [revcount])[0])
625 629 tmpl.defaults['sessionvars']['revcount'] = revcount
626 630
627 631 lessvars = copy.copy(tmpl.defaults['sessionvars'])
628 632 lessvars['revcount'] = revcount / 2
629 633 morevars = copy.copy(tmpl.defaults['sessionvars'])
630 634 morevars['revcount'] = revcount * 2
631 635
632 636 max_rev = len(web.repo) - 1
633 637 revcount = min(max_rev, revcount)
634 638 revnode = web.repo.changelog.node(rev)
635 639 revnode_hex = hex(revnode)
636 640 uprev = min(max_rev, rev + revcount)
637 641 downrev = max(0, rev - revcount)
638 642 count = len(web.repo)
639 643 changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
640 644
641 645 tree = list(graphmod.graph(web.repo, rev, downrev))
642 646 canvasheight = (len(tree) + 1) * bg_height - 27;
643 647 data = []
644 648 for i, (ctx, vtx, edges) in enumerate(tree):
645 649 node = short(ctx.node())
646 650 age = templatefilters.age(ctx.date())
647 651 desc = templatefilters.firstline(ctx.description())
648 652 desc = cgi.escape(desc)
649 653 user = cgi.escape(templatefilters.person(ctx.user()))
650 654 branch = ctx.branch()
651 655 branch = branch, web.repo.branchtags().get(branch) == ctx.node()
652 656 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags()))
653 657
654 658 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
655 659 lessvars=lessvars, morevars=morevars, downrev=downrev,
656 660 canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
657 661 node=revnode_hex, changenav=changenav)
@@ -1,5 +1,5 b''
1 1 <tr class="parity{parity}">
2 2 <td class="age">{date|age}</td>
3 3 <td class="author">{author|person}</td>
4 <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape}</a></td>
4 <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}</td>
5 5 </tr>
General Comments 0
You need to be logged in to leave comments. Login now