diff-cmd = svndiff_helper
into the [helpers]
section of your ~/.subversion/config
file, where svndiff_helper
would containgvimdiff -f "$6" "$7"
We pass the sixth and seventh parameters to gvimdiff because that's where svn diff
passes us the names of the files to diff. Incidentally, the -f parameter is needed to prevent Vim from forking on startup, since svn would then delete the temporary files too quickly.So what do the other parameters contain? Let's find out:
$ echo 'for a in "$@"; do echo "$a"; done' >pargs $ chmod +x pargs $ ls -A aa rand readme .svn $ svn diff -r1 --diff-cmd=./pargs readme Index: readme =================================================================== -u -L readme (.../readme) (revision 1) -L readme (.../branches/mybranch/readme) (working copy) .svn/tmp/tempfile.tmp readme
Interesting – svn gives us a nice textual description of both files in arguments three and five respectively. How about we use those to name the buffers in gvimdiff?
With this script, you can. There are a few tricks to it:
- I use the --cmd option to Vim to make it run a command on startup.
- Specifically, I set up autocommands (
autocmd
, abbreviated toau
) to change both buffer names as appropriate when the BufReadPost event is triggered, which happens when the files are read. - I use the
:file
command (abbreviated to justf
) to change the buffer name. Unfortunately, Vim doesn't handle tabs in the name very well, so I replace those by spaces. Those in turn I have to escape in order for the:file
command to accept them. - Vim also gets confused if the buffer name contains a slash, so I replace those by backslashes.
Cool, and pretty darn useful. I also use this in a non-graphical environment and took out the -g. And in general I like to do edits back and forth with modifications so dropped the -R.
ReplyDeleteOne thing is that I get a prompt that requires hitting ENTER before I get to the diff, which is a bit frustrating.
If you drop the -R, you will also have to take out the two --cmd options which make Vim rename the buffers, because Vim uses the buffer names as the file names. So when you write the file, it will write it to the wrong name.
ReplyDeleteAs for the "Press ENTER or type command to continue" prompt, I've fixed that now.
Great, it works well for me, that's what I want!
ReplyDeleteI use '-dR' option for this script, since I don't run it on gvim
This comment has been removed by the author.
ReplyDeleteNice script thank you!
ReplyDeleteOne issue i have with this script is that i can't make inline edits to the working-copy file. that is, if i have:
ReplyDelete"vimdiff file.java file.java.svn-base"
your script will load it that as
"vimdiff -R file.java\ \(working copy\) file.java.svn-base.java"
so now if i look at the diff and realize "oh, i want to undo a diff between the working copy and what's in svn" i can' really do that, even if i turn off the -readonly, i still have the problem that the file will be saved as file.java\ \(working\ copy\), and then i have to manually diff back into file.java. that's kind of a PITA
How do I get this to automatically save changes back to the working copy?? When I write out, it saves a file with the buffer name to the current working directory, instead of back to the sym-link.
ReplyDeletee.g.
$ svn diff src/filename.c
## edit, quit
$ ls
... src\filename.c (working copy)
And then I have to vimdiff that file with the working copy... :(
to spleach, or anyone else reading this, if you want to fix the problems change lines 38-42 to the following:
ReplyDeletevim_rc = subprocess.call(['vim', '-df',
'--cmd', "au BufReadPost " + lf2 + "silent f " + sanitise(lf2),
'--cmd', "au BufReadPost " + lf1 + "silent f " + sanitise(n1),
lf2, lf1])
so i've done 2 things here, 1, i flipped lf1 & lf2 so that the 'working copy' file is on the left split. to me this makes WAY more sense (you can easily flip it back if you like)
and 2nd, i've changed the sanitise(n2) with sanitise(lf2), the reason here is that i don't want it to use the file's label for display because apparently the label is what vim uses when saving the filename.
What was the fix to remove the hitting Enter Key? I still see that
ReplyDeletegreat post, and the script works like a charm, thanks!
ReplyDeleteA minor improvement to Vat's suggestion is to make the buffer naming of the left hand side (lhs) buffer conditional on whether it is a "working copy" file or not:
ReplyDeletesvn_diff_name1, svn_diff_name2 = sys.argv[3], sys.argv[5]
file1, file2 = sys.argv[6], sys.argv[7]
link_to_file1, link_to_file2 = map(lntemp, [file1, file2], [svn_diff_name1, svn_diff_name2])
lhs_buffer_name = link_to_file2 if "working copy" in svn_diff_name2 else sanitise(svn_diff_name2)
rhs_buffer_name = sanitise(svn_diff_name1)
cmd = ['vim', '-df',
'--cmd', "au BufReadPost " + link_to_file2 + " silent f " + lhs_buffer_name,
'--cmd', "au BufReadPost " + link_to_file1 + " silent f " + rhs_buffer_name,
link_to_file2, link_to_file1]
What this does is makes working copy diffs work the way Vat recommended, while still naming the buffers properly in the case that you are doing a diff of 2 remote files.