[PATCH 3 of 8 V2] mdiff: make unidiff filter hunks out of specified line ranges

Denis Laxalde denis at laxalde.org
Sat Feb 25 04:06:00 EST 2017


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1484921181 -3600
#      Fri Jan 20 15:06:21 2017 +0100
# Node ID fcc621e177b1034101f7acc0ba6828e9db6be1a7
# Parent  43d99fe8dcb510540db19366fcac8159d4e26691
# Available At https://hg.logilab.org/users/dlaxalde/hg
#              hg pull https://hg.logilab.org/users/dlaxalde/hg -r fcc621e177b1
# EXP-Topic linerange-log/hgweb-filelog
mdiff: make unidiff filter hunks out of specified line ranges

We add two range parameters to filter diff blocks coming from allblocks()
which starting/ending line are out of specified line range.

This will be used by patch.diff() to make it possible to build a diff with
only hunks in a specified range of lines while preserving correct line number
information.

diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -195,7 +195,8 @@ def allblocks(text1, text2, opts=None, l
             yield s, type
         yield s1, '='
 
-def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts):
+def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts,
+            rangea=None, rangeb=None):
     def datetag(date, fn=None):
         if not opts.git and not opts.nodates:
             return '\t%s\n' % date
@@ -242,7 +243,8 @@ def unidiff(a, ad, b, bd, fn1, fn2, opts
     else:
         al = splitnewlines(a)
         bl = splitnewlines(b)
-        l = list(_unidiff(a, b, al, bl, opts=opts))
+        l = list(_unidiff(a, b, al, bl, opts=opts,
+                          range1=rangea, range2=rangeb))
         if not l:
             return ""
 
@@ -258,7 +260,7 @@ def unidiff(a, ad, b, bd, fn1, fn2, opts
 # creates a headerless unified diff
 # t1 and t2 are the text to be diffed
 # l1 and l2 are the text broken up into lines
-def _unidiff(t1, t2, l1, l2, opts=defaultopts):
+def _unidiff(t1, t2, l1, l2, opts=defaultopts, range1=None, range2=None):
     def contextend(l, len):
         ret = l + opts.context
         if ret > len:
@@ -315,6 +317,10 @@ def _unidiff(t1, t2, l1, l2, opts=defaul
     ignoredlines = 0
     for s, stype in allblocks(t1, t2, opts, l1, l2):
         a1, a2, b1, b2 = s
+        if range1 is not None and not (range1[0] < a2 and a1 < range1[1]):
+            continue
+        if range2 is not None and not (range2[0] < b2 and b1 < range2[1]):
+            continue
         if stype != '!':
             if stype == '~':
                 # The diff context lines are based on t1 content. When


More information about the Mercurial-devel mailing list