[PATCH] hgweb: display difference for a changeset against any parents (issue2810)

Weiwen Liu weiwen at fb.com
Tue Nov 27 15:29:32 CST 2012


Thanks for the guidance and patience, Matt.  Your suggestion works great.

This is updated patch to use rev/12345:12300 and use list in runsymbol.

# HG changeset patch
# User Weiwen <weiwen at fb.com>
# Date 1352757939 28800
# Node ID 675eeb03d023ee5cc5d4bb68e0dbd969d6e2331d
# Parent  fb14a5dcdc62987512820531fe60719d650491b6
hgweb: display difference for a changeset against any parents (issue2810)

During merge of branches, it is useful to compare merge results against
the two parents.  This change adds this support to hgweb.  To specify
which parent to compare to, use rev/12345:12300 where 12300 is a
parent changeset number.  Two links are added to changeset web page so
that one can choose which parent to compare to.

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -255,6 +255,9 @@
 
 def changeset(web, req, tmpl):
     ctx = webutil.changectx(web.repo, req)
+    basectx = webutil.basechangectx(web.repo, req)
+    if basectx is None:
+        basectx = ctx.p1()
     showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
     showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
                                          ctx.node())
@@ -273,10 +276,10 @@
         style = req.form['style'][0]
 
     parity = paritygen(web.stripecount)
-    diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
+    diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
 
     parity = paritygen(web.stripecount)
-    diffstatgen = webutil.diffstatgen(ctx)
+    diffstatgen = webutil.diffstatgen(ctx, basectx)
     diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
 
     return tmpl('changeset',
@@ -285,6 +288,7 @@
                 node=ctx.hex(),
                 parent=webutil.parents(ctx),
                 child=webutil.children(ctx),
+                currentbaseline=basectx.hex(),
                 changesettag=showtags,
                 changesetbookmark=showbookmarks,
                 changesetbranch=showbranch,
@@ -566,7 +570,7 @@
     if 'style' in req.form:
         style = req.form['style'][0]
 
-    diffs = webutil.diffs(web.repo, tmpl, ctx, [path], parity, style)
+    diffs = webutil.diffs(web.repo, tmpl, ctx, None, [path], parity, style)
     rename = fctx and webutil.renamelink(fctx) or []
     ctx = fctx and fctx or ctx
     return tmpl("filediff",
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -140,13 +140,7 @@
     path = path.lstrip('/')
     return scmutil.canonpath(repo.root, '', path)
 
-def changectx(repo, req):
-    changeid = "tip"
-    if 'node' in req.form:
-        changeid = req.form['node'][0]
-    elif 'manifest' in req.form:
-        changeid = req.form['manifest'][0]
-
+def changeidctx (repo, changeid):
     try:
         ctx = repo[changeid]
     except error.RepoError:
@@ -155,6 +149,28 @@
 
     return ctx
 
+def changectx (repo, req):
+    changeid = "tip"
+    if 'node' in req.form:
+        changeid = req.form['node'][0]
+        ipos=changeid.find(':')
+        if ipos != -1:
+            changeid = changeid[:ipos]
+    elif 'manifest' in req.form:
+        changeid = req.form['manifest'][0]
+
+    return changeidctx(repo, changeid)
+
+def basechangectx(repo, req):
+    if 'node' in req.form:
+        changeid = req.form['node'][0]
+        ipos=changeid.find(':')
+        if ipos != -1:
+            changeid = changeid[(ipos + 1):]
+            return changeidctx(repo, changeid)
+
+    return None
+
 def filectx(repo, req):
     if 'file' not in req.form:
         raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
@@ -178,7 +194,7 @@
     if len(files) > max:
         yield tmpl('fileellipses')
 
-def diffs(repo, tmpl, ctx, files, parity, style):
+def diffs(repo, tmpl, ctx, basectx, files, parity, style):
 
     def countgen():
         start = 1
@@ -209,8 +225,11 @@
         m = match.always(repo.root, repo.getcwd())
 
     diffopts = patch.diffopts(repo.ui, untrusted=True)
-    parents = ctx.parents()
-    node1 = parents and parents[0].node() or nullid
+    if basectx is None:
+        parents = ctx.parents()
+        node1 = parents and parents[0].node() or nullid
+    else:
+        node1 = basectx.node()
     node2 = ctx.node()
 
     block = []
@@ -274,10 +293,10 @@
         for oc in s.get_grouped_opcodes(n=context):
             yield tmpl('comparisonblock', lines=getblock(oc))
 
-def diffstatgen(ctx):
+def diffstatgen(ctx, basectx):
     '''Generator function that provides the diffstat data.'''
 
-    stats = patch.diffstatdata(util.iterlines(ctx.diff()))
+    stats = patch.diffstatdata(util.iterlines(ctx.diff(basectx)))
     maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
     while True:
         yield stats, maxname, maxtotal, addtotal, removetotal, binary
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -8,6 +8,7 @@
 from i18n import _
 import sys, os, re
 import util, config, templatefilters, parser, error
+import types
 
 # template parsing
 
@@ -140,6 +141,10 @@
         v = context._defaults.get(key, '')
     if util.safehasattr(v, '__call__'):
         return v(**mapping)
+    if isinstance(v, types.GeneratorType):
+        v = list(v)
+        mapping[key] = v
+        return v
     return v
 
 def buildfilter(exp, context):
@@ -179,6 +184,7 @@
     for i in d:
         if isinstance(i, dict):
             lm.update(i)
+            lm['originalnode'] = mapping.get('node')
             yield runtemplate(context, lm, ctmpl)
         else:
             # v is not an iterable of dicts, this happen when 'key'
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
@@ -74,6 +74,14 @@
     </div>
   </td>
 </tr>
+<tr>
+ <th class="author">change baseline</th>
+ <td class="author">{parent%changesetbaseline}</td>
+</tr>
+<tr>
+ <th class="author">current baseline</th>
+ <td class="author"><a href="{url}rev/{currentbaseline|short}{sessionvars%urlparameter}">{currentbaseline|short}</a> </td>
+</tr>
 </table>
 
 <div class="overflow">
diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map
--- a/mercurial/templates/paper/map
+++ b/mercurial/templates/paper/map
@@ -101,6 +101,8 @@
 
 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
 
+changesetbaseline = '<a href="{url}rev/{originalnode|short}:{node|short}{sessionvars%urlparameter}">{node|short} </a> '
+
 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
 
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
@@ -441,6 +441,14 @@
       </div>
     </td>
   </tr>
+  <tr>
+   <th class="author">change baseline</th>
+   <td class="author"></td>
+  </tr>
+  <tr>
+   <th class="author">current baseline</th>
+   <td class="author"><a href="/rev/000000000000">000000000000</a> </td>
+  </tr>
   </table>
   
   <div class="overflow">
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
@@ -139,6 +139,14 @@
       </div>
     </td>
   </tr>
+  <tr>
+   <th class="author">change baseline</th>
+   <td class="author"></td>
+  </tr>
+  <tr>
+   <th class="author">current baseline</th>
+   <td class="author"><a href="/rev/000000000000">000000000000</a> </td>
+  </tr>
   </table>
   
   <div class="overflow">
@@ -400,6 +408,14 @@
       </div>
     </td>
   </tr>
+  <tr>
+   <th class="author">change baseline</th>
+   <td class="author"></td>
+  </tr>
+  <tr>
+   <th class="author">current baseline</th>
+   <td class="author"><a href="/rev/000000000000">000000000000</a> </td>
+  </tr>
   </table>
   
   <div class="overflow">
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
@@ -112,6 +112,14 @@
       </div>
     </td>
   </tr>
+  <tr>
+   <th class="author">change baseline</th>
+   <td class="author"><a href="/rev/c78f6c5cbea9:cb9a9f314b8b">cb9a9f314b8b </a> </td>
+  </tr>
+  <tr>
+   <th class="author">current baseline</th>
+   <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
+  </tr>
   </table>
   
   <div class="overflow">



More information about the Mercurial-devel mailing list