Patch adding a "changesetdiff" command to hgwebdir

Radomir Dopieralski sheep at stxnext.pl
Fri Oct 29 06:45:41 CDT 2010


The following patch, written by Tomasz Nowicki, adds a new command do
hgweb, allowing it do display a diff between any two revisions, not
just consecutive revisions.
We are using this in our local hgweb install to review differences
bewteen different tagged releases of our software.

The patch is rather long, because it adds a new template in every one
of available skins -- the changes in code itself are small.
I have applied it successfully against revision 12873:e1855dee28c1 in
the http://selenic.com/repo/hg repository and ran the tests. The
results are as follow:

Skipped test-casefolding.t: missing feature: case insensitive file system
Skipped test-convert-baz: missing feature: GNU Arch baz client
Skipped test-convert-darcs.t: missing feature: darcs client
Skipped test-convert-hg-svn.t: missing feature: subversion python bindings
Skipped test-convert-mtn.t: missing feature: monotone client (> 0.31)
Skipped test-convert-p4: missing feature: Perforce server and client
Skipped test-convert-p4-filetypes: missing feature: Perforce server and client
Skipped test-convert-svn-branches.t: missing feature: subversion python bindings
Skipped test-convert-svn-encoding.t: missing feature: subversion python bindings
Skipped test-convert-svn-move.t: missing feature: subversion python bindings
Skipped test-convert-svn-sink.t: missing feature: subversion python bindings
Skipped test-convert-svn-source.t: missing feature: subversion python bindings
Skipped test-convert-svn-startrev.t: missing feature: subversion python bindings
Skipped test-convert-svn-tags.t: missing feature: subversion python bindings
Skipped test-convert-tla.t: missing feature: GNU Arch tla client
Skipped test-no-symlinks: system supports symbolic links
Failed test-convert-cvs-branch.t: output changed
Failed test-convert-cvs-detectmerge.t: output changed
Failed test-convert-cvs-synthetic.t: output changed
Failed test-convert-cvs.t: output changed
Failed test-convert-cvsnt-mergepoints.t: output changed
# Ran 392 tests, 16 skipped, 6 failed.

I assume that the failures are due to a missing CVS repository that
could be used for testing, but I am not entirely sure.

# HG changeset patch
# User Radomir Dopieralski <hg at sheep.art.pl>

hgweb:  show differences between two changesets

New method changesetdiff which works like diff for specified changsets.

Require URL in form: repo_url/changesetdiff/node1/node2
Example: repo_url/changesetdiff/2f4a5838ad9a/906566e84024

diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/hgweb/hgweb_mod.py	Fri Oct 29 13:16:09 2010 +0200
@@ -145,6 +145,12 @@

             if cmd == 'static':
                 req.form['file'] = ['/'.join(args)]
+            elif cmd == 'changesetdiff':
+                if args:
+                    if len(args)== 1:
+                        req.form['node'] = [args.pop(0)]
+                    if len(args) == 2:
+                        req.form['node'] = [args.pop(0), args.pop(0)]
             else:
                 if args and args[0]:
                     node = args.pop(0)
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/hgweb/webcommands.py	Fri Oct 29 13:16:09 2010 +0200
@@ -22,7 +22,7 @@
 __all__ = [
    'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
    'manifest', 'tags', 'branches', 'summary', 'filediff', 'diff', 'annotate',
-   'filelog', 'archive', 'static', 'graph', 'help',
+   'filelog', 'archive', 'static', 'graph', 'help', 'changesetdiff',
 ]

 def log(web, req, tmpl):
@@ -781,3 +781,37 @@
         raise ErrorResponse(HTTP_NOT_FOUND)
     doc = u.popbuffer()
     return tmpl('help', topic=topicname, doc=doc)
+
+def changesetdiff(web, req, tmpl):
+    """
+    Show differences between two changesets specified in the URL.
+
+    Require URL in form: /changesetdiff/node1/node2
+    """
+    ctx1 = webutil.changectx(web.repo, req, node_id=0)
+    ctx2 = webutil.changectx(web.repo, req, node_id=1)
+
+    if ctx1.node() == ctx2.node():
+        return changeset(web, req, tmpl)
+
+    parity = paritygen(web.stripecount)
+
+    style = web.config('web', 'style', 'paper')
+    if 'style' in req.form:
+        style = req.form['style'][0]
+
+    diffs = webutil.diffs(web.repo, tmpl, ctx1, None, parity, style, ctx2)
+    return tmpl('changesetdiff',
+                diff=diffs,
+                rev1=ctx1.rev(),
+                rev2=ctx2.rev(),
+                node1=ctx1.hex(),
+                node2=ctx2.hex(),
+                desc1=ctx1.description(),
+                desc2=ctx2.description(),
+                author1=ctx1.user(),
+                author2=ctx2.user(),
+                date1=ctx1.date(),
+                date2=ctx2.date(),
+    )
+
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/hgweb/webutil.py	Fri Oct 29 13:16:09 2010 +0200
@@ -122,10 +122,13 @@
     path = path.lstrip('/')
     return util.canonpath(repo.root, '', path)

-def changectx(repo, req):
+def changectx(repo, req, node_id=0):
     changeid = "tip"
     if 'node' in req.form:
-        changeid = req.form['node'][0]
+        try:
+            changeid = req.form['node'][node_id]
+        except IndexError:
+            changeid = req.form['node'][0]
     elif 'manifest' in req.form:
         changeid = req.form['manifest'][0]

@@ -156,7 +159,7 @@
     if len(files) > max:
         yield tmpl('fileellipses')

-def diffs(repo, tmpl, ctx, files, parity, style):
+def diffs(repo, tmpl, ctx, files, parity, style, ctx2=None):

     def countgen():
         start = 1
@@ -189,7 +192,12 @@

     diffopts = patch.diffopts(repo.ui, untrusted=True)
     parents = ctx.parents()
-    node1 = parents and parents[0].node() or nullid
+
+    if ctx2 is None:
+        node1 = parents and parents[0].node() or nullid
+    else:
+        node1 = ctx2.node()
+
     node2 = ctx.node()

     block = []
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/templates/coal/map
--- a/mercurial/templates/coal/map	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/templates/coal/map	Fri Oct 29 13:16:09 2010 +0200
@@ -9,6 +9,7 @@
 shortlog = ../paper/shortlog.tmpl
 shortlogentry = ../paper/shortlogentry.tmpl
 graph = ../paper/graph.tmpl
+changesetdiff = ../paper/changesetdiff.tmpl

 help = ../paper/help.tmpl
 helptopics = ../paper/helptopics.tmpl
diff -r 6bf8d48bec8e -r c58f2feedeab
mercurial/templates/gitweb/changesetdiff.tmpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/gitweb/changesetdiff.tmpl	Fri Oct 29
13:16:09 2010 +0200
@@ -0,0 +1,70 @@
+{header}
+<title>{repo|escape}: diff {file|escape}</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+<link rel="alternate" type="application/rss+xml"
+   href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://mercurial.selenic.com/" title="Mercurial"
style="float: right;">Mercurial</a><a
href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> /
ndiff
+</div>
+
+<div class="page_nav">
+<a href="{url}summary{sessionvars%urlparameter}">summary</a> |
+<a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
+<a href="{url}log{sessionvars%urlparameter}">changelog</a> |
+<a href="{url}graph{sessionvars%urlparameter}">graph</a> |
+<a href="{url}tags{sessionvars%urlparameter}">tags</a> |
+<a href="{url}branches{sessionvars%urlparameter}">branches</a><br/>
+</div>
+
+<div class="title">ndiff {rev1}:{node1|short} {rev2}:{node2|short}</div>
+
+<div class="title_text">
+    <table>
+    <tr>
+     <td>changeset {rev1}</td>
+     <td style="font-family:monospace"><a class="list"
href="{url}rev/{node1|short}{sessionvars%urlparameter}">{node1|short}</a></td>
+    </tr>
+    <tr>
+      <td>author</td>
+      <td>{author1|obfuscate}</td>
+     </tr>
+    <tr>
+     <td>date</td>
+     <td>{date1|date} ({date1|age})</td>
+    </tr>
+    </table>
+</div>
+
+<div class="page_body">{desc1}</div>
+<div class="list_head"></div>
+
+<div class="title_text">
+    <table>
+    <tr>
+     <td>changeset {rev2}</td>
+     <td style="font-family:monospace"><a class="list"
href="{url}rev/{node2|short}{sessionvars%urlparameter}">{node2|short}</a></td>
+    </tr>
+    <tr>
+      <td>author</td>
+      <td>{author2|obfuscate}</td>
+     </tr>
+    <tr>
+     <td>date</td>
+     <td>{date2|date} ({date2|age})</td>
+    </tr>
+    </table>
+</div>
+
+<div class="page_body">{desc2}</div>
+<div class="list_head"></div>
+
+
+<div class="page_body">
+{diff}
+</div>
+
+{footer}
diff -r 6bf8d48bec8e -r c58f2feedeab
mercurial/templates/monoblue/changesetdiff.tmpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/monoblue/changesetdiff.tmpl	Fri Oct 29
13:16:09 2010 +0200
@@ -0,0 +1,55 @@
+{header}
+<title>{repo|escape}: ndiff {file|escape}</title>
+    <link rel="alternate" type="application/atom+xml"
href="{url}atom-log" title="Atom feed for {repo|escape}"/>
+    <link rel="alternate" type="application/rss+xml"
href="{url}rss-log" title="RSS feed for {repo|escape}"/>
+</head>
+
+<body>
+<div id="container">
+    <div class="page-header">
+        <h1><a
href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file
ndiff</h1>
+
+        <form action="{url}log">
+            {sessionvars%hiddenformentry}
+            <dl class="search">
+                <dt><label>Search: </label></dt>
+                <dd><input type="text" name="rev" /></dd>
+            </dl>
+        </form>
+
+        <ul class="page-nav">
+            <li><a
href="{url}summary{sessionvars%urlparameter}">summary</a></li>
+            <li><a
href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
+            <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
+            <li><a
href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+            <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+            <li><a
href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+            <li><a
href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></li>
+        </ul>
+</div>
+
+    <h2 class="no-link no-border">ndiff {rev1}:{node1|short}
{rev2}:{node2|short}</h2>
+
+    <h3 class="changeset">Changeset {rev1}:{node1|short}</h3>
+
+    <dl class="overview">
+        <dt>author</dt><dd>{author1|obfuscate}</dd>
+        <dt>date</dt><dd>{date1|date} ({date1|age})</dd>
+    </dl>
+
+    <p class="description">{desc1|strip|escape|addbreaks|nonempty}</p>
+
+    <h3 class="changeset">Changeset {rev2}:{node2|short}</h3>
+
+    <dl class="overview">
+        <dt>author</dt><dd>{author2|obfuscate}</dd>
+        <dt>date</dt><dd>{date2|date} ({date2|age})</dd>
+    </dl>
+
+    <p class="description">{desc2|strip|escape|addbreaks|nonempty}</p>
+
+    <div class="diff">
+    {diff}
+    </div>
+
+{footer}
diff -r 6bf8d48bec8e -r c58f2feedeab
mercurial/templates/paper/changesetdiff.tmpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/paper/changesetdiff.tmpl	Fri Oct 29 13:16:09
2010 +0200
@@ -0,0 +1,70 @@
+{header}
+<title>{repo|escape}: {node|short}</title>
+</head>
+<body>
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="http://mercurial.selenic.com/">
+<img src="{staticurl}hglogo.png" alt="mercurial" /></a>
+</div>
+<ul>
+ <li><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">log</a></li>
+ <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+</div>
+
+<div class="main">
+
+<h2><a href="{url}{sessionvars%urlparameter}">{repo|escape}</a></h2>
+<h3>ndiff {rev1}:{node1|short} {rev2}:{node2|short}</h3>
+
+<form class="search" action="{url}log">
+{sessionvars%hiddenformentry}
+<p><input name="rev" id="search1" type="text" size="30" /></p>
+<div id="hint">find changesets by author, revision,
+files, or words in the commit message</div>
+</form>
+
+
+<h4>changeset {rev1}:{node1|short}</h4>
+
+<div class="description">{desc1|strip|escape|addbreaks|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th>author</th>
+ <td>{author1|obfuscate}</td>
+</tr>
+<tr>
+ <th>date</th>
+ <td>{date1|date} ({date1|age})</td>
+</tr>
+</table>
+
+<h4>changeset {rev2}:{node2|short}</h4>
+
+<div class="description">{desc2|strip|escape|addbreaks|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th>author</th>
+ <td>{author2|obfuscate}</td>
+</tr>
+<tr>
+ <th>date</th>
+ <td>{date2|date} ({date2|age})</td>
+</tr>
+</table>
+
+<div class="overflow">
+<div class="sourcefirst">   line diff</div>
+
+{diff}
+</div>
+
+</div>
+</div>
+{footer}
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/templates/paper/map
--- a/mercurial/templates/paper/map	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/templates/paper/map	Fri Oct 29 13:16:09 2010 +0200
@@ -26,6 +26,7 @@
 searchentry = shortlogentry.tmpl
 changeset = changeset.tmpl
 manifest = manifest.tmpl
+changesetdiff = changesetdiff.tmpl

 nav = '{before%naventry} {after%naventry}'
 navshort = '{before%navshortentry}{after%navshortentry}'
diff -r 6bf8d48bec8e -r c58f2feedeab
mercurial/templates/spartan/changesetdiff.tmpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/spartan/changesetdiff.tmpl	Fri Oct 29
13:16:09 2010 +0200
@@ -0,0 +1,61 @@
+{header}
+<title>{repo|escape}: {file|escape} ndiff</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="{url}log/{rev}{sessionvars%urlparameter}">changelog</a>
+<a href="{url}graph{sessionvars%urlparameter}">graph</a>
+<a href="{url}tags{sessionvars%urlparameter}">tags</a>
+<a href="{url}branches{sessionvars%urlparameter}">branches</a>
+</div>
+
+<h2>ndiff {rev1}:{node1|short} {rev2}:{node2|short}</h2>
+
+<table id="filediffEntry">
+<tr>
+ <th class="revision">revision {rev1}:</th>
+ <td class="revision"><a
href="{url}rev/{node1|short}{sessionvars%urlparameter}">{node1|short}</a></td>
+</tr>
+<tr>
+ <th class="author">author:</th>
+ <td class="author">{author1|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date:</th>
+ <td class="date">{date1|date} ({date1|age})</td>
+</tr>
+<tr>
+ <th class="description">description:</th>
+ <td class="description">{desc1}</td>
+</tr>
+</table>
+
+<br />
+
+<table id="filediffEntry">
+<tr>
+ <th class="revision">revision {rev2}:</th>
+ <td class="revision"><a
href="{url}rev/{node2|short}{sessionvars%urlparameter}">{node2|short}</a></td>
+</tr>
+<tr>
+ <th class="author">author:</th>
+ <td class="author">{author2|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date:</th>
+ <td class="date">{date2|date} ({date2|age})</td>
+</tr>
+<tr>
+ <th class="description">description:</th>
+ <td class="description">{desc2}</td>
+</tr>
+</table>
+
+<div id="fileDiff">
+{diff}
+</div>
+
+{footer}
+
+
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/templates/spartan/map
--- a/mercurial/templates/spartan/map	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/templates/spartan/map	Fri Oct 29 13:16:09 2010 +0200
@@ -7,6 +7,8 @@
 shortlog = shortlog.tmpl
 shortlogentry = shortlogentry.tmpl
 graph = graph.tmpl
+changesetdiff = changesetdiff.tmpl
+
 naventry = '<a
href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a>
'
 navshortentry = '<a
href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a>
'
 navgraphentry = '<a
href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a>
'
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/templates/static/style-coal.css
--- a/mercurial/templates/static/style-coal.css	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/templates/static/style-coal.css	Fri Oct 29 13:16:09 2010 +0200
@@ -150,6 +150,9 @@
   margin-top: -.7em;
   font-size: 100%;
 }
+h4 {
+    font-size: 90%;
+}

 /* log and tags tables */
 .bigtable {
diff -r 6bf8d48bec8e -r c58f2feedeab mercurial/templates/static/style-paper.css
--- a/mercurial/templates/static/style-paper.css	Wed Oct 20 23:48:33 2010 +0200
+++ b/mercurial/templates/static/style-paper.css	Fri Oct 29 13:16:09 2010 +0200
@@ -141,6 +141,9 @@
   margin-top: -.7em;
   font-size: 100%;
 }
+h4 {
+    font-size: 90%;
+}

 /* log and tags tables */
 .bigtable {


More information about the Mercurial-devel mailing list