[PATCH STABLE] mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)

Patrick Mezard patrick at mezard.eu
Mon Feb 6 15:14:14 CST 2012


# HG changeset patch
# User Patrick Mezard <patrick at mezard.eu>
# Date 1328559470 -3600
# Branch stable
# Node ID 9c990aa000f7a448f0b2535111ebfd2f5e7b4e54
# Parent  7e5a281a082cdbff4ae9553e01b5ff36dc2c11ee
mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234)

When diffing the following documents with --ignore-blank-lines (-B):

  $ cat > a <<EOF
  >
  >
  >
  > b
  > x
  > d
  > EOF

and:

  $ cat > b <<EOF
  > b
  > y
  > d
  > EOF

the context lines are taken from the first document, even if the lines differ
(with -w or -b) or if the number of lines differ (with -B). In the second case,
we have to adjust the hunk new lines offsets or we end with inconsistent diffs
like (see the @@ offsets):

  diff -r 0e66aa54f318 a
  --- a/a
  +++ b/a
  @@ -1,4 +1,3 @@

   b
  -x
  +y
   d

Note that having different context lines in a and b means the diff can be
applied but is not invertible.

Reported by Nicholas Riley <com-selenic at sabi.net>

diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -268,14 +268,23 @@
     # them into diff output.
     #
     hunk = None
+    ignoredlines = 0
     for s, stype in allblocks(t1, t2, opts, l1, l2):
+        a1, a2, b1, b2 = s
         if stype != '!':
+            if stype == '~':
+                # The diff context lines are based on t1 content. When
+                # blank lines are ignored, the new lines offsets must
+                # be adjusted as if equivalent blocks ('~') had the
+                # same sizes on both sides.
+                ignoredlines += (b2 - b1) - (a2 - a1)
             continue
         delta = []
-        a1, a2, b1, b2 = s
         old = l1[a1:a2]
         new = l2[b1:b2]
 
+        b1 -= ignoredlines
+        b2 -= ignoredlines
         astart = contextstart(a1)
         bstart = contextstart(b1)
         prev = None
diff --git a/tests/test-diff-ignore-whitespace.t b/tests/test-diff-ignore-whitespace.t
--- a/tests/test-diff-ignore-whitespace.t
+++ b/tests/test-diff-ignore-whitespace.t
@@ -455,3 +455,46 @@
   +hello 
   +world
    goodbye world
+
+Test hunk offsets adjustments with --ignore-blank-lines
+
+  $ hg revert -aC
+  reverting foo
+  $ printf '\nb\nx\nd\n' > a
+  $ printf 'b\ny\nd\n' > b
+  $ hg add a b
+  $ hg ci -m add
+  $ hg cat -r . a > b
+  $ hg cat -r . b > a
+  $ hg diff -B --nodates a > ../diffa
+  $ cat ../diffa
+  diff -r 0e66aa54f318 a
+  --- a/a
+  +++ b/a
+  @@ -1,4 +1,4 @@
+   
+   b
+  -x
+  +y
+   d
+  $ hg diff -B --nodates b > ../diffb
+  $ cat ../diffb
+  diff -r 0e66aa54f318 b
+  --- a/b
+  +++ b/b
+  @@ -1,3 +1,3 @@
+   b
+  -y
+  +x
+   d
+  $ hg revert -aC
+  reverting a
+  reverting b
+  $ hg import --no-commit ../diffa
+  applying ../diffa
+  $ hg revert -aC
+  reverting a
+  $ hg import --no-commit ../diffb
+  applying ../diffb
+  $ hg revert -aC
+  reverting b
diff --git a/tests/test-mq-qdiff.t b/tests/test-mq-qdiff.t
--- a/tests/test-mq-qdiff.t
+++ b/tests/test-mq-qdiff.t
@@ -98,7 +98,7 @@
   diff -r b0c220e1cf43 lines
   --- a/lines
   +++ b/lines
-  @@ -4,4 +6,4 @@
+  @@ -4,4 +4,4 @@
    4
   -hello world
   -goodbye world


More information about the Mercurial-devel mailing list