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