hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
authorDenis Laxalde <denis.laxalde@logilab.fr>
Mon, 06 Mar 2017 09:28:33 +0100
changeset 31276 cd29673cebdb
parent 31275 e2f141045634
child 31278 1c97a91a18dc
hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm Function patch.diffhunks yields items for a "block" (i.e. a file) as a whole so take advantage of this to simplify the algorithm and avoid parsing diff lines to determine whether we're starting a new "block" or not. Thus we drop to external block counter and rely on diffhunks iterations instead. We also take advantage of the fact that patch.diffhunks() yields *lines* of hunks (instead of a string) to avoid building a list that is ''.join-ed into a string that is then split. As lines in 'header' returned by patch.diffhunks() have no trailing new line, we need to insert it ourselves to match template expectations.
mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py	Mon Mar 06 09:44:39 2017 +0100
+++ b/mercurial/hgweb/webutil.py	Mon Mar 06 09:28:33 2017 +0100
@@ -412,15 +412,8 @@
 
 def diffs(repo, tmpl, ctx, basectx, files, parity, style):
 
-    def countgen():
-        start = 1
-        while True:
-            yield start
-            start += 1
-
-    blockcount = countgen()
-    def prettyprintlines(diff, blockno):
-        for lineno, l in enumerate(diff.splitlines(True), 1):
+    def prettyprintlines(lines, blockno):
+        for lineno, l in enumerate(lines, 1):
             difflineno = "%d.%d" % (blockno, lineno)
             if l.startswith('+'):
                 ltype = "difflineplus"
@@ -445,19 +438,16 @@
     node1 = basectx.node()
     node2 = ctx.node()
 
-    block = []
-    for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
-        if chunk.startswith('diff') and block:
-            blockno = next(blockcount)
+    diffhunks = patch.diffhunks(repo, node1, node2, m, opts=diffopts)
+    for blockno, (header, hunks) in enumerate(diffhunks, 1):
+        if style != 'raw':
+            header = header[1:]
+        lines = [h + '\n' for h in header]
+        for hunkrange, hunklines in hunks:
+            lines.extend(hunklines)
+        if lines:
             yield tmpl('diffblock', parity=next(parity), blockno=blockno,
-                       lines=prettyprintlines(''.join(block), blockno))
-            block = []
-        if chunk.startswith('diff') and style != 'raw':
-            chunk = ''.join(chunk.splitlines(True)[1:])
-        block.append(chunk)
-    blockno = next(blockcount)
-    yield tmpl('diffblock', parity=next(parity), blockno=blockno,
-               lines=prettyprintlines(''.join(block), blockno))
+                       lines=prettyprintlines(lines, blockno))
 
 def compare(tmpl, context, leftlines, rightlines):
     '''Generator function that provides side-by-side comparison data.'''