Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vimdiff: force line-by-line comparison (ignore supposedly missing/additional lines)

Tags:

vim

diff

vimdiff

How do I force vimdiff to always compare two files line-by-line without identifying added or deleted lines?

The problem is that if the diff between two files is large, but by chance two lines in the file match up, vimdiff thinks these lines are the same and just treats the rest as added or deleted lines, and the resulting diff is totally unusable. In my case, line i in file1 always corresponds to line i in file2, so vimdiff has no business finding added or deleted lines.

Following is a small example with two files containing the values of two variables three times each. Vimdiff erroneously matches up file1/line1 with file2/line3 and thinks some lines around it have been added or deleted. The diff (minus colors) then looks like this:

              |  1 foo 8.1047  < del/new
              |  2 bar 6.2343  < del/new
1 foo 0.0000  |  3 foo 0.0000  < match
2 bar 5.3124  |  4 bar 1.4452  < wrong
3 foo 4.5621  |                < new/del
4 bar 6.3914  |                < new/del
5 foo 1.0000  |  5 foo 1.0000  < match
6 bar 6.3212  |  6 bar 7.2321  < wrong

What I want, however, is the following, with all lines marked as wrong except for the matching lines 5:

1 foo 0.0000  |  1 foo 8.1047 < wrong
2 bar 5.3124  |  2 bar 6.2343 < wrong
3 foo 4.5621  |  3 foo 0.0000 < wrong
4 bar 6.3914  |  4 bar 1.4452 < wrong
5 foo 1.0000  |  5 foo 1.0000 < match
6 bar 6.3212  |  6 bar 7.2321 < wrong
like image 536
flotzilla Avatar asked Jan 05 '15 14:01

flotzilla


People also ask

How do you get to the next difference in Vimdiff?

You can jump to the "next difference" ( ] c ), but this will jump to the next line with a difference.

How do I copy a line in Vimdiff?

Use dp for copying the current difference block to another side, do for copying from another side to the current. dp means "put", do means "obtain". The current difference block is where your caret is.

How do I save Vimdiff output?

Open a terminal and run this command: vimdiff file1. txt file2. txt -c TOhtml -c 'w!


1 Answers

As I was copying this example to try it, I noticed that vimdiff will do what you want if you have the line number associated with each line.

Therefore, you can use cat to add the line number and then diff:

  cat -n file1 > file1_with_line_no
  cat -n file2 > file2_with_line_no

  vimdiff file1_with_line_no file2_with_line_no

The output is then as you want (shown with diff for easy copying to here):

 diff file1_with_line_no file2_with_line_no --side-by-side
 1  foo 0.0000                                            |      1  foo 8.1047
 2  bar 5.3124                                            |      2  bar 6.2343
 3  foo 4.5621                                            |      3  foo 0.0000
 4  bar 6.3914                                            |      4  bar 1.4452
 5  foo 1.0000                                                   5  foo 1.0000
 6  bar 6.3212                                            |      6  bar 7.2321

In bash you can add this to your .bashrc so you can use linediff from the command line to just normally call a diff between two files with the above:

linediff() { 
     if [ -z "$1" ] || [ -z "$2" ]; then return; fi
     f1=$(basename "$1")
     f2=$(basename "$2")
     cat -n "$1" > "/tmp/$f1"
     cat -n "$2" > "/tmp/$f2"
     vimdiff "/tmp/$f1" "/tmp/$f2"
     rm "/tmp/$f1" "/tmp/$f2"
 }

and now linediff file1 file2 will do the above and clean up after.

like image 113
jas_raj Avatar answered Sep 20 '22 03:09

jas_raj