Patchwork [1,of,2,V2] hgweb: display fate of obsolete changesets

login
register
mail settings
Submitter Anton Shestakov
Date Dec. 22, 2017, 2:40 p.m.
Message ID <d3211cd1ef5ed1f5a50d.1513953615@neuro>
Download mbox | patch
Permalink /patch/26401/
State Accepted
Headers show

Comments

Anton Shestakov - Dec. 22, 2017, 2:40 p.m.
# HG changeset patch
# User Anton Shestakov <av6@dwimlabs.net>
# Date 1511255021 -28800
#      Tue Nov 21 17:03:41 2017 +0800
# Node ID d3211cd1ef5ed1f5a50d49af800155271ad3861e
# Parent  bb6a80fc969a2c5da80cbb7f29de7ca576c4e251
# EXP-Topic hgweb-more-info
hgweb: display fate of obsolete changesets

Operations that obsolete changesets store enough metadata to explain what
happened after the fact. One way to get that metadata is showsuccsandmarkers
function, which returns a list of successors of a particular changeset and
appropriate obsolescence markers.

Templates have a set of experimental functions that have names starting with
obsfate. This patch uses some of these functions to interpret output of
succsandmarkers() and produce human-friendly messages that describe what
happened to an obsolete changeset, e.g. "pruned" or "rewritten as
6:3de5eca88c00".

In commonentry(), succsandmarkers property is made callable so it's only
executed on demand; this saves time when changeset is not obsolete, and also in
e.g. /shortlog view, where there are a lot of changesets, but we don't need to
show each and every one in detail.

In spartan theme, succsandmarkers is used instead of the simple "obsolete:
yes", in other themes a new line is added to /rev page.

Patch

diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -32,6 +32,7 @@  from .. import (
     pathutil,
     pycompat,
     templatefilters,
+    templatekw,
     ui as uimod,
     util,
 )
@@ -351,6 +352,9 @@  def linerange(req):
 def formatlinerange(fromline, toline):
     return '%d:%d' % (fromline + 1, toline)
 
+def succsandmarkers(repo, ctx):
+    return templatekw.showsuccsandmarkers(repo, ctx)
+
 def commonentry(repo, ctx):
     node = ctx.node()
     return {
@@ -362,6 +366,7 @@  def commonentry(repo, ctx):
         'extra': ctx.extra(),
         'phase': ctx.phasestr(),
         'obsolete': ctx.obsolete(),
+        'succsandmarkers': lambda **x: succsandmarkers(repo, ctx),
         'instabilities': [{"instability": i} for i in ctx.instabilities()],
         'branch': nodebranchnodefault(ctx),
         'inbranch': nodeinbranch(repo, ctx),
diff --git a/mercurial/templates/gitweb/changeset.tmpl b/mercurial/templates/gitweb/changeset.tmpl
--- a/mercurial/templates/gitweb/changeset.tmpl
+++ b/mercurial/templates/gitweb/changeset.tmpl
@@ -44,6 +44,7 @@  changeset |
  <td>changeset {rev}</td>
  <td style="font-family:monospace"><a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
 </tr>
+{if(obsolete, '<tr><td>obsolete</td><td>{succsandmarkers%obsfateentry}</td></tr>')}
 {ifeq(count(parent), '2', parent%changesetparentdiff, parent%changesetparent)}
 {child%changesetchild}
 </table></div>
diff --git a/mercurial/templates/gitweb/map b/mercurial/templates/gitweb/map
--- a/mercurial/templates/gitweb/map
+++ b/mercurial/templates/gitweb/map
@@ -271,6 +271,10 @@  branchtag = '<span class="branchtag" tit
 inbranchtag = '<span class="inbranchtag" title="{name|escape}">{name|escape}</span> '
 bookmarktag = '<span class="bookmarktag" title="{name|escape}">{name|escape}</span> '
 alltags = '<span class="logtags">{phasetag}{obsoletetag}{instabilities%instabilitytag}{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>'
+obsfatesuccessors = '{if(successors, ' as ')}{join(successors, ', ')}'
+obsfateverb = '{obsfateverb(successors, markers)}'
+obsfateoperations = '{if(obsfateoperations(markers), ' using {join(obsfateoperations(markers), ', ')}')}'
+obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}'
 shortlogentry = '
   <tr class="parity{parity}">
     <td class="age"><i class="age">{date|rfc822date}</i></td>
diff --git a/mercurial/templates/monoblue/changeset.tmpl b/mercurial/templates/monoblue/changeset.tmpl
--- a/mercurial/templates/monoblue/changeset.tmpl
+++ b/mercurial/templates/monoblue/changeset.tmpl
@@ -48,6 +48,7 @@ 
         {branch%changesetbranch}
         <dt>changeset {rev}</dt>
         <dd><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
+        {if(obsolete, '<dt>obsolete</dt><dd>{succsandmarkers%obsfateentry}</dd>')}
         {ifeq(count(parent), '2', parent%changesetparentdiff, parent%changesetparent)}
         {child%changesetchild}
     </dl>
diff --git a/mercurial/templates/monoblue/map b/mercurial/templates/monoblue/map
--- a/mercurial/templates/monoblue/map
+++ b/mercurial/templates/monoblue/map
@@ -229,6 +229,10 @@  branchtag = '<span class="branchtag" tit
 inbranchtag = '<span class="inbranchtag" title="{name|escape}">{name|escape}</span> '
 bookmarktag = '<span class="bookmarktag" title="{name|escape}">{name|escape}</span> '
 alltags = '<span class="logtags">{phasetag}{obsoletetag}{instabilities%instabilitytag}{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>'
+obsfatesuccessors = '{if(successors, ' as ')}{join(successors, ', ')}'
+obsfateverb = '{obsfateverb(successors, markers)}'
+obsfateoperations = '{if(obsfateoperations(markers), ' using {join(obsfateoperations(markers), ', ')}')}'
+obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}'
 shortlogentry = '
   <tr class="parity{parity}">
     <td class="nowrap age">{date|rfc822date}</td>
diff --git a/mercurial/templates/paper/changeset.tmpl b/mercurial/templates/paper/changeset.tmpl
--- a/mercurial/templates/paper/changeset.tmpl
+++ b/mercurial/templates/paper/changeset.tmpl
@@ -49,6 +49,10 @@ 
  <th class="date">date</th>
  <td class="date age">{date|rfc822date}</td>
 </tr>
+{if(obsolete, '<tr>
+ <th>obsolete</th>
+ <td>{succsandmarkers%obsfateentry}</td>
+</tr>')}
 <tr>
  <th class="author">parents</th>
  <td class="author">{ifeq(count(parent), '2', parent%changesetparentdiff, parent%changesetparent)}</td>
diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map
--- a/mercurial/templates/paper/map
+++ b/mercurial/templates/paper/map
@@ -209,6 +209,11 @@  changelogbranchhead = '<span class="bran
 changelogbranchname = '<span class="branchname">{name|escape}</span> '
 alltags = '{phasetag}{obsoletetag}{instabilities%instabilitytag}{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}{bookmarks%changelogtag}'
 
+obsfatesuccessors = '{if(successors, ' as ')}{join(successors, ', ')}'
+obsfateverb = '{obsfateverb(successors, markers)}'
+obsfateoperations = '{if(obsfateoperations(markers), ' using {join(obsfateoperations(markers), ', ')}')}'
+obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}'
+
 filediffparent = '
   <tr>
     <th class="parent">parent {rev}:</th>
diff --git a/mercurial/templates/spartan/changelogentry.tmpl b/mercurial/templates/spartan/changelogentry.tmpl
--- a/mercurial/templates/spartan/changelogentry.tmpl
+++ b/mercurial/templates/spartan/changelogentry.tmpl
@@ -24,7 +24,7 @@ 
  </tr>')}
  {if(obsolete, '<tr>
   <th class="obsolete">obsolete:</th>
-  <td class="obsolete">yes</td>
+  <td class="obsolete">{succsandmarkers%obsfateentry}</td>
  </tr>')}
  {ifeq(count(instabilities), '0', '', '<tr>
   <th class="instabilities">instabilities:</th>
diff --git a/mercurial/templates/spartan/changeset.tmpl b/mercurial/templates/spartan/changeset.tmpl
--- a/mercurial/templates/spartan/changeset.tmpl
+++ b/mercurial/templates/spartan/changeset.tmpl
@@ -39,7 +39,7 @@ 
 </tr>')}
 {if(obsolete, '<tr>
  <th class="obsolete">obsolete:</th>
- <td class="obsolete">yes</td>
+ <td class="obsolete">{succsandmarkers%obsfateentry}</td>
 </tr>')}
 {ifeq(count(instabilities), '0', '', '<tr>
  <th class="instabilities">instabilities:</th>
diff --git a/mercurial/templates/spartan/map b/mercurial/templates/spartan/map
--- a/mercurial/templates/spartan/map
+++ b/mercurial/templates/spartan/map
@@ -166,6 +166,10 @@  branchentry = '
 diffblock = '<pre class="parity{parity}">{lines}</pre>'
 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">{tag|escape}</td></tr>'
 changesettag = '<tr><th class="tag">tag:</th><td class="tag">{tag|escape}</td></tr>'
+obsfatesuccessors = '{if(successors, ' as ')}{join(successors, ', ')}'
+obsfateverb = '{obsfateverb(successors, markers)}'
+obsfateoperations = '{if(obsfateoperations(markers), ' using {join(obsfateoperations(markers), ', ')}')}'
+obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}'
 filediffparent = '
   <tr>
     <th class="parent">parent {rev}:</th>
diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t
--- a/tests/test-hgweb-commands.t
+++ b/tests/test-hgweb-commands.t
@@ -902,6 +902,7 @@  Logs and changes
    <th class="date">date</th>
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
diff --git a/tests/test-hgweb-diffs.t b/tests/test-hgweb-diffs.t
--- a/tests/test-hgweb-diffs.t
+++ b/tests/test-hgweb-diffs.t
@@ -103,6 +103,7 @@  revision
    <th class="date">date</th>
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
@@ -398,6 +399,7 @@  revision
    <th class="date">date</th>
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
diff --git a/tests/test-hgweb-removed.t b/tests/test-hgweb-removed.t
--- a/tests/test-hgweb-removed.t
+++ b/tests/test-hgweb-removed.t
@@ -84,6 +84,7 @@  revision
    <th class="date">date</th>
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -1032,7 +1032,19 @@  check obsolete changeset
           <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
   $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=spartan' | grep 'class="obsolete"'
     <th class="obsolete">obsolete:</th>
-    <td class="obsolete">yes</td>
+    <td class="obsolete">pruned</td>
+
+check an obsolete changeset that has been rewritten
+  $ get-with-headers.py localhost:$HGPORT 'rev/cda648ca50f5?style=paper' | grep rewritten
+   <td>rewritten as 6:3de5eca88c00</td>
+  $ get-with-headers.py localhost:$HGPORT 'rev/cda648ca50f5?style=coal' | grep rewritten
+   <td>rewritten as 6:3de5eca88c00</td>
+  $ get-with-headers.py localhost:$HGPORT 'rev/cda648ca50f5?style=gitweb' | grep rewritten
+  <tr><td>obsolete</td><td>rewritten as 6:3de5eca88c00</td></tr>
+  $ get-with-headers.py localhost:$HGPORT 'rev/cda648ca50f5?style=monoblue' | grep rewritten
+          <dt>obsolete</dt><dd>rewritten as 6:3de5eca88c00</dd>
+  $ get-with-headers.py localhost:$HGPORT 'rev/cda648ca50f5?style=spartan' | grep rewritten
+   <td class="obsolete">rewritten as 6:3de5eca88c00</td>
 
 check changeset with instabilities