[PATCH 5 of 8 V2] hgweb: handle "linerange" request parameter in filediff command

Denis Laxalde denis at laxalde.org
Sat Feb 25 04:06:02 EST 2017


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1484922599 -3600
#      Fri Jan 20 15:29:59 2017 +0100
# Node ID 7fbe70c91d65683ab3984f7c80edc85f5c02860c
# Parent  6625dfbecf264f51748a96aa7203fc09bee597e9
# Available At https://hg.logilab.org/users/dlaxalde/hg
#              hg pull https://hg.logilab.org/users/dlaxalde/hg -r 7fbe70c91d65
# 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.

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -762,7 +762,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 = webutil.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
@@ -774,6 +791,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)
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -430,7 +430,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
@@ -466,7 +466,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


More information about the Mercurial-devel mailing list