93 For URLs of the form ``/log/{revision}/{file}``, the history for a specific |
93 For URLs of the form ``/log/{revision}/{file}``, the history for a specific |
94 file will be shown. This form is equivalent to the ``filelog`` handler. |
94 file will be shown. This form is equivalent to the ``filelog`` handler. |
95 """ |
95 """ |
96 |
96 |
97 if web.req.qsparams.get('file'): |
97 if web.req.qsparams.get('file'): |
98 return filelog(web, req, tmpl) |
98 return filelog(web, req, None) |
99 else: |
99 else: |
100 return changelog(web, req, tmpl) |
100 return changelog(web, req, None) |
101 |
101 |
102 @webcommand('rawfile') |
102 @webcommand('rawfile') |
103 def rawfile(web, req, tmpl): |
103 def rawfile(web, req, tmpl): |
104 guessmime = web.configbool('web', 'guessmime') |
104 guessmime = web.configbool('web', 'guessmime') |
105 |
105 |
106 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) |
106 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) |
107 if not path: |
107 if not path: |
108 return manifest(web, req, tmpl) |
108 return manifest(web, req, None) |
109 |
109 |
110 try: |
110 try: |
111 fctx = webutil.filectx(web.repo, req) |
111 fctx = webutil.filectx(web.repo, req) |
112 except error.LookupError as inst: |
112 except error.LookupError as inst: |
113 try: |
113 try: |
114 return manifest(web, req, tmpl) |
114 return manifest(web, req, None) |
115 except ErrorResponse: |
115 except ErrorResponse: |
116 raise inst |
116 raise inst |
117 |
117 |
118 path = fctx.path() |
118 path = fctx.path() |
119 text = fctx.data() |
119 text = fctx.data() |
133 .replace('\\', '\\\\').replace('"', '\\"')) |
133 .replace('\\', '\\\\').replace('"', '\\"')) |
134 web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename |
134 web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename |
135 web.res.setbodybytes(text) |
135 web.res.setbodybytes(text) |
136 return web.res.sendresponse() |
136 return web.res.sendresponse() |
137 |
137 |
138 def _filerevision(web, req, tmpl, fctx): |
138 def _filerevision(web, req, fctx): |
139 f = fctx.path() |
139 f = fctx.path() |
140 text = fctx.data() |
140 text = fctx.data() |
141 parity = paritygen(web.stripecount) |
141 parity = paritygen(web.stripecount) |
142 ishead = fctx.filerev() in fctx.filelog().headrevs() |
142 ishead = fctx.filerev() in fctx.filelog().headrevs() |
143 |
143 |
182 |
182 |
183 If ``path`` is not defined, information about the root directory will |
183 If ``path`` is not defined, information about the root directory will |
184 be rendered. |
184 be rendered. |
185 """ |
185 """ |
186 if web.req.qsparams.get('style') == 'raw': |
186 if web.req.qsparams.get('style') == 'raw': |
187 return rawfile(web, req, tmpl) |
187 return rawfile(web, req, None) |
188 |
188 |
189 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) |
189 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) |
190 if not path: |
190 if not path: |
191 return manifest(web, req, tmpl) |
191 return manifest(web, req, None) |
192 try: |
192 try: |
193 return _filerevision(web, req, tmpl, webutil.filectx(web.repo, req)) |
193 return _filerevision(web, req, webutil.filectx(web.repo, req)) |
194 except error.LookupError as inst: |
194 except error.LookupError as inst: |
195 try: |
195 try: |
196 return manifest(web, req, tmpl) |
196 return manifest(web, req, None) |
197 except ErrorResponse: |
197 except ErrorResponse: |
198 raise inst |
198 raise inst |
199 |
199 |
200 def _search(web, tmpl): |
200 def _search(web): |
201 MODE_REVISION = 'rev' |
201 MODE_REVISION = 'rev' |
202 MODE_KEYWORD = 'keyword' |
202 MODE_KEYWORD = 'keyword' |
203 MODE_REVSET = 'revset' |
203 MODE_REVSET = 'revset' |
204 |
204 |
205 def revsearch(ctx): |
205 def revsearch(ctx): |
288 count = 0 |
288 count = 0 |
289 |
289 |
290 for ctx in searchfunc[0](funcarg): |
290 for ctx in searchfunc[0](funcarg): |
291 count += 1 |
291 count += 1 |
292 n = ctx.node() |
292 n = ctx.node() |
293 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n) |
293 showtags = webutil.showtag(web.repo, web.tmpl, 'changelogtag', n) |
294 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles) |
294 files = webutil.listfilediffs(web.tmpl, ctx.files(), n, |
295 |
295 web.maxfiles) |
296 yield tmpl('searchentry', |
296 |
297 parity=next(parity), |
297 yield web.tmpl( |
298 changelogtag=showtags, |
298 'searchentry', |
299 files=files, |
299 parity=next(parity), |
300 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) |
300 changelogtag=showtags, |
|
301 files=files, |
|
302 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) |
301 |
303 |
302 if count >= revcount: |
304 if count >= revcount: |
303 break |
305 break |
304 |
306 |
305 query = web.req.qsparams['rev'] |
307 query = web.req.qsparams['rev'] |
306 revcount = web.maxchanges |
308 revcount = web.maxchanges |
307 if 'revcount' in web.req.qsparams: |
309 if 'revcount' in web.req.qsparams: |
308 try: |
310 try: |
309 revcount = int(web.req.qsparams.get('revcount', revcount)) |
311 revcount = int(web.req.qsparams.get('revcount', revcount)) |
310 revcount = max(revcount, 1) |
312 revcount = max(revcount, 1) |
311 tmpl.defaults['sessionvars']['revcount'] = revcount |
313 web.tmpl.defaults['sessionvars']['revcount'] = revcount |
312 except ValueError: |
314 except ValueError: |
313 pass |
315 pass |
314 |
316 |
315 lessvars = copy.copy(tmpl.defaults['sessionvars']) |
317 lessvars = copy.copy(web.tmpl.defaults['sessionvars']) |
316 lessvars['revcount'] = max(revcount // 2, 1) |
318 lessvars['revcount'] = max(revcount // 2, 1) |
317 lessvars['rev'] = query |
319 lessvars['rev'] = query |
318 morevars = copy.copy(tmpl.defaults['sessionvars']) |
320 morevars = copy.copy(web.tmpl.defaults['sessionvars']) |
319 morevars['revcount'] = revcount * 2 |
321 morevars['revcount'] = revcount * 2 |
320 morevars['rev'] = query |
322 morevars['rev'] = query |
321 |
323 |
322 mode, funcarg = getsearchmode(query) |
324 mode, funcarg = getsearchmode(query) |
323 |
325 |
380 query = '' |
382 query = '' |
381 if 'node' in web.req.qsparams: |
383 if 'node' in web.req.qsparams: |
382 ctx = webutil.changectx(web.repo, req) |
384 ctx = webutil.changectx(web.repo, req) |
383 symrev = webutil.symrevorshortnode(req, ctx) |
385 symrev = webutil.symrevorshortnode(req, ctx) |
384 elif 'rev' in web.req.qsparams: |
386 elif 'rev' in web.req.qsparams: |
385 return _search(web, tmpl) |
387 return _search(web) |
386 else: |
388 else: |
387 ctx = web.repo['tip'] |
389 ctx = web.repo['tip'] |
388 symrev = 'tip' |
390 symrev = 'tip' |
389 |
391 |
390 def changelist(): |
392 def changelist(): |
408 |
410 |
409 if 'revcount' in web.req.qsparams: |
411 if 'revcount' in web.req.qsparams: |
410 try: |
412 try: |
411 revcount = int(web.req.qsparams.get('revcount', revcount)) |
413 revcount = int(web.req.qsparams.get('revcount', revcount)) |
412 revcount = max(revcount, 1) |
414 revcount = max(revcount, 1) |
413 tmpl.defaults['sessionvars']['revcount'] = revcount |
415 web.tmpl.defaults['sessionvars']['revcount'] = revcount |
414 except ValueError: |
416 except ValueError: |
415 pass |
417 pass |
416 |
418 |
417 lessvars = copy.copy(tmpl.defaults['sessionvars']) |
419 lessvars = copy.copy(web.tmpl.defaults['sessionvars']) |
418 lessvars['revcount'] = max(revcount // 2, 1) |
420 lessvars['revcount'] = max(revcount // 2, 1) |
419 morevars = copy.copy(tmpl.defaults['sessionvars']) |
421 morevars = copy.copy(web.tmpl.defaults['sessionvars']) |
420 morevars['revcount'] = revcount * 2 |
422 morevars['revcount'] = revcount * 2 |
421 |
423 |
422 count = len(web.repo) |
424 count = len(web.repo) |
423 pos = ctx.rev() |
425 pos = ctx.rev() |
424 parity = paritygen(web.stripecount) |
426 parity = paritygen(web.stripecount) |
459 |
461 |
460 This accepts the same parameters as the ``changelog`` handler. The only |
462 This accepts the same parameters as the ``changelog`` handler. The only |
461 difference is the ``shortlog`` template will be rendered instead of the |
463 difference is the ``shortlog`` template will be rendered instead of the |
462 ``changelog`` template. |
464 ``changelog`` template. |
463 """ |
465 """ |
464 return changelog(web, req, tmpl, shortlog=True) |
466 return changelog(web, req, None, shortlog=True) |
465 |
467 |
466 @webcommand('changeset') |
468 @webcommand('changeset') |
467 def changeset(web, req, tmpl): |
469 def changeset(web, req, tmpl): |
468 """ |
470 """ |
469 /changeset[/{revision}] |
471 /changeset[/{revision}] |
481 """ |
483 """ |
482 ctx = webutil.changectx(web.repo, req) |
484 ctx = webutil.changectx(web.repo, req) |
483 |
485 |
484 return web.sendtemplate( |
486 return web.sendtemplate( |
485 'changeset', |
487 'changeset', |
486 **webutil.changesetentry(web, req, tmpl, ctx)) |
488 **webutil.changesetentry(web, req, web.tmpl, ctx)) |
487 |
489 |
488 rev = webcommand('rev')(changeset) |
490 rev = webcommand('rev')(changeset) |
489 |
491 |
490 def decodepath(path): |
492 def decodepath(path): |
491 """Hook for mapping a path in the repository to a path in the |
493 """Hook for mapping a path in the repository to a path in the |
715 |
717 |
716 count += 1 |
718 count += 1 |
717 if count > 10: # limit to 10 tags |
719 if count > 10: # limit to 10 tags |
718 break |
720 break |
719 |
721 |
720 yield tmpl("tagentry", |
722 yield web.tmpl( |
721 parity=next(parity), |
723 'tagentry', |
722 tag=k, |
724 parity=next(parity), |
723 node=hex(n), |
725 tag=k, |
724 date=web.repo[n].date()) |
726 node=hex(n), |
|
727 date=web.repo[n].date()) |
725 |
728 |
726 def bookmarks(**map): |
729 def bookmarks(**map): |
727 parity = paritygen(web.stripecount) |
730 parity = paritygen(web.stripecount) |
728 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo] |
731 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo] |
729 sortkey = lambda b: (web.repo[b[1]].rev(), b[0]) |
732 sortkey = lambda b: (web.repo[b[1]].rev(), b[0]) |
803 |
806 |
804 style = web.config('web', 'style') |
807 style = web.config('web', 'style') |
805 if 'style' in web.req.qsparams: |
808 if 'style' in web.req.qsparams: |
806 style = web.req.qsparams['style'] |
809 style = web.req.qsparams['style'] |
807 |
810 |
808 diffs = webutil.diffs(web, tmpl, ctx, basectx, [path], style) |
811 diffs = webutil.diffs(web, web.tmpl, ctx, basectx, [path], style) |
809 if fctx is not None: |
812 if fctx is not None: |
810 rename = webutil.renamelink(fctx) |
813 rename = webutil.renamelink(fctx) |
811 ctx = fctx |
814 ctx = fctx |
812 else: |
815 else: |
813 rename = [] |
816 rename = [] |
876 else: |
879 else: |
877 rightlines = () |
880 rightlines = () |
878 pfctx = ctx.parents()[0][path] |
881 pfctx = ctx.parents()[0][path] |
879 leftlines = filelines(pfctx) |
882 leftlines = filelines(pfctx) |
880 |
883 |
881 comparison = webutil.compare(tmpl, context, leftlines, rightlines) |
884 comparison = webutil.compare(web.tmpl, context, leftlines, rightlines) |
882 if fctx is not None: |
885 if fctx is not None: |
883 rename = webutil.renamelink(fctx) |
886 rename = webutil.renamelink(fctx) |
884 ctx = fctx |
887 ctx = fctx |
885 else: |
888 else: |
886 rename = [] |
889 rename = [] |
1026 revcount = web.maxshortchanges |
1029 revcount = web.maxshortchanges |
1027 if 'revcount' in web.req.qsparams: |
1030 if 'revcount' in web.req.qsparams: |
1028 try: |
1031 try: |
1029 revcount = int(web.req.qsparams.get('revcount', revcount)) |
1032 revcount = int(web.req.qsparams.get('revcount', revcount)) |
1030 revcount = max(revcount, 1) |
1033 revcount = max(revcount, 1) |
1031 tmpl.defaults['sessionvars']['revcount'] = revcount |
1034 web.tmpl.defaults['sessionvars']['revcount'] = revcount |
1032 except ValueError: |
1035 except ValueError: |
1033 pass |
1036 pass |
1034 |
1037 |
1035 lrange = webutil.linerange(req) |
1038 lrange = webutil.linerange(req) |
1036 |
1039 |
1037 lessvars = copy.copy(tmpl.defaults['sessionvars']) |
1040 lessvars = copy.copy(web.tmpl.defaults['sessionvars']) |
1038 lessvars['revcount'] = max(revcount // 2, 1) |
1041 lessvars['revcount'] = max(revcount // 2, 1) |
1039 morevars = copy.copy(tmpl.defaults['sessionvars']) |
1042 morevars = copy.copy(web.tmpl.defaults['sessionvars']) |
1040 morevars['revcount'] = revcount * 2 |
1043 morevars['revcount'] = revcount * 2 |
1041 |
1044 |
1042 patch = 'patch' in web.req.qsparams |
1045 patch = 'patch' in web.req.qsparams |
1043 if patch: |
1046 if patch: |
1044 lessvars['patch'] = morevars['patch'] = web.req.qsparams['patch'] |
1047 lessvars['patch'] = morevars['patch'] = web.req.qsparams['patch'] |
1061 |
1064 |
1062 def diff(fctx, linerange=None): |
1065 def diff(fctx, linerange=None): |
1063 ctx = fctx.changectx() |
1066 ctx = fctx.changectx() |
1064 basectx = ctx.p1() |
1067 basectx = ctx.p1() |
1065 path = fctx.path() |
1068 path = fctx.path() |
1066 return webutil.diffs(web, tmpl, ctx, basectx, [path], diffstyle, |
1069 return webutil.diffs(web, web.tmpl, ctx, basectx, [path], diffstyle, |
1067 linerange=linerange, |
1070 linerange=linerange, |
1068 lineidprefix='%s-' % ctx.hex()[:12]) |
1071 lineidprefix='%s-' % ctx.hex()[:12]) |
1069 |
1072 |
1070 linerange = None |
1073 linerange = None |
1071 if lrange is not None: |
1074 if lrange is not None: |
1253 revcount = web.maxshortchanges |
1256 revcount = web.maxshortchanges |
1254 if 'revcount' in web.req.qsparams: |
1257 if 'revcount' in web.req.qsparams: |
1255 try: |
1258 try: |
1256 revcount = int(web.req.qsparams.get('revcount', revcount)) |
1259 revcount = int(web.req.qsparams.get('revcount', revcount)) |
1257 revcount = max(revcount, 1) |
1260 revcount = max(revcount, 1) |
1258 tmpl.defaults['sessionvars']['revcount'] = revcount |
1261 web.tmpl.defaults['sessionvars']['revcount'] = revcount |
1259 except ValueError: |
1262 except ValueError: |
1260 pass |
1263 pass |
1261 |
1264 |
1262 lessvars = copy.copy(tmpl.defaults['sessionvars']) |
1265 lessvars = copy.copy(web.tmpl.defaults['sessionvars']) |
1263 lessvars['revcount'] = max(revcount // 2, 1) |
1266 lessvars['revcount'] = max(revcount // 2, 1) |
1264 morevars = copy.copy(tmpl.defaults['sessionvars']) |
1267 morevars = copy.copy(web.tmpl.defaults['sessionvars']) |
1265 morevars['revcount'] = revcount * 2 |
1268 morevars['revcount'] = revcount * 2 |
1266 |
1269 |
1267 graphtop = web.req.qsparams.get('graphtop', ctx.hex()) |
1270 graphtop = web.req.qsparams.get('graphtop', ctx.hex()) |
1268 graphvars = copy.copy(tmpl.defaults['sessionvars']) |
1271 graphvars = copy.copy(web.tmpl.defaults['sessionvars']) |
1269 graphvars['graphtop'] = graphtop |
1272 graphvars['graphtop'] = graphtop |
1270 |
1273 |
1271 count = len(web.repo) |
1274 count = len(web.repo) |
1272 pos = rev |
1275 pos = rev |
1273 |
1276 |