Using svn diff in combination with vimdiff to get diff tab on every modified file

Is it possible to use svn in combination with vim to get a series of tab pages containing diff of each file? This would be a much better alternative to svn diff | view - svn diff | view - but instead of a linear list of differences, he would use vimdiff.

In the past, I found a way to do this and get svn diff to open multiple vims for each edited file, but being able to go back and view old files would be very useful. Therefore, given the set of tuples of S files, I need a vim shell command that will open each file in the first position of S tuples in a different tab and mark it with the corresponding file in the second position of tuples in S.

+7
source share
2 answers

This can be done with a few scripts and using the vim "server" functionality. The scripts below can be improved a bit, for example, it is assumed that you want to do this in a graphical Vim, and that you do not want the script to exit until you leave this Vim. In addition, the default difference is used for horizontal separation due to the use of "diffsplit".

I am doing this with the following two scenarios. Run the bash script in the directory in which you want to run diff:

 #!/bin/bash export VIM_SERVERNAME="SVN-$RANDOM" # Start up a vim, graphical, in the foreground, but backgrounded... vim -g -f --servername "$VIM_SERVERNAME" & # So we get can it PID to wait on later gvim_pid=$! # Wait for the server to start up enough sleep 0.5 # Use svn diff to get the right set of files to pass to vimdiff svn diff --diff-cmd "vim_tab_diff_helper.py" >/dev/null # Move to the start of the list; remove the first tab which will be the empty # tab vim --servername "$VIM_SERVERNAME" --remote-send ":tabfirst<Return>" vim --servername "$VIM_SERVERNAME" --remote-send ":bd<Return>" # Wait for the user to exit vim before returning wait $gvim_pid 

The helper script "vim_tab_diff_helper.py" looks like this:

 #!/usr/bin/python import os import subprocess import sys def vim_send(command): global vim_server subprocess.call(['vim', '--servername', vim_server, '--remote-send', command + '<Return>']) vim_server = os.environ['VIM_SERVERNAME'] svn_orig_file = sys.argv[ len(sys.argv) - 2 ] modified_file = sys.argv[ len(sys.argv) - 1 ] vim_send(":tabnew") vim_send(":e " + svn_orig_file) vim_send(":diffsplit " + modified_file) 
+3
source

You can specify the diff command that you want to use in Subversion using the --diff-cmd command line or by specifying it in the Subversion configuration (which is $HOME/.subversion/config for the Unix command line client).

The main thing is to understand what parameters are passed to your SVN diff command:

  • 4 th for the last parameter - the name of the program on the left side
  • 3 rd to the last parameter - the name of the program on the right side
  • 2 nd for the last parameter - temporary file on the left side
  • The last parameter is a temporary file on the right side

The first parameters passed are the keys to the Subversion diff command. For example:

  • -u
  • -L

You can use this information to create a script to view files in VIM. Here's a simple Perl:

 #! /usr/bin/env perl use strict; use warnings; my $diff = "/usr/bin/vimdiff"; my $num_of_params = $#ARGV; my $file1 = $ARGV[$num_of_params - 1]; my $file2 = $ARGV[$num_of_params]; my $title1 = $ARGV[$num_of_params - 4]; my $title2 = $ARGV[$num_of_params - 3]; my $title = "$title1 - $title2"; $title =~ s/\t/ /g; $title =~ s/ /\\ /g; system qq($diff -c "set titlestring=$title" "$file1" "$file2"); 

You must ensure that your system command (e.g. vimdiff) contains the command line. I tried using mvim on my Mac, but temporary files were deleted before the mvim command was executed.

Now you can do this:

 $ svn diff --diff-cmd mydiff -rPREV 

And if your script is in your PATH and is executable, it should work.


Thanks ZyX

The program that accepts ZyX offers has been improved here. I had to make some changes. My diff command is actually mvim on my machine, and I need to pass two parameters ( -d to say diff, and -f say not to throw mvim in the background). This meant that passing $DIFF at the suggestion of ZyX would make my system command think that mvim -d -f is my command and I get an error message. To solve this problem, I store the command in an array. I also made the array persistent while I was on it.

Here is the program below. Modify the DIFF to point to the diff command (probably vimdiff , gvim -d -f or vim -d ). If you are on Windows and the full path is in C:/Program Files/Vim , you can use C:/Progr~1/Vim to get rid of the space. Otherwise, you will need to do:

 use constant DIFF => ('C:/Program Files/Vim/VIM73/gvim', '-f', '-d') 

since you cannot use qw . Can we say thanks to Microsoft for putting a space in the name of the directory where all commands are stored for no good reason? I knew you could. BTW, if the directory where your editor is located is in your PATH , you do not need to specify the full name of the directory.

 #! /usr/bin/env perl use strict; use warnings; use constant DIFF => qw(mvim -d -f); my $parameters = $#ARGV; my $file1 = $ARGV[$parameters - 1]; my $file2 = $ARGV[$parameters]; my $title1 = $ARGV[$parameters - 4]; my $title2 = $ARGV[$parameters - 2]; $ENV{TITLE} = "$title1 - $title2"; system DIFF, '-c', 'let &titlestring=$TITLE', $file1, $file2; 
+5
source

All Articles