Patchwork [2,of,4,V2] hgweb: use an extensible list of file to check for refresh

mail settings
Submitter Pierre-Yves David
Date July 3, 2015, 6:29 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/9887/
State Accepted
Headers show


Pierre-Yves David - July 3, 2015, 6:29 p.m.
# HG changeset patch
# User Pierre-Yves David <>
# Date 1435735130 25200
#      Wed Jul 01 00:18:50 2015 -0700
# Node ID bed25733093ce290beb35f5197e84fa2292c2aa4
# Parent  668074775c8340236993cea30795204034d66d5c
hgweb: use an extensible list of file to check for refresh

The refresh feature was explicitly testing if '00changelog.i' and 'phasesroots'
changed. This is overlooking other important information like bookmarks and
obsstore (bookmark have their own hack to work around it).

We move to a more extensible system with a list of file of interest that will be
used to build the repo state. The system should probably move in a more central
place so that the command server and other system are able to use it.
Extensions write will also be able to add entry to ensure that changes to
extension data are properly detected.

Also the current key (mtime, size) is notably weak for bookmarks and phases
whose files can easily change content without effect on their size.

Still, this patch seems like a valuable minimal first step.


diff --git a/mercurial/hgweb/ b/mercurial/hgweb/
--- a/mercurial/hgweb/
+++ b/mercurial/hgweb/
@@ -24,10 +24,17 @@  perms = {
     'listkeys': 'pull',
     'unbundle': 'push',
     'pushkey': 'push',
+## files of interrest
+# used to check if the repository has changed looking at mtime and size of
+# theses files.  This should probably be relocated a bit higher in core
+foi = [('spath', '00changelog.i'),
+       ('spath', 'phaseroots'), # ! phase can change content at the same size
+      ]
 def makebreadcrumb(url, prefix=''):
     '''Return a 'URL breadcrumb' list
     A 'URL breadcrumb' is a list of URL-name pairs,
     corresponding to each of the path items on a URL.
@@ -118,14 +125,17 @@  class hgweb(object):
             return repo.filtered(viewconfig)
             return repo.filtered('served')
     def refresh(self, request=None):
-        st = get_stat(self.repo.spath, '00changelog.i')
-        pst = get_stat(self.repo.spath, 'phaseroots')
-        # changelog mtime and size, phaseroots mtime and size
-        repostate = ((st.st_mtime, st.st_size), (pst.st_mtime, pst.st_size))
+        repostate = []
+        # file of interrests mtime and size
+        for meth, fname in foi:
+            prefix = getattr(self.repo, meth)
+            st = get_stat(prefix, fname)
+            repostate.append((st.st_mtime, st.st_size))
+        repostate = tuple(repostate)
         # we need to compare file size in addition to mtime to catch
         # changes made less than a second ago
         if repostate != self.repostate:
             r = hg.repository(self.repo.baseui, self.repo.url())
             self.repo = self._getview(r)