# HG changeset patch # User Denis Laxalde # Date 2016-06-07 10:10:01 # Node ID f694e20193f20548fdc4a89062bef99781d58c39 # Parent 6b77adc2c7b52af4050355a362c1d739193439e9 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 @@ -872,14 +872,19 @@ 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, "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,8 +97,10 @@ fileline = ' annotateline = ' - {author|user}@{rev} + {if(blockhead, + '{author|user}@{rev}', + '')}
{linenumber}
{line|escape}
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 = ' - {author|user}@{rev} + {if(blockhead, + '{author|user}@{rev}', + '')} {linenumber} 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 = ' - {author|user}@{rev} + {if(blockhead, + '{author|user}@{rev}', + '')} {linenumber} {line|escape} ' 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 = ' - {author|user}@{rev} + {if(blockhead, + '{author|user}@{rev}', + '')} {linenumber} 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 - test@0 + 2 - test@0 + 3 """Fun with generators. Corresponding Haskell implementation: - test@0 + 4 - test@0 + 5 primes = 2 : sieve [3, 5..] - test@0 + 6 where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0] - test@0 + 7 """ - test@0 + 8 - test@0 + 9 from itertools import dropwhile, ifilter, islice, count, chain - test@0 + 10 - test@0 + 11 def primes(): - test@0 + 12 """Generate all primes.""" - test@0 + 13 def sieve(ns): - test@0 + 14 p = ns.next() - test@0 + 15 # It is important to yield *here* in order to stop the - test@0 + 16 # infinite recursion. - test@0 + 17 yield p - test@0 + 18 ns = ifilter(lambda n: n % p != 0, ns) - test@0 + 19 for n in sieve(ns): - test@0 + 20 yield n - test@0 + 21 - test@0 + 22 odds = ifilter(lambda i: i % 2 == 1, count()) - test@0 + 23 return chain([2], sieve(dropwhile(lambda n: n < 3, odds))) - test@0 + 24 - test@0 + 25 if __name__ == "__main__": - test@0 + 26 import sys - test@0 + 27 try: - test@0 + 28 n = int(sys.argv[1]) - test@0 + 29 except (ValueError, IndexError): - test@0 + 30 n = 10 - test@0 + 31 p = primes() - test@0 + 32 print "The first %d primes: %s" % (n, list(islice(p, n))) - test@0 + 33