I just tried out a build from the Subversion 1.7.x branch which appears to come close to a final release. Instead of creating .svn directories everywhere, the new working copy layout switches to a central storage using SQLite. You will only see a single .svn at the top most directory of the working copy. Details are outlined in the preliminary release notes.
The following is a totally inaccurate benchmark, but I want to share some numbers. The MacPorts repository used here contains lots of directories with only a few files in each, often only a single file. This makes operations walking the .svn directories in the tree very expensive.
Listing status of files:
~/src/macports/trunk-svn $ time svn st
real 3m39.347s
user 0m1.450s
sys 0m5.900s
~/src/macports/trunk-svn17 $ time svn17 st
real 0m23.788s
user 0m1.914s
sys 0m2.297s
Update without changes (locking the whole working copy against concurrent access):
~/src/macports/trunk-svn $ time svn up
At revision 83750.
real 2m32.855s
user 0m1.202s
sys 0m5.060s
~/src/macports/trunk-svn17 $ time svn17 up
Updating '.':
At revision 83750.
real 0m5.362s
user 0m1.793s
sys 0m1.166s
Impressive results!
Subversion allows to use a custom command for displaying diffs using svn diff --diff-cmd <cmd>. I have been using diff-cmd=colordiff in my ~/.subversion/config for quite some time now. This is really useful, but occasionally I would also like to use vimdiff to get a nice side-by-side diff.
Although this sounds quite easy at first, there are some hurdles. Subversion expects the given command to adhere to the GNU diff parameters, that means it expects it to understand and parse the labels it passes before the actual filenames. This works fine for colordiff, but not vimdiff which only wants the old and new filenames.
For a better diff experience with svn, I set up the following shell function which let’s me choose the program I want to use for diffing.
First, I need a new wrapper script at ~/libexec/svndiff which takes the actual diff program as first option, ignores the GNU diff labels and calls that program passing old and new filename.
#!/bin/bash
BIN=$1
shift 5
$BIN "$@"
Then I define this shell alias in my ~/.bashrc to extend the functionality of the svn command:
function svn() {
case "$1" in
diff-plain)
shift;
`which svn` diff --diff-cmd diff $@
;;
diff-color)
shift;
`which svn` diff --diff-cmd colordiff $@
;;
diff-vim)
shift;
`which svn` diff --diff-cmd $HOME/libexec/svndiff -x vimdiff $@
;;
diff-filemerge)
shift;
`which svn` diff --diff-cmd $HOME/libexec/svndiff -x opendiff $@
;;
*)
`which svn` $@
;;
esac
}
Now I can choose the program I find best suited for the current task in a very simplified manner, for example svn diff-vim -c1337.