##// END OF EJS Templates
hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov -
r13596:270f57d3 stable
parent child Browse files
Show More
@@ -1,784 +1,789 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 of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 import os, mimetypes, re, cgi, copy
9 9 import webutil
10 10 from mercurial import error, encoding, archival, templater, templatefilters
11 11 from mercurial.node import short, hex
12 12 from mercurial.util import binary
13 13 from common import paritygen, staticfile, get_contact, ErrorResponse
14 14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
15 15 from mercurial import graphmod
16 16 from mercurial import help as helpmod
17 17 from mercurial.i18n import _
18 18
19 19 # __all__ is populated with the allowed commands. Be sure to add to it if
20 20 # you're adding a new command, or the new command won't work.
21 21
22 22 __all__ = [
23 23 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
24 24 'manifest', 'tags', 'branches', 'summary', 'filediff', 'diff', 'annotate',
25 25 'filelog', 'archive', 'static', 'graph', 'help',
26 26 ]
27 27
28 28 def log(web, req, tmpl):
29 29 if 'file' in req.form and req.form['file'][0]:
30 30 return filelog(web, req, tmpl)
31 31 else:
32 32 return changelog(web, req, tmpl)
33 33
34 34 def rawfile(web, req, tmpl):
35 35 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
36 36 if not path:
37 37 content = manifest(web, req, tmpl)
38 38 req.respond(HTTP_OK, web.ctype)
39 39 return content
40 40
41 41 try:
42 42 fctx = webutil.filectx(web.repo, req)
43 43 except error.LookupError, inst:
44 44 try:
45 45 content = manifest(web, req, tmpl)
46 46 req.respond(HTTP_OK, web.ctype)
47 47 return content
48 48 except ErrorResponse:
49 49 raise inst
50 50
51 51 path = fctx.path()
52 52 text = fctx.data()
53 53 mt = mimetypes.guess_type(path)[0]
54 54 if mt is None:
55 55 mt = binary(text) and 'application/octet-stream' or 'text/plain'
56 56 if mt.startswith('text/'):
57 57 mt += '; charset="%s"' % encoding.encoding
58 58
59 59 req.respond(HTTP_OK, mt, path, len(text))
60 60 return [text]
61 61
62 62 def _filerevision(web, tmpl, fctx):
63 63 f = fctx.path()
64 64 text = fctx.data()
65 65 parity = paritygen(web.stripecount)
66 66
67 67 if binary(text):
68 68 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
69 69 text = '(binary:%s)' % mt
70 70
71 71 def lines():
72 72 for lineno, t in enumerate(text.splitlines(True)):
73 73 yield {"line": t,
74 74 "lineid": "l%d" % (lineno + 1),
75 75 "linenumber": "% 6d" % (lineno + 1),
76 76 "parity": parity.next()}
77 77
78 78 return tmpl("filerevision",
79 79 file=f,
80 80 path=webutil.up(f),
81 81 text=lines(),
82 82 rev=fctx.rev(),
83 83 node=hex(fctx.node()),
84 84 author=fctx.user(),
85 85 date=fctx.date(),
86 86 desc=fctx.description(),
87 87 branch=webutil.nodebranchnodefault(fctx),
88 88 parent=webutil.parents(fctx),
89 89 child=webutil.children(fctx),
90 90 rename=webutil.renamelink(fctx),
91 91 permissions=fctx.manifest().flags(f))
92 92
93 93 def file(web, req, tmpl):
94 94 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
95 95 if not path:
96 96 return manifest(web, req, tmpl)
97 97 try:
98 98 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
99 99 except error.LookupError, inst:
100 100 try:
101 101 return manifest(web, req, tmpl)
102 102 except ErrorResponse:
103 103 raise inst
104 104
105 105 def _search(web, req, tmpl):
106 106
107 107 query = req.form['rev'][0]
108 108 revcount = web.maxchanges
109 109 if 'revcount' in req.form:
110 110 revcount = int(req.form.get('revcount', [revcount])[0])
111 111 tmpl.defaults['sessionvars']['revcount'] = revcount
112 112
113 113 lessvars = copy.copy(tmpl.defaults['sessionvars'])
114 114 lessvars['revcount'] = revcount / 2
115 115 lessvars['rev'] = query
116 116 morevars = copy.copy(tmpl.defaults['sessionvars'])
117 117 morevars['revcount'] = revcount * 2
118 118 morevars['rev'] = query
119 119
120 120 def changelist(**map):
121 121 count = 0
122 122 qw = query.lower().split()
123 123
124 124 def revgen():
125 125 for i in xrange(len(web.repo) - 1, 0, -100):
126 126 l = []
127 127 for j in xrange(max(0, i - 100), i + 1):
128 128 ctx = web.repo[j]
129 129 l.append(ctx)
130 130 l.reverse()
131 131 for e in l:
132 132 yield e
133 133
134 134 for ctx in revgen():
135 135 miss = 0
136 136 for q in qw:
137 137 if not (q in ctx.user().lower() or
138 138 q in ctx.description().lower() or
139 139 q in " ".join(ctx.files()).lower()):
140 140 miss = 1
141 141 break
142 142 if miss:
143 143 continue
144 144
145 145 count += 1
146 146 n = ctx.node()
147 147 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
148 148 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
149 149
150 150 yield tmpl('searchentry',
151 151 parity=parity.next(),
152 152 author=ctx.user(),
153 153 parent=webutil.parents(ctx),
154 154 child=webutil.children(ctx),
155 155 changelogtag=showtags,
156 156 desc=ctx.description(),
157 157 date=ctx.date(),
158 158 files=files,
159 159 rev=ctx.rev(),
160 160 node=hex(n),
161 161 tags=webutil.nodetagsdict(web.repo, n),
162 162 inbranch=webutil.nodeinbranch(web.repo, ctx),
163 163 branches=webutil.nodebranchdict(web.repo, ctx))
164 164
165 165 if count >= revcount:
166 166 break
167 167
168 168 tip = web.repo['tip']
169 169 parity = paritygen(web.stripecount)
170 170
171 171 return tmpl('search', query=query, node=tip.hex(),
172 172 entries=changelist, archives=web.archivelist("tip"),
173 173 morevars=morevars, lessvars=lessvars)
174 174
175 175 def changelog(web, req, tmpl, shortlog=False):
176 176
177 177 if 'node' in req.form:
178 178 ctx = webutil.changectx(web.repo, req)
179 179 else:
180 180 if 'rev' in req.form:
181 181 hi = req.form['rev'][0]
182 182 else:
183 183 hi = len(web.repo) - 1
184 184 try:
185 185 ctx = web.repo[hi]
186 186 except error.RepoError:
187 187 return _search(web, req, tmpl) # XXX redirect to 404 page?
188 188
189 189 def changelist(limit=0, **map):
190 190 l = [] # build a list in forward order for efficiency
191 191 for i in xrange(start, end):
192 192 ctx = web.repo[i]
193 193 n = ctx.node()
194 194 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
195 195 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
196 196
197 197 l.insert(0, {"parity": parity.next(),
198 198 "author": ctx.user(),
199 199 "parent": webutil.parents(ctx, i - 1),
200 200 "child": webutil.children(ctx, i + 1),
201 201 "changelogtag": showtags,
202 202 "desc": ctx.description(),
203 203 "date": ctx.date(),
204 204 "files": files,
205 205 "rev": i,
206 206 "node": hex(n),
207 207 "tags": webutil.nodetagsdict(web.repo, n),
208 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
208 209 "inbranch": webutil.nodeinbranch(web.repo, ctx),
209 210 "branches": webutil.nodebranchdict(web.repo, ctx)
210 211 })
211 212
212 213 if limit > 0:
213 214 l = l[:limit]
214 215
215 216 for e in l:
216 217 yield e
217 218
218 219 revcount = shortlog and web.maxshortchanges or web.maxchanges
219 220 if 'revcount' in req.form:
220 221 revcount = int(req.form.get('revcount', [revcount])[0])
221 222 tmpl.defaults['sessionvars']['revcount'] = revcount
222 223
223 224 lessvars = copy.copy(tmpl.defaults['sessionvars'])
224 225 lessvars['revcount'] = revcount / 2
225 226 morevars = copy.copy(tmpl.defaults['sessionvars'])
226 227 morevars['revcount'] = revcount * 2
227 228
228 229 count = len(web.repo)
229 230 pos = ctx.rev()
230 231 start = max(0, pos - revcount + 1)
231 232 end = min(count, start + revcount)
232 233 pos = end - 1
233 234 parity = paritygen(web.stripecount, offset=start - end)
234 235
235 236 changenav = webutil.revnavgen(pos, revcount, count, web.repo.changectx)
236 237
237 238 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
238 239 node=hex(ctx.node()), rev=pos, changesets=count,
239 240 entries=lambda **x: changelist(limit=0,**x),
240 241 latestentry=lambda **x: changelist(limit=1,**x),
241 242 archives=web.archivelist("tip"), revcount=revcount,
242 243 morevars=morevars, lessvars=lessvars)
243 244
244 245 def shortlog(web, req, tmpl):
245 246 return changelog(web, req, tmpl, shortlog = True)
246 247
247 248 def changeset(web, req, tmpl):
248 249 ctx = webutil.changectx(web.repo, req)
249 250 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
251 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
252 ctx.node())
250 253 showbranch = webutil.nodebranchnodefault(ctx)
251 254
252 255 files = []
253 256 parity = paritygen(web.stripecount)
254 257 for f in ctx.files():
255 258 template = f in ctx and 'filenodelink' or 'filenolink'
256 259 files.append(tmpl(template,
257 260 node=ctx.hex(), file=f,
258 261 parity=parity.next()))
259 262
260 263 parity = paritygen(web.stripecount)
261 264 style = web.config('web', 'style', 'paper')
262 265 if 'style' in req.form:
263 266 style = req.form['style'][0]
264 267
265 268 diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
266 269 return tmpl('changeset',
267 270 diff=diffs,
268 271 rev=ctx.rev(),
269 272 node=ctx.hex(),
270 273 parent=webutil.parents(ctx),
271 274 child=webutil.children(ctx),
272 275 changesettag=showtags,
276 changesetbookmark=showbookmarks,
273 277 changesetbranch=showbranch,
274 278 author=ctx.user(),
275 279 desc=ctx.description(),
276 280 date=ctx.date(),
277 281 files=files,
278 282 archives=web.archivelist(ctx.hex()),
279 283 tags=webutil.nodetagsdict(web.repo, ctx.node()),
284 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
280 285 branch=webutil.nodebranchnodefault(ctx),
281 286 inbranch=webutil.nodeinbranch(web.repo, ctx),
282 287 branches=webutil.nodebranchdict(web.repo, ctx))
283 288
284 289 rev = changeset
285 290
286 291 def manifest(web, req, tmpl):
287 292 ctx = webutil.changectx(web.repo, req)
288 293 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
289 294 mf = ctx.manifest()
290 295 node = ctx.node()
291 296
292 297 files = {}
293 298 dirs = {}
294 299 parity = paritygen(web.stripecount)
295 300
296 301 if path and path[-1] != "/":
297 302 path += "/"
298 303 l = len(path)
299 304 abspath = "/" + path
300 305
301 306 for f, n in mf.iteritems():
302 307 if f[:l] != path:
303 308 continue
304 309 remain = f[l:]
305 310 elements = remain.split('/')
306 311 if len(elements) == 1:
307 312 files[remain] = f
308 313 else:
309 314 h = dirs # need to retain ref to dirs (root)
310 315 for elem in elements[0:-1]:
311 316 if elem not in h:
312 317 h[elem] = {}
313 318 h = h[elem]
314 319 if len(h) > 1:
315 320 break
316 321 h[None] = None # denotes files present
317 322
318 323 if mf and not files and not dirs:
319 324 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
320 325
321 326 def filelist(**map):
322 327 for f in sorted(files):
323 328 full = files[f]
324 329
325 330 fctx = ctx.filectx(full)
326 331 yield {"file": full,
327 332 "parity": parity.next(),
328 333 "basename": f,
329 334 "date": fctx.date(),
330 335 "size": fctx.size(),
331 336 "permissions": mf.flags(full)}
332 337
333 338 def dirlist(**map):
334 339 for d in sorted(dirs):
335 340
336 341 emptydirs = []
337 342 h = dirs[d]
338 343 while isinstance(h, dict) and len(h) == 1:
339 344 k, v = h.items()[0]
340 345 if v:
341 346 emptydirs.append(k)
342 347 h = v
343 348
344 349 path = "%s%s" % (abspath, d)
345 350 yield {"parity": parity.next(),
346 351 "path": path,
347 352 "emptydirs": "/".join(emptydirs),
348 353 "basename": d}
349 354
350 355 return tmpl("manifest",
351 356 rev=ctx.rev(),
352 357 node=hex(node),
353 358 path=abspath,
354 359 up=webutil.up(abspath),
355 360 upparity=parity.next(),
356 361 fentries=filelist,
357 362 dentries=dirlist,
358 363 archives=web.archivelist(hex(node)),
359 364 tags=webutil.nodetagsdict(web.repo, node),
360 365 inbranch=webutil.nodeinbranch(web.repo, ctx),
361 366 branches=webutil.nodebranchdict(web.repo, ctx))
362 367
363 368 def tags(web, req, tmpl):
364 369 i = web.repo.tagslist()
365 370 i.reverse()
366 371 parity = paritygen(web.stripecount)
367 372
368 373 def entries(notip=False, limit=0, **map):
369 374 count = 0
370 375 for k, n in i:
371 376 if notip and k == "tip":
372 377 continue
373 378 if limit > 0 and count >= limit:
374 379 continue
375 380 count = count + 1
376 381 yield {"parity": parity.next(),
377 382 "tag": k,
378 383 "date": web.repo[n].date(),
379 384 "node": hex(n)}
380 385
381 386 return tmpl("tags",
382 387 node=hex(web.repo.changelog.tip()),
383 388 entries=lambda **x: entries(False, 0, **x),
384 389 entriesnotip=lambda **x: entries(True, 0, **x),
385 390 latestentry=lambda **x: entries(True, 1, **x))
386 391
387 392 def branches(web, req, tmpl):
388 393 tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
389 394 heads = web.repo.heads()
390 395 parity = paritygen(web.stripecount)
391 396 sortkey = lambda ctx: ('close' not in ctx.extra(), ctx.rev())
392 397
393 398 def entries(limit, **map):
394 399 count = 0
395 400 for ctx in sorted(tips, key=sortkey, reverse=True):
396 401 if limit > 0 and count >= limit:
397 402 return
398 403 count += 1
399 404 if ctx.node() not in heads:
400 405 status = 'inactive'
401 406 elif not web.repo.branchheads(ctx.branch()):
402 407 status = 'closed'
403 408 else:
404 409 status = 'open'
405 410 yield {'parity': parity.next(),
406 411 'branch': ctx.branch(),
407 412 'status': status,
408 413 'node': ctx.hex(),
409 414 'date': ctx.date()}
410 415
411 416 return tmpl('branches', node=hex(web.repo.changelog.tip()),
412 417 entries=lambda **x: entries(0, **x),
413 418 latestentry=lambda **x: entries(1, **x))
414 419
415 420 def summary(web, req, tmpl):
416 421 i = web.repo.tagslist()
417 422 i.reverse()
418 423
419 424 def tagentries(**map):
420 425 parity = paritygen(web.stripecount)
421 426 count = 0
422 427 for k, n in i:
423 428 if k == "tip": # skip tip
424 429 continue
425 430
426 431 count += 1
427 432 if count > 10: # limit to 10 tags
428 433 break
429 434
430 435 yield tmpl("tagentry",
431 436 parity=parity.next(),
432 437 tag=k,
433 438 node=hex(n),
434 439 date=web.repo[n].date())
435 440
436 441 def branches(**map):
437 442 parity = paritygen(web.stripecount)
438 443
439 444 b = web.repo.branchtags()
440 445 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
441 446 for r, n, t in sorted(l):
442 447 yield {'parity': parity.next(),
443 448 'branch': t,
444 449 'node': hex(n),
445 450 'date': web.repo[n].date()}
446 451
447 452 def changelist(**map):
448 453 parity = paritygen(web.stripecount, offset=start - end)
449 454 l = [] # build a list in forward order for efficiency
450 455 for i in xrange(start, end):
451 456 ctx = web.repo[i]
452 457 n = ctx.node()
453 458 hn = hex(n)
454 459
455 460 l.insert(0, tmpl(
456 461 'shortlogentry',
457 462 parity=parity.next(),
458 463 author=ctx.user(),
459 464 desc=ctx.description(),
460 465 date=ctx.date(),
461 466 rev=i,
462 467 node=hn,
463 468 tags=webutil.nodetagsdict(web.repo, n),
464 469 inbranch=webutil.nodeinbranch(web.repo, ctx),
465 470 branches=webutil.nodebranchdict(web.repo, ctx)))
466 471
467 472 yield l
468 473
469 474 tip = web.repo['tip']
470 475 count = len(web.repo)
471 476 start = max(0, count - web.maxchanges)
472 477 end = min(count, start + web.maxchanges)
473 478
474 479 return tmpl("summary",
475 480 desc=web.config("web", "description", "unknown"),
476 481 owner=get_contact(web.config) or "unknown",
477 482 lastchange=tip.date(),
478 483 tags=tagentries,
479 484 branches=branches,
480 485 shortlog=changelist,
481 486 node=tip.hex(),
482 487 archives=web.archivelist("tip"))
483 488
484 489 def filediff(web, req, tmpl):
485 490 fctx, ctx = None, None
486 491 try:
487 492 fctx = webutil.filectx(web.repo, req)
488 493 except LookupError:
489 494 ctx = webutil.changectx(web.repo, req)
490 495 path = webutil.cleanpath(web.repo, req.form['file'][0])
491 496 if path not in ctx.files():
492 497 raise
493 498
494 499 if fctx is not None:
495 500 n = fctx.node()
496 501 path = fctx.path()
497 502 else:
498 503 n = ctx.node()
499 504 # path already defined in except clause
500 505
501 506 parity = paritygen(web.stripecount)
502 507 style = web.config('web', 'style', 'paper')
503 508 if 'style' in req.form:
504 509 style = req.form['style'][0]
505 510
506 511 diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity, style)
507 512 rename = fctx and webutil.renamelink(fctx) or []
508 513 ctx = fctx and fctx or ctx
509 514 return tmpl("filediff",
510 515 file=path,
511 516 node=hex(n),
512 517 rev=ctx.rev(),
513 518 date=ctx.date(),
514 519 desc=ctx.description(),
515 520 author=ctx.user(),
516 521 rename=rename,
517 522 branch=webutil.nodebranchnodefault(ctx),
518 523 parent=webutil.parents(ctx),
519 524 child=webutil.children(ctx),
520 525 diff=diffs)
521 526
522 527 diff = filediff
523 528
524 529 def annotate(web, req, tmpl):
525 530 fctx = webutil.filectx(web.repo, req)
526 531 f = fctx.path()
527 532 parity = paritygen(web.stripecount)
528 533
529 534 def annotate(**map):
530 535 last = None
531 536 if binary(fctx.data()):
532 537 mt = (mimetypes.guess_type(fctx.path())[0]
533 538 or 'application/octet-stream')
534 539 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
535 540 '(binary:%s)' % mt)])
536 541 else:
537 542 lines = enumerate(fctx.annotate(follow=True, linenumber=True))
538 543 for lineno, ((f, targetline), l) in lines:
539 544 fnode = f.filenode()
540 545
541 546 if last != fnode:
542 547 last = fnode
543 548
544 549 yield {"parity": parity.next(),
545 550 "node": hex(f.node()),
546 551 "rev": f.rev(),
547 552 "author": f.user(),
548 553 "desc": f.description(),
549 554 "file": f.path(),
550 555 "targetline": targetline,
551 556 "line": l,
552 557 "lineid": "l%d" % (lineno + 1),
553 558 "linenumber": "% 6d" % (lineno + 1),
554 559 "revdate": f.date()}
555 560
556 561 return tmpl("fileannotate",
557 562 file=f,
558 563 annotate=annotate,
559 564 path=webutil.up(f),
560 565 rev=fctx.rev(),
561 566 node=hex(fctx.node()),
562 567 author=fctx.user(),
563 568 date=fctx.date(),
564 569 desc=fctx.description(),
565 570 rename=webutil.renamelink(fctx),
566 571 branch=webutil.nodebranchnodefault(fctx),
567 572 parent=webutil.parents(fctx),
568 573 child=webutil.children(fctx),
569 574 permissions=fctx.manifest().flags(f))
570 575
571 576 def filelog(web, req, tmpl):
572 577
573 578 try:
574 579 fctx = webutil.filectx(web.repo, req)
575 580 f = fctx.path()
576 581 fl = fctx.filelog()
577 582 except error.LookupError:
578 583 f = webutil.cleanpath(web.repo, req.form['file'][0])
579 584 fl = web.repo.file(f)
580 585 numrevs = len(fl)
581 586 if not numrevs: # file doesn't exist at all
582 587 raise
583 588 rev = webutil.changectx(web.repo, req).rev()
584 589 first = fl.linkrev(0)
585 590 if rev < first: # current rev is from before file existed
586 591 raise
587 592 frev = numrevs - 1
588 593 while fl.linkrev(frev) > rev:
589 594 frev -= 1
590 595 fctx = web.repo.filectx(f, fl.linkrev(frev))
591 596
592 597 revcount = web.maxshortchanges
593 598 if 'revcount' in req.form:
594 599 revcount = int(req.form.get('revcount', [revcount])[0])
595 600 tmpl.defaults['sessionvars']['revcount'] = revcount
596 601
597 602 lessvars = copy.copy(tmpl.defaults['sessionvars'])
598 603 lessvars['revcount'] = revcount / 2
599 604 morevars = copy.copy(tmpl.defaults['sessionvars'])
600 605 morevars['revcount'] = revcount * 2
601 606
602 607 count = fctx.filerev() + 1
603 608 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
604 609 end = min(count, start + revcount) # last rev on this page
605 610 parity = paritygen(web.stripecount, offset=start - end)
606 611
607 612 def entries(limit=0, **map):
608 613 l = []
609 614
610 615 repo = web.repo
611 616 for i in xrange(start, end):
612 617 iterfctx = fctx.filectx(i)
613 618
614 619 l.insert(0, {"parity": parity.next(),
615 620 "filerev": i,
616 621 "file": f,
617 622 "node": hex(iterfctx.node()),
618 623 "author": iterfctx.user(),
619 624 "date": iterfctx.date(),
620 625 "rename": webutil.renamelink(iterfctx),
621 626 "parent": webutil.parents(iterfctx),
622 627 "child": webutil.children(iterfctx),
623 628 "desc": iterfctx.description(),
624 629 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
625 630 "branch": webutil.nodebranchnodefault(iterfctx),
626 631 "inbranch": webutil.nodeinbranch(repo, iterfctx),
627 632 "branches": webutil.nodebranchdict(repo, iterfctx)})
628 633
629 634 if limit > 0:
630 635 l = l[:limit]
631 636
632 637 for e in l:
633 638 yield e
634 639
635 640 nodefunc = lambda x: fctx.filectx(fileid=x)
636 641 nav = webutil.revnavgen(end - 1, revcount, count, nodefunc)
637 642 return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
638 643 entries=lambda **x: entries(limit=0, **x),
639 644 latestentry=lambda **x: entries(limit=1, **x),
640 645 revcount=revcount, morevars=morevars, lessvars=lessvars)
641 646
642 647 def archive(web, req, tmpl):
643 648 type_ = req.form.get('type', [None])[0]
644 649 allowed = web.configlist("web", "allow_archive")
645 650 key = req.form['node'][0]
646 651
647 652 if type_ not in web.archives:
648 653 msg = 'Unsupported archive type: %s' % type_
649 654 raise ErrorResponse(HTTP_NOT_FOUND, msg)
650 655
651 656 if not ((type_ in allowed or
652 657 web.configbool("web", "allow" + type_, False))):
653 658 msg = 'Archive type not allowed: %s' % type_
654 659 raise ErrorResponse(HTTP_FORBIDDEN, msg)
655 660
656 661 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
657 662 cnode = web.repo.lookup(key)
658 663 arch_version = key
659 664 if cnode == key or key == 'tip':
660 665 arch_version = short(cnode)
661 666 name = "%s-%s" % (reponame, arch_version)
662 667 mimetype, artype, extension, encoding = web.archive_specs[type_]
663 668 headers = [
664 669 ('Content-Type', mimetype),
665 670 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
666 671 ]
667 672 if encoding:
668 673 headers.append(('Content-Encoding', encoding))
669 674 req.header(headers)
670 675 req.respond(HTTP_OK)
671 676 archival.archive(web.repo, req, cnode, artype, prefix=name)
672 677 return []
673 678
674 679
675 680 def static(web, req, tmpl):
676 681 fname = req.form['file'][0]
677 682 # a repo owner may set web.static in .hg/hgrc to get any file
678 683 # readable by the user running the CGI script
679 684 static = web.config("web", "static", None, untrusted=False)
680 685 if not static:
681 686 tp = web.templatepath or templater.templatepath()
682 687 if isinstance(tp, str):
683 688 tp = [tp]
684 689 static = [os.path.join(p, 'static') for p in tp]
685 690 return [staticfile(static, fname, req)]
686 691
687 692 def graph(web, req, tmpl):
688 693
689 694 rev = webutil.changectx(web.repo, req).rev()
690 695 bg_height = 39
691 696 revcount = web.maxshortchanges
692 697 if 'revcount' in req.form:
693 698 revcount = int(req.form.get('revcount', [revcount])[0])
694 699 tmpl.defaults['sessionvars']['revcount'] = revcount
695 700
696 701 lessvars = copy.copy(tmpl.defaults['sessionvars'])
697 702 lessvars['revcount'] = revcount / 2
698 703 morevars = copy.copy(tmpl.defaults['sessionvars'])
699 704 morevars['revcount'] = revcount * 2
700 705
701 706 max_rev = len(web.repo) - 1
702 707 revcount = min(max_rev, revcount)
703 708 revnode = web.repo.changelog.node(rev)
704 709 revnode_hex = hex(revnode)
705 710 uprev = min(max_rev, rev + revcount)
706 711 downrev = max(0, rev - revcount)
707 712 count = len(web.repo)
708 713 changenav = webutil.revnavgen(rev, revcount, count, web.repo.changectx)
709 714
710 715 dag = graphmod.revisions(web.repo, rev, downrev)
711 716 tree = list(graphmod.colored(dag))
712 717 canvasheight = (len(tree) + 1) * bg_height - 27
713 718 data = []
714 719 for (id, type, ctx, vtx, edges) in tree:
715 720 if type != graphmod.CHANGESET:
716 721 continue
717 722 node = short(ctx.node())
718 723 age = templatefilters.age(ctx.date())
719 724 desc = templatefilters.firstline(ctx.description())
720 725 desc = cgi.escape(templatefilters.nonempty(desc))
721 726 user = cgi.escape(templatefilters.person(ctx.user()))
722 727 branch = ctx.branch()
723 728 branch = branch, web.repo.branchtags().get(branch) == ctx.node()
724 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags()))
729 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(), ctx.bookmarks()))
725 730
726 731 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
727 732 lessvars=lessvars, morevars=morevars, downrev=downrev,
728 733 canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
729 734 node=revnode_hex, changenav=changenav)
730 735
731 736 def _getdoc(e):
732 737 doc = e[0].__doc__
733 738 if doc:
734 739 doc = doc.split('\n')[0]
735 740 else:
736 741 doc = _('(no help text available)')
737 742 return doc
738 743
739 744 def help(web, req, tmpl):
740 745 from mercurial import commands # avoid cycle
741 746
742 747 topicname = req.form.get('node', [None])[0]
743 748 if not topicname:
744 749 topic = []
745 750
746 751 def topics(**map):
747 752 for entries, summary, _ in helpmod.helptable:
748 753 entries = sorted(entries, key=len)
749 754 yield {'topic': entries[-1], 'summary': summary}
750 755
751 756 early, other = [], []
752 757 primary = lambda s: s.split('|')[0]
753 758 for c, e in commands.table.iteritems():
754 759 doc = _getdoc(e)
755 760 if 'DEPRECATED' in doc or c.startswith('debug'):
756 761 continue
757 762 cmd = primary(c)
758 763 if cmd.startswith('^'):
759 764 early.append((cmd[1:], doc))
760 765 else:
761 766 other.append((cmd, doc))
762 767
763 768 early.sort()
764 769 other.sort()
765 770
766 771 def earlycommands(**map):
767 772 for c, doc in early:
768 773 yield {'topic': c, 'summary': doc}
769 774
770 775 def othercommands(**map):
771 776 for c, doc in other:
772 777 yield {'topic': c, 'summary': doc}
773 778
774 779 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
775 780 othercommands=othercommands, title='Index')
776 781
777 782 u = webutil.wsgiui()
778 783 u.pushbuffer()
779 784 try:
780 785 commands.help_(u, topicname)
781 786 except error.UnknownCommand:
782 787 raise ErrorResponse(HTTP_NOT_FOUND)
783 788 doc = u.popbuffer()
784 789 return tmpl('help', topic=topicname, doc=doc)
@@ -1,226 +1,233 b''
1 1 # hgweb/webutil.py - utility library for the web interface.
2 2 #
3 3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 import os, copy
10 10 from mercurial import match, patch, util, error, ui
11 11 from mercurial.node import hex, nullid
12 12
13 13 def up(p):
14 14 if p[0] != "/":
15 15 p = "/" + p
16 16 if p[-1] == "/":
17 17 p = p[:-1]
18 18 up = os.path.dirname(p)
19 19 if up == "/":
20 20 return "/"
21 21 return up + "/"
22 22
23 23 def revnavgen(pos, pagelen, limit, nodefunc):
24 24 def seq(factor, limit=None):
25 25 if limit:
26 26 yield limit
27 27 if limit >= 20 and limit <= 40:
28 28 yield 50
29 29 else:
30 30 yield 1 * factor
31 31 yield 3 * factor
32 32 for f in seq(factor * 10):
33 33 yield f
34 34
35 35 navbefore = []
36 36 navafter = []
37 37
38 38 last = 0
39 39 for f in seq(1, pagelen):
40 40 if f < pagelen or f <= last:
41 41 continue
42 42 if f > limit:
43 43 break
44 44 last = f
45 45 if pos + f < limit:
46 46 navafter.append(("+%d" % f, hex(nodefunc(pos + f).node())))
47 47 if pos - f >= 0:
48 48 navbefore.insert(0, ("-%d" % f, hex(nodefunc(pos - f).node())))
49 49
50 50 navafter.append(("tip", "tip"))
51 51 try:
52 52 navbefore.insert(0, ("(0)", hex(nodefunc('0').node())))
53 53 except error.RepoError:
54 54 pass
55 55
56 56 def gen(l):
57 57 def f(**map):
58 58 for label, node in l:
59 59 yield {"label": label, "node": node}
60 60 return f
61 61
62 62 return (dict(before=gen(navbefore), after=gen(navafter)),)
63 63
64 64 def _siblings(siblings=[], hiderev=None):
65 65 siblings = [s for s in siblings if s.node() != nullid]
66 66 if len(siblings) == 1 and siblings[0].rev() == hiderev:
67 67 return
68 68 for s in siblings:
69 69 d = {'node': hex(s.node()), 'rev': s.rev()}
70 70 d['user'] = s.user()
71 71 d['date'] = s.date()
72 72 d['description'] = s.description()
73 73 d['branch'] = s.branch()
74 74 if hasattr(s, 'path'):
75 75 d['file'] = s.path()
76 76 yield d
77 77
78 78 def parents(ctx, hide=None):
79 79 return _siblings(ctx.parents(), hide)
80 80
81 81 def children(ctx, hide=None):
82 82 return _siblings(ctx.children(), hide)
83 83
84 84 def renamelink(fctx):
85 85 r = fctx.renamed()
86 86 if r:
87 87 return [dict(file=r[0], node=hex(r[1]))]
88 88 return []
89 89
90 90 def nodetagsdict(repo, node):
91 91 return [{"name": i} for i in repo.nodetags(node)]
92 92
93 def nodebookmarksdict(repo, node):
94 return [{"name": i} for i in repo.nodebookmarks(node)]
95
93 96 def nodebranchdict(repo, ctx):
94 97 branches = []
95 98 branch = ctx.branch()
96 99 # If this is an empty repo, ctx.node() == nullid,
97 100 # ctx.branch() == 'default', but branchtags() is
98 101 # an empty dict. Using dict.get avoids a traceback.
99 102 if repo.branchtags().get(branch) == ctx.node():
100 103 branches.append({"name": branch})
101 104 return branches
102 105
103 106 def nodeinbranch(repo, ctx):
104 107 branches = []
105 108 branch = ctx.branch()
106 109 if branch != 'default' and repo.branchtags().get(branch) != ctx.node():
107 110 branches.append({"name": branch})
108 111 return branches
109 112
110 113 def nodebranchnodefault(ctx):
111 114 branches = []
112 115 branch = ctx.branch()
113 116 if branch != 'default':
114 117 branches.append({"name": branch})
115 118 return branches
116 119
117 120 def showtag(repo, tmpl, t1, node=nullid, **args):
118 121 for t in repo.nodetags(node):
119 122 yield tmpl(t1, tag=t, **args)
120 123
124 def showbookmark(repo, tmpl, t1, node=nullid, **args):
125 for t in repo.nodebookmarks(node):
126 yield tmpl(t1, bookmark=t, **args)
127
121 128 def cleanpath(repo, path):
122 129 path = path.lstrip('/')
123 130 return util.canonpath(repo.root, '', path)
124 131
125 132 def changectx(repo, req):
126 133 changeid = "tip"
127 134 if 'node' in req.form:
128 135 changeid = req.form['node'][0]
129 136 elif 'manifest' in req.form:
130 137 changeid = req.form['manifest'][0]
131 138
132 139 try:
133 140 ctx = repo[changeid]
134 141 except error.RepoError:
135 142 man = repo.manifest
136 143 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
137 144
138 145 return ctx
139 146
140 147 def filectx(repo, req):
141 148 path = cleanpath(repo, req.form['file'][0])
142 149 if 'node' in req.form:
143 150 changeid = req.form['node'][0]
144 151 else:
145 152 changeid = req.form['filenode'][0]
146 153 try:
147 154 fctx = repo[changeid][path]
148 155 except error.RepoError:
149 156 fctx = repo.filectx(path, fileid=changeid)
150 157
151 158 return fctx
152 159
153 160 def listfilediffs(tmpl, files, node, max):
154 161 for f in files[:max]:
155 162 yield tmpl('filedifflink', node=hex(node), file=f)
156 163 if len(files) > max:
157 164 yield tmpl('fileellipses')
158 165
159 166 def diffs(repo, tmpl, ctx, files, parity, style):
160 167
161 168 def countgen():
162 169 start = 1
163 170 while True:
164 171 yield start
165 172 start += 1
166 173
167 174 blockcount = countgen()
168 175 def prettyprintlines(diff):
169 176 blockno = blockcount.next()
170 177 for lineno, l in enumerate(diff.splitlines(True)):
171 178 lineno = "%d.%d" % (blockno, lineno + 1)
172 179 if l.startswith('+'):
173 180 ltype = "difflineplus"
174 181 elif l.startswith('-'):
175 182 ltype = "difflineminus"
176 183 elif l.startswith('@'):
177 184 ltype = "difflineat"
178 185 else:
179 186 ltype = "diffline"
180 187 yield tmpl(ltype,
181 188 line=l,
182 189 lineid="l%s" % lineno,
183 190 linenumber="% 8s" % lineno)
184 191
185 192 if files:
186 193 m = match.exact(repo.root, repo.getcwd(), files)
187 194 else:
188 195 m = match.always(repo.root, repo.getcwd())
189 196
190 197 diffopts = patch.diffopts(repo.ui, untrusted=True)
191 198 parents = ctx.parents()
192 199 node1 = parents and parents[0].node() or nullid
193 200 node2 = ctx.node()
194 201
195 202 block = []
196 203 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
197 204 if chunk.startswith('diff') and block:
198 205 yield tmpl('diffblock', parity=parity.next(),
199 206 lines=prettyprintlines(''.join(block)))
200 207 block = []
201 208 if chunk.startswith('diff') and style != 'raw':
202 209 chunk = ''.join(chunk.splitlines(True)[1:])
203 210 block.append(chunk)
204 211 yield tmpl('diffblock', parity=parity.next(),
205 212 lines=prettyprintlines(''.join(block)))
206 213
207 214 class sessionvars(object):
208 215 def __init__(self, vars, start='?'):
209 216 self.start = start
210 217 self.vars = vars
211 218 def __getitem__(self, key):
212 219 return self.vars[key]
213 220 def __setitem__(self, key, value):
214 221 self.vars[key] = value
215 222 def __copy__(self):
216 223 return sessionvars(copy.copy(self.vars), self.start)
217 224 def __iter__(self):
218 225 separator = self.start
219 226 for key, value in self.vars.iteritems():
220 227 yield {'name': key, 'value': str(value), 'separator': separator}
221 228 separator = '&'
222 229
223 230 class wsgiui(ui.ui):
224 231 # default termwidth breaks under mod_wsgi
225 232 def termwidth(self):
226 233 return 80
@@ -1,74 +1,74 b''
1 1 {header}
2 2 <title>{repo|escape}: {node|short}</title>
3 3 </head>
4 4 <body>
5 5 <div class="container">
6 6 <div class="menu">
7 7 <div class="logo">
8 8 <a href="http://mercurial.selenic.com/">
9 9 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
10 10 </div>
11 11 <ul>
12 12 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
13 13 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
14 14 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
15 15 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
16 16 </ul>
17 17 <ul>
18 18 <li class="active">changeset</li>
19 19 <li><a href="{url}raw-rev/{node|short}{sessionvars%urlparameter}">raw</a></li>
20 20 <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">browse</a></li>
21 21 </ul>
22 22 <ul>
23 23 {archives%archiveentry}
24 24 </ul>
25 25 <ul>
26 26 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
27 27 </ul>
28 28 </div>
29 29
30 30 <div class="main">
31 31
32 32 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
33 <h3>changeset {rev}:{node|short} {changesetbranch%changelogbranchname} {changesettag}</h3>
33 <h3>changeset {rev}:{node|short} {changesetbranch%changelogbranchname} {changesettag} {changesetbookmark}</h3>
34 34
35 35 <form class="search" action="{url}log">
36 36 {sessionvars%hiddenformentry}
37 37 <p><input name="rev" id="search1" type="text" size="30" /></p>
38 38 <div id="hint">find changesets by author, revision,
39 39 files, or words in the commit message</div>
40 40 </form>
41 41
42 42 <div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
43 43
44 44 <table id="changesetEntry">
45 45 <tr>
46 46 <th class="author">author</th>
47 47 <td class="author">{author|obfuscate}</td>
48 48 </tr>
49 49 <tr>
50 50 <th class="date">date</th>
51 51 <td class="date">{date|date} ({date|age})</td></tr>
52 52 <tr>
53 53 <th class="author">parents</th>
54 54 <td class="author">{parent%changesetparent}</td>
55 55 </tr>
56 56 <tr>
57 57 <th class="author">children</th>
58 58 <td class="author">{child%changesetchild}</td>
59 59 </tr>
60 60 <tr>
61 61 <th class="files">files</th>
62 62 <td class="files">{files}</td>
63 63 </tr>
64 64 </table>
65 65
66 66 <div class="overflow">
67 67 <div class="sourcefirst"> line diff</div>
68 68
69 69 {diff}
70 70 </div>
71 71
72 72 </div>
73 73 </div>
74 74 {footer}
@@ -1,135 +1,141 b''
1 1 {header}
2 2 <title>{repo|escape}: revision graph</title>
3 3 <link rel="alternate" type="application/atom+xml"
4 4 href="{url}atom-log" title="Atom feed for {repo|escape}: log" />
5 5 <link rel="alternate" type="application/rss+xml"
6 6 href="{url}rss-log" title="RSS feed for {repo|escape}: log" />
7 7 <!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
8 8 </head>
9 9 <body>
10 10
11 11 <div class="container">
12 12 <div class="menu">
13 13 <div class="logo">
14 14 <a href="http://mercurial.selenic.com/">
15 15 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
16 16 </div>
17 17 <ul>
18 18 <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
19 19 <li class="active">graph</li>
20 20 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
21 21 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
22 22 </ul>
23 23 <ul>
24 24 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
25 25 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
26 26 </ul>
27 27 <ul>
28 28 <li><a href="{url}help{sessionvars%urlparameter}">help</a></li>
29 29 </ul>
30 30 </div>
31 31
32 32 <div class="main">
33 33 <h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
34 34 <h3>graph</h3>
35 35
36 36 <form class="search" action="{url}log">
37 37 {sessionvars%hiddenformentry}
38 38 <p><input name="rev" id="search1" type="text" size="30" /></p>
39 39 <div id="hint">find changesets by author, revision,
40 40 files, or words in the commit message</div>
41 41 </form>
42 42
43 43 <div class="navigate">
44 44 <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
45 45 <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
46 46 | rev {rev}: {changenav%navgraph}
47 47 </div>
48 48
49 49 <noscript><p>The revision graph only works with JavaScript-enabled browsers.</p></noscript>
50 50
51 51 <div id="wrapper">
52 52 <ul id="nodebgs"></ul>
53 53 <canvas id="graph" width="224" height="{canvasheight}"></canvas>
54 54 <ul id="graphnodes"></ul>
55 55 </div>
56 56
57 57 <script type="text/javascript" src="{staticurl}graph.js"></script>
58 58 <script type="text/javascript">
59 59 <!-- hide script content
60 60
61 61 var data = {jsdata|json};
62 62 var graph = new Graph();
63 63 graph.scale({bg_height});
64 64
65 65 graph.edge = function(x0, y0, x1, y1, color) \{
66 66
67 67 this.setColor(color, 0.0, 0.65);
68 68 this.ctx.beginPath();
69 69 this.ctx.moveTo(x0, y0);
70 70 this.ctx.lineTo(x1, y1);
71 71 this.ctx.stroke();
72 72
73 73 }
74 74
75 75 var revlink = '<li style="_STYLE"><span class="desc">';
76 76 revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
77 77 revlink += '</span>_TAGS<span class="info">_DATE, by _USER</span></li>';
78 78
79 79 graph.vertex = function(x, y, color, parity, cur) \{
80 80
81 81 this.ctx.beginPath();
82 82 color = this.setColor(color, 0.25, 0.75);
83 83 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
84 84 this.ctx.fill();
85 85
86 86 var bg = '<li class="bg parity' + parity + '"></li>';
87 87 var left = (this.columns + 1) * this.bg_height;
88 88 var nstyle = 'padding-left: ' + left + 'px;';
89 89 var item = revlink.replace(/_STYLE/, nstyle);
90 90 item = item.replace(/_PARITY/, 'parity' + parity);
91 91 item = item.replace(/_NODEID/, cur[0]);
92 92 item = item.replace(/_NODEID/, cur[0]);
93 93 item = item.replace(/_DESC/, cur[3]);
94 94 item = item.replace(/_USER/, cur[4]);
95 95 item = item.replace(/_DATE/, cur[5]);
96 96
97 97 var tagspan = '';
98 98 if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) \{
99 99 tagspan = '<span class="logtags">';
100 100 if (cur[6][1]) \{
101 101 tagspan += '<span class="branchhead" title="' + cur[6][0] + '">';
102 102 tagspan += cur[6][0] + '</span> ';
103 103 } else if (!cur[6][1] && cur[6][0] != 'default') \{
104 104 tagspan += '<span class="branchname" title="' + cur[6][0] + '">';
105 105 tagspan += cur[6][0] + '</span> ';
106 106 }
107 107 if (cur[7].length) \{
108 108 for (var t in cur[7]) \{
109 109 var tag = cur[7][t];
110 110 tagspan += '<span class="tag">' + tag + '</span> ';
111 111 }
112 112 }
113 if (cur[8].length) \{
114 for (var b in cur[8]) \{
115 var bookmark = cur[8][b];
116 tagspan += '<span class="tag">' + bookmark + '</span> ';
117 }
118 }
113 119 tagspan += '</span>';
114 120 }
115 121
116 122 item = item.replace(/_TAGS/, tagspan);
117 123 return [bg, item];
118 124
119 125 }
120 126
121 127 graph.render(data);
122 128
123 129 // stop hiding script -->
124 130 </script>
125 131
126 132 <div class="navigate">
127 133 <a href="{url}graph/{rev}{lessvars%urlparameter}">less</a>
128 134 <a href="{url}graph/{rev}{morevars%urlparameter}">more</a>
129 135 | rev {rev}: {changenav%navgraph}
130 136 </div>
131 137
132 138 </div>
133 139 </div>
134 140
135 141 {footer}
@@ -1,200 +1,201 b''
1 1 default = 'shortlog'
2 2
3 3 mimetype = 'text/html; charset={encoding}'
4 4 header = header.tmpl
5 5 footer = footer.tmpl
6 6 search = search.tmpl
7 7
8 8 changelog = shortlog.tmpl
9 9 shortlog = shortlog.tmpl
10 10 shortlogentry = shortlogentry.tmpl
11 11 graph = graph.tmpl
12 12 help = help.tmpl
13 13 helptopics = helptopics.tmpl
14 14
15 15 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
16 16
17 17 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 18 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 19 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
20 20 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
21 21 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
22 22 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
23 23 filenolink = '{file|escape} '
24 24 fileellipses = '...'
25 25 changelogentry = shortlogentry.tmpl
26 26 searchentry = shortlogentry.tmpl
27 27 changeset = changeset.tmpl
28 28 manifest = manifest.tmpl
29 29
30 30 nav = '{before%naventry} {after%naventry}'
31 31 navshort = '{before%navshortentry}{after%navshortentry}'
32 32 navgraph = '{before%navgraphentry}{after%navgraphentry}'
33 33 filenav = '{before%filenaventry}{after%filenaventry}'
34 34
35 35 direntry = '
36 36 <tr class="fileline parity{parity}">
37 37 <td class="name">
38 38 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">
39 39 <img src="{staticurl}coal-folder.png" alt="dir."/> {basename|escape}/
40 40 </a>
41 41 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
42 42 {emptydirs|escape}
43 43 </a>
44 44 </td>
45 45 <td class="size"></td>
46 46 <td class="permissions">drwxr-xr-x</td>
47 47 </tr>'
48 48
49 49 fileentry = '
50 50 <tr class="fileline parity{parity}">
51 51 <td class="filename">
52 52 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
53 53 <img src="{staticurl}coal-file.png" alt="file"/> {basename|escape}
54 54 </a>
55 55 </td>
56 56 <td class="size">{size}</td>
57 57 <td class="permissions">{permissions|permissions}</td>
58 58 </tr>'
59 59
60 60 filerevision = filerevision.tmpl
61 61 fileannotate = fileannotate.tmpl
62 62 filediff = filediff.tmpl
63 63 filelog = filelog.tmpl
64 64 fileline = '
65 65 <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
66 66 filelogentry = filelogentry.tmpl
67 67
68 68 annotateline = '
69 69 <tr class="parity{parity}">
70 70 <td class="annotate">
71 71 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}"
72 72 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
73 73 </td>
74 74 <td class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</td>
75 75 </tr>'
76 76
77 77 diffblock = '<div class="source bottomline parity{parity}"><pre>{lines}</pre></div>'
78 78 difflineplus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="plusline">{line|escape}</span>'
79 79 difflineminus = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="minusline">{line|escape}</span>'
80 80 difflineat = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> <span class="atline">{line|escape}</span>'
81 81 diffline = '<a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}'
82 82
83 83 changelogparent = '
84 84 <tr>
85 85 <th class="parent">parent {rev}:</th>
86 86 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
87 87 </tr>'
88 88
89 89 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
90 90
91 91 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
92 92 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
93 93
94 94 filerename = '{file|escape}@'
95 95 filelogrename = '
96 96 <tr>
97 97 <th>base:</th>
98 98 <td>
99 99 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
100 100 {file|escape}@{node|short}
101 101 </a>
102 102 </td>
103 103 </tr>'
104 104 fileannotateparent = '
105 105 <tr>
106 106 <td class="metatag">parent:</td>
107 107 <td>
108 108 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
109 109 {rename%filerename}{node|short}
110 110 </a>
111 111 </td>
112 112 </tr>'
113 113 changesetchild = ' <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
114 114 changelogchild = '
115 115 <tr>
116 116 <th class="child">child</th>
117 117 <td class="child">
118 118 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
119 119 {node|short}
120 120 </a>
121 121 </td>
122 122 </tr>'
123 123 fileannotatechild = '
124 124 <tr>
125 125 <td class="metatag">child:</td>
126 126 <td>
127 127 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
128 128 {node|short}
129 129 </a>
130 130 </td>
131 131 </tr>'
132 132 tags = tags.tmpl
133 133 tagentry = '
134 134 <tr class="tagEntry parity{parity}">
135 135 <td>
136 136 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
137 137 {tag|escape}
138 138 </a>
139 139 </td>
140 140 <td class="node">
141 141 {node|short}
142 142 </td>
143 143 </tr>'
144 144 branches = branches.tmpl
145 145 branchentry = '
146 146 <tr class="tagEntry parity{parity}">
147 147 <td>
148 148 <a href="{url}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
149 149 {branch|escape}
150 150 </a>
151 151 </td>
152 152 <td class="node">
153 153 {node|short}
154 154 </td>
155 155 </tr>'
156 156 changelogtag = '<span class="tag">{name|escape}</span> '
157 157 changesettag = '<span class="tag">{tag|escape}</span> '
158 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
158 159 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
159 160 changelogbranchname = '<span class="branchname">{name|escape}</span> '
160 161
161 162 filediffparent = '
162 163 <tr>
163 164 <th class="parent">parent {rev}:</th>
164 165 <td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
165 166 </tr>'
166 167 filelogparent = '
167 168 <tr>
168 169 <th>parent {rev}:</th>
169 170 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
170 171 </tr>'
171 172 filediffchild = '
172 173 <tr>
173 174 <th class="child">child {rev}:</th>
174 175 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
175 176 </td>
176 177 </tr>'
177 178 filelogchild = '
178 179 <tr>
179 180 <th>child {rev}:</th>
180 181 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
181 182 </tr>'
182 183
183 184 indexentry = '
184 185 <tr class="parity{parity}">
185 186 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
186 187 <td>{description}</td>
187 188 <td>{contact|obfuscate}</td>
188 189 <td class="age">{lastchange|age}</td>
189 190 <td class="indexlinks">{archives%indexarchiveentry}</td>
190 191 </tr>\n'
191 192 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
192 193 index = index.tmpl
193 194 archiveentry = '
194 195 <li>
195 196 <a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a>
196 197 </li>'
197 198 notfound = notfound.tmpl
198 199 error = error.tmpl
199 200 urlparameter = '{separator}{name}={value|urlescape}'
200 201 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
@@ -1,5 +1,5 b''
1 1 <tr class="parity{parity}">
2 2 <td class="age">{age(date)}</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|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags % '<span class="tag">{name|escape}</span> '}</td>
4 <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags % '<span class="tag">{name|escape}</span> '}{bookmarks % '<span class="tag">{name|escape}</span> '}</td>
5 5 </tr>
@@ -1,1077 +1,1078 b''
1 1 An attempt at more fully testing the hgweb web interface.
2 2 The following things are tested elsewhere and are therefore omitted:
3 3 - archive, tested in test-archive
4 4 - unbundle, tested in test-push-http
5 5 - changegroupsubset, tested in test-pull
6 6
7 7 Set up the repo
8 8
9 9 $ hg init test
10 10 $ cd test
11 11 $ mkdir da
12 12 $ echo foo > da/foo
13 13 $ echo foo > foo
14 14 $ hg ci -Ambase
15 15 adding da/foo
16 16 adding foo
17 17 $ hg tag 1.0
18 $ hg bookmark something
18 19 $ echo another > foo
19 20 $ hg branch stable
20 21 marked working directory as branch stable
21 22 $ hg ci -Ambranch
22 23 $ hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
23 24 $ cat hg.pid >> $DAEMON_PIDS
24 25
25 26 Logs and changes
26 27
27 28 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom'
28 29 200 Script output follows
29 30
30 31 <?xml version="1.0" encoding="ascii"?>
31 32 <feed xmlns="http://www.w3.org/2005/Atom">
32 33 <!-- Changelog -->
33 34 <id>http://*:$HGPORT/</id> (glob)
34 35 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
35 36 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
36 37 <title>test Changelog</title>
37 38 <updated>1970-01-01T00:00:00+00:00</updated>
38 39
39 40 <entry>
40 41 <title>branch</title>
41 42 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
42 43 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
43 44 <author>
44 45 <name>test</name>
45 46 <email>&#116;&#101;&#115;&#116;</email>
46 47 </author>
47 48 <updated>1970-01-01T00:00:00+00:00</updated>
48 49 <published>1970-01-01T00:00:00+00:00</published>
49 50 <content type="xhtml">
50 51 <div xmlns="http://www.w3.org/1999/xhtml">
51 52 <pre xml:space="preserve">branch</pre>
52 53 </div>
53 54 </content>
54 55 </entry>
55 56 <entry>
56 57 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
57 58 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
58 59 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
59 60 <author>
60 61 <name>test</name>
61 62 <email>&#116;&#101;&#115;&#116;</email>
62 63 </author>
63 64 <updated>1970-01-01T00:00:00+00:00</updated>
64 65 <published>1970-01-01T00:00:00+00:00</published>
65 66 <content type="xhtml">
66 67 <div xmlns="http://www.w3.org/1999/xhtml">
67 68 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
68 69 </div>
69 70 </content>
70 71 </entry>
71 72 <entry>
72 73 <title>base</title>
73 74 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
74 75 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
75 76 <author>
76 77 <name>test</name>
77 78 <email>&#116;&#101;&#115;&#116;</email>
78 79 </author>
79 80 <updated>1970-01-01T00:00:00+00:00</updated>
80 81 <published>1970-01-01T00:00:00+00:00</published>
81 82 <content type="xhtml">
82 83 <div xmlns="http://www.w3.org/1999/xhtml">
83 84 <pre xml:space="preserve">base</pre>
84 85 </div>
85 86 </content>
86 87 </entry>
87 88
88 89 </feed>
89 90 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom'
90 91 200 Script output follows
91 92
92 93 <?xml version="1.0" encoding="ascii"?>
93 94 <feed xmlns="http://www.w3.org/2005/Atom">
94 95 <!-- Changelog -->
95 96 <id>http://*:$HGPORT/</id> (glob)
96 97 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
97 98 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
98 99 <title>test Changelog</title>
99 100 <updated>1970-01-01T00:00:00+00:00</updated>
100 101
101 102 <entry>
102 103 <title>branch</title>
103 104 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
104 105 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
105 106 <author>
106 107 <name>test</name>
107 108 <email>&#116;&#101;&#115;&#116;</email>
108 109 </author>
109 110 <updated>1970-01-01T00:00:00+00:00</updated>
110 111 <published>1970-01-01T00:00:00+00:00</published>
111 112 <content type="xhtml">
112 113 <div xmlns="http://www.w3.org/1999/xhtml">
113 114 <pre xml:space="preserve">branch</pre>
114 115 </div>
115 116 </content>
116 117 </entry>
117 118 <entry>
118 119 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
119 120 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
120 121 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
121 122 <author>
122 123 <name>test</name>
123 124 <email>&#116;&#101;&#115;&#116;</email>
124 125 </author>
125 126 <updated>1970-01-01T00:00:00+00:00</updated>
126 127 <published>1970-01-01T00:00:00+00:00</published>
127 128 <content type="xhtml">
128 129 <div xmlns="http://www.w3.org/1999/xhtml">
129 130 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
130 131 </div>
131 132 </content>
132 133 </entry>
133 134 <entry>
134 135 <title>base</title>
135 136 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
136 137 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
137 138 <author>
138 139 <name>test</name>
139 140 <email>&#116;&#101;&#115;&#116;</email>
140 141 </author>
141 142 <updated>1970-01-01T00:00:00+00:00</updated>
142 143 <published>1970-01-01T00:00:00+00:00</published>
143 144 <content type="xhtml">
144 145 <div xmlns="http://www.w3.org/1999/xhtml">
145 146 <pre xml:space="preserve">base</pre>
146 147 </div>
147 148 </content>
148 149 </entry>
149 150
150 151 </feed>
151 152 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom'
152 153 200 Script output follows
153 154
154 155 <?xml version="1.0" encoding="ascii"?>
155 156 <feed xmlns="http://www.w3.org/2005/Atom">
156 157 <id>http://*:$HGPORT/atom-log/tip/foo</id> (glob)
157 158 <link rel="self" href="http://*:$HGPORT/atom-log/tip/foo"/> (glob)
158 159 <title>test: foo history</title>
159 160 <updated>1970-01-01T00:00:00+00:00</updated>
160 161
161 162 <entry>
162 163 <title>base</title>
163 164 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
164 165 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
165 166 <author>
166 167 <name>test</name>
167 168 <email>&#116;&#101;&#115;&#116;</email>
168 169 </author>
169 170 <updated>1970-01-01T00:00:00+00:00</updated>
170 171 <published>1970-01-01T00:00:00+00:00</published>
171 172 <content type="xhtml">
172 173 <div xmlns="http://www.w3.org/1999/xhtml">
173 174 <pre xml:space="preserve">base</pre>
174 175 </div>
175 176 </content>
176 177 </entry>
177 178
178 179 </feed>
179 180 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
180 181 200 Script output follows
181 182
182 183 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
183 184 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
184 185 <head>
185 186 <link rel="icon" href="/static/hgicon.png" type="image/png" />
186 187 <meta name="robots" content="index, nofollow" />
187 188 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
188 189
189 190 <title>test: log</title>
190 191 <link rel="alternate" type="application/atom+xml"
191 192 href="/atom-log" title="Atom feed for test" />
192 193 <link rel="alternate" type="application/rss+xml"
193 194 href="/rss-log" title="RSS feed for test" />
194 195 </head>
195 196 <body>
196 197
197 198 <div class="container">
198 199 <div class="menu">
199 200 <div class="logo">
200 201 <a href="http://mercurial.selenic.com/">
201 202 <img src="/static/hglogo.png" alt="mercurial" /></a>
202 203 </div>
203 204 <ul>
204 205 <li class="active">log</li>
205 206 <li><a href="/graph/1d22e65f027e">graph</a></li>
206 207 <li><a href="/tags">tags</a></li>
207 208 <li><a href="/branches">branches</a></li>
208 209 </ul>
209 210 <ul>
210 211 <li><a href="/rev/1d22e65f027e">changeset</a></li>
211 212 <li><a href="/file/1d22e65f027e">browse</a></li>
212 213 </ul>
213 214 <ul>
214 215
215 216 </ul>
216 217 <ul>
217 218 <li><a href="/help">help</a></li>
218 219 </ul>
219 220 </div>
220 221
221 222 <div class="main">
222 223 <h2><a href="/">test</a></h2>
223 224 <h3>log</h3>
224 225
225 226 <form class="search" action="/log">
226 227
227 228 <p><input name="rev" id="search1" type="text" size="30" /></p>
228 229 <div id="hint">find changesets by author, revision,
229 230 files, or words in the commit message</div>
230 231 </form>
231 232
232 233 <div class="navigate">
233 234 <a href="/shortlog/2?revcount=30">less</a>
234 235 <a href="/shortlog/2?revcount=120">more</a>
235 236 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
236 237 </div>
237 238
238 239 <table class="bigtable">
239 240 <tr>
240 241 <th class="age">age</th>
241 242 <th class="author">author</th>
242 243 <th class="description">description</th>
243 244 </tr>
244 245 <tr class="parity0">
245 246 <td class="age">1970-01-01</td>
246 247 <td class="author">test</td>
247 <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> </td>
248 <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> <span class="tag">something</span> </td>
248 249 </tr>
249 250 <tr class="parity1">
250 251 <td class="age">1970-01-01</td>
251 252 <td class="author">test</td>
252 253 <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td>
253 254 </tr>
254 255 <tr class="parity0">
255 256 <td class="age">1970-01-01</td>
256 257 <td class="author">test</td>
257 258 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> </td>
258 259 </tr>
259 260
260 261 </table>
261 262
262 263 <div class="navigate">
263 264 <a href="/shortlog/2?revcount=30">less</a>
264 265 <a href="/shortlog/2?revcount=120">more</a>
265 266 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
266 267 </div>
267 268
268 269 </div>
269 270 </div>
270 271
271 272
272 273
273 274 </body>
274 275 </html>
275 276
276 277 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
277 278 200 Script output follows
278 279
279 280 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
280 281 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
281 282 <head>
282 283 <link rel="icon" href="/static/hgicon.png" type="image/png" />
283 284 <meta name="robots" content="index, nofollow" />
284 285 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
285 286
286 287 <title>test: 2ef0ac749a14</title>
287 288 </head>
288 289 <body>
289 290 <div class="container">
290 291 <div class="menu">
291 292 <div class="logo">
292 293 <a href="http://mercurial.selenic.com/">
293 294 <img src="/static/hglogo.png" alt="mercurial" /></a>
294 295 </div>
295 296 <ul>
296 297 <li><a href="/shortlog/2ef0ac749a14">log</a></li>
297 298 <li><a href="/graph/2ef0ac749a14">graph</a></li>
298 299 <li><a href="/tags">tags</a></li>
299 300 <li><a href="/branches">branches</a></li>
300 301 </ul>
301 302 <ul>
302 303 <li class="active">changeset</li>
303 304 <li><a href="/raw-rev/2ef0ac749a14">raw</a></li>
304 305 <li><a href="/file/2ef0ac749a14">browse</a></li>
305 306 </ul>
306 307 <ul>
307 308
308 309 </ul>
309 310 <ul>
310 311 <li><a href="/help">help</a></li>
311 312 </ul>
312 313 </div>
313 314
314 315 <div class="main">
315 316
316 317 <h2><a href="/">test</a></h2>
317 <h3>changeset 0:2ef0ac749a14 <span class="tag">1.0</span> </h3>
318 <h3>changeset 0:2ef0ac749a14 <span class="tag">1.0</span> </h3>
318 319
319 320 <form class="search" action="/log">
320 321
321 322 <p><input name="rev" id="search1" type="text" size="30" /></p>
322 323 <div id="hint">find changesets by author, revision,
323 324 files, or words in the commit message</div>
324 325 </form>
325 326
326 327 <div class="description">base</div>
327 328
328 329 <table id="changesetEntry">
329 330 <tr>
330 331 <th class="author">author</th>
331 332 <td class="author">&#116;&#101;&#115;&#116;</td>
332 333 </tr>
333 334 <tr>
334 335 <th class="date">date</th>
335 336 <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
336 337 <tr>
337 338 <th class="author">parents</th>
338 339 <td class="author"></td>
339 340 </tr>
340 341 <tr>
341 342 <th class="author">children</th>
342 343 <td class="author"> <a href="/rev/a4f92ed23982">a4f92ed23982</a></td>
343 344 </tr>
344 345 <tr>
345 346 <th class="files">files</th>
346 347 <td class="files"><a href="/file/2ef0ac749a14/da/foo">da/foo</a> <a href="/file/2ef0ac749a14/foo">foo</a> </td>
347 348 </tr>
348 349 </table>
349 350
350 351 <div class="overflow">
351 352 <div class="sourcefirst"> line diff</div>
352 353
353 354 <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
354 355 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/da/foo Thu Jan 01 00:00:00 1970 +0000
355 356 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
356 357 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+foo
357 358 </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
358 359 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/foo Thu Jan 01 00:00:00 1970 +0000
359 360 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
360 361 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+foo
361 362 </span></pre></div>
362 363 </div>
363 364
364 365 </div>
365 366 </div>
366 367
367 368
368 369 </body>
369 370 </html>
370 371
371 372 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
372 373 200 Script output follows
373 374
374 375
375 376 # HG changeset patch
376 377 # User test
377 378 # Date 0 0
378 379 # Node ID a4f92ed23982be056b9852de5dfe873eaac7f0de
379 380 # Parent 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
380 381 Added tag 1.0 for changeset 2ef0ac749a14
381 382
382 383 diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags
383 384 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
384 385 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
385 386 @@ -0,0 +1,1 @@
386 387 +2ef0ac749a14e4f57a5a822464a0902c6f7f448f 1.0
387 388
388 389 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
389 390 200 Script output follows
390 391
391 392 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
392 393 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
393 394 <head>
394 395 <link rel="icon" href="/static/hgicon.png" type="image/png" />
395 396 <meta name="robots" content="index, nofollow" />
396 397 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
397 398
398 399 <title>test: searching for base</title>
399 400 </head>
400 401 <body>
401 402
402 403 <div class="container">
403 404 <div class="menu">
404 405 <div class="logo">
405 406 <a href="http://mercurial.selenic.com/">
406 407 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
407 408 </div>
408 409 <ul>
409 410 <li><a href="/shortlog">log</a></li>
410 411 <li><a href="/graph">graph</a></li>
411 412 <li><a href="/tags">tags</a></li>
412 413 <li><a href="/branches">branches</a></li>
413 414 <li><a href="/help">help</a></li>
414 415 </ul>
415 416 </div>
416 417
417 418 <div class="main">
418 419 <h2><a href="/">test</a></h2>
419 420 <h3>searching for 'base'</h3>
420 421
421 422 <form class="search" action="/log">
422 423
423 424 <p><input name="rev" id="search1" type="text" size="30"></p>
424 425 <div id="hint">find changesets by author, revision,
425 426 files, or words in the commit message</div>
426 427 </form>
427 428
428 429 <div class="navigate">
429 430 <a href="/search/?rev=base&revcount=5">less</a>
430 431 <a href="/search/?rev=base&revcount=20">more</a>
431 432 </div>
432 433
433 434 <table class="bigtable">
434 435 <tr>
435 436 <th class="age">age</th>
436 437 <th class="author">author</th>
437 438 <th class="description">description</th>
438 439 </tr>
439 440 <tr class="parity0">
440 441 <td class="age">1970-01-01</td>
441 442 <td class="author">test</td>
442 443 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> </td>
443 444 </tr>
444 445
445 446 </table>
446 447
447 448 <div class="navigate">
448 449 <a href="/search/?rev=base&revcount=5">less</a>
449 450 <a href="/search/?rev=base&revcount=20">more</a>
450 451 </div>
451 452
452 453 </div>
453 454 </div>
454 455
455 456
456 457
457 458 </body>
458 459 </html>
459 460
460 461
461 462 File-related
462 463
463 464 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
464 465 200 Script output follows
465 466
466 467 foo
467 468 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
468 469 200 Script output follows
469 470
470 471
471 472 test@0: foo
472 473
473 474
474 475
475 476
476 477 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
477 478 200 Script output follows
478 479
479 480
480 481 drwxr-xr-x da
481 482 -rw-r--r-- 45 .hgtags
482 483 -rw-r--r-- 4 foo
483 484
484 485
485 486 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
486 487 200 Script output follows
487 488
488 489 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
489 490 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
490 491 <head>
491 492 <link rel="icon" href="/static/hgicon.png" type="image/png" />
492 493 <meta name="robots" content="index, nofollow" />
493 494 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
494 495
495 496 <title>test: a4f92ed23982 foo</title>
496 497 </head>
497 498 <body>
498 499
499 500 <div class="container">
500 501 <div class="menu">
501 502 <div class="logo">
502 503 <a href="http://mercurial.selenic.com/">
503 504 <img src="/static/hglogo.png" alt="mercurial" /></a>
504 505 </div>
505 506 <ul>
506 507 <li><a href="/shortlog/a4f92ed23982">log</a></li>
507 508 <li><a href="/graph/a4f92ed23982">graph</a></li>
508 509 <li><a href="/tags">tags</a></li>
509 510 <li><a href="/branches">branches</a></li>
510 511 </ul>
511 512 <ul>
512 513 <li><a href="/rev/a4f92ed23982">changeset</a></li>
513 514 <li><a href="/file/a4f92ed23982/">browse</a></li>
514 515 </ul>
515 516 <ul>
516 517 <li class="active">file</li>
517 518 <li><a href="/file/tip/foo">latest</a></li>
518 519 <li><a href="/diff/a4f92ed23982/foo">diff</a></li>
519 520 <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li>
520 521 <li><a href="/log/a4f92ed23982/foo">file log</a></li>
521 522 <li><a href="/raw-file/a4f92ed23982/foo">raw</a></li>
522 523 </ul>
523 524 <ul>
524 525 <li><a href="/help">help</a></li>
525 526 </ul>
526 527 </div>
527 528
528 529 <div class="main">
529 530 <h2><a href="/">test</a></h2>
530 531 <h3>view foo @ 1:a4f92ed23982</h3>
531 532
532 533 <form class="search" action="/log">
533 534
534 535 <p><input name="rev" id="search1" type="text" size="30" /></p>
535 536 <div id="hint">find changesets by author, revision,
536 537 files, or words in the commit message</div>
537 538 </form>
538 539
539 540 <div class="description">Added tag 1.0 for changeset 2ef0ac749a14</div>
540 541
541 542 <table id="changesetEntry">
542 543 <tr>
543 544 <th class="author">author</th>
544 545 <td class="author">&#116;&#101;&#115;&#116;</td>
545 546 </tr>
546 547 <tr>
547 548 <th class="date">date</th>
548 549 <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
549 550 </tr>
550 551 <tr>
551 552 <th class="author">parents</th>
552 553 <td class="author"></td>
553 554 </tr>
554 555 <tr>
555 556 <th class="author">children</th>
556 557 <td class="author"><a href="/file/1d22e65f027e/foo">1d22e65f027e</a> </td>
557 558 </tr>
558 559
559 560 </table>
560 561
561 562 <div class="overflow">
562 563 <div class="sourcefirst"> line source</div>
563 564
564 565 <div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
565 566 </div>
566 567 <div class="sourcelast"></div>
567 568 </div>
568 569 </div>
569 570 </div>
570 571
571 572
572 573
573 574 </body>
574 575 </html>
575 576
576 577 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
577 578 200 Script output follows
578 579
579 580
580 581 diff -r 000000000000 -r a4f92ed23982 foo
581 582 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
582 583 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
583 584 @@ -0,0 +1,1 @@
584 585 +foo
585 586
586 587
587 588
588 589
589 590
590 591 Overviews
591 592
592 593 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
593 594 200 Script output follows
594 595
595 596 tip 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
596 597 1.0 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
597 598 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
598 599 200 Script output follows
599 600
600 601 stable 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe open
601 602 default a4f92ed23982be056b9852de5dfe873eaac7f0de inactive
602 603 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
603 604 200 Script output follows
604 605
605 606 <?xml version="1.0" encoding="ascii"?>
606 607 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
607 608 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
608 609 <head>
609 610 <link rel="icon" href="/static/hgicon.png" type="image/png" />
610 611 <meta name="robots" content="index, nofollow"/>
611 612 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
612 613
613 614
614 615 <title>test: Summary</title>
615 616 <link rel="alternate" type="application/atom+xml"
616 617 href="/atom-log" title="Atom feed for test"/>
617 618 <link rel="alternate" type="application/rss+xml"
618 619 href="/rss-log" title="RSS feed for test"/>
619 620 </head>
620 621 <body>
621 622
622 623 <div class="page_header">
623 624 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / summary
624 625
625 626 <form action="/log">
626 627 <input type="hidden" name="style" value="gitweb" />
627 628 <div class="search">
628 629 <input type="text" name="rev" />
629 630 </div>
630 631 </form>
631 632 </div>
632 633
633 634 <div class="page_nav">
634 635 summary |
635 636 <a href="/shortlog?style=gitweb">shortlog</a> |
636 637 <a href="/log?style=gitweb">changelog</a> |
637 638 <a href="/graph?style=gitweb">graph</a> |
638 639 <a href="/tags?style=gitweb">tags</a> |
639 640 <a href="/branches?style=gitweb">branches</a> |
640 641 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
641 642 <a href="/help?style=gitweb">help</a>
642 643 <br/>
643 644 </div>
644 645
645 646 <div class="title">&nbsp;</div>
646 647 <table cellspacing="0">
647 648 <tr><td>description</td><td>unknown</td></tr>
648 649 <tr><td>owner</td><td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td></tr>
649 650 <tr><td>last change</td><td>Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
650 651 </table>
651 652
652 653 <div><a class="title" href="/shortlog?style=gitweb">changes</a></div>
653 654 <table cellspacing="0">
654 655
655 656 <tr class="parity0">
656 657 <td class="age"><i>1970-01-01</i></td>
657 658 <td><i>test</i></td>
658 659 <td>
659 660 <a class="list" href="/rev/1d22e65f027e?style=gitweb">
660 661 <b>branch</b>
661 662 <span class="logtags"><span class="branchtag" title="stable">stable</span> <span class="tagtag" title="tip">tip</span> </span>
662 663 </a>
663 664 </td>
664 665 <td class="link" nowrap>
665 666 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
666 667 <a href="/file/1d22e65f027e?style=gitweb">files</a>
667 668 </td>
668 669 </tr>
669 670 <tr class="parity1">
670 671 <td class="age"><i>1970-01-01</i></td>
671 672 <td><i>test</i></td>
672 673 <td>
673 674 <a class="list" href="/rev/a4f92ed23982?style=gitweb">
674 675 <b>Added tag 1.0 for changeset 2ef0ac749a14</b>
675 676 <span class="logtags"><span class="branchtag" title="default">default</span> </span>
676 677 </a>
677 678 </td>
678 679 <td class="link" nowrap>
679 680 <a href="/rev/a4f92ed23982?style=gitweb">changeset</a> |
680 681 <a href="/file/a4f92ed23982?style=gitweb">files</a>
681 682 </td>
682 683 </tr>
683 684 <tr class="parity0">
684 685 <td class="age"><i>1970-01-01</i></td>
685 686 <td><i>test</i></td>
686 687 <td>
687 688 <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
688 689 <b>base</b>
689 690 <span class="logtags"><span class="tagtag" title="1.0">1.0</span> </span>
690 691 </a>
691 692 </td>
692 693 <td class="link" nowrap>
693 694 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
694 695 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
695 696 </td>
696 697 </tr>
697 698 <tr class="light"><td colspan="4"><a class="list" href="/shortlog?style=gitweb">...</a></td></tr>
698 699 </table>
699 700
700 701 <div><a class="title" href="/tags?style=gitweb">tags</a></div>
701 702 <table cellspacing="0">
702 703
703 704 <tr class="parity0">
704 705 <td class="age"><i>1970-01-01</i></td>
705 706 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td>
706 707 <td class="link">
707 708 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
708 709 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
709 710 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
710 711 </td>
711 712 </tr>
712 713 <tr class="light"><td colspan="3"><a class="list" href="/tags?style=gitweb">...</a></td></tr>
713 714 </table>
714 715
715 716 <div><a class="title" href="#">branches</a></div>
716 717 <table cellspacing="0">
717 718
718 719 <tr class="parity0">
719 720 <td class="age"><i>1970-01-01</i></td>
720 721 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
721 722 <td class="">stable</td>
722 723 <td class="link">
723 724 <a href="/changeset/1d22e65f027e?style=gitweb">changeset</a> |
724 725 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
725 726 <a href="/file/1d22e65f027e?style=gitweb">files</a>
726 727 </td>
727 728 </tr>
728 729 <tr class="parity1">
729 730 <td class="age"><i>1970-01-01</i></td>
730 731 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
731 732 <td class="">default</td>
732 733 <td class="link">
733 734 <a href="/changeset/a4f92ed23982?style=gitweb">changeset</a> |
734 735 <a href="/log/a4f92ed23982?style=gitweb">changelog</a> |
735 736 <a href="/file/a4f92ed23982?style=gitweb">files</a>
736 737 </td>
737 738 </tr>
738 739 <tr class="light">
739 740 <td colspan="4"><a class="list" href="#">...</a></td>
740 741 </tr>
741 742 </table>
742 743 <div class="page_footer">
743 744 <div class="page_footer_text">test</div>
744 745 <div class="rss_logo">
745 746 <a href="/rss-log">RSS</a>
746 747 <a href="/atom-log">Atom</a>
747 748 </div>
748 749 <br />
749 750
750 751 </div>
751 752 </body>
752 753 </html>
753 754
754 755 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
755 756 200 Script output follows
756 757
757 758 <?xml version="1.0" encoding="ascii"?>
758 759 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
759 760 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
760 761 <head>
761 762 <link rel="icon" href="/static/hgicon.png" type="image/png" />
762 763 <meta name="robots" content="index, nofollow"/>
763 764 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
764 765
765 766
766 767 <title>test: Graph</title>
767 768 <link rel="alternate" type="application/atom+xml"
768 769 href="/atom-log" title="Atom feed for test"/>
769 770 <link rel="alternate" type="application/rss+xml"
770 771 href="/rss-log" title="RSS feed for test"/>
771 772 <!--[if IE]><script type="text/javascript" src="/static/excanvas.js"></script><![endif]-->
772 773 </head>
773 774 <body>
774 775
775 776 <div class="page_header">
776 777 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / graph
777 778 </div>
778 779
779 780 <form action="/log">
780 781 <input type="hidden" name="style" value="gitweb" />
781 782 <div class="search">
782 783 <input type="text" name="rev" />
783 784 </div>
784 785 </form>
785 786 <div class="page_nav">
786 787 <a href="/summary?style=gitweb">summary</a> |
787 788 <a href="/shortlog?style=gitweb">shortlog</a> |
788 789 <a href="/log/2?style=gitweb">changelog</a> |
789 790 graph |
790 791 <a href="/tags?style=gitweb">tags</a> |
791 792 <a href="/branches?style=gitweb">branches</a> |
792 793 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
793 794 <a href="/help?style=gitweb">help</a>
794 795 <br/>
795 796 <a href="/graph/2?style=gitweb&revcount=30">less</a>
796 797 <a href="/graph/2?style=gitweb&revcount=120">more</a>
797 798 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a> <br/>
798 799 </div>
799 800
800 801 <div class="title">&nbsp;</div>
801 802
802 803 <noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
803 804
804 805 <div id="wrapper">
805 806 <ul id="nodebgs"></ul>
806 807 <canvas id="graph" width="224" height="129"></canvas>
807 808 <ul id="graphnodes"></ul>
808 809 </div>
809 810
810 811 <script type="text/javascript" src="/static/graph.js"></script>
811 812 <script>
812 813 <!-- hide script content
813 814
814 var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"]]];
815 var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], []]];
815 816 var graph = new Graph();
816 817 graph.scale(39);
817 818
818 819 graph.edge = function(x0, y0, x1, y1, color) {
819 820
820 821 this.setColor(color, 0.0, 0.65);
821 822 this.ctx.beginPath();
822 823 this.ctx.moveTo(x0, y0);
823 824 this.ctx.lineTo(x1, y1);
824 825 this.ctx.stroke();
825 826
826 827 }
827 828
828 829 var revlink = '<li style="_STYLE"><span class="desc">';
829 830 revlink += '<a class="list" href="/rev/_NODEID?style=gitweb" title="_NODEID"><b>_DESC</b></a>';
830 831 revlink += '</span> _TAGS';
831 832 revlink += '<span class="info">_DATE, by _USER</span></li>';
832 833
833 834 graph.vertex = function(x, y, color, parity, cur) {
834 835
835 836 this.ctx.beginPath();
836 837 color = this.setColor(color, 0.25, 0.75);
837 838 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
838 839 this.ctx.fill();
839 840
840 841 var bg = '<li class="bg parity' + parity + '"></li>';
841 842 var left = (this.columns + 1) * this.bg_height;
842 843 var nstyle = 'padding-left: ' + left + 'px;';
843 844 var item = revlink.replace(/_STYLE/, nstyle);
844 845 item = item.replace(/_PARITY/, 'parity' + parity);
845 846 item = item.replace(/_NODEID/, cur[0]);
846 847 item = item.replace(/_NODEID/, cur[0]);
847 848 item = item.replace(/_DESC/, cur[3]);
848 849 item = item.replace(/_USER/, cur[4]);
849 850 item = item.replace(/_DATE/, cur[5]);
850 851
851 852 var tagspan = '';
852 853 if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) {
853 854 tagspan = '<span class="logtags">';
854 855 if (cur[6][1]) {
855 856 tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
856 857 tagspan += cur[6][0] + '</span> ';
857 858 } else if (!cur[6][1] && cur[6][0] != 'default') {
858 859 tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
859 860 tagspan += cur[6][0] + '</span> ';
860 861 }
861 862 if (cur[7].length) {
862 863 for (var t in cur[7]) {
863 864 var tag = cur[7][t];
864 865 tagspan += '<span class="tagtag">' + tag + '</span> ';
865 866 }
866 867 }
867 868 tagspan += '</span>';
868 869 }
869 870
870 871 item = item.replace(/_TAGS/, tagspan);
871 872 return [bg, item];
872 873
873 874 }
874 875
875 876 graph.render(data);
876 877
877 878 // stop hiding script -->
878 879 </script>
879 880
880 881 <div class="page_nav">
881 882 <a href="/graph/2?style=gitweb&revcount=30">less</a>
882 883 <a href="/graph/2?style=gitweb&revcount=120">more</a>
883 884 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a>
884 885 </div>
885 886
886 887 <div class="page_footer">
887 888 <div class="page_footer_text">test</div>
888 889 <div class="rss_logo">
889 890 <a href="/rss-log">RSS</a>
890 891 <a href="/atom-log">Atom</a>
891 892 </div>
892 893 <br />
893 894
894 895 </div>
895 896 </body>
896 897 </html>
897 898
898 899
899 900 capabilities
900 901
901 902 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
902 903 200 Script output follows
903 904
904 905 lookup changegroupsubset branchmap pushkey unbundle=HG10GZ,HG10BZ,HG10UN
905 906
906 907 heads
907 908
908 909 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
909 910 200 Script output follows
910 911
911 912 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
912 913
913 914 branches
914 915
915 916 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches&nodes=0000000000000000000000000000000000000000'
916 917 200 Script output follows
917 918
918 919 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
919 920
920 921 changegroup
921 922
922 923 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup&roots=0000000000000000000000000000000000000000'
923 924 200 Script output follows
924 925
925 926 x\x9c\xbdTMHUA\x14\xbe\xa8\xf9\xec\xda&\x10\x11*\xb8\x88\x81\x99\xbef\xe6\xce\xbdw\xc6\xf2a\x16E\x1b\x11[%\x98\xcc\xaf\x8f\x8c\xf7\xc0\xf7\x82 (esc)
926 927 4\x11KP2m\x95\xad*\xabE\x05AP\xd0\xc22Z\x14\xf9\x03\xb9j\xa3\x9b$\xa4MJ\xb4\x90\xc0\x9a\x9bO0\x10\xdf\x13\xa2\x81\x0f\x869g\xe6|\xe7\x9c\xef\x8ceY\xf7\xa2KO\xd2\xb7K\x16~\\n\xe9\xad\x90w\x86\xab\x93W\x8e\xdf\xb0r\\Y\xee6(\xa2)\xf6\x95\xc6\x01\xe4\x1az\x80R\xe8kN\x98\xe7R\xa4\xa9K@\xe0!A\xb4k\xa7U*m\x03\x07\xd8\x92\x1d\xd2\xc9\xa4\x1d\xc2\xe6,\xa5\xcc+\x1f\xef\xafDgi\xef\xab\x1d\x1d\xb7\x9a\xe7[W\xfbc\x8f\xde-\xcd\xe7\xcaz\xb3\xbb\x19\xd3\x81\x10>c>\x08\x00"X\x11\xc2\x84@\xd2\xe7B*L\x00\x01P\x04R\xc3@\xbaB0\xdb8#\x83:\x83\xa2h\xbc=\xcd\xdaS\xe1Y,L\xd3\xa0\xf2\xa8\x94J:\xe6\xd8\x81Q\xe0\xe8d\xa7#\xe2,\xd1\xaeR*\xed \xa5\x01\x13\x01\xa6\x0cb\xe3;\xbe\xaf\xfcK[^wK\xe1N\xaf\xbbk\xe8B\xd1\xf4\xc1\x07\xb3\xab[\x10\xfdkmvwcB\xa6\xa4\xd4G\xc4D\xc2\x141\xad\x91\x10\x00\x08J\x81\xcb}\xee \xee+W\xba\x8a\x80\x90|\xd4\xa0\xd6\xa0\xd4T\xde\xe1\x9d,!\xe2\xb5\xa94\xe3\xe7\xd5\x9f\x06\x18\xcba\x03aP\xb8f\xcd\x04\x1a_\\9\xf1\xed\xe4\x9e\xe5\xa6\xd1\xd2\x9f\x03\xa7o\xae\x90H\xf3\xfb\xef\xffH3\xadk (esc)
927 928 \xb0\x90\x92\x88\xb9\x14"\x068\xc2\x1e@\x00\xbb\x8a)\xd3'\x859 (esc)
928 929 \xa8\x80\x84S \xa5\xbd-g\x13`\xe4\xdc\xc3H^\xdf\xe2\xc0TM\xc7\xf4BO\xcf\xde\xae\xe5\xae#\x1frM(K\x97`F\x19\x16s\x05GD\xb9\x01\xc1\x00+\x8c|\x9fp\xc11\xf0\x14\x00\x9cJ\x82<\xe0\x12\x9f\xc1\x90\xd0\xf5\xc8\x19>Pr\xaa\xeaW\xf5\xc4\xae\xd1\xfc\x17\xcf'\x13u\xb1\x9e\xcdHnC\x0e\xcc`\xc8\xa0&\xac\x0e\xf1|\x8c\x10$\xc4\x8c\xa2p\x05`\xdc\x08 \x80\xc4\xd7Rr-\x94\x10\x102\xedi;\xf3f\xf1z\x16\x86\xdb\xd8d\xe5\xe7\x8b\xf5\x8d\rzp\xb2\xfe\xac\xf5\xf2\xd3\xfe\xfckws\xedt\x96b\xd5l\x1c\x0b\x85\xb5\x170\x8f\x11\x84\xb0\x8f\x19\xa0\x00 _\x07\x1ac\xa2\xc3\x89Z\xe7\x96\xf9 \xccNFg\xc7F\xaa\x8a+\x9a\x9cc_\x17\x1b\x17\x9e]z38<\x97+\xb5,",\xc8\xc8?\\\x91\xff\x17.~U\x96\x97\xf5%\xdeN<\x8e\xf5\x97%\xe7^\xcfL\xed~\xda\x96k\xdc->\x86\x02\x83"\x96H\xa6\xe3\xaas=-\xeb7\xe5\xda\x8f\xbc (no-eol) (esc)
929 930
930 931 stream_out
931 932
932 933 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
933 934 200 Script output follows
934 935
935 936 1
936 937
937 938 failing unbundle, requires POST request
938 939
939 940 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
940 941 405 push requires POST request
941 942
942 943 0
943 944 push requires POST request
944 945 [1]
945 946
946 947 Static files
947 948
948 949 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
949 950 200 Script output follows
950 951
951 952 a { text-decoration:none; }
952 953 .age { white-space:nowrap; }
953 954 .date { white-space:nowrap; }
954 955 .indexlinks { white-space:nowrap; }
955 956 .parity0 { background-color: #ddd; }
956 957 .parity1 { background-color: #eee; }
957 958 .lineno { width: 60px; color: #aaa; font-size: smaller;
958 959 text-align: right; }
959 960 .plusline { color: green; }
960 961 .minusline { color: red; }
961 962 .atline { color: purple; }
962 963 .annotate { font-size: smaller; text-align: right; padding-right: 1em; }
963 964 .buttons a {
964 965 background-color: #666;
965 966 padding: 2pt;
966 967 color: white;
967 968 font-family: sans;
968 969 font-weight: bold;
969 970 }
970 971 .navigate a {
971 972 background-color: #ccc;
972 973 padding: 2pt;
973 974 font-family: sans;
974 975 color: black;
975 976 }
976 977
977 978 .metatag {
978 979 background-color: #888;
979 980 color: white;
980 981 text-align: right;
981 982 }
982 983
983 984 /* Common */
984 985 pre { margin: 0; }
985 986
986 987 .logo {
987 988 float: right;
988 989 clear: right;
989 990 }
990 991
991 992 /* Changelog/Filelog entries */
992 993 .logEntry { width: 100%; }
993 994 .logEntry .age { width: 15%; }
994 995 .logEntry th { font-weight: normal; text-align: right; vertical-align: top; }
995 996 .logEntry th.age, .logEntry th.firstline { font-weight: bold; }
996 997 .logEntry th.firstline { text-align: left; width: inherit; }
997 998
998 999 /* Shortlog entries */
999 1000 .slogEntry { width: 100%; }
1000 1001 .slogEntry .age { width: 8em; }
1001 1002 .slogEntry td { font-weight: normal; text-align: left; vertical-align: top; }
1002 1003 .slogEntry td.author { width: 15em; }
1003 1004
1004 1005 /* Tag entries */
1005 1006 #tagEntries { list-style: none; margin: 0; padding: 0; }
1006 1007 #tagEntries .tagEntry { list-style: none; margin: 0; padding: 0; }
1007 1008
1008 1009 /* Changeset entry */
1009 1010 #changesetEntry { }
1010 1011 #changesetEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1011 1012 #changesetEntry th.files, #changesetEntry th.description { vertical-align: top; }
1012 1013
1013 1014 /* File diff view */
1014 1015 #filediffEntry { }
1015 1016 #filediffEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1016 1017
1017 1018 /* Graph */
1018 1019 div#wrapper {
1019 1020 position: relative;
1020 1021 margin: 0;
1021 1022 padding: 0;
1022 1023 }
1023 1024
1024 1025 canvas {
1025 1026 position: absolute;
1026 1027 z-index: 5;
1027 1028 top: -0.6em;
1028 1029 margin: 0;
1029 1030 }
1030 1031
1031 1032 ul#nodebgs {
1032 1033 list-style: none inside none;
1033 1034 padding: 0;
1034 1035 margin: 0;
1035 1036 top: -0.7em;
1036 1037 }
1037 1038
1038 1039 ul#graphnodes li, ul#nodebgs li {
1039 1040 height: 39px;
1040 1041 }
1041 1042
1042 1043 ul#graphnodes {
1043 1044 position: absolute;
1044 1045 z-index: 10;
1045 1046 top: -0.85em;
1046 1047 list-style: none inside none;
1047 1048 padding: 0;
1048 1049 }
1049 1050
1050 1051 ul#graphnodes li .info {
1051 1052 display: block;
1052 1053 font-size: 70%;
1053 1054 position: relative;
1054 1055 top: -1px;
1055 1056 }
1056 1057
1057 1058 Stop and restart with HGENCODING=cp932
1058 1059
1059 1060 $ "$TESTDIR/killdaemons.py"
1060 1061 $ HGENCODING=cp932 hg serve --config server.uncompressed=False -n test \
1061 1062 > -p $HGPORT -d --pid-file=hg.pid -E errors.log
1062 1063 $ cat hg.pid >> $DAEMON_PIDS
1063 1064
1064 1065 commit message with Japanese Kanji 'Noh', which ends with '\x5c'
1065 1066
1066 1067 $ echo foo >> foo
1067 1068 $ HGENCODING=cp932 hg ci -m `python -c 'print("\x94\x5c")'`
1068 1069
1069 1070 Graph json escape of multibyte character
1070 1071
1071 1072 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
1072 1073 > | grep '^var data ='
1073 var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], []], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"]]];
1074 var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], []]];
1074 1075
1075 1076 ERRORS ENCOUNTERED
1076 1077
1077 1078 $ cat errors.log
@@ -1,485 +1,485 b''
1 1 setting up repo
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo a > a
6 6 $ echo b > b
7 7 $ hg ci -Ama
8 8 adding a
9 9 adding b
10 10
11 11 change permissions for git diffs
12 12
13 13 $ chmod 755 a
14 14 $ hg ci -Amb
15 15
16 16 set up hgweb
17 17
18 18 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
19 19 $ cat hg.pid >> $DAEMON_PIDS
20 20
21 21 revision
22 22
23 23 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0'
24 24 200 Script output follows
25 25
26 26 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
27 27 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
28 28 <head>
29 29 <link rel="icon" href="/static/hgicon.png" type="image/png" />
30 30 <meta name="robots" content="index, nofollow" />
31 31 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
32 32
33 33 <title>test: 0cd96de13884</title>
34 34 </head>
35 35 <body>
36 36 <div class="container">
37 37 <div class="menu">
38 38 <div class="logo">
39 39 <a href="http://mercurial.selenic.com/">
40 40 <img src="/static/hglogo.png" alt="mercurial" /></a>
41 41 </div>
42 42 <ul>
43 43 <li><a href="/shortlog/0cd96de13884">log</a></li>
44 44 <li><a href="/graph/0cd96de13884">graph</a></li>
45 45 <li><a href="/tags">tags</a></li>
46 46 <li><a href="/branches">branches</a></li>
47 47 </ul>
48 48 <ul>
49 49 <li class="active">changeset</li>
50 50 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
51 51 <li><a href="/file/0cd96de13884">browse</a></li>
52 52 </ul>
53 53 <ul>
54 54
55 55 </ul>
56 56 <ul>
57 57 <li><a href="/help">help</a></li>
58 58 </ul>
59 59 </div>
60 60
61 61 <div class="main">
62 62
63 63 <h2><a href="/">test</a></h2>
64 <h3>changeset 0:0cd96de13884 </h3>
64 <h3>changeset 0:0cd96de13884 </h3>
65 65
66 66 <form class="search" action="/log">
67 67
68 68 <p><input name="rev" id="search1" type="text" size="30" /></p>
69 69 <div id="hint">find changesets by author, revision,
70 70 files, or words in the commit message</div>
71 71 </form>
72 72
73 73 <div class="description">a</div>
74 74
75 75 <table id="changesetEntry">
76 76 <tr>
77 77 <th class="author">author</th>
78 78 <td class="author">&#116;&#101;&#115;&#116;</td>
79 79 </tr>
80 80 <tr>
81 81 <th class="date">date</th>
82 82 <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
83 83 <tr>
84 84 <th class="author">parents</th>
85 85 <td class="author"></td>
86 86 </tr>
87 87 <tr>
88 88 <th class="author">children</th>
89 89 <td class="author"> <a href="/rev/78e4ebad7cdf">78e4ebad7cdf</a></td>
90 90 </tr>
91 91 <tr>
92 92 <th class="files">files</th>
93 93 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
94 94 </tr>
95 95 </table>
96 96
97 97 <div class="overflow">
98 98 <div class="sourcefirst"> line diff</div>
99 99
100 100 <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
101 101 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000
102 102 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
103 103 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+a
104 104 </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
105 105 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000
106 106 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
107 107 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+b
108 108 </span></pre></div>
109 109 </div>
110 110
111 111 </div>
112 112 </div>
113 113
114 114
115 115 </body>
116 116 </html>
117 117
118 118
119 119 raw revision
120 120
121 121 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/raw-rev/0'
122 122 200 Script output follows
123 123
124 124
125 125 # HG changeset patch
126 126 # User test
127 127 # Date 0 0
128 128 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
129 129
130 130 a
131 131
132 132 diff -r 000000000000 -r 0cd96de13884 a
133 133 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
134 134 +++ b/a Thu Jan 01 00:00:00 1970 +0000
135 135 @@ -0,0 +1,1 @@
136 136 +a
137 137 diff -r 000000000000 -r 0cd96de13884 b
138 138 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139 139 +++ b/b Thu Jan 01 00:00:00 1970 +0000
140 140 @@ -0,0 +1,1 @@
141 141 +b
142 142
143 143
144 144 diff removed file
145 145
146 146 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
147 147 200 Script output follows
148 148
149 149 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
150 150 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
151 151 <head>
152 152 <link rel="icon" href="/static/hgicon.png" type="image/png" />
153 153 <meta name="robots" content="index, nofollow" />
154 154 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
155 155
156 156 <title>test: a diff</title>
157 157 </head>
158 158 <body>
159 159
160 160 <div class="container">
161 161 <div class="menu">
162 162 <div class="logo">
163 163 <a href="http://mercurial.selenic.com/">
164 164 <img src="/static/hglogo.png" alt="mercurial" /></a>
165 165 </div>
166 166 <ul>
167 167 <li><a href="/shortlog/78e4ebad7cdf">log</a></li>
168 168 <li><a href="/graph/78e4ebad7cdf">graph</a></li>
169 169 <li><a href="/tags">tags</a></li>
170 170 <li><a href="/branches">branches</a></li>
171 171 </ul>
172 172 <ul>
173 173 <li><a href="/rev/78e4ebad7cdf">changeset</a></li>
174 174 <li><a href="/file/78e4ebad7cdf">browse</a></li>
175 175 </ul>
176 176 <ul>
177 177 <li><a href="/file/78e4ebad7cdf/a">file</a></li>
178 178 <li><a href="/file/tip/a">latest</a></li>
179 179 <li class="active">diff</li>
180 180 <li><a href="/annotate/78e4ebad7cdf/a">annotate</a></li>
181 181 <li><a href="/log/78e4ebad7cdf/a">file log</a></li>
182 182 <li><a href="/raw-file/78e4ebad7cdf/a">raw</a></li>
183 183 </ul>
184 184 <ul>
185 185 <li><a href="/help">help</a></li>
186 186 </ul>
187 187 </div>
188 188
189 189 <div class="main">
190 190 <h2><a href="/">test</a></h2>
191 191 <h3>diff a @ 1:78e4ebad7cdf</h3>
192 192
193 193 <form class="search" action="/log">
194 194 <p></p>
195 195 <p><input name="rev" id="search1" type="text" size="30" /></p>
196 196 <div id="hint">find changesets by author, revision,
197 197 files, or words in the commit message</div>
198 198 </form>
199 199
200 200 <div class="description">b</div>
201 201
202 202 <table id="changesetEntry">
203 203 <tr>
204 204 <th>author</th>
205 205 <td>&#116;&#101;&#115;&#116;</td>
206 206 </tr>
207 207 <tr>
208 208 <th>date</th>
209 209 <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
210 210 </tr>
211 211 <tr>
212 212 <th>parents</th>
213 213 <td></td>
214 214 </tr>
215 215 <tr>
216 216 <th>children</th>
217 217 <td></td>
218 218 </tr>
219 219
220 220 </table>
221 221
222 222 <div class="overflow">
223 223 <div class="sourcefirst"> line diff</div>
224 224
225 225 <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
226 226 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000
227 227 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
228 228 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+a
229 229 </span></pre></div>
230 230 </div>
231 231 </div>
232 232 </div>
233 233
234 234
235 235
236 236 </body>
237 237 </html>
238 238
239 239
240 240 set up hgweb with git diffs
241 241
242 242 $ "$TESTDIR/killdaemons.py"
243 243 $ hg serve --config 'diff.git=1' -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
244 244 $ cat hg.pid >> $DAEMON_PIDS
245 245
246 246 revision
247 247
248 248 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0'
249 249 200 Script output follows
250 250
251 251 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
252 252 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
253 253 <head>
254 254 <link rel="icon" href="/static/hgicon.png" type="image/png" />
255 255 <meta name="robots" content="index, nofollow" />
256 256 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
257 257
258 258 <title>test: 0cd96de13884</title>
259 259 </head>
260 260 <body>
261 261 <div class="container">
262 262 <div class="menu">
263 263 <div class="logo">
264 264 <a href="http://mercurial.selenic.com/">
265 265 <img src="/static/hglogo.png" alt="mercurial" /></a>
266 266 </div>
267 267 <ul>
268 268 <li><a href="/shortlog/0cd96de13884">log</a></li>
269 269 <li><a href="/graph/0cd96de13884">graph</a></li>
270 270 <li><a href="/tags">tags</a></li>
271 271 <li><a href="/branches">branches</a></li>
272 272 </ul>
273 273 <ul>
274 274 <li class="active">changeset</li>
275 275 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
276 276 <li><a href="/file/0cd96de13884">browse</a></li>
277 277 </ul>
278 278 <ul>
279 279
280 280 </ul>
281 281 <ul>
282 282 <li><a href="/help">help</a></li>
283 283 </ul>
284 284 </div>
285 285
286 286 <div class="main">
287 287
288 288 <h2><a href="/">test</a></h2>
289 <h3>changeset 0:0cd96de13884 </h3>
289 <h3>changeset 0:0cd96de13884 </h3>
290 290
291 291 <form class="search" action="/log">
292 292
293 293 <p><input name="rev" id="search1" type="text" size="30" /></p>
294 294 <div id="hint">find changesets by author, revision,
295 295 files, or words in the commit message</div>
296 296 </form>
297 297
298 298 <div class="description">a</div>
299 299
300 300 <table id="changesetEntry">
301 301 <tr>
302 302 <th class="author">author</th>
303 303 <td class="author">&#116;&#101;&#115;&#116;</td>
304 304 </tr>
305 305 <tr>
306 306 <th class="date">date</th>
307 307 <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
308 308 <tr>
309 309 <th class="author">parents</th>
310 310 <td class="author"></td>
311 311 </tr>
312 312 <tr>
313 313 <th class="author">children</th>
314 314 <td class="author"> <a href="/rev/78e4ebad7cdf">78e4ebad7cdf</a></td>
315 315 </tr>
316 316 <tr>
317 317 <th class="files">files</th>
318 318 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
319 319 </tr>
320 320 </table>
321 321
322 322 <div class="overflow">
323 323 <div class="sourcefirst"> line diff</div>
324 324
325 325 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> new file mode 100644
326 326 <a href="#l1.2" id="l1.2"> 1.2</a> <span class="minusline">--- /dev/null
327 327 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="plusline">+++ b/a
328 328 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="atline">@@ -0,0 +1,1 @@
329 329 </span><a href="#l1.5" id="l1.5"> 1.5</a> <span class="plusline">+a
330 330 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> new file mode 100644
331 331 <a href="#l2.2" id="l2.2"> 2.2</a> <span class="minusline">--- /dev/null
332 332 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="plusline">+++ b/b
333 333 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="atline">@@ -0,0 +1,1 @@
334 334 </span><a href="#l2.5" id="l2.5"> 2.5</a> <span class="plusline">+b
335 335 </span></pre></div>
336 336 </div>
337 337
338 338 </div>
339 339 </div>
340 340
341 341
342 342 </body>
343 343 </html>
344 344
345 345
346 346 revision
347 347
348 348 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/raw-rev/0'
349 349 200 Script output follows
350 350
351 351
352 352 # HG changeset patch
353 353 # User test
354 354 # Date 0 0
355 355 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
356 356
357 357 a
358 358
359 359 diff --git a/a b/a
360 360 new file mode 100644
361 361 --- /dev/null
362 362 +++ b/a
363 363 @@ -0,0 +1,1 @@
364 364 +a
365 365 diff --git a/b b/b
366 366 new file mode 100644
367 367 --- /dev/null
368 368 +++ b/b
369 369 @@ -0,0 +1,1 @@
370 370 +b
371 371
372 372
373 373 diff removed file
374 374
375 375 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
376 376 200 Script output follows
377 377
378 378 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
379 379 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
380 380 <head>
381 381 <link rel="icon" href="/static/hgicon.png" type="image/png" />
382 382 <meta name="robots" content="index, nofollow" />
383 383 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
384 384
385 385 <title>test: a diff</title>
386 386 </head>
387 387 <body>
388 388
389 389 <div class="container">
390 390 <div class="menu">
391 391 <div class="logo">
392 392 <a href="http://mercurial.selenic.com/">
393 393 <img src="/static/hglogo.png" alt="mercurial" /></a>
394 394 </div>
395 395 <ul>
396 396 <li><a href="/shortlog/78e4ebad7cdf">log</a></li>
397 397 <li><a href="/graph/78e4ebad7cdf">graph</a></li>
398 398 <li><a href="/tags">tags</a></li>
399 399 <li><a href="/branches">branches</a></li>
400 400 </ul>
401 401 <ul>
402 402 <li><a href="/rev/78e4ebad7cdf">changeset</a></li>
403 403 <li><a href="/file/78e4ebad7cdf">browse</a></li>
404 404 </ul>
405 405 <ul>
406 406 <li><a href="/file/78e4ebad7cdf/a">file</a></li>
407 407 <li><a href="/file/tip/a">latest</a></li>
408 408 <li class="active">diff</li>
409 409 <li><a href="/annotate/78e4ebad7cdf/a">annotate</a></li>
410 410 <li><a href="/log/78e4ebad7cdf/a">file log</a></li>
411 411 <li><a href="/raw-file/78e4ebad7cdf/a">raw</a></li>
412 412 </ul>
413 413 <ul>
414 414 <li><a href="/help">help</a></li>
415 415 </ul>
416 416 </div>
417 417
418 418 <div class="main">
419 419 <h2><a href="/">test</a></h2>
420 420 <h3>diff a @ 1:78e4ebad7cdf</h3>
421 421
422 422 <form class="search" action="/log">
423 423 <p></p>
424 424 <p><input name="rev" id="search1" type="text" size="30" /></p>
425 425 <div id="hint">find changesets by author, revision,
426 426 files, or words in the commit message</div>
427 427 </form>
428 428
429 429 <div class="description">b</div>
430 430
431 431 <table id="changesetEntry">
432 432 <tr>
433 433 <th>author</th>
434 434 <td>&#116;&#101;&#115;&#116;</td>
435 435 </tr>
436 436 <tr>
437 437 <th>date</th>
438 438 <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
439 439 </tr>
440 440 <tr>
441 441 <th>parents</th>
442 442 <td></td>
443 443 </tr>
444 444 <tr>
445 445 <th>children</th>
446 446 <td></td>
447 447 </tr>
448 448
449 449 </table>
450 450
451 451 <div class="overflow">
452 452 <div class="sourcefirst"> line diff</div>
453 453
454 454 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> new file mode 100755
455 455 <a href="#l1.2" id="l1.2"> 1.2</a> <span class="minusline">--- /dev/null
456 456 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="plusline">+++ b/a
457 457 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="atline">@@ -0,0 +1,1 @@
458 458 </span><a href="#l1.5" id="l1.5"> 1.5</a> <span class="plusline">+a
459 459 </span></pre></div>
460 460 </div>
461 461 </div>
462 462 </div>
463 463
464 464
465 465
466 466 </body>
467 467 </html>
468 468
469 469 $ cd ..
470 470
471 471 test import rev as raw-rev
472 472
473 473 $ hg clone -r0 test test1
474 474 adding changesets
475 475 adding manifests
476 476 adding file changes
477 477 added 1 changesets with 2 changes to 2 files
478 478 updating to branch default
479 479 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 480 $ cd test1
481 481 $ hg import -q --exact http://localhost:$HGPORT/rev/1
482 482
483 483 errors
484 484
485 485 $ cat ../test/errors.log
@@ -1,388 +1,394 b''
1 1 Some tests for hgweb in an empty repository
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
6 6 $ cat hg.pid >> $DAEMON_PIDS
7 7 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/shortlog')
8 8 200 Script output follows
9 9
10 10 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
11 11 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
12 12 <head>
13 13 <link rel="icon" href="/static/hgicon.png" type="image/png" />
14 14 <meta name="robots" content="index, nofollow" />
15 15 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
16 16
17 17 <title>test: log</title>
18 18 <link rel="alternate" type="application/atom+xml"
19 19 href="/atom-log" title="Atom feed for test" />
20 20 <link rel="alternate" type="application/rss+xml"
21 21 href="/rss-log" title="RSS feed for test" />
22 22 </head>
23 23 <body>
24 24
25 25 <div class="container">
26 26 <div class="menu">
27 27 <div class="logo">
28 28 <a href="http://mercurial.selenic.com/">
29 29 <img src="/static/hglogo.png" alt="mercurial" /></a>
30 30 </div>
31 31 <ul>
32 32 <li class="active">log</li>
33 33 <li><a href="/graph/000000000000">graph</a></li>
34 34 <li><a href="/tags">tags</a></li>
35 35 <li><a href="/branches">branches</a></li>
36 36 </ul>
37 37 <ul>
38 38 <li><a href="/rev/000000000000">changeset</a></li>
39 39 <li><a href="/file/000000000000">browse</a></li>
40 40 </ul>
41 41 <ul>
42 42
43 43 </ul>
44 44 <ul>
45 45 <li><a href="/help">help</a></li>
46 46 </ul>
47 47 </div>
48 48
49 49 <div class="main">
50 50 <h2><a href="/">test</a></h2>
51 51 <h3>log</h3>
52 52
53 53 <form class="search" action="/log">
54 54
55 55 <p><input name="rev" id="search1" type="text" size="30" /></p>
56 56 <div id="hint">find changesets by author, revision,
57 57 files, or words in the commit message</div>
58 58 </form>
59 59
60 60 <div class="navigate">
61 61 <a href="/shortlog/-1?revcount=30">less</a>
62 62 <a href="/shortlog/-1?revcount=120">more</a>
63 63 | rev -1: <a href="/shortlog/000000000000">(0)</a> <a href="/shortlog/tip">tip</a>
64 64 </div>
65 65
66 66 <table class="bigtable">
67 67 <tr>
68 68 <th class="age">age</th>
69 69 <th class="author">author</th>
70 70 <th class="description">description</th>
71 71 </tr>
72 72
73 73 </table>
74 74
75 75 <div class="navigate">
76 76 <a href="/shortlog/-1?revcount=30">less</a>
77 77 <a href="/shortlog/-1?revcount=120">more</a>
78 78 | rev -1: <a href="/shortlog/000000000000">(0)</a> <a href="/shortlog/tip">tip</a>
79 79 </div>
80 80
81 81 </div>
82 82 </div>
83 83
84 84
85 85
86 86 </body>
87 87 </html>
88 88
89 89 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/log')
90 90 200 Script output follows
91 91
92 92 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
93 93 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
94 94 <head>
95 95 <link rel="icon" href="/static/hgicon.png" type="image/png" />
96 96 <meta name="robots" content="index, nofollow" />
97 97 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
98 98
99 99 <title>test: log</title>
100 100 <link rel="alternate" type="application/atom+xml"
101 101 href="/atom-log" title="Atom feed for test" />
102 102 <link rel="alternate" type="application/rss+xml"
103 103 href="/rss-log" title="RSS feed for test" />
104 104 </head>
105 105 <body>
106 106
107 107 <div class="container">
108 108 <div class="menu">
109 109 <div class="logo">
110 110 <a href="http://mercurial.selenic.com/">
111 111 <img src="/static/hglogo.png" alt="mercurial" /></a>
112 112 </div>
113 113 <ul>
114 114 <li class="active">log</li>
115 115 <li><a href="/graph/000000000000">graph</a></li>
116 116 <li><a href="/tags">tags</a></li>
117 117 <li><a href="/branches">branches</a></li>
118 118 </ul>
119 119 <ul>
120 120 <li><a href="/rev/000000000000">changeset</a></li>
121 121 <li><a href="/file/000000000000">browse</a></li>
122 122 </ul>
123 123 <ul>
124 124
125 125 </ul>
126 126 <ul>
127 127 <li><a href="/help">help</a></li>
128 128 </ul>
129 129 </div>
130 130
131 131 <div class="main">
132 132 <h2><a href="/">test</a></h2>
133 133 <h3>log</h3>
134 134
135 135 <form class="search" action="/log">
136 136
137 137 <p><input name="rev" id="search1" type="text" size="30" /></p>
138 138 <div id="hint">find changesets by author, revision,
139 139 files, or words in the commit message</div>
140 140 </form>
141 141
142 142 <div class="navigate">
143 143 <a href="/shortlog/-1?revcount=5">less</a>
144 144 <a href="/shortlog/-1?revcount=20">more</a>
145 145 | rev -1: <a href="/shortlog/000000000000">(0)</a> <a href="/shortlog/tip">tip</a>
146 146 </div>
147 147
148 148 <table class="bigtable">
149 149 <tr>
150 150 <th class="age">age</th>
151 151 <th class="author">author</th>
152 152 <th class="description">description</th>
153 153 </tr>
154 154
155 155 </table>
156 156
157 157 <div class="navigate">
158 158 <a href="/shortlog/-1?revcount=5">less</a>
159 159 <a href="/shortlog/-1?revcount=20">more</a>
160 160 | rev -1: <a href="/shortlog/000000000000">(0)</a> <a href="/shortlog/tip">tip</a>
161 161 </div>
162 162
163 163 </div>
164 164 </div>
165 165
166 166
167 167
168 168 </body>
169 169 </html>
170 170
171 171 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/graph')
172 172 200 Script output follows
173 173
174 174 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
175 175 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
176 176 <head>
177 177 <link rel="icon" href="/static/hgicon.png" type="image/png" />
178 178 <meta name="robots" content="index, nofollow" />
179 179 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
180 180
181 181 <title>test: revision graph</title>
182 182 <link rel="alternate" type="application/atom+xml"
183 183 href="/atom-log" title="Atom feed for test: log" />
184 184 <link rel="alternate" type="application/rss+xml"
185 185 href="/rss-log" title="RSS feed for test: log" />
186 186 <!--[if IE]><script type="text/javascript" src="/static/excanvas.js"></script><![endif]-->
187 187 </head>
188 188 <body>
189 189
190 190 <div class="container">
191 191 <div class="menu">
192 192 <div class="logo">
193 193 <a href="http://mercurial.selenic.com/">
194 194 <img src="/static/hglogo.png" alt="mercurial" /></a>
195 195 </div>
196 196 <ul>
197 197 <li><a href="/shortlog/000000000000">log</a></li>
198 198 <li class="active">graph</li>
199 199 <li><a href="/tags">tags</a></li>
200 200 <li><a href="/branches">branches</a></li>
201 201 </ul>
202 202 <ul>
203 203 <li><a href="/rev/000000000000">changeset</a></li>
204 204 <li><a href="/file/000000000000">browse</a></li>
205 205 </ul>
206 206 <ul>
207 207 <li><a href="/help">help</a></li>
208 208 </ul>
209 209 </div>
210 210
211 211 <div class="main">
212 212 <h2><a href="/">test</a></h2>
213 213 <h3>graph</h3>
214 214
215 215 <form class="search" action="/log">
216 216
217 217 <p><input name="rev" id="search1" type="text" size="30" /></p>
218 218 <div id="hint">find changesets by author, revision,
219 219 files, or words in the commit message</div>
220 220 </form>
221 221
222 222 <div class="navigate">
223 223 <a href="/graph/-1?revcount=30">less</a>
224 224 <a href="/graph/-1?revcount=120">more</a>
225 225 | rev -1: <a href="/graph/000000000000">(0)</a> <a href="/graph/tip">tip</a>
226 226 </div>
227 227
228 228 <noscript><p>The revision graph only works with JavaScript-enabled browsers.</p></noscript>
229 229
230 230 <div id="wrapper">
231 231 <ul id="nodebgs"></ul>
232 232 <canvas id="graph" width="224" height="12"></canvas>
233 233 <ul id="graphnodes"></ul>
234 234 </div>
235 235
236 236 <script type="text/javascript" src="/static/graph.js"></script>
237 237 <script type="text/javascript">
238 238 <!-- hide script content
239 239
240 240 var data = [];
241 241 var graph = new Graph();
242 242 graph.scale(39);
243 243
244 244 graph.edge = function(x0, y0, x1, y1, color) {
245 245
246 246 this.setColor(color, 0.0, 0.65);
247 247 this.ctx.beginPath();
248 248 this.ctx.moveTo(x0, y0);
249 249 this.ctx.lineTo(x1, y1);
250 250 this.ctx.stroke();
251 251
252 252 }
253 253
254 254 var revlink = '<li style="_STYLE"><span class="desc">';
255 255 revlink += '<a href="/rev/_NODEID" title="_NODEID">_DESC</a>';
256 256 revlink += '</span>_TAGS<span class="info">_DATE, by _USER</span></li>';
257 257
258 258 graph.vertex = function(x, y, color, parity, cur) {
259 259
260 260 this.ctx.beginPath();
261 261 color = this.setColor(color, 0.25, 0.75);
262 262 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
263 263 this.ctx.fill();
264 264
265 265 var bg = '<li class="bg parity' + parity + '"></li>';
266 266 var left = (this.columns + 1) * this.bg_height;
267 267 var nstyle = 'padding-left: ' + left + 'px;';
268 268 var item = revlink.replace(/_STYLE/, nstyle);
269 269 item = item.replace(/_PARITY/, 'parity' + parity);
270 270 item = item.replace(/_NODEID/, cur[0]);
271 271 item = item.replace(/_NODEID/, cur[0]);
272 272 item = item.replace(/_DESC/, cur[3]);
273 273 item = item.replace(/_USER/, cur[4]);
274 274 item = item.replace(/_DATE/, cur[5]);
275 275
276 276 var tagspan = '';
277 277 if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) {
278 278 tagspan = '<span class="logtags">';
279 279 if (cur[6][1]) {
280 280 tagspan += '<span class="branchhead" title="' + cur[6][0] + '">';
281 281 tagspan += cur[6][0] + '</span> ';
282 282 } else if (!cur[6][1] && cur[6][0] != 'default') {
283 283 tagspan += '<span class="branchname" title="' + cur[6][0] + '">';
284 284 tagspan += cur[6][0] + '</span> ';
285 285 }
286 286 if (cur[7].length) {
287 287 for (var t in cur[7]) {
288 288 var tag = cur[7][t];
289 289 tagspan += '<span class="tag">' + tag + '</span> ';
290 290 }
291 291 }
292 if (cur[8].length) {
293 for (var b in cur[8]) {
294 var bookmark = cur[8][b];
295 tagspan += '<span class="tag">' + bookmark + '</span> ';
296 }
297 }
292 298 tagspan += '</span>';
293 299 }
294 300
295 301 item = item.replace(/_TAGS/, tagspan);
296 302 return [bg, item];
297 303
298 304 }
299 305
300 306 graph.render(data);
301 307
302 308 // stop hiding script -->
303 309 </script>
304 310
305 311 <div class="navigate">
306 312 <a href="/graph/-1?revcount=30">less</a>
307 313 <a href="/graph/-1?revcount=120">more</a>
308 314 | rev -1: <a href="/graph/000000000000">(0)</a> <a href="/graph/tip">tip</a>
309 315 </div>
310 316
311 317 </div>
312 318 </div>
313 319
314 320
315 321
316 322 </body>
317 323 </html>
318 324
319 325 $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file')
320 326 200 Script output follows
321 327
322 328 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
323 329 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
324 330 <head>
325 331 <link rel="icon" href="/static/hgicon.png" type="image/png" />
326 332 <meta name="robots" content="index, nofollow" />
327 333 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
328 334
329 335 <title>test: 000000000000 /</title>
330 336 </head>
331 337 <body>
332 338
333 339 <div class="container">
334 340 <div class="menu">
335 341 <div class="logo">
336 342 <a href="http://mercurial.selenic.com/">
337 343 <img src="/static/hglogo.png" alt="mercurial" /></a>
338 344 </div>
339 345 <ul>
340 346 <li><a href="/shortlog/000000000000">log</a></li>
341 347 <li><a href="/graph/000000000000">graph</a></li>
342 348 <li><a href="/tags">tags</a></li>
343 349 <li><a href="/branches">branches</a></li>
344 350 </ul>
345 351 <ul>
346 352 <li><a href="/rev/000000000000">changeset</a></li>
347 353 <li class="active">browse</li>
348 354 </ul>
349 355 <ul>
350 356
351 357 </ul>
352 358 <ul>
353 359 <li><a href="/help">help</a></li>
354 360 </ul>
355 361 </div>
356 362
357 363 <div class="main">
358 364 <h2><a href="/">test</a></h2>
359 365 <h3>directory / @ -1:000000000000 <span class="tag">tip</span> </h3>
360 366
361 367 <form class="search" action="/log">
362 368
363 369 <p><input name="rev" id="search1" type="text" size="30" /></p>
364 370 <div id="hint">find changesets by author, revision,
365 371 files, or words in the commit message</div>
366 372 </form>
367 373
368 374 <table class="bigtable">
369 375 <tr>
370 376 <th class="name">name</th>
371 377 <th class="size">size</th>
372 378 <th class="permissions">permissions</th>
373 379 </tr>
374 380 <tr class="fileline parity0">
375 381 <td class="name"><a href="/file/000000000000/">[up]</a></td>
376 382 <td class="size"></td>
377 383 <td class="permissions">drwxr-xr-x</td>
378 384 </tr>
379 385
380 386
381 387 </table>
382 388 </div>
383 389 </div>
384 390
385 391
386 392 </body>
387 393 </html>
388 394
@@ -1,204 +1,204 b''
1 1 setting up repo
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo a > a
6 6 $ hg ci -Ama
7 7 adding a
8 8 $ hg rm a
9 9 $ hg ci -mdel
10 10
11 11 set up hgweb
12 12
13 13 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
14 14 $ cat hg.pid >> $DAEMON_PIDS
15 15
16 16 revision
17 17
18 18 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/tip'
19 19 200 Script output follows
20 20
21 21 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
22 22 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
23 23 <head>
24 24 <link rel="icon" href="/static/hgicon.png" type="image/png" />
25 25 <meta name="robots" content="index, nofollow" />
26 26 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
27 27
28 28 <title>test: c78f6c5cbea9</title>
29 29 </head>
30 30 <body>
31 31 <div class="container">
32 32 <div class="menu">
33 33 <div class="logo">
34 34 <a href="http://mercurial.selenic.com/">
35 35 <img src="/static/hglogo.png" alt="mercurial" /></a>
36 36 </div>
37 37 <ul>
38 38 <li><a href="/shortlog/c78f6c5cbea9">log</a></li>
39 39 <li><a href="/graph/c78f6c5cbea9">graph</a></li>
40 40 <li><a href="/tags">tags</a></li>
41 41 <li><a href="/branches">branches</a></li>
42 42 </ul>
43 43 <ul>
44 44 <li class="active">changeset</li>
45 45 <li><a href="/raw-rev/c78f6c5cbea9">raw</a></li>
46 46 <li><a href="/file/c78f6c5cbea9">browse</a></li>
47 47 </ul>
48 48 <ul>
49 49
50 50 </ul>
51 51 <ul>
52 52 <li><a href="/help">help</a></li>
53 53 </ul>
54 54 </div>
55 55
56 56 <div class="main">
57 57
58 58 <h2><a href="/">test</a></h2>
59 <h3>changeset 1:c78f6c5cbea9 <span class="tag">tip</span> </h3>
59 <h3>changeset 1:c78f6c5cbea9 <span class="tag">tip</span> </h3>
60 60
61 61 <form class="search" action="/log">
62 62
63 63 <p><input name="rev" id="search1" type="text" size="30" /></p>
64 64 <div id="hint">find changesets by author, revision,
65 65 files, or words in the commit message</div>
66 66 </form>
67 67
68 68 <div class="description">del</div>
69 69
70 70 <table id="changesetEntry">
71 71 <tr>
72 72 <th class="author">author</th>
73 73 <td class="author">&#116;&#101;&#115;&#116;</td>
74 74 </tr>
75 75 <tr>
76 76 <th class="date">date</th>
77 77 <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
78 78 <tr>
79 79 <th class="author">parents</th>
80 80 <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
81 81 </tr>
82 82 <tr>
83 83 <th class="author">children</th>
84 84 <td class="author"></td>
85 85 </tr>
86 86 <tr>
87 87 <th class="files">files</th>
88 88 <td class="files">a </td>
89 89 </tr>
90 90 </table>
91 91
92 92 <div class="overflow">
93 93 <div class="sourcefirst"> line diff</div>
94 94
95 95 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- a/a Thu Jan 01 00:00:00 1970 +0000
96 96 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
97 97 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -1,1 +0,0 @@
98 98 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="minusline">-a
99 99 </span></pre></div>
100 100 </div>
101 101
102 102 </div>
103 103 </div>
104 104
105 105
106 106 </body>
107 107 </html>
108 108
109 109
110 110 diff removed file
111 111
112 112 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
113 113 200 Script output follows
114 114
115 115 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
116 116 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
117 117 <head>
118 118 <link rel="icon" href="/static/hgicon.png" type="image/png" />
119 119 <meta name="robots" content="index, nofollow" />
120 120 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
121 121
122 122 <title>test: a diff</title>
123 123 </head>
124 124 <body>
125 125
126 126 <div class="container">
127 127 <div class="menu">
128 128 <div class="logo">
129 129 <a href="http://mercurial.selenic.com/">
130 130 <img src="/static/hglogo.png" alt="mercurial" /></a>
131 131 </div>
132 132 <ul>
133 133 <li><a href="/shortlog/c78f6c5cbea9">log</a></li>
134 134 <li><a href="/graph/c78f6c5cbea9">graph</a></li>
135 135 <li><a href="/tags">tags</a></li>
136 136 <li><a href="/branches">branches</a></li>
137 137 </ul>
138 138 <ul>
139 139 <li><a href="/rev/c78f6c5cbea9">changeset</a></li>
140 140 <li><a href="/file/c78f6c5cbea9">browse</a></li>
141 141 </ul>
142 142 <ul>
143 143 <li><a href="/file/c78f6c5cbea9/a">file</a></li>
144 144 <li><a href="/file/tip/a">latest</a></li>
145 145 <li class="active">diff</li>
146 146 <li><a href="/annotate/c78f6c5cbea9/a">annotate</a></li>
147 147 <li><a href="/log/c78f6c5cbea9/a">file log</a></li>
148 148 <li><a href="/raw-file/c78f6c5cbea9/a">raw</a></li>
149 149 </ul>
150 150 <ul>
151 151 <li><a href="/help">help</a></li>
152 152 </ul>
153 153 </div>
154 154
155 155 <div class="main">
156 156 <h2><a href="/">test</a></h2>
157 157 <h3>diff a @ 1:c78f6c5cbea9</h3>
158 158
159 159 <form class="search" action="/log">
160 160 <p></p>
161 161 <p><input name="rev" id="search1" type="text" size="30" /></p>
162 162 <div id="hint">find changesets by author, revision,
163 163 files, or words in the commit message</div>
164 164 </form>
165 165
166 166 <div class="description">del</div>
167 167
168 168 <table id="changesetEntry">
169 169 <tr>
170 170 <th>author</th>
171 171 <td>&#116;&#101;&#115;&#116;</td>
172 172 </tr>
173 173 <tr>
174 174 <th>date</th>
175 175 <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
176 176 </tr>
177 177 <tr>
178 178 <th>parents</th>
179 179 <td><a href="/file/cb9a9f314b8b/a">cb9a9f314b8b</a> </td>
180 180 </tr>
181 181 <tr>
182 182 <th>children</th>
183 183 <td></td>
184 184 </tr>
185 185
186 186 </table>
187 187
188 188 <div class="overflow">
189 189 <div class="sourcefirst"> line diff</div>
190 190
191 191 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- a/a Thu Jan 01 00:00:00 1970 +0000
192 192 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
193 193 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -1,1 +0,0 @@
194 194 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="minusline">-a
195 195 </span></pre></div>
196 196 </div>
197 197 </div>
198 198 </div>
199 199
200 200
201 201
202 202 </body>
203 203 </html>
204 204
General Comments 0
You need to be logged in to leave comments. Login now