Patchwork [08,of,11] hgweb: handle "linerange" request parameter in filediff command

login
register
mail settings
Submitter Denis Laxalde
Date Feb. 22, 2017, 3:10 p.m.
Message ID <39e3bd58cb1af11ba2fd.1487776202@sh77.tls.logilab.fr>
Download mbox | patch
Permalink /patch/18715/
State Accepted
Delegated to: Yuya Nishihara
Headers show

Comments

Denis Laxalde - Feb. 22, 2017, 3:10 p.m.
# HG changeset patch
# User Denis Laxalde <denis.laxalde@logilab.fr>
# Date 1484922599 -3600
#      Fri Jan 20 15:29:59 2017 +0100
# Node ID 39e3bd58cb1af11ba2fd0a1a74bb134711dfe718
# Parent  b3f8ef870003ee2ca6b6db70860a065f255902b7
# EXP-Topic linerange-log/hgweb-filelog
hgweb: handle "linerange" request parameter in filediff command

If a linerange=<fromline>-<toline> query parameter is present on a request to
filediff view we use this information to filter the diff to only display the
specified range of lines. This is achieved by getting the first "block
ancestor" of filectx and using it as the "basectx" in comparison along with
the pair of line ranges of both file contexts to generated a filtered diff.

Extra tests added in test-hgweb-diffs.t covering changes on hgweb side as well
as those in patch/mdiff of previous changesets.

Update only gitweb template in this version.

Patch

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -728,6 +728,9 @@  def summary(web, req, tmpl):
                 archives=web.archivelist("tip"),
                 labels=web.configlist('web', 'labels'))
 
+def formatlinerange(fromline, toline):
+    return '%d-%d' % (fromline + 1, toline)
+
 @webcommand('filediff')
 def filediff(web, req, tmpl):
     """
@@ -760,7 +763,24 @@  def filediff(web, req, tmpl):
     if 'style' in req.form:
         style = req.form['style'][0]
 
-    diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], parity, style)
+    lineranges = {}
+    linerange = webutil.linerange(req)
+    if linerange is not None:
+        assert fctx is not None
+        lineranges = {fctx: linerange}
+        ancestors = context.blockancestors(fctx, *linerange, followfirst=True)
+        try:
+            next(ancestors)  # first iteration returns fctx
+            p, plinerange = next(ancestors)
+        except StopIteration:
+            pass
+        else:
+            lineranges[p] = plinerange
+            basectx = p.changectx()
+        linerange = formatlinerange(*linerange)
+
+    diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], parity, style,
+                          lineranges)
     if fctx is not None:
         rename = webutil.renamelink(fctx)
         ctx = fctx
@@ -772,6 +792,7 @@  def filediff(web, req, tmpl):
                 symrev=webutil.symrevorshortnode(req, ctx),
                 rename=rename,
                 diff=diffs,
+                linerange=linerange,
                 **webutil.commonentry(web.repo, ctx))
 
 diff = webcommand('diff')(filediff)
@@ -970,9 +991,6 @@  def filelog(web, req, tmpl):
 
     lrange = webutil.linerange(req)
 
-    def formatlinerange(fromline, toline):
-        return '%d-%d' % (fromline + 1, toline)
-
     lessvars = copy.copy(tmpl.defaults['sessionvars'])
     lessvars['revcount'] = max(revcount / 2, 1)
     morevars = copy.copy(tmpl.defaults['sessionvars'])
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -431,7 +431,7 @@  def listfilediffs(tmpl, files, node, max
     if len(files) > max:
         yield tmpl('fileellipses')
 
-def diffs(repo, tmpl, ctx, basectx, files, parity, style):
+def diffs(repo, tmpl, ctx, basectx, files, parity, style, lineranges=None):
 
     def countgen():
         start = 1
@@ -467,7 +467,8 @@  def diffs(repo, tmpl, ctx, basectx, file
     node2 = ctx.node()
 
     block = []
-    for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
+    for chunk in patch.diff(repo, node1, node2, m, opts=diffopts,
+                            lineranges=lineranges):
         if chunk.startswith('diff') and block:
             blockno = next(blockcount)
             yield tmpl('diffblock', parity=next(parity), blockno=blockno,
diff --git a/mercurial/templates/gitweb/filediff.tmpl b/mercurial/templates/gitweb/filediff.tmpl
--- a/mercurial/templates/gitweb/filediff.tmpl
+++ b/mercurial/templates/gitweb/filediff.tmpl
@@ -33,7 +33,9 @@  diff |
 <br/>
 </div>
 
-<div class="title">{file|escape}</div>
+<div class="title">\
+{file|escape}{if(linerange, ' (line range: {linerange} <a href="{url|urlescape}diff/{symrev}/{file|urlescape}{sessionvars%urlparameter}">full diff</a>)')}\
+</div>
 
 <table>
 {branch%filerevbranch}
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
@@ -1094,6 +1094,305 @@  comparison not-modified file
   </body>
   </html>
   
+  $ cat <<EOF > c
+  > 1
+  > 2
+  > 3
+  > 4
+  > 5
+  > 6
+  > EOF
+  $ hg ci -Amc c
+  $ cat <<EOF > c
+  > 1
+  > 2+
+  > 3
+  > 4
+  > 5-
+  > 6
+  > EOF
+  $ hg ci -m 'update c' c
+  $ get-with-headers.py localhost:$HGPORT 'diff/tip/c?style=gitweb'
+  200 Script output follows
+  
+  <?xml version="1.0" encoding="ascii"?>
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+  <head>
+  <link rel="icon" href="/static/hgicon.png" type="image/png" />
+  <meta name="robots" content="index, nofollow"/>
+  <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
+  
+  <title>test: diff c</title>
+  <link rel="alternate" type="application/atom+xml"
+     href="/atom-log" title="Atom feed for test"/>
+  <link rel="alternate" type="application/rss+xml"
+     href="/rss-log" title="RSS feed for test"/>
+  </head>
+  <body>
+  
+  <div class="page_header">
+  <a href="https://mercurial-scm.org/" title="Mercurial" style="float: right;">Mercurial</a>
+  <a href="/">Mercurial</a>  / diff
+  </div>
+  
+  <div class="page_nav">
+  <a href="/summary?style=gitweb">summary</a> |
+  <a href="/shortlog?style=gitweb">shortlog</a> |
+  <a href="/log?style=gitweb">changelog</a> |
+  <a href="/graph?style=gitweb">graph</a> |
+  <a href="/tags?style=gitweb">tags</a> |
+  <a href="/bookmarks?style=gitweb">bookmarks</a> |
+  <a href="/branches?style=gitweb">branches</a> |
+  <a href="/file/tip?style=gitweb">files</a> |
+  <a href="/rev/tip?style=gitweb">changeset</a> |
+  <a href="/file/tip/c?style=gitweb">file</a> |
+  <a href="/file/tip/c?style=gitweb">latest</a> |
+  <a href="/log/tip/c?style=gitweb">revisions</a> |
+  <a href="/annotate/tip/c?style=gitweb">annotate</a> |
+  diff |
+  <a href="/comparison/tip/c?style=gitweb">comparison</a> |
+  <a href="/raw-diff/tip/c">raw</a> |
+  <a href="/help?style=gitweb">help</a>
+  <br/>
+  </div>
+  
+  <div class="title">c</div>
+  
+  <table>
+  
+  <tr>
+   <td>changeset 7</td>
+   <td style="font-family:monospace"><a class="list" href="/rev/46dadddbce95?style=gitweb">46dadddbce95</a></td>
+  </tr>
+  
+  <tr>
+  <td>parent 6</td>
+  <td style="font-family:monospace">
+  <a class="list" href="/diff/3deb5080745a/c?style=gitweb">
+  3deb5080745a
+  </a>
+  </td>
+  </tr>
+  
+  </table>
+  
+  <div class="list_head"></div>
+  
+  <div class="page_body">
+  <div class="diffblock"><pre class="sourcelines">
+  <a href="#l1.1"></a><span id="l1.1" class="difflineminus">--- a/c</span>
+  <a href="#l1.2"></a><span id="l1.2" class="difflineplus">+++ b/c</span>
+  <a href="#l1.3"></a><span id="l1.3" class="difflineat">@@ -1,6 +1,6 @@</span>
+  <a href="#l1.4"></a><span id="l1.4"> 1</span>
+  <a href="#l1.5"></a><span id="l1.5" class="difflineminus">-2</span>
+  <a href="#l1.6"></a><span id="l1.6" class="difflineplus">+2+</span>
+  <a href="#l1.7"></a><span id="l1.7"> 3</span>
+  <a href="#l1.8"></a><span id="l1.8"> 4</span>
+  <a href="#l1.9"></a><span id="l1.9" class="difflineminus">-5</span>
+  <a href="#l1.10"></a><span id="l1.10" class="difflineplus">+5-</span>
+  <a href="#l1.11"></a><span id="l1.11"> 6</span></pre></div>
+  </div>
+  
+  <div class="page_footer">
+  <div class="page_footer_text">test</div>
+  <div class="rss_logo">
+  <a href="/rss-log">RSS</a>
+  <a href="/atom-log">Atom</a>
+  </div>
+  <br />
+  
+  </div>
+  </body>
+  </html>
+  
+  $ get-with-headers.py localhost:$HGPORT 'diff/tip/c?style=gitweb&linerange=1-3'
+  200 Script output follows
+  
+  <?xml version="1.0" encoding="ascii"?>
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+  <head>
+  <link rel="icon" href="/static/hgicon.png" type="image/png" />
+  <meta name="robots" content="index, nofollow"/>
+  <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
+  
+  <title>test: diff c</title>
+  <link rel="alternate" type="application/atom+xml"
+     href="/atom-log" title="Atom feed for test"/>
+  <link rel="alternate" type="application/rss+xml"
+     href="/rss-log" title="RSS feed for test"/>
+  </head>
+  <body>
+  
+  <div class="page_header">
+  <a href="https://mercurial-scm.org/" title="Mercurial" style="float: right;">Mercurial</a>
+  <a href="/">Mercurial</a>  / diff
+  </div>
+  
+  <div class="page_nav">
+  <a href="/summary?style=gitweb">summary</a> |
+  <a href="/shortlog?style=gitweb">shortlog</a> |
+  <a href="/log?style=gitweb">changelog</a> |
+  <a href="/graph?style=gitweb">graph</a> |
+  <a href="/tags?style=gitweb">tags</a> |
+  <a href="/bookmarks?style=gitweb">bookmarks</a> |
+  <a href="/branches?style=gitweb">branches</a> |
+  <a href="/file/tip?style=gitweb">files</a> |
+  <a href="/rev/tip?style=gitweb">changeset</a> |
+  <a href="/file/tip/c?style=gitweb">file</a> |
+  <a href="/file/tip/c?style=gitweb">latest</a> |
+  <a href="/log/tip/c?style=gitweb">revisions</a> |
+  <a href="/annotate/tip/c?style=gitweb">annotate</a> |
+  diff |
+  <a href="/comparison/tip/c?style=gitweb">comparison</a> |
+  <a href="/raw-diff/tip/c">raw</a> |
+  <a href="/help?style=gitweb">help</a>
+  <br/>
+  </div>
+  
+  <div class="title">c (line range: 1-3 <a href="/diff/tip/c?style=gitweb">full diff</a>)</div>
+  
+  <table>
+  
+  <tr>
+   <td>changeset 7</td>
+   <td style="font-family:monospace"><a class="list" href="/rev/46dadddbce95?style=gitweb">46dadddbce95</a></td>
+  </tr>
+  
+  <tr>
+  <td>parent 6</td>
+  <td style="font-family:monospace">
+  <a class="list" href="/diff/3deb5080745a/c?style=gitweb">
+  3deb5080745a
+  </a>
+  </td>
+  </tr>
+  
+  </table>
+  
+  <div class="list_head"></div>
+  
+  <div class="page_body">
+  <div class="diffblock"><pre class="sourcelines">
+  <a href="#l1.1"></a><span id="l1.1" class="difflineminus">--- a/c</span>
+  <a href="#l1.2"></a><span id="l1.2" class="difflineplus">+++ b/c</span>
+  <a href="#l1.3"></a><span id="l1.3" class="difflineat">@@ -1,5 +1,5 @@</span>
+  <a href="#l1.4"></a><span id="l1.4"> 1</span>
+  <a href="#l1.5"></a><span id="l1.5" class="difflineminus">-2</span>
+  <a href="#l1.6"></a><span id="l1.6" class="difflineplus">+2+</span>
+  <a href="#l1.7"></a><span id="l1.7"> 3</span>
+  <a href="#l1.8"></a><span id="l1.8"> 4</span>
+  <a href="#l1.9"></a><span id="l1.9"> 5</span></pre></div>
+  </div>
+  
+  <div class="page_footer">
+  <div class="page_footer_text">test</div>
+  <div class="rss_logo">
+  <a href="/rss-log">RSS</a>
+  <a href="/atom-log">Atom</a>
+  </div>
+  <br />
+  
+  </div>
+  </body>
+  </html>
+  
+  $ get-with-headers.py localhost:$HGPORT 'diff/tip/c?style=gitweb&linerange=3-6'
+  200 Script output follows
+  
+  <?xml version="1.0" encoding="ascii"?>
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+  <head>
+  <link rel="icon" href="/static/hgicon.png" type="image/png" />
+  <meta name="robots" content="index, nofollow"/>
+  <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
+  
+  <title>test: diff c</title>
+  <link rel="alternate" type="application/atom+xml"
+     href="/atom-log" title="Atom feed for test"/>
+  <link rel="alternate" type="application/rss+xml"
+     href="/rss-log" title="RSS feed for test"/>
+  </head>
+  <body>
+  
+  <div class="page_header">
+  <a href="https://mercurial-scm.org/" title="Mercurial" style="float: right;">Mercurial</a>
+  <a href="/">Mercurial</a>  / diff
+  </div>
+  
+  <div class="page_nav">
+  <a href="/summary?style=gitweb">summary</a> |
+  <a href="/shortlog?style=gitweb">shortlog</a> |
+  <a href="/log?style=gitweb">changelog</a> |
+  <a href="/graph?style=gitweb">graph</a> |
+  <a href="/tags?style=gitweb">tags</a> |
+  <a href="/bookmarks?style=gitweb">bookmarks</a> |
+  <a href="/branches?style=gitweb">branches</a> |
+  <a href="/file/tip?style=gitweb">files</a> |
+  <a href="/rev/tip?style=gitweb">changeset</a> |
+  <a href="/file/tip/c?style=gitweb">file</a> |
+  <a href="/file/tip/c?style=gitweb">latest</a> |
+  <a href="/log/tip/c?style=gitweb">revisions</a> |
+  <a href="/annotate/tip/c?style=gitweb">annotate</a> |
+  diff |
+  <a href="/comparison/tip/c?style=gitweb">comparison</a> |
+  <a href="/raw-diff/tip/c">raw</a> |
+  <a href="/help?style=gitweb">help</a>
+  <br/>
+  </div>
+  
+  <div class="title">c (line range: 3-6 <a href="/diff/tip/c?style=gitweb">full diff</a>)</div>
+  
+  <table>
+  
+  <tr>
+   <td>changeset 7</td>
+   <td style="font-family:monospace"><a class="list" href="/rev/46dadddbce95?style=gitweb">46dadddbce95</a></td>
+  </tr>
+  
+  <tr>
+  <td>parent 6</td>
+  <td style="font-family:monospace">
+  <a class="list" href="/diff/3deb5080745a/c?style=gitweb">
+  3deb5080745a
+  </a>
+  </td>
+  </tr>
+  
+  </table>
+  
+  <div class="list_head"></div>
+  
+  <div class="page_body">
+  <div class="diffblock"><pre class="sourcelines">
+  <a href="#l1.1"></a><span id="l1.1" class="difflineminus">--- a/c</span>
+  <a href="#l1.2"></a><span id="l1.2" class="difflineplus">+++ b/c</span>
+  <a href="#l1.3"></a><span id="l1.3" class="difflineat">@@ -2,5 +2,5 @@</span>
+  <a href="#l1.4"></a><span id="l1.4"> 2</span>
+  <a href="#l1.5"></a><span id="l1.5"> 3</span>
+  <a href="#l1.6"></a><span id="l1.6"> 4</span>
+  <a href="#l1.7"></a><span id="l1.7" class="difflineminus">-5</span>
+  <a href="#l1.8"></a><span id="l1.8" class="difflineplus">+5-</span>
+  <a href="#l1.9"></a><span id="l1.9"> 6</span></pre></div>
+  </div>
+  
+  <div class="page_footer">
+  <div class="page_footer_text">test</div>
+  <div class="rss_logo">
+  <a href="/rss-log">RSS</a>
+  <a href="/atom-log">Atom</a>
+  </div>
+  <br />
+  
+  </div>
+  </body>
+  </html>
+  
   $ cd ..
 
 test import rev as raw-rev