# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@logilab.fr>
# Date 2013-01-16 12:18:22
# Node ID e3f5cef11d6a8eafdbaefa9b6c3d0e91fc3273fc
# Parent  f332a64fef517ff800416bb79fd4764fa3fc4903

hgweb: pass repo object to revnav construction

For compatibility with changelog filtering we need access to the changelog, a
simple nodefunc is not sufficient, only the changelog and repo have access the
filteredrevs information.

For the filerevnav version, we use an unfiltered changelog. Linkrev is currently
broken with filtering and we need some failsafe to prevent traceback. This is
the same approach as the one used in 518c1403838f. The use of
filectx.changectx() allowed the previous code to use the 518c1403838f hack.

This changeset may result in an incorrect behaviors, Navigation
link may point to missing revision. However this bad navigation
generation is much better than a plain crash

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -242,7 +242,7 @@ def changelog(web, req, tmpl, shortlog=F
     pos = end - 1
     parity = paritygen(web.stripecount, offset=start - end)
 
-    changenav = webutil.revnav(web.repo.changectx).gen(pos, revcount, count)
+    changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
 
     return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
                 node=ctx.hex(), rev=pos, changesets=count,
@@ -771,8 +771,8 @@ def filelog(web, req, tmpl):
         for e in reversed(l):
             yield e
 
-    nodefunc = lambda x: fctx.filectx(fileid=x)
-    nav = webutil.filerevnav(nodefunc).gen(end - 1, revcount, count)
+    revnav = webutil.filerevnav(web.repo, fctx.path())
+    nav = revnav.gen(end - 1, revcount, count)
     return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
                 entries=lambda **x: entries(latestonly=False, **x),
                 latestentry=lambda **x: entries(latestonly=True, **x),
@@ -851,7 +851,7 @@ def graph(web, req, tmpl):
 
     uprev = min(max(0, count - 1), rev + revcount)
     downrev = max(0, rev - revcount)
-    changenav = webutil.revnav(web.repo.changectx).gen(pos, revcount, count)
+    changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
 
     dag = graphmod.dagwalker(web.repo, range(start, end)[::-1])
     tree = list(graphmod.colored(dag, web.repo))
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -41,23 +41,24 @@ def _navseq(step, firststep=None):
 
 class revnav(object):
 
-    def __init__(self, nodefunc):
+    def __init__(self, repo):
         """Navigation generation object
 
-        :nodefun: factory for a changectx from a revision
+        :repo: repo object we generate nav for
         """
-        self.nodefunc = nodefunc
+        # used for hex generation
+        self._revlog = repo.changelog
 
     def __nonzero__(self):
         """return True if any revision to navigate over"""
         try:
-            self.nodefunc(0)
+            self._revlog.node(0)
             return True
         except error.RepoError:
             return False
 
     def hex(self, rev):
-        return self.nodefunc(rev).hex()
+        return hex(self._revlog.node(rev))
 
     def gen(self, pos, pagelen, limit):
         """computes label and revision id for navigation link
@@ -94,7 +95,21 @@ class revnav(object):
                  'after':  lambda **map: (data(i) for i in navafter)},)
 
 class filerevnav(revnav):
-    pass
+
+    def __init__(self, repo, path):
+        """Navigation generation object
+
+        :repo: repo object we generate nav for
+        :path: path of the file we generate nav for
+        """
+        # used for iteration
+        self._changelog = repo.unfiltered().changelog
+        # used for hex generation
+        self._revlog = repo.file(path)
+
+    def hex(self, rev):
+        return hex(self._changelog.node(self._revlog.linkrev(rev)))
+
 
 def _siblings(siblings=[], hiderev=None):
     siblings = [s for s in siblings if s.node() != nullid]