Patchwork [2,of,9] mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)

login
register
mail settings
Submitter Denis Laxalde
Date March 6, 2017, 9:38 a.m.
Message ID <201a5066da14bc8272b0.1488793100@sh77.tls.logilab.fr>
Download mbox | patch
Permalink /patch/18928/
State Accepted
Headers show

Comments

Denis Laxalde - March 6, 2017, 9:38 a.m.
# HG changeset patch
# User Denis Laxalde <denis.laxalde@logilab.fr>
# Date 1488471766 -3600
#      Thu Mar 02 17:22:46 2017 +0100
# Node ID 201a5066da14bc8272b057eb2130bd1f12ace96c
# Parent  adbaa893b3e5e619402ba761b507c385fb8f8d8a
# Available At http://hg.logilab.org/users/dlaxalde/hg
#              hg pull http://hg.logilab.org/users/dlaxalde/hg -r 201a5066da14
# EXP-Topic diffhunks
mdiff: let _unidiff yield hunks as (<range information>, <hunk lines>)

Now _unidiff yields each hunk lines packed into a tuple with the "range
information" `(s1, l1, s2, l2)` that is used to build the typical hunk header
'@@ -s1,l1 +s2,l2 @@'.
This will be used to make it possible to filter diff hunks based on this range
information.

The new "range information" is ignored in unidiff() (only caller of _unidiff)
for now.

Patch

diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -240,7 +240,7 @@  def unidiff(a, ad, b, bd, fn1, fn2, opts
         l3 = "@@ -1,%d +0,0 @@\n" % len(a)
         l = [l1, l2, l3] + ["-" + e for e in a]
     else:
-        l = list(_unidiff(a, b, opts=opts))
+        l = sum((hlines for hrange, hlines in _unidiff(a, b, opts=opts)), [])
         if not l:
             return ""
 
@@ -254,7 +254,14 @@  def unidiff(a, ad, b, bd, fn1, fn2, opts
     return "".join(l)
 
 def _unidiff(t1, t2, opts=defaultopts):
-    """Yield hunks of a headerless unified diff from t1 and t2 texts."""
+    """Yield hunks of a headerless unified diff from t1 and t2 texts.
+
+    Each hunk consists of a (hunkrange, hunklines) tuple where `hunkrange` is a
+    tuple (s1, l1, s2, l2) representing the range information of the hunk to
+    form the '@@ -s1,l1 +s2,l2 @@' header and `hunklines` is a list of lines
+    of the hunk combining said header followed by line additions and
+    deletions.
+    """
     l1 = splitnewlines(t1)
     l2 = splitnewlines(t2)
     def contextend(l, len):
@@ -298,12 +305,13 @@  def _unidiff(t1, t2, opts=defaultopts):
         if blen:
             bstart += 1
 
-        yield "@@ -%d,%d +%d,%d @@%s\n" % (astart, alen,
-                                           bstart, blen, func)
-        for x in delta:
-            yield x
-        for x in xrange(a2, aend):
-            yield ' ' + l1[x]
+        hunkrange = astart, alen, bstart, blen
+        hunklines = (
+            ["@@ -%d,%d +%d,%d @@%s\n" % (hunkrange + (func,))]
+            + delta
+            + [' ' + l1[x] for x in xrange(a2, aend)]
+        )
+        yield hunkrange, hunklines
 
     # bdiff.blocks gives us the matching sequences in the files.  The loop
     # below finds the spaces between those matching sequences and translates