##// END OF EJS Templates
hgweb: fix type of {nav} keyword when linerange filter is active...
Yuya Nishihara -
r37421:448f7ec2 default
parent child Browse files
Show More
@@ -1,1493 +1,1493 b''
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import copy
10 import copy
11 import mimetypes
11 import mimetypes
12 import os
12 import os
13 import re
13 import re
14
14
15 from ..i18n import _
15 from ..i18n import _
16 from ..node import hex, nullid, short
16 from ..node import hex, nullid, short
17
17
18 from .common import (
18 from .common import (
19 ErrorResponse,
19 ErrorResponse,
20 HTTP_FORBIDDEN,
20 HTTP_FORBIDDEN,
21 HTTP_NOT_FOUND,
21 HTTP_NOT_FOUND,
22 get_contact,
22 get_contact,
23 paritygen,
23 paritygen,
24 staticfile,
24 staticfile,
25 )
25 )
26
26
27 from .. import (
27 from .. import (
28 archival,
28 archival,
29 dagop,
29 dagop,
30 encoding,
30 encoding,
31 error,
31 error,
32 graphmod,
32 graphmod,
33 pycompat,
33 pycompat,
34 revset,
34 revset,
35 revsetlang,
35 revsetlang,
36 scmutil,
36 scmutil,
37 smartset,
37 smartset,
38 templater,
38 templater,
39 templateutil,
39 templateutil,
40 )
40 )
41
41
42 from ..utils import (
42 from ..utils import (
43 stringutil,
43 stringutil,
44 )
44 )
45
45
46 from . import (
46 from . import (
47 webutil,
47 webutil,
48 )
48 )
49
49
50 __all__ = []
50 __all__ = []
51 commands = {}
51 commands = {}
52
52
53 class webcommand(object):
53 class webcommand(object):
54 """Decorator used to register a web command handler.
54 """Decorator used to register a web command handler.
55
55
56 The decorator takes as its positional arguments the name/path the
56 The decorator takes as its positional arguments the name/path the
57 command should be accessible under.
57 command should be accessible under.
58
58
59 When called, functions receive as arguments a ``requestcontext``,
59 When called, functions receive as arguments a ``requestcontext``,
60 ``wsgirequest``, and a templater instance for generatoring output.
60 ``wsgirequest``, and a templater instance for generatoring output.
61 The functions should populate the ``rctx.res`` object with details
61 The functions should populate the ``rctx.res`` object with details
62 about the HTTP response.
62 about the HTTP response.
63
63
64 The function returns a generator to be consumed by the WSGI application.
64 The function returns a generator to be consumed by the WSGI application.
65 For most commands, this should be the result from
65 For most commands, this should be the result from
66 ``web.res.sendresponse()``. Many commands will call ``web.sendtemplate()``
66 ``web.res.sendresponse()``. Many commands will call ``web.sendtemplate()``
67 to render a template.
67 to render a template.
68
68
69 Usage:
69 Usage:
70
70
71 @webcommand('mycommand')
71 @webcommand('mycommand')
72 def mycommand(web):
72 def mycommand(web):
73 pass
73 pass
74 """
74 """
75
75
76 def __init__(self, name):
76 def __init__(self, name):
77 self.name = name
77 self.name = name
78
78
79 def __call__(self, func):
79 def __call__(self, func):
80 __all__.append(self.name)
80 __all__.append(self.name)
81 commands[self.name] = func
81 commands[self.name] = func
82 return func
82 return func
83
83
84 @webcommand('log')
84 @webcommand('log')
85 def log(web):
85 def log(web):
86 """
86 """
87 /log[/{revision}[/{path}]]
87 /log[/{revision}[/{path}]]
88 --------------------------
88 --------------------------
89
89
90 Show repository or file history.
90 Show repository or file history.
91
91
92 For URLs of the form ``/log/{revision}``, a list of changesets starting at
92 For URLs of the form ``/log/{revision}``, a list of changesets starting at
93 the specified changeset identifier is shown. If ``{revision}`` is not
93 the specified changeset identifier is shown. If ``{revision}`` is not
94 defined, the default is ``tip``. This form is equivalent to the
94 defined, the default is ``tip``. This form is equivalent to the
95 ``changelog`` handler.
95 ``changelog`` handler.
96
96
97 For URLs of the form ``/log/{revision}/{file}``, the history for a specific
97 For URLs of the form ``/log/{revision}/{file}``, the history for a specific
98 file will be shown. This form is equivalent to the ``filelog`` handler.
98 file will be shown. This form is equivalent to the ``filelog`` handler.
99 """
99 """
100
100
101 if web.req.qsparams.get('file'):
101 if web.req.qsparams.get('file'):
102 return filelog(web)
102 return filelog(web)
103 else:
103 else:
104 return changelog(web)
104 return changelog(web)
105
105
106 @webcommand('rawfile')
106 @webcommand('rawfile')
107 def rawfile(web):
107 def rawfile(web):
108 guessmime = web.configbool('web', 'guessmime')
108 guessmime = web.configbool('web', 'guessmime')
109
109
110 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
110 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
111 if not path:
111 if not path:
112 return manifest(web)
112 return manifest(web)
113
113
114 try:
114 try:
115 fctx = webutil.filectx(web.repo, web.req)
115 fctx = webutil.filectx(web.repo, web.req)
116 except error.LookupError as inst:
116 except error.LookupError as inst:
117 try:
117 try:
118 return manifest(web)
118 return manifest(web)
119 except ErrorResponse:
119 except ErrorResponse:
120 raise inst
120 raise inst
121
121
122 path = fctx.path()
122 path = fctx.path()
123 text = fctx.data()
123 text = fctx.data()
124 mt = 'application/binary'
124 mt = 'application/binary'
125 if guessmime:
125 if guessmime:
126 mt = mimetypes.guess_type(path)[0]
126 mt = mimetypes.guess_type(path)[0]
127 if mt is None:
127 if mt is None:
128 if stringutil.binary(text):
128 if stringutil.binary(text):
129 mt = 'application/binary'
129 mt = 'application/binary'
130 else:
130 else:
131 mt = 'text/plain'
131 mt = 'text/plain'
132 if mt.startswith('text/'):
132 if mt.startswith('text/'):
133 mt += '; charset="%s"' % encoding.encoding
133 mt += '; charset="%s"' % encoding.encoding
134
134
135 web.res.headers['Content-Type'] = mt
135 web.res.headers['Content-Type'] = mt
136 filename = (path.rpartition('/')[-1]
136 filename = (path.rpartition('/')[-1]
137 .replace('\\', '\\\\').replace('"', '\\"'))
137 .replace('\\', '\\\\').replace('"', '\\"'))
138 web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename
138 web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename
139 web.res.setbodybytes(text)
139 web.res.setbodybytes(text)
140 return web.res.sendresponse()
140 return web.res.sendresponse()
141
141
142 def _filerevision(web, fctx):
142 def _filerevision(web, fctx):
143 f = fctx.path()
143 f = fctx.path()
144 text = fctx.data()
144 text = fctx.data()
145 parity = paritygen(web.stripecount)
145 parity = paritygen(web.stripecount)
146 ishead = fctx.filerev() in fctx.filelog().headrevs()
146 ishead = fctx.filerev() in fctx.filelog().headrevs()
147
147
148 if stringutil.binary(text):
148 if stringutil.binary(text):
149 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
149 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
150 text = '(binary:%s)' % mt
150 text = '(binary:%s)' % mt
151
151
152 def lines():
152 def lines():
153 for lineno, t in enumerate(text.splitlines(True)):
153 for lineno, t in enumerate(text.splitlines(True)):
154 yield {"line": t,
154 yield {"line": t,
155 "lineid": "l%d" % (lineno + 1),
155 "lineid": "l%d" % (lineno + 1),
156 "linenumber": "% 6d" % (lineno + 1),
156 "linenumber": "% 6d" % (lineno + 1),
157 "parity": next(parity)}
157 "parity": next(parity)}
158
158
159 return web.sendtemplate(
159 return web.sendtemplate(
160 'filerevision',
160 'filerevision',
161 file=f,
161 file=f,
162 path=webutil.up(f),
162 path=webutil.up(f),
163 text=lines(),
163 text=lines(),
164 symrev=webutil.symrevorshortnode(web.req, fctx),
164 symrev=webutil.symrevorshortnode(web.req, fctx),
165 rename=webutil.renamelink(fctx),
165 rename=webutil.renamelink(fctx),
166 permissions=fctx.manifest().flags(f),
166 permissions=fctx.manifest().flags(f),
167 ishead=int(ishead),
167 ishead=int(ishead),
168 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
168 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
169
169
170 @webcommand('file')
170 @webcommand('file')
171 def file(web):
171 def file(web):
172 """
172 """
173 /file/{revision}[/{path}]
173 /file/{revision}[/{path}]
174 -------------------------
174 -------------------------
175
175
176 Show information about a directory or file in the repository.
176 Show information about a directory or file in the repository.
177
177
178 Info about the ``path`` given as a URL parameter will be rendered.
178 Info about the ``path`` given as a URL parameter will be rendered.
179
179
180 If ``path`` is a directory, information about the entries in that
180 If ``path`` is a directory, information about the entries in that
181 directory will be rendered. This form is equivalent to the ``manifest``
181 directory will be rendered. This form is equivalent to the ``manifest``
182 handler.
182 handler.
183
183
184 If ``path`` is a file, information about that file will be shown via
184 If ``path`` is a file, information about that file will be shown via
185 the ``filerevision`` template.
185 the ``filerevision`` template.
186
186
187 If ``path`` is not defined, information about the root directory will
187 If ``path`` is not defined, information about the root directory will
188 be rendered.
188 be rendered.
189 """
189 """
190 if web.req.qsparams.get('style') == 'raw':
190 if web.req.qsparams.get('style') == 'raw':
191 return rawfile(web)
191 return rawfile(web)
192
192
193 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
193 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
194 if not path:
194 if not path:
195 return manifest(web)
195 return manifest(web)
196 try:
196 try:
197 return _filerevision(web, webutil.filectx(web.repo, web.req))
197 return _filerevision(web, webutil.filectx(web.repo, web.req))
198 except error.LookupError as inst:
198 except error.LookupError as inst:
199 try:
199 try:
200 return manifest(web)
200 return manifest(web)
201 except ErrorResponse:
201 except ErrorResponse:
202 raise inst
202 raise inst
203
203
204 def _search(web):
204 def _search(web):
205 MODE_REVISION = 'rev'
205 MODE_REVISION = 'rev'
206 MODE_KEYWORD = 'keyword'
206 MODE_KEYWORD = 'keyword'
207 MODE_REVSET = 'revset'
207 MODE_REVSET = 'revset'
208
208
209 def revsearch(ctx):
209 def revsearch(ctx):
210 yield ctx
210 yield ctx
211
211
212 def keywordsearch(query):
212 def keywordsearch(query):
213 lower = encoding.lower
213 lower = encoding.lower
214 qw = lower(query).split()
214 qw = lower(query).split()
215
215
216 def revgen():
216 def revgen():
217 cl = web.repo.changelog
217 cl = web.repo.changelog
218 for i in xrange(len(web.repo) - 1, 0, -100):
218 for i in xrange(len(web.repo) - 1, 0, -100):
219 l = []
219 l = []
220 for j in cl.revs(max(0, i - 99), i):
220 for j in cl.revs(max(0, i - 99), i):
221 ctx = web.repo[j]
221 ctx = web.repo[j]
222 l.append(ctx)
222 l.append(ctx)
223 l.reverse()
223 l.reverse()
224 for e in l:
224 for e in l:
225 yield e
225 yield e
226
226
227 for ctx in revgen():
227 for ctx in revgen():
228 miss = 0
228 miss = 0
229 for q in qw:
229 for q in qw:
230 if not (q in lower(ctx.user()) or
230 if not (q in lower(ctx.user()) or
231 q in lower(ctx.description()) or
231 q in lower(ctx.description()) or
232 q in lower(" ".join(ctx.files()))):
232 q in lower(" ".join(ctx.files()))):
233 miss = 1
233 miss = 1
234 break
234 break
235 if miss:
235 if miss:
236 continue
236 continue
237
237
238 yield ctx
238 yield ctx
239
239
240 def revsetsearch(revs):
240 def revsetsearch(revs):
241 for r in revs:
241 for r in revs:
242 yield web.repo[r]
242 yield web.repo[r]
243
243
244 searchfuncs = {
244 searchfuncs = {
245 MODE_REVISION: (revsearch, 'exact revision search'),
245 MODE_REVISION: (revsearch, 'exact revision search'),
246 MODE_KEYWORD: (keywordsearch, 'literal keyword search'),
246 MODE_KEYWORD: (keywordsearch, 'literal keyword search'),
247 MODE_REVSET: (revsetsearch, 'revset expression search'),
247 MODE_REVSET: (revsetsearch, 'revset expression search'),
248 }
248 }
249
249
250 def getsearchmode(query):
250 def getsearchmode(query):
251 try:
251 try:
252 ctx = scmutil.revsymbol(web.repo, query)
252 ctx = scmutil.revsymbol(web.repo, query)
253 except (error.RepoError, error.LookupError):
253 except (error.RepoError, error.LookupError):
254 # query is not an exact revision pointer, need to
254 # query is not an exact revision pointer, need to
255 # decide if it's a revset expression or keywords
255 # decide if it's a revset expression or keywords
256 pass
256 pass
257 else:
257 else:
258 return MODE_REVISION, ctx
258 return MODE_REVISION, ctx
259
259
260 revdef = 'reverse(%s)' % query
260 revdef = 'reverse(%s)' % query
261 try:
261 try:
262 tree = revsetlang.parse(revdef)
262 tree = revsetlang.parse(revdef)
263 except error.ParseError:
263 except error.ParseError:
264 # can't parse to a revset tree
264 # can't parse to a revset tree
265 return MODE_KEYWORD, query
265 return MODE_KEYWORD, query
266
266
267 if revsetlang.depth(tree) <= 2:
267 if revsetlang.depth(tree) <= 2:
268 # no revset syntax used
268 # no revset syntax used
269 return MODE_KEYWORD, query
269 return MODE_KEYWORD, query
270
270
271 if any((token, (value or '')[:3]) == ('string', 're:')
271 if any((token, (value or '')[:3]) == ('string', 're:')
272 for token, value, pos in revsetlang.tokenize(revdef)):
272 for token, value, pos in revsetlang.tokenize(revdef)):
273 return MODE_KEYWORD, query
273 return MODE_KEYWORD, query
274
274
275 funcsused = revsetlang.funcsused(tree)
275 funcsused = revsetlang.funcsused(tree)
276 if not funcsused.issubset(revset.safesymbols):
276 if not funcsused.issubset(revset.safesymbols):
277 return MODE_KEYWORD, query
277 return MODE_KEYWORD, query
278
278
279 mfunc = revset.match(web.repo.ui, revdef, repo=web.repo)
279 mfunc = revset.match(web.repo.ui, revdef, repo=web.repo)
280 try:
280 try:
281 revs = mfunc(web.repo)
281 revs = mfunc(web.repo)
282 return MODE_REVSET, revs
282 return MODE_REVSET, revs
283 # ParseError: wrongly placed tokens, wrongs arguments, etc
283 # ParseError: wrongly placed tokens, wrongs arguments, etc
284 # RepoLookupError: no such revision, e.g. in 'revision:'
284 # RepoLookupError: no such revision, e.g. in 'revision:'
285 # Abort: bookmark/tag not exists
285 # Abort: bookmark/tag not exists
286 # LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo
286 # LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo
287 except (error.ParseError, error.RepoLookupError, error.Abort,
287 except (error.ParseError, error.RepoLookupError, error.Abort,
288 LookupError):
288 LookupError):
289 return MODE_KEYWORD, query
289 return MODE_KEYWORD, query
290
290
291 def changelist(context):
291 def changelist(context):
292 count = 0
292 count = 0
293
293
294 for ctx in searchfunc[0](funcarg):
294 for ctx in searchfunc[0](funcarg):
295 count += 1
295 count += 1
296 n = ctx.node()
296 n = ctx.node()
297 showtags = webutil.showtag(web.repo, web.tmpl, 'changelogtag', n)
297 showtags = webutil.showtag(web.repo, web.tmpl, 'changelogtag', n)
298 files = webutil.listfilediffs(web.tmpl, ctx.files(), n,
298 files = webutil.listfilediffs(web.tmpl, ctx.files(), n,
299 web.maxfiles)
299 web.maxfiles)
300
300
301 lm = webutil.commonentry(web.repo, ctx)
301 lm = webutil.commonentry(web.repo, ctx)
302 lm.update({
302 lm.update({
303 'parity': next(parity),
303 'parity': next(parity),
304 'changelogtag': showtags,
304 'changelogtag': showtags,
305 'files': files,
305 'files': files,
306 })
306 })
307 yield lm
307 yield lm
308
308
309 if count >= revcount:
309 if count >= revcount:
310 break
310 break
311
311
312 query = web.req.qsparams['rev']
312 query = web.req.qsparams['rev']
313 revcount = web.maxchanges
313 revcount = web.maxchanges
314 if 'revcount' in web.req.qsparams:
314 if 'revcount' in web.req.qsparams:
315 try:
315 try:
316 revcount = int(web.req.qsparams.get('revcount', revcount))
316 revcount = int(web.req.qsparams.get('revcount', revcount))
317 revcount = max(revcount, 1)
317 revcount = max(revcount, 1)
318 web.tmpl.defaults['sessionvars']['revcount'] = revcount
318 web.tmpl.defaults['sessionvars']['revcount'] = revcount
319 except ValueError:
319 except ValueError:
320 pass
320 pass
321
321
322 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
322 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
323 lessvars['revcount'] = max(revcount // 2, 1)
323 lessvars['revcount'] = max(revcount // 2, 1)
324 lessvars['rev'] = query
324 lessvars['rev'] = query
325 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
325 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
326 morevars['revcount'] = revcount * 2
326 morevars['revcount'] = revcount * 2
327 morevars['rev'] = query
327 morevars['rev'] = query
328
328
329 mode, funcarg = getsearchmode(query)
329 mode, funcarg = getsearchmode(query)
330
330
331 if 'forcekw' in web.req.qsparams:
331 if 'forcekw' in web.req.qsparams:
332 showforcekw = ''
332 showforcekw = ''
333 showunforcekw = searchfuncs[mode][1]
333 showunforcekw = searchfuncs[mode][1]
334 mode = MODE_KEYWORD
334 mode = MODE_KEYWORD
335 funcarg = query
335 funcarg = query
336 else:
336 else:
337 if mode != MODE_KEYWORD:
337 if mode != MODE_KEYWORD:
338 showforcekw = searchfuncs[MODE_KEYWORD][1]
338 showforcekw = searchfuncs[MODE_KEYWORD][1]
339 else:
339 else:
340 showforcekw = ''
340 showforcekw = ''
341 showunforcekw = ''
341 showunforcekw = ''
342
342
343 searchfunc = searchfuncs[mode]
343 searchfunc = searchfuncs[mode]
344
344
345 tip = web.repo['tip']
345 tip = web.repo['tip']
346 parity = paritygen(web.stripecount)
346 parity = paritygen(web.stripecount)
347
347
348 return web.sendtemplate(
348 return web.sendtemplate(
349 'search',
349 'search',
350 query=query,
350 query=query,
351 node=tip.hex(),
351 node=tip.hex(),
352 symrev='tip',
352 symrev='tip',
353 entries=templateutil.mappinggenerator(changelist, name='searchentry'),
353 entries=templateutil.mappinggenerator(changelist, name='searchentry'),
354 archives=web.archivelist('tip'),
354 archives=web.archivelist('tip'),
355 morevars=morevars,
355 morevars=morevars,
356 lessvars=lessvars,
356 lessvars=lessvars,
357 modedesc=searchfunc[1],
357 modedesc=searchfunc[1],
358 showforcekw=showforcekw,
358 showforcekw=showforcekw,
359 showunforcekw=showunforcekw)
359 showunforcekw=showunforcekw)
360
360
361 @webcommand('changelog')
361 @webcommand('changelog')
362 def changelog(web, shortlog=False):
362 def changelog(web, shortlog=False):
363 """
363 """
364 /changelog[/{revision}]
364 /changelog[/{revision}]
365 -----------------------
365 -----------------------
366
366
367 Show information about multiple changesets.
367 Show information about multiple changesets.
368
368
369 If the optional ``revision`` URL argument is absent, information about
369 If the optional ``revision`` URL argument is absent, information about
370 all changesets starting at ``tip`` will be rendered. If the ``revision``
370 all changesets starting at ``tip`` will be rendered. If the ``revision``
371 argument is present, changesets will be shown starting from the specified
371 argument is present, changesets will be shown starting from the specified
372 revision.
372 revision.
373
373
374 If ``revision`` is absent, the ``rev`` query string argument may be
374 If ``revision`` is absent, the ``rev`` query string argument may be
375 defined. This will perform a search for changesets.
375 defined. This will perform a search for changesets.
376
376
377 The argument for ``rev`` can be a single revision, a revision set,
377 The argument for ``rev`` can be a single revision, a revision set,
378 or a literal keyword to search for in changeset data (equivalent to
378 or a literal keyword to search for in changeset data (equivalent to
379 :hg:`log -k`).
379 :hg:`log -k`).
380
380
381 The ``revcount`` query string argument defines the maximum numbers of
381 The ``revcount`` query string argument defines the maximum numbers of
382 changesets to render.
382 changesets to render.
383
383
384 For non-searches, the ``changelog`` template will be rendered.
384 For non-searches, the ``changelog`` template will be rendered.
385 """
385 """
386
386
387 query = ''
387 query = ''
388 if 'node' in web.req.qsparams:
388 if 'node' in web.req.qsparams:
389 ctx = webutil.changectx(web.repo, web.req)
389 ctx = webutil.changectx(web.repo, web.req)
390 symrev = webutil.symrevorshortnode(web.req, ctx)
390 symrev = webutil.symrevorshortnode(web.req, ctx)
391 elif 'rev' in web.req.qsparams:
391 elif 'rev' in web.req.qsparams:
392 return _search(web)
392 return _search(web)
393 else:
393 else:
394 ctx = web.repo['tip']
394 ctx = web.repo['tip']
395 symrev = 'tip'
395 symrev = 'tip'
396
396
397 def changelist():
397 def changelist():
398 revs = []
398 revs = []
399 if pos != -1:
399 if pos != -1:
400 revs = web.repo.changelog.revs(pos, 0)
400 revs = web.repo.changelog.revs(pos, 0)
401 curcount = 0
401 curcount = 0
402 for rev in revs:
402 for rev in revs:
403 curcount += 1
403 curcount += 1
404 if curcount > revcount + 1:
404 if curcount > revcount + 1:
405 break
405 break
406
406
407 entry = webutil.changelistentry(web, web.repo[rev])
407 entry = webutil.changelistentry(web, web.repo[rev])
408 entry['parity'] = next(parity)
408 entry['parity'] = next(parity)
409 yield entry
409 yield entry
410
410
411 if shortlog:
411 if shortlog:
412 revcount = web.maxshortchanges
412 revcount = web.maxshortchanges
413 else:
413 else:
414 revcount = web.maxchanges
414 revcount = web.maxchanges
415
415
416 if 'revcount' in web.req.qsparams:
416 if 'revcount' in web.req.qsparams:
417 try:
417 try:
418 revcount = int(web.req.qsparams.get('revcount', revcount))
418 revcount = int(web.req.qsparams.get('revcount', revcount))
419 revcount = max(revcount, 1)
419 revcount = max(revcount, 1)
420 web.tmpl.defaults['sessionvars']['revcount'] = revcount
420 web.tmpl.defaults['sessionvars']['revcount'] = revcount
421 except ValueError:
421 except ValueError:
422 pass
422 pass
423
423
424 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
424 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
425 lessvars['revcount'] = max(revcount // 2, 1)
425 lessvars['revcount'] = max(revcount // 2, 1)
426 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
426 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
427 morevars['revcount'] = revcount * 2
427 morevars['revcount'] = revcount * 2
428
428
429 count = len(web.repo)
429 count = len(web.repo)
430 pos = ctx.rev()
430 pos = ctx.rev()
431 parity = paritygen(web.stripecount)
431 parity = paritygen(web.stripecount)
432
432
433 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
433 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
434
434
435 entries = list(changelist())
435 entries = list(changelist())
436 latestentry = entries[:1]
436 latestentry = entries[:1]
437 if len(entries) > revcount:
437 if len(entries) > revcount:
438 nextentry = entries[-1:]
438 nextentry = entries[-1:]
439 entries = entries[:-1]
439 entries = entries[:-1]
440 else:
440 else:
441 nextentry = []
441 nextentry = []
442
442
443 return web.sendtemplate(
443 return web.sendtemplate(
444 'shortlog' if shortlog else 'changelog',
444 'shortlog' if shortlog else 'changelog',
445 changenav=changenav,
445 changenav=changenav,
446 node=ctx.hex(),
446 node=ctx.hex(),
447 rev=pos,
447 rev=pos,
448 symrev=symrev,
448 symrev=symrev,
449 changesets=count,
449 changesets=count,
450 entries=entries,
450 entries=entries,
451 latestentry=latestentry,
451 latestentry=latestentry,
452 nextentry=nextentry,
452 nextentry=nextentry,
453 archives=web.archivelist('tip'),
453 archives=web.archivelist('tip'),
454 revcount=revcount,
454 revcount=revcount,
455 morevars=morevars,
455 morevars=morevars,
456 lessvars=lessvars,
456 lessvars=lessvars,
457 query=query)
457 query=query)
458
458
459 @webcommand('shortlog')
459 @webcommand('shortlog')
460 def shortlog(web):
460 def shortlog(web):
461 """
461 """
462 /shortlog
462 /shortlog
463 ---------
463 ---------
464
464
465 Show basic information about a set of changesets.
465 Show basic information about a set of changesets.
466
466
467 This accepts the same parameters as the ``changelog`` handler. The only
467 This accepts the same parameters as the ``changelog`` handler. The only
468 difference is the ``shortlog`` template will be rendered instead of the
468 difference is the ``shortlog`` template will be rendered instead of the
469 ``changelog`` template.
469 ``changelog`` template.
470 """
470 """
471 return changelog(web, shortlog=True)
471 return changelog(web, shortlog=True)
472
472
473 @webcommand('changeset')
473 @webcommand('changeset')
474 def changeset(web):
474 def changeset(web):
475 """
475 """
476 /changeset[/{revision}]
476 /changeset[/{revision}]
477 -----------------------
477 -----------------------
478
478
479 Show information about a single changeset.
479 Show information about a single changeset.
480
480
481 A URL path argument is the changeset identifier to show. See ``hg help
481 A URL path argument is the changeset identifier to show. See ``hg help
482 revisions`` for possible values. If not defined, the ``tip`` changeset
482 revisions`` for possible values. If not defined, the ``tip`` changeset
483 will be shown.
483 will be shown.
484
484
485 The ``changeset`` template is rendered. Contents of the ``changesettag``,
485 The ``changeset`` template is rendered. Contents of the ``changesettag``,
486 ``changesetbookmark``, ``filenodelink``, ``filenolink``, and the many
486 ``changesetbookmark``, ``filenodelink``, ``filenolink``, and the many
487 templates related to diffs may all be used to produce the output.
487 templates related to diffs may all be used to produce the output.
488 """
488 """
489 ctx = webutil.changectx(web.repo, web.req)
489 ctx = webutil.changectx(web.repo, web.req)
490
490
491 return web.sendtemplate(
491 return web.sendtemplate(
492 'changeset',
492 'changeset',
493 **webutil.changesetentry(web, ctx))
493 **webutil.changesetentry(web, ctx))
494
494
495 rev = webcommand('rev')(changeset)
495 rev = webcommand('rev')(changeset)
496
496
497 def decodepath(path):
497 def decodepath(path):
498 """Hook for mapping a path in the repository to a path in the
498 """Hook for mapping a path in the repository to a path in the
499 working copy.
499 working copy.
500
500
501 Extensions (e.g., largefiles) can override this to remap files in
501 Extensions (e.g., largefiles) can override this to remap files in
502 the virtual file system presented by the manifest command below."""
502 the virtual file system presented by the manifest command below."""
503 return path
503 return path
504
504
505 @webcommand('manifest')
505 @webcommand('manifest')
506 def manifest(web):
506 def manifest(web):
507 """
507 """
508 /manifest[/{revision}[/{path}]]
508 /manifest[/{revision}[/{path}]]
509 -------------------------------
509 -------------------------------
510
510
511 Show information about a directory.
511 Show information about a directory.
512
512
513 If the URL path arguments are omitted, information about the root
513 If the URL path arguments are omitted, information about the root
514 directory for the ``tip`` changeset will be shown.
514 directory for the ``tip`` changeset will be shown.
515
515
516 Because this handler can only show information for directories, it
516 Because this handler can only show information for directories, it
517 is recommended to use the ``file`` handler instead, as it can handle both
517 is recommended to use the ``file`` handler instead, as it can handle both
518 directories and files.
518 directories and files.
519
519
520 The ``manifest`` template will be rendered for this handler.
520 The ``manifest`` template will be rendered for this handler.
521 """
521 """
522 if 'node' in web.req.qsparams:
522 if 'node' in web.req.qsparams:
523 ctx = webutil.changectx(web.repo, web.req)
523 ctx = webutil.changectx(web.repo, web.req)
524 symrev = webutil.symrevorshortnode(web.req, ctx)
524 symrev = webutil.symrevorshortnode(web.req, ctx)
525 else:
525 else:
526 ctx = web.repo['tip']
526 ctx = web.repo['tip']
527 symrev = 'tip'
527 symrev = 'tip'
528 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
528 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
529 mf = ctx.manifest()
529 mf = ctx.manifest()
530 node = ctx.node()
530 node = ctx.node()
531
531
532 files = {}
532 files = {}
533 dirs = {}
533 dirs = {}
534 parity = paritygen(web.stripecount)
534 parity = paritygen(web.stripecount)
535
535
536 if path and path[-1:] != "/":
536 if path and path[-1:] != "/":
537 path += "/"
537 path += "/"
538 l = len(path)
538 l = len(path)
539 abspath = "/" + path
539 abspath = "/" + path
540
540
541 for full, n in mf.iteritems():
541 for full, n in mf.iteritems():
542 # the virtual path (working copy path) used for the full
542 # the virtual path (working copy path) used for the full
543 # (repository) path
543 # (repository) path
544 f = decodepath(full)
544 f = decodepath(full)
545
545
546 if f[:l] != path:
546 if f[:l] != path:
547 continue
547 continue
548 remain = f[l:]
548 remain = f[l:]
549 elements = remain.split('/')
549 elements = remain.split('/')
550 if len(elements) == 1:
550 if len(elements) == 1:
551 files[remain] = full
551 files[remain] = full
552 else:
552 else:
553 h = dirs # need to retain ref to dirs (root)
553 h = dirs # need to retain ref to dirs (root)
554 for elem in elements[0:-1]:
554 for elem in elements[0:-1]:
555 if elem not in h:
555 if elem not in h:
556 h[elem] = {}
556 h[elem] = {}
557 h = h[elem]
557 h = h[elem]
558 if len(h) > 1:
558 if len(h) > 1:
559 break
559 break
560 h[None] = None # denotes files present
560 h[None] = None # denotes files present
561
561
562 if mf and not files and not dirs:
562 if mf and not files and not dirs:
563 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
563 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
564
564
565 def filelist(**map):
565 def filelist(**map):
566 for f in sorted(files):
566 for f in sorted(files):
567 full = files[f]
567 full = files[f]
568
568
569 fctx = ctx.filectx(full)
569 fctx = ctx.filectx(full)
570 yield {"file": full,
570 yield {"file": full,
571 "parity": next(parity),
571 "parity": next(parity),
572 "basename": f,
572 "basename": f,
573 "date": fctx.date(),
573 "date": fctx.date(),
574 "size": fctx.size(),
574 "size": fctx.size(),
575 "permissions": mf.flags(full)}
575 "permissions": mf.flags(full)}
576
576
577 def dirlist(**map):
577 def dirlist(**map):
578 for d in sorted(dirs):
578 for d in sorted(dirs):
579
579
580 emptydirs = []
580 emptydirs = []
581 h = dirs[d]
581 h = dirs[d]
582 while isinstance(h, dict) and len(h) == 1:
582 while isinstance(h, dict) and len(h) == 1:
583 k, v = next(iter(h.items()))
583 k, v = next(iter(h.items()))
584 if v:
584 if v:
585 emptydirs.append(k)
585 emptydirs.append(k)
586 h = v
586 h = v
587
587
588 path = "%s%s" % (abspath, d)
588 path = "%s%s" % (abspath, d)
589 yield {"parity": next(parity),
589 yield {"parity": next(parity),
590 "path": path,
590 "path": path,
591 "emptydirs": "/".join(emptydirs),
591 "emptydirs": "/".join(emptydirs),
592 "basename": d}
592 "basename": d}
593
593
594 return web.sendtemplate(
594 return web.sendtemplate(
595 'manifest',
595 'manifest',
596 symrev=symrev,
596 symrev=symrev,
597 path=abspath,
597 path=abspath,
598 up=webutil.up(abspath),
598 up=webutil.up(abspath),
599 upparity=next(parity),
599 upparity=next(parity),
600 fentries=filelist,
600 fentries=filelist,
601 dentries=dirlist,
601 dentries=dirlist,
602 archives=web.archivelist(hex(node)),
602 archives=web.archivelist(hex(node)),
603 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
603 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
604
604
605 @webcommand('tags')
605 @webcommand('tags')
606 def tags(web):
606 def tags(web):
607 """
607 """
608 /tags
608 /tags
609 -----
609 -----
610
610
611 Show information about tags.
611 Show information about tags.
612
612
613 No arguments are accepted.
613 No arguments are accepted.
614
614
615 The ``tags`` template is rendered.
615 The ``tags`` template is rendered.
616 """
616 """
617 i = list(reversed(web.repo.tagslist()))
617 i = list(reversed(web.repo.tagslist()))
618 parity = paritygen(web.stripecount)
618 parity = paritygen(web.stripecount)
619
619
620 def entries(notip, latestonly, **map):
620 def entries(notip, latestonly, **map):
621 t = i
621 t = i
622 if notip:
622 if notip:
623 t = [(k, n) for k, n in i if k != "tip"]
623 t = [(k, n) for k, n in i if k != "tip"]
624 if latestonly:
624 if latestonly:
625 t = t[:1]
625 t = t[:1]
626 for k, n in t:
626 for k, n in t:
627 yield {"parity": next(parity),
627 yield {"parity": next(parity),
628 "tag": k,
628 "tag": k,
629 "date": web.repo[n].date(),
629 "date": web.repo[n].date(),
630 "node": hex(n)}
630 "node": hex(n)}
631
631
632 return web.sendtemplate(
632 return web.sendtemplate(
633 'tags',
633 'tags',
634 node=hex(web.repo.changelog.tip()),
634 node=hex(web.repo.changelog.tip()),
635 entries=lambda **x: entries(False, False, **x),
635 entries=lambda **x: entries(False, False, **x),
636 entriesnotip=lambda **x: entries(True, False, **x),
636 entriesnotip=lambda **x: entries(True, False, **x),
637 latestentry=lambda **x: entries(True, True, **x))
637 latestentry=lambda **x: entries(True, True, **x))
638
638
639 @webcommand('bookmarks')
639 @webcommand('bookmarks')
640 def bookmarks(web):
640 def bookmarks(web):
641 """
641 """
642 /bookmarks
642 /bookmarks
643 ----------
643 ----------
644
644
645 Show information about bookmarks.
645 Show information about bookmarks.
646
646
647 No arguments are accepted.
647 No arguments are accepted.
648
648
649 The ``bookmarks`` template is rendered.
649 The ``bookmarks`` template is rendered.
650 """
650 """
651 i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
651 i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
652 sortkey = lambda b: (web.repo[b[1]].rev(), b[0])
652 sortkey = lambda b: (web.repo[b[1]].rev(), b[0])
653 i = sorted(i, key=sortkey, reverse=True)
653 i = sorted(i, key=sortkey, reverse=True)
654 parity = paritygen(web.stripecount)
654 parity = paritygen(web.stripecount)
655
655
656 def entries(latestonly, **map):
656 def entries(latestonly, **map):
657 t = i
657 t = i
658 if latestonly:
658 if latestonly:
659 t = i[:1]
659 t = i[:1]
660 for k, n in t:
660 for k, n in t:
661 yield {"parity": next(parity),
661 yield {"parity": next(parity),
662 "bookmark": k,
662 "bookmark": k,
663 "date": web.repo[n].date(),
663 "date": web.repo[n].date(),
664 "node": hex(n)}
664 "node": hex(n)}
665
665
666 if i:
666 if i:
667 latestrev = i[0][1]
667 latestrev = i[0][1]
668 else:
668 else:
669 latestrev = -1
669 latestrev = -1
670
670
671 return web.sendtemplate(
671 return web.sendtemplate(
672 'bookmarks',
672 'bookmarks',
673 node=hex(web.repo.changelog.tip()),
673 node=hex(web.repo.changelog.tip()),
674 lastchange=[{'date': web.repo[latestrev].date()}],
674 lastchange=[{'date': web.repo[latestrev].date()}],
675 entries=lambda **x: entries(latestonly=False, **x),
675 entries=lambda **x: entries(latestonly=False, **x),
676 latestentry=lambda **x: entries(latestonly=True, **x))
676 latestentry=lambda **x: entries(latestonly=True, **x))
677
677
678 @webcommand('branches')
678 @webcommand('branches')
679 def branches(web):
679 def branches(web):
680 """
680 """
681 /branches
681 /branches
682 ---------
682 ---------
683
683
684 Show information about branches.
684 Show information about branches.
685
685
686 All known branches are contained in the output, even closed branches.
686 All known branches are contained in the output, even closed branches.
687
687
688 No arguments are accepted.
688 No arguments are accepted.
689
689
690 The ``branches`` template is rendered.
690 The ``branches`` template is rendered.
691 """
691 """
692 entries = webutil.branchentries(web.repo, web.stripecount)
692 entries = webutil.branchentries(web.repo, web.stripecount)
693 latestentry = webutil.branchentries(web.repo, web.stripecount, 1)
693 latestentry = webutil.branchentries(web.repo, web.stripecount, 1)
694
694
695 return web.sendtemplate(
695 return web.sendtemplate(
696 'branches',
696 'branches',
697 node=hex(web.repo.changelog.tip()),
697 node=hex(web.repo.changelog.tip()),
698 entries=entries,
698 entries=entries,
699 latestentry=latestentry)
699 latestentry=latestentry)
700
700
701 @webcommand('summary')
701 @webcommand('summary')
702 def summary(web):
702 def summary(web):
703 """
703 """
704 /summary
704 /summary
705 --------
705 --------
706
706
707 Show a summary of repository state.
707 Show a summary of repository state.
708
708
709 Information about the latest changesets, bookmarks, tags, and branches
709 Information about the latest changesets, bookmarks, tags, and branches
710 is captured by this handler.
710 is captured by this handler.
711
711
712 The ``summary`` template is rendered.
712 The ``summary`` template is rendered.
713 """
713 """
714 i = reversed(web.repo.tagslist())
714 i = reversed(web.repo.tagslist())
715
715
716 def tagentries(context):
716 def tagentries(context):
717 parity = paritygen(web.stripecount)
717 parity = paritygen(web.stripecount)
718 count = 0
718 count = 0
719 for k, n in i:
719 for k, n in i:
720 if k == "tip": # skip tip
720 if k == "tip": # skip tip
721 continue
721 continue
722
722
723 count += 1
723 count += 1
724 if count > 10: # limit to 10 tags
724 if count > 10: # limit to 10 tags
725 break
725 break
726
726
727 yield {
727 yield {
728 'parity': next(parity),
728 'parity': next(parity),
729 'tag': k,
729 'tag': k,
730 'node': hex(n),
730 'node': hex(n),
731 'date': web.repo[n].date(),
731 'date': web.repo[n].date(),
732 }
732 }
733
733
734 def bookmarks(**map):
734 def bookmarks(**map):
735 parity = paritygen(web.stripecount)
735 parity = paritygen(web.stripecount)
736 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
736 marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
737 sortkey = lambda b: (web.repo[b[1]].rev(), b[0])
737 sortkey = lambda b: (web.repo[b[1]].rev(), b[0])
738 marks = sorted(marks, key=sortkey, reverse=True)
738 marks = sorted(marks, key=sortkey, reverse=True)
739 for k, n in marks[:10]: # limit to 10 bookmarks
739 for k, n in marks[:10]: # limit to 10 bookmarks
740 yield {'parity': next(parity),
740 yield {'parity': next(parity),
741 'bookmark': k,
741 'bookmark': k,
742 'date': web.repo[n].date(),
742 'date': web.repo[n].date(),
743 'node': hex(n)}
743 'node': hex(n)}
744
744
745 def changelist(context):
745 def changelist(context):
746 parity = paritygen(web.stripecount, offset=start - end)
746 parity = paritygen(web.stripecount, offset=start - end)
747 l = [] # build a list in forward order for efficiency
747 l = [] # build a list in forward order for efficiency
748 revs = []
748 revs = []
749 if start < end:
749 if start < end:
750 revs = web.repo.changelog.revs(start, end - 1)
750 revs = web.repo.changelog.revs(start, end - 1)
751 for i in revs:
751 for i in revs:
752 ctx = web.repo[i]
752 ctx = web.repo[i]
753 lm = webutil.commonentry(web.repo, ctx)
753 lm = webutil.commonentry(web.repo, ctx)
754 lm['parity'] = next(parity)
754 lm['parity'] = next(parity)
755 l.append(lm)
755 l.append(lm)
756
756
757 for entry in reversed(l):
757 for entry in reversed(l):
758 yield entry
758 yield entry
759
759
760 tip = web.repo['tip']
760 tip = web.repo['tip']
761 count = len(web.repo)
761 count = len(web.repo)
762 start = max(0, count - web.maxchanges)
762 start = max(0, count - web.maxchanges)
763 end = min(count, start + web.maxchanges)
763 end = min(count, start + web.maxchanges)
764
764
765 desc = web.config("web", "description")
765 desc = web.config("web", "description")
766 if not desc:
766 if not desc:
767 desc = 'unknown'
767 desc = 'unknown'
768
768
769 return web.sendtemplate(
769 return web.sendtemplate(
770 'summary',
770 'summary',
771 desc=desc,
771 desc=desc,
772 owner=get_contact(web.config) or 'unknown',
772 owner=get_contact(web.config) or 'unknown',
773 lastchange=tip.date(),
773 lastchange=tip.date(),
774 tags=templateutil.mappinggenerator(tagentries, name='tagentry'),
774 tags=templateutil.mappinggenerator(tagentries, name='tagentry'),
775 bookmarks=bookmarks,
775 bookmarks=bookmarks,
776 branches=webutil.branchentries(web.repo, web.stripecount, 10),
776 branches=webutil.branchentries(web.repo, web.stripecount, 10),
777 shortlog=templateutil.mappinggenerator(changelist,
777 shortlog=templateutil.mappinggenerator(changelist,
778 name='shortlogentry'),
778 name='shortlogentry'),
779 node=tip.hex(),
779 node=tip.hex(),
780 symrev='tip',
780 symrev='tip',
781 archives=web.archivelist('tip'),
781 archives=web.archivelist('tip'),
782 labels=web.configlist('web', 'labels'))
782 labels=web.configlist('web', 'labels'))
783
783
784 @webcommand('filediff')
784 @webcommand('filediff')
785 def filediff(web):
785 def filediff(web):
786 """
786 """
787 /diff/{revision}/{path}
787 /diff/{revision}/{path}
788 -----------------------
788 -----------------------
789
789
790 Show how a file changed in a particular commit.
790 Show how a file changed in a particular commit.
791
791
792 The ``filediff`` template is rendered.
792 The ``filediff`` template is rendered.
793
793
794 This handler is registered under both the ``/diff`` and ``/filediff``
794 This handler is registered under both the ``/diff`` and ``/filediff``
795 paths. ``/diff`` is used in modern code.
795 paths. ``/diff`` is used in modern code.
796 """
796 """
797 fctx, ctx = None, None
797 fctx, ctx = None, None
798 try:
798 try:
799 fctx = webutil.filectx(web.repo, web.req)
799 fctx = webutil.filectx(web.repo, web.req)
800 except LookupError:
800 except LookupError:
801 ctx = webutil.changectx(web.repo, web.req)
801 ctx = webutil.changectx(web.repo, web.req)
802 path = webutil.cleanpath(web.repo, web.req.qsparams['file'])
802 path = webutil.cleanpath(web.repo, web.req.qsparams['file'])
803 if path not in ctx.files():
803 if path not in ctx.files():
804 raise
804 raise
805
805
806 if fctx is not None:
806 if fctx is not None:
807 path = fctx.path()
807 path = fctx.path()
808 ctx = fctx.changectx()
808 ctx = fctx.changectx()
809 basectx = ctx.p1()
809 basectx = ctx.p1()
810
810
811 style = web.config('web', 'style')
811 style = web.config('web', 'style')
812 if 'style' in web.req.qsparams:
812 if 'style' in web.req.qsparams:
813 style = web.req.qsparams['style']
813 style = web.req.qsparams['style']
814
814
815 diffs = webutil.diffs(web, ctx, basectx, [path], style)
815 diffs = webutil.diffs(web, ctx, basectx, [path], style)
816 if fctx is not None:
816 if fctx is not None:
817 rename = webutil.renamelink(fctx)
817 rename = webutil.renamelink(fctx)
818 ctx = fctx
818 ctx = fctx
819 else:
819 else:
820 rename = []
820 rename = []
821 ctx = ctx
821 ctx = ctx
822
822
823 return web.sendtemplate(
823 return web.sendtemplate(
824 'filediff',
824 'filediff',
825 file=path,
825 file=path,
826 symrev=webutil.symrevorshortnode(web.req, ctx),
826 symrev=webutil.symrevorshortnode(web.req, ctx),
827 rename=rename,
827 rename=rename,
828 diff=diffs,
828 diff=diffs,
829 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
829 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
830
830
831 diff = webcommand('diff')(filediff)
831 diff = webcommand('diff')(filediff)
832
832
833 @webcommand('comparison')
833 @webcommand('comparison')
834 def comparison(web):
834 def comparison(web):
835 """
835 """
836 /comparison/{revision}/{path}
836 /comparison/{revision}/{path}
837 -----------------------------
837 -----------------------------
838
838
839 Show a comparison between the old and new versions of a file from changes
839 Show a comparison between the old and new versions of a file from changes
840 made on a particular revision.
840 made on a particular revision.
841
841
842 This is similar to the ``diff`` handler. However, this form features
842 This is similar to the ``diff`` handler. However, this form features
843 a split or side-by-side diff rather than a unified diff.
843 a split or side-by-side diff rather than a unified diff.
844
844
845 The ``context`` query string argument can be used to control the lines of
845 The ``context`` query string argument can be used to control the lines of
846 context in the diff.
846 context in the diff.
847
847
848 The ``filecomparison`` template is rendered.
848 The ``filecomparison`` template is rendered.
849 """
849 """
850 ctx = webutil.changectx(web.repo, web.req)
850 ctx = webutil.changectx(web.repo, web.req)
851 if 'file' not in web.req.qsparams:
851 if 'file' not in web.req.qsparams:
852 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
852 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
853 path = webutil.cleanpath(web.repo, web.req.qsparams['file'])
853 path = webutil.cleanpath(web.repo, web.req.qsparams['file'])
854
854
855 parsecontext = lambda v: v == 'full' and -1 or int(v)
855 parsecontext = lambda v: v == 'full' and -1 or int(v)
856 if 'context' in web.req.qsparams:
856 if 'context' in web.req.qsparams:
857 context = parsecontext(web.req.qsparams['context'])
857 context = parsecontext(web.req.qsparams['context'])
858 else:
858 else:
859 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
859 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
860
860
861 def filelines(f):
861 def filelines(f):
862 if f.isbinary():
862 if f.isbinary():
863 mt = mimetypes.guess_type(f.path())[0]
863 mt = mimetypes.guess_type(f.path())[0]
864 if not mt:
864 if not mt:
865 mt = 'application/octet-stream'
865 mt = 'application/octet-stream'
866 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
866 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
867 return f.data().splitlines()
867 return f.data().splitlines()
868
868
869 fctx = None
869 fctx = None
870 parent = ctx.p1()
870 parent = ctx.p1()
871 leftrev = parent.rev()
871 leftrev = parent.rev()
872 leftnode = parent.node()
872 leftnode = parent.node()
873 rightrev = ctx.rev()
873 rightrev = ctx.rev()
874 rightnode = ctx.node()
874 rightnode = ctx.node()
875 if path in ctx:
875 if path in ctx:
876 fctx = ctx[path]
876 fctx = ctx[path]
877 rightlines = filelines(fctx)
877 rightlines = filelines(fctx)
878 if path not in parent:
878 if path not in parent:
879 leftlines = ()
879 leftlines = ()
880 else:
880 else:
881 pfctx = parent[path]
881 pfctx = parent[path]
882 leftlines = filelines(pfctx)
882 leftlines = filelines(pfctx)
883 else:
883 else:
884 rightlines = ()
884 rightlines = ()
885 pfctx = ctx.parents()[0][path]
885 pfctx = ctx.parents()[0][path]
886 leftlines = filelines(pfctx)
886 leftlines = filelines(pfctx)
887
887
888 comparison = webutil.compare(web.tmpl, context, leftlines, rightlines)
888 comparison = webutil.compare(web.tmpl, context, leftlines, rightlines)
889 if fctx is not None:
889 if fctx is not None:
890 rename = webutil.renamelink(fctx)
890 rename = webutil.renamelink(fctx)
891 ctx = fctx
891 ctx = fctx
892 else:
892 else:
893 rename = []
893 rename = []
894 ctx = ctx
894 ctx = ctx
895
895
896 return web.sendtemplate(
896 return web.sendtemplate(
897 'filecomparison',
897 'filecomparison',
898 file=path,
898 file=path,
899 symrev=webutil.symrevorshortnode(web.req, ctx),
899 symrev=webutil.symrevorshortnode(web.req, ctx),
900 rename=rename,
900 rename=rename,
901 leftrev=leftrev,
901 leftrev=leftrev,
902 leftnode=hex(leftnode),
902 leftnode=hex(leftnode),
903 rightrev=rightrev,
903 rightrev=rightrev,
904 rightnode=hex(rightnode),
904 rightnode=hex(rightnode),
905 comparison=comparison,
905 comparison=comparison,
906 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
906 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
907
907
908 @webcommand('annotate')
908 @webcommand('annotate')
909 def annotate(web):
909 def annotate(web):
910 """
910 """
911 /annotate/{revision}/{path}
911 /annotate/{revision}/{path}
912 ---------------------------
912 ---------------------------
913
913
914 Show changeset information for each line in a file.
914 Show changeset information for each line in a file.
915
915
916 The ``ignorews``, ``ignorewsamount``, ``ignorewseol``, and
916 The ``ignorews``, ``ignorewsamount``, ``ignorewseol``, and
917 ``ignoreblanklines`` query string arguments have the same meaning as
917 ``ignoreblanklines`` query string arguments have the same meaning as
918 their ``[annotate]`` config equivalents. It uses the hgrc boolean
918 their ``[annotate]`` config equivalents. It uses the hgrc boolean
919 parsing logic to interpret the value. e.g. ``0`` and ``false`` are
919 parsing logic to interpret the value. e.g. ``0`` and ``false`` are
920 false and ``1`` and ``true`` are true. If not defined, the server
920 false and ``1`` and ``true`` are true. If not defined, the server
921 default settings are used.
921 default settings are used.
922
922
923 The ``fileannotate`` template is rendered.
923 The ``fileannotate`` template is rendered.
924 """
924 """
925 fctx = webutil.filectx(web.repo, web.req)
925 fctx = webutil.filectx(web.repo, web.req)
926 f = fctx.path()
926 f = fctx.path()
927 parity = paritygen(web.stripecount)
927 parity = paritygen(web.stripecount)
928 ishead = fctx.filerev() in fctx.filelog().headrevs()
928 ishead = fctx.filerev() in fctx.filelog().headrevs()
929
929
930 # parents() is called once per line and several lines likely belong to
930 # parents() is called once per line and several lines likely belong to
931 # same revision. So it is worth caching.
931 # same revision. So it is worth caching.
932 # TODO there are still redundant operations within basefilectx.parents()
932 # TODO there are still redundant operations within basefilectx.parents()
933 # and from the fctx.annotate() call itself that could be cached.
933 # and from the fctx.annotate() call itself that could be cached.
934 parentscache = {}
934 parentscache = {}
935 def parents(f):
935 def parents(f):
936 rev = f.rev()
936 rev = f.rev()
937 if rev not in parentscache:
937 if rev not in parentscache:
938 parentscache[rev] = []
938 parentscache[rev] = []
939 for p in f.parents():
939 for p in f.parents():
940 entry = {
940 entry = {
941 'node': p.hex(),
941 'node': p.hex(),
942 'rev': p.rev(),
942 'rev': p.rev(),
943 }
943 }
944 parentscache[rev].append(entry)
944 parentscache[rev].append(entry)
945
945
946 for p in parentscache[rev]:
946 for p in parentscache[rev]:
947 yield p
947 yield p
948
948
949 def annotate(**map):
949 def annotate(**map):
950 if fctx.isbinary():
950 if fctx.isbinary():
951 mt = (mimetypes.guess_type(fctx.path())[0]
951 mt = (mimetypes.guess_type(fctx.path())[0]
952 or 'application/octet-stream')
952 or 'application/octet-stream')
953 lines = [dagop.annotateline(fctx=fctx.filectx(fctx.filerev()),
953 lines = [dagop.annotateline(fctx=fctx.filectx(fctx.filerev()),
954 lineno=1, text='(binary:%s)' % mt)]
954 lineno=1, text='(binary:%s)' % mt)]
955 else:
955 else:
956 lines = webutil.annotate(web.req, fctx, web.repo.ui)
956 lines = webutil.annotate(web.req, fctx, web.repo.ui)
957
957
958 previousrev = None
958 previousrev = None
959 blockparitygen = paritygen(1)
959 blockparitygen = paritygen(1)
960 for lineno, aline in enumerate(lines):
960 for lineno, aline in enumerate(lines):
961 f = aline.fctx
961 f = aline.fctx
962 rev = f.rev()
962 rev = f.rev()
963 if rev != previousrev:
963 if rev != previousrev:
964 blockhead = True
964 blockhead = True
965 blockparity = next(blockparitygen)
965 blockparity = next(blockparitygen)
966 else:
966 else:
967 blockhead = None
967 blockhead = None
968 previousrev = rev
968 previousrev = rev
969 yield {"parity": next(parity),
969 yield {"parity": next(parity),
970 "node": f.hex(),
970 "node": f.hex(),
971 "rev": rev,
971 "rev": rev,
972 "author": f.user(),
972 "author": f.user(),
973 "parents": parents(f),
973 "parents": parents(f),
974 "desc": f.description(),
974 "desc": f.description(),
975 "extra": f.extra(),
975 "extra": f.extra(),
976 "file": f.path(),
976 "file": f.path(),
977 "blockhead": blockhead,
977 "blockhead": blockhead,
978 "blockparity": blockparity,
978 "blockparity": blockparity,
979 "targetline": aline.lineno,
979 "targetline": aline.lineno,
980 "line": aline.text,
980 "line": aline.text,
981 "lineno": lineno + 1,
981 "lineno": lineno + 1,
982 "lineid": "l%d" % (lineno + 1),
982 "lineid": "l%d" % (lineno + 1),
983 "linenumber": "% 6d" % (lineno + 1),
983 "linenumber": "% 6d" % (lineno + 1),
984 "revdate": f.date()}
984 "revdate": f.date()}
985
985
986 diffopts = webutil.difffeatureopts(web.req, web.repo.ui, 'annotate')
986 diffopts = webutil.difffeatureopts(web.req, web.repo.ui, 'annotate')
987 diffopts = {k: getattr(diffopts, k) for k in diffopts.defaults}
987 diffopts = {k: getattr(diffopts, k) for k in diffopts.defaults}
988
988
989 return web.sendtemplate(
989 return web.sendtemplate(
990 'fileannotate',
990 'fileannotate',
991 file=f,
991 file=f,
992 annotate=annotate,
992 annotate=annotate,
993 path=webutil.up(f),
993 path=webutil.up(f),
994 symrev=webutil.symrevorshortnode(web.req, fctx),
994 symrev=webutil.symrevorshortnode(web.req, fctx),
995 rename=webutil.renamelink(fctx),
995 rename=webutil.renamelink(fctx),
996 permissions=fctx.manifest().flags(f),
996 permissions=fctx.manifest().flags(f),
997 ishead=int(ishead),
997 ishead=int(ishead),
998 diffopts=diffopts,
998 diffopts=diffopts,
999 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
999 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
1000
1000
1001 @webcommand('filelog')
1001 @webcommand('filelog')
1002 def filelog(web):
1002 def filelog(web):
1003 """
1003 """
1004 /filelog/{revision}/{path}
1004 /filelog/{revision}/{path}
1005 --------------------------
1005 --------------------------
1006
1006
1007 Show information about the history of a file in the repository.
1007 Show information about the history of a file in the repository.
1008
1008
1009 The ``revcount`` query string argument can be defined to control the
1009 The ``revcount`` query string argument can be defined to control the
1010 maximum number of entries to show.
1010 maximum number of entries to show.
1011
1011
1012 The ``filelog`` template will be rendered.
1012 The ``filelog`` template will be rendered.
1013 """
1013 """
1014
1014
1015 try:
1015 try:
1016 fctx = webutil.filectx(web.repo, web.req)
1016 fctx = webutil.filectx(web.repo, web.req)
1017 f = fctx.path()
1017 f = fctx.path()
1018 fl = fctx.filelog()
1018 fl = fctx.filelog()
1019 except error.LookupError:
1019 except error.LookupError:
1020 f = webutil.cleanpath(web.repo, web.req.qsparams['file'])
1020 f = webutil.cleanpath(web.repo, web.req.qsparams['file'])
1021 fl = web.repo.file(f)
1021 fl = web.repo.file(f)
1022 numrevs = len(fl)
1022 numrevs = len(fl)
1023 if not numrevs: # file doesn't exist at all
1023 if not numrevs: # file doesn't exist at all
1024 raise
1024 raise
1025 rev = webutil.changectx(web.repo, web.req).rev()
1025 rev = webutil.changectx(web.repo, web.req).rev()
1026 first = fl.linkrev(0)
1026 first = fl.linkrev(0)
1027 if rev < first: # current rev is from before file existed
1027 if rev < first: # current rev is from before file existed
1028 raise
1028 raise
1029 frev = numrevs - 1
1029 frev = numrevs - 1
1030 while fl.linkrev(frev) > rev:
1030 while fl.linkrev(frev) > rev:
1031 frev -= 1
1031 frev -= 1
1032 fctx = web.repo.filectx(f, fl.linkrev(frev))
1032 fctx = web.repo.filectx(f, fl.linkrev(frev))
1033
1033
1034 revcount = web.maxshortchanges
1034 revcount = web.maxshortchanges
1035 if 'revcount' in web.req.qsparams:
1035 if 'revcount' in web.req.qsparams:
1036 try:
1036 try:
1037 revcount = int(web.req.qsparams.get('revcount', revcount))
1037 revcount = int(web.req.qsparams.get('revcount', revcount))
1038 revcount = max(revcount, 1)
1038 revcount = max(revcount, 1)
1039 web.tmpl.defaults['sessionvars']['revcount'] = revcount
1039 web.tmpl.defaults['sessionvars']['revcount'] = revcount
1040 except ValueError:
1040 except ValueError:
1041 pass
1041 pass
1042
1042
1043 lrange = webutil.linerange(web.req)
1043 lrange = webutil.linerange(web.req)
1044
1044
1045 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
1045 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
1046 lessvars['revcount'] = max(revcount // 2, 1)
1046 lessvars['revcount'] = max(revcount // 2, 1)
1047 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
1047 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
1048 morevars['revcount'] = revcount * 2
1048 morevars['revcount'] = revcount * 2
1049
1049
1050 patch = 'patch' in web.req.qsparams
1050 patch = 'patch' in web.req.qsparams
1051 if patch:
1051 if patch:
1052 lessvars['patch'] = morevars['patch'] = web.req.qsparams['patch']
1052 lessvars['patch'] = morevars['patch'] = web.req.qsparams['patch']
1053 descend = 'descend' in web.req.qsparams
1053 descend = 'descend' in web.req.qsparams
1054 if descend:
1054 if descend:
1055 lessvars['descend'] = morevars['descend'] = web.req.qsparams['descend']
1055 lessvars['descend'] = morevars['descend'] = web.req.qsparams['descend']
1056
1056
1057 count = fctx.filerev() + 1
1057 count = fctx.filerev() + 1
1058 start = max(0, count - revcount) # first rev on this page
1058 start = max(0, count - revcount) # first rev on this page
1059 end = min(count, start + revcount) # last rev on this page
1059 end = min(count, start + revcount) # last rev on this page
1060 parity = paritygen(web.stripecount, offset=start - end)
1060 parity = paritygen(web.stripecount, offset=start - end)
1061
1061
1062 repo = web.repo
1062 repo = web.repo
1063 filelog = fctx.filelog()
1063 filelog = fctx.filelog()
1064 revs = [filerev for filerev in filelog.revs(start, end - 1)
1064 revs = [filerev for filerev in filelog.revs(start, end - 1)
1065 if filelog.linkrev(filerev) in repo]
1065 if filelog.linkrev(filerev) in repo]
1066 entries = []
1066 entries = []
1067
1067
1068 diffstyle = web.config('web', 'style')
1068 diffstyle = web.config('web', 'style')
1069 if 'style' in web.req.qsparams:
1069 if 'style' in web.req.qsparams:
1070 diffstyle = web.req.qsparams['style']
1070 diffstyle = web.req.qsparams['style']
1071
1071
1072 def diff(fctx, linerange=None):
1072 def diff(fctx, linerange=None):
1073 ctx = fctx.changectx()
1073 ctx = fctx.changectx()
1074 basectx = ctx.p1()
1074 basectx = ctx.p1()
1075 path = fctx.path()
1075 path = fctx.path()
1076 return webutil.diffs(web, ctx, basectx, [path], diffstyle,
1076 return webutil.diffs(web, ctx, basectx, [path], diffstyle,
1077 linerange=linerange,
1077 linerange=linerange,
1078 lineidprefix='%s-' % ctx.hex()[:12])
1078 lineidprefix='%s-' % ctx.hex()[:12])
1079
1079
1080 linerange = None
1080 linerange = None
1081 if lrange is not None:
1081 if lrange is not None:
1082 linerange = webutil.formatlinerange(*lrange)
1082 linerange = webutil.formatlinerange(*lrange)
1083 # deactivate numeric nav links when linerange is specified as this
1083 # deactivate numeric nav links when linerange is specified as this
1084 # would required a dedicated "revnav" class
1084 # would required a dedicated "revnav" class
1085 nav = None
1085 nav = []
1086 if descend:
1086 if descend:
1087 it = dagop.blockdescendants(fctx, *lrange)
1087 it = dagop.blockdescendants(fctx, *lrange)
1088 else:
1088 else:
1089 it = dagop.blockancestors(fctx, *lrange)
1089 it = dagop.blockancestors(fctx, *lrange)
1090 for i, (c, lr) in enumerate(it, 1):
1090 for i, (c, lr) in enumerate(it, 1):
1091 diffs = None
1091 diffs = None
1092 if patch:
1092 if patch:
1093 diffs = diff(c, linerange=lr)
1093 diffs = diff(c, linerange=lr)
1094 # follow renames accross filtered (not in range) revisions
1094 # follow renames accross filtered (not in range) revisions
1095 path = c.path()
1095 path = c.path()
1096 entries.append(dict(
1096 entries.append(dict(
1097 parity=next(parity),
1097 parity=next(parity),
1098 filerev=c.rev(),
1098 filerev=c.rev(),
1099 file=path,
1099 file=path,
1100 diff=diffs,
1100 diff=diffs,
1101 linerange=webutil.formatlinerange(*lr),
1101 linerange=webutil.formatlinerange(*lr),
1102 **pycompat.strkwargs(webutil.commonentry(repo, c))))
1102 **pycompat.strkwargs(webutil.commonentry(repo, c))))
1103 if i == revcount:
1103 if i == revcount:
1104 break
1104 break
1105 lessvars['linerange'] = webutil.formatlinerange(*lrange)
1105 lessvars['linerange'] = webutil.formatlinerange(*lrange)
1106 morevars['linerange'] = lessvars['linerange']
1106 morevars['linerange'] = lessvars['linerange']
1107 else:
1107 else:
1108 for i in revs:
1108 for i in revs:
1109 iterfctx = fctx.filectx(i)
1109 iterfctx = fctx.filectx(i)
1110 diffs = None
1110 diffs = None
1111 if patch:
1111 if patch:
1112 diffs = diff(iterfctx)
1112 diffs = diff(iterfctx)
1113 entries.append(dict(
1113 entries.append(dict(
1114 parity=next(parity),
1114 parity=next(parity),
1115 filerev=i,
1115 filerev=i,
1116 file=f,
1116 file=f,
1117 diff=diffs,
1117 diff=diffs,
1118 rename=webutil.renamelink(iterfctx),
1118 rename=webutil.renamelink(iterfctx),
1119 **pycompat.strkwargs(webutil.commonentry(repo, iterfctx))))
1119 **pycompat.strkwargs(webutil.commonentry(repo, iterfctx))))
1120 entries.reverse()
1120 entries.reverse()
1121 revnav = webutil.filerevnav(web.repo, fctx.path())
1121 revnav = webutil.filerevnav(web.repo, fctx.path())
1122 nav = revnav.gen(end - 1, revcount, count)
1122 nav = revnav.gen(end - 1, revcount, count)
1123
1123
1124 latestentry = entries[:1]
1124 latestentry = entries[:1]
1125
1125
1126 return web.sendtemplate(
1126 return web.sendtemplate(
1127 'filelog',
1127 'filelog',
1128 file=f,
1128 file=f,
1129 nav=nav,
1129 nav=nav,
1130 symrev=webutil.symrevorshortnode(web.req, fctx),
1130 symrev=webutil.symrevorshortnode(web.req, fctx),
1131 entries=entries,
1131 entries=entries,
1132 descend=descend,
1132 descend=descend,
1133 patch=patch,
1133 patch=patch,
1134 latestentry=latestentry,
1134 latestentry=latestentry,
1135 linerange=linerange,
1135 linerange=linerange,
1136 revcount=revcount,
1136 revcount=revcount,
1137 morevars=morevars,
1137 morevars=morevars,
1138 lessvars=lessvars,
1138 lessvars=lessvars,
1139 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
1139 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
1140
1140
1141 @webcommand('archive')
1141 @webcommand('archive')
1142 def archive(web):
1142 def archive(web):
1143 """
1143 """
1144 /archive/{revision}.{format}[/{path}]
1144 /archive/{revision}.{format}[/{path}]
1145 -------------------------------------
1145 -------------------------------------
1146
1146
1147 Obtain an archive of repository content.
1147 Obtain an archive of repository content.
1148
1148
1149 The content and type of the archive is defined by a URL path parameter.
1149 The content and type of the archive is defined by a URL path parameter.
1150 ``format`` is the file extension of the archive type to be generated. e.g.
1150 ``format`` is the file extension of the archive type to be generated. e.g.
1151 ``zip`` or ``tar.bz2``. Not all archive types may be allowed by your
1151 ``zip`` or ``tar.bz2``. Not all archive types may be allowed by your
1152 server configuration.
1152 server configuration.
1153
1153
1154 The optional ``path`` URL parameter controls content to include in the
1154 The optional ``path`` URL parameter controls content to include in the
1155 archive. If omitted, every file in the specified revision is present in the
1155 archive. If omitted, every file in the specified revision is present in the
1156 archive. If included, only the specified file or contents of the specified
1156 archive. If included, only the specified file or contents of the specified
1157 directory will be included in the archive.
1157 directory will be included in the archive.
1158
1158
1159 No template is used for this handler. Raw, binary content is generated.
1159 No template is used for this handler. Raw, binary content is generated.
1160 """
1160 """
1161
1161
1162 type_ = web.req.qsparams.get('type')
1162 type_ = web.req.qsparams.get('type')
1163 allowed = web.configlist("web", "allow_archive")
1163 allowed = web.configlist("web", "allow_archive")
1164 key = web.req.qsparams['node']
1164 key = web.req.qsparams['node']
1165
1165
1166 if type_ not in web.archivespecs:
1166 if type_ not in web.archivespecs:
1167 msg = 'Unsupported archive type: %s' % type_
1167 msg = 'Unsupported archive type: %s' % type_
1168 raise ErrorResponse(HTTP_NOT_FOUND, msg)
1168 raise ErrorResponse(HTTP_NOT_FOUND, msg)
1169
1169
1170 if not ((type_ in allowed or
1170 if not ((type_ in allowed or
1171 web.configbool("web", "allow" + type_))):
1171 web.configbool("web", "allow" + type_))):
1172 msg = 'Archive type not allowed: %s' % type_
1172 msg = 'Archive type not allowed: %s' % type_
1173 raise ErrorResponse(HTTP_FORBIDDEN, msg)
1173 raise ErrorResponse(HTTP_FORBIDDEN, msg)
1174
1174
1175 reponame = re.sub(br"\W+", "-", os.path.basename(web.reponame))
1175 reponame = re.sub(br"\W+", "-", os.path.basename(web.reponame))
1176 cnode = web.repo.lookup(key)
1176 cnode = web.repo.lookup(key)
1177 arch_version = key
1177 arch_version = key
1178 if cnode == key or key == 'tip':
1178 if cnode == key or key == 'tip':
1179 arch_version = short(cnode)
1179 arch_version = short(cnode)
1180 name = "%s-%s" % (reponame, arch_version)
1180 name = "%s-%s" % (reponame, arch_version)
1181
1181
1182 ctx = webutil.changectx(web.repo, web.req)
1182 ctx = webutil.changectx(web.repo, web.req)
1183 pats = []
1183 pats = []
1184 match = scmutil.match(ctx, [])
1184 match = scmutil.match(ctx, [])
1185 file = web.req.qsparams.get('file')
1185 file = web.req.qsparams.get('file')
1186 if file:
1186 if file:
1187 pats = ['path:' + file]
1187 pats = ['path:' + file]
1188 match = scmutil.match(ctx, pats, default='path')
1188 match = scmutil.match(ctx, pats, default='path')
1189 if pats:
1189 if pats:
1190 files = [f for f in ctx.manifest().keys() if match(f)]
1190 files = [f for f in ctx.manifest().keys() if match(f)]
1191 if not files:
1191 if not files:
1192 raise ErrorResponse(HTTP_NOT_FOUND,
1192 raise ErrorResponse(HTTP_NOT_FOUND,
1193 'file(s) not found: %s' % file)
1193 'file(s) not found: %s' % file)
1194
1194
1195 mimetype, artype, extension, encoding = web.archivespecs[type_]
1195 mimetype, artype, extension, encoding = web.archivespecs[type_]
1196
1196
1197 web.res.headers['Content-Type'] = mimetype
1197 web.res.headers['Content-Type'] = mimetype
1198 web.res.headers['Content-Disposition'] = 'attachment; filename=%s%s' % (
1198 web.res.headers['Content-Disposition'] = 'attachment; filename=%s%s' % (
1199 name, extension)
1199 name, extension)
1200
1200
1201 if encoding:
1201 if encoding:
1202 web.res.headers['Content-Encoding'] = encoding
1202 web.res.headers['Content-Encoding'] = encoding
1203
1203
1204 web.res.setbodywillwrite()
1204 web.res.setbodywillwrite()
1205 if list(web.res.sendresponse()):
1205 if list(web.res.sendresponse()):
1206 raise error.ProgrammingError('sendresponse() should not emit data '
1206 raise error.ProgrammingError('sendresponse() should not emit data '
1207 'if writing later')
1207 'if writing later')
1208
1208
1209 bodyfh = web.res.getbodyfile()
1209 bodyfh = web.res.getbodyfile()
1210
1210
1211 archival.archive(web.repo, bodyfh, cnode, artype, prefix=name,
1211 archival.archive(web.repo, bodyfh, cnode, artype, prefix=name,
1212 matchfn=match,
1212 matchfn=match,
1213 subrepos=web.configbool("web", "archivesubrepos"))
1213 subrepos=web.configbool("web", "archivesubrepos"))
1214
1214
1215 return []
1215 return []
1216
1216
1217 @webcommand('static')
1217 @webcommand('static')
1218 def static(web):
1218 def static(web):
1219 fname = web.req.qsparams['file']
1219 fname = web.req.qsparams['file']
1220 # a repo owner may set web.static in .hg/hgrc to get any file
1220 # a repo owner may set web.static in .hg/hgrc to get any file
1221 # readable by the user running the CGI script
1221 # readable by the user running the CGI script
1222 static = web.config("web", "static", None, untrusted=False)
1222 static = web.config("web", "static", None, untrusted=False)
1223 if not static:
1223 if not static:
1224 tp = web.templatepath or templater.templatepaths()
1224 tp = web.templatepath or templater.templatepaths()
1225 if isinstance(tp, str):
1225 if isinstance(tp, str):
1226 tp = [tp]
1226 tp = [tp]
1227 static = [os.path.join(p, 'static') for p in tp]
1227 static = [os.path.join(p, 'static') for p in tp]
1228
1228
1229 staticfile(static, fname, web.res)
1229 staticfile(static, fname, web.res)
1230 return web.res.sendresponse()
1230 return web.res.sendresponse()
1231
1231
1232 @webcommand('graph')
1232 @webcommand('graph')
1233 def graph(web):
1233 def graph(web):
1234 """
1234 """
1235 /graph[/{revision}]
1235 /graph[/{revision}]
1236 -------------------
1236 -------------------
1237
1237
1238 Show information about the graphical topology of the repository.
1238 Show information about the graphical topology of the repository.
1239
1239
1240 Information rendered by this handler can be used to create visual
1240 Information rendered by this handler can be used to create visual
1241 representations of repository topology.
1241 representations of repository topology.
1242
1242
1243 The ``revision`` URL parameter controls the starting changeset. If it's
1243 The ``revision`` URL parameter controls the starting changeset. If it's
1244 absent, the default is ``tip``.
1244 absent, the default is ``tip``.
1245
1245
1246 The ``revcount`` query string argument can define the number of changesets
1246 The ``revcount`` query string argument can define the number of changesets
1247 to show information for.
1247 to show information for.
1248
1248
1249 The ``graphtop`` query string argument can specify the starting changeset
1249 The ``graphtop`` query string argument can specify the starting changeset
1250 for producing ``jsdata`` variable that is used for rendering graph in
1250 for producing ``jsdata`` variable that is used for rendering graph in
1251 JavaScript. By default it has the same value as ``revision``.
1251 JavaScript. By default it has the same value as ``revision``.
1252
1252
1253 This handler will render the ``graph`` template.
1253 This handler will render the ``graph`` template.
1254 """
1254 """
1255
1255
1256 if 'node' in web.req.qsparams:
1256 if 'node' in web.req.qsparams:
1257 ctx = webutil.changectx(web.repo, web.req)
1257 ctx = webutil.changectx(web.repo, web.req)
1258 symrev = webutil.symrevorshortnode(web.req, ctx)
1258 symrev = webutil.symrevorshortnode(web.req, ctx)
1259 else:
1259 else:
1260 ctx = web.repo['tip']
1260 ctx = web.repo['tip']
1261 symrev = 'tip'
1261 symrev = 'tip'
1262 rev = ctx.rev()
1262 rev = ctx.rev()
1263
1263
1264 bg_height = 39
1264 bg_height = 39
1265 revcount = web.maxshortchanges
1265 revcount = web.maxshortchanges
1266 if 'revcount' in web.req.qsparams:
1266 if 'revcount' in web.req.qsparams:
1267 try:
1267 try:
1268 revcount = int(web.req.qsparams.get('revcount', revcount))
1268 revcount = int(web.req.qsparams.get('revcount', revcount))
1269 revcount = max(revcount, 1)
1269 revcount = max(revcount, 1)
1270 web.tmpl.defaults['sessionvars']['revcount'] = revcount
1270 web.tmpl.defaults['sessionvars']['revcount'] = revcount
1271 except ValueError:
1271 except ValueError:
1272 pass
1272 pass
1273
1273
1274 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
1274 lessvars = copy.copy(web.tmpl.defaults['sessionvars'])
1275 lessvars['revcount'] = max(revcount // 2, 1)
1275 lessvars['revcount'] = max(revcount // 2, 1)
1276 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
1276 morevars = copy.copy(web.tmpl.defaults['sessionvars'])
1277 morevars['revcount'] = revcount * 2
1277 morevars['revcount'] = revcount * 2
1278
1278
1279 graphtop = web.req.qsparams.get('graphtop', ctx.hex())
1279 graphtop = web.req.qsparams.get('graphtop', ctx.hex())
1280 graphvars = copy.copy(web.tmpl.defaults['sessionvars'])
1280 graphvars = copy.copy(web.tmpl.defaults['sessionvars'])
1281 graphvars['graphtop'] = graphtop
1281 graphvars['graphtop'] = graphtop
1282
1282
1283 count = len(web.repo)
1283 count = len(web.repo)
1284 pos = rev
1284 pos = rev
1285
1285
1286 uprev = min(max(0, count - 1), rev + revcount)
1286 uprev = min(max(0, count - 1), rev + revcount)
1287 downrev = max(0, rev - revcount)
1287 downrev = max(0, rev - revcount)
1288 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
1288 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
1289
1289
1290 tree = []
1290 tree = []
1291 nextentry = []
1291 nextentry = []
1292 lastrev = 0
1292 lastrev = 0
1293 if pos != -1:
1293 if pos != -1:
1294 allrevs = web.repo.changelog.revs(pos, 0)
1294 allrevs = web.repo.changelog.revs(pos, 0)
1295 revs = []
1295 revs = []
1296 for i in allrevs:
1296 for i in allrevs:
1297 revs.append(i)
1297 revs.append(i)
1298 if len(revs) >= revcount + 1:
1298 if len(revs) >= revcount + 1:
1299 break
1299 break
1300
1300
1301 if len(revs) > revcount:
1301 if len(revs) > revcount:
1302 nextentry = [webutil.commonentry(web.repo, web.repo[revs[-1]])]
1302 nextentry = [webutil.commonentry(web.repo, web.repo[revs[-1]])]
1303 revs = revs[:-1]
1303 revs = revs[:-1]
1304
1304
1305 lastrev = revs[-1]
1305 lastrev = revs[-1]
1306
1306
1307 # We have to feed a baseset to dagwalker as it is expecting smartset
1307 # We have to feed a baseset to dagwalker as it is expecting smartset
1308 # object. This does not have a big impact on hgweb performance itself
1308 # object. This does not have a big impact on hgweb performance itself
1309 # since hgweb graphing code is not itself lazy yet.
1309 # since hgweb graphing code is not itself lazy yet.
1310 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs))
1310 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs))
1311 # As we said one line above... not lazy.
1311 # As we said one line above... not lazy.
1312 tree = list(item for item in graphmod.colored(dag, web.repo)
1312 tree = list(item for item in graphmod.colored(dag, web.repo)
1313 if item[1] == graphmod.CHANGESET)
1313 if item[1] == graphmod.CHANGESET)
1314
1314
1315 def nodecurrent(ctx):
1315 def nodecurrent(ctx):
1316 wpnodes = web.repo.dirstate.parents()
1316 wpnodes = web.repo.dirstate.parents()
1317 if wpnodes[1] == nullid:
1317 if wpnodes[1] == nullid:
1318 wpnodes = wpnodes[:1]
1318 wpnodes = wpnodes[:1]
1319 if ctx.node() in wpnodes:
1319 if ctx.node() in wpnodes:
1320 return '@'
1320 return '@'
1321 return ''
1321 return ''
1322
1322
1323 def nodesymbol(ctx):
1323 def nodesymbol(ctx):
1324 if ctx.obsolete():
1324 if ctx.obsolete():
1325 return 'x'
1325 return 'x'
1326 elif ctx.isunstable():
1326 elif ctx.isunstable():
1327 return '*'
1327 return '*'
1328 elif ctx.closesbranch():
1328 elif ctx.closesbranch():
1329 return '_'
1329 return '_'
1330 else:
1330 else:
1331 return 'o'
1331 return 'o'
1332
1332
1333 def fulltree():
1333 def fulltree():
1334 pos = web.repo[graphtop].rev()
1334 pos = web.repo[graphtop].rev()
1335 tree = []
1335 tree = []
1336 if pos != -1:
1336 if pos != -1:
1337 revs = web.repo.changelog.revs(pos, lastrev)
1337 revs = web.repo.changelog.revs(pos, lastrev)
1338 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs))
1338 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs))
1339 tree = list(item for item in graphmod.colored(dag, web.repo)
1339 tree = list(item for item in graphmod.colored(dag, web.repo)
1340 if item[1] == graphmod.CHANGESET)
1340 if item[1] == graphmod.CHANGESET)
1341 return tree
1341 return tree
1342
1342
1343 def jsdata():
1343 def jsdata():
1344 return [{'node': pycompat.bytestr(ctx),
1344 return [{'node': pycompat.bytestr(ctx),
1345 'graphnode': nodecurrent(ctx) + nodesymbol(ctx),
1345 'graphnode': nodecurrent(ctx) + nodesymbol(ctx),
1346 'vertex': vtx,
1346 'vertex': vtx,
1347 'edges': edges}
1347 'edges': edges}
1348 for (id, type, ctx, vtx, edges) in fulltree()]
1348 for (id, type, ctx, vtx, edges) in fulltree()]
1349
1349
1350 def nodes():
1350 def nodes():
1351 parity = paritygen(web.stripecount)
1351 parity = paritygen(web.stripecount)
1352 for row, (id, type, ctx, vtx, edges) in enumerate(tree):
1352 for row, (id, type, ctx, vtx, edges) in enumerate(tree):
1353 entry = webutil.commonentry(web.repo, ctx)
1353 entry = webutil.commonentry(web.repo, ctx)
1354 edgedata = [{'col': edge[0],
1354 edgedata = [{'col': edge[0],
1355 'nextcol': edge[1],
1355 'nextcol': edge[1],
1356 'color': (edge[2] - 1) % 6 + 1,
1356 'color': (edge[2] - 1) % 6 + 1,
1357 'width': edge[3],
1357 'width': edge[3],
1358 'bcolor': edge[4]}
1358 'bcolor': edge[4]}
1359 for edge in edges]
1359 for edge in edges]
1360
1360
1361 entry.update({'col': vtx[0],
1361 entry.update({'col': vtx[0],
1362 'color': (vtx[1] - 1) % 6 + 1,
1362 'color': (vtx[1] - 1) % 6 + 1,
1363 'parity': next(parity),
1363 'parity': next(parity),
1364 'edges': edgedata,
1364 'edges': edgedata,
1365 'row': row,
1365 'row': row,
1366 'nextrow': row + 1})
1366 'nextrow': row + 1})
1367
1367
1368 yield entry
1368 yield entry
1369
1369
1370 rows = len(tree)
1370 rows = len(tree)
1371
1371
1372 return web.sendtemplate(
1372 return web.sendtemplate(
1373 'graph',
1373 'graph',
1374 rev=rev,
1374 rev=rev,
1375 symrev=symrev,
1375 symrev=symrev,
1376 revcount=revcount,
1376 revcount=revcount,
1377 uprev=uprev,
1377 uprev=uprev,
1378 lessvars=lessvars,
1378 lessvars=lessvars,
1379 morevars=morevars,
1379 morevars=morevars,
1380 downrev=downrev,
1380 downrev=downrev,
1381 graphvars=graphvars,
1381 graphvars=graphvars,
1382 rows=rows,
1382 rows=rows,
1383 bg_height=bg_height,
1383 bg_height=bg_height,
1384 changesets=count,
1384 changesets=count,
1385 nextentry=nextentry,
1385 nextentry=nextentry,
1386 jsdata=lambda **x: jsdata(),
1386 jsdata=lambda **x: jsdata(),
1387 nodes=lambda **x: nodes(),
1387 nodes=lambda **x: nodes(),
1388 node=ctx.hex(),
1388 node=ctx.hex(),
1389 changenav=changenav)
1389 changenav=changenav)
1390
1390
1391 def _getdoc(e):
1391 def _getdoc(e):
1392 doc = e[0].__doc__
1392 doc = e[0].__doc__
1393 if doc:
1393 if doc:
1394 doc = _(doc).partition('\n')[0]
1394 doc = _(doc).partition('\n')[0]
1395 else:
1395 else:
1396 doc = _('(no help text available)')
1396 doc = _('(no help text available)')
1397 return doc
1397 return doc
1398
1398
1399 @webcommand('help')
1399 @webcommand('help')
1400 def help(web):
1400 def help(web):
1401 """
1401 """
1402 /help[/{topic}]
1402 /help[/{topic}]
1403 ---------------
1403 ---------------
1404
1404
1405 Render help documentation.
1405 Render help documentation.
1406
1406
1407 This web command is roughly equivalent to :hg:`help`. If a ``topic``
1407 This web command is roughly equivalent to :hg:`help`. If a ``topic``
1408 is defined, that help topic will be rendered. If not, an index of
1408 is defined, that help topic will be rendered. If not, an index of
1409 available help topics will be rendered.
1409 available help topics will be rendered.
1410
1410
1411 The ``help`` template will be rendered when requesting help for a topic.
1411 The ``help`` template will be rendered when requesting help for a topic.
1412 ``helptopics`` will be rendered for the index of help topics.
1412 ``helptopics`` will be rendered for the index of help topics.
1413 """
1413 """
1414 from .. import commands, help as helpmod # avoid cycle
1414 from .. import commands, help as helpmod # avoid cycle
1415
1415
1416 topicname = web.req.qsparams.get('node')
1416 topicname = web.req.qsparams.get('node')
1417 if not topicname:
1417 if not topicname:
1418 def topics(**map):
1418 def topics(**map):
1419 for entries, summary, _doc in helpmod.helptable:
1419 for entries, summary, _doc in helpmod.helptable:
1420 yield {'topic': entries[0], 'summary': summary}
1420 yield {'topic': entries[0], 'summary': summary}
1421
1421
1422 early, other = [], []
1422 early, other = [], []
1423 primary = lambda s: s.partition('|')[0]
1423 primary = lambda s: s.partition('|')[0]
1424 for c, e in commands.table.iteritems():
1424 for c, e in commands.table.iteritems():
1425 doc = _getdoc(e)
1425 doc = _getdoc(e)
1426 if 'DEPRECATED' in doc or c.startswith('debug'):
1426 if 'DEPRECATED' in doc or c.startswith('debug'):
1427 continue
1427 continue
1428 cmd = primary(c)
1428 cmd = primary(c)
1429 if cmd.startswith('^'):
1429 if cmd.startswith('^'):
1430 early.append((cmd[1:], doc))
1430 early.append((cmd[1:], doc))
1431 else:
1431 else:
1432 other.append((cmd, doc))
1432 other.append((cmd, doc))
1433
1433
1434 early.sort()
1434 early.sort()
1435 other.sort()
1435 other.sort()
1436
1436
1437 def earlycommands(**map):
1437 def earlycommands(**map):
1438 for c, doc in early:
1438 for c, doc in early:
1439 yield {'topic': c, 'summary': doc}
1439 yield {'topic': c, 'summary': doc}
1440
1440
1441 def othercommands(**map):
1441 def othercommands(**map):
1442 for c, doc in other:
1442 for c, doc in other:
1443 yield {'topic': c, 'summary': doc}
1443 yield {'topic': c, 'summary': doc}
1444
1444
1445 return web.sendtemplate(
1445 return web.sendtemplate(
1446 'helptopics',
1446 'helptopics',
1447 topics=topics,
1447 topics=topics,
1448 earlycommands=earlycommands,
1448 earlycommands=earlycommands,
1449 othercommands=othercommands,
1449 othercommands=othercommands,
1450 title='Index')
1450 title='Index')
1451
1451
1452 # Render an index of sub-topics.
1452 # Render an index of sub-topics.
1453 if topicname in helpmod.subtopics:
1453 if topicname in helpmod.subtopics:
1454 topics = []
1454 topics = []
1455 for entries, summary, _doc in helpmod.subtopics[topicname]:
1455 for entries, summary, _doc in helpmod.subtopics[topicname]:
1456 topics.append({
1456 topics.append({
1457 'topic': '%s.%s' % (topicname, entries[0]),
1457 'topic': '%s.%s' % (topicname, entries[0]),
1458 'basename': entries[0],
1458 'basename': entries[0],
1459 'summary': summary,
1459 'summary': summary,
1460 })
1460 })
1461
1461
1462 return web.sendtemplate(
1462 return web.sendtemplate(
1463 'helptopics',
1463 'helptopics',
1464 topics=topics,
1464 topics=topics,
1465 title=topicname,
1465 title=topicname,
1466 subindex=True)
1466 subindex=True)
1467
1467
1468 u = webutil.wsgiui.load()
1468 u = webutil.wsgiui.load()
1469 u.verbose = True
1469 u.verbose = True
1470
1470
1471 # Render a page from a sub-topic.
1471 # Render a page from a sub-topic.
1472 if '.' in topicname:
1472 if '.' in topicname:
1473 # TODO implement support for rendering sections, like
1473 # TODO implement support for rendering sections, like
1474 # `hg help` works.
1474 # `hg help` works.
1475 topic, subtopic = topicname.split('.', 1)
1475 topic, subtopic = topicname.split('.', 1)
1476 if topic not in helpmod.subtopics:
1476 if topic not in helpmod.subtopics:
1477 raise ErrorResponse(HTTP_NOT_FOUND)
1477 raise ErrorResponse(HTTP_NOT_FOUND)
1478 else:
1478 else:
1479 topic = topicname
1479 topic = topicname
1480 subtopic = None
1480 subtopic = None
1481
1481
1482 try:
1482 try:
1483 doc = helpmod.help_(u, commands, topic, subtopic=subtopic)
1483 doc = helpmod.help_(u, commands, topic, subtopic=subtopic)
1484 except error.Abort:
1484 except error.Abort:
1485 raise ErrorResponse(HTTP_NOT_FOUND)
1485 raise ErrorResponse(HTTP_NOT_FOUND)
1486
1486
1487 return web.sendtemplate(
1487 return web.sendtemplate(
1488 'help',
1488 'help',
1489 topic=topicname,
1489 topic=topicname,
1490 doc=doc)
1490 doc=doc)
1491
1491
1492 # tell hggettext to extract docstrings from these functions:
1492 # tell hggettext to extract docstrings from these functions:
1493 i18nfunctions = commands.values()
1493 i18nfunctions = commands.values()
@@ -1,1847 +1,1847 b''
1 #require serve
1 #require serve
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ echo b > b
5 $ echo b > b
6 $ hg ci -Am "b"
6 $ hg ci -Am "b"
7 adding b
7 adding b
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Am "first a"
9 $ hg ci -Am "first a"
10 adding a
10 adding a
11 $ hg tag -r 1 a-tag
11 $ hg tag -r 1 a-tag
12 $ hg bookmark -r 1 a-bookmark
12 $ hg bookmark -r 1 a-bookmark
13 $ hg rm a
13 $ hg rm a
14 $ hg ci -m "del a"
14 $ hg ci -m "del a"
15 $ hg branch a-branch
15 $ hg branch a-branch
16 marked working directory as branch a-branch
16 marked working directory as branch a-branch
17 (branches are permanent and global, did you want a bookmark?)
17 (branches are permanent and global, did you want a bookmark?)
18 $ echo b > a
18 $ echo b > a
19 $ hg ci -Am "second a"
19 $ hg ci -Am "second a"
20 adding a
20 adding a
21 $ hg rm a
21 $ hg rm a
22 $ hg ci -m "del2 a"
22 $ hg ci -m "del2 a"
23 $ hg mv b c
23 $ hg mv b c
24 $ hg ci -m "mv b"
24 $ hg ci -m "mv b"
25 $ echo c >> c
25 $ echo c >> c
26 $ hg ci -m "change c"
26 $ hg ci -m "change c"
27 $ hg log -p
27 $ hg log -p
28 changeset: 7:46c1a66bd8fc
28 changeset: 7:46c1a66bd8fc
29 branch: a-branch
29 branch: a-branch
30 tag: tip
30 tag: tip
31 user: test
31 user: test
32 date: Thu Jan 01 00:00:00 1970 +0000
32 date: Thu Jan 01 00:00:00 1970 +0000
33 summary: change c
33 summary: change c
34
34
35 diff -r c9637d3cc8ef -r 46c1a66bd8fc c
35 diff -r c9637d3cc8ef -r 46c1a66bd8fc c
36 --- a/c Thu Jan 01 00:00:00 1970 +0000
36 --- a/c Thu Jan 01 00:00:00 1970 +0000
37 +++ b/c Thu Jan 01 00:00:00 1970 +0000
37 +++ b/c Thu Jan 01 00:00:00 1970 +0000
38 @@ -1,1 +1,2 @@
38 @@ -1,1 +1,2 @@
39 b
39 b
40 +c
40 +c
41
41
42 changeset: 6:c9637d3cc8ef
42 changeset: 6:c9637d3cc8ef
43 branch: a-branch
43 branch: a-branch
44 user: test
44 user: test
45 date: Thu Jan 01 00:00:00 1970 +0000
45 date: Thu Jan 01 00:00:00 1970 +0000
46 summary: mv b
46 summary: mv b
47
47
48 diff -r 958bd88be4eb -r c9637d3cc8ef b
48 diff -r 958bd88be4eb -r c9637d3cc8ef b
49 --- a/b Thu Jan 01 00:00:00 1970 +0000
49 --- a/b Thu Jan 01 00:00:00 1970 +0000
50 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51 @@ -1,1 +0,0 @@
51 @@ -1,1 +0,0 @@
52 -b
52 -b
53 diff -r 958bd88be4eb -r c9637d3cc8ef c
53 diff -r 958bd88be4eb -r c9637d3cc8ef c
54 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55 +++ b/c Thu Jan 01 00:00:00 1970 +0000
55 +++ b/c Thu Jan 01 00:00:00 1970 +0000
56 @@ -0,0 +1,1 @@
56 @@ -0,0 +1,1 @@
57 +b
57 +b
58
58
59 changeset: 5:958bd88be4eb
59 changeset: 5:958bd88be4eb
60 branch: a-branch
60 branch: a-branch
61 user: test
61 user: test
62 date: Thu Jan 01 00:00:00 1970 +0000
62 date: Thu Jan 01 00:00:00 1970 +0000
63 summary: del2 a
63 summary: del2 a
64
64
65 diff -r 3f41bc784e7e -r 958bd88be4eb a
65 diff -r 3f41bc784e7e -r 958bd88be4eb a
66 --- a/a Thu Jan 01 00:00:00 1970 +0000
66 --- a/a Thu Jan 01 00:00:00 1970 +0000
67 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
67 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
68 @@ -1,1 +0,0 @@
68 @@ -1,1 +0,0 @@
69 -b
69 -b
70
70
71 changeset: 4:3f41bc784e7e
71 changeset: 4:3f41bc784e7e
72 branch: a-branch
72 branch: a-branch
73 user: test
73 user: test
74 date: Thu Jan 01 00:00:00 1970 +0000
74 date: Thu Jan 01 00:00:00 1970 +0000
75 summary: second a
75 summary: second a
76
76
77 diff -r 292258f86fdf -r 3f41bc784e7e a
77 diff -r 292258f86fdf -r 3f41bc784e7e a
78 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79 +++ b/a Thu Jan 01 00:00:00 1970 +0000
79 +++ b/a Thu Jan 01 00:00:00 1970 +0000
80 @@ -0,0 +1,1 @@
80 @@ -0,0 +1,1 @@
81 +b
81 +b
82
82
83 changeset: 3:292258f86fdf
83 changeset: 3:292258f86fdf
84 user: test
84 user: test
85 date: Thu Jan 01 00:00:00 1970 +0000
85 date: Thu Jan 01 00:00:00 1970 +0000
86 summary: del a
86 summary: del a
87
87
88 diff -r 94c9dd5ca9b4 -r 292258f86fdf a
88 diff -r 94c9dd5ca9b4 -r 292258f86fdf a
89 --- a/a Thu Jan 01 00:00:00 1970 +0000
89 --- a/a Thu Jan 01 00:00:00 1970 +0000
90 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
90 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
91 @@ -1,1 +0,0 @@
91 @@ -1,1 +0,0 @@
92 -a
92 -a
93
93
94 changeset: 2:94c9dd5ca9b4
94 changeset: 2:94c9dd5ca9b4
95 user: test
95 user: test
96 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
97 summary: Added tag a-tag for changeset 5ed941583260
97 summary: Added tag a-tag for changeset 5ed941583260
98
98
99 diff -r 5ed941583260 -r 94c9dd5ca9b4 .hgtags
99 diff -r 5ed941583260 -r 94c9dd5ca9b4 .hgtags
100 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
101 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
102 @@ -0,0 +1,1 @@
102 @@ -0,0 +1,1 @@
103 +5ed941583260248620985524192fdc382ef57c36 a-tag
103 +5ed941583260248620985524192fdc382ef57c36 a-tag
104
104
105 changeset: 1:5ed941583260
105 changeset: 1:5ed941583260
106 bookmark: a-bookmark
106 bookmark: a-bookmark
107 tag: a-tag
107 tag: a-tag
108 user: test
108 user: test
109 date: Thu Jan 01 00:00:00 1970 +0000
109 date: Thu Jan 01 00:00:00 1970 +0000
110 summary: first a
110 summary: first a
111
111
112 diff -r 6563da9dcf87 -r 5ed941583260 a
112 diff -r 6563da9dcf87 -r 5ed941583260 a
113 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
113 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
114 +++ b/a Thu Jan 01 00:00:00 1970 +0000
114 +++ b/a Thu Jan 01 00:00:00 1970 +0000
115 @@ -0,0 +1,1 @@
115 @@ -0,0 +1,1 @@
116 +a
116 +a
117
117
118 changeset: 0:6563da9dcf87
118 changeset: 0:6563da9dcf87
119 user: test
119 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
120 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: b
121 summary: b
122
122
123 diff -r 000000000000 -r 6563da9dcf87 b
123 diff -r 000000000000 -r 6563da9dcf87 b
124 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
124 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125 +++ b/b Thu Jan 01 00:00:00 1970 +0000
125 +++ b/b Thu Jan 01 00:00:00 1970 +0000
126 @@ -0,0 +1,1 @@
126 @@ -0,0 +1,1 @@
127 +b
127 +b
128
128
129 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
129 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
130 $ cat hg.pid >> $DAEMON_PIDS
130 $ cat hg.pid >> $DAEMON_PIDS
131
131
132 tip - two revisions
132 tip - two revisions
133
133
134 $ (get-with-headers.py localhost:$HGPORT 'log/tip/a')
134 $ (get-with-headers.py localhost:$HGPORT 'log/tip/a')
135 200 Script output follows
135 200 Script output follows
136
136
137 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
137 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
138 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
138 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
139 <head>
139 <head>
140 <link rel="icon" href="/static/hgicon.png" type="image/png" />
140 <link rel="icon" href="/static/hgicon.png" type="image/png" />
141 <meta name="robots" content="index, nofollow" />
141 <meta name="robots" content="index, nofollow" />
142 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
142 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
143 <script type="text/javascript" src="/static/mercurial.js"></script>
143 <script type="text/javascript" src="/static/mercurial.js"></script>
144
144
145 <title>test: a history</title>
145 <title>test: a history</title>
146 <link rel="alternate" type="application/atom+xml"
146 <link rel="alternate" type="application/atom+xml"
147 href="/atom-log/tip/a" title="Atom feed for test:a" />
147 href="/atom-log/tip/a" title="Atom feed for test:a" />
148 <link rel="alternate" type="application/rss+xml"
148 <link rel="alternate" type="application/rss+xml"
149 href="/rss-log/tip/a" title="RSS feed for test:a" />
149 href="/rss-log/tip/a" title="RSS feed for test:a" />
150 </head>
150 </head>
151 <body>
151 <body>
152
152
153 <div class="container">
153 <div class="container">
154 <div class="menu">
154 <div class="menu">
155 <div class="logo">
155 <div class="logo">
156 <a href="https://mercurial-scm.org/">
156 <a href="https://mercurial-scm.org/">
157 <img src="/static/hglogo.png" alt="mercurial" /></a>
157 <img src="/static/hglogo.png" alt="mercurial" /></a>
158 </div>
158 </div>
159 <ul>
159 <ul>
160 <li><a href="/shortlog/tip">log</a></li>
160 <li><a href="/shortlog/tip">log</a></li>
161 <li><a href="/graph/tip">graph</a></li>
161 <li><a href="/graph/tip">graph</a></li>
162 <li><a href="/tags">tags</a></li>
162 <li><a href="/tags">tags</a></li>
163 <li><a href="/bookmarks">bookmarks</a></li>
163 <li><a href="/bookmarks">bookmarks</a></li>
164 <li><a href="/branches">branches</a></li>
164 <li><a href="/branches">branches</a></li>
165 </ul>
165 </ul>
166 <ul>
166 <ul>
167 <li><a href="/rev/tip">changeset</a></li>
167 <li><a href="/rev/tip">changeset</a></li>
168 <li><a href="/file/tip">browse</a></li>
168 <li><a href="/file/tip">browse</a></li>
169 </ul>
169 </ul>
170 <ul>
170 <ul>
171 <li><a href="/file/tip/a">file</a></li>
171 <li><a href="/file/tip/a">file</a></li>
172 <li><a href="/diff/tip/a">diff</a></li>
172 <li><a href="/diff/tip/a">diff</a></li>
173 <li><a href="/comparison/tip/a">comparison</a></li>
173 <li><a href="/comparison/tip/a">comparison</a></li>
174 <li><a href="/annotate/tip/a">annotate</a></li>
174 <li><a href="/annotate/tip/a">annotate</a></li>
175 <li class="active">file log</li>
175 <li class="active">file log</li>
176 <li><a href="/raw-file/tip/a">raw</a></li>
176 <li><a href="/raw-file/tip/a">raw</a></li>
177 </ul>
177 </ul>
178 <ul>
178 <ul>
179 <li><a href="/help">help</a></li>
179 <li><a href="/help">help</a></li>
180 </ul>
180 </ul>
181 <div class="atom-logo">
181 <div class="atom-logo">
182 <a href="/atom-log/tip/a" title="subscribe to atom feed">
182 <a href="/atom-log/tip/a" title="subscribe to atom feed">
183 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
183 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
184 </a>
184 </a>
185 </div>
185 </div>
186 </div>
186 </div>
187
187
188 <div class="main">
188 <div class="main">
189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
190 <h3>
190 <h3>
191 log a @ 4:<a href="/rev/3f41bc784e7e">3f41bc784e7e</a>
191 log a @ 4:<a href="/rev/3f41bc784e7e">3f41bc784e7e</a>
192 <span class="phase">draft</span> <span class="branchname">a-branch</span>
192 <span class="phase">draft</span> <span class="branchname">a-branch</span>
193
193
194 </h3>
194 </h3>
195
195
196
196
197 <form class="search" action="/log">
197 <form class="search" action="/log">
198
198
199 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
199 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
200 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
200 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
201 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
201 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
202 </form>
202 </form>
203
203
204 <div class="navigate">
204 <div class="navigate">
205 <a href="/log/tip/a?revcount=30">less</a>
205 <a href="/log/tip/a?revcount=30">less</a>
206 <a href="/log/tip/a?revcount=120">more</a>
206 <a href="/log/tip/a?revcount=120">more</a>
207 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
207 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
208
208
209 <table class="bigtable">
209 <table class="bigtable">
210 <thead>
210 <thead>
211 <tr>
211 <tr>
212 <th class="age">age</th>
212 <th class="age">age</th>
213 <th class="author">author</th>
213 <th class="author">author</th>
214 <th class="description">description</th>
214 <th class="description">description</th>
215 </tr>
215 </tr>
216 </thead>
216 </thead>
217 <tbody class="stripes2">
217 <tbody class="stripes2">
218 <tr>
218 <tr>
219 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
219 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
220 <td class="author">test</td>
220 <td class="author">test</td>
221 <td class="description">
221 <td class="description">
222 <a href="/rev/3f41bc784e7e">second a</a>
222 <a href="/rev/3f41bc784e7e">second a</a>
223 <span class="phase">draft</span> <span class="branchname">a-branch</span>
223 <span class="phase">draft</span> <span class="branchname">a-branch</span>
224 </td>
224 </td>
225 </tr>
225 </tr>
226
226
227 <tr>
227 <tr>
228 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
228 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
229 <td class="author">test</td>
229 <td class="author">test</td>
230 <td class="description">
230 <td class="description">
231 <a href="/rev/5ed941583260">first a</a>
231 <a href="/rev/5ed941583260">first a</a>
232 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
232 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
233 </td>
233 </td>
234 </tr>
234 </tr>
235
235
236
236
237 </tbody>
237 </tbody>
238 </table>
238 </table>
239
239
240 <div class="navigate">
240 <div class="navigate">
241 <a href="/log/tip/a?revcount=30">less</a>
241 <a href="/log/tip/a?revcount=30">less</a>
242 <a href="/log/tip/a?revcount=120">more</a>
242 <a href="/log/tip/a?revcount=120">more</a>
243 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
243 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
244 </div>
244 </div>
245
245
246 </div>
246 </div>
247 </div>
247 </div>
248
248
249
249
250
250
251 </body>
251 </body>
252 </html>
252 </html>
253
253
254
254
255 second version - two revisions
255 second version - two revisions
256
256
257 $ (get-with-headers.py localhost:$HGPORT 'log/4/a')
257 $ (get-with-headers.py localhost:$HGPORT 'log/4/a')
258 200 Script output follows
258 200 Script output follows
259
259
260 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
260 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
261 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
261 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
262 <head>
262 <head>
263 <link rel="icon" href="/static/hgicon.png" type="image/png" />
263 <link rel="icon" href="/static/hgicon.png" type="image/png" />
264 <meta name="robots" content="index, nofollow" />
264 <meta name="robots" content="index, nofollow" />
265 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
265 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
266 <script type="text/javascript" src="/static/mercurial.js"></script>
266 <script type="text/javascript" src="/static/mercurial.js"></script>
267
267
268 <title>test: a history</title>
268 <title>test: a history</title>
269 <link rel="alternate" type="application/atom+xml"
269 <link rel="alternate" type="application/atom+xml"
270 href="/atom-log/tip/a" title="Atom feed for test:a" />
270 href="/atom-log/tip/a" title="Atom feed for test:a" />
271 <link rel="alternate" type="application/rss+xml"
271 <link rel="alternate" type="application/rss+xml"
272 href="/rss-log/tip/a" title="RSS feed for test:a" />
272 href="/rss-log/tip/a" title="RSS feed for test:a" />
273 </head>
273 </head>
274 <body>
274 <body>
275
275
276 <div class="container">
276 <div class="container">
277 <div class="menu">
277 <div class="menu">
278 <div class="logo">
278 <div class="logo">
279 <a href="https://mercurial-scm.org/">
279 <a href="https://mercurial-scm.org/">
280 <img src="/static/hglogo.png" alt="mercurial" /></a>
280 <img src="/static/hglogo.png" alt="mercurial" /></a>
281 </div>
281 </div>
282 <ul>
282 <ul>
283 <li><a href="/shortlog/4">log</a></li>
283 <li><a href="/shortlog/4">log</a></li>
284 <li><a href="/graph/4">graph</a></li>
284 <li><a href="/graph/4">graph</a></li>
285 <li><a href="/tags">tags</a></li>
285 <li><a href="/tags">tags</a></li>
286 <li><a href="/bookmarks">bookmarks</a></li>
286 <li><a href="/bookmarks">bookmarks</a></li>
287 <li><a href="/branches">branches</a></li>
287 <li><a href="/branches">branches</a></li>
288 </ul>
288 </ul>
289 <ul>
289 <ul>
290 <li><a href="/rev/4">changeset</a></li>
290 <li><a href="/rev/4">changeset</a></li>
291 <li><a href="/file/4">browse</a></li>
291 <li><a href="/file/4">browse</a></li>
292 </ul>
292 </ul>
293 <ul>
293 <ul>
294 <li><a href="/file/4/a">file</a></li>
294 <li><a href="/file/4/a">file</a></li>
295 <li><a href="/diff/4/a">diff</a></li>
295 <li><a href="/diff/4/a">diff</a></li>
296 <li><a href="/comparison/4/a">comparison</a></li>
296 <li><a href="/comparison/4/a">comparison</a></li>
297 <li><a href="/annotate/4/a">annotate</a></li>
297 <li><a href="/annotate/4/a">annotate</a></li>
298 <li class="active">file log</li>
298 <li class="active">file log</li>
299 <li><a href="/raw-file/4/a">raw</a></li>
299 <li><a href="/raw-file/4/a">raw</a></li>
300 </ul>
300 </ul>
301 <ul>
301 <ul>
302 <li><a href="/help">help</a></li>
302 <li><a href="/help">help</a></li>
303 </ul>
303 </ul>
304 <div class="atom-logo">
304 <div class="atom-logo">
305 <a href="/atom-log/tip/a" title="subscribe to atom feed">
305 <a href="/atom-log/tip/a" title="subscribe to atom feed">
306 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
306 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
307 </a>
307 </a>
308 </div>
308 </div>
309 </div>
309 </div>
310
310
311 <div class="main">
311 <div class="main">
312 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
312 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
313 <h3>
313 <h3>
314 log a @ 4:<a href="/rev/3f41bc784e7e">3f41bc784e7e</a>
314 log a @ 4:<a href="/rev/3f41bc784e7e">3f41bc784e7e</a>
315 <span class="phase">draft</span> <span class="branchname">a-branch</span>
315 <span class="phase">draft</span> <span class="branchname">a-branch</span>
316
316
317 </h3>
317 </h3>
318
318
319
319
320 <form class="search" action="/log">
320 <form class="search" action="/log">
321
321
322 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
322 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
323 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
323 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
324 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
324 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
325 </form>
325 </form>
326
326
327 <div class="navigate">
327 <div class="navigate">
328 <a href="/log/4/a?revcount=30">less</a>
328 <a href="/log/4/a?revcount=30">less</a>
329 <a href="/log/4/a?revcount=120">more</a>
329 <a href="/log/4/a?revcount=120">more</a>
330 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
330 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
331
331
332 <table class="bigtable">
332 <table class="bigtable">
333 <thead>
333 <thead>
334 <tr>
334 <tr>
335 <th class="age">age</th>
335 <th class="age">age</th>
336 <th class="author">author</th>
336 <th class="author">author</th>
337 <th class="description">description</th>
337 <th class="description">description</th>
338 </tr>
338 </tr>
339 </thead>
339 </thead>
340 <tbody class="stripes2">
340 <tbody class="stripes2">
341 <tr>
341 <tr>
342 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
342 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
343 <td class="author">test</td>
343 <td class="author">test</td>
344 <td class="description">
344 <td class="description">
345 <a href="/rev/3f41bc784e7e">second a</a>
345 <a href="/rev/3f41bc784e7e">second a</a>
346 <span class="phase">draft</span> <span class="branchname">a-branch</span>
346 <span class="phase">draft</span> <span class="branchname">a-branch</span>
347 </td>
347 </td>
348 </tr>
348 </tr>
349
349
350 <tr>
350 <tr>
351 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
351 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
352 <td class="author">test</td>
352 <td class="author">test</td>
353 <td class="description">
353 <td class="description">
354 <a href="/rev/5ed941583260">first a</a>
354 <a href="/rev/5ed941583260">first a</a>
355 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
355 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
356 </td>
356 </td>
357 </tr>
357 </tr>
358
358
359
359
360 </tbody>
360 </tbody>
361 </table>
361 </table>
362
362
363 <div class="navigate">
363 <div class="navigate">
364 <a href="/log/4/a?revcount=30">less</a>
364 <a href="/log/4/a?revcount=30">less</a>
365 <a href="/log/4/a?revcount=120">more</a>
365 <a href="/log/4/a?revcount=120">more</a>
366 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
366 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
367 </div>
367 </div>
368
368
369 </div>
369 </div>
370 </div>
370 </div>
371
371
372
372
373
373
374 </body>
374 </body>
375 </html>
375 </html>
376
376
377
377
378 first deleted - one revision
378 first deleted - one revision
379
379
380 $ (get-with-headers.py localhost:$HGPORT 'log/3/a')
380 $ (get-with-headers.py localhost:$HGPORT 'log/3/a')
381 200 Script output follows
381 200 Script output follows
382
382
383 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
383 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
384 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
384 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
385 <head>
385 <head>
386 <link rel="icon" href="/static/hgicon.png" type="image/png" />
386 <link rel="icon" href="/static/hgicon.png" type="image/png" />
387 <meta name="robots" content="index, nofollow" />
387 <meta name="robots" content="index, nofollow" />
388 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
388 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
389 <script type="text/javascript" src="/static/mercurial.js"></script>
389 <script type="text/javascript" src="/static/mercurial.js"></script>
390
390
391 <title>test: a history</title>
391 <title>test: a history</title>
392 <link rel="alternate" type="application/atom+xml"
392 <link rel="alternate" type="application/atom+xml"
393 href="/atom-log/tip/a" title="Atom feed for test:a" />
393 href="/atom-log/tip/a" title="Atom feed for test:a" />
394 <link rel="alternate" type="application/rss+xml"
394 <link rel="alternate" type="application/rss+xml"
395 href="/rss-log/tip/a" title="RSS feed for test:a" />
395 href="/rss-log/tip/a" title="RSS feed for test:a" />
396 </head>
396 </head>
397 <body>
397 <body>
398
398
399 <div class="container">
399 <div class="container">
400 <div class="menu">
400 <div class="menu">
401 <div class="logo">
401 <div class="logo">
402 <a href="https://mercurial-scm.org/">
402 <a href="https://mercurial-scm.org/">
403 <img src="/static/hglogo.png" alt="mercurial" /></a>
403 <img src="/static/hglogo.png" alt="mercurial" /></a>
404 </div>
404 </div>
405 <ul>
405 <ul>
406 <li><a href="/shortlog/3">log</a></li>
406 <li><a href="/shortlog/3">log</a></li>
407 <li><a href="/graph/3">graph</a></li>
407 <li><a href="/graph/3">graph</a></li>
408 <li><a href="/tags">tags</a></li>
408 <li><a href="/tags">tags</a></li>
409 <li><a href="/bookmarks">bookmarks</a></li>
409 <li><a href="/bookmarks">bookmarks</a></li>
410 <li><a href="/branches">branches</a></li>
410 <li><a href="/branches">branches</a></li>
411 </ul>
411 </ul>
412 <ul>
412 <ul>
413 <li><a href="/rev/3">changeset</a></li>
413 <li><a href="/rev/3">changeset</a></li>
414 <li><a href="/file/3">browse</a></li>
414 <li><a href="/file/3">browse</a></li>
415 </ul>
415 </ul>
416 <ul>
416 <ul>
417 <li><a href="/file/3/a">file</a></li>
417 <li><a href="/file/3/a">file</a></li>
418 <li><a href="/diff/3/a">diff</a></li>
418 <li><a href="/diff/3/a">diff</a></li>
419 <li><a href="/comparison/3/a">comparison</a></li>
419 <li><a href="/comparison/3/a">comparison</a></li>
420 <li><a href="/annotate/3/a">annotate</a></li>
420 <li><a href="/annotate/3/a">annotate</a></li>
421 <li class="active">file log</li>
421 <li class="active">file log</li>
422 <li><a href="/raw-file/3/a">raw</a></li>
422 <li><a href="/raw-file/3/a">raw</a></li>
423 </ul>
423 </ul>
424 <ul>
424 <ul>
425 <li><a href="/help">help</a></li>
425 <li><a href="/help">help</a></li>
426 </ul>
426 </ul>
427 <div class="atom-logo">
427 <div class="atom-logo">
428 <a href="/atom-log/tip/a" title="subscribe to atom feed">
428 <a href="/atom-log/tip/a" title="subscribe to atom feed">
429 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
429 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
430 </a>
430 </a>
431 </div>
431 </div>
432 </div>
432 </div>
433
433
434 <div class="main">
434 <div class="main">
435 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
435 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
436 <h3>
436 <h3>
437 log a @ 1:<a href="/rev/5ed941583260">5ed941583260</a>
437 log a @ 1:<a href="/rev/5ed941583260">5ed941583260</a>
438 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
438 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
439
439
440 </h3>
440 </h3>
441
441
442
442
443 <form class="search" action="/log">
443 <form class="search" action="/log">
444
444
445 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
445 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
446 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
446 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
447 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
447 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
448 </form>
448 </form>
449
449
450 <div class="navigate">
450 <div class="navigate">
451 <a href="/log/3/a?revcount=30">less</a>
451 <a href="/log/3/a?revcount=30">less</a>
452 <a href="/log/3/a?revcount=120">more</a>
452 <a href="/log/3/a?revcount=120">more</a>
453 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
453 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
454
454
455 <table class="bigtable">
455 <table class="bigtable">
456 <thead>
456 <thead>
457 <tr>
457 <tr>
458 <th class="age">age</th>
458 <th class="age">age</th>
459 <th class="author">author</th>
459 <th class="author">author</th>
460 <th class="description">description</th>
460 <th class="description">description</th>
461 </tr>
461 </tr>
462 </thead>
462 </thead>
463 <tbody class="stripes2">
463 <tbody class="stripes2">
464 <tr>
464 <tr>
465 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
465 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
466 <td class="author">test</td>
466 <td class="author">test</td>
467 <td class="description">
467 <td class="description">
468 <a href="/rev/5ed941583260">first a</a>
468 <a href="/rev/5ed941583260">first a</a>
469 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
469 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
470 </td>
470 </td>
471 </tr>
471 </tr>
472
472
473
473
474 </tbody>
474 </tbody>
475 </table>
475 </table>
476
476
477 <div class="navigate">
477 <div class="navigate">
478 <a href="/log/3/a?revcount=30">less</a>
478 <a href="/log/3/a?revcount=30">less</a>
479 <a href="/log/3/a?revcount=120">more</a>
479 <a href="/log/3/a?revcount=120">more</a>
480 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
480 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
481 </div>
481 </div>
482
482
483 </div>
483 </div>
484 </div>
484 </div>
485
485
486
486
487
487
488 </body>
488 </body>
489 </html>
489 </html>
490
490
491
491
492 first version - one revision
492 first version - one revision
493
493
494 $ (get-with-headers.py localhost:$HGPORT 'log/1/a')
494 $ (get-with-headers.py localhost:$HGPORT 'log/1/a')
495 200 Script output follows
495 200 Script output follows
496
496
497 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
497 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
498 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
498 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
499 <head>
499 <head>
500 <link rel="icon" href="/static/hgicon.png" type="image/png" />
500 <link rel="icon" href="/static/hgicon.png" type="image/png" />
501 <meta name="robots" content="index, nofollow" />
501 <meta name="robots" content="index, nofollow" />
502 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
502 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
503 <script type="text/javascript" src="/static/mercurial.js"></script>
503 <script type="text/javascript" src="/static/mercurial.js"></script>
504
504
505 <title>test: a history</title>
505 <title>test: a history</title>
506 <link rel="alternate" type="application/atom+xml"
506 <link rel="alternate" type="application/atom+xml"
507 href="/atom-log/tip/a" title="Atom feed for test:a" />
507 href="/atom-log/tip/a" title="Atom feed for test:a" />
508 <link rel="alternate" type="application/rss+xml"
508 <link rel="alternate" type="application/rss+xml"
509 href="/rss-log/tip/a" title="RSS feed for test:a" />
509 href="/rss-log/tip/a" title="RSS feed for test:a" />
510 </head>
510 </head>
511 <body>
511 <body>
512
512
513 <div class="container">
513 <div class="container">
514 <div class="menu">
514 <div class="menu">
515 <div class="logo">
515 <div class="logo">
516 <a href="https://mercurial-scm.org/">
516 <a href="https://mercurial-scm.org/">
517 <img src="/static/hglogo.png" alt="mercurial" /></a>
517 <img src="/static/hglogo.png" alt="mercurial" /></a>
518 </div>
518 </div>
519 <ul>
519 <ul>
520 <li><a href="/shortlog/1">log</a></li>
520 <li><a href="/shortlog/1">log</a></li>
521 <li><a href="/graph/1">graph</a></li>
521 <li><a href="/graph/1">graph</a></li>
522 <li><a href="/tags">tags</a></li>
522 <li><a href="/tags">tags</a></li>
523 <li><a href="/bookmarks">bookmarks</a></li>
523 <li><a href="/bookmarks">bookmarks</a></li>
524 <li><a href="/branches">branches</a></li>
524 <li><a href="/branches">branches</a></li>
525 </ul>
525 </ul>
526 <ul>
526 <ul>
527 <li><a href="/rev/1">changeset</a></li>
527 <li><a href="/rev/1">changeset</a></li>
528 <li><a href="/file/1">browse</a></li>
528 <li><a href="/file/1">browse</a></li>
529 </ul>
529 </ul>
530 <ul>
530 <ul>
531 <li><a href="/file/1/a">file</a></li>
531 <li><a href="/file/1/a">file</a></li>
532 <li><a href="/diff/1/a">diff</a></li>
532 <li><a href="/diff/1/a">diff</a></li>
533 <li><a href="/comparison/1/a">comparison</a></li>
533 <li><a href="/comparison/1/a">comparison</a></li>
534 <li><a href="/annotate/1/a">annotate</a></li>
534 <li><a href="/annotate/1/a">annotate</a></li>
535 <li class="active">file log</li>
535 <li class="active">file log</li>
536 <li><a href="/raw-file/1/a">raw</a></li>
536 <li><a href="/raw-file/1/a">raw</a></li>
537 </ul>
537 </ul>
538 <ul>
538 <ul>
539 <li><a href="/help">help</a></li>
539 <li><a href="/help">help</a></li>
540 </ul>
540 </ul>
541 <div class="atom-logo">
541 <div class="atom-logo">
542 <a href="/atom-log/tip/a" title="subscribe to atom feed">
542 <a href="/atom-log/tip/a" title="subscribe to atom feed">
543 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
543 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
544 </a>
544 </a>
545 </div>
545 </div>
546 </div>
546 </div>
547
547
548 <div class="main">
548 <div class="main">
549 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
549 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
550 <h3>
550 <h3>
551 log a @ 1:<a href="/rev/5ed941583260">5ed941583260</a>
551 log a @ 1:<a href="/rev/5ed941583260">5ed941583260</a>
552 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
552 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
553
553
554 </h3>
554 </h3>
555
555
556
556
557 <form class="search" action="/log">
557 <form class="search" action="/log">
558
558
559 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
559 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
560 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
560 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
561 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
561 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
562 </form>
562 </form>
563
563
564 <div class="navigate">
564 <div class="navigate">
565 <a href="/log/1/a?revcount=30">less</a>
565 <a href="/log/1/a?revcount=30">less</a>
566 <a href="/log/1/a?revcount=120">more</a>
566 <a href="/log/1/a?revcount=120">more</a>
567 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
567 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
568
568
569 <table class="bigtable">
569 <table class="bigtable">
570 <thead>
570 <thead>
571 <tr>
571 <tr>
572 <th class="age">age</th>
572 <th class="age">age</th>
573 <th class="author">author</th>
573 <th class="author">author</th>
574 <th class="description">description</th>
574 <th class="description">description</th>
575 </tr>
575 </tr>
576 </thead>
576 </thead>
577 <tbody class="stripes2">
577 <tbody class="stripes2">
578 <tr>
578 <tr>
579 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
579 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
580 <td class="author">test</td>
580 <td class="author">test</td>
581 <td class="description">
581 <td class="description">
582 <a href="/rev/5ed941583260">first a</a>
582 <a href="/rev/5ed941583260">first a</a>
583 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
583 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
584 </td>
584 </td>
585 </tr>
585 </tr>
586
586
587
587
588 </tbody>
588 </tbody>
589 </table>
589 </table>
590
590
591 <div class="navigate">
591 <div class="navigate">
592 <a href="/log/1/a?revcount=30">less</a>
592 <a href="/log/1/a?revcount=30">less</a>
593 <a href="/log/1/a?revcount=120">more</a>
593 <a href="/log/1/a?revcount=120">more</a>
594 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
594 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
595 </div>
595 </div>
596
596
597 </div>
597 </div>
598 </div>
598 </div>
599
599
600
600
601
601
602 </body>
602 </body>
603 </html>
603 </html>
604
604
605
605
606 before addition - error
606 before addition - error
607
607
608 $ (get-with-headers.py localhost:$HGPORT 'log/0/a')
608 $ (get-with-headers.py localhost:$HGPORT 'log/0/a')
609 404 Not Found
609 404 Not Found
610
610
611 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
611 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
612 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
612 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
613 <head>
613 <head>
614 <link rel="icon" href="/static/hgicon.png" type="image/png" />
614 <link rel="icon" href="/static/hgicon.png" type="image/png" />
615 <meta name="robots" content="index, nofollow" />
615 <meta name="robots" content="index, nofollow" />
616 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
616 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
617 <script type="text/javascript" src="/static/mercurial.js"></script>
617 <script type="text/javascript" src="/static/mercurial.js"></script>
618
618
619 <title>test: error</title>
619 <title>test: error</title>
620 </head>
620 </head>
621 <body>
621 <body>
622
622
623 <div class="container">
623 <div class="container">
624 <div class="menu">
624 <div class="menu">
625 <div class="logo">
625 <div class="logo">
626 <a href="https://mercurial-scm.org/">
626 <a href="https://mercurial-scm.org/">
627 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
627 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
628 </div>
628 </div>
629 <ul>
629 <ul>
630 <li><a href="/shortlog">log</a></li>
630 <li><a href="/shortlog">log</a></li>
631 <li><a href="/graph">graph</a></li>
631 <li><a href="/graph">graph</a></li>
632 <li><a href="/tags">tags</a></li>
632 <li><a href="/tags">tags</a></li>
633 <li><a href="/bookmarks">bookmarks</a></li>
633 <li><a href="/bookmarks">bookmarks</a></li>
634 <li><a href="/branches">branches</a></li>
634 <li><a href="/branches">branches</a></li>
635 </ul>
635 </ul>
636 <ul>
636 <ul>
637 <li><a href="/help">help</a></li>
637 <li><a href="/help">help</a></li>
638 </ul>
638 </ul>
639 </div>
639 </div>
640
640
641 <div class="main">
641 <div class="main">
642
642
643 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
643 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
644 <h3>error</h3>
644 <h3>error</h3>
645
645
646
646
647 <form class="search" action="/log">
647 <form class="search" action="/log">
648
648
649 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
649 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
650 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
650 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
651 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
651 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
652 </form>
652 </form>
653
653
654 <div class="description">
654 <div class="description">
655 <p>
655 <p>
656 An error occurred while processing your request:
656 An error occurred while processing your request:
657 </p>
657 </p>
658 <p>
658 <p>
659 a@6563da9dcf87: not found in manifest
659 a@6563da9dcf87: not found in manifest
660 </p>
660 </p>
661 </div>
661 </div>
662 </div>
662 </div>
663 </div>
663 </div>
664
664
665
665
666
666
667 </body>
667 </body>
668 </html>
668 </html>
669
669
670 [1]
670 [1]
671
671
672 $ hg log -r 'followlines(c, 1:2, startrev=tip) and follow(c)'
672 $ hg log -r 'followlines(c, 1:2, startrev=tip) and follow(c)'
673 changeset: 0:6563da9dcf87
673 changeset: 0:6563da9dcf87
674 user: test
674 user: test
675 date: Thu Jan 01 00:00:00 1970 +0000
675 date: Thu Jan 01 00:00:00 1970 +0000
676 summary: b
676 summary: b
677
677
678 changeset: 7:46c1a66bd8fc
678 changeset: 7:46c1a66bd8fc
679 branch: a-branch
679 branch: a-branch
680 tag: tip
680 tag: tip
681 user: test
681 user: test
682 date: Thu Jan 01 00:00:00 1970 +0000
682 date: Thu Jan 01 00:00:00 1970 +0000
683 summary: change c
683 summary: change c
684
684
685 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=1:2')
685 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=1:2')
686 200 Script output follows
686 200 Script output follows
687
687
688 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
688 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
689 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
689 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
690 <head>
690 <head>
691 <link rel="icon" href="/static/hgicon.png" type="image/png" />
691 <link rel="icon" href="/static/hgicon.png" type="image/png" />
692 <meta name="robots" content="index, nofollow" />
692 <meta name="robots" content="index, nofollow" />
693 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
693 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
694 <script type="text/javascript" src="/static/mercurial.js"></script>
694 <script type="text/javascript" src="/static/mercurial.js"></script>
695
695
696 <title>test: c history</title>
696 <title>test: c history</title>
697 <link rel="alternate" type="application/atom+xml"
697 <link rel="alternate" type="application/atom+xml"
698 href="/atom-log/tip/c" title="Atom feed for test:c" />
698 href="/atom-log/tip/c" title="Atom feed for test:c" />
699 <link rel="alternate" type="application/rss+xml"
699 <link rel="alternate" type="application/rss+xml"
700 href="/rss-log/tip/c" title="RSS feed for test:c" />
700 href="/rss-log/tip/c" title="RSS feed for test:c" />
701 </head>
701 </head>
702 <body>
702 <body>
703
703
704 <div class="container">
704 <div class="container">
705 <div class="menu">
705 <div class="menu">
706 <div class="logo">
706 <div class="logo">
707 <a href="https://mercurial-scm.org/">
707 <a href="https://mercurial-scm.org/">
708 <img src="/static/hglogo.png" alt="mercurial" /></a>
708 <img src="/static/hglogo.png" alt="mercurial" /></a>
709 </div>
709 </div>
710 <ul>
710 <ul>
711 <li><a href="/shortlog/tip">log</a></li>
711 <li><a href="/shortlog/tip">log</a></li>
712 <li><a href="/graph/tip">graph</a></li>
712 <li><a href="/graph/tip">graph</a></li>
713 <li><a href="/tags">tags</a></li>
713 <li><a href="/tags">tags</a></li>
714 <li><a href="/bookmarks">bookmarks</a></li>
714 <li><a href="/bookmarks">bookmarks</a></li>
715 <li><a href="/branches">branches</a></li>
715 <li><a href="/branches">branches</a></li>
716 </ul>
716 </ul>
717 <ul>
717 <ul>
718 <li><a href="/rev/tip">changeset</a></li>
718 <li><a href="/rev/tip">changeset</a></li>
719 <li><a href="/file/tip">browse</a></li>
719 <li><a href="/file/tip">browse</a></li>
720 </ul>
720 </ul>
721 <ul>
721 <ul>
722 <li><a href="/file/tip/c">file</a></li>
722 <li><a href="/file/tip/c">file</a></li>
723 <li><a href="/diff/tip/c">diff</a></li>
723 <li><a href="/diff/tip/c">diff</a></li>
724 <li><a href="/comparison/tip/c">comparison</a></li>
724 <li><a href="/comparison/tip/c">comparison</a></li>
725 <li><a href="/annotate/tip/c">annotate</a></li>
725 <li><a href="/annotate/tip/c">annotate</a></li>
726 <li class="active">file log</li>
726 <li class="active">file log</li>
727 <li><a href="/raw-file/tip/c">raw</a></li>
727 <li><a href="/raw-file/tip/c">raw</a></li>
728 </ul>
728 </ul>
729 <ul>
729 <ul>
730 <li><a href="/help">help</a></li>
730 <li><a href="/help">help</a></li>
731 </ul>
731 </ul>
732 <div class="atom-logo">
732 <div class="atom-logo">
733 <a href="/atom-log/tip/c" title="subscribe to atom feed">
733 <a href="/atom-log/tip/c" title="subscribe to atom feed">
734 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
734 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
735 </a>
735 </a>
736 </div>
736 </div>
737 </div>
737 </div>
738
738
739 <div class="main">
739 <div class="main">
740 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
740 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
741 <h3>
741 <h3>
742 log c @ 7:<a href="/rev/46c1a66bd8fc">46c1a66bd8fc</a>
742 log c @ 7:<a href="/rev/46c1a66bd8fc">46c1a66bd8fc</a>
743 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
743 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
744 (following lines 1:2 <a href="/log/tip/c">all revisions for this file</a>)
744 (following lines 1:2 <a href="/log/tip/c">all revisions for this file</a>)
745 </h3>
745 </h3>
746
746
747
747
748 <form class="search" action="/log">
748 <form class="search" action="/log">
749
749
750 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
750 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
751 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
751 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
752 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
752 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
753 </form>
753 </form>
754
754
755 <div class="navigate">
755 <div class="navigate">
756 <a href="/log/tip/c?linerange=1%3A2&revcount=30">less</a>
756 <a href="/log/tip/c?linerange=1%3A2&revcount=30">less</a>
757 <a href="/log/tip/c?linerange=1%3A2&revcount=120">more</a>
757 <a href="/log/tip/c?linerange=1%3A2&revcount=120">more</a>
758 | </div>
758 | </div>
759
759
760 <table class="bigtable">
760 <table class="bigtable">
761 <thead>
761 <thead>
762 <tr>
762 <tr>
763 <th class="age">age</th>
763 <th class="age">age</th>
764 <th class="author">author</th>
764 <th class="author">author</th>
765 <th class="description">description</th>
765 <th class="description">description</th>
766 </tr>
766 </tr>
767 </thead>
767 </thead>
768 <tbody class="stripes2">
768 <tbody class="stripes2">
769 <tr>
769 <tr>
770 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
770 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
771 <td class="author">test</td>
771 <td class="author">test</td>
772 <td class="description">
772 <td class="description">
773 <a href="/rev/46c1a66bd8fc">change c</a>
773 <a href="/rev/46c1a66bd8fc">change c</a>
774 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
774 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
775 </td>
775 </td>
776 </tr>
776 </tr>
777
777
778 <tr>
778 <tr>
779 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
779 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
780 <td class="author">test</td>
780 <td class="author">test</td>
781 <td class="description">
781 <td class="description">
782 <a href="/rev/6563da9dcf87">b</a>
782 <a href="/rev/6563da9dcf87">b</a>
783 <span class="phase">draft</span>
783 <span class="phase">draft</span>
784 </td>
784 </td>
785 </tr>
785 </tr>
786
786
787
787
788 </tbody>
788 </tbody>
789 </table>
789 </table>
790
790
791 <div class="navigate">
791 <div class="navigate">
792 <a href="/log/tip/c?linerange=1%3A2&revcount=30">less</a>
792 <a href="/log/tip/c?linerange=1%3A2&revcount=30">less</a>
793 <a href="/log/tip/c?linerange=1%3A2&revcount=120">more</a>
793 <a href="/log/tip/c?linerange=1%3A2&revcount=120">more</a>
794 |
794 |
795 </div>
795 </div>
796
796
797 </div>
797 </div>
798 </div>
798 </div>
799
799
800
800
801
801
802 </body>
802 </body>
803 </html>
803 </html>
804
804
805 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=1%3A2&revcount=1')
805 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=1%3A2&revcount=1')
806 200 Script output follows
806 200 Script output follows
807
807
808 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
808 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
809 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
809 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
810 <head>
810 <head>
811 <link rel="icon" href="/static/hgicon.png" type="image/png" />
811 <link rel="icon" href="/static/hgicon.png" type="image/png" />
812 <meta name="robots" content="index, nofollow" />
812 <meta name="robots" content="index, nofollow" />
813 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
813 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
814 <script type="text/javascript" src="/static/mercurial.js"></script>
814 <script type="text/javascript" src="/static/mercurial.js"></script>
815
815
816 <title>test: c history</title>
816 <title>test: c history</title>
817 <link rel="alternate" type="application/atom+xml"
817 <link rel="alternate" type="application/atom+xml"
818 href="/atom-log/tip/c" title="Atom feed for test:c" />
818 href="/atom-log/tip/c" title="Atom feed for test:c" />
819 <link rel="alternate" type="application/rss+xml"
819 <link rel="alternate" type="application/rss+xml"
820 href="/rss-log/tip/c" title="RSS feed for test:c" />
820 href="/rss-log/tip/c" title="RSS feed for test:c" />
821 </head>
821 </head>
822 <body>
822 <body>
823
823
824 <div class="container">
824 <div class="container">
825 <div class="menu">
825 <div class="menu">
826 <div class="logo">
826 <div class="logo">
827 <a href="https://mercurial-scm.org/">
827 <a href="https://mercurial-scm.org/">
828 <img src="/static/hglogo.png" alt="mercurial" /></a>
828 <img src="/static/hglogo.png" alt="mercurial" /></a>
829 </div>
829 </div>
830 <ul>
830 <ul>
831 <li><a href="/shortlog/tip?revcount=1">log</a></li>
831 <li><a href="/shortlog/tip?revcount=1">log</a></li>
832 <li><a href="/graph/tip?revcount=1">graph</a></li>
832 <li><a href="/graph/tip?revcount=1">graph</a></li>
833 <li><a href="/tags?revcount=1">tags</a></li>
833 <li><a href="/tags?revcount=1">tags</a></li>
834 <li><a href="/bookmarks?revcount=1">bookmarks</a></li>
834 <li><a href="/bookmarks?revcount=1">bookmarks</a></li>
835 <li><a href="/branches?revcount=1">branches</a></li>
835 <li><a href="/branches?revcount=1">branches</a></li>
836 </ul>
836 </ul>
837 <ul>
837 <ul>
838 <li><a href="/rev/tip?revcount=1">changeset</a></li>
838 <li><a href="/rev/tip?revcount=1">changeset</a></li>
839 <li><a href="/file/tip?revcount=1">browse</a></li>
839 <li><a href="/file/tip?revcount=1">browse</a></li>
840 </ul>
840 </ul>
841 <ul>
841 <ul>
842 <li><a href="/file/tip/c?revcount=1">file</a></li>
842 <li><a href="/file/tip/c?revcount=1">file</a></li>
843 <li><a href="/diff/tip/c?revcount=1">diff</a></li>
843 <li><a href="/diff/tip/c?revcount=1">diff</a></li>
844 <li><a href="/comparison/tip/c?revcount=1">comparison</a></li>
844 <li><a href="/comparison/tip/c?revcount=1">comparison</a></li>
845 <li><a href="/annotate/tip/c?revcount=1">annotate</a></li>
845 <li><a href="/annotate/tip/c?revcount=1">annotate</a></li>
846 <li class="active">file log</li>
846 <li class="active">file log</li>
847 <li><a href="/raw-file/tip/c">raw</a></li>
847 <li><a href="/raw-file/tip/c">raw</a></li>
848 </ul>
848 </ul>
849 <ul>
849 <ul>
850 <li><a href="/help?revcount=1">help</a></li>
850 <li><a href="/help?revcount=1">help</a></li>
851 </ul>
851 </ul>
852 <div class="atom-logo">
852 <div class="atom-logo">
853 <a href="/atom-log/tip/c" title="subscribe to atom feed">
853 <a href="/atom-log/tip/c" title="subscribe to atom feed">
854 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
854 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
855 </a>
855 </a>
856 </div>
856 </div>
857 </div>
857 </div>
858
858
859 <div class="main">
859 <div class="main">
860 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
860 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
861 <h3>
861 <h3>
862 log c @ 7:<a href="/rev/46c1a66bd8fc?revcount=1">46c1a66bd8fc</a>
862 log c @ 7:<a href="/rev/46c1a66bd8fc?revcount=1">46c1a66bd8fc</a>
863 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
863 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
864 (following lines 1:2 <a href="/log/tip/c?revcount=1">all revisions for this file</a>)
864 (following lines 1:2 <a href="/log/tip/c?revcount=1">all revisions for this file</a>)
865 </h3>
865 </h3>
866
866
867
867
868 <form class="search" action="/log">
868 <form class="search" action="/log">
869 <input type="hidden" name="revcount" value="1" />
869 <input type="hidden" name="revcount" value="1" />
870 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
870 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
871 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
871 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
872 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
872 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
873 </form>
873 </form>
874
874
875 <div class="navigate">
875 <div class="navigate">
876 <a href="/log/tip/c?linerange=1%3A2&revcount=1">less</a>
876 <a href="/log/tip/c?linerange=1%3A2&revcount=1">less</a>
877 <a href="/log/tip/c?linerange=1%3A2&revcount=2">more</a>
877 <a href="/log/tip/c?linerange=1%3A2&revcount=2">more</a>
878 | </div>
878 | </div>
879
879
880 <table class="bigtable">
880 <table class="bigtable">
881 <thead>
881 <thead>
882 <tr>
882 <tr>
883 <th class="age">age</th>
883 <th class="age">age</th>
884 <th class="author">author</th>
884 <th class="author">author</th>
885 <th class="description">description</th>
885 <th class="description">description</th>
886 </tr>
886 </tr>
887 </thead>
887 </thead>
888 <tbody class="stripes2">
888 <tbody class="stripes2">
889 <tr>
889 <tr>
890 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
890 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
891 <td class="author">test</td>
891 <td class="author">test</td>
892 <td class="description">
892 <td class="description">
893 <a href="/rev/46c1a66bd8fc?revcount=1">change c</a>
893 <a href="/rev/46c1a66bd8fc?revcount=1">change c</a>
894 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
894 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
895 </td>
895 </td>
896 </tr>
896 </tr>
897
897
898
898
899 </tbody>
899 </tbody>
900 </table>
900 </table>
901
901
902 <div class="navigate">
902 <div class="navigate">
903 <a href="/log/tip/c?linerange=1%3A2&revcount=1">less</a>
903 <a href="/log/tip/c?linerange=1%3A2&revcount=1">less</a>
904 <a href="/log/tip/c?linerange=1%3A2&revcount=2">more</a>
904 <a href="/log/tip/c?linerange=1%3A2&revcount=2">more</a>
905 |
905 |
906 </div>
906 </div>
907
907
908 </div>
908 </div>
909 </div>
909 </div>
910
910
911
911
912
912
913 </body>
913 </body>
914 </html>
914 </html>
915
915
916 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=1' --headeronly)
916 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=1' --headeronly)
917 400 invalid linerange parameter
917 400 invalid linerange parameter
918 [1]
918 [1]
919 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=1:a' --headeronly)
919 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=1:a' --headeronly)
920 400 invalid linerange parameter
920 400 invalid linerange parameter
921 [1]
921 [1]
922 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=1:2&linerange=3:4' --headeronly)
922 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=1:2&linerange=3:4' --headeronly)
923 400 redundant linerange parameter
923 400 redundant linerange parameter
924 [1]
924 [1]
925 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=3:2' --headeronly)
925 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=3:2' --headeronly)
926 400 line range must be positive
926 400 line range must be positive
927 [1]
927 [1]
928 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=0:1' --headeronly)
928 $ (get-with-headers.py localhost:$HGPORT 'log/3/a?linerange=0:1' --headeronly)
929 400 fromline must be strictly positive
929 400 fromline must be strictly positive
930 [1]
930 [1]
931
931
932 should show base link, use spartan because it shows it
932 should show base link, use spartan because it shows it
933
933
934 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?style=spartan')
934 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?style=spartan')
935 200 Script output follows
935 200 Script output follows
936
936
937 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
937 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
938 <html>
938 <html>
939 <head>
939 <head>
940 <link rel="icon" href="/static/hgicon.png" type="image/png">
940 <link rel="icon" href="/static/hgicon.png" type="image/png">
941 <meta name="robots" content="index, nofollow" />
941 <meta name="robots" content="index, nofollow" />
942 <link rel="stylesheet" href="/static/style.css" type="text/css" />
942 <link rel="stylesheet" href="/static/style.css" type="text/css" />
943 <script type="text/javascript" src="/static/mercurial.js"></script>
943 <script type="text/javascript" src="/static/mercurial.js"></script>
944
944
945 <title>test: c history</title>
945 <title>test: c history</title>
946 <link rel="alternate" type="application/atom+xml"
946 <link rel="alternate" type="application/atom+xml"
947 href="/atom-log/tip/c" title="Atom feed for test:c">
947 href="/atom-log/tip/c" title="Atom feed for test:c">
948 <link rel="alternate" type="application/rss+xml"
948 <link rel="alternate" type="application/rss+xml"
949 href="/rss-log/tip/c" title="RSS feed for test:c">
949 href="/rss-log/tip/c" title="RSS feed for test:c">
950 </head>
950 </head>
951 <body>
951 <body>
952
952
953 <div class="buttons">
953 <div class="buttons">
954 <a href="/log?style=spartan">changelog</a>
954 <a href="/log?style=spartan">changelog</a>
955 <a href="/shortlog?style=spartan">shortlog</a>
955 <a href="/shortlog?style=spartan">shortlog</a>
956 <a href="/graph?style=spartan">graph</a>
956 <a href="/graph?style=spartan">graph</a>
957 <a href="/tags?style=spartan">tags</a>
957 <a href="/tags?style=spartan">tags</a>
958 <a href="/branches?style=spartan">branches</a>
958 <a href="/branches?style=spartan">branches</a>
959 <a href="/file/tip/c?style=spartan">file</a>
959 <a href="/file/tip/c?style=spartan">file</a>
960 <a href="/annotate/tip/c?style=spartan">annotate</a>
960 <a href="/annotate/tip/c?style=spartan">annotate</a>
961 <a href="/help?style=spartan">help</a>
961 <a href="/help?style=spartan">help</a>
962 <a type="application/rss+xml" href="/rss-log/tip/c">rss</a>
962 <a type="application/rss+xml" href="/rss-log/tip/c">rss</a>
963 <a type="application/atom+xml" href="/atom-log/tip/c" title="Atom feed for test:c">atom</a>
963 <a type="application/atom+xml" href="/atom-log/tip/c" title="Atom feed for test:c">atom</a>
964 </div>
964 </div>
965
965
966 <h2><a href="/">Mercurial</a> / c revision history</h2>
966 <h2><a href="/">Mercurial</a> / c revision history</h2>
967
967
968 <p>navigate: <small class="navigate"><a href="/log/c9637d3cc8ef/c?style=spartan">(0)</a> <a href="/log/tip/c?style=spartan">tip</a> </small></p>
968 <p>navigate: <small class="navigate"><a href="/log/c9637d3cc8ef/c?style=spartan">(0)</a> <a href="/log/tip/c?style=spartan">tip</a> </small></p>
969
969
970 <table class="logEntry parity0">
970 <table class="logEntry parity0">
971 <tr>
971 <tr>
972 <th class="label"><span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span>:</th>
972 <th class="label"><span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span>:</th>
973 <th class="firstline"><a href="/rev/46c1a66bd8fc?style=spartan">change c</a></th>
973 <th class="firstline"><a href="/rev/46c1a66bd8fc?style=spartan">change c</a></th>
974 </tr>
974 </tr>
975 <tr>
975 <tr>
976 <th class="revision">revision 1:</th>
976 <th class="revision">revision 1:</th>
977 <td class="node">
977 <td class="node">
978 <a href="/file/46c1a66bd8fc/c?style=spartan">46c1a66bd8fc</a>
978 <a href="/file/46c1a66bd8fc/c?style=spartan">46c1a66bd8fc</a>
979 <a href="/diff/46c1a66bd8fc/c?style=spartan">(diff)</a>
979 <a href="/diff/46c1a66bd8fc/c?style=spartan">(diff)</a>
980 <a href="/annotate/46c1a66bd8fc/c?style=spartan">(annotate)</a>
980 <a href="/annotate/46c1a66bd8fc/c?style=spartan">(annotate)</a>
981 </td>
981 </td>
982 </tr>
982 </tr>
983
983
984 <tr>
984 <tr>
985 <th class="author">author:</th>
985 <th class="author">author:</th>
986 <td class="author">&#116;&#101;&#115;&#116;</td>
986 <td class="author">&#116;&#101;&#115;&#116;</td>
987 </tr>
987 </tr>
988 <tr>
988 <tr>
989 <th class="date">date:</th>
989 <th class="date">date:</th>
990 <td class="date">Thu, 01 Jan 1970 00:00:00 +0000</td>
990 <td class="date">Thu, 01 Jan 1970 00:00:00 +0000</td>
991 </tr>
991 </tr>
992 </table>
992 </table>
993
993
994
994
995 <table class="logEntry parity1">
995 <table class="logEntry parity1">
996 <tr>
996 <tr>
997 <th class="label"><span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span>:</th>
997 <th class="label"><span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span>:</th>
998 <th class="firstline"><a href="/rev/c9637d3cc8ef?style=spartan">mv b</a></th>
998 <th class="firstline"><a href="/rev/c9637d3cc8ef?style=spartan">mv b</a></th>
999 </tr>
999 </tr>
1000 <tr>
1000 <tr>
1001 <th class="revision">revision 0:</th>
1001 <th class="revision">revision 0:</th>
1002 <td class="node">
1002 <td class="node">
1003 <a href="/file/c9637d3cc8ef/c?style=spartan">c9637d3cc8ef</a>
1003 <a href="/file/c9637d3cc8ef/c?style=spartan">c9637d3cc8ef</a>
1004 <a href="/diff/c9637d3cc8ef/c?style=spartan">(diff)</a>
1004 <a href="/diff/c9637d3cc8ef/c?style=spartan">(diff)</a>
1005 <a href="/annotate/c9637d3cc8ef/c?style=spartan">(annotate)</a>
1005 <a href="/annotate/c9637d3cc8ef/c?style=spartan">(annotate)</a>
1006 </td>
1006 </td>
1007 </tr>
1007 </tr>
1008
1008
1009 <tr>
1009 <tr>
1010 <th>base:</th>
1010 <th>base:</th>
1011 <td>
1011 <td>
1012 <a href="/file/1e88685f5dde/b?style=spartan">
1012 <a href="/file/1e88685f5dde/b?style=spartan">
1013 b@1e88685f5dde
1013 b@1e88685f5dde
1014 </a>
1014 </a>
1015 </td>
1015 </td>
1016 </tr>
1016 </tr>
1017 <tr>
1017 <tr>
1018 <th class="author">author:</th>
1018 <th class="author">author:</th>
1019 <td class="author">&#116;&#101;&#115;&#116;</td>
1019 <td class="author">&#116;&#101;&#115;&#116;</td>
1020 </tr>
1020 </tr>
1021 <tr>
1021 <tr>
1022 <th class="date">date:</th>
1022 <th class="date">date:</th>
1023 <td class="date">Thu, 01 Jan 1970 00:00:00 +0000</td>
1023 <td class="date">Thu, 01 Jan 1970 00:00:00 +0000</td>
1024 </tr>
1024 </tr>
1025 </table>
1025 </table>
1026
1026
1027
1027
1028
1028
1029
1029
1030
1030
1031 <div class="logo">
1031 <div class="logo">
1032 <a href="https://mercurial-scm.org/">
1032 <a href="https://mercurial-scm.org/">
1033 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
1033 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
1034 </div>
1034 </div>
1035
1035
1036 </body>
1036 </body>
1037 </html>
1037 </html>
1038
1038
1039
1039
1040 filelog with patch
1040 filelog with patch
1041
1041
1042 $ (get-with-headers.py localhost:$HGPORT 'log/4/a?patch=1')
1042 $ (get-with-headers.py localhost:$HGPORT 'log/4/a?patch=1')
1043 200 Script output follows
1043 200 Script output follows
1044
1044
1045 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1045 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1046 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1046 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1047 <head>
1047 <head>
1048 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1048 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1049 <meta name="robots" content="index, nofollow" />
1049 <meta name="robots" content="index, nofollow" />
1050 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1050 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1051 <script type="text/javascript" src="/static/mercurial.js"></script>
1051 <script type="text/javascript" src="/static/mercurial.js"></script>
1052
1052
1053 <title>test: a history</title>
1053 <title>test: a history</title>
1054 <link rel="alternate" type="application/atom+xml"
1054 <link rel="alternate" type="application/atom+xml"
1055 href="/atom-log/tip/a" title="Atom feed for test:a" />
1055 href="/atom-log/tip/a" title="Atom feed for test:a" />
1056 <link rel="alternate" type="application/rss+xml"
1056 <link rel="alternate" type="application/rss+xml"
1057 href="/rss-log/tip/a" title="RSS feed for test:a" />
1057 href="/rss-log/tip/a" title="RSS feed for test:a" />
1058 </head>
1058 </head>
1059 <body>
1059 <body>
1060
1060
1061 <div class="container">
1061 <div class="container">
1062 <div class="menu">
1062 <div class="menu">
1063 <div class="logo">
1063 <div class="logo">
1064 <a href="https://mercurial-scm.org/">
1064 <a href="https://mercurial-scm.org/">
1065 <img src="/static/hglogo.png" alt="mercurial" /></a>
1065 <img src="/static/hglogo.png" alt="mercurial" /></a>
1066 </div>
1066 </div>
1067 <ul>
1067 <ul>
1068 <li><a href="/shortlog/4">log</a></li>
1068 <li><a href="/shortlog/4">log</a></li>
1069 <li><a href="/graph/4">graph</a></li>
1069 <li><a href="/graph/4">graph</a></li>
1070 <li><a href="/tags">tags</a></li>
1070 <li><a href="/tags">tags</a></li>
1071 <li><a href="/bookmarks">bookmarks</a></li>
1071 <li><a href="/bookmarks">bookmarks</a></li>
1072 <li><a href="/branches">branches</a></li>
1072 <li><a href="/branches">branches</a></li>
1073 </ul>
1073 </ul>
1074 <ul>
1074 <ul>
1075 <li><a href="/rev/4">changeset</a></li>
1075 <li><a href="/rev/4">changeset</a></li>
1076 <li><a href="/file/4">browse</a></li>
1076 <li><a href="/file/4">browse</a></li>
1077 </ul>
1077 </ul>
1078 <ul>
1078 <ul>
1079 <li><a href="/file/4/a">file</a></li>
1079 <li><a href="/file/4/a">file</a></li>
1080 <li><a href="/diff/4/a">diff</a></li>
1080 <li><a href="/diff/4/a">diff</a></li>
1081 <li><a href="/comparison/4/a">comparison</a></li>
1081 <li><a href="/comparison/4/a">comparison</a></li>
1082 <li><a href="/annotate/4/a">annotate</a></li>
1082 <li><a href="/annotate/4/a">annotate</a></li>
1083 <li class="active">file log</li>
1083 <li class="active">file log</li>
1084 <li><a href="/raw-file/4/a">raw</a></li>
1084 <li><a href="/raw-file/4/a">raw</a></li>
1085 </ul>
1085 </ul>
1086 <ul>
1086 <ul>
1087 <li><a href="/help">help</a></li>
1087 <li><a href="/help">help</a></li>
1088 </ul>
1088 </ul>
1089 <div class="atom-logo">
1089 <div class="atom-logo">
1090 <a href="/atom-log/tip/a" title="subscribe to atom feed">
1090 <a href="/atom-log/tip/a" title="subscribe to atom feed">
1091 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
1091 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
1092 </a>
1092 </a>
1093 </div>
1093 </div>
1094 </div>
1094 </div>
1095
1095
1096 <div class="main">
1096 <div class="main">
1097 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1097 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1098 <h3>
1098 <h3>
1099 log a @ 4:<a href="/rev/3f41bc784e7e">3f41bc784e7e</a>
1099 log a @ 4:<a href="/rev/3f41bc784e7e">3f41bc784e7e</a>
1100 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1100 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1101
1101
1102 </h3>
1102 </h3>
1103
1103
1104
1104
1105 <form class="search" action="/log">
1105 <form class="search" action="/log">
1106
1106
1107 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
1107 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
1108 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1108 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1109 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1109 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1110 </form>
1110 </form>
1111
1111
1112 <div class="navigate">
1112 <div class="navigate">
1113 <a href="/log/4/a?patch=1&revcount=30">less</a>
1113 <a href="/log/4/a?patch=1&revcount=30">less</a>
1114 <a href="/log/4/a?patch=1&revcount=120">more</a>
1114 <a href="/log/4/a?patch=1&revcount=120">more</a>
1115 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
1115 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </div>
1116
1116
1117 <table class="bigtable">
1117 <table class="bigtable">
1118 <thead>
1118 <thead>
1119 <tr>
1119 <tr>
1120 <th class="age">age</th>
1120 <th class="age">age</th>
1121 <th class="author">author</th>
1121 <th class="author">author</th>
1122 <th class="description">description</th>
1122 <th class="description">description</th>
1123 </tr>
1123 </tr>
1124 </thead>
1124 </thead>
1125 <tbody class="stripes2">
1125 <tbody class="stripes2">
1126 <tr>
1126 <tr>
1127 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1127 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1128 <td class="author">test</td>
1128 <td class="author">test</td>
1129 <td class="description">
1129 <td class="description">
1130 <a href="/rev/3f41bc784e7e">second a</a>
1130 <a href="/rev/3f41bc784e7e">second a</a>
1131 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1131 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1132 </td>
1132 </td>
1133 </tr>
1133 </tr>
1134 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1134 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1135 <span id="3f41bc784e7e-l1.1" class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000</span><a href="#3f41bc784e7e-l1.1"></a>
1135 <span id="3f41bc784e7e-l1.1" class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000</span><a href="#3f41bc784e7e-l1.1"></a>
1136 <span id="3f41bc784e7e-l1.2" class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000</span><a href="#3f41bc784e7e-l1.2"></a>
1136 <span id="3f41bc784e7e-l1.2" class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000</span><a href="#3f41bc784e7e-l1.2"></a>
1137 <span id="3f41bc784e7e-l1.3" class="atline">@@ -0,0 +1,1 @@</span><a href="#3f41bc784e7e-l1.3"></a>
1137 <span id="3f41bc784e7e-l1.3" class="atline">@@ -0,0 +1,1 @@</span><a href="#3f41bc784e7e-l1.3"></a>
1138 <span id="3f41bc784e7e-l1.4" class="plusline">+b</span><a href="#3f41bc784e7e-l1.4"></a></pre></div></td></tr>
1138 <span id="3f41bc784e7e-l1.4" class="plusline">+b</span><a href="#3f41bc784e7e-l1.4"></a></pre></div></td></tr>
1139 <tr>
1139 <tr>
1140 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1140 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1141 <td class="author">test</td>
1141 <td class="author">test</td>
1142 <td class="description">
1142 <td class="description">
1143 <a href="/rev/5ed941583260">first a</a>
1143 <a href="/rev/5ed941583260">first a</a>
1144 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
1144 <span class="phase">draft</span> <span class="tag">a-tag</span> <span class="tag">a-bookmark</span>
1145 </td>
1145 </td>
1146 </tr>
1146 </tr>
1147 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1147 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1148 <span id="5ed941583260-l1.1" class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000</span><a href="#5ed941583260-l1.1"></a>
1148 <span id="5ed941583260-l1.1" class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000</span><a href="#5ed941583260-l1.1"></a>
1149 <span id="5ed941583260-l1.2" class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000</span><a href="#5ed941583260-l1.2"></a>
1149 <span id="5ed941583260-l1.2" class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000</span><a href="#5ed941583260-l1.2"></a>
1150 <span id="5ed941583260-l1.3" class="atline">@@ -0,0 +1,1 @@</span><a href="#5ed941583260-l1.3"></a>
1150 <span id="5ed941583260-l1.3" class="atline">@@ -0,0 +1,1 @@</span><a href="#5ed941583260-l1.3"></a>
1151 <span id="5ed941583260-l1.4" class="plusline">+a</span><a href="#5ed941583260-l1.4"></a></pre></div></td></tr>
1151 <span id="5ed941583260-l1.4" class="plusline">+a</span><a href="#5ed941583260-l1.4"></a></pre></div></td></tr>
1152
1152
1153 </tbody>
1153 </tbody>
1154 </table>
1154 </table>
1155
1155
1156 <div class="navigate">
1156 <div class="navigate">
1157 <a href="/log/4/a?patch=1&revcount=30">less</a>
1157 <a href="/log/4/a?patch=1&revcount=30">less</a>
1158 <a href="/log/4/a?patch=1&revcount=120">more</a>
1158 <a href="/log/4/a?patch=1&revcount=120">more</a>
1159 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
1159 | <a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a>
1160 </div>
1160 </div>
1161
1161
1162 </div>
1162 </div>
1163 </div>
1163 </div>
1164
1164
1165
1165
1166
1166
1167 </body>
1167 </body>
1168 </html>
1168 </html>
1169
1169
1170 filelog with 'linerange' and 'patch'
1170 filelog with 'linerange' and 'patch'
1171
1171
1172 $ cat c
1172 $ cat c
1173 b
1173 b
1174 c
1174 c
1175 $ cat <<EOF > c
1175 $ cat <<EOF > c
1176 > 0
1176 > 0
1177 > 0
1177 > 0
1178 > b
1178 > b
1179 > c+
1179 > c+
1180 >
1180 >
1181 > a
1181 > a
1182 > a
1182 > a
1183 >
1183 >
1184 > d
1184 > d
1185 > e
1185 > e
1186 > f
1186 > f
1187 > EOF
1187 > EOF
1188 $ hg ci -m 'make c bigger and touch its beginning' c
1188 $ hg ci -m 'make c bigger and touch its beginning' c
1189 $ cat <<EOF > c
1189 $ cat <<EOF > c
1190 > 0
1190 > 0
1191 > 0
1191 > 0
1192 > b
1192 > b
1193 > c+
1193 > c+
1194 >
1194 >
1195 > a
1195 > a
1196 > a
1196 > a
1197 >
1197 >
1198 > d
1198 > d
1199 > e+
1199 > e+
1200 > f
1200 > f
1201 > EOF
1201 > EOF
1202 $ hg ci -m 'just touch end of c' c
1202 $ hg ci -m 'just touch end of c' c
1203 $ cat <<EOF > c
1203 $ cat <<EOF > c
1204 > 0
1204 > 0
1205 > 0
1205 > 0
1206 > b
1206 > b
1207 > c++
1207 > c++
1208 >
1208 >
1209 > a
1209 > a
1210 > a
1210 > a
1211 >
1211 >
1212 > d
1212 > d
1213 > e+
1213 > e+
1214 > f
1214 > f
1215 > EOF
1215 > EOF
1216 $ hg ci -m 'touch beginning of c' c
1216 $ hg ci -m 'touch beginning of c' c
1217 $ cat <<EOF > c
1217 $ cat <<EOF > c
1218 > 0
1218 > 0
1219 > 0
1219 > 0
1220 > b-
1220 > b-
1221 > c++
1221 > c++
1222 >
1222 >
1223 > a
1223 > a
1224 > a
1224 > a
1225 >
1225 >
1226 > d
1226 > d
1227 > e+
1227 > e+
1228 > f+
1228 > f+
1229 > EOF
1229 > EOF
1230 $ hg ci -m 'touching beginning and end of c' c
1230 $ hg ci -m 'touching beginning and end of c' c
1231 $ echo c > cc
1231 $ echo c > cc
1232 $ hg ci -Am 'tip does not touch c' cc
1232 $ hg ci -Am 'tip does not touch c' cc
1233 $ hg log -r 'followlines(c, 3:4, startrev=tip) and follow(c)' -p
1233 $ hg log -r 'followlines(c, 3:4, startrev=tip) and follow(c)' -p
1234 changeset: 0:6563da9dcf87
1234 changeset: 0:6563da9dcf87
1235 user: test
1235 user: test
1236 date: Thu Jan 01 00:00:00 1970 +0000
1236 date: Thu Jan 01 00:00:00 1970 +0000
1237 summary: b
1237 summary: b
1238
1238
1239 diff -r 000000000000 -r 6563da9dcf87 b
1239 diff -r 000000000000 -r 6563da9dcf87 b
1240 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1240 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1241 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1241 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1242 @@ -0,0 +1,1 @@
1242 @@ -0,0 +1,1 @@
1243 +b
1243 +b
1244
1244
1245 changeset: 7:46c1a66bd8fc
1245 changeset: 7:46c1a66bd8fc
1246 branch: a-branch
1246 branch: a-branch
1247 user: test
1247 user: test
1248 date: Thu Jan 01 00:00:00 1970 +0000
1248 date: Thu Jan 01 00:00:00 1970 +0000
1249 summary: change c
1249 summary: change c
1250
1250
1251 diff -r c9637d3cc8ef -r 46c1a66bd8fc c
1251 diff -r c9637d3cc8ef -r 46c1a66bd8fc c
1252 --- a/c Thu Jan 01 00:00:00 1970 +0000
1252 --- a/c Thu Jan 01 00:00:00 1970 +0000
1253 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1253 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1254 @@ -1,1 +1,2 @@
1254 @@ -1,1 +1,2 @@
1255 b
1255 b
1256 +c
1256 +c
1257
1257
1258 changeset: 8:5c6574614c37
1258 changeset: 8:5c6574614c37
1259 branch: a-branch
1259 branch: a-branch
1260 user: test
1260 user: test
1261 date: Thu Jan 01 00:00:00 1970 +0000
1261 date: Thu Jan 01 00:00:00 1970 +0000
1262 summary: make c bigger and touch its beginning
1262 summary: make c bigger and touch its beginning
1263
1263
1264 diff -r 46c1a66bd8fc -r 5c6574614c37 c
1264 diff -r 46c1a66bd8fc -r 5c6574614c37 c
1265 --- a/c Thu Jan 01 00:00:00 1970 +0000
1265 --- a/c Thu Jan 01 00:00:00 1970 +0000
1266 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1266 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1267 @@ -1,2 +1,11 @@
1267 @@ -1,2 +1,11 @@
1268 +0
1268 +0
1269 +0
1269 +0
1270 b
1270 b
1271 -c
1271 -c
1272 +c+
1272 +c+
1273 +
1273 +
1274 +a
1274 +a
1275 +a
1275 +a
1276 +
1276 +
1277 +d
1277 +d
1278 +e
1278 +e
1279 +f
1279 +f
1280
1280
1281 changeset: 10:e95928d60479
1281 changeset: 10:e95928d60479
1282 branch: a-branch
1282 branch: a-branch
1283 user: test
1283 user: test
1284 date: Thu Jan 01 00:00:00 1970 +0000
1284 date: Thu Jan 01 00:00:00 1970 +0000
1285 summary: touch beginning of c
1285 summary: touch beginning of c
1286
1286
1287 diff -r e1d3e9c5a23f -r e95928d60479 c
1287 diff -r e1d3e9c5a23f -r e95928d60479 c
1288 --- a/c Thu Jan 01 00:00:00 1970 +0000
1288 --- a/c Thu Jan 01 00:00:00 1970 +0000
1289 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1289 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1290 @@ -1,7 +1,7 @@
1290 @@ -1,7 +1,7 @@
1291 0
1291 0
1292 0
1292 0
1293 b
1293 b
1294 -c+
1294 -c+
1295 +c++
1295 +c++
1296
1296
1297 a
1297 a
1298 a
1298 a
1299
1299
1300 changeset: 11:fb9bc322513a
1300 changeset: 11:fb9bc322513a
1301 branch: a-branch
1301 branch: a-branch
1302 user: test
1302 user: test
1303 date: Thu Jan 01 00:00:00 1970 +0000
1303 date: Thu Jan 01 00:00:00 1970 +0000
1304 summary: touching beginning and end of c
1304 summary: touching beginning and end of c
1305
1305
1306 diff -r e95928d60479 -r fb9bc322513a c
1306 diff -r e95928d60479 -r fb9bc322513a c
1307 --- a/c Thu Jan 01 00:00:00 1970 +0000
1307 --- a/c Thu Jan 01 00:00:00 1970 +0000
1308 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1308 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1309 @@ -1,6 +1,6 @@
1309 @@ -1,6 +1,6 @@
1310 0
1310 0
1311 0
1311 0
1312 -b
1312 -b
1313 +b-
1313 +b-
1314 c++
1314 c++
1315
1315
1316 a
1316 a
1317 @@ -8,4 +8,4 @@
1317 @@ -8,4 +8,4 @@
1318
1318
1319 d
1319 d
1320 e+
1320 e+
1321 -f
1321 -f
1322 +f+
1322 +f+
1323
1323
1324 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=3:4&patch=')
1324 $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=3:4&patch=')
1325 200 Script output follows
1325 200 Script output follows
1326
1326
1327 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1327 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1328 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1328 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1329 <head>
1329 <head>
1330 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1330 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1331 <meta name="robots" content="index, nofollow" />
1331 <meta name="robots" content="index, nofollow" />
1332 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1332 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1333 <script type="text/javascript" src="/static/mercurial.js"></script>
1333 <script type="text/javascript" src="/static/mercurial.js"></script>
1334
1334
1335 <title>test: c history</title>
1335 <title>test: c history</title>
1336 <link rel="alternate" type="application/atom+xml"
1336 <link rel="alternate" type="application/atom+xml"
1337 href="/atom-log/tip/c" title="Atom feed for test:c" />
1337 href="/atom-log/tip/c" title="Atom feed for test:c" />
1338 <link rel="alternate" type="application/rss+xml"
1338 <link rel="alternate" type="application/rss+xml"
1339 href="/rss-log/tip/c" title="RSS feed for test:c" />
1339 href="/rss-log/tip/c" title="RSS feed for test:c" />
1340 </head>
1340 </head>
1341 <body>
1341 <body>
1342
1342
1343 <div class="container">
1343 <div class="container">
1344 <div class="menu">
1344 <div class="menu">
1345 <div class="logo">
1345 <div class="logo">
1346 <a href="https://mercurial-scm.org/">
1346 <a href="https://mercurial-scm.org/">
1347 <img src="/static/hglogo.png" alt="mercurial" /></a>
1347 <img src="/static/hglogo.png" alt="mercurial" /></a>
1348 </div>
1348 </div>
1349 <ul>
1349 <ul>
1350 <li><a href="/shortlog/tip">log</a></li>
1350 <li><a href="/shortlog/tip">log</a></li>
1351 <li><a href="/graph/tip">graph</a></li>
1351 <li><a href="/graph/tip">graph</a></li>
1352 <li><a href="/tags">tags</a></li>
1352 <li><a href="/tags">tags</a></li>
1353 <li><a href="/bookmarks">bookmarks</a></li>
1353 <li><a href="/bookmarks">bookmarks</a></li>
1354 <li><a href="/branches">branches</a></li>
1354 <li><a href="/branches">branches</a></li>
1355 </ul>
1355 </ul>
1356 <ul>
1356 <ul>
1357 <li><a href="/rev/tip">changeset</a></li>
1357 <li><a href="/rev/tip">changeset</a></li>
1358 <li><a href="/file/tip">browse</a></li>
1358 <li><a href="/file/tip">browse</a></li>
1359 </ul>
1359 </ul>
1360 <ul>
1360 <ul>
1361 <li><a href="/file/tip/c">file</a></li>
1361 <li><a href="/file/tip/c">file</a></li>
1362 <li><a href="/diff/tip/c">diff</a></li>
1362 <li><a href="/diff/tip/c">diff</a></li>
1363 <li><a href="/comparison/tip/c">comparison</a></li>
1363 <li><a href="/comparison/tip/c">comparison</a></li>
1364 <li><a href="/annotate/tip/c">annotate</a></li>
1364 <li><a href="/annotate/tip/c">annotate</a></li>
1365 <li class="active">file log</li>
1365 <li class="active">file log</li>
1366 <li><a href="/raw-file/tip/c">raw</a></li>
1366 <li><a href="/raw-file/tip/c">raw</a></li>
1367 </ul>
1367 </ul>
1368 <ul>
1368 <ul>
1369 <li><a href="/help">help</a></li>
1369 <li><a href="/help">help</a></li>
1370 </ul>
1370 </ul>
1371 <div class="atom-logo">
1371 <div class="atom-logo">
1372 <a href="/atom-log/tip/c" title="subscribe to atom feed">
1372 <a href="/atom-log/tip/c" title="subscribe to atom feed">
1373 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
1373 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
1374 </a>
1374 </a>
1375 </div>
1375 </div>
1376 </div>
1376 </div>
1377
1377
1378 <div class="main">
1378 <div class="main">
1379 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1379 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1380 <h3>
1380 <h3>
1381 log c @ 12:<a href="/rev/6e4182052f7b">6e4182052f7b</a>
1381 log c @ 12:<a href="/rev/6e4182052f7b">6e4182052f7b</a>
1382 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
1382 <span class="phase">draft</span> <span class="branchhead">a-branch</span> <span class="tag">tip</span>
1383 (following lines 3:4 <a href="/log/tip/c">all revisions for this file</a>)
1383 (following lines 3:4 <a href="/log/tip/c">all revisions for this file</a>)
1384 </h3>
1384 </h3>
1385
1385
1386
1386
1387 <form class="search" action="/log">
1387 <form class="search" action="/log">
1388
1388
1389 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
1389 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
1390 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1390 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1391 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1391 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1392 </form>
1392 </form>
1393
1393
1394 <div class="navigate">
1394 <div class="navigate">
1395 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=30">less</a>
1395 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=30">less</a>
1396 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=120">more</a>
1396 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=120">more</a>
1397 | </div>
1397 | </div>
1398
1398
1399 <table class="bigtable">
1399 <table class="bigtable">
1400 <thead>
1400 <thead>
1401 <tr>
1401 <tr>
1402 <th class="age">age</th>
1402 <th class="age">age</th>
1403 <th class="author">author</th>
1403 <th class="author">author</th>
1404 <th class="description">description</th>
1404 <th class="description">description</th>
1405 </tr>
1405 </tr>
1406 </thead>
1406 </thead>
1407 <tbody class="stripes2">
1407 <tbody class="stripes2">
1408 <tr>
1408 <tr>
1409 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1409 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1410 <td class="author">test</td>
1410 <td class="author">test</td>
1411 <td class="description">
1411 <td class="description">
1412 <a href="/rev/fb9bc322513a">touching beginning and end of c</a>
1412 <a href="/rev/fb9bc322513a">touching beginning and end of c</a>
1413 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1413 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1414 </td>
1414 </td>
1415 </tr>
1415 </tr>
1416 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1416 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1417 <span id="fb9bc322513a-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#fb9bc322513a-l1.1"></a>
1417 <span id="fb9bc322513a-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#fb9bc322513a-l1.1"></a>
1418 <span id="fb9bc322513a-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#fb9bc322513a-l1.2"></a>
1418 <span id="fb9bc322513a-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#fb9bc322513a-l1.2"></a>
1419 <span id="fb9bc322513a-l1.3" class="atline">@@ -1,6 +1,6 @@</span><a href="#fb9bc322513a-l1.3"></a>
1419 <span id="fb9bc322513a-l1.3" class="atline">@@ -1,6 +1,6 @@</span><a href="#fb9bc322513a-l1.3"></a>
1420 <span id="fb9bc322513a-l1.4"> 0</span><a href="#fb9bc322513a-l1.4"></a>
1420 <span id="fb9bc322513a-l1.4"> 0</span><a href="#fb9bc322513a-l1.4"></a>
1421 <span id="fb9bc322513a-l1.5"> 0</span><a href="#fb9bc322513a-l1.5"></a>
1421 <span id="fb9bc322513a-l1.5"> 0</span><a href="#fb9bc322513a-l1.5"></a>
1422 <span id="fb9bc322513a-l1.6" class="minusline">-b</span><a href="#fb9bc322513a-l1.6"></a>
1422 <span id="fb9bc322513a-l1.6" class="minusline">-b</span><a href="#fb9bc322513a-l1.6"></a>
1423 <span id="fb9bc322513a-l1.7" class="plusline">+b-</span><a href="#fb9bc322513a-l1.7"></a>
1423 <span id="fb9bc322513a-l1.7" class="plusline">+b-</span><a href="#fb9bc322513a-l1.7"></a>
1424 <span id="fb9bc322513a-l1.8"> c++</span><a href="#fb9bc322513a-l1.8"></a>
1424 <span id="fb9bc322513a-l1.8"> c++</span><a href="#fb9bc322513a-l1.8"></a>
1425 <span id="fb9bc322513a-l1.9"> </span><a href="#fb9bc322513a-l1.9"></a>
1425 <span id="fb9bc322513a-l1.9"> </span><a href="#fb9bc322513a-l1.9"></a>
1426 <span id="fb9bc322513a-l1.10"> a</span><a href="#fb9bc322513a-l1.10"></a></pre></div></td></tr>
1426 <span id="fb9bc322513a-l1.10"> a</span><a href="#fb9bc322513a-l1.10"></a></pre></div></td></tr>
1427 <tr>
1427 <tr>
1428 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1428 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1429 <td class="author">test</td>
1429 <td class="author">test</td>
1430 <td class="description">
1430 <td class="description">
1431 <a href="/rev/e95928d60479">touch beginning of c</a>
1431 <a href="/rev/e95928d60479">touch beginning of c</a>
1432 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1432 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1433 </td>
1433 </td>
1434 </tr>
1434 </tr>
1435 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1435 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1436 <span id="e95928d60479-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#e95928d60479-l1.1"></a>
1436 <span id="e95928d60479-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#e95928d60479-l1.1"></a>
1437 <span id="e95928d60479-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#e95928d60479-l1.2"></a>
1437 <span id="e95928d60479-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#e95928d60479-l1.2"></a>
1438 <span id="e95928d60479-l1.3" class="atline">@@ -1,7 +1,7 @@</span><a href="#e95928d60479-l1.3"></a>
1438 <span id="e95928d60479-l1.3" class="atline">@@ -1,7 +1,7 @@</span><a href="#e95928d60479-l1.3"></a>
1439 <span id="e95928d60479-l1.4"> 0</span><a href="#e95928d60479-l1.4"></a>
1439 <span id="e95928d60479-l1.4"> 0</span><a href="#e95928d60479-l1.4"></a>
1440 <span id="e95928d60479-l1.5"> 0</span><a href="#e95928d60479-l1.5"></a>
1440 <span id="e95928d60479-l1.5"> 0</span><a href="#e95928d60479-l1.5"></a>
1441 <span id="e95928d60479-l1.6"> b</span><a href="#e95928d60479-l1.6"></a>
1441 <span id="e95928d60479-l1.6"> b</span><a href="#e95928d60479-l1.6"></a>
1442 <span id="e95928d60479-l1.7" class="minusline">-c+</span><a href="#e95928d60479-l1.7"></a>
1442 <span id="e95928d60479-l1.7" class="minusline">-c+</span><a href="#e95928d60479-l1.7"></a>
1443 <span id="e95928d60479-l1.8" class="plusline">+c++</span><a href="#e95928d60479-l1.8"></a>
1443 <span id="e95928d60479-l1.8" class="plusline">+c++</span><a href="#e95928d60479-l1.8"></a>
1444 <span id="e95928d60479-l1.9"> </span><a href="#e95928d60479-l1.9"></a>
1444 <span id="e95928d60479-l1.9"> </span><a href="#e95928d60479-l1.9"></a>
1445 <span id="e95928d60479-l1.10"> a</span><a href="#e95928d60479-l1.10"></a>
1445 <span id="e95928d60479-l1.10"> a</span><a href="#e95928d60479-l1.10"></a>
1446 <span id="e95928d60479-l1.11"> a</span><a href="#e95928d60479-l1.11"></a></pre></div></td></tr>
1446 <span id="e95928d60479-l1.11"> a</span><a href="#e95928d60479-l1.11"></a></pre></div></td></tr>
1447 <tr>
1447 <tr>
1448 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1448 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1449 <td class="author">test</td>
1449 <td class="author">test</td>
1450 <td class="description">
1450 <td class="description">
1451 <a href="/rev/5c6574614c37">make c bigger and touch its beginning</a>
1451 <a href="/rev/5c6574614c37">make c bigger and touch its beginning</a>
1452 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1452 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1453 </td>
1453 </td>
1454 </tr>
1454 </tr>
1455 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1455 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1456 <span id="5c6574614c37-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#5c6574614c37-l1.1"></a>
1456 <span id="5c6574614c37-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#5c6574614c37-l1.1"></a>
1457 <span id="5c6574614c37-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#5c6574614c37-l1.2"></a>
1457 <span id="5c6574614c37-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#5c6574614c37-l1.2"></a>
1458 <span id="5c6574614c37-l1.3" class="atline">@@ -1,2 +1,11 @@</span><a href="#5c6574614c37-l1.3"></a>
1458 <span id="5c6574614c37-l1.3" class="atline">@@ -1,2 +1,11 @@</span><a href="#5c6574614c37-l1.3"></a>
1459 <span id="5c6574614c37-l1.4" class="plusline">+0</span><a href="#5c6574614c37-l1.4"></a>
1459 <span id="5c6574614c37-l1.4" class="plusline">+0</span><a href="#5c6574614c37-l1.4"></a>
1460 <span id="5c6574614c37-l1.5" class="plusline">+0</span><a href="#5c6574614c37-l1.5"></a>
1460 <span id="5c6574614c37-l1.5" class="plusline">+0</span><a href="#5c6574614c37-l1.5"></a>
1461 <span id="5c6574614c37-l1.6"> b</span><a href="#5c6574614c37-l1.6"></a>
1461 <span id="5c6574614c37-l1.6"> b</span><a href="#5c6574614c37-l1.6"></a>
1462 <span id="5c6574614c37-l1.7" class="minusline">-c</span><a href="#5c6574614c37-l1.7"></a>
1462 <span id="5c6574614c37-l1.7" class="minusline">-c</span><a href="#5c6574614c37-l1.7"></a>
1463 <span id="5c6574614c37-l1.8" class="plusline">+c+</span><a href="#5c6574614c37-l1.8"></a>
1463 <span id="5c6574614c37-l1.8" class="plusline">+c+</span><a href="#5c6574614c37-l1.8"></a>
1464 <span id="5c6574614c37-l1.9" class="plusline">+</span><a href="#5c6574614c37-l1.9"></a>
1464 <span id="5c6574614c37-l1.9" class="plusline">+</span><a href="#5c6574614c37-l1.9"></a>
1465 <span id="5c6574614c37-l1.10" class="plusline">+a</span><a href="#5c6574614c37-l1.10"></a>
1465 <span id="5c6574614c37-l1.10" class="plusline">+a</span><a href="#5c6574614c37-l1.10"></a>
1466 <span id="5c6574614c37-l1.11" class="plusline">+a</span><a href="#5c6574614c37-l1.11"></a>
1466 <span id="5c6574614c37-l1.11" class="plusline">+a</span><a href="#5c6574614c37-l1.11"></a>
1467 <span id="5c6574614c37-l1.12" class="plusline">+</span><a href="#5c6574614c37-l1.12"></a>
1467 <span id="5c6574614c37-l1.12" class="plusline">+</span><a href="#5c6574614c37-l1.12"></a>
1468 <span id="5c6574614c37-l1.13" class="plusline">+d</span><a href="#5c6574614c37-l1.13"></a>
1468 <span id="5c6574614c37-l1.13" class="plusline">+d</span><a href="#5c6574614c37-l1.13"></a>
1469 <span id="5c6574614c37-l1.14" class="plusline">+e</span><a href="#5c6574614c37-l1.14"></a>
1469 <span id="5c6574614c37-l1.14" class="plusline">+e</span><a href="#5c6574614c37-l1.14"></a>
1470 <span id="5c6574614c37-l1.15" class="plusline">+f</span><a href="#5c6574614c37-l1.15"></a></pre></div></td></tr>
1470 <span id="5c6574614c37-l1.15" class="plusline">+f</span><a href="#5c6574614c37-l1.15"></a></pre></div></td></tr>
1471 <tr>
1471 <tr>
1472 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1472 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1473 <td class="author">test</td>
1473 <td class="author">test</td>
1474 <td class="description">
1474 <td class="description">
1475 <a href="/rev/46c1a66bd8fc">change c</a>
1475 <a href="/rev/46c1a66bd8fc">change c</a>
1476 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1476 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1477 </td>
1477 </td>
1478 </tr>
1478 </tr>
1479 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1479 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1480 <span id="46c1a66bd8fc-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#46c1a66bd8fc-l1.1"></a>
1480 <span id="46c1a66bd8fc-l1.1" class="minusline">--- a/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#46c1a66bd8fc-l1.1"></a>
1481 <span id="46c1a66bd8fc-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#46c1a66bd8fc-l1.2"></a>
1481 <span id="46c1a66bd8fc-l1.2" class="plusline">+++ b/c Thu Jan 01 00:00:00 1970 +0000</span><a href="#46c1a66bd8fc-l1.2"></a>
1482 <span id="46c1a66bd8fc-l1.3" class="atline">@@ -1,1 +1,2 @@</span><a href="#46c1a66bd8fc-l1.3"></a>
1482 <span id="46c1a66bd8fc-l1.3" class="atline">@@ -1,1 +1,2 @@</span><a href="#46c1a66bd8fc-l1.3"></a>
1483 <span id="46c1a66bd8fc-l1.4"> b</span><a href="#46c1a66bd8fc-l1.4"></a>
1483 <span id="46c1a66bd8fc-l1.4"> b</span><a href="#46c1a66bd8fc-l1.4"></a>
1484 <span id="46c1a66bd8fc-l1.5" class="plusline">+c</span><a href="#46c1a66bd8fc-l1.5"></a></pre></div></td></tr>
1484 <span id="46c1a66bd8fc-l1.5" class="plusline">+c</span><a href="#46c1a66bd8fc-l1.5"></a></pre></div></td></tr>
1485 <tr>
1485 <tr>
1486 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1486 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1487 <td class="author">test</td>
1487 <td class="author">test</td>
1488 <td class="description">
1488 <td class="description">
1489 <a href="/rev/6563da9dcf87">b</a>
1489 <a href="/rev/6563da9dcf87">b</a>
1490 <span class="phase">draft</span>
1490 <span class="phase">draft</span>
1491 </td>
1491 </td>
1492 </tr>
1492 </tr>
1493 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1493 <tr><td colspan="3"><div class="bottomline inc-lineno"><pre class="sourcelines wrap">
1494 <span id="6563da9dcf87-l1.1" class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000</span><a href="#6563da9dcf87-l1.1"></a>
1494 <span id="6563da9dcf87-l1.1" class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000</span><a href="#6563da9dcf87-l1.1"></a>
1495 <span id="6563da9dcf87-l1.2" class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000</span><a href="#6563da9dcf87-l1.2"></a></pre></div></td></tr>
1495 <span id="6563da9dcf87-l1.2" class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000</span><a href="#6563da9dcf87-l1.2"></a></pre></div></td></tr>
1496
1496
1497 </tbody>
1497 </tbody>
1498 </table>
1498 </table>
1499
1499
1500 <div class="navigate">
1500 <div class="navigate">
1501 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=30">less</a>
1501 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=30">less</a>
1502 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=120">more</a>
1502 <a href="/log/tip/c?linerange=3%3A4&patch=&revcount=120">more</a>
1503 |
1503 |
1504 </div>
1504 </div>
1505
1505
1506 </div>
1506 </div>
1507 </div>
1507 </div>
1508
1508
1509
1509
1510
1510
1511 </body>
1511 </body>
1512 </html>
1512 </html>
1513
1513
1514 $ hg log -r 'followlines(c, 3:4, startrev=8, descend=True) and follow(c)' -p
1514 $ hg log -r 'followlines(c, 3:4, startrev=8, descend=True) and follow(c)' -p
1515 changeset: 8:5c6574614c37
1515 changeset: 8:5c6574614c37
1516 branch: a-branch
1516 branch: a-branch
1517 user: test
1517 user: test
1518 date: Thu Jan 01 00:00:00 1970 +0000
1518 date: Thu Jan 01 00:00:00 1970 +0000
1519 summary: make c bigger and touch its beginning
1519 summary: make c bigger and touch its beginning
1520
1520
1521 diff -r 46c1a66bd8fc -r 5c6574614c37 c
1521 diff -r 46c1a66bd8fc -r 5c6574614c37 c
1522 --- a/c Thu Jan 01 00:00:00 1970 +0000
1522 --- a/c Thu Jan 01 00:00:00 1970 +0000
1523 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1523 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1524 @@ -1,2 +1,11 @@
1524 @@ -1,2 +1,11 @@
1525 +0
1525 +0
1526 +0
1526 +0
1527 b
1527 b
1528 -c
1528 -c
1529 +c+
1529 +c+
1530 +
1530 +
1531 +a
1531 +a
1532 +a
1532 +a
1533 +
1533 +
1534 +d
1534 +d
1535 +e
1535 +e
1536 +f
1536 +f
1537
1537
1538 changeset: 10:e95928d60479
1538 changeset: 10:e95928d60479
1539 branch: a-branch
1539 branch: a-branch
1540 user: test
1540 user: test
1541 date: Thu Jan 01 00:00:00 1970 +0000
1541 date: Thu Jan 01 00:00:00 1970 +0000
1542 summary: touch beginning of c
1542 summary: touch beginning of c
1543
1543
1544 diff -r e1d3e9c5a23f -r e95928d60479 c
1544 diff -r e1d3e9c5a23f -r e95928d60479 c
1545 --- a/c Thu Jan 01 00:00:00 1970 +0000
1545 --- a/c Thu Jan 01 00:00:00 1970 +0000
1546 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1546 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1547 @@ -1,7 +1,7 @@
1547 @@ -1,7 +1,7 @@
1548 0
1548 0
1549 0
1549 0
1550 b
1550 b
1551 -c+
1551 -c+
1552 +c++
1552 +c++
1553
1553
1554 a
1554 a
1555 a
1555 a
1556
1556
1557 changeset: 11:fb9bc322513a
1557 changeset: 11:fb9bc322513a
1558 branch: a-branch
1558 branch: a-branch
1559 user: test
1559 user: test
1560 date: Thu Jan 01 00:00:00 1970 +0000
1560 date: Thu Jan 01 00:00:00 1970 +0000
1561 summary: touching beginning and end of c
1561 summary: touching beginning and end of c
1562
1562
1563 diff -r e95928d60479 -r fb9bc322513a c
1563 diff -r e95928d60479 -r fb9bc322513a c
1564 --- a/c Thu Jan 01 00:00:00 1970 +0000
1564 --- a/c Thu Jan 01 00:00:00 1970 +0000
1565 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1565 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1566 @@ -1,6 +1,6 @@
1566 @@ -1,6 +1,6 @@
1567 0
1567 0
1568 0
1568 0
1569 -b
1569 -b
1570 +b-
1570 +b-
1571 c++
1571 c++
1572
1572
1573 a
1573 a
1574 @@ -8,4 +8,4 @@
1574 @@ -8,4 +8,4 @@
1575
1575
1576 d
1576 d
1577 e+
1577 e+
1578 -f
1578 -f
1579 +f+
1579 +f+
1580
1580
1581 $ (get-with-headers.py localhost:$HGPORT 'log/8/c?linerange=3:4&descend=')
1581 $ (get-with-headers.py localhost:$HGPORT 'log/8/c?linerange=3:4&descend=')
1582 200 Script output follows
1582 200 Script output follows
1583
1583
1584 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1584 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1585 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1585 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1586 <head>
1586 <head>
1587 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1587 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1588 <meta name="robots" content="index, nofollow" />
1588 <meta name="robots" content="index, nofollow" />
1589 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1589 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1590 <script type="text/javascript" src="/static/mercurial.js"></script>
1590 <script type="text/javascript" src="/static/mercurial.js"></script>
1591
1591
1592 <title>test: c history</title>
1592 <title>test: c history</title>
1593 <link rel="alternate" type="application/atom+xml"
1593 <link rel="alternate" type="application/atom+xml"
1594 href="/atom-log/tip/c" title="Atom feed for test:c" />
1594 href="/atom-log/tip/c" title="Atom feed for test:c" />
1595 <link rel="alternate" type="application/rss+xml"
1595 <link rel="alternate" type="application/rss+xml"
1596 href="/rss-log/tip/c" title="RSS feed for test:c" />
1596 href="/rss-log/tip/c" title="RSS feed for test:c" />
1597 </head>
1597 </head>
1598 <body>
1598 <body>
1599
1599
1600 <div class="container">
1600 <div class="container">
1601 <div class="menu">
1601 <div class="menu">
1602 <div class="logo">
1602 <div class="logo">
1603 <a href="https://mercurial-scm.org/">
1603 <a href="https://mercurial-scm.org/">
1604 <img src="/static/hglogo.png" alt="mercurial" /></a>
1604 <img src="/static/hglogo.png" alt="mercurial" /></a>
1605 </div>
1605 </div>
1606 <ul>
1606 <ul>
1607 <li><a href="/shortlog/8">log</a></li>
1607 <li><a href="/shortlog/8">log</a></li>
1608 <li><a href="/graph/8">graph</a></li>
1608 <li><a href="/graph/8">graph</a></li>
1609 <li><a href="/tags">tags</a></li>
1609 <li><a href="/tags">tags</a></li>
1610 <li><a href="/bookmarks">bookmarks</a></li>
1610 <li><a href="/bookmarks">bookmarks</a></li>
1611 <li><a href="/branches">branches</a></li>
1611 <li><a href="/branches">branches</a></li>
1612 </ul>
1612 </ul>
1613 <ul>
1613 <ul>
1614 <li><a href="/rev/8">changeset</a></li>
1614 <li><a href="/rev/8">changeset</a></li>
1615 <li><a href="/file/8">browse</a></li>
1615 <li><a href="/file/8">browse</a></li>
1616 </ul>
1616 </ul>
1617 <ul>
1617 <ul>
1618 <li><a href="/file/8/c">file</a></li>
1618 <li><a href="/file/8/c">file</a></li>
1619 <li><a href="/diff/8/c">diff</a></li>
1619 <li><a href="/diff/8/c">diff</a></li>
1620 <li><a href="/comparison/8/c">comparison</a></li>
1620 <li><a href="/comparison/8/c">comparison</a></li>
1621 <li><a href="/annotate/8/c">annotate</a></li>
1621 <li><a href="/annotate/8/c">annotate</a></li>
1622 <li class="active">file log</li>
1622 <li class="active">file log</li>
1623 <li><a href="/raw-file/8/c">raw</a></li>
1623 <li><a href="/raw-file/8/c">raw</a></li>
1624 </ul>
1624 </ul>
1625 <ul>
1625 <ul>
1626 <li><a href="/help">help</a></li>
1626 <li><a href="/help">help</a></li>
1627 </ul>
1627 </ul>
1628 <div class="atom-logo">
1628 <div class="atom-logo">
1629 <a href="/atom-log/tip/c" title="subscribe to atom feed">
1629 <a href="/atom-log/tip/c" title="subscribe to atom feed">
1630 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
1630 <img class="atom-logo" src="/static/feed-icon-14x14.png" alt="atom feed" />
1631 </a>
1631 </a>
1632 </div>
1632 </div>
1633 </div>
1633 </div>
1634
1634
1635 <div class="main">
1635 <div class="main">
1636 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1636 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1637 <h3>
1637 <h3>
1638 log c @ 8:<a href="/rev/5c6574614c37">5c6574614c37</a>
1638 log c @ 8:<a href="/rev/5c6574614c37">5c6574614c37</a>
1639 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1639 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1640 (following lines 3:4, descending <a href="/log/8/c">all revisions for this file</a>)
1640 (following lines 3:4, descending <a href="/log/8/c">all revisions for this file</a>)
1641 </h3>
1641 </h3>
1642
1642
1643
1643
1644 <form class="search" action="/log">
1644 <form class="search" action="/log">
1645
1645
1646 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
1646 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
1647 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1647 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1648 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1648 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1649 </form>
1649 </form>
1650
1650
1651 <div class="navigate">
1651 <div class="navigate">
1652 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=30">less</a>
1652 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=30">less</a>
1653 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=120">more</a>
1653 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=120">more</a>
1654 | </div>
1654 | </div>
1655
1655
1656 <table class="bigtable">
1656 <table class="bigtable">
1657 <thead>
1657 <thead>
1658 <tr>
1658 <tr>
1659 <th class="age">age</th>
1659 <th class="age">age</th>
1660 <th class="author">author</th>
1660 <th class="author">author</th>
1661 <th class="description">description</th>
1661 <th class="description">description</th>
1662 </tr>
1662 </tr>
1663 </thead>
1663 </thead>
1664 <tbody class="stripes2">
1664 <tbody class="stripes2">
1665 <tr>
1665 <tr>
1666 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1666 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1667 <td class="author">test</td>
1667 <td class="author">test</td>
1668 <td class="description">
1668 <td class="description">
1669 <a href="/rev/5c6574614c37">make c bigger and touch its beginning</a>
1669 <a href="/rev/5c6574614c37">make c bigger and touch its beginning</a>
1670 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1670 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1671 </td>
1671 </td>
1672 </tr>
1672 </tr>
1673
1673
1674 <tr>
1674 <tr>
1675 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1675 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1676 <td class="author">test</td>
1676 <td class="author">test</td>
1677 <td class="description">
1677 <td class="description">
1678 <a href="/rev/e95928d60479">touch beginning of c</a>
1678 <a href="/rev/e95928d60479">touch beginning of c</a>
1679 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1679 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1680 </td>
1680 </td>
1681 </tr>
1681 </tr>
1682
1682
1683 <tr>
1683 <tr>
1684 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1684 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
1685 <td class="author">test</td>
1685 <td class="author">test</td>
1686 <td class="description">
1686 <td class="description">
1687 <a href="/rev/fb9bc322513a">touching beginning and end of c</a>
1687 <a href="/rev/fb9bc322513a">touching beginning and end of c</a>
1688 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1688 <span class="phase">draft</span> <span class="branchname">a-branch</span>
1689 </td>
1689 </td>
1690 </tr>
1690 </tr>
1691
1691
1692
1692
1693 </tbody>
1693 </tbody>
1694 </table>
1694 </table>
1695
1695
1696 <div class="navigate">
1696 <div class="navigate">
1697 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=30">less</a>
1697 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=30">less</a>
1698 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=120">more</a>
1698 <a href="/log/8/c?descend=&linerange=3%3A4&revcount=120">more</a>
1699 |
1699 |
1700 </div>
1700 </div>
1701
1701
1702 </div>
1702 </div>
1703 </div>
1703 </div>
1704
1704
1705
1705
1706
1706
1707 </body>
1707 </body>
1708 </html>
1708 </html>
1709
1709
1710
1710
1711 rss log
1711 rss log
1712
1712
1713 $ (get-with-headers.py localhost:$HGPORT 'rss-log/tip/a')
1713 $ (get-with-headers.py localhost:$HGPORT 'rss-log/tip/a')
1714 200 Script output follows
1714 200 Script output follows
1715
1715
1716 <?xml version="1.0" encoding="ascii"?>
1716 <?xml version="1.0" encoding="ascii"?>
1717 <rss version="2.0">
1717 <rss version="2.0">
1718 <channel>
1718 <channel>
1719 <link>http://*:$HGPORT/</link> (glob)
1719 <link>http://*:$HGPORT/</link> (glob)
1720 <language>en-us</language>
1720 <language>en-us</language>
1721
1721
1722 <title>test: a history</title>
1722 <title>test: a history</title>
1723 <description>a revision history</description>
1723 <description>a revision history</description>
1724 <item>
1724 <item>
1725 <title>second a</title>
1725 <title>second a</title>
1726 <link>http://*:$HGPORT/log/3f41bc784e7e/a</link> (glob)
1726 <link>http://*:$HGPORT/log/3f41bc784e7e/a</link> (glob)
1727 <description><![CDATA[second a]]></description>
1727 <description><![CDATA[second a]]></description>
1728 <author>&#116;&#101;&#115;&#116;</author>
1728 <author>&#116;&#101;&#115;&#116;</author>
1729 <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
1729 <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
1730 </item>
1730 </item>
1731 <item>
1731 <item>
1732 <title>first a</title>
1732 <title>first a</title>
1733 <link>http://*:$HGPORT/log/5ed941583260/a</link> (glob)
1733 <link>http://*:$HGPORT/log/5ed941583260/a</link> (glob)
1734 <description><![CDATA[first a]]></description>
1734 <description><![CDATA[first a]]></description>
1735 <author>&#116;&#101;&#115;&#116;</author>
1735 <author>&#116;&#101;&#115;&#116;</author>
1736 <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
1736 <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
1737 </item>
1737 </item>
1738
1738
1739 </channel>
1739 </channel>
1740 </rss>
1740 </rss>
1741
1741
1742 atom log
1742 atom log
1743
1743
1744 $ (get-with-headers.py localhost:$HGPORT 'atom-log/tip/a')
1744 $ (get-with-headers.py localhost:$HGPORT 'atom-log/tip/a')
1745 200 Script output follows
1745 200 Script output follows
1746
1746
1747 <?xml version="1.0" encoding="ascii"?>
1747 <?xml version="1.0" encoding="ascii"?>
1748 <feed xmlns="http://www.w3.org/2005/Atom">
1748 <feed xmlns="http://www.w3.org/2005/Atom">
1749 <id>http://*:$HGPORT/atom-log/tip/a</id> (glob)
1749 <id>http://*:$HGPORT/atom-log/tip/a</id> (glob)
1750 <link rel="self" href="http://*:$HGPORT/atom-log/tip/a"/> (glob)
1750 <link rel="self" href="http://*:$HGPORT/atom-log/tip/a"/> (glob)
1751 <title>test: a history</title>
1751 <title>test: a history</title>
1752 <updated>1970-01-01T00:00:00+00:00</updated>
1752 <updated>1970-01-01T00:00:00+00:00</updated>
1753
1753
1754 <entry>
1754 <entry>
1755 <title>[a-branch] second a</title>
1755 <title>[a-branch] second a</title>
1756 <id>http://*:$HGPORT/#changeset-3f41bc784e7e73035c6d47112c6cc7efb673adf8</id> (glob)
1756 <id>http://*:$HGPORT/#changeset-3f41bc784e7e73035c6d47112c6cc7efb673adf8</id> (glob)
1757 <link href="http://*:$HGPORT/rev/3f41bc784e7e"/> (glob)
1757 <link href="http://*:$HGPORT/rev/3f41bc784e7e"/> (glob)
1758 <author>
1758 <author>
1759 <name>test</name>
1759 <name>test</name>
1760 <email>&#116;&#101;&#115;&#116;</email>
1760 <email>&#116;&#101;&#115;&#116;</email>
1761 </author>
1761 </author>
1762 <updated>1970-01-01T00:00:00+00:00</updated>
1762 <updated>1970-01-01T00:00:00+00:00</updated>
1763 <published>1970-01-01T00:00:00+00:00</published>
1763 <published>1970-01-01T00:00:00+00:00</published>
1764 <content type="xhtml">
1764 <content type="xhtml">
1765 <table xmlns="http://www.w3.org/1999/xhtml">
1765 <table xmlns="http://www.w3.org/1999/xhtml">
1766 <tr>
1766 <tr>
1767 <th style="text-align:left;">changeset</th>
1767 <th style="text-align:left;">changeset</th>
1768 <td>3f41bc784e7e</td>
1768 <td>3f41bc784e7e</td>
1769 </tr>
1769 </tr>
1770 <tr>
1770 <tr>
1771 <th style="text-align:left;">branch</th>
1771 <th style="text-align:left;">branch</th>
1772 <td>a-branch</td>
1772 <td>a-branch</td>
1773 </tr>
1773 </tr>
1774 <tr>
1774 <tr>
1775 <th style="text-align:left;">bookmark</th>
1775 <th style="text-align:left;">bookmark</th>
1776 <td></td>
1776 <td></td>
1777 </tr>
1777 </tr>
1778 <tr>
1778 <tr>
1779 <th style="text-align:left;">tag</th>
1779 <th style="text-align:left;">tag</th>
1780 <td></td>
1780 <td></td>
1781 </tr>
1781 </tr>
1782 <tr>
1782 <tr>
1783 <th style="text-align:left;">user</th>
1783 <th style="text-align:left;">user</th>
1784 <td>&#116;&#101;&#115;&#116;</td>
1784 <td>&#116;&#101;&#115;&#116;</td>
1785 </tr>
1785 </tr>
1786 <tr>
1786 <tr>
1787 <th style="text-align:left;vertical-align:top;">description</th>
1787 <th style="text-align:left;vertical-align:top;">description</th>
1788 <td>second a</td>
1788 <td>second a</td>
1789 </tr>
1789 </tr>
1790 <tr>
1790 <tr>
1791 <th style="text-align:left;vertical-align:top;">files</th>
1791 <th style="text-align:left;vertical-align:top;">files</th>
1792 <td></td>
1792 <td></td>
1793 </tr>
1793 </tr>
1794 </table>
1794 </table>
1795 </content>
1795 </content>
1796 </entry>
1796 </entry>
1797 <entry>
1797 <entry>
1798 <title>first a</title>
1798 <title>first a</title>
1799 <id>http://*:$HGPORT/#changeset-5ed941583260248620985524192fdc382ef57c36</id> (glob)
1799 <id>http://*:$HGPORT/#changeset-5ed941583260248620985524192fdc382ef57c36</id> (glob)
1800 <link href="http://*:$HGPORT/rev/5ed941583260"/> (glob)
1800 <link href="http://*:$HGPORT/rev/5ed941583260"/> (glob)
1801 <author>
1801 <author>
1802 <name>test</name>
1802 <name>test</name>
1803 <email>&#116;&#101;&#115;&#116;</email>
1803 <email>&#116;&#101;&#115;&#116;</email>
1804 </author>
1804 </author>
1805 <updated>1970-01-01T00:00:00+00:00</updated>
1805 <updated>1970-01-01T00:00:00+00:00</updated>
1806 <published>1970-01-01T00:00:00+00:00</published>
1806 <published>1970-01-01T00:00:00+00:00</published>
1807 <content type="xhtml">
1807 <content type="xhtml">
1808 <table xmlns="http://www.w3.org/1999/xhtml">
1808 <table xmlns="http://www.w3.org/1999/xhtml">
1809 <tr>
1809 <tr>
1810 <th style="text-align:left;">changeset</th>
1810 <th style="text-align:left;">changeset</th>
1811 <td>5ed941583260</td>
1811 <td>5ed941583260</td>
1812 </tr>
1812 </tr>
1813 <tr>
1813 <tr>
1814 <th style="text-align:left;">branch</th>
1814 <th style="text-align:left;">branch</th>
1815 <td></td>
1815 <td></td>
1816 </tr>
1816 </tr>
1817 <tr>
1817 <tr>
1818 <th style="text-align:left;">bookmark</th>
1818 <th style="text-align:left;">bookmark</th>
1819 <td>a-bookmark</td>
1819 <td>a-bookmark</td>
1820 </tr>
1820 </tr>
1821 <tr>
1821 <tr>
1822 <th style="text-align:left;">tag</th>
1822 <th style="text-align:left;">tag</th>
1823 <td>a-tag</td>
1823 <td>a-tag</td>
1824 </tr>
1824 </tr>
1825 <tr>
1825 <tr>
1826 <th style="text-align:left;">user</th>
1826 <th style="text-align:left;">user</th>
1827 <td>&#116;&#101;&#115;&#116;</td>
1827 <td>&#116;&#101;&#115;&#116;</td>
1828 </tr>
1828 </tr>
1829 <tr>
1829 <tr>
1830 <th style="text-align:left;vertical-align:top;">description</th>
1830 <th style="text-align:left;vertical-align:top;">description</th>
1831 <td>first a</td>
1831 <td>first a</td>
1832 </tr>
1832 </tr>
1833 <tr>
1833 <tr>
1834 <th style="text-align:left;vertical-align:top;">files</th>
1834 <th style="text-align:left;vertical-align:top;">files</th>
1835 <td></td>
1835 <td></td>
1836 </tr>
1836 </tr>
1837 </table>
1837 </table>
1838 </content>
1838 </content>
1839 </entry>
1839 </entry>
1840
1840
1841 </feed>
1841 </feed>
1842
1842
1843 errors
1843 errors
1844
1844
1845 $ cat errors.log
1845 $ cat errors.log
1846
1846
1847 $ cd ..
1847 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now