Showing posts with label subversion. Show all posts
Showing posts with label subversion. Show all posts

Saturday, 15 January 2011

Subversion and vimdiff: a little improvement

Vim is commonly used as a diff visualisation tool for Subversion. Often, this is accomplished by putting a line like
diff-cmd = svndiff_helper
into the [helpers] section of your ~/.subversion/config file, where svndiff_helper would contain
gvimdiff -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 to au) 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 just f) 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.
One other issue you may find with the "naïve" wrapper script shown at the start is that it makes Vim not apply syntax highlighting, because the temporary filenames like tempfile.tmp do not have the appropriate extension. My script addresses that too, by temporarily creating a symlink with the right extension to the temp file and passing that to Vim.

How to see all changes on a branch in Subversion

Ever wanted to see a diff containing all the changes you made on a branch since the branch was created from trunk? This is one of those things that should be easy in Subversion but isn't (or I couldn't find an easy way).

Helpfully, "svn help log" has a hint:

Logs follow copy history by default. Use --stop-on-copy to disable this behavior, which can be useful for determining branchpoints.

I've turned that idea into a handy wrapper script around "svn diff", which adds a revision specifier for "the revision just before this branch was created". I call it BRANCHPT or BRPT for short. Otherwise, the script just passes all arguments through unchanged to "svn diff".