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