2

(I'm running into this in a context of using vimdiff, which relies on and interprets the output of diff, so I think this is a diff question.)

Given these files, the first having 2 lines, the second having 4, diff (GNU 3.3) shows the complete files.

< 09/02/2014 | CFCU Checking          | PAYPAL |      12.99 |            | 12.99
< 09/03/2014 | CFCU Checking          | PAYPAL |      24.45 |            | 37.44
---
> 09/02/2014 | Expenses : Advertising | Closed |            |      12.99 | 12.99
> 09/02/2014 | CFCU Checking          | PAYPAL |      12.99 |            | 0.00
> 09/03/2014 | Expenses : Advertising | Closed |            |      24.45 | 24.45
> 09/03/2014 | CFCU Checking          | PAYPAL |      24.45 |            | 0.00

This makes vimdiff see there as being virtually no shared content. As shown in the top of the picture below, it shows matching the first 13 characters on line 1, the first 4 on line 2, and sees lines 3 and 4 as new.

I spend a lot of time in this situation adding newlines in place of the inserted lines, to force diff (and in turn vimdiff) to show it as the middle of the picture below.

Is there a way to make diff to break this up better, so vimdiff would see it as the bottom of the picture? (Which I Photoshoped.)

It would need 4 sections rather than the 1 shown above. Something like:

#,#c#,#
---
> 09/02/2014 | Expenses : Advertising | Closed |            |      12.99 | 12.99
#,#c#,#
< 09/02/2014 | CFCU Checking          | PAYPAL |      12.99 |            | 12.99
---
> 09/02/2014 | CFCU Checking          | PAYPAL |      12.99 |            | 0.00
#,#c#,#
---
> 09/03/2014 | Expenses : Advertising | Closed |            |      24.45 | 24.45
#,#c#,#
< 09/03/2014 | CFCU Checking          | PAYPAL |      24.45 |            | 37.44
---
> 09/03/2014 | CFCU Checking          | PAYPAL |      24.45 |            | 0.00

By the way, vimdiff can use different diff options, through diffexpr, but requires default (I think called ed) style diffs.

So, I think what I'm looking for is a way to make diff not mixing a changed line and an inserted line in the same section.

vimdiff examples

1

One approach that often works is to increase the amount of context, so that adjacent small differences will be collected into a more cohesive display.

  • In the command-line diff, you would do this with the -C option.
  • With vimdiff, you would do this with the diffopt setting, and the context feature, e.g., this is the implicit default:
    set diffopt=filler,context:6

and you could change that, e.g.,

    set diffopt+=context:9
    set diffopt=filler,context:9

Other than that:

  • the underlying diff utility has no way to detect that lines are interchanged with respect to each other.
  • nor does it have a way to compare files while ignoring certain columns.

The example given appears to be a series of transactions by date. If there is some other ordering (which tends to make larger chunks of unchanged lines) then re-ordering the data would help.

In principle, you could use the diffexpr setting, and construct a script which pre/post-processes your data so that only certain columns are compared. I used that approach a while back to make a free-format (word-level) compare utility. But doing that is a fair amount of work, and not simple due to diff's inability to ignore columns of its input.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.