Patchwork hgweb: refresh hgweb.repo on phase change (issue4061)

login
register
mail settings
Submitter Anton Shestakov
Date Sept. 27, 2014, 5:28 p.m.
Message ID <9927c91e31140e9e5294.1411838930@inspiron>
Download mbox | patch
Permalink /patch/5992/
State Superseded
Commit a111e460318af49aeb6578cf142a63426c5e764d
Headers show

Comments

Anton Shestakov - Sept. 27, 2014, 5:28 p.m.
# HG changeset patch
# User Anton Shestakov <engored@ya.ru>
# Date 1411822795 -32400
#      Sat Sep 27 21:59:55 2014 +0900
# Node ID 9927c91e31140e9e529473073768912745cfb9cc
# Parent  e6e7ef68c879b55c1b2c0ebe00d8cbdbc929dbed
hgweb: refresh hgweb.repo on phase change (issue4061)

Make hgweb.refresh() also look at phaseroots file (in addition to 00changelog.i
file) and reload the repo when os.stat returns different mtime or size than
cached, signifying the file was modified.

This way if user changes phase of a changeset (secret <-> draft), there's no
need to restart hg serve to see the change.
Pierre-Yves David - Sept. 27, 2014, 10:50 p.m.
On 09/27/2014 10:28 AM, Anton Shestakov wrote:
> # HG changeset patch
> # User Anton Shestakov <engored@ya.ru>
> # Date 1411822795 -32400
> #      Sat Sep 27 21:59:55 2014 +0900
> # Node ID 9927c91e31140e9e529473073768912745cfb9cc
> # Parent  e6e7ef68c879b55c1b2c0ebe00d8cbdbc929dbed
> hgweb: refresh hgweb.repo on phase change (issue4061)

This seems to belong on stable but does not apply there.
Can you send a version rebased on stable (with a STABLE flag?)


> Make hgweb.refresh() also look at phaseroots file (in addition to 00changelog.i
> file) and reload the repo when os.stat returns different mtime or size than
> cached, signifying the file was modified.
>
> This way if user changes phase of a changeset (secret <-> draft), there's no
> need to restart hg serve to see the change.
>
> diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
> --- a/mercurial/hgweb/common.py
> +++ b/mercurial/hgweb/common.py
> @@ -112,9 +112,9 @@
>   def statusmessage(code, message=None):
>       return '%d %s' % (code, message or _statusmessage(code))
>
> -def get_stat(spath):
> -    """stat changelog if it exists, spath otherwise"""
> -    cl_path = os.path.join(spath, "00changelog.i")
> +def get_stat(spath, fn="00changelog.i"):
> +    """stat fn (00changelog.i by default) if it exists, spath otherwise"""
> +    cl_path = os.path.join(spath, fn)
>       if os.path.exists(cl_path):
>           return os.stat(cl_path)
>       else:
> diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
> --- a/mercurial/hgweb/hgweb_mod.py
> +++ b/mercurial/hgweb/hgweb_mod.py
> @@ -71,8 +71,8 @@
>           r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
>           self.repo = r
>           hook.redirect(True)
> +        self.repostate = (-1, -1, -1, -1)
>           self.mtime = -1
> -        self.size = -1
>           self.reponame = name
>           self.archives = 'zip', 'gz', 'bz2'
>           self.stripecount = 1
> @@ -107,9 +107,12 @@
>
>       def refresh(self, request=None):
>           st = get_stat(self.repo.spath)
> -        # compare changelog size in addition to mtime to catch
> -        # rollbacks made less than a second ago
> -        if st.st_mtime != self.mtime or st.st_size != self.size:
> +        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)

Can we get the mtime and st_size to be grouped in pari instead?

((time, size), (time, size))

> +        # 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)
>               self.maxchanges = int(self.config("web", "maxchanges", 10))
> @@ -121,8 +124,9 @@
>               encoding.encoding = self.config("web", "encoding",
>                                               encoding.encoding)
>               # update these last to avoid threads seeing empty settings
> +            self.repostate = repostate
> +            # mtime is needed for ETag
>               self.mtime = st.st_mtime
> -            self.size = st.st_size
>           if request:
>               self.repo.ui.environ = request.env
>
> diff --git a/tests/test-hgweb.t b/tests/test-hgweb.t
> --- a/tests/test-hgweb.t
> +++ b/tests/test-hgweb.t
> @@ -513,6 +513,50 @@
>     304 Not Modified
>
>
> +phase changes are refreshed (issue4061)
> +
> +  $ echo bar >> foo
> +  $ hg ci -msecret --secret
> +  $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'log?style=raw'
> +  200 Script output follows
> +
> +
> +  # HG changelog
> +  # Node ID 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
> +
> +  changeset:   2ef0ac749a14e4f57a5a822464a0902c6f7f448f
> +  revision:    0
> +  user:        test
> +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> +  summary:     base
> +  branch:      default
> +  tag:         tip
> +
> +
> +  $ hg phase --draft tip
> +  $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'log?style=raw'
> +  200 Script output follows
> +
> +
> +  # HG changelog
> +  # Node ID a084749e708a9c4c0a5b652a2a446322ce290e04
> +
> +  changeset:   a084749e708a9c4c0a5b652a2a446322ce290e04
> +  revision:    1
> +  user:        test
> +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> +  summary:     secret
> +  branch:      default
> +  tag:         tip
> +
> +  changeset:   2ef0ac749a14e4f57a5a822464a0902c6f7f448f
> +  revision:    0
> +  user:        test
> +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> +  summary:     base
> +
> +
> +
>   errors
>
>     $ cat errors.log
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>

Patch

diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -112,9 +112,9 @@ 
 def statusmessage(code, message=None):
     return '%d %s' % (code, message or _statusmessage(code))
 
-def get_stat(spath):
-    """stat changelog if it exists, spath otherwise"""
-    cl_path = os.path.join(spath, "00changelog.i")
+def get_stat(spath, fn="00changelog.i"):
+    """stat fn (00changelog.i by default) if it exists, spath otherwise"""
+    cl_path = os.path.join(spath, fn)
     if os.path.exists(cl_path):
         return os.stat(cl_path)
     else:
diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -71,8 +71,8 @@ 
         r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
         self.repo = r
         hook.redirect(True)
+        self.repostate = (-1, -1, -1, -1)
         self.mtime = -1
-        self.size = -1
         self.reponame = name
         self.archives = 'zip', 'gz', 'bz2'
         self.stripecount = 1
@@ -107,9 +107,12 @@ 
 
     def refresh(self, request=None):
         st = get_stat(self.repo.spath)
-        # compare changelog size in addition to mtime to catch
-        # rollbacks made less than a second ago
-        if st.st_mtime != self.mtime or st.st_size != self.size:
+        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)
+        # 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)
             self.maxchanges = int(self.config("web", "maxchanges", 10))
@@ -121,8 +124,9 @@ 
             encoding.encoding = self.config("web", "encoding",
                                             encoding.encoding)
             # update these last to avoid threads seeing empty settings
+            self.repostate = repostate
+            # mtime is needed for ETag
             self.mtime = st.st_mtime
-            self.size = st.st_size
         if request:
             self.repo.ui.environ = request.env
 
diff --git a/tests/test-hgweb.t b/tests/test-hgweb.t
--- a/tests/test-hgweb.t
+++ b/tests/test-hgweb.t
@@ -513,6 +513,50 @@ 
   304 Not Modified
   
 
+phase changes are refreshed (issue4061)
+
+  $ echo bar >> foo
+  $ hg ci -msecret --secret
+  $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'log?style=raw'
+  200 Script output follows
+  
+  
+  # HG changelog
+  # Node ID 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
+  
+  changeset:   2ef0ac749a14e4f57a5a822464a0902c6f7f448f
+  revision:    0
+  user:        test
+  date:        Thu, 01 Jan 1970 00:00:00 +0000
+  summary:     base
+  branch:      default
+  tag:         tip
+  
+  
+  $ hg phase --draft tip
+  $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'log?style=raw'
+  200 Script output follows
+  
+  
+  # HG changelog
+  # Node ID a084749e708a9c4c0a5b652a2a446322ce290e04
+  
+  changeset:   a084749e708a9c4c0a5b652a2a446322ce290e04
+  revision:    1
+  user:        test
+  date:        Thu, 01 Jan 1970 00:00:00 +0000
+  summary:     secret
+  branch:      default
+  tag:         tip
+  
+  changeset:   2ef0ac749a14e4f57a5a822464a0902c6f7f448f
+  revision:    0
+  user:        test
+  date:        Thu, 01 Jan 1970 00:00:00 +0000
+  summary:     base
+  
+  
+
 errors
 
   $ cat errors.log