##// END OF EJS Templates
monoblue: make actual changeset entries have backgrounds on /graph...
av6 -
r35548:acd8a245 default
parent child Browse files
Show More
@@ -1,1390 +1,1392 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 from __future__ import absolute_import
9 9
10 10 import copy
11 11 import mimetypes
12 12 import os
13 13 import re
14 14
15 15 from ..i18n import _
16 16 from ..node import hex, short
17 17
18 18 from .common import (
19 19 ErrorResponse,
20 20 HTTP_FORBIDDEN,
21 21 HTTP_NOT_FOUND,
22 22 HTTP_OK,
23 23 get_contact,
24 24 paritygen,
25 25 staticfile,
26 26 )
27 27
28 28 from .. import (
29 29 archival,
30 30 dagop,
31 31 encoding,
32 32 error,
33 33 graphmod,
34 34 pycompat,
35 35 revset,
36 36 revsetlang,
37 37 scmutil,
38 38 smartset,
39 39 templater,
40 40 util,
41 41 )
42 42
43 43 from . import (
44 44 webutil,
45 45 )
46 46
47 47 __all__ = []
48 48 commands = {}
49 49
50 50 class webcommand(object):
51 51 """Decorator used to register a web command handler.
52 52
53 53 The decorator takes as its positional arguments the name/path the
54 54 command should be accessible under.
55 55
56 56 Usage:
57 57
58 58 @webcommand('mycommand')
59 59 def mycommand(web, req, tmpl):
60 60 pass
61 61 """
62 62
63 63 def __init__(self, name):
64 64 self.name = name
65 65
66 66 def __call__(self, func):
67 67 __all__.append(self.name)
68 68 commands[self.name] = func
69 69 return func
70 70
71 71 @webcommand('log')
72 72 def log(web, req, tmpl):
73 73 """
74 74 /log[/{revision}[/{path}]]
75 75 --------------------------
76 76
77 77 Show repository or file history.
78 78
79 79 For URLs of the form ``/log/{revision}``, a list of changesets starting at
80 80 the specified changeset identifier is shown. If ``{revision}`` is not
81 81 defined, the default is ``tip``. This form is equivalent to the
82 82 ``changelog`` handler.
83 83
84 84 For URLs of the form ``/log/{revision}/{file}``, the history for a specific
85 85 file will be shown. This form is equivalent to the ``filelog`` handler.
86 86 """
87 87
88 88 if 'file' in req.form and req.form['file'][0]:
89 89 return filelog(web, req, tmpl)
90 90 else:
91 91 return changelog(web, req, tmpl)
92 92
93 93 @webcommand('rawfile')
94 94 def rawfile(web, req, tmpl):
95 95 guessmime = web.configbool('web', 'guessmime')
96 96
97 97 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
98 98 if not path:
99 99 content = manifest(web, req, tmpl)
100 100 req.respond(HTTP_OK, web.ctype)
101 101 return content
102 102
103 103 try:
104 104 fctx = webutil.filectx(web.repo, req)
105 105 except error.LookupError as inst:
106 106 try:
107 107 content = manifest(web, req, tmpl)
108 108 req.respond(HTTP_OK, web.ctype)
109 109 return content
110 110 except ErrorResponse:
111 111 raise inst
112 112
113 113 path = fctx.path()
114 114 text = fctx.data()
115 115 mt = 'application/binary'
116 116 if guessmime:
117 117 mt = mimetypes.guess_type(path)[0]
118 118 if mt is None:
119 119 if util.binary(text):
120 120 mt = 'application/binary'
121 121 else:
122 122 mt = 'text/plain'
123 123 if mt.startswith('text/'):
124 124 mt += '; charset="%s"' % encoding.encoding
125 125
126 126 req.respond(HTTP_OK, mt, path, body=text)
127 127 return []
128 128
129 129 def _filerevision(web, req, tmpl, fctx):
130 130 f = fctx.path()
131 131 text = fctx.data()
132 132 parity = paritygen(web.stripecount)
133 133 ishead = fctx.filerev() in fctx.filelog().headrevs()
134 134
135 135 if util.binary(text):
136 136 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
137 137 text = '(binary:%s)' % mt
138 138
139 139 def lines():
140 140 for lineno, t in enumerate(text.splitlines(True)):
141 141 yield {"line": t,
142 142 "lineid": "l%d" % (lineno + 1),
143 143 "linenumber": "% 6d" % (lineno + 1),
144 144 "parity": next(parity)}
145 145
146 146 return tmpl("filerevision",
147 147 file=f,
148 148 path=webutil.up(f),
149 149 text=lines(),
150 150 symrev=webutil.symrevorshortnode(req, fctx),
151 151 rename=webutil.renamelink(fctx),
152 152 permissions=fctx.manifest().flags(f),
153 153 ishead=int(ishead),
154 154 **webutil.commonentry(web.repo, fctx))
155 155
156 156 @webcommand('file')
157 157 def file(web, req, tmpl):
158 158 """
159 159 /file/{revision}[/{path}]
160 160 -------------------------
161 161
162 162 Show information about a directory or file in the repository.
163 163
164 164 Info about the ``path`` given as a URL parameter will be rendered.
165 165
166 166 If ``path`` is a directory, information about the entries in that
167 167 directory will be rendered. This form is equivalent to the ``manifest``
168 168 handler.
169 169
170 170 If ``path`` is a file, information about that file will be shown via
171 171 the ``filerevision`` template.
172 172
173 173 If ``path`` is not defined, information about the root directory will
174 174 be rendered.
175 175 """
176 176 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
177 177 if not path:
178 178 return manifest(web, req, tmpl)
179 179 try:
180 180 return _filerevision(web, req, tmpl, webutil.filectx(web.repo, req))
181 181 except error.LookupError as inst:
182 182 try:
183 183 return manifest(web, req, tmpl)
184 184 except ErrorResponse:
185 185 raise inst
186 186
187 187 def _search(web, req, tmpl):
188 188 MODE_REVISION = 'rev'
189 189 MODE_KEYWORD = 'keyword'
190 190 MODE_REVSET = 'revset'
191 191
192 192 def revsearch(ctx):
193 193 yield ctx
194 194
195 195 def keywordsearch(query):
196 196 lower = encoding.lower
197 197 qw = lower(query).split()
198 198
199 199 def revgen():
200 200 cl = web.repo.changelog
201 201 for i in xrange(len(web.repo) - 1, 0, -100):
202 202 l = []
203 203 for j in cl.revs(max(0, i - 99), i):
204 204 ctx = web.repo[j]
205 205 l.append(ctx)
206 206 l.reverse()
207 207 for e in l:
208 208 yield e
209 209
210 210 for ctx in revgen():
211 211 miss = 0
212 212 for q in qw:
213 213 if not (q in lower(ctx.user()) or
214 214 q in lower(ctx.description()) or
215 215 q in lower(" ".join(ctx.files()))):
216 216 miss = 1
217 217 break
218 218 if miss:
219 219 continue
220 220
221 221 yield ctx
222 222
223 223 def revsetsearch(revs):
224 224 for r in revs:
225 225 yield web.repo[r]
226 226
227 227 searchfuncs = {
228 228 MODE_REVISION: (revsearch, 'exact revision search'),
229 229 MODE_KEYWORD: (keywordsearch, 'literal keyword search'),
230 230 MODE_REVSET: (revsetsearch, 'revset expression search'),
231 231 }
232 232
233 233 def getsearchmode(query):
234 234 try:
235 235 ctx = web.repo[query]
236 236 except (error.RepoError, error.LookupError):
237 237 # query is not an exact revision pointer, need to
238 238 # decide if it's a revset expression or keywords
239 239 pass
240 240 else:
241 241 return MODE_REVISION, ctx
242 242
243 243 revdef = 'reverse(%s)' % query
244 244 try:
245 245 tree = revsetlang.parse(revdef)
246 246 except error.ParseError:
247 247 # can't parse to a revset tree
248 248 return MODE_KEYWORD, query
249 249
250 250 if revsetlang.depth(tree) <= 2:
251 251 # no revset syntax used
252 252 return MODE_KEYWORD, query
253 253
254 254 if any((token, (value or '')[:3]) == ('string', 're:')
255 255 for token, value, pos in revsetlang.tokenize(revdef)):
256 256 return MODE_KEYWORD, query
257 257
258 258 funcsused = revsetlang.funcsused(tree)
259 259 if not funcsused.issubset(revset.safesymbols):
260 260 return MODE_KEYWORD, query
261 261
262 262 mfunc = revset.match(web.repo.ui, revdef, repo=web.repo)
263 263 try:
264 264 revs = mfunc(web.repo)
265 265 return MODE_REVSET, revs
266 266 # ParseError: wrongly placed tokens, wrongs arguments, etc
267 267 # RepoLookupError: no such revision, e.g. in 'revision:'
268 268 # Abort: bookmark/tag not exists
269 269 # LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo
270 270 except (error.ParseError, error.RepoLookupError, error.Abort,
271 271 LookupError):
272 272 return MODE_KEYWORD, query
273 273
274 274 def changelist(**map):
275 275 count = 0
276 276
277 277 for ctx in searchfunc[0](funcarg):
278 278 count += 1
279 279 n = ctx.node()
280 280 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
281 281 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
282 282
283 283 yield tmpl('searchentry',
284 284 parity=next(parity),
285 285 changelogtag=showtags,
286 286 files=files,
287 287 **webutil.commonentry(web.repo, ctx))
288 288
289 289 if count >= revcount:
290 290 break
291 291
292 292 query = req.form['rev'][0]
293 293 revcount = web.maxchanges
294 294 if 'revcount' in req.form:
295 295 try:
296 296 revcount = int(req.form.get('revcount', [revcount])[0])
297 297 revcount = max(revcount, 1)
298 298 tmpl.defaults['sessionvars']['revcount'] = revcount
299 299 except ValueError:
300 300 pass
301 301
302 302 lessvars = copy.copy(tmpl.defaults['sessionvars'])
303 303 lessvars['revcount'] = max(revcount / 2, 1)
304 304 lessvars['rev'] = query
305 305 morevars = copy.copy(tmpl.defaults['sessionvars'])
306 306 morevars['revcount'] = revcount * 2
307 307 morevars['rev'] = query
308 308
309 309 mode, funcarg = getsearchmode(query)
310 310
311 311 if 'forcekw' in req.form:
312 312 showforcekw = ''
313 313 showunforcekw = searchfuncs[mode][1]
314 314 mode = MODE_KEYWORD
315 315 funcarg = query
316 316 else:
317 317 if mode != MODE_KEYWORD:
318 318 showforcekw = searchfuncs[MODE_KEYWORD][1]
319 319 else:
320 320 showforcekw = ''
321 321 showunforcekw = ''
322 322
323 323 searchfunc = searchfuncs[mode]
324 324
325 325 tip = web.repo['tip']
326 326 parity = paritygen(web.stripecount)
327 327
328 328 return tmpl('search', query=query, node=tip.hex(), symrev='tip',
329 329 entries=changelist, archives=web.archivelist("tip"),
330 330 morevars=morevars, lessvars=lessvars,
331 331 modedesc=searchfunc[1],
332 332 showforcekw=showforcekw, showunforcekw=showunforcekw)
333 333
334 334 @webcommand('changelog')
335 335 def changelog(web, req, tmpl, shortlog=False):
336 336 """
337 337 /changelog[/{revision}]
338 338 -----------------------
339 339
340 340 Show information about multiple changesets.
341 341
342 342 If the optional ``revision`` URL argument is absent, information about
343 343 all changesets starting at ``tip`` will be rendered. If the ``revision``
344 344 argument is present, changesets will be shown starting from the specified
345 345 revision.
346 346
347 347 If ``revision`` is absent, the ``rev`` query string argument may be
348 348 defined. This will perform a search for changesets.
349 349
350 350 The argument for ``rev`` can be a single revision, a revision set,
351 351 or a literal keyword to search for in changeset data (equivalent to
352 352 :hg:`log -k`).
353 353
354 354 The ``revcount`` query string argument defines the maximum numbers of
355 355 changesets to render.
356 356
357 357 For non-searches, the ``changelog`` template will be rendered.
358 358 """
359 359
360 360 query = ''
361 361 if 'node' in req.form:
362 362 ctx = webutil.changectx(web.repo, req)
363 363 symrev = webutil.symrevorshortnode(req, ctx)
364 364 elif 'rev' in req.form:
365 365 return _search(web, req, tmpl)
366 366 else:
367 367 ctx = web.repo['tip']
368 368 symrev = 'tip'
369 369
370 370 def changelist():
371 371 revs = []
372 372 if pos != -1:
373 373 revs = web.repo.changelog.revs(pos, 0)
374 374 curcount = 0
375 375 for rev in revs:
376 376 curcount += 1
377 377 if curcount > revcount + 1:
378 378 break
379 379
380 380 entry = webutil.changelistentry(web, web.repo[rev], tmpl)
381 381 entry['parity'] = next(parity)
382 382 yield entry
383 383
384 384 if shortlog:
385 385 revcount = web.maxshortchanges
386 386 else:
387 387 revcount = web.maxchanges
388 388
389 389 if 'revcount' in req.form:
390 390 try:
391 391 revcount = int(req.form.get('revcount', [revcount])[0])
392 392 revcount = max(revcount, 1)
393 393 tmpl.defaults['sessionvars']['revcount'] = revcount
394 394 except ValueError:
395 395 pass
396 396
397 397 lessvars = copy.copy(tmpl.defaults['sessionvars'])
398 398 lessvars['revcount'] = max(revcount / 2, 1)
399 399 morevars = copy.copy(tmpl.defaults['sessionvars'])
400 400 morevars['revcount'] = revcount * 2
401 401
402 402 count = len(web.repo)
403 403 pos = ctx.rev()
404 404 parity = paritygen(web.stripecount)
405 405
406 406 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
407 407
408 408 entries = list(changelist())
409 409 latestentry = entries[:1]
410 410 if len(entries) > revcount:
411 411 nextentry = entries[-1:]
412 412 entries = entries[:-1]
413 413 else:
414 414 nextentry = []
415 415
416 416 return tmpl('shortlog' if shortlog else 'changelog', changenav=changenav,
417 417 node=ctx.hex(), rev=pos, symrev=symrev, changesets=count,
418 418 entries=entries,
419 419 latestentry=latestentry, nextentry=nextentry,
420 420 archives=web.archivelist("tip"), revcount=revcount,
421 421 morevars=morevars, lessvars=lessvars, query=query)
422 422
423 423 @webcommand('shortlog')
424 424 def shortlog(web, req, tmpl):
425 425 """
426 426 /shortlog
427 427 ---------
428 428
429 429 Show basic information about a set of changesets.
430 430
431 431 This accepts the same parameters as the ``changelog`` handler. The only
432 432 difference is the ``shortlog`` template will be rendered instead of the
433 433 ``changelog`` template.
434 434 """
435 435 return changelog(web, req, tmpl, shortlog=True)
436 436
437 437 @webcommand('changeset')
438 438 def changeset(web, req, tmpl):
439 439 """
440 440 /changeset[/{revision}]
441 441 -----------------------
442 442
443 443 Show information about a single changeset.
444 444
445 445 A URL path argument is the changeset identifier to show. See ``hg help
446 446 revisions`` for possible values. If not defined, the ``tip`` changeset
447 447 will be shown.
448 448
449 449 The ``changeset`` template is rendered. Contents of the ``changesettag``,
450 450 ``changesetbookmark``, ``filenodelink``, ``filenolink``, and the many
451 451 templates related to diffs may all be used to produce the output.
452 452 """
453 453 ctx = webutil.changectx(web.repo, req)
454 454
455 455 return tmpl('changeset', **webutil.changesetentry(web, req, tmpl, ctx))
456 456
457 457 rev = webcommand('rev')(changeset)
458 458
459 459 def decodepath(path):
460 460 """Hook for mapping a path in the repository to a path in the
461 461 working copy.
462 462
463 463 Extensions (e.g., largefiles) can override this to remap files in
464 464 the virtual file system presented by the manifest command below."""
465 465 return path
466 466
467 467 @webcommand('manifest')
468 468 def manifest(web, req, tmpl):
469 469 """
470 470 /manifest[/{revision}[/{path}]]
471 471 -------------------------------
472 472
473 473 Show information about a directory.
474 474
475 475 If the URL path arguments are omitted, information about the root
476 476 directory for the ``tip`` changeset will be shown.
477 477
478 478 Because this handler can only show information for directories, it
479 479 is recommended to use the ``file`` handler instead, as it can handle both
480 480 directories and files.
481 481
482 482 The ``manifest`` template will be rendered for this handler.
483 483 """
484 484 if 'node' in req.form:
485 485 ctx = webutil.changectx(web.repo, req)
486 486 symrev = webutil.symrevorshortnode(req, ctx)
487 487 else:
488 488 ctx = web.repo['tip']
489 489 symrev = 'tip'
490 490 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
491 491 mf = ctx.manifest()
492 492 node = ctx.node()
493 493
494 494 files = {}
495 495 dirs = {}
496 496 parity = paritygen(web.stripecount)
497 497
498 498 if path and path[-1] != "/":
499 499 path += "/"
500 500 l = len(path)
501 501 abspath = "/" + path
502 502
503 503 for full, n in mf.iteritems():
504 504 # the virtual path (working copy path) used for the full
505 505 # (repository) path
506 506 f = decodepath(full)
507 507
508 508 if f[:l] != path:
509 509 continue
510 510 remain = f[l:]
511 511 elements = remain.split('/')
512 512 if len(elements) == 1:
513 513 files[remain] = full
514 514 else:
515 515 h = dirs # need to retain ref to dirs (root)
516 516 for elem in elements[0:-1]:
517 517 if elem not in h:
518 518 h[elem] = {}
519 519 h = h[elem]
520 520 if len(h) > 1:
521 521 break
522 522 h[None] = None # denotes files present
523 523
524 524 if mf and not files and not dirs:
525 525 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
526 526
527 527 def filelist(**map):
528 528 for f in sorted(files):
529 529 full = files[f]
530 530
531 531 fctx = ctx.filectx(full)
532 532 yield {"file": full,
533 533 "parity": next(parity),
534 534 "basename": f,
535 535 "date": fctx.date(),
536 536 "size": fctx.size(),
537 537 "permissions": mf.flags(full)}
538 538
539 539 def dirlist(**map):
540 540 for d in sorted(dirs):
541 541
542 542 emptydirs = []
543 543 h = dirs[d]
544 544 while isinstance(h, dict) and len(h) == 1:
545 545 k, v = h.items()[0]
546 546 if v:
547 547 emptydirs.append(k)
548 548 h = v
549 549
550 550 path = "%s%s" % (abspath, d)
551 551 yield {"parity": next(parity),
552 552 "path": path,
553 553 "emptydirs": "/".join(emptydirs),
554 554 "basename": d}
555 555
556 556 return tmpl("manifest",
557 557 symrev=symrev,
558 558 path=abspath,
559 559 up=webutil.up(abspath),
560 560 upparity=next(parity),
561 561 fentries=filelist,
562 562 dentries=dirlist,
563 563 archives=web.archivelist(hex(node)),
564 564 **webutil.commonentry(web.repo, ctx))
565 565
566 566 @webcommand('tags')
567 567 def tags(web, req, tmpl):
568 568 """
569 569 /tags
570 570 -----
571 571
572 572 Show information about tags.
573 573
574 574 No arguments are accepted.
575 575
576 576 The ``tags`` template is rendered.
577 577 """
578 578 i = list(reversed(web.repo.tagslist()))
579 579 parity = paritygen(web.stripecount)
580 580
581 581 def entries(notip, latestonly, **map):
582 582 t = i
583 583 if notip:
584 584 t = [(k, n) for k, n in i if k != "tip"]
585 585 if latestonly:
586 586 t = t[:1]
587 587 for k, n in t:
588 588 yield {"parity": next(parity),
589 589 "tag": k,
590 590 "date": web.repo[n].date(),
591 591 "node": hex(n)}
592 592
593 593 return tmpl("tags",
594 594 node=hex(web.repo.changelog.tip()),
595 595 entries=lambda **x: entries(False, False, **x),
596 596 entriesnotip=lambda **x: entries(True, False, **x),
597 597 latestentry=lambda **x: entries(True, True, **x))
598 598
599 599 @webcommand('bookmarks')
600 600 def bookmarks(web, req, tmpl):
601 601 """
602 602 /bookmarks
603 603 ----------
604 604
605 605 Show information about bookmarks.
606 606
607 607 No arguments are accepted.
608 608
609 609 The ``bookmarks`` template is rendered.
610 610 """
611 611 i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
612 612 sortkey = lambda b: (web.repo[b[1]].rev(), b[0])
613 613 i = sorted(i, key=sortkey, reverse=True)
614 614 parity = paritygen(web.stripecount)
615 615
616 616 def entries(latestonly, **map):
617 617 t = i
618 618 if latestonly:
619 619 t = i[:1]
620 620 for k, n in t:
621 621 yield {"parity": next(parity),
622 622 "bookmark": k,
623 623 "date": web.repo[n].date(),
624 624 "node": hex(n)}
625 625
626 626 if i:
627 627 latestrev = i[0][1]
628 628 else:
629 629 latestrev = -1
630 630
631 631 return tmpl("bookmarks",
632 632 node=hex(web.repo.changelog.tip()),
633 633 lastchange=[{"date": web.repo[latestrev].date()}],
634 634 entries=lambda **x: entries(latestonly=False, **x),
635 635 latestentry=lambda **x: entries(latestonly=True, **x))
636 636
637 637 @webcommand('branches')
638 638 def branches(web, req, tmpl):
639 639 """
640 640 /branches
641 641 ---------
642 642
643 643 Show information about branches.
644 644
645 645 All known branches are contained in the output, even closed branches.
646 646
647 647 No arguments are accepted.
648 648
649 649 The ``branches`` template is rendered.
650 650 """
651 651 entries = webutil.branchentries(web.repo, web.stripecount)
652 652 latestentry = webutil.branchentries(web.repo, web.stripecount, 1)
653 653 return tmpl('branches', node=hex(web.repo.changelog.tip()),
654 654 entries=entries, latestentry=latestentry)
655 655
656 656 @webcommand('summary')
657 657 def summary(web, req, tmpl):
658 658 """
659 659 /summary
660 660 --------
661 661
662 662 Show a summary of repository state.
663 663
664 664 Information about the latest changesets, bookmarks, tags, and branches
665 665 is captured by this handler.
666 666
667 667 The ``summary`` template is rendered.
668 668 """
669 669 i = reversed(web.repo.tagslist())
670 670
671 671 def tagentries(**map):
672 672 parity = paritygen(web.stripecount)
673 673 count = 0
674 674 for k, n in i:
675 675 if k == "tip": # skip tip
676 676 continue
677 677
678 678 count += 1
679 679 if count > 10: # limit to 10 tags
680 680 break
681 681
682 682 yield tmpl("tagentry",
683 683 parity=next(parity),
684 684 tag=k,
685 685 node=hex(n),
686 686 date=web.repo[n].date())
687 687
688 688 def bookmarks(**map):
689 689 parity = paritygen(web.stripecount)
690 690 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
691 691 sortkey = lambda b: (web.repo[b[1]].rev(), b[0])
692 692 marks = sorted(marks, key=sortkey, reverse=True)
693 693 for k, n in marks[:10]: # limit to 10 bookmarks
694 694 yield {'parity': next(parity),
695 695 'bookmark': k,
696 696 'date': web.repo[n].date(),
697 697 'node': hex(n)}
698 698
699 699 def changelist(**map):
700 700 parity = paritygen(web.stripecount, offset=start - end)
701 701 l = [] # build a list in forward order for efficiency
702 702 revs = []
703 703 if start < end:
704 704 revs = web.repo.changelog.revs(start, end - 1)
705 705 for i in revs:
706 706 ctx = web.repo[i]
707 707
708 708 l.append(tmpl(
709 709 'shortlogentry',
710 710 parity=next(parity),
711 711 **webutil.commonentry(web.repo, ctx)))
712 712
713 713 for entry in reversed(l):
714 714 yield entry
715 715
716 716 tip = web.repo['tip']
717 717 count = len(web.repo)
718 718 start = max(0, count - web.maxchanges)
719 719 end = min(count, start + web.maxchanges)
720 720
721 721 desc = web.config("web", "description")
722 722 if not desc:
723 723 desc = 'unknown'
724 724 return tmpl("summary",
725 725 desc=desc,
726 726 owner=get_contact(web.config) or "unknown",
727 727 lastchange=tip.date(),
728 728 tags=tagentries,
729 729 bookmarks=bookmarks,
730 730 branches=webutil.branchentries(web.repo, web.stripecount, 10),
731 731 shortlog=changelist,
732 732 node=tip.hex(),
733 733 symrev='tip',
734 734 archives=web.archivelist("tip"),
735 735 labels=web.configlist('web', 'labels'))
736 736
737 737 @webcommand('filediff')
738 738 def filediff(web, req, tmpl):
739 739 """
740 740 /diff/{revision}/{path}
741 741 -----------------------
742 742
743 743 Show how a file changed in a particular commit.
744 744
745 745 The ``filediff`` template is rendered.
746 746
747 747 This handler is registered under both the ``/diff`` and ``/filediff``
748 748 paths. ``/diff`` is used in modern code.
749 749 """
750 750 fctx, ctx = None, None
751 751 try:
752 752 fctx = webutil.filectx(web.repo, req)
753 753 except LookupError:
754 754 ctx = webutil.changectx(web.repo, req)
755 755 path = webutil.cleanpath(web.repo, req.form['file'][0])
756 756 if path not in ctx.files():
757 757 raise
758 758
759 759 if fctx is not None:
760 760 path = fctx.path()
761 761 ctx = fctx.changectx()
762 762 basectx = ctx.p1()
763 763
764 764 style = web.config('web', 'style')
765 765 if 'style' in req.form:
766 766 style = req.form['style'][0]
767 767
768 768 diffs = webutil.diffs(web, tmpl, ctx, basectx, [path], style)
769 769 if fctx is not None:
770 770 rename = webutil.renamelink(fctx)
771 771 ctx = fctx
772 772 else:
773 773 rename = []
774 774 ctx = ctx
775 775 return tmpl("filediff",
776 776 file=path,
777 777 symrev=webutil.symrevorshortnode(req, ctx),
778 778 rename=rename,
779 779 diff=diffs,
780 780 **webutil.commonentry(web.repo, ctx))
781 781
782 782 diff = webcommand('diff')(filediff)
783 783
784 784 @webcommand('comparison')
785 785 def comparison(web, req, tmpl):
786 786 """
787 787 /comparison/{revision}/{path}
788 788 -----------------------------
789 789
790 790 Show a comparison between the old and new versions of a file from changes
791 791 made on a particular revision.
792 792
793 793 This is similar to the ``diff`` handler. However, this form features
794 794 a split or side-by-side diff rather than a unified diff.
795 795
796 796 The ``context`` query string argument can be used to control the lines of
797 797 context in the diff.
798 798
799 799 The ``filecomparison`` template is rendered.
800 800 """
801 801 ctx = webutil.changectx(web.repo, req)
802 802 if 'file' not in req.form:
803 803 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
804 804 path = webutil.cleanpath(web.repo, req.form['file'][0])
805 805
806 806 parsecontext = lambda v: v == 'full' and -1 or int(v)
807 807 if 'context' in req.form:
808 808 context = parsecontext(req.form['context'][0])
809 809 else:
810 810 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
811 811
812 812 def filelines(f):
813 813 if f.isbinary():
814 814 mt = mimetypes.guess_type(f.path())[0]
815 815 if not mt:
816 816 mt = 'application/octet-stream'
817 817 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
818 818 return f.data().splitlines()
819 819
820 820 fctx = None
821 821 parent = ctx.p1()
822 822 leftrev = parent.rev()
823 823 leftnode = parent.node()
824 824 rightrev = ctx.rev()
825 825 rightnode = ctx.node()
826 826 if path in ctx:
827 827 fctx = ctx[path]
828 828 rightlines = filelines(fctx)
829 829 if path not in parent:
830 830 leftlines = ()
831 831 else:
832 832 pfctx = parent[path]
833 833 leftlines = filelines(pfctx)
834 834 else:
835 835 rightlines = ()
836 836 pfctx = ctx.parents()[0][path]
837 837 leftlines = filelines(pfctx)
838 838
839 839 comparison = webutil.compare(tmpl, context, leftlines, rightlines)
840 840 if fctx is not None:
841 841 rename = webutil.renamelink(fctx)
842 842 ctx = fctx
843 843 else:
844 844 rename = []
845 845 ctx = ctx
846 846 return tmpl('filecomparison',
847 847 file=path,
848 848 symrev=webutil.symrevorshortnode(req, ctx),
849 849 rename=rename,
850 850 leftrev=leftrev,
851 851 leftnode=hex(leftnode),
852 852 rightrev=rightrev,
853 853 rightnode=hex(rightnode),
854 854 comparison=comparison,
855 855 **webutil.commonentry(web.repo, ctx))
856 856
857 857 @webcommand('annotate')
858 858 def annotate(web, req, tmpl):
859 859 """
860 860 /annotate/{revision}/{path}
861 861 ---------------------------
862 862
863 863 Show changeset information for each line in a file.
864 864
865 865 The ``ignorews``, ``ignorewsamount``, ``ignorewseol``, and
866 866 ``ignoreblanklines`` query string arguments have the same meaning as
867 867 their ``[annotate]`` config equivalents. It uses the hgrc boolean
868 868 parsing logic to interpret the value. e.g. ``0`` and ``false`` are
869 869 false and ``1`` and ``true`` are true. If not defined, the server
870 870 default settings are used.
871 871
872 872 The ``fileannotate`` template is rendered.
873 873 """
874 874 fctx = webutil.filectx(web.repo, req)
875 875 f = fctx.path()
876 876 parity = paritygen(web.stripecount)
877 877 ishead = fctx.filerev() in fctx.filelog().headrevs()
878 878
879 879 # parents() is called once per line and several lines likely belong to
880 880 # same revision. So it is worth caching.
881 881 # TODO there are still redundant operations within basefilectx.parents()
882 882 # and from the fctx.annotate() call itself that could be cached.
883 883 parentscache = {}
884 884 def parents(f):
885 885 rev = f.rev()
886 886 if rev not in parentscache:
887 887 parentscache[rev] = []
888 888 for p in f.parents():
889 889 entry = {
890 890 'node': p.hex(),
891 891 'rev': p.rev(),
892 892 }
893 893 parentscache[rev].append(entry)
894 894
895 895 for p in parentscache[rev]:
896 896 yield p
897 897
898 898 def annotate(**map):
899 899 if fctx.isbinary():
900 900 mt = (mimetypes.guess_type(fctx.path())[0]
901 901 or 'application/octet-stream')
902 902 lines = [((fctx.filectx(fctx.filerev()), 1), '(binary:%s)' % mt)]
903 903 else:
904 904 lines = webutil.annotate(req, fctx, web.repo.ui)
905 905
906 906 previousrev = None
907 907 blockparitygen = paritygen(1)
908 908 for lineno, (aline, l) in enumerate(lines):
909 909 f = aline.fctx
910 910 rev = f.rev()
911 911 if rev != previousrev:
912 912 blockhead = True
913 913 blockparity = next(blockparitygen)
914 914 else:
915 915 blockhead = None
916 916 previousrev = rev
917 917 yield {"parity": next(parity),
918 918 "node": f.hex(),
919 919 "rev": rev,
920 920 "author": f.user(),
921 921 "parents": parents(f),
922 922 "desc": f.description(),
923 923 "extra": f.extra(),
924 924 "file": f.path(),
925 925 "blockhead": blockhead,
926 926 "blockparity": blockparity,
927 927 "targetline": aline.lineno,
928 928 "line": l,
929 929 "lineno": lineno + 1,
930 930 "lineid": "l%d" % (lineno + 1),
931 931 "linenumber": "% 6d" % (lineno + 1),
932 932 "revdate": f.date()}
933 933
934 934 diffopts = webutil.difffeatureopts(req, web.repo.ui, 'annotate')
935 935 diffopts = {k: getattr(diffopts, k) for k in diffopts.defaults}
936 936
937 937 return tmpl("fileannotate",
938 938 file=f,
939 939 annotate=annotate,
940 940 path=webutil.up(f),
941 941 symrev=webutil.symrevorshortnode(req, fctx),
942 942 rename=webutil.renamelink(fctx),
943 943 permissions=fctx.manifest().flags(f),
944 944 ishead=int(ishead),
945 945 diffopts=diffopts,
946 946 **webutil.commonentry(web.repo, fctx))
947 947
948 948 @webcommand('filelog')
949 949 def filelog(web, req, tmpl):
950 950 """
951 951 /filelog/{revision}/{path}
952 952 --------------------------
953 953
954 954 Show information about the history of a file in the repository.
955 955
956 956 The ``revcount`` query string argument can be defined to control the
957 957 maximum number of entries to show.
958 958
959 959 The ``filelog`` template will be rendered.
960 960 """
961 961
962 962 try:
963 963 fctx = webutil.filectx(web.repo, req)
964 964 f = fctx.path()
965 965 fl = fctx.filelog()
966 966 except error.LookupError:
967 967 f = webutil.cleanpath(web.repo, req.form['file'][0])
968 968 fl = web.repo.file(f)
969 969 numrevs = len(fl)
970 970 if not numrevs: # file doesn't exist at all
971 971 raise
972 972 rev = webutil.changectx(web.repo, req).rev()
973 973 first = fl.linkrev(0)
974 974 if rev < first: # current rev is from before file existed
975 975 raise
976 976 frev = numrevs - 1
977 977 while fl.linkrev(frev) > rev:
978 978 frev -= 1
979 979 fctx = web.repo.filectx(f, fl.linkrev(frev))
980 980
981 981 revcount = web.maxshortchanges
982 982 if 'revcount' in req.form:
983 983 try:
984 984 revcount = int(req.form.get('revcount', [revcount])[0])
985 985 revcount = max(revcount, 1)
986 986 tmpl.defaults['sessionvars']['revcount'] = revcount
987 987 except ValueError:
988 988 pass
989 989
990 990 lrange = webutil.linerange(req)
991 991
992 992 lessvars = copy.copy(tmpl.defaults['sessionvars'])
993 993 lessvars['revcount'] = max(revcount / 2, 1)
994 994 morevars = copy.copy(tmpl.defaults['sessionvars'])
995 995 morevars['revcount'] = revcount * 2
996 996
997 997 patch = 'patch' in req.form
998 998 if patch:
999 999 lessvars['patch'] = morevars['patch'] = req.form['patch'][0]
1000 1000 descend = 'descend' in req.form
1001 1001 if descend:
1002 1002 lessvars['descend'] = morevars['descend'] = req.form['descend'][0]
1003 1003
1004 1004 count = fctx.filerev() + 1
1005 1005 start = max(0, count - revcount) # first rev on this page
1006 1006 end = min(count, start + revcount) # last rev on this page
1007 1007 parity = paritygen(web.stripecount, offset=start - end)
1008 1008
1009 1009 repo = web.repo
1010 1010 revs = fctx.filelog().revs(start, end - 1)
1011 1011 entries = []
1012 1012
1013 1013 diffstyle = web.config('web', 'style')
1014 1014 if 'style' in req.form:
1015 1015 diffstyle = req.form['style'][0]
1016 1016
1017 1017 def diff(fctx, linerange=None):
1018 1018 ctx = fctx.changectx()
1019 1019 basectx = ctx.p1()
1020 1020 path = fctx.path()
1021 1021 return webutil.diffs(web, tmpl, ctx, basectx, [path], diffstyle,
1022 1022 linerange=linerange,
1023 1023 lineidprefix='%s-' % ctx.hex()[:12])
1024 1024
1025 1025 linerange = None
1026 1026 if lrange is not None:
1027 1027 linerange = webutil.formatlinerange(*lrange)
1028 1028 # deactivate numeric nav links when linerange is specified as this
1029 1029 # would required a dedicated "revnav" class
1030 1030 nav = None
1031 1031 if descend:
1032 1032 it = dagop.blockdescendants(fctx, *lrange)
1033 1033 else:
1034 1034 it = dagop.blockancestors(fctx, *lrange)
1035 1035 for i, (c, lr) in enumerate(it, 1):
1036 1036 diffs = None
1037 1037 if patch:
1038 1038 diffs = diff(c, linerange=lr)
1039 1039 # follow renames accross filtered (not in range) revisions
1040 1040 path = c.path()
1041 1041 entries.append(dict(
1042 1042 parity=next(parity),
1043 1043 filerev=c.rev(),
1044 1044 file=path,
1045 1045 diff=diffs,
1046 1046 linerange=webutil.formatlinerange(*lr),
1047 1047 **webutil.commonentry(repo, c)))
1048 1048 if i == revcount:
1049 1049 break
1050 1050 lessvars['linerange'] = webutil.formatlinerange(*lrange)
1051 1051 morevars['linerange'] = lessvars['linerange']
1052 1052 else:
1053 1053 for i in revs:
1054 1054 iterfctx = fctx.filectx(i)
1055 1055 diffs = None
1056 1056 if patch:
1057 1057 diffs = diff(iterfctx)
1058 1058 entries.append(dict(
1059 1059 parity=next(parity),
1060 1060 filerev=i,
1061 1061 file=f,
1062 1062 diff=diffs,
1063 1063 rename=webutil.renamelink(iterfctx),
1064 1064 **webutil.commonentry(repo, iterfctx)))
1065 1065 entries.reverse()
1066 1066 revnav = webutil.filerevnav(web.repo, fctx.path())
1067 1067 nav = revnav.gen(end - 1, revcount, count)
1068 1068
1069 1069 latestentry = entries[:1]
1070 1070
1071 1071 return tmpl("filelog",
1072 1072 file=f,
1073 1073 nav=nav,
1074 1074 symrev=webutil.symrevorshortnode(req, fctx),
1075 1075 entries=entries,
1076 1076 descend=descend,
1077 1077 patch=patch,
1078 1078 latestentry=latestentry,
1079 1079 linerange=linerange,
1080 1080 revcount=revcount,
1081 1081 morevars=morevars,
1082 1082 lessvars=lessvars,
1083 1083 **webutil.commonentry(web.repo, fctx))
1084 1084
1085 1085 @webcommand('archive')
1086 1086 def archive(web, req, tmpl):
1087 1087 """
1088 1088 /archive/{revision}.{format}[/{path}]
1089 1089 -------------------------------------
1090 1090
1091 1091 Obtain an archive of repository content.
1092 1092
1093 1093 The content and type of the archive is defined by a URL path parameter.
1094 1094 ``format`` is the file extension of the archive type to be generated. e.g.
1095 1095 ``zip`` or ``tar.bz2``. Not all archive types may be allowed by your
1096 1096 server configuration.
1097 1097
1098 1098 The optional ``path`` URL parameter controls content to include in the
1099 1099 archive. If omitted, every file in the specified revision is present in the
1100 1100 archive. If included, only the specified file or contents of the specified
1101 1101 directory will be included in the archive.
1102 1102
1103 1103 No template is used for this handler. Raw, binary content is generated.
1104 1104 """
1105 1105
1106 1106 type_ = req.form.get('type', [None])[0]
1107 1107 allowed = web.configlist("web", "allow_archive")
1108 1108 key = req.form['node'][0]
1109 1109
1110 1110 if type_ not in web.archivespecs:
1111 1111 msg = 'Unsupported archive type: %s' % type_
1112 1112 raise ErrorResponse(HTTP_NOT_FOUND, msg)
1113 1113
1114 1114 if not ((type_ in allowed or
1115 1115 web.configbool("web", "allow" + type_))):
1116 1116 msg = 'Archive type not allowed: %s' % type_
1117 1117 raise ErrorResponse(HTTP_FORBIDDEN, msg)
1118 1118
1119 1119 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
1120 1120 cnode = web.repo.lookup(key)
1121 1121 arch_version = key
1122 1122 if cnode == key or key == 'tip':
1123 1123 arch_version = short(cnode)
1124 1124 name = "%s-%s" % (reponame, arch_version)
1125 1125
1126 1126 ctx = webutil.changectx(web.repo, req)
1127 1127 pats = []
1128 1128 match = scmutil.match(ctx, [])
1129 1129 file = req.form.get('file', None)
1130 1130 if file:
1131 1131 pats = ['path:' + file[0]]
1132 1132 match = scmutil.match(ctx, pats, default='path')
1133 1133 if pats:
1134 1134 files = [f for f in ctx.manifest().keys() if match(f)]
1135 1135 if not files:
1136 1136 raise ErrorResponse(HTTP_NOT_FOUND,
1137 1137 'file(s) not found: %s' % file[0])
1138 1138
1139 1139 mimetype, artype, extension, encoding = web.archivespecs[type_]
1140 1140 headers = [
1141 1141 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
1142 1142 ]
1143 1143 if encoding:
1144 1144 headers.append(('Content-Encoding', encoding))
1145 1145 req.headers.extend(headers)
1146 1146 req.respond(HTTP_OK, mimetype)
1147 1147
1148 1148 archival.archive(web.repo, req, cnode, artype, prefix=name,
1149 1149 matchfn=match,
1150 1150 subrepos=web.configbool("web", "archivesubrepos"))
1151 1151 return []
1152 1152
1153 1153
1154 1154 @webcommand('static')
1155 1155 def static(web, req, tmpl):
1156 1156 fname = req.form['file'][0]
1157 1157 # a repo owner may set web.static in .hg/hgrc to get any file
1158 1158 # readable by the user running the CGI script
1159 1159 static = web.config("web", "static", None, untrusted=False)
1160 1160 if not static:
1161 1161 tp = web.templatepath or templater.templatepaths()
1162 1162 if isinstance(tp, str):
1163 1163 tp = [tp]
1164 1164 static = [os.path.join(p, 'static') for p in tp]
1165 1165 staticfile(static, fname, req)
1166 1166 return []
1167 1167
1168 1168 @webcommand('graph')
1169 1169 def graph(web, req, tmpl):
1170 1170 """
1171 1171 /graph[/{revision}]
1172 1172 -------------------
1173 1173
1174 1174 Show information about the graphical topology of the repository.
1175 1175
1176 1176 Information rendered by this handler can be used to create visual
1177 1177 representations of repository topology.
1178 1178
1179 1179 The ``revision`` URL parameter controls the starting changeset. If it's
1180 1180 absent, the default is ``tip``.
1181 1181
1182 1182 The ``revcount`` query string argument can define the number of changesets
1183 1183 to show information for.
1184 1184
1185 1185 The ``graphtop`` query string argument can specify the starting changeset
1186 1186 for producing ``jsdata`` variable that is used for rendering graph in
1187 1187 JavaScript. By default it has the same value as ``revision``.
1188 1188
1189 1189 This handler will render the ``graph`` template.
1190 1190 """
1191 1191
1192 1192 if 'node' in req.form:
1193 1193 ctx = webutil.changectx(web.repo, req)
1194 1194 symrev = webutil.symrevorshortnode(req, ctx)
1195 1195 else:
1196 1196 ctx = web.repo['tip']
1197 1197 symrev = 'tip'
1198 1198 rev = ctx.rev()
1199 1199
1200 1200 bg_height = 39
1201 1201 revcount = web.maxshortchanges
1202 1202 if 'revcount' in req.form:
1203 1203 try:
1204 1204 revcount = int(req.form.get('revcount', [revcount])[0])
1205 1205 revcount = max(revcount, 1)
1206 1206 tmpl.defaults['sessionvars']['revcount'] = revcount
1207 1207 except ValueError:
1208 1208 pass
1209 1209
1210 1210 lessvars = copy.copy(tmpl.defaults['sessionvars'])
1211 1211 lessvars['revcount'] = max(revcount / 2, 1)
1212 1212 morevars = copy.copy(tmpl.defaults['sessionvars'])
1213 1213 morevars['revcount'] = revcount * 2
1214 1214
1215 1215 graphtop = req.form.get('graphtop', [ctx.hex()])[0]
1216 1216 graphvars = copy.copy(tmpl.defaults['sessionvars'])
1217 1217 graphvars['graphtop'] = graphtop
1218 1218
1219 1219 count = len(web.repo)
1220 1220 pos = rev
1221 1221
1222 1222 uprev = min(max(0, count - 1), rev + revcount)
1223 1223 downrev = max(0, rev - revcount)
1224 1224 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
1225 1225
1226 1226 tree = []
1227 1227 nextentry = []
1228 1228 lastrev = 0
1229 1229 if pos != -1:
1230 1230 allrevs = web.repo.changelog.revs(pos, 0)
1231 1231 revs = []
1232 1232 for i in allrevs:
1233 1233 revs.append(i)
1234 1234 if len(revs) >= revcount + 1:
1235 1235 break
1236 1236
1237 1237 if len(revs) > revcount:
1238 1238 nextentry = [webutil.commonentry(web.repo, web.repo[revs[-1]])]
1239 1239 revs = revs[:-1]
1240 1240
1241 1241 lastrev = revs[-1]
1242 1242
1243 1243 # We have to feed a baseset to dagwalker as it is expecting smartset
1244 1244 # object. This does not have a big impact on hgweb performance itself
1245 1245 # since hgweb graphing code is not itself lazy yet.
1246 1246 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs))
1247 1247 # As we said one line above... not lazy.
1248 1248 tree = list(item for item in graphmod.colored(dag, web.repo)
1249 1249 if item[1] == graphmod.CHANGESET)
1250 1250
1251 1251 def fulltree():
1252 1252 pos = web.repo[graphtop].rev()
1253 1253 tree = []
1254 1254 if pos != -1:
1255 1255 revs = web.repo.changelog.revs(pos, lastrev)
1256 1256 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs))
1257 1257 tree = list(item for item in graphmod.colored(dag, web.repo)
1258 1258 if item[1] == graphmod.CHANGESET)
1259 1259 return tree
1260 1260
1261 1261 def jsdata():
1262 1262 return [{'node': pycompat.bytestr(ctx),
1263 1263 'vertex': vtx,
1264 1264 'edges': edges}
1265 1265 for (id, type, ctx, vtx, edges) in fulltree()]
1266 1266
1267 1267 def nodes():
1268 parity = paritygen(web.stripecount)
1268 1269 for row, (id, type, ctx, vtx, edges) in enumerate(tree):
1269 1270 entry = webutil.commonentry(web.repo, ctx)
1270 1271 edgedata = [{'col': edge[0],
1271 1272 'nextcol': edge[1],
1272 1273 'color': (edge[2] - 1) % 6 + 1,
1273 1274 'width': edge[3],
1274 1275 'bcolor': edge[4]}
1275 1276 for edge in edges]
1276 1277
1277 1278 entry.update({'col': vtx[0],
1278 1279 'color': (vtx[1] - 1) % 6 + 1,
1280 'parity': next(parity),
1279 1281 'edges': edgedata,
1280 1282 'row': row,
1281 1283 'nextrow': row + 1})
1282 1284
1283 1285 yield entry
1284 1286
1285 1287 rows = len(tree)
1286 1288
1287 1289 return tmpl('graph', rev=rev, symrev=symrev, revcount=revcount,
1288 1290 uprev=uprev,
1289 1291 lessvars=lessvars, morevars=morevars, downrev=downrev,
1290 1292 graphvars=graphvars,
1291 1293 rows=rows,
1292 1294 bg_height=bg_height,
1293 1295 changesets=count,
1294 1296 nextentry=nextentry,
1295 1297 jsdata=lambda **x: jsdata(),
1296 1298 nodes=lambda **x: nodes(),
1297 1299 node=ctx.hex(), changenav=changenav)
1298 1300
1299 1301 def _getdoc(e):
1300 1302 doc = e[0].__doc__
1301 1303 if doc:
1302 1304 doc = _(doc).partition('\n')[0]
1303 1305 else:
1304 1306 doc = _('(no help text available)')
1305 1307 return doc
1306 1308
1307 1309 @webcommand('help')
1308 1310 def help(web, req, tmpl):
1309 1311 """
1310 1312 /help[/{topic}]
1311 1313 ---------------
1312 1314
1313 1315 Render help documentation.
1314 1316
1315 1317 This web command is roughly equivalent to :hg:`help`. If a ``topic``
1316 1318 is defined, that help topic will be rendered. If not, an index of
1317 1319 available help topics will be rendered.
1318 1320
1319 1321 The ``help`` template will be rendered when requesting help for a topic.
1320 1322 ``helptopics`` will be rendered for the index of help topics.
1321 1323 """
1322 1324 from .. import commands, help as helpmod # avoid cycle
1323 1325
1324 1326 topicname = req.form.get('node', [None])[0]
1325 1327 if not topicname:
1326 1328 def topics(**map):
1327 1329 for entries, summary, _doc in helpmod.helptable:
1328 1330 yield {'topic': entries[0], 'summary': summary}
1329 1331
1330 1332 early, other = [], []
1331 1333 primary = lambda s: s.partition('|')[0]
1332 1334 for c, e in commands.table.iteritems():
1333 1335 doc = _getdoc(e)
1334 1336 if 'DEPRECATED' in doc or c.startswith('debug'):
1335 1337 continue
1336 1338 cmd = primary(c)
1337 1339 if cmd.startswith('^'):
1338 1340 early.append((cmd[1:], doc))
1339 1341 else:
1340 1342 other.append((cmd, doc))
1341 1343
1342 1344 early.sort()
1343 1345 other.sort()
1344 1346
1345 1347 def earlycommands(**map):
1346 1348 for c, doc in early:
1347 1349 yield {'topic': c, 'summary': doc}
1348 1350
1349 1351 def othercommands(**map):
1350 1352 for c, doc in other:
1351 1353 yield {'topic': c, 'summary': doc}
1352 1354
1353 1355 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
1354 1356 othercommands=othercommands, title='Index')
1355 1357
1356 1358 # Render an index of sub-topics.
1357 1359 if topicname in helpmod.subtopics:
1358 1360 topics = []
1359 1361 for entries, summary, _doc in helpmod.subtopics[topicname]:
1360 1362 topics.append({
1361 1363 'topic': '%s.%s' % (topicname, entries[0]),
1362 1364 'basename': entries[0],
1363 1365 'summary': summary,
1364 1366 })
1365 1367
1366 1368 return tmpl('helptopics', topics=topics, title=topicname,
1367 1369 subindex=True)
1368 1370
1369 1371 u = webutil.wsgiui.load()
1370 1372 u.verbose = True
1371 1373
1372 1374 # Render a page from a sub-topic.
1373 1375 if '.' in topicname:
1374 1376 # TODO implement support for rendering sections, like
1375 1377 # `hg help` works.
1376 1378 topic, subtopic = topicname.split('.', 1)
1377 1379 if topic not in helpmod.subtopics:
1378 1380 raise ErrorResponse(HTTP_NOT_FOUND)
1379 1381 else:
1380 1382 topic = topicname
1381 1383 subtopic = None
1382 1384
1383 1385 try:
1384 1386 doc = helpmod.help_(u, commands, topic, subtopic=subtopic)
1385 1387 except error.UnknownCommand:
1386 1388 raise ErrorResponse(HTTP_NOT_FOUND)
1387 1389 return tmpl('help', topic=topicname, doc=doc)
1388 1390
1389 1391 # tell hggettext to extract docstrings from these functions:
1390 1392 i18nfunctions = commands.values()
@@ -1,72 +1,65 b''
1 1 {header}
2 2 <title>{repo|escape}: graph</title>
3 3 <link rel="alternate" type="application/atom+xml" href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/>
4 4 <link rel="alternate" type="application/rss+xml" href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/>
5 5 <!--[if IE]><script type="text/javascript" src="{staticurl|urlescape}excanvas.js"></script><![endif]-->
6 6 </head>
7 7
8 8 <body>
9 9 <div id="container">
10 10 <div class="page-header">
11 11 <h1 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb} / graph</h1>
12 12
13 13 {searchform}
14 14
15 15 <ul class="page-nav">
16 16 <li><a href="{url|urlescape}summary{sessionvars%urlparameter}">summary</a></li>
17 17 <li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">shortlog</a></li>
18 18 <li><a href="{url|urlescape}changelog{sessionvars%urlparameter}">changelog</a></li>
19 19 <li class="current">graph</li>
20 20 <li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
21 21 <li><a href="{url|urlescape}bookmarks{sessionvars%urlparameter}">bookmarks</a></li>
22 22 <li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
23 23 <li><a href="{url|urlescape}file/{symrev}{sessionvars%urlparameter}">files</a></li>
24 24 <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
25 25 </ul>
26 26 </div>
27 27
28 28 <h2 class="no-link no-border">graph</h2>
29 29
30 30 <div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
31 31 <div id="wrapper">
32 <ul id="nodebgs"></ul>
33 32 <canvas id="graph"></canvas>
34 33 <ul id="graphnodes">{nodes%graphentry}</ul>
35 34 </div>
36 35
37 36 <script{if(nonce, ' nonce="{nonce}"')}>
38 37 document.getElementById('noscript').style.display = 'none';
39 38
40 39 var data = {jsdata|json};
41 40 var graph = new Graph();
42 41 graph.scale({bg_height});
43
44 graph.vertex = function(x, y, radius, color, parity, cur) \{
45 Graph.prototype.vertex.apply(this, arguments);
46 return ['<li class="bg parity' + parity + '"></li>', ''];
47 }
48
49 42 graph.render(data);
50 43 </script>
51 44
52 45 <div class="page-path">
53 46 <a href="{url|urlescape}graph/{symrev}{lessvars%urlparameter}">less</a>
54 47 <a href="{url|urlescape}graph/{symrev}{morevars%urlparameter}">more</a>
55 48 | {changenav%navgraph}
56 49 </div>
57 50
58 51 <script type="text/javascript"{if(nonce, ' nonce="{nonce}"')}>
59 52 ajaxScrollInit(
60 53 '{url|urlescape}graph/%next%{graphvars%urlparameter}',
61 54 '{nextentry%"{node}"}', <!-- NEXTHASH
62 55 function (htmlText, previousVal) \{
63 56 var m = htmlText.match(/'(\w+)', <!-- NEXTHASH/);
64 57 return m ? m[1] : null;
65 58 },
66 59 '#wrapper',
67 60 '<div class="%class%" style="text-align: center;">%text%</div>',
68 61 'graph'
69 62 );
70 63 </script>
71 64
72 65 {footer}
@@ -1,7 +1,9 b''
1 <li data-node="{node|short}">
2 <span class="desc">
3 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>
4 </span>
5 {alltags}
6 <div class="info"><span class="age">{date|rfc822date}</span>, by {author|person}</div>
1 <li class="parity{parity}" data-node="{node|short}">
2 <div class="fg">
3 <span class="desc">
4 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>
5 </span>
6 {alltags}
7 <div class="info"><span class="age">{date|rfc822date}</span>, by {author|person}</div>
8 </div>
7 9 </li>
@@ -1,586 +1,588 b''
1 1 /*** Initial Settings ***/
2 2 * {
3 3 margin: 0;
4 4 padding: 0;
5 5 font-weight: normal;
6 6 font-style: normal;
7 7 }
8 8
9 9 html {
10 10 font-size: 100%;
11 11 font-family: sans-serif;
12 12 }
13 13
14 14 body {
15 15 font-size: 77%;
16 16 margin: 15px 50px;
17 17 background: #4B4B4C;
18 18 }
19 19
20 20 a {
21 21 color:#0000cc;
22 22 text-decoration: none;
23 23 }
24 24 /*** end of Initial Settings ***/
25 25
26 26
27 27 /** common settings **/
28 28 div#container {
29 29 background: #FFFFFF;
30 30 position: relative;
31 31 color: #666;
32 32 }
33 33
34 34 div.page-header {
35 35 padding: 50px 20px 0;
36 36 background: #006699 top left repeat-x;
37 37 position: relative;
38 38 }
39 39 div.page-header h1 {
40 40 margin: 10px 0 30px;
41 41 font-size: 1.8em;
42 42 font-weight: bold;
43 43 font-family: osaka,'MS P Gothic', Georgia, serif;
44 44 letter-spacing: 1px;
45 45 color: #DDD;
46 46 }
47 47 div.page-header h1 a {
48 48 font-weight: bold;
49 49 color: #FFF;
50 50 }
51 51 div.page-header a {
52 52 text-decoration: none;
53 53 }
54 54
55 55 div.page-header form {
56 56 float: right;
57 57 margin-top: -2px;
58 58 }
59 59 div.page-header form label {
60 60 color: #DDD;
61 61 }
62 62 div.page-header form input {
63 63 padding: 2px;
64 64 border: solid 1px #DDD;
65 65 }
66 66 div.page-header form dl {
67 67 overflow: hidden;
68 68 }
69 69 div.page-header form dl dt {
70 70 font-size: 1.2em;
71 71 }
72 72 div.page-header form dl dt,
73 73 div.page-header form dl dd {
74 74 margin: 0 0 0 5px;
75 75 float: left;
76 76 height: 24px;
77 77 line-height: 20px;
78 78 }
79 79
80 80 ul.page-nav {
81 81 margin: 10px 0 0 0;
82 82 list-style-type: none;
83 83 overflow: hidden;
84 84 }
85 85 ul.page-nav li {
86 86 margin: 0 2px 0 0;
87 87 float: left;
88 88 width: 80px;
89 89 height: 24px;
90 90 font-size: 1.1em;
91 91 line-height: 24px;
92 92 text-align: center;
93 93 }
94 94 ul.page-nav li.current {
95 95 background: #FFF;
96 96 }
97 97 ul.page-nav li a {
98 98 height: 24px;
99 99 color: #666;
100 100 background: #DDD;
101 101 display: block;
102 102 text-decoration: none;
103 103 }
104 104 ul.page-nav li a:hover {
105 105 color:#333;
106 106 background: #FFF;
107 107 }
108 108
109 109 ul.submenu {
110 110 margin: 10px 0 -10px 20px;
111 111 list-style-type: none;
112 112 }
113 113 ul.submenu li {
114 114 margin: 0 10px 0 0;
115 115 font-size: 1.2em;
116 116 display: inline;
117 117 }
118 118
119 119 h2 {
120 120 margin: 20px 0 10px;
121 121 height: 30px;
122 122 line-height: 30px;
123 123 text-indent: 20px;
124 124 background: #FFF;
125 125 font-size: 1.2em;
126 126 border-top: dotted 1px #D5E1E6;
127 127 font-weight: bold;
128 128 }
129 129 h2.no-link {
130 130 color:#006699;
131 131 }
132 132 h2.no-border {
133 133 color: #FFF;
134 134 background: #006699;
135 135 border: 0;
136 136 }
137 137 h2 a {
138 138 font-weight:bold;
139 139 color:#006699;
140 140 }
141 141
142 142 div.page-path {
143 143 text-align: right;
144 144 padding: 20px 30px 10px 0;
145 145 border:solid #d9d8d1;
146 146 border-width:0px 0px 1px;
147 147 font-size: 1.2em;
148 148 }
149 149
150 150 div.page-footer {
151 151 margin: 50px 0 0;
152 152 position: relative;
153 153 }
154 154 div.page-footer p {
155 155 position: relative;
156 156 padding-left: 20px;
157 157 bottom: 5px;
158 158 font-size: 1.2em;
159 159 }
160 160
161 161 ul.rss-logo {
162 162 position: absolute;
163 163 top: -10px;
164 164 right: 20px;
165 165 height: 20px;
166 166 list-style-type: none;
167 167 }
168 168 ul.rss-logo li {
169 169 display: inline;
170 170 }
171 171 ul.rss-logo li a {
172 172 padding: 3px 6px;
173 173 line-height: 10px;
174 174 border:1px solid;
175 175 border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
176 176 color:#ffffff;
177 177 background-color:#ff6600;
178 178 font-weight:bold;
179 179 font-family:sans-serif;
180 180 font-size:10px;
181 181 text-align:center;
182 182 text-decoration:none;
183 183 }
184 184 div.rss-logo li a:hover {
185 185 background-color:#ee5500;
186 186 }
187 187
188 188 p.normal {
189 189 margin: 20px 0 20px 30px;
190 190 font-size: 1.2em;
191 191 }
192 192
193 193 table {
194 194 margin: 10px 0 0 20px;
195 195 width: 95%;
196 196 border-collapse: collapse;
197 197 }
198 198 table tr td {
199 199 font-size: 1.1em;
200 200 }
201 201 table tr td.nowrap {
202 202 white-space: nowrap;
203 203 }
204 204 table tr td.closed {
205 205 background-color: #99f;
206 206 }
207 207 /*
208 208 table tr.parity0:hover,
209 209 table tr.parity1:hover {
210 210 background: #D5E1E6;
211 211 }
212 212 */
213 213 table tr.parity0,
214 214 table td.annotate.parity0 {
215 215 background: #F1F6F7;
216 216 }
217 217 table tr.parity1,
218 218 table td.annotate.parity1 {
219 219 background: #FFFFFF;
220 220 }
221 221 table tr td {
222 222 padding: 5px 5px;
223 223 }
224 224 table.annotated tr td {
225 225 padding: 0px 5px;
226 226 }
227 227
228 228 span.logtags span {
229 229 padding: 2px 6px;
230 230 font-weight: normal;
231 231 font-size: 11px;
232 232 border: 1px solid;
233 233 background-color: #ffaaff;
234 234 border-color: #ffccff #ff00ee #ff00ee #ffccff;
235 235 }
236 236 span.logtags span.phasetag {
237 237 background-color: #dfafff;
238 238 border-color: #e2b8ff #ce48ff #ce48ff #e2b8ff;
239 239 }
240 240 span.logtags span.obsoletetag {
241 241 background-color: #dddddd;
242 242 border-color: #e4e4e4 #a3a3a3 #a3a3a3 #e4e4e4;
243 243 }
244 244 span.logtags span.instabilitytag {
245 245 background-color: #ffb1c0;
246 246 border-color: #ffbbc8 #ff4476 #ff4476 #ffbbc8;
247 247 }
248 248 span.logtags span.tagtag {
249 249 background-color: #ffffaa;
250 250 border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
251 251 }
252 252 span.logtags span.branchtag {
253 253 background-color: #aaffaa;
254 254 border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
255 255 }
256 256 span.logtags span.inbranchtag {
257 257 background-color: #d5dde6;
258 258 border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
259 259 }
260 260 span.logtags span.bookmarktag {
261 261 background-color: #afdffa;
262 262 border-color: #ccecff #46ace6 #46ace6 #ccecff;
263 263 }
264 264
265 265 div.diff pre {
266 266 margin: 10px 0 0 0;
267 267 }
268 268 div.diff pre span {
269 269 font-family: monospace;
270 270 white-space: pre;
271 271 font-size: 1.2em;
272 272 }
273 273 div.diffblocks { counter-reset: lineno; }
274 274 div.diffblock { counter-increment: lineno; }
275 275 span.difflineplus { color:#008800; }
276 276 span.difflineminus { color:#cc0000; }
277 277 span.difflineat { color:#990099; }
278 278
279 279 pre.sourcelines {
280 280 position: relative;
281 281 counter-reset: lineno;
282 282 font-size: 1.2em;
283 283 }
284 284 pre.sourcelines > span {
285 285 display: inline-block;
286 286 box-sizing: border-box;
287 287 width: 100%;
288 288 padding: 0 0 0 5em;
289 289 counter-increment: lineno;
290 290 vertical-align: top;
291 291 }
292 292 div.source > pre.sourcelines > span {
293 293 padding: 1px 1px 1px 5em;
294 294 }
295 295 pre.sourcelines > span:before {
296 296 -moz-user-select: -moz-none;
297 297 -khtml-user-select: none;
298 298 -webkit-user-select: none;
299 299 -ms-user-select: none;
300 300 user-select: none;
301 301 display: inline-block;
302 302 margin-left: -5em;
303 303 width: 4em;
304 304 color: #999;
305 305 text-align: right;
306 306 content: counters(lineno,".");
307 307 float: left;
308 308 }
309 309 pre.sourcelines > a {
310 310 display: inline-block;
311 311 position: absolute;
312 312 left: 0px;
313 313 width: 4em;
314 314 height: 1em;
315 315 padding: 0.15em;
316 316 }
317 317 pre.sourcelines.stripes > :nth-child(4n+2) { background-color: #F1F6F7; }
318 318 pre.sourcelines.stripes > :nth-child(4n+4) { background-color: #FFFFFF; }
319 319 pre.sourcelines.stripes > :nth-child(4n+2):hover,
320 320 pre.sourcelines.stripes > :nth-child(4n+4):hover,
321 321 pre.sourcelines.stripes > :nth-child(4n+1):hover + :nth-child(4n+2),
322 322 pre.sourcelines.stripes > :nth-child(4n+3):hover + :nth-child(4n+4) { background-color: #D5E1E6; }
323 323
324 324 tr:target td,
325 325 pre.sourcelines > span:target,
326 326 pre.sourcelines.stripes > span:target {
327 327 background-color: #bfdfff;
328 328 }
329 329
330 330 td.source {
331 331 white-space: pre;
332 332 margin: 10px 30px 0;
333 333 font-size: 1.2em;
334 334 font-family: monospace;
335 335 }
336 336 .linenr {
337 337 color: #999;
338 338 text-align: right;
339 339 }
340 340 .lineno {
341 341 text-align: right;
342 342 }
343 343 .lineno a {
344 344 color: #999;
345 345 }
346 346 td.linenr {
347 347 width: 60px;
348 348 }
349 349 tr.thisrev a { color:#999999; text-decoration: none; }
350 350 tr.thisrev td.source { color:#009900; }
351 351 td.annotate {
352 352 white-space: nowrap;
353 353 }
354 354 div.annotate-info {
355 355 display: none;
356 356 position: absolute;
357 357 background-color: #FFFFFF;
358 358 border: solid 1px #CCC;
359 359 text-align: left;
360 360 color: #666;
361 361 padding: 5px;
362 362 }
363 363 div.annotate-info a { color: #0000FF; }
364 364 td.annotate:hover div.annotate-info { display: inline; }
365 365
366 366 div#powered-by {
367 367 position: absolute;
368 368 width: 75px;
369 369 top: 15px;
370 370 right: 20px;
371 371 font-size: 1.2em;
372 372 }
373 373 div#powered-by a {
374 374 color: #EEE;
375 375 text-decoration: none;
376 376 }
377 377 div#powered-by a:hover {
378 378 text-decoration: underline;
379 379 }
380 380 /** end of common settings **/
381 381
382 382 /** summary **/
383 383 dl.overview {
384 384 margin: 0 0 0 30px;
385 385 font-size: 1.1em;
386 386 overflow: hidden;
387 387 }
388 388 dl.overview dt,
389 389 dl.overview dd {
390 390 margin: 5px 0;
391 391 float: left;
392 392 }
393 393 dl.overview dt {
394 394 clear: left;
395 395 font-weight: bold;
396 396 width: 150px;
397 397 }
398 398 /** end of summary **/
399 399
400 400 /** chagelog **/
401 401 h3.changelog {
402 402 margin: 20px 0 5px 30px;
403 403 padding: 0 0 2px;
404 404 font-size: 1.4em;
405 405 border-bottom: dotted 1px #D5E1E6;
406 406 }
407 407 ul.changelog-entry {
408 408 margin: 0 0 10px 30px;
409 409 list-style-type: none;
410 410 position: relative;
411 411 }
412 412 ul.changelog-entry li span.revdate {
413 413 font-size: 1.1em;
414 414 }
415 415 ul.changelog-entry li.age {
416 416 position: absolute;
417 417 top: -25px;
418 418 right: 10px;
419 419 font-size: 1.4em;
420 420 color: #CCC;
421 421 font-weight: bold;
422 422 font-style: italic;
423 423 }
424 424 ul.changelog-entry li span.name {
425 425 font-size: 1.2em;
426 426 font-weight: bold;
427 427 }
428 428 ul.changelog-entry li.description {
429 429 margin: 10px 0 0;
430 430 font-size: 1.1em;
431 431 }
432 432 /** end of changelog **/
433 433
434 434 /** file **/
435 435 p.files {
436 436 margin: 0 0 0 20px;
437 437 font-size: 2.0em;
438 438 font-weight: bold;
439 439 }
440 440 /** end of file **/
441 441
442 442 /** changeset **/
443 443 h3.changeset {
444 444 margin: 20px 0 5px 20px;
445 445 padding: 0 0 2px;
446 446 font-size: 1.6em;
447 447 border-bottom: dotted 1px #D5E1E6;
448 448 }
449 449 p.changeset-age {
450 450 position: relative;
451 451 }
452 452 p.changeset-age span {
453 453 position: absolute;
454 454 top: -25px;
455 455 right: 10px;
456 456 font-size: 1.4em;
457 457 color: #CCC;
458 458 font-weight: bold;
459 459 font-style: italic;
460 460 }
461 461 p.description {
462 462 margin: 10px 30px 0 30px;
463 463 padding: 10px;
464 464 border: solid 1px #CCC;
465 465 font-size: 1.2em;
466 466 }
467 467 /** end of changeset **/
468 468
469 469 /** canvas **/
470 470 div#wrapper {
471 471 position: relative;
472 472 font-size: 1.1em;
473 473 }
474 474
475 475 canvas {
476 476 position: absolute;
477 477 z-index: 5;
478 478 top: -0.7em;
479 479 }
480 480
481 ul#nodebgs li.parity0 {
481 ul#graphnodes li.parity0 {
482 482 background: #F1F6F7;
483 483 }
484 484
485 ul#nodebgs li.parity1 {
485 ul#graphnodes li.parity1 {
486 486 background: #FFFFFF;
487 487 }
488 488
489 489 ul#graphnodes {
490 position: absolute;
491 z-index: 10;
492 top: 7px;
493 490 list-style: none inside none;
491 margin: 0;
492 padding: 0;
494 493 }
495 494
496 ul#nodebgs {
497 list-style: none inside none;
495 ul#graphnodes li {
496 height: 37px;
497 overflow: visible;
498 padding-top: 2px;
498 499 }
499 500
500 ul#graphnodes li, ul#nodebgs li {
501 height: 39px;
501 ul#graphnodes li .fg {
502 position: absolute;
503 z-index: 10;
502 504 }
503 505
504 506 ul#graphnodes li .info {
505 507 margin-top: 2px;
506 508 }
507 509 /** end of canvas **/
508 510
509 511 /** comparison **/
510 512 .legend {
511 513 margin-left: 20px;
512 514 padding: 1.5% 0 1.5% 0;
513 515 }
514 516
515 517 .legendinfo {
516 518 border: 1px solid #999;
517 519 font-size: 80%;
518 520 text-align: center;
519 521 padding: 0.5%;
520 522 }
521 523
522 524 .equal {
523 525 background-color: #ffffff;
524 526 }
525 527
526 528 .delete {
527 529 background-color: #faa;
528 530 color: #333;
529 531 }
530 532
531 533 .insert {
532 534 background-color: #ffa;
533 535 }
534 536
535 537 .replace {
536 538 background-color: #e8e8e8;
537 539 }
538 540
539 541 .comparison {
540 542 overflow-x: auto;
541 543 }
542 544
543 545 .comparison table td {
544 546 padding: 0px 5px;
545 547 }
546 548
547 549 .header th {
548 550 font-weight: bold;
549 551 }
550 552
551 553 .block {
552 554 border-top: 1px solid #999;
553 555 }
554 556 /** end of comparison **/
555 557
556 558 .breadcrumb a:hover {
557 559 text-decoration:underline;
558 560 }
559 561
560 562 .scroll-loading {
561 563 -webkit-animation: change_color 1s linear 0s infinite alternate;
562 564 -moz-animation: change_color 1s linear 0s infinite alternate;
563 565 -o-animation: change_color 1s linear 0s infinite alternate;
564 566 animation: change_color 1s linear 0s infinite alternate;
565 567 }
566 568
567 569 @-webkit-keyframes change_color {
568 570 from { background-color: #A0CEFF; } to { }
569 571 }
570 572 @-moz-keyframes change_color {
571 573 from { background-color: #A0CEFF; } to { }
572 574 }
573 575 @-o-keyframes change_color {
574 576 from { background-color: #A0CEFF; } to { }
575 577 }
576 578 @keyframes change_color {
577 579 from { background-color: #A0CEFF; } to { }
578 580 }
579 581
580 582 .scroll-loading-error {
581 583 background-color: #FFCCCC !important;
582 584 }
583 585
584 586 #doc {
585 587 margin: 0 30px;
586 588 }
@@ -1,1114 +1,1114 b''
1 1 #require serve
2 2
3 3 Test symbolic revision usage in links produced by hgweb pages. There are
4 4 multiple issues related to this:
5 5 - issue2296
6 6 - issue2826
7 7 - issue3594
8 8 - issue3634
9 9
10 10 Set up the repo
11 11
12 12 $ hg init test
13 13 $ cd test
14 14 $ echo 0 > foo
15 15 $ mkdir dir
16 16 $ echo 0 > dir/bar
17 17 $ hg ci -Am 'first'
18 18 adding dir/bar
19 19 adding foo
20 20 $ echo 1 >> foo
21 21 $ hg ci -m 'second'
22 22 $ echo 2 >> foo
23 23 $ hg ci -m 'third'
24 24 $ hg bookmark -r1 xyzzy
25 25
26 26 $ hg log -G --template '{rev}:{node|short} {tags} {bookmarks}\n'
27 27 @ 2:9d8c40cba617 tip
28 28 |
29 29 o 1:a7c1559b7bba xyzzy
30 30 |
31 31 o 0:43c799df6e75
32 32
33 33 $ hg serve --config web.allow_archive=zip -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
34 34 $ cat hg.pid >> $DAEMON_PIDS
35 35
36 36 $ REVLINKS='href=[^>]+(rev=|/)(43c799df6e75|0|a7c1559b7bba|1|xyzzy|9d8c40cba617|2|tip|default)'
37 37
38 38 (De)referencing symbolic revisions (paper)
39 39
40 40 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=paper' | egrep $REVLINKS
41 41 <li><a href="/graph/tip?style=paper">graph</a></li>
42 42 <li><a href="/rev/tip?style=paper">changeset</a></li>
43 43 <li><a href="/file/tip?style=paper">browse</a></li>
44 44 <a href="/archive/tip.zip">zip</a>
45 45 <a href="/shortlog/tip?revcount=30&style=paper">less</a>
46 46 <a href="/shortlog/tip?revcount=120&style=paper">more</a>
47 47 | rev 2: <a href="/shortlog/43c799df6e75?style=paper">(0)</a> <a href="/shortlog/tip?style=paper">tip</a>
48 48 <a href="/rev/9d8c40cba617?style=paper">third</a>
49 49 <a href="/rev/a7c1559b7bba?style=paper">second</a>
50 50 <a href="/rev/43c799df6e75?style=paper">first</a>
51 51 <a href="/shortlog/tip?revcount=30&style=paper">less</a>
52 52 <a href="/shortlog/tip?revcount=120&style=paper">more</a>
53 53 | rev 2: <a href="/shortlog/43c799df6e75?style=paper">(0)</a> <a href="/shortlog/tip?style=paper">tip</a>
54 54
55 55 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph?style=paper' | egrep $REVLINKS
56 56 <li><a href="/shortlog/tip?style=paper">log</a></li>
57 57 <li><a href="/rev/tip?style=paper">changeset</a></li>
58 58 <li><a href="/file/tip?style=paper">browse</a></li>
59 59 <a href="/graph/tip?revcount=30&style=paper">less</a>
60 60 <a href="/graph/tip?revcount=120&style=paper">more</a>
61 61 | rev 2: <a href="/graph/43c799df6e75?style=paper">(0)</a> <a href="/graph/tip?style=paper">tip</a>
62 62 <a href="/rev/9d8c40cba617?style=paper">third</a>
63 63 <a href="/rev/a7c1559b7bba?style=paper">second</a>
64 64 <a href="/rev/43c799df6e75?style=paper">first</a>
65 65 <a href="/graph/tip?revcount=30&style=paper">less</a>
66 66 <a href="/graph/tip?revcount=120&style=paper">more</a>
67 67 | rev 2: <a href="/graph/43c799df6e75?style=paper">(0)</a> <a href="/graph/tip?style=paper">tip</a>
68 68
69 69 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file?style=paper' | egrep $REVLINKS
70 70 <li><a href="/shortlog/tip?style=paper">log</a></li>
71 71 <li><a href="/graph/tip?style=paper">graph</a></li>
72 72 <li><a href="/rev/tip?style=paper">changeset</a></li>
73 73 <a href="/archive/tip.zip">zip</a>
74 74 directory / @ 2:<a href="/rev/9d8c40cba617?style=paper">9d8c40cba617</a>
75 75 <td class="name"><a href="/file/tip/?style=paper">[up]</a></td>
76 76 <a href="/file/tip/dir?style=paper">
77 77 <a href="/file/tip/dir/?style=paper">
78 78 <a href="/file/tip/foo?style=paper">
79 79
80 80 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'branches?style=paper' | egrep $REVLINKS
81 81 <a href="/shortlog/default?style=paper" class="open">
82 82 <a href="/shortlog/9d8c40cba617?style=paper" class="open">
83 83
84 84 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'tags?style=paper' | egrep $REVLINKS
85 85 <a href="/rev/tip?style=paper">
86 86 <a href="/rev/9d8c40cba617?style=paper">
87 87
88 88 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'bookmarks?style=paper' | egrep $REVLINKS
89 89 <a href="/rev/xyzzy?style=paper">
90 90 <a href="/rev/a7c1559b7bba?style=paper">
91 91
92 92 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=paper&rev=all()' | egrep $REVLINKS
93 93 <a href="/rev/9d8c40cba617?style=paper">third</a>
94 94 <a href="/rev/a7c1559b7bba?style=paper">second</a>
95 95 <a href="/rev/43c799df6e75?style=paper">first</a>
96 96
97 97 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'rev/xyzzy?style=paper' | egrep $REVLINKS
98 98 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
99 99 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
100 100 <li><a href="/raw-rev/xyzzy?style=paper">raw</a></li>
101 101 <li><a href="/file/xyzzy?style=paper">browse</a></li>
102 102 <a href="/archive/xyzzy.zip">zip</a>
103 103 changeset 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
104 104 <td class="author"><a href="/rev/43c799df6e75?style=paper">43c799df6e75</a> </td>
105 105 <td class="author"> <a href="/rev/9d8c40cba617?style=paper">9d8c40cba617</a></td>
106 106 <td class="files"><a href="/file/a7c1559b7bba/foo?style=paper">foo</a> </td>
107 107
108 108 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog/xyzzy?style=paper' | egrep $REVLINKS
109 109 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
110 110 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
111 111 <li><a href="/file/xyzzy?style=paper">browse</a></li>
112 112 <a href="/archive/xyzzy.zip">zip</a>
113 113 <a href="/shortlog/xyzzy?revcount=30&style=paper">less</a>
114 114 <a href="/shortlog/xyzzy?revcount=120&style=paper">more</a>
115 115 | rev 1: <a href="/shortlog/43c799df6e75?style=paper">(0)</a> <a href="/shortlog/tip?style=paper">tip</a>
116 116 <a href="/rev/a7c1559b7bba?style=paper">second</a>
117 117 <a href="/rev/43c799df6e75?style=paper">first</a>
118 118 <a href="/shortlog/xyzzy?revcount=30&style=paper">less</a>
119 119 <a href="/shortlog/xyzzy?revcount=120&style=paper">more</a>
120 120 | rev 1: <a href="/shortlog/43c799df6e75?style=paper">(0)</a> <a href="/shortlog/tip?style=paper">tip</a>
121 121
122 122 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph/xyzzy?style=paper' | egrep $REVLINKS
123 123 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
124 124 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
125 125 <li><a href="/file/xyzzy?style=paper">browse</a></li>
126 126 <a href="/graph/xyzzy?revcount=30&style=paper">less</a>
127 127 <a href="/graph/xyzzy?revcount=120&style=paper">more</a>
128 128 | rev 1: <a href="/graph/43c799df6e75?style=paper">(0)</a> <a href="/graph/tip?style=paper">tip</a>
129 129 <a href="/rev/a7c1559b7bba?style=paper">second</a>
130 130 <a href="/rev/43c799df6e75?style=paper">first</a>
131 131 <a href="/graph/xyzzy?revcount=30&style=paper">less</a>
132 132 <a href="/graph/xyzzy?revcount=120&style=paper">more</a>
133 133 | rev 1: <a href="/graph/43c799df6e75?style=paper">(0)</a> <a href="/graph/tip?style=paper">tip</a>
134 134
135 135 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy?style=paper' | egrep $REVLINKS
136 136 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
137 137 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
138 138 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
139 139 <a href="/archive/xyzzy.zip">zip</a>
140 140 directory / @ 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
141 141 <td class="name"><a href="/file/xyzzy/?style=paper">[up]</a></td>
142 142 <a href="/file/xyzzy/dir?style=paper">
143 143 <a href="/file/xyzzy/dir/?style=paper">
144 144 <a href="/file/xyzzy/foo?style=paper">
145 145
146 146 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy/foo?style=paper' | egrep $REVLINKS
147 147 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
148 148 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
149 149 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
150 150 <li><a href="/file/xyzzy/?style=paper">browse</a></li>
151 151 <li><a href="/file/tip/foo?style=paper">latest</a></li>
152 152 <li><a href="/diff/xyzzy/foo?style=paper">diff</a></li>
153 153 <li><a href="/comparison/xyzzy/foo?style=paper">comparison</a></li>
154 154 <li><a href="/annotate/xyzzy/foo?style=paper">annotate</a></li>
155 155 <li><a href="/log/xyzzy/foo?style=paper">file log</a></li>
156 156 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
157 157 view foo @ 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
158 158 <td class="author"><a href="/file/43c799df6e75/foo?style=paper">43c799df6e75</a> </td>
159 159 <td class="author"><a href="/file/9d8c40cba617/foo?style=paper">9d8c40cba617</a> </td>
160 160
161 161 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy/foo?style=paper' | egrep $REVLINKS
162 162 href="/atom-log/tip/foo" title="Atom feed for test:foo" />
163 163 href="/rss-log/tip/foo" title="RSS feed for test:foo" />
164 164 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
165 165 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
166 166 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
167 167 <li><a href="/file/xyzzy?style=paper">browse</a></li>
168 168 <li><a href="/file/xyzzy/foo?style=paper">file</a></li>
169 169 <li><a href="/diff/xyzzy/foo?style=paper">diff</a></li>
170 170 <li><a href="/comparison/xyzzy/foo?style=paper">comparison</a></li>
171 171 <li><a href="/annotate/xyzzy/foo?style=paper">annotate</a></li>
172 172 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
173 173 <a href="/atom-log/tip/foo" title="subscribe to atom feed">
174 174 log foo @ 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
175 175 <a href="/log/xyzzy/foo?revcount=30&style=paper">less</a>
176 176 <a href="/log/xyzzy/foo?revcount=120&style=paper">more</a>
177 177 | <a href="/log/43c799df6e75/foo?style=paper">(0)</a> <a href="/log/tip/foo?style=paper">tip</a> </div>
178 178 <a href="/rev/a7c1559b7bba?style=paper">second</a>
179 179 <a href="/rev/43c799df6e75?style=paper">first</a>
180 180 <a href="/log/xyzzy/foo?revcount=30&style=paper">less</a>
181 181 <a href="/log/xyzzy/foo?revcount=120&style=paper">more</a>
182 182 | <a href="/log/43c799df6e75/foo?style=paper">(0)</a> <a href="/log/tip/foo?style=paper">tip</a>
183 183
184 184 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'annotate/xyzzy/foo?style=paper' | egrep $REVLINKS
185 185 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
186 186 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
187 187 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
188 188 <li><a href="/file/xyzzy/?style=paper">browse</a></li>
189 189 <li><a href="/file/xyzzy/foo?style=paper">file</a></li>
190 190 <li><a href="/file/tip/foo?style=paper">latest</a></li>
191 191 <li><a href="/diff/xyzzy/foo?style=paper">diff</a></li>
192 192 <li><a href="/comparison/xyzzy/foo?style=paper">comparison</a></li>
193 193 <li><a href="/log/xyzzy/foo?style=paper">file log</a></li>
194 194 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
195 195 annotate foo @ 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
196 196 <td class="author"><a href="/file/43c799df6e75/foo?style=paper">43c799df6e75</a> </td>
197 197 <td class="author"><a href="/file/9d8c40cba617/foo?style=paper">9d8c40cba617</a> </td>
198 198 <a href="/annotate/43c799df6e75/foo?style=paper#l1">
199 199 <a href="/annotate/43c799df6e75/foo?style=paper#l1">
200 200 <a href="/diff/43c799df6e75/foo?style=paper">diff</a>
201 201 <a href="/rev/43c799df6e75?style=paper">changeset</a>
202 202 <a href="/annotate/a7c1559b7bba/foo?style=paper#l2">
203 203 <a href="/annotate/a7c1559b7bba/foo?style=paper#l2">
204 204 <a href="/annotate/43c799df6e75/foo?style=paper">0</a></div>
205 205 <a href="/diff/a7c1559b7bba/foo?style=paper">diff</a>
206 206 <a href="/rev/a7c1559b7bba?style=paper">changeset</a>
207 207
208 208 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'diff/xyzzy/foo?style=paper' | egrep $REVLINKS
209 209 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
210 210 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
211 211 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
212 212 <li><a href="/file/xyzzy?style=paper">browse</a></li>
213 213 <li><a href="/file/xyzzy/foo?style=paper">file</a></li>
214 214 <li><a href="/file/tip/foo?style=paper">latest</a></li>
215 215 <li><a href="/comparison/xyzzy/foo?style=paper">comparison</a></li>
216 216 <li><a href="/annotate/xyzzy/foo?style=paper">annotate</a></li>
217 217 <li><a href="/log/xyzzy/foo?style=paper">file log</a></li>
218 218 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
219 219 diff foo @ 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
220 220 <td><a href="/file/43c799df6e75/foo?style=paper">43c799df6e75</a> </td>
221 221 <td><a href="/file/9d8c40cba617/foo?style=paper">9d8c40cba617</a> </td>
222 222
223 223 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'comparison/xyzzy/foo?style=paper' | egrep $REVLINKS
224 224 <li><a href="/shortlog/xyzzy?style=paper">log</a></li>
225 225 <li><a href="/graph/xyzzy?style=paper">graph</a></li>
226 226 <li><a href="/rev/xyzzy?style=paper">changeset</a></li>
227 227 <li><a href="/file/xyzzy?style=paper">browse</a></li>
228 228 <li><a href="/file/xyzzy/foo?style=paper">file</a></li>
229 229 <li><a href="/file/tip/foo?style=paper">latest</a></li>
230 230 <li><a href="/diff/xyzzy/foo?style=paper">diff</a></li>
231 231 <li><a href="/annotate/xyzzy/foo?style=paper">annotate</a></li>
232 232 <li><a href="/log/xyzzy/foo?style=paper">file log</a></li>
233 233 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
234 234 comparison foo @ 1:<a href="/rev/a7c1559b7bba?style=paper">a7c1559b7bba</a>
235 235 <td><a href="/file/43c799df6e75/foo?style=paper">43c799df6e75</a> </td>
236 236 <td><a href="/file/9d8c40cba617/foo?style=paper">9d8c40cba617</a> </td>
237 237
238 238 (De)referencing symbolic revisions (coal)
239 239
240 240 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=coal' | egrep $REVLINKS
241 241 <li><a href="/graph/tip?style=coal">graph</a></li>
242 242 <li><a href="/rev/tip?style=coal">changeset</a></li>
243 243 <li><a href="/file/tip?style=coal">browse</a></li>
244 244 <a href="/archive/tip.zip">zip</a>
245 245 <a href="/shortlog/tip?revcount=30&style=coal">less</a>
246 246 <a href="/shortlog/tip?revcount=120&style=coal">more</a>
247 247 | rev 2: <a href="/shortlog/43c799df6e75?style=coal">(0)</a> <a href="/shortlog/tip?style=coal">tip</a>
248 248 <a href="/rev/9d8c40cba617?style=coal">third</a>
249 249 <a href="/rev/a7c1559b7bba?style=coal">second</a>
250 250 <a href="/rev/43c799df6e75?style=coal">first</a>
251 251 <a href="/shortlog/tip?revcount=30&style=coal">less</a>
252 252 <a href="/shortlog/tip?revcount=120&style=coal">more</a>
253 253 | rev 2: <a href="/shortlog/43c799df6e75?style=coal">(0)</a> <a href="/shortlog/tip?style=coal">tip</a>
254 254
255 255 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph?style=coal' | egrep $REVLINKS
256 256 <li><a href="/shortlog/tip?style=coal">log</a></li>
257 257 <li><a href="/rev/tip?style=coal">changeset</a></li>
258 258 <li><a href="/file/tip?style=coal">browse</a></li>
259 259 <a href="/graph/tip?revcount=30&style=coal">less</a>
260 260 <a href="/graph/tip?revcount=120&style=coal">more</a>
261 261 | rev 2: <a href="/graph/43c799df6e75?style=coal">(0)</a> <a href="/graph/tip?style=coal">tip</a>
262 262 <a href="/rev/9d8c40cba617?style=coal">third</a>
263 263 <a href="/rev/a7c1559b7bba?style=coal">second</a>
264 264 <a href="/rev/43c799df6e75?style=coal">first</a>
265 265 <a href="/graph/tip?revcount=30&style=coal">less</a>
266 266 <a href="/graph/tip?revcount=120&style=coal">more</a>
267 267 | rev 2: <a href="/graph/43c799df6e75?style=coal">(0)</a> <a href="/graph/tip?style=coal">tip</a>
268 268
269 269 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file?style=coal' | egrep $REVLINKS
270 270 <li><a href="/shortlog/tip?style=coal">log</a></li>
271 271 <li><a href="/graph/tip?style=coal">graph</a></li>
272 272 <li><a href="/rev/tip?style=coal">changeset</a></li>
273 273 <a href="/archive/tip.zip">zip</a>
274 274 directory / @ 2:<a href="/rev/9d8c40cba617?style=coal">9d8c40cba617</a>
275 275 <td class="name"><a href="/file/tip/?style=coal">[up]</a></td>
276 276 <a href="/file/tip/dir?style=coal">
277 277 <a href="/file/tip/dir/?style=coal">
278 278 <a href="/file/tip/foo?style=coal">
279 279
280 280 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'branches?style=coal' | egrep $REVLINKS
281 281 <a href="/shortlog/default?style=coal" class="open">
282 282 <a href="/shortlog/9d8c40cba617?style=coal" class="open">
283 283
284 284 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'tags?style=coal' | egrep $REVLINKS
285 285 <a href="/rev/tip?style=coal">
286 286 <a href="/rev/9d8c40cba617?style=coal">
287 287
288 288 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'bookmarks?style=coal' | egrep $REVLINKS
289 289 <a href="/rev/xyzzy?style=coal">
290 290 <a href="/rev/a7c1559b7bba?style=coal">
291 291
292 292 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=coal&rev=all()' | egrep $REVLINKS
293 293 <a href="/rev/9d8c40cba617?style=coal">third</a>
294 294 <a href="/rev/a7c1559b7bba?style=coal">second</a>
295 295 <a href="/rev/43c799df6e75?style=coal">first</a>
296 296
297 297 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'rev/xyzzy?style=coal' | egrep $REVLINKS
298 298 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
299 299 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
300 300 <li><a href="/raw-rev/xyzzy?style=coal">raw</a></li>
301 301 <li><a href="/file/xyzzy?style=coal">browse</a></li>
302 302 <a href="/archive/xyzzy.zip">zip</a>
303 303 changeset 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
304 304 <td class="author"><a href="/rev/43c799df6e75?style=coal">43c799df6e75</a> </td>
305 305 <td class="author"> <a href="/rev/9d8c40cba617?style=coal">9d8c40cba617</a></td>
306 306 <td class="files"><a href="/file/a7c1559b7bba/foo?style=coal">foo</a> </td>
307 307
308 308 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog/xyzzy?style=coal' | egrep $REVLINKS
309 309 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
310 310 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
311 311 <li><a href="/file/xyzzy?style=coal">browse</a></li>
312 312 <a href="/archive/xyzzy.zip">zip</a>
313 313 <a href="/shortlog/xyzzy?revcount=30&style=coal">less</a>
314 314 <a href="/shortlog/xyzzy?revcount=120&style=coal">more</a>
315 315 | rev 1: <a href="/shortlog/43c799df6e75?style=coal">(0)</a> <a href="/shortlog/tip?style=coal">tip</a>
316 316 <a href="/rev/a7c1559b7bba?style=coal">second</a>
317 317 <a href="/rev/43c799df6e75?style=coal">first</a>
318 318 <a href="/shortlog/xyzzy?revcount=30&style=coal">less</a>
319 319 <a href="/shortlog/xyzzy?revcount=120&style=coal">more</a>
320 320 | rev 1: <a href="/shortlog/43c799df6e75?style=coal">(0)</a> <a href="/shortlog/tip?style=coal">tip</a>
321 321
322 322 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph/xyzzy?style=coal' | egrep $REVLINKS
323 323 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
324 324 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
325 325 <li><a href="/file/xyzzy?style=coal">browse</a></li>
326 326 <a href="/graph/xyzzy?revcount=30&style=coal">less</a>
327 327 <a href="/graph/xyzzy?revcount=120&style=coal">more</a>
328 328 | rev 1: <a href="/graph/43c799df6e75?style=coal">(0)</a> <a href="/graph/tip?style=coal">tip</a>
329 329 <a href="/rev/a7c1559b7bba?style=coal">second</a>
330 330 <a href="/rev/43c799df6e75?style=coal">first</a>
331 331 <a href="/graph/xyzzy?revcount=30&style=coal">less</a>
332 332 <a href="/graph/xyzzy?revcount=120&style=coal">more</a>
333 333 | rev 1: <a href="/graph/43c799df6e75?style=coal">(0)</a> <a href="/graph/tip?style=coal">tip</a>
334 334
335 335 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy?style=coal' | egrep $REVLINKS
336 336 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
337 337 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
338 338 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
339 339 <a href="/archive/xyzzy.zip">zip</a>
340 340 directory / @ 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
341 341 <td class="name"><a href="/file/xyzzy/?style=coal">[up]</a></td>
342 342 <a href="/file/xyzzy/dir?style=coal">
343 343 <a href="/file/xyzzy/dir/?style=coal">
344 344 <a href="/file/xyzzy/foo?style=coal">
345 345
346 346 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy/foo?style=coal' | egrep $REVLINKS
347 347 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
348 348 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
349 349 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
350 350 <li><a href="/file/xyzzy/?style=coal">browse</a></li>
351 351 <li><a href="/file/tip/foo?style=coal">latest</a></li>
352 352 <li><a href="/diff/xyzzy/foo?style=coal">diff</a></li>
353 353 <li><a href="/comparison/xyzzy/foo?style=coal">comparison</a></li>
354 354 <li><a href="/annotate/xyzzy/foo?style=coal">annotate</a></li>
355 355 <li><a href="/log/xyzzy/foo?style=coal">file log</a></li>
356 356 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
357 357 view foo @ 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
358 358 <td class="author"><a href="/file/43c799df6e75/foo?style=coal">43c799df6e75</a> </td>
359 359 <td class="author"><a href="/file/9d8c40cba617/foo?style=coal">9d8c40cba617</a> </td>
360 360
361 361 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy/foo?style=coal' | egrep $REVLINKS
362 362 href="/atom-log/tip/foo" title="Atom feed for test:foo" />
363 363 href="/rss-log/tip/foo" title="RSS feed for test:foo" />
364 364 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
365 365 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
366 366 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
367 367 <li><a href="/file/xyzzy?style=coal">browse</a></li>
368 368 <li><a href="/file/xyzzy/foo?style=coal">file</a></li>
369 369 <li><a href="/diff/xyzzy/foo?style=coal">diff</a></li>
370 370 <li><a href="/comparison/xyzzy/foo?style=coal">comparison</a></li>
371 371 <li><a href="/annotate/xyzzy/foo?style=coal">annotate</a></li>
372 372 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
373 373 <a href="/atom-log/tip/foo" title="subscribe to atom feed">
374 374 log foo @ 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
375 375 <a href="/log/xyzzy/foo?revcount=30&style=coal">less</a>
376 376 <a href="/log/xyzzy/foo?revcount=120&style=coal">more</a>
377 377 | <a href="/log/43c799df6e75/foo?style=coal">(0)</a> <a href="/log/tip/foo?style=coal">tip</a> </div>
378 378 <a href="/rev/a7c1559b7bba?style=coal">second</a>
379 379 <a href="/rev/43c799df6e75?style=coal">first</a>
380 380 <a href="/log/xyzzy/foo?revcount=30&style=coal">less</a>
381 381 <a href="/log/xyzzy/foo?revcount=120&style=coal">more</a>
382 382 | <a href="/log/43c799df6e75/foo?style=coal">(0)</a> <a href="/log/tip/foo?style=coal">tip</a>
383 383
384 384 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'annotate/xyzzy/foo?style=coal' | egrep $REVLINKS
385 385 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
386 386 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
387 387 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
388 388 <li><a href="/file/xyzzy/?style=coal">browse</a></li>
389 389 <li><a href="/file/xyzzy/foo?style=coal">file</a></li>
390 390 <li><a href="/file/tip/foo?style=coal">latest</a></li>
391 391 <li><a href="/diff/xyzzy/foo?style=coal">diff</a></li>
392 392 <li><a href="/comparison/xyzzy/foo?style=coal">comparison</a></li>
393 393 <li><a href="/log/xyzzy/foo?style=coal">file log</a></li>
394 394 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
395 395 annotate foo @ 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
396 396 <td class="author"><a href="/file/43c799df6e75/foo?style=coal">43c799df6e75</a> </td>
397 397 <td class="author"><a href="/file/9d8c40cba617/foo?style=coal">9d8c40cba617</a> </td>
398 398 <a href="/annotate/43c799df6e75/foo?style=coal#l1">
399 399 <a href="/annotate/43c799df6e75/foo?style=coal#l1">
400 400 <a href="/diff/43c799df6e75/foo?style=coal">diff</a>
401 401 <a href="/rev/43c799df6e75?style=coal">changeset</a>
402 402 <a href="/annotate/a7c1559b7bba/foo?style=coal#l2">
403 403 <a href="/annotate/a7c1559b7bba/foo?style=coal#l2">
404 404 <a href="/annotate/43c799df6e75/foo?style=coal">0</a></div>
405 405 <a href="/diff/a7c1559b7bba/foo?style=coal">diff</a>
406 406 <a href="/rev/a7c1559b7bba?style=coal">changeset</a>
407 407
408 408 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'diff/xyzzy/foo?style=coal' | egrep $REVLINKS
409 409 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
410 410 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
411 411 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
412 412 <li><a href="/file/xyzzy?style=coal">browse</a></li>
413 413 <li><a href="/file/xyzzy/foo?style=coal">file</a></li>
414 414 <li><a href="/file/tip/foo?style=coal">latest</a></li>
415 415 <li><a href="/comparison/xyzzy/foo?style=coal">comparison</a></li>
416 416 <li><a href="/annotate/xyzzy/foo?style=coal">annotate</a></li>
417 417 <li><a href="/log/xyzzy/foo?style=coal">file log</a></li>
418 418 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
419 419 diff foo @ 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
420 420 <td><a href="/file/43c799df6e75/foo?style=coal">43c799df6e75</a> </td>
421 421 <td><a href="/file/9d8c40cba617/foo?style=coal">9d8c40cba617</a> </td>
422 422
423 423 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'comparison/xyzzy/foo?style=coal' | egrep $REVLINKS
424 424 <li><a href="/shortlog/xyzzy?style=coal">log</a></li>
425 425 <li><a href="/graph/xyzzy?style=coal">graph</a></li>
426 426 <li><a href="/rev/xyzzy?style=coal">changeset</a></li>
427 427 <li><a href="/file/xyzzy?style=coal">browse</a></li>
428 428 <li><a href="/file/xyzzy/foo?style=coal">file</a></li>
429 429 <li><a href="/file/tip/foo?style=coal">latest</a></li>
430 430 <li><a href="/diff/xyzzy/foo?style=coal">diff</a></li>
431 431 <li><a href="/annotate/xyzzy/foo?style=coal">annotate</a></li>
432 432 <li><a href="/log/xyzzy/foo?style=coal">file log</a></li>
433 433 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
434 434 comparison foo @ 1:<a href="/rev/a7c1559b7bba?style=coal">a7c1559b7bba</a>
435 435 <td><a href="/file/43c799df6e75/foo?style=coal">43c799df6e75</a> </td>
436 436 <td><a href="/file/9d8c40cba617/foo?style=coal">9d8c40cba617</a> </td>
437 437
438 438 (De)referencing symbolic revisions (gitweb)
439 439
440 440 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'summary?style=gitweb' | egrep $REVLINKS
441 441 <a href="/file?style=gitweb">files</a> | <a href="/archive/tip.zip">zip</a> |
442 442 <a class="list" href="/rev/9d8c40cba617?style=gitweb">
443 443 <a href="/rev/9d8c40cba617?style=gitweb">changeset</a> |
444 444 <a href="/file/9d8c40cba617?style=gitweb">files</a>
445 445 <a class="list" href="/rev/a7c1559b7bba?style=gitweb">
446 446 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a> |
447 447 <a href="/file/a7c1559b7bba?style=gitweb">files</a>
448 448 <a class="list" href="/rev/43c799df6e75?style=gitweb">
449 449 <a href="/rev/43c799df6e75?style=gitweb">changeset</a> |
450 450 <a href="/file/43c799df6e75?style=gitweb">files</a>
451 451 <td><a class="list" href="/rev/xyzzy?style=gitweb"><b>xyzzy</b></a></td>
452 452 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a> |
453 453 <a href="/log/a7c1559b7bba?style=gitweb">changelog</a> |
454 454 <a href="/file/a7c1559b7bba?style=gitweb">files</a>
455 455 <td class="open"><a class="list" href="/shortlog/default?style=gitweb"><b>default</b></a></td>
456 456 <a href="/changeset/9d8c40cba617?style=gitweb">changeset</a> |
457 457 <a href="/log/9d8c40cba617?style=gitweb">changelog</a> |
458 458 <a href="/file/9d8c40cba617?style=gitweb">files</a>
459 459
460 460 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=gitweb' | egrep $REVLINKS
461 461 <a href="/log/tip?style=gitweb">changelog</a> |
462 462 <a href="/graph/tip?style=gitweb">graph</a> |
463 463 <a href="/file/tip?style=gitweb">files</a> | <a href="/archive/tip.zip">zip</a> |
464 464 <br/><a href="/shortlog/43c799df6e75?style=gitweb">(0)</a> <a href="/shortlog/tip?style=gitweb">tip</a> <br/>
465 465 <a class="list" href="/rev/9d8c40cba617?style=gitweb">
466 466 <a href="/rev/9d8c40cba617?style=gitweb">changeset</a> |
467 467 <a href="/file/9d8c40cba617?style=gitweb">files</a>
468 468 <a class="list" href="/rev/a7c1559b7bba?style=gitweb">
469 469 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a> |
470 470 <a href="/file/a7c1559b7bba?style=gitweb">files</a>
471 471 <a class="list" href="/rev/43c799df6e75?style=gitweb">
472 472 <a href="/rev/43c799df6e75?style=gitweb">changeset</a> |
473 473 <a href="/file/43c799df6e75?style=gitweb">files</a>
474 474 <a href="/shortlog/43c799df6e75?style=gitweb">(0)</a> <a href="/shortlog/tip?style=gitweb">tip</a>
475 475
476 476 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log?style=gitweb' | egrep $REVLINKS
477 477 <a href="/shortlog/tip?style=gitweb">shortlog</a> |
478 478 <a href="/graph/tip?style=gitweb">graph</a> |
479 479 <a href="/file/tip?style=gitweb">files</a> | <a href="/archive/tip.zip">zip</a> |
480 480 <a href="/log/43c799df6e75?style=gitweb">(0)</a> <a href="/log/tip?style=gitweb">tip</a> <br/>
481 481 <a class="title" href="/rev/9d8c40cba617?style=gitweb">
482 482 <a href="/rev/9d8c40cba617?style=gitweb">changeset</a><br/>
483 483 <a class="title" href="/rev/a7c1559b7bba?style=gitweb">
484 484 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a><br/>
485 485 <a class="title" href="/rev/43c799df6e75?style=gitweb">
486 486 <a href="/rev/43c799df6e75?style=gitweb">changeset</a><br/>
487 487 <a href="/log/43c799df6e75?style=gitweb">(0)</a> <a href="/log/tip?style=gitweb">tip</a> <br/>
488 488
489 489 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph?style=gitweb' | egrep $REVLINKS
490 490 <a href="/shortlog/tip?style=gitweb">shortlog</a> |
491 491 <a href="/log/tip?style=gitweb">changelog</a> |
492 492 <a href="/file/tip?style=gitweb">files</a> |
493 493 <a href="/graph/tip?revcount=30&style=gitweb">less</a>
494 494 <a href="/graph/tip?revcount=120&style=gitweb">more</a>
495 495 | <a href="/graph/43c799df6e75?style=gitweb">(0)</a> <a href="/graph/tip?style=gitweb">tip</a>
496 496 <a class="list" href="/rev/9d8c40cba617?style=gitweb"><b>third</b></a>
497 497 <a class="list" href="/rev/a7c1559b7bba?style=gitweb"><b>second</b></a>
498 498 <a class="list" href="/rev/43c799df6e75?style=gitweb"><b>first</b></a>
499 499 <a href="/graph/tip?revcount=30&style=gitweb">less</a>
500 500 <a href="/graph/tip?revcount=120&style=gitweb">more</a>
501 501 | <a href="/graph/43c799df6e75?style=gitweb">(0)</a> <a href="/graph/tip?style=gitweb">tip</a>
502 502
503 503 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'tags?style=gitweb' | egrep $REVLINKS
504 504 <td><a class="list" href="/rev/tip?style=gitweb"><b>tip</b></a></td>
505 505 <a href="/rev/9d8c40cba617?style=gitweb">changeset</a> |
506 506 <a href="/log/9d8c40cba617?style=gitweb">changelog</a> |
507 507 <a href="/file/9d8c40cba617?style=gitweb">files</a>
508 508
509 509 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'bookmarks?style=gitweb' | egrep $REVLINKS
510 510 <td><a class="list" href="/rev/xyzzy?style=gitweb"><b>xyzzy</b></a></td>
511 511 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a> |
512 512 <a href="/log/a7c1559b7bba?style=gitweb">changelog</a> |
513 513 <a href="/file/a7c1559b7bba?style=gitweb">files</a>
514 514
515 515 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'branches?style=gitweb' | egrep $REVLINKS
516 516 <td class="open"><a class="list" href="/shortlog/default?style=gitweb"><b>default</b></a></td>
517 517 <a href="/changeset/9d8c40cba617?style=gitweb">changeset</a> |
518 518 <a href="/log/9d8c40cba617?style=gitweb">changelog</a> |
519 519 <a href="/file/9d8c40cba617?style=gitweb">files</a>
520 520
521 521 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file?style=gitweb' | egrep $REVLINKS
522 522 <a href="/rev/tip?style=gitweb">changeset</a> | <a href="/archive/tip.zip">zip</a> |
523 523 <td><a href="/file/tip/?style=gitweb">[up]</a></td>
524 524 <a href="/file/tip/dir?style=gitweb">dir</a>
525 525 <a href="/file/tip/dir/?style=gitweb"></a>
526 526 <a href="/file/tip/dir?style=gitweb">files</a>
527 527 <a class="list" href="/file/tip/foo?style=gitweb">foo</a>
528 528 <a href="/file/tip/foo?style=gitweb">file</a> |
529 529 <a href="/log/tip/foo?style=gitweb">revisions</a> |
530 530 <a href="/annotate/tip/foo?style=gitweb">annotate</a>
531 531
532 532 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=gitweb&rev=all()' | egrep $REVLINKS
533 533 <a href="/file?style=gitweb">files</a> | <a href="/archive/tip.zip">zip</a>
534 534 <a class="title" href="/rev/9d8c40cba617?style=gitweb">
535 535 <a href="/rev/9d8c40cba617?style=gitweb">changeset</a><br/>
536 536 <a class="title" href="/rev/a7c1559b7bba?style=gitweb">
537 537 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a><br/>
538 538 <a class="title" href="/rev/43c799df6e75?style=gitweb">
539 539 <a href="/rev/43c799df6e75?style=gitweb">changeset</a><br/>
540 540
541 541 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'rev/xyzzy?style=gitweb' | egrep $REVLINKS
542 542 <a href="/shortlog/xyzzy?style=gitweb">shortlog</a> |
543 543 <a href="/log/xyzzy?style=gitweb">changelog</a> |
544 544 <a href="/graph/xyzzy?style=gitweb">graph</a> |
545 545 <a href="/file/xyzzy?style=gitweb">files</a> |
546 546 <a href="/raw-rev/xyzzy">raw</a> | <a href="/archive/xyzzy.zip">zip</a> |
547 547 <a class="title" href="/raw-rev/a7c1559b7bba">
548 548 <td style="font-family:monospace"><a class="list" href="/rev/a7c1559b7bba?style=gitweb">a7c1559b7bba</a></td>
549 549 <a class="list" href="/rev/43c799df6e75?style=gitweb">43c799df6e75</a>
550 550 <a class="list" href="/rev/9d8c40cba617?style=gitweb">9d8c40cba617</a>
551 551 <td><a class="list" href="/diff/a7c1559b7bba/foo?style=gitweb">foo</a></td>
552 552 <a href="/file/a7c1559b7bba/foo?style=gitweb">file</a> |
553 553 <a href="/annotate/a7c1559b7bba/foo?style=gitweb">annotate</a> |
554 554 <a href="/diff/a7c1559b7bba/foo?style=gitweb">diff</a> |
555 555 <a href="/comparison/a7c1559b7bba/foo?style=gitweb">comparison</a> |
556 556 <a href="/log/a7c1559b7bba/foo?style=gitweb">revisions</a>
557 557
558 558 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog/xyzzy?style=gitweb' | egrep $REVLINKS
559 559 <a href="/log/xyzzy?style=gitweb">changelog</a> |
560 560 <a href="/graph/xyzzy?style=gitweb">graph</a> |
561 561 <a href="/file/xyzzy?style=gitweb">files</a> | <a href="/archive/xyzzy.zip">zip</a> |
562 562 <br/><a href="/shortlog/43c799df6e75?style=gitweb">(0)</a> <a href="/shortlog/tip?style=gitweb">tip</a> <br/>
563 563 <a class="list" href="/rev/a7c1559b7bba?style=gitweb">
564 564 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a> |
565 565 <a href="/file/a7c1559b7bba?style=gitweb">files</a>
566 566 <a class="list" href="/rev/43c799df6e75?style=gitweb">
567 567 <a href="/rev/43c799df6e75?style=gitweb">changeset</a> |
568 568 <a href="/file/43c799df6e75?style=gitweb">files</a>
569 569 <a href="/shortlog/43c799df6e75?style=gitweb">(0)</a> <a href="/shortlog/tip?style=gitweb">tip</a>
570 570
571 571 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy?style=gitweb' | egrep $REVLINKS
572 572 <a href="/shortlog/xyzzy?style=gitweb">shortlog</a> |
573 573 <a href="/graph/xyzzy?style=gitweb">graph</a> |
574 574 <a href="/file/xyzzy?style=gitweb">files</a> | <a href="/archive/xyzzy.zip">zip</a> |
575 575 <a href="/log/43c799df6e75?style=gitweb">(0)</a> <a href="/log/tip?style=gitweb">tip</a> <br/>
576 576 <a class="title" href="/rev/a7c1559b7bba?style=gitweb">
577 577 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a><br/>
578 578 <a class="title" href="/rev/43c799df6e75?style=gitweb">
579 579 <a href="/rev/43c799df6e75?style=gitweb">changeset</a><br/>
580 580 <a href="/log/43c799df6e75?style=gitweb">(0)</a> <a href="/log/tip?style=gitweb">tip</a> <br/>
581 581
582 582 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph/xyzzy?style=gitweb' | egrep $REVLINKS
583 583 <a href="/shortlog/xyzzy?style=gitweb">shortlog</a> |
584 584 <a href="/log/xyzzy?style=gitweb">changelog</a> |
585 585 <a href="/file/xyzzy?style=gitweb">files</a> |
586 586 <a href="/graph/xyzzy?revcount=30&style=gitweb">less</a>
587 587 <a href="/graph/xyzzy?revcount=120&style=gitweb">more</a>
588 588 | <a href="/graph/43c799df6e75?style=gitweb">(0)</a> <a href="/graph/tip?style=gitweb">tip</a>
589 589 <a class="list" href="/rev/a7c1559b7bba?style=gitweb"><b>second</b></a>
590 590 <a class="list" href="/rev/43c799df6e75?style=gitweb"><b>first</b></a>
591 591 <a href="/graph/xyzzy?revcount=30&style=gitweb">less</a>
592 592 <a href="/graph/xyzzy?revcount=120&style=gitweb">more</a>
593 593 | <a href="/graph/43c799df6e75?style=gitweb">(0)</a> <a href="/graph/tip?style=gitweb">tip</a>
594 594
595 595 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy?style=gitweb' | egrep $REVLINKS
596 596 <a href="/rev/xyzzy?style=gitweb">changeset</a> | <a href="/archive/xyzzy.zip">zip</a> |
597 597 <td><a href="/file/xyzzy/?style=gitweb">[up]</a></td>
598 598 <a href="/file/xyzzy/dir?style=gitweb">dir</a>
599 599 <a href="/file/xyzzy/dir/?style=gitweb"></a>
600 600 <a href="/file/xyzzy/dir?style=gitweb">files</a>
601 601 <a class="list" href="/file/xyzzy/foo?style=gitweb">foo</a>
602 602 <a href="/file/xyzzy/foo?style=gitweb">file</a> |
603 603 <a href="/log/xyzzy/foo?style=gitweb">revisions</a> |
604 604 <a href="/annotate/xyzzy/foo?style=gitweb">annotate</a>
605 605
606 606 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy/foo?style=gitweb' | egrep $REVLINKS
607 607 <a href="/file/xyzzy/?style=gitweb">files</a> |
608 608 <a href="/rev/xyzzy?style=gitweb">changeset</a> |
609 609 <a href="/file/tip/foo?style=gitweb">latest</a> |
610 610 <a href="/log/xyzzy/foo?style=gitweb">revisions</a> |
611 611 <a href="/annotate/xyzzy/foo?style=gitweb">annotate</a> |
612 612 <a href="/diff/xyzzy/foo?style=gitweb">diff</a> |
613 613 <a href="/comparison/xyzzy/foo?style=gitweb">comparison</a> |
614 614 <a href="/raw-file/xyzzy/foo">raw</a> |
615 615 <td style="font-family:monospace"><a class="list" href="/rev/a7c1559b7bba?style=gitweb">a7c1559b7bba</a></td>
616 616 <a class="list" href="/file/43c799df6e75/foo?style=gitweb">
617 617 <a class="list" href="/file/9d8c40cba617/foo?style=gitweb">9d8c40cba617</a></td>
618 618
619 619 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy/foo?style=gitweb' | egrep $REVLINKS
620 620 <a href="/file/xyzzy/foo?style=gitweb">file</a> |
621 621 <a href="/annotate/xyzzy/foo?style=gitweb">annotate</a> |
622 622 <a href="/diff/xyzzy/foo?style=gitweb">diff</a> |
623 623 <a href="/comparison/xyzzy/foo?style=gitweb">comparison</a> |
624 624 <a href="/rss-log/tip/foo">rss</a> |
625 625 <a href="/log/43c799df6e75/foo?style=gitweb">(0)</a> <a href="/log/tip/foo?style=gitweb">tip</a>
626 626 <a class="list" href="/rev/a7c1559b7bba?style=gitweb">
627 627 <a href="/file/a7c1559b7bba/foo?style=gitweb">file</a> |
628 628 <a href="/diff/a7c1559b7bba/foo?style=gitweb">diff</a> |
629 629 <a href="/annotate/a7c1559b7bba/foo?style=gitweb">annotate</a>
630 630 <a class="list" href="/rev/43c799df6e75?style=gitweb">
631 631 <a href="/file/43c799df6e75/foo?style=gitweb">file</a> |
632 632 <a href="/diff/43c799df6e75/foo?style=gitweb">diff</a> |
633 633 <a href="/annotate/43c799df6e75/foo?style=gitweb">annotate</a>
634 634 <a href="/log/xyzzy/foo?revcount=30&style=gitweb">less</a>
635 635 <a href="/log/xyzzy/foo?revcount=120&style=gitweb">more</a>
636 636 <a href="/log/43c799df6e75/foo?style=gitweb">(0)</a> <a href="/log/tip/foo?style=gitweb">tip</a>
637 637
638 638 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'annotate/xyzzy/foo?style=gitweb' | egrep $REVLINKS
639 639 <a href="/file/xyzzy/?style=gitweb">files</a> |
640 640 <a href="/rev/xyzzy?style=gitweb">changeset</a> |
641 641 <a href="/file/xyzzy/foo?style=gitweb">file</a> |
642 642 <a href="/file/tip/foo?style=gitweb">latest</a> |
643 643 <a href="/log/xyzzy/foo?style=gitweb">revisions</a> |
644 644 <a href="/diff/xyzzy/foo?style=gitweb">diff</a> |
645 645 <a href="/comparison/xyzzy/foo?style=gitweb">comparison</a> |
646 646 <a href="/raw-file/xyzzy/foo">raw</a> |
647 647 <td style="font-family:monospace"><a class="list" href="/rev/a7c1559b7bba?style=gitweb">a7c1559b7bba</a></td>
648 648 <a class="list" href="/annotate/43c799df6e75/foo?style=gitweb">
649 649 <a class="list" href="/annotate/9d8c40cba617/foo?style=gitweb">9d8c40cba617</a></td>
650 650 <a href="/annotate/43c799df6e75/foo?style=gitweb#l1">
651 651 <a href="/annotate/43c799df6e75/foo?style=gitweb#l1">
652 652 <a href="/diff/43c799df6e75/foo?style=gitweb">diff</a>
653 653 <a href="/rev/43c799df6e75?style=gitweb">changeset</a>
654 654 <a href="/annotate/a7c1559b7bba/foo?style=gitweb#l2">
655 655 <a href="/annotate/a7c1559b7bba/foo?style=gitweb#l2">
656 656 <a href="/annotate/43c799df6e75/foo?style=gitweb">0</a></div>
657 657 <a href="/diff/a7c1559b7bba/foo?style=gitweb">diff</a>
658 658 <a href="/rev/a7c1559b7bba?style=gitweb">changeset</a>
659 659
660 660 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'diff/xyzzy/foo?style=gitweb' | egrep $REVLINKS
661 661 <a href="/file/xyzzy?style=gitweb">files</a> |
662 662 <a href="/rev/xyzzy?style=gitweb">changeset</a> |
663 663 <a href="/file/xyzzy/foo?style=gitweb">file</a> |
664 664 <a href="/file/tip/foo?style=gitweb">latest</a> |
665 665 <a href="/log/xyzzy/foo?style=gitweb">revisions</a> |
666 666 <a href="/annotate/xyzzy/foo?style=gitweb">annotate</a> |
667 667 <a href="/comparison/xyzzy/foo?style=gitweb">comparison</a> |
668 668 <a href="/raw-diff/xyzzy/foo">raw</a> |
669 669 <td style="font-family:monospace"><a class="list" href="/rev/a7c1559b7bba?style=gitweb">a7c1559b7bba</a></td>
670 670 <a class="list" href="/diff/43c799df6e75/foo?style=gitweb">
671 671 <a class="list" href="/diff/9d8c40cba617/foo?style=gitweb">9d8c40cba617</a>
672 672
673 673 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'comparison/xyzzy/foo?style=gitweb' | egrep $REVLINKS
674 674 <a href="/file/xyzzy?style=gitweb">files</a> |
675 675 <a href="/rev/xyzzy?style=gitweb">changeset</a> |
676 676 <a href="/file/xyzzy/foo?style=gitweb">file</a> |
677 677 <a href="/file/tip/foo?style=gitweb">latest</a> |
678 678 <a href="/log/xyzzy/foo?style=gitweb">revisions</a> |
679 679 <a href="/annotate/xyzzy/foo?style=gitweb">annotate</a> |
680 680 <a href="/diff/xyzzy/foo?style=gitweb">diff</a> |
681 681 <a href="/raw-diff/xyzzy/foo">raw</a> |
682 682 <td style="font-family:monospace"><a class="list" href="/rev/a7c1559b7bba?style=gitweb">a7c1559b7bba</a></td>
683 683 <a class="list" href="/comparison/43c799df6e75/foo?style=gitweb">
684 684 <a class="list" href="/comparison/9d8c40cba617/foo?style=gitweb">9d8c40cba617</a>
685 685
686 686 (De)referencing symbolic revisions (monoblue)
687 687
688 688 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'summary?style=monoblue' | egrep $REVLINKS
689 689 <li><a href="/archive/tip.zip">zip</a></li>
690 690 <a href="/rev/9d8c40cba617?style=monoblue">
691 691 <a href="/rev/9d8c40cba617?style=monoblue">changeset</a> |
692 692 <a href="/file/9d8c40cba617?style=monoblue">files</a>
693 693 <a href="/rev/a7c1559b7bba?style=monoblue">
694 694 <a href="/rev/a7c1559b7bba?style=monoblue">changeset</a> |
695 695 <a href="/file/a7c1559b7bba?style=monoblue">files</a>
696 696 <a href="/rev/43c799df6e75?style=monoblue">
697 697 <a href="/rev/43c799df6e75?style=monoblue">changeset</a> |
698 698 <a href="/file/43c799df6e75?style=monoblue">files</a>
699 699 <td><a href="/rev/xyzzy?style=monoblue">xyzzy</a></td>
700 700 <a href="/rev/a7c1559b7bba?style=monoblue">changeset</a> |
701 701 <a href="/log/a7c1559b7bba?style=monoblue">changelog</a> |
702 702 <a href="/file/a7c1559b7bba?style=monoblue">files</a>
703 703 <td class="open"><a href="/shortlog/default?style=monoblue">default</a></td>
704 704 <a href="/rev/9d8c40cba617?style=monoblue">changeset</a> |
705 705 <a href="/log/9d8c40cba617?style=monoblue">changelog</a> |
706 706 <a href="/file/9d8c40cba617?style=monoblue">files</a>
707 707
708 708 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=monoblue' | egrep $REVLINKS
709 709 <li><a href="/graph/tip?style=monoblue">graph</a></li>
710 710 <li><a href="/file/tip?style=monoblue">files</a></li>
711 711 <li><a href="/archive/tip.zip">zip</a></li>
712 712 <a href="/rev/9d8c40cba617?style=monoblue">
713 713 <a href="/rev/9d8c40cba617?style=monoblue">changeset</a> |
714 714 <a href="/file/9d8c40cba617?style=monoblue">files</a>
715 715 <a href="/rev/a7c1559b7bba?style=monoblue">
716 716 <a href="/rev/a7c1559b7bba?style=monoblue">changeset</a> |
717 717 <a href="/file/a7c1559b7bba?style=monoblue">files</a>
718 718 <a href="/rev/43c799df6e75?style=monoblue">
719 719 <a href="/rev/43c799df6e75?style=monoblue">changeset</a> |
720 720 <a href="/file/43c799df6e75?style=monoblue">files</a>
721 721 <a href="/shortlog/43c799df6e75?style=monoblue">(0)</a> <a href="/shortlog/tip?style=monoblue">tip</a>
722 722
723 723 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log?style=monoblue' | egrep $REVLINKS
724 724 <li><a href="/graph/tip?style=monoblue">graph</a></li>
725 725 <li><a href="/file/tip?style=monoblue">files</a></li>
726 726 <li><a href="/archive/tip.zip">zip</a></li>
727 727 <a class="title" href="/rev/9d8c40cba617?style=monoblue">
728 728 <a class="title" href="/rev/a7c1559b7bba?style=monoblue">
729 729 <a class="title" href="/rev/43c799df6e75?style=monoblue">
730 730 <a href="/log/43c799df6e75?style=monoblue">(0)</a> <a href="/log/tip?style=monoblue">tip</a>
731 731
732 732 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph?style=monoblue' | egrep $REVLINKS
733 733 <li><a href="/file/tip?style=monoblue">files</a></li>
734 <a href="/rev/9d8c40cba617?style=monoblue">third</a>
735 <a href="/rev/a7c1559b7bba?style=monoblue">second</a>
736 <a href="/rev/43c799df6e75?style=monoblue">first</a>
734 <a href="/rev/9d8c40cba617?style=monoblue">third</a>
735 <a href="/rev/a7c1559b7bba?style=monoblue">second</a>
736 <a href="/rev/43c799df6e75?style=monoblue">first</a>
737 737 <a href="/graph/tip?revcount=30&style=monoblue">less</a>
738 738 <a href="/graph/tip?revcount=120&style=monoblue">more</a>
739 739 | <a href="/graph/43c799df6e75?style=monoblue">(0)</a> <a href="/graph/tip?style=monoblue">tip</a>
740 740
741 741 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'tags?style=monoblue' | egrep $REVLINKS
742 742 <td><a href="/rev/tip?style=monoblue">tip</a></td>
743 743 <a href="/rev/9d8c40cba617?style=monoblue">changeset</a> |
744 744 <a href="/log/9d8c40cba617?style=monoblue">changelog</a> |
745 745 <a href="/file/9d8c40cba617?style=monoblue">files</a>
746 746
747 747 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'bookmarks?style=monoblue' | egrep $REVLINKS
748 748 <td><a href="/rev/xyzzy?style=monoblue">xyzzy</a></td>
749 749 <a href="/rev/a7c1559b7bba?style=monoblue">changeset</a> |
750 750 <a href="/log/a7c1559b7bba?style=monoblue">changelog</a> |
751 751 <a href="/file/a7c1559b7bba?style=monoblue">files</a>
752 752
753 753 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'branches?style=monoblue' | egrep $REVLINKS
754 754 <td class="open"><a href="/shortlog/default?style=monoblue">default</a></td>
755 755 <a href="/rev/9d8c40cba617?style=monoblue">changeset</a> |
756 756 <a href="/log/9d8c40cba617?style=monoblue">changelog</a> |
757 757 <a href="/file/9d8c40cba617?style=monoblue">files</a>
758 758
759 759 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file?style=monoblue' | egrep $REVLINKS
760 760 <li><a href="/graph/tip?style=monoblue">graph</a></li>
761 761 <li><a href="/rev/tip?style=monoblue">changeset</a></li>
762 762 <li><a href="/archive/tip.zip">zip</a></li>
763 763 <td><a href="/file/tip/?style=monoblue">[up]</a></td>
764 764 <a href="/file/tip/dir?style=monoblue">dir</a>
765 765 <a href="/file/tip/dir/?style=monoblue"></a>
766 766 <td><a href="/file/tip/dir?style=monoblue">files</a></td>
767 767 <td><a href="/file/tip/foo?style=monoblue">foo</a></td>
768 768 <a href="/file/tip/foo?style=monoblue">file</a> |
769 769 <a href="/log/tip/foo?style=monoblue">revisions</a> |
770 770 <a href="/annotate/tip/foo?style=monoblue">annotate</a>
771 771
772 772 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=monoblue&rev=all()' | egrep $REVLINKS
773 773 <li><a href="/archive/tip.zip">zip</a></li>
774 774 <a class="title" href="/rev/9d8c40cba617?style=monoblue">
775 775 <a class="title" href="/rev/a7c1559b7bba?style=monoblue">
776 776 <a class="title" href="/rev/43c799df6e75?style=monoblue">
777 777
778 778 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'rev/xyzzy?style=monoblue' | egrep $REVLINKS
779 779 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
780 780 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
781 781 <li><a href="/raw-rev/xyzzy">raw</a></li>
782 782 <li><a href="/archive/xyzzy.zip">zip</a></li>
783 783 <a href="/raw-rev/a7c1559b7bba">
784 784 <dd><a href="/rev/a7c1559b7bba?style=monoblue">a7c1559b7bba</a></dd>
785 785 <dd><a href="/rev/43c799df6e75?style=monoblue">43c799df6e75</a></dd>
786 786 <dd><a href="/rev/9d8c40cba617?style=monoblue">9d8c40cba617</a></dd>
787 787 <td><a href="/diff/a7c1559b7bba/foo?style=monoblue">foo</a></td>
788 788 <a href="/file/a7c1559b7bba/foo?style=monoblue">file</a> |
789 789 <a href="/annotate/a7c1559b7bba/foo?style=monoblue">annotate</a> |
790 790 <a href="/diff/a7c1559b7bba/foo?style=monoblue">diff</a> |
791 791 <a href="/comparison/a7c1559b7bba/foo?style=monoblue">comparison</a> |
792 792 <a href="/log/a7c1559b7bba/foo?style=monoblue">revisions</a>
793 793
794 794 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog/xyzzy?style=monoblue' | egrep $REVLINKS
795 795 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
796 796 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
797 797 <li><a href="/archive/xyzzy.zip">zip</a></li>
798 798 <a href="/rev/a7c1559b7bba?style=monoblue">
799 799 <a href="/rev/a7c1559b7bba?style=monoblue">changeset</a> |
800 800 <a href="/file/a7c1559b7bba?style=monoblue">files</a>
801 801 <a href="/rev/43c799df6e75?style=monoblue">
802 802 <a href="/rev/43c799df6e75?style=monoblue">changeset</a> |
803 803 <a href="/file/43c799df6e75?style=monoblue">files</a>
804 804 <a href="/shortlog/43c799df6e75?style=monoblue">(0)</a> <a href="/shortlog/tip?style=monoblue">tip</a>
805 805
806 806 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy?style=monoblue' | egrep $REVLINKS
807 807 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
808 808 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
809 809 <li><a href="/archive/xyzzy.zip">zip</a></li>
810 810 <a class="title" href="/rev/a7c1559b7bba?style=monoblue">
811 811 <a class="title" href="/rev/43c799df6e75?style=monoblue">
812 812 <a href="/log/43c799df6e75?style=monoblue">(0)</a> <a href="/log/tip?style=monoblue">tip</a>
813 813
814 814 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph/xyzzy?style=monoblue' | egrep $REVLINKS
815 815 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
816 <a href="/rev/a7c1559b7bba?style=monoblue">second</a>
817 <a href="/rev/43c799df6e75?style=monoblue">first</a>
816 <a href="/rev/a7c1559b7bba?style=monoblue">second</a>
817 <a href="/rev/43c799df6e75?style=monoblue">first</a>
818 818 <a href="/graph/xyzzy?revcount=30&style=monoblue">less</a>
819 819 <a href="/graph/xyzzy?revcount=120&style=monoblue">more</a>
820 820 | <a href="/graph/43c799df6e75?style=monoblue">(0)</a> <a href="/graph/tip?style=monoblue">tip</a>
821 821
822 822 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy?style=monoblue' | egrep $REVLINKS
823 823 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
824 824 <li><a href="/rev/xyzzy?style=monoblue">changeset</a></li>
825 825 <li><a href="/archive/xyzzy.zip">zip</a></li>
826 826 <td><a href="/file/xyzzy/?style=monoblue">[up]</a></td>
827 827 <a href="/file/xyzzy/dir?style=monoblue">dir</a>
828 828 <a href="/file/xyzzy/dir/?style=monoblue"></a>
829 829 <td><a href="/file/xyzzy/dir?style=monoblue">files</a></td>
830 830 <td><a href="/file/xyzzy/foo?style=monoblue">foo</a></td>
831 831 <a href="/file/xyzzy/foo?style=monoblue">file</a> |
832 832 <a href="/log/xyzzy/foo?style=monoblue">revisions</a> |
833 833 <a href="/annotate/xyzzy/foo?style=monoblue">annotate</a>
834 834
835 835 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy/foo?style=monoblue' | egrep $REVLINKS
836 836 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
837 837 <li><a href="/file/xyzzy/?style=monoblue">files</a></li>
838 838 <li><a href="/file/tip/foo?style=monoblue">latest</a></li>
839 839 <li><a href="/log/xyzzy/foo?style=monoblue">revisions</a></li>
840 840 <li><a href="/annotate/xyzzy/foo?style=monoblue">annotate</a></li>
841 841 <li><a href="/diff/xyzzy/foo?style=monoblue">diff</a></li>
842 842 <li><a href="/comparison/xyzzy/foo?style=monoblue">comparison</a></li>
843 843 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
844 844 <dd><a class="list" href="/rev/a7c1559b7bba?style=monoblue">a7c1559b7bba</a></dd>
845 845 <a href="/file/43c799df6e75/foo?style=monoblue">
846 846 <a href="/file/9d8c40cba617/foo?style=monoblue">9d8c40cba617</a>
847 847
848 848 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy/foo?style=monoblue' | egrep $REVLINKS
849 849 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
850 850 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
851 851 <li><a href="/file/xyzzy/foo?style=monoblue">file</a></li>
852 852 <li><a href="/annotate/xyzzy/foo?style=monoblue">annotate</a></li>
853 853 <li><a href="/diff/xyzzy/foo?style=monoblue">diff</a></li>
854 854 <li><a href="/comparison/xyzzy/foo?style=monoblue">comparison</a></li>
855 855 <li><a href="/rss-log/tip/foo">rss</a></li>
856 856 <a href="/rev/a7c1559b7bba?style=monoblue">
857 857 <a href="/file/a7c1559b7bba/foo?style=monoblue">file</a> |
858 858 <a href="/diff/a7c1559b7bba/foo?style=monoblue">diff</a> |
859 859 <a href="/annotate/a7c1559b7bba/foo?style=monoblue">annotate</a>
860 860 <a href="/rev/43c799df6e75?style=monoblue">
861 861 <a href="/file/43c799df6e75/foo?style=monoblue">file</a> |
862 862 <a href="/diff/43c799df6e75/foo?style=monoblue">diff</a> |
863 863 <a href="/annotate/43c799df6e75/foo?style=monoblue">annotate</a>
864 864 <a href="/log/43c799df6e75/foo?style=monoblue">(0)</a> <a href="/log/tip/foo?style=monoblue">tip</a>
865 865
866 866 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'annotate/xyzzy/foo?style=monoblue' | egrep $REVLINKS
867 867 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
868 868 <li><a href="/file/xyzzy/?style=monoblue">files</a></li>
869 869 <li><a href="/file/xyzzy/foo?style=monoblue">file</a></li>
870 870 <li><a href="/file/tip/foo?style=monoblue">latest</a></li>
871 871 <li><a href="/log/xyzzy/foo?style=monoblue">revisions</a></li>
872 872 <li><a href="/diff/xyzzy/foo?style=monoblue">diff</a></li>
873 873 <li><a href="/comparison/xyzzy/foo?style=monoblue">comparison</a></li>
874 874 <li><a href="/raw-file/xyzzy/foo">raw</a></li>
875 875 <dd><a href="/rev/a7c1559b7bba?style=monoblue">a7c1559b7bba</a></dd>
876 876 <a href="/annotate/43c799df6e75/foo?style=monoblue">
877 877 <a href="/annotate/9d8c40cba617/foo?style=monoblue">9d8c40cba617</a>
878 878 <a href="/annotate/43c799df6e75/foo?style=monoblue#l1">
879 879 <a href="/annotate/43c799df6e75/foo?style=monoblue#l1">
880 880 <a href="/diff/43c799df6e75/foo?style=monoblue">diff</a>
881 881 <a href="/rev/43c799df6e75?style=monoblue">changeset</a>
882 882 <a href="/annotate/a7c1559b7bba/foo?style=monoblue#l2">
883 883 <a href="/annotate/a7c1559b7bba/foo?style=monoblue#l2">
884 884 <a href="/annotate/43c799df6e75/foo?style=monoblue">0</a></div>
885 885 <a href="/diff/a7c1559b7bba/foo?style=monoblue">diff</a>
886 886 <a href="/rev/a7c1559b7bba?style=monoblue">changeset</a>
887 887
888 888 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'diff/xyzzy/foo?style=monoblue' | egrep $REVLINKS
889 889 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
890 890 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
891 891 <li><a href="/file/xyzzy/foo?style=monoblue">file</a></li>
892 892 <li><a href="/file/tip/foo?style=monoblue">latest</a></li>
893 893 <li><a href="/log/xyzzy/foo?style=monoblue">revisions</a></li>
894 894 <li><a href="/annotate/xyzzy/foo?style=monoblue">annotate</a></li>
895 895 <li><a href="/comparison/xyzzy/foo?style=monoblue">comparison</a></li>
896 896 <li><a href="/raw-diff/xyzzy/foo">raw</a></li>
897 897 <dd><a href="/rev/a7c1559b7bba?style=monoblue">a7c1559b7bba</a></dd>
898 898 <dd><a href="/diff/43c799df6e75/foo?style=monoblue">43c799df6e75</a></dd>
899 899 <dd><a href="/diff/9d8c40cba617/foo?style=monoblue">9d8c40cba617</a></dd>
900 900
901 901 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'comparison/xyzzy/foo?style=monoblue' | egrep $REVLINKS
902 902 <li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
903 903 <li><a href="/file/xyzzy?style=monoblue">files</a></li>
904 904 <li><a href="/file/xyzzy/foo?style=monoblue">file</a></li>
905 905 <li><a href="/file/tip/foo?style=monoblue">latest</a></li>
906 906 <li><a href="/log/xyzzy/foo?style=monoblue">revisions</a></li>
907 907 <li><a href="/annotate/xyzzy/foo?style=monoblue">annotate</a></li>
908 908 <li><a href="/diff/xyzzy/foo?style=monoblue">diff</a></li>
909 909 <li><a href="/raw-diff/xyzzy/foo">raw</a></li>
910 910 <dd><a href="/rev/a7c1559b7bba?style=monoblue">a7c1559b7bba</a></dd>
911 911 <dd><a href="/comparison/43c799df6e75/foo?style=monoblue">43c799df6e75</a></dd>
912 912 <dd><a href="/comparison/9d8c40cba617/foo?style=monoblue">9d8c40cba617</a></dd>
913 913
914 914 (De)referencing symbolic revisions (spartan)
915 915
916 916 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=spartan' | egrep $REVLINKS
917 917 <a href="/log/tip?style=spartan">changelog</a>
918 918 <a href="/graph/tip?style=spartan">graph</a>
919 919 <a href="/file/tip/?style=spartan">files</a>
920 920 <a href="/archive/tip.zip">zip</a>
921 921 navigate: <small class="navigate"><a href="/shortlog/43c799df6e75?style=spartan">(0)</a> <a href="/shortlog/tip?style=spartan">tip</a> </small>
922 922 <td class="node"><a href="/rev/9d8c40cba617?style=spartan">third</a></td>
923 923 <td class="node"><a href="/rev/a7c1559b7bba?style=spartan">second</a></td>
924 924 <td class="node"><a href="/rev/43c799df6e75?style=spartan">first</a></td>
925 925 navigate: <small class="navigate"><a href="/shortlog/43c799df6e75?style=spartan">(0)</a> <a href="/shortlog/tip?style=spartan">tip</a> </small>
926 926
927 927 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log?style=spartan' | egrep $REVLINKS
928 928 <a href="/shortlog/tip?style=spartan">shortlog</a>
929 929 <a href="/graph/tip?style=spartan">graph</a>
930 930 <a href="/file/tip?style=spartan">files</a>
931 931 <a href="/archive/tip.zip">zip</a>
932 932 navigate: <small class="navigate"><a href="/log/43c799df6e75?style=spartan">(0)</a> <a href="/log/tip?style=spartan">tip</a> </small>
933 933 <td class="node"><a href="/rev/9d8c40cba617?style=spartan">9d8c40cba617</a></td>
934 934 <th class="files"><a href="/file/9d8c40cba617?style=spartan">files</a>:</th>
935 935 <td class="files"><a href="/diff/9d8c40cba617/foo?style=spartan">foo</a> </td>
936 936 <td class="node"><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
937 937 <th class="files"><a href="/file/a7c1559b7bba?style=spartan">files</a>:</th>
938 938 <td class="files"><a href="/diff/a7c1559b7bba/foo?style=spartan">foo</a> </td>
939 939 <td class="node"><a href="/rev/43c799df6e75?style=spartan">43c799df6e75</a></td>
940 940 <th class="files"><a href="/file/43c799df6e75?style=spartan">files</a>:</th>
941 941 <td class="files"><a href="/diff/43c799df6e75/dir/bar?style=spartan">dir/bar</a> <a href="/diff/43c799df6e75/foo?style=spartan">foo</a> </td>
942 942 navigate: <small class="navigate"><a href="/log/43c799df6e75?style=spartan">(0)</a> <a href="/log/tip?style=spartan">tip</a> </small>
943 943
944 944 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph?style=spartan' | egrep $REVLINKS
945 945 <a href="/log/tip?style=spartan">changelog</a>
946 946 <a href="/shortlog/tip?style=spartan">shortlog</a>
947 947 <a href="/file/tip/?style=spartan">files</a>
948 948 navigate: <small class="navigate"><a href="/graph/43c799df6e75?style=spartan">(0)</a> <a href="/graph/tip?style=spartan">tip</a> </small>
949 949 <a href="/rev/9d8c40cba617?style=spartan">third</a>
950 950 <a href="/rev/a7c1559b7bba?style=spartan">second</a>
951 951 <a href="/rev/43c799df6e75?style=spartan">first</a>
952 952 navigate: <small class="navigate"><a href="/graph/43c799df6e75?style=spartan">(0)</a> <a href="/graph/tip?style=spartan">tip</a> </small>
953 953
954 954 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'tags?style=spartan' | egrep $REVLINKS
955 955 <a href="/rev/9d8c40cba617?style=spartan">tip</a>
956 956
957 957 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'branches?style=spartan' | egrep $REVLINKS
958 958 <a href="/shortlog/9d8c40cba617?style=spartan" class="open">default</a>
959 959
960 960 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file?style=spartan' | egrep $REVLINKS
961 961 <a href="/log/tip?style=spartan">changelog</a>
962 962 <a href="/shortlog/tip?style=spartan">shortlog</a>
963 963 <a href="/graph/tip?style=spartan">graph</a>
964 964 <a href="/rev/tip?style=spartan">changeset</a>
965 965 <a href="/archive/tip.zip">zip</a>
966 966 <h2><a href="/">Mercurial</a> / files for changeset <a href="/rev/9d8c40cba617">9d8c40cba617</a>: /</h2>
967 967 <td><a href="/file/tip/?style=spartan">[up]</a>
968 968 <a href="/file/tip/dir?style=spartan">dir/</a>
969 969 <a href="/file/tip/dir/?style=spartan">
970 970 <td><a href="/file/tip/foo?style=spartan">foo</a>
971 971
972 972 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog?style=spartan&rev=all()' | egrep $REVLINKS
973 973 <a href="/archive/tip.zip">zip</a>
974 974 <td class="node"><a href="/rev/9d8c40cba617?style=spartan">9d8c40cba617</a></td>
975 975 <a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a>
976 976 <th class="files"><a href="/file/9d8c40cba617?style=spartan">files</a>:</th>
977 977 <td class="files"><a href="/diff/9d8c40cba617/foo?style=spartan">foo</a> </td>
978 978 <td class="node"><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
979 979 <a href="/rev/43c799df6e75?style=spartan">43c799df6e75</a>
980 980 <td class="child"><a href="/rev/9d8c40cba617?style=spartan">9d8c40cba617</a></td>
981 981 <th class="files"><a href="/file/a7c1559b7bba?style=spartan">files</a>:</th>
982 982 <td class="files"><a href="/diff/a7c1559b7bba/foo?style=spartan">foo</a> </td>
983 983 <td class="node"><a href="/rev/43c799df6e75?style=spartan">43c799df6e75</a></td>
984 984 <td class="child"><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
985 985 <th class="files"><a href="/file/43c799df6e75?style=spartan">files</a>:</th>
986 986 <td class="files"><a href="/diff/43c799df6e75/dir/bar?style=spartan">dir/bar</a> <a href="/diff/43c799df6e75/foo?style=spartan">foo</a> </td>
987 987
988 988 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'rev/xyzzy?style=spartan' | egrep $REVLINKS
989 989 <a href="/log/xyzzy?style=spartan">changelog</a>
990 990 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
991 991 <a href="/graph/xyzzy?style=spartan">graph</a>
992 992 <a href="/file/xyzzy?style=spartan">files</a>
993 993 <a href="/raw-rev/xyzzy">raw</a>
994 994 <a href="/archive/xyzzy.zip">zip</a>
995 995 <td class="changeset"><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
996 996 <td class="parent"><a href="/rev/43c799df6e75?style=spartan">43c799df6e75</a></td>
997 997 <td class="child"><a href="/rev/9d8c40cba617?style=spartan">9d8c40cba617</a></td>
998 998 <td class="files"><a href="/file/a7c1559b7bba/foo?style=spartan">foo</a> </td>
999 999
1000 1000 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'shortlog/xyzzy?style=spartan' | egrep $REVLINKS
1001 1001 <a href="/log/xyzzy?style=spartan">changelog</a>
1002 1002 <a href="/graph/xyzzy?style=spartan">graph</a>
1003 1003 <a href="/file/xyzzy/?style=spartan">files</a>
1004 1004 <a href="/archive/xyzzy.zip">zip</a>
1005 1005 navigate: <small class="navigate"><a href="/shortlog/43c799df6e75?style=spartan">(0)</a> <a href="/shortlog/tip?style=spartan">tip</a> </small>
1006 1006 <td class="node"><a href="/rev/a7c1559b7bba?style=spartan">second</a></td>
1007 1007 <td class="node"><a href="/rev/43c799df6e75?style=spartan">first</a></td>
1008 1008 navigate: <small class="navigate"><a href="/shortlog/43c799df6e75?style=spartan">(0)</a> <a href="/shortlog/tip?style=spartan">tip</a> </small>
1009 1009
1010 1010 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy?style=spartan' | egrep $REVLINKS
1011 1011 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
1012 1012 <a href="/graph/xyzzy?style=spartan">graph</a>
1013 1013 <a href="/file/xyzzy?style=spartan">files</a>
1014 1014 <a href="/archive/xyzzy.zip">zip</a>
1015 1015 navigate: <small class="navigate"><a href="/log/43c799df6e75?style=spartan">(0)</a> <a href="/log/tip?style=spartan">tip</a> </small>
1016 1016 <td class="node"><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
1017 1017 <th class="files"><a href="/file/a7c1559b7bba?style=spartan">files</a>:</th>
1018 1018 <td class="files"><a href="/diff/a7c1559b7bba/foo?style=spartan">foo</a> </td>
1019 1019 <td class="node"><a href="/rev/43c799df6e75?style=spartan">43c799df6e75</a></td>
1020 1020 <th class="files"><a href="/file/43c799df6e75?style=spartan">files</a>:</th>
1021 1021 <td class="files"><a href="/diff/43c799df6e75/dir/bar?style=spartan">dir/bar</a> <a href="/diff/43c799df6e75/foo?style=spartan">foo</a> </td>
1022 1022 navigate: <small class="navigate"><a href="/log/43c799df6e75?style=spartan">(0)</a> <a href="/log/tip?style=spartan">tip</a> </small>
1023 1023
1024 1024 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'graph/xyzzy?style=spartan' | egrep $REVLINKS
1025 1025 <a href="/log/xyzzy?style=spartan">changelog</a>
1026 1026 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
1027 1027 <a href="/file/xyzzy/?style=spartan">files</a>
1028 1028 navigate: <small class="navigate"><a href="/graph/43c799df6e75?style=spartan">(0)</a> <a href="/graph/tip?style=spartan">tip</a> </small>
1029 1029 <a href="/rev/a7c1559b7bba?style=spartan">second</a>
1030 1030 <a href="/rev/43c799df6e75?style=spartan">first</a>
1031 1031 navigate: <small class="navigate"><a href="/graph/43c799df6e75?style=spartan">(0)</a> <a href="/graph/tip?style=spartan">tip</a> </small>
1032 1032
1033 1033 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy?style=spartan' | egrep $REVLINKS
1034 1034 <a href="/log/xyzzy?style=spartan">changelog</a>
1035 1035 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
1036 1036 <a href="/graph/xyzzy?style=spartan">graph</a>
1037 1037 <a href="/rev/xyzzy?style=spartan">changeset</a>
1038 1038 <a href="/archive/xyzzy.zip">zip</a>
1039 1039 <h2><a href="/">Mercurial</a> / files for changeset <a href="/rev/a7c1559b7bba">a7c1559b7bba</a>: /</h2>
1040 1040 <td><a href="/file/xyzzy/?style=spartan">[up]</a>
1041 1041 <a href="/file/xyzzy/dir?style=spartan">dir/</a>
1042 1042 <a href="/file/xyzzy/dir/?style=spartan">
1043 1043 <td><a href="/file/xyzzy/foo?style=spartan">foo</a>
1044 1044
1045 1045 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'file/xyzzy/foo?style=spartan' | egrep $REVLINKS
1046 1046 <a href="/log/xyzzy?style=spartan">changelog</a>
1047 1047 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
1048 1048 <a href="/graph/xyzzy?style=spartan">graph</a>
1049 1049 <a href="/rev/xyzzy?style=spartan">changeset</a>
1050 1050 <a href="/file/xyzzy/?style=spartan">files</a>
1051 1051 <a href="/log/xyzzy/foo?style=spartan">revisions</a>
1052 1052 <a href="/annotate/xyzzy/foo?style=spartan">annotate</a>
1053 1053 <a href="/raw-file/xyzzy/foo">raw</a>
1054 1054 <td><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
1055 1055 <a href="/file/43c799df6e75/foo?style=spartan">
1056 1056 <td><a href="/file/9d8c40cba617/foo?style=spartan">9d8c40cba617</a></td>
1057 1057
1058 1058 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'log/xyzzy/foo?style=spartan' | egrep $REVLINKS
1059 1059 href="/atom-log/tip/foo" title="Atom feed for test:foo">
1060 1060 href="/rss-log/tip/foo" title="RSS feed for test:foo">
1061 1061 <a href="/file/xyzzy/foo?style=spartan">file</a>
1062 1062 <a href="/annotate/xyzzy/foo?style=spartan">annotate</a>
1063 1063 <a type="application/rss+xml" href="/rss-log/tip/foo">rss</a>
1064 1064 <a type="application/atom+xml" href="/atom-log/tip/foo" title="Atom feed for test:foo">atom</a>
1065 1065 <p>navigate: <small class="navigate"><a href="/log/43c799df6e75/foo?style=spartan">(0)</a> <a href="/log/tip/foo?style=spartan">tip</a> </small></p>
1066 1066 <th class="firstline"><a href="/rev/a7c1559b7bba?style=spartan">second</a></th>
1067 1067 <a href="/file/a7c1559b7bba/foo?style=spartan">a7c1559b7bba</a>
1068 1068 <a href="/diff/a7c1559b7bba/foo?style=spartan">(diff)</a>
1069 1069 <a href="/annotate/a7c1559b7bba/foo?style=spartan">(annotate)</a>
1070 1070 <th class="firstline"><a href="/rev/43c799df6e75?style=spartan">first</a></th>
1071 1071 <a href="/file/43c799df6e75/foo?style=spartan">43c799df6e75</a>
1072 1072 <a href="/diff/43c799df6e75/foo?style=spartan">(diff)</a>
1073 1073 <a href="/annotate/43c799df6e75/foo?style=spartan">(annotate)</a>
1074 1074
1075 1075 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'annotate/xyzzy/foo?style=spartan' | egrep $REVLINKS
1076 1076 <a href="/log/xyzzy?style=spartan">changelog</a>
1077 1077 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
1078 1078 <a href="/graph/xyzzy?style=spartan">graph</a>
1079 1079 <a href="/rev/xyzzy?style=spartan">changeset</a>
1080 1080 <a href="/file/xyzzy/?style=spartan">files</a>
1081 1081 <a href="/file/xyzzy/foo?style=spartan">file</a>
1082 1082 <a href="/log/xyzzy/foo?style=spartan">revisions</a>
1083 1083 <a href="/raw-file/xyzzy/foo">raw</a>
1084 1084 <td><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
1085 1085 <a href="/annotate/43c799df6e75/foo?style=spartan">
1086 1086 <td><a href="/annotate/9d8c40cba617/foo?style=spartan">9d8c40cba617</a></td>
1087 1087 <a href="/annotate/43c799df6e75/foo?style=spartan#l1">
1088 1088 <a href="/annotate/43c799df6e75/foo?style=spartan#l1">
1089 1089 <a href="/diff/43c799df6e75/foo?style=spartan">diff</a>
1090 1090 <a href="/rev/43c799df6e75?style=spartan">changeset</a>
1091 1091 <a href="/annotate/a7c1559b7bba/foo?style=spartan#l2">
1092 1092 <a href="/annotate/a7c1559b7bba/foo?style=spartan#l2">
1093 1093 <a href="/annotate/43c799df6e75/foo?style=spartan">0</a></div>
1094 1094 <a href="/diff/a7c1559b7bba/foo?style=spartan">diff</a>
1095 1095 <a href="/rev/a7c1559b7bba?style=spartan">changeset</a>
1096 1096
1097 1097 $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT 'diff/xyzzy/foo?style=spartan' | egrep $REVLINKS
1098 1098 <a href="/log/xyzzy?style=spartan">changelog</a>
1099 1099 <a href="/shortlog/xyzzy?style=spartan">shortlog</a>
1100 1100 <a href="/graph/xyzzy?style=spartan">graph</a>
1101 1101 <a href="/rev/xyzzy?style=spartan">changeset</a>
1102 1102 <a href="/file/xyzzy/foo?style=spartan">file</a>
1103 1103 <a href="/log/xyzzy/foo?style=spartan">revisions</a>
1104 1104 <a href="/annotate/xyzzy/foo?style=spartan">annotate</a>
1105 1105 <a href="/raw-diff/xyzzy/foo">raw</a>
1106 1106 <td class="revision"><a href="/rev/a7c1559b7bba?style=spartan">a7c1559b7bba</a></td>
1107 1107 <td class="parent"><a href="/rev/43c799df6e75?style=spartan">43c799df6e75</a></td>
1108 1108 <td class="child"><a href="/rev/9d8c40cba617?style=spartan">9d8c40cba617</a></td>
1109 1109
1110 1110 Done
1111 1111
1112 1112 $ cat errors.log
1113 1113 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1114 1114 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now