[PATCH 2 of 3 V2] hgweb: display blamed revision once per block in annotate view

Denis Laxalde denis.laxalde at logilab.fr
Thu Jun 9 08:34:57 EDT 2016


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1465294201 -7200
#      Tue Jun 07 12:10:01 2016 +0200
# Node ID 04658d400e7f667f70a639f919f6ff45dcccb52a
# Parent  3064963ddbc0b509c0f3f8149ca2c6edb2edb568
hgweb: display blamed revision once per block in annotate view

I.e. when a revision blames a block of source lines, only display the
revision link on the first line of the block (this is identified by the
"blockhead" key in annotate context).

This addresses item "Visual grouping of changesets" of the blame improvements
plan (https://www.mercurial-scm.org/wiki/BlamePlan) which states: "Typically
there are block of lines all attributed to the same revision. Instead of
rendering the revision/changeset for every line, we could only render it once
per block."

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -873,15 +873,20 @@ def annotate(web, req, tmpl):
         else:
             lines = enumerate(fctx.annotate(follow=True, linenumber=True,
                                             diffopts=diffopts))
+        previousrev = None
         for lineno, ((f, targetline), l) in lines:
+            rev = f.rev()
+            blockhead = rev != previousrev or None
+            previousrev = rev
             yield {"parity": next(parity),
                    "node": f.hex(),
-                   "rev": f.rev(),
+                   "rev": rev,
                    "blamedrev": blamedrev,
                    "author": f.user(),
                    "desc": f.description(),
                    "extra": f.extra(),
                    "file": f.path(),
+                   "blockhead": blockhead,
                    "targetline": targetline,
                    "line": l,
                    "lineno": lineno + 1,
diff --git a/mercurial/templates/gitweb/map b/mercurial/templates/gitweb/map
--- a/mercurial/templates/gitweb/map
+++ b/mercurial/templates/gitweb/map
@@ -97,9 +97,11 @@ fileline = '
 annotateline = '
   <tr id="{lineid}" style="font-family:monospace" class="parity{parity}">
     <td class="linenr" style="text-align: right;">
-      <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
-         {ifeq(rev, blamedrev, 'class="blamedrev"', '')}
-         title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+      {if(blockhead,
+          '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
+              {ifeq(rev, blamedrev, 'class="blamedrev"', '')}
+              title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>',
+          '')}
     </td>
     <td><pre><a class="linenr" href="#{lineid}">{linenumber}</a></pre></td>
     <td><pre{ifeq(rev, blamedrev, ' class="blamedrev"', '')}>{line|escape}</pre></td>
diff --git a/mercurial/templates/monoblue/map b/mercurial/templates/monoblue/map
--- a/mercurial/templates/monoblue/map
+++ b/mercurial/templates/monoblue/map
@@ -93,8 +93,10 @@ fileline = '
 annotateline = '
   <tr id="{lineid}" class="parity{parity}">
     <td class="linenr">
-      <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
-         title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+      {if(blockhead,
+          '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
+              title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>',
+          '')}
     </td>
     <td class="lineno">
       <a href="#{lineid}">{linenumber}</a>
diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map
--- a/mercurial/templates/paper/map
+++ b/mercurial/templates/paper/map
@@ -78,8 +78,10 @@ filelogentry = filelogentry.tmpl
 annotateline = '
   <tr id="{lineid}">
     <td class="annotate">
-      <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
-         title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+      {if(blockhead,
+          '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
+              title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>',
+          '')}
     </td>
     <td class="source"><a href="#{lineid}">{linenumber}</a> {line|escape}</td>
   </tr>'
diff --git a/mercurial/templates/spartan/map b/mercurial/templates/spartan/map
--- a/mercurial/templates/spartan/map
+++ b/mercurial/templates/spartan/map
@@ -56,8 +56,10 @@ filelogentry = filelogentry.tmpl
 annotateline = '
   <tr class="parity{parity}">
     <td class="annotate">
-      <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
-         title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
+      {if(blockhead,
+          '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
+              title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>',
+          '')}
     </td>
     <td>
       <a class="lineno" href="#{lineid}" id="{lineid}">{linenumber}</a>
diff --git a/tests/test-highlight.t b/tests/test-highlight.t
--- a/tests/test-highlight.t
+++ b/tests/test-highlight.t
@@ -297,225 +297,193 @@ hgweb fileannotate, html
   </tr>
   <tr id="l2">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l2"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l2">     2</a> </td>
   </tr>
   <tr id="l3">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l3"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l3">     3</a> <span class="sd">"""Fun with generators. Corresponding Haskell implementation:</span></td>
   </tr>
   <tr id="l4">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l4"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l4">     4</a> </td>
   </tr>
   <tr id="l5">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l5"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l5">     5</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></td>
   </tr>
   <tr id="l6">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l6"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l6">     6</a> <span class="sd">    where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0]</span></td>
   </tr>
   <tr id="l7">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l7"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l7">     7</a> <span class="sd">"""</span></td>
   </tr>
   <tr id="l8">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l8"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l8">     8</a> </td>
   </tr>
   <tr id="l9">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l9"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l9">     9</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></td>
   </tr>
   <tr id="l10">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l10"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l10">    10</a> </td>
   </tr>
   <tr id="l11">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l11"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l11">    11</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></td>
   </tr>
   <tr id="l12">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l12"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l12">    12</a>     <span class="sd">"""Generate all primes."""</span></td>
   </tr>
   <tr id="l13">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l13"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l13">    13</a>     <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
   </tr>
   <tr id="l14">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l14"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l14">    14</a>         <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></td>
   </tr>
   <tr id="l15">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l15"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l15">    15</a>         <span class="c"># It is important to yield *here* in order to stop the</span></td>
   </tr>
   <tr id="l16">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l16"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l16">    16</a>         <span class="c"># infinite recursion.</span></td>
   </tr>
   <tr id="l17">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l17"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l17">    17</a>         <span class="kn">yield</span> <span class="n">p</span></td>
   </tr>
   <tr id="l18">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l18"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l18">    18</a>         <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></td>
   </tr>
   <tr id="l19">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l19"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l19">    19</a>         <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
   </tr>
   <tr id="l20">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l20"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l20">    20</a>             <span class="kn">yield</span> <span class="n">n</span></td>
   </tr>
   <tr id="l21">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l21"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l21">    21</a> </td>
   </tr>
   <tr id="l22">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l22"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l22">    22</a>     <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></td>
   </tr>
   <tr id="l23">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l23"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l23">    23</a>     <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o"><</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></td>
   </tr>
   <tr id="l24">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l24"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l24">    24</a> </td>
   </tr>
   <tr id="l25">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l25"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l25">    25</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span></td>
   </tr>
   <tr id="l26">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l26"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l26">    26</a>     <span class="kn">import</span> <span class="nn">sys</span></td>
   </tr>
   <tr id="l27">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l27"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l27">    27</a>     <span class="kn">try</span><span class="p">:</span></td>
   </tr>
   <tr id="l28">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l28"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l28">    28</a>         <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></td>
   </tr>
   <tr id="l29">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l29"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l29">    29</a>     <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></td>
   </tr>
   <tr id="l30">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l30"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l30">    30</a>         <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></td>
   </tr>
   <tr id="l31">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l31"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l31">    31</a>     <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></td>
   </tr>
   <tr id="l32">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l32"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l32">    32</a>     <span class="kn">print</span> <span class="s">"The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></td>
   </tr>
   <tr id="l33">
   <td class="annotate">
-  <a href="/annotate/06824edf55d0/primes.py#l33"
-  title="06824edf55d0: a">test at 0</a>
+  
   </td>
   <td class="source"><a href="#l33">    33</a> </td>
   </tr>


More information about the Mercurial-devel mailing list