--- a/mercurial/hgweb/webcommands.py Sat Nov 01 13:07:20 2008 +0100
+++ b/mercurial/hgweb/webcommands.py Sat Nov 01 13:07:24 2008 +0100
@@ -500,15 +500,30 @@
permissions=fctx.manifest().flags(f))
def filelog(web, req, tmpl):
- fctx = webutil.filectx(web.repo, req)
- f = fctx.path()
- fl = fctx.filelog()
- count = len(fl)
+
+ try:
+ fctx = webutil.filectx(web.repo, req)
+ f = fctx.path()
+ fl = fctx.filelog()
+ except revlog.LookupError:
+ f = webutil.cleanpath(web.repo, req.form['file'][0])
+ fl = web.repo.file(f)
+ numrevs = len(fl)
+ if not numrevs: # file doesn't exist at all
+ raise
+ rev = webutil.changectx(web.repo, req).rev()
+ first = fl.linkrev(fl.node(0))
+ if rev < first: # current rev is from before file existed
+ raise
+ frev = numrevs - 1
+ while fl.linkrev(fl.node(frev)) > rev:
+ frev -= 1
+ fctx = web.repo.filectx(f, fl.linkrev(fl.node(frev)))
+
+ count = fctx.filerev() + 1
pagelen = web.maxshortchanges
- pos = fctx.filerev()
- start = max(0, pos - pagelen + 1)
- end = min(count, start + pagelen)
- pos = end - 1
+ start = max(0, fctx.filerev() - pagelen + 1) # first rev on this page
+ end = min(count, start + pagelen) # last rev on this page
parity = paritygen(web.stripecount, offset=start-end)
def entries(limit=0, **map):
@@ -535,7 +550,7 @@
yield e
nodefunc = lambda x: fctx.filectx(fileid=x)
- nav = webutil.revnavgen(pos, pagelen, count, nodefunc)
+ nav = webutil.revnavgen(end - 1, pagelen, count, nodefunc)
return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
entries=lambda **x: entries(limit=0, **x),
latestentry=lambda **x: entries(limit=1, **x))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-hgweb-filelog Sat Nov 01 13:07:24 2008 +0100
@@ -0,0 +1,40 @@
+hg init test
+cd test
+
+echo b > b
+hg ci -Am "b"
+
+echo a > a
+hg ci -Am "first a"
+
+hg rm a
+hg ci -m "del a"
+
+echo b > a
+hg ci -Am "second a"
+
+hg rm a
+hg ci -m "del2 a"
+
+hg log -p
+
+hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
+cat hg.pid >> $DAEMON_PIDS
+
+echo % tip - two revisions
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/log/tip/a')
+
+echo % second version - two revisions
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/log/3/a')
+
+echo % first deleted - one revision
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/log/2/a')
+
+echo % first version - one revision
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/log/1/a')
+
+echo % before addition - error
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/log/0/a')
+
+echo % errors
+cat errors.log
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-hgweb-filelog.out Sat Nov 01 13:07:24 2008 +0100
@@ -0,0 +1,418 @@
+adding b
+adding a
+adding a
+changeset: 4:52e848cdcd88
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: del2 a
+
+diff -r 01de2d66a28d -r 52e848cdcd88 a
+--- a/a Thu Jan 01 00:00:00 1970 +0000
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-b
+
+changeset: 3:01de2d66a28d
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: second a
+
+diff -r be3ebcc91739 -r 01de2d66a28d a
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/a Thu Jan 01 00:00:00 1970 +0000
+@@ -0,0 +1,1 @@
++b
+
+changeset: 2:be3ebcc91739
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: del a
+
+diff -r 5ed941583260 -r be3ebcc91739 a
+--- a/a Thu Jan 01 00:00:00 1970 +0000
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-a
+
+changeset: 1:5ed941583260
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: first a
+
+diff -r 6563da9dcf87 -r 5ed941583260 a
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/a Thu Jan 01 00:00:00 1970 +0000
+@@ -0,0 +1,1 @@
++a
+
+changeset: 0:6563da9dcf87
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: b
+
+diff -r 000000000000 -r 6563da9dcf87 b
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/b Thu Jan 01 00:00:00 1970 +0000
+@@ -0,0 +1,1 @@
++b
+
+% tip - two revisions
+200 Script output follows
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<link rel="icon" href="/static/hgicon.png" type="image/png">
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="/static/style.css" type="text/css" />
+
+<title>test: a history</title>
+<link rel="alternate" type="application/atom+xml"
+ href="/atom-log/tip/a" title="Atom feed for test:a">
+<link rel="alternate" type="application/rss+xml"
+ href="/rss-log/tip/a" title="RSS feed for test:a">
+</head>
+<body>
+
+<div class="buttons">
+<a href="/log">changelog</a>
+<a href="/shortlog">shortlog</a>
+<a href="/graph">graph</a>
+<a href="/tags">tags</a>
+<a href="/file/01de2d66a28d/a">file</a>
+<a href="/annotate/01de2d66a28d/a">annotate</a>
+<a type="application/rss+xml" href="/rss-log/tip/a">rss</a>
+<a type="application/atom+xml" href="/atom-log/tip/a" title="Atom feed for test:a">atom</a>
+</div>
+
+<h2>a revision history</h2>
+
+<p>navigate: <small class="navigate"><a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </small></p>
+
+<table class="logEntry parity0">
+ <tr>
+ <th class="age">38 years ago:</th>
+ <th class="firstline"><a href="/rev/01de2d66a28d">second a</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision 1:</td>
+ <td class="node">
+ <a href="/file/01de2d66a28d/a">01de2d66a28d</a>
+ <a href="/diff/01de2d66a28d/a">(diff)</a>
+ <a href="/annotate/01de2d66a28d/a">(annotate)</a>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">test</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000</td>
+ </tr>
+</table>
+
+
+<table class="logEntry parity1">
+ <tr>
+ <th class="age">38 years ago:</th>
+ <th class="firstline"><a href="/rev/5ed941583260">first a</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision 0:</td>
+ <td class="node">
+ <a href="/file/5ed941583260/a">5ed941583260</a>
+ <a href="/diff/5ed941583260/a">(diff)</a>
+ <a href="/annotate/5ed941583260/a">(annotate)</a>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">test</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000</td>
+ </tr>
+</table>
+
+
+
+
+
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+
+</body>
+</html>
+
+% second version - two revisions
+200 Script output follows
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<link rel="icon" href="/static/hgicon.png" type="image/png">
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="/static/style.css" type="text/css" />
+
+<title>test: a history</title>
+<link rel="alternate" type="application/atom+xml"
+ href="/atom-log/tip/a" title="Atom feed for test:a">
+<link rel="alternate" type="application/rss+xml"
+ href="/rss-log/tip/a" title="RSS feed for test:a">
+</head>
+<body>
+
+<div class="buttons">
+<a href="/log">changelog</a>
+<a href="/shortlog">shortlog</a>
+<a href="/graph">graph</a>
+<a href="/tags">tags</a>
+<a href="/file/01de2d66a28d/a">file</a>
+<a href="/annotate/01de2d66a28d/a">annotate</a>
+<a type="application/rss+xml" href="/rss-log/tip/a">rss</a>
+<a type="application/atom+xml" href="/atom-log/tip/a" title="Atom feed for test:a">atom</a>
+</div>
+
+<h2>a revision history</h2>
+
+<p>navigate: <small class="navigate"><a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </small></p>
+
+<table class="logEntry parity0">
+ <tr>
+ <th class="age">38 years ago:</th>
+ <th class="firstline"><a href="/rev/01de2d66a28d">second a</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision 1:</td>
+ <td class="node">
+ <a href="/file/01de2d66a28d/a">01de2d66a28d</a>
+ <a href="/diff/01de2d66a28d/a">(diff)</a>
+ <a href="/annotate/01de2d66a28d/a">(annotate)</a>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">test</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000</td>
+ </tr>
+</table>
+
+
+<table class="logEntry parity1">
+ <tr>
+ <th class="age">38 years ago:</th>
+ <th class="firstline"><a href="/rev/5ed941583260">first a</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision 0:</td>
+ <td class="node">
+ <a href="/file/5ed941583260/a">5ed941583260</a>
+ <a href="/diff/5ed941583260/a">(diff)</a>
+ <a href="/annotate/5ed941583260/a">(annotate)</a>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">test</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000</td>
+ </tr>
+</table>
+
+
+
+
+
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+
+</body>
+</html>
+
+% first deleted - one revision
+200 Script output follows
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<link rel="icon" href="/static/hgicon.png" type="image/png">
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="/static/style.css" type="text/css" />
+
+<title>test: a history</title>
+<link rel="alternate" type="application/atom+xml"
+ href="/atom-log/tip/a" title="Atom feed for test:a">
+<link rel="alternate" type="application/rss+xml"
+ href="/rss-log/tip/a" title="RSS feed for test:a">
+</head>
+<body>
+
+<div class="buttons">
+<a href="/log">changelog</a>
+<a href="/shortlog">shortlog</a>
+<a href="/graph">graph</a>
+<a href="/tags">tags</a>
+<a href="/file/5ed941583260/a">file</a>
+<a href="/annotate/5ed941583260/a">annotate</a>
+<a type="application/rss+xml" href="/rss-log/tip/a">rss</a>
+<a type="application/atom+xml" href="/atom-log/tip/a" title="Atom feed for test:a">atom</a>
+</div>
+
+<h2>a revision history</h2>
+
+<p>navigate: <small class="navigate"><a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </small></p>
+
+<table class="logEntry parity0">
+ <tr>
+ <th class="age">38 years ago:</th>
+ <th class="firstline"><a href="/rev/5ed941583260">first a</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision 0:</td>
+ <td class="node">
+ <a href="/file/5ed941583260/a">5ed941583260</a>
+ <a href="/diff/5ed941583260/a">(diff)</a>
+ <a href="/annotate/5ed941583260/a">(annotate)</a>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">test</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000</td>
+ </tr>
+</table>
+
+
+
+
+
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+
+</body>
+</html>
+
+% first version - one revision
+200 Script output follows
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<link rel="icon" href="/static/hgicon.png" type="image/png">
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="/static/style.css" type="text/css" />
+
+<title>test: a history</title>
+<link rel="alternate" type="application/atom+xml"
+ href="/atom-log/tip/a" title="Atom feed for test:a">
+<link rel="alternate" type="application/rss+xml"
+ href="/rss-log/tip/a" title="RSS feed for test:a">
+</head>
+<body>
+
+<div class="buttons">
+<a href="/log">changelog</a>
+<a href="/shortlog">shortlog</a>
+<a href="/graph">graph</a>
+<a href="/tags">tags</a>
+<a href="/file/5ed941583260/a">file</a>
+<a href="/annotate/5ed941583260/a">annotate</a>
+<a type="application/rss+xml" href="/rss-log/tip/a">rss</a>
+<a type="application/atom+xml" href="/atom-log/tip/a" title="Atom feed for test:a">atom</a>
+</div>
+
+<h2>a revision history</h2>
+
+<p>navigate: <small class="navigate"><a href="/log/5ed941583260/a">(0)</a> <a href="/log/tip/a">tip</a> </small></p>
+
+<table class="logEntry parity0">
+ <tr>
+ <th class="age">38 years ago:</th>
+ <th class="firstline"><a href="/rev/5ed941583260">first a</a></th>
+ </tr>
+ <tr>
+ <th class="revision">revision 0:</td>
+ <td class="node">
+ <a href="/file/5ed941583260/a">5ed941583260</a>
+ <a href="/diff/5ed941583260/a">(diff)</a>
+ <a href="/annotate/5ed941583260/a">(annotate)</a>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="author">author:</th>
+ <td class="author">test</td>
+ </tr>
+ <tr>
+ <th class="date">date:</th>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000</td>
+ </tr>
+</table>
+
+
+
+
+
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+
+</body>
+</html>
+
+% before addition - error
+404 Not Found
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<link rel="icon" href="/static/hgicon.png" type="image/png">
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="/static/style.css" type="text/css" />
+
+<title>Mercurial Error</title>
+</head>
+<body>
+
+<h2>Mercurial Error</h2>
+
+<p>
+An error occurred while processing your request:
+</p>
+<p>
+a@6563da9dcf87: not found in manifest
+</p>
+
+
+<div class="logo">
+<a href="http://www.selenic.com/mercurial/">
+<img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+
+</body>
+</html>
+
+% errors