# HG changeset patch # User Patrick Mezard # Date 2012-02-06 20:17:50 # Node ID 2e8f4b82c551014a5895b3dfc5858f2341bd7f41 # Parent d1538789a1b3cb6117d450bdf9b382da5c6c25cd mdiff: adjust hunk offsets with --ignore-blank-lines (issue3234) When diffing the following documents with --ignore-blank-lines (-B): $ cat > a < > > > b > x > d > EOF and: $ cat > b < 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 diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -268,14 +268,23 @@ def _unidiff(t1, t2, l1, l2, opts=defaul # 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 @@ Do not ignore all newlines, only blank l +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 @@ qdiff filename: diff -r b0c220e1cf43 lines --- a/lines +++ b/lines - @@ -4,4 +6,4 @@ + @@ -4,4 +4,4 @@ 4 -hello world -goodbye world