Using Newer Subversion in Xcode

Posted by Thoughts and Ramblings on Saturday, July 25, 2009

I use MacPorts to get a whole host of utilities. In addition, I’ve always used it to obtain later versions of subversion that the one provided with the OS. Xcode, on the other hand, is locked into using the version of Subversion which is installed in /usr (currently version 1.4.4 where as I have 1.6.3). Since I often work in the command line, eventually I will use the newer version of Subversion on a directory which I also use in Xcode. This causes a problem since the command line utility will upgrade the local repository format in such a way that old versions of Subversion (Xcode’s) cannot use it.

So, my options are:

  • Only use the command line utility, or use Xcode, on a single repository checkout, but never both.
  • Use a horribly out of date version of Subversion
  • Hack Xcode’s plugin to work with newer versions of Subversion

I chose the last, as it should give me the best of both worlds. If you were to conduct a quick Google search, you would find a whole host of people posing a solution which involves moving around system libraries!!!!! This is a horrible idea, as it breaks other things such as Apache. Buried somewhere in the sea of bad ideas, I ran across a good one, written by Jean-Daniel Dupas and improved by Philippe Casgrain which only changes the path location of libraries used by Xcode’s Subversion plugin. This script worked well for Subversion 1.5, but recent versions of Subversion would cause Xcode to crash in libapr. The solution is to add libapr and libaprutil to the script. Here is the corrected script for your use.

#!/bin/sh

if [ "$#" -lt "2" ]
then
  echo "Usage: xcode-svn-update.sh"
  echo "Example: xcode-svn-update.sh /Developer/Library/Xcode/Plug-ins/\"
  echo "XcodeSubversionPlugin.xcplugin/Contents/MacOS/XcodeSubversionPlugin /opt/local"
  exit 1;
fi

# Save a backup copy, if necessary
if [ -e "$1_Old" ]
then
  echo "Backup copy of \"$1\" exists."
else
  echo "Saving a backup copy of \"$1\"."
  cp "$1" "$1_Old"
fi

echo "Updating install path using svn libraries in \"$2\"..."
install_name_tool -change \
  /usr/lib/libapr-1.0.dylib \
  $2/lib/libapr-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libaprutil-1.0.dylib \
  $2/lib/libaprutil-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_client-1.0.dylib \
  $2/lib/libsvn_client-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_delta-1.0.dylib \
  $2/lib/libsvn_delta-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_diff-1.0.dylib \
  $2/lib/libsvn_diff-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_fs_fs-1.0.dylib \
  $2/lib/libsvn_fs_fs-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_fs-1.0.dylib \
  $2/lib/libsvn_fs-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_ra_local-1.0.dylib \
  $2/lib/libsvn_ra_local-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_ra_svn-1.0.dylib \
  $2/lib/libsvn_ra_svn-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_ra-1.0.dylib \
  $2/lib/libsvn_ra-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_repos-1.0.dylib \
  $2/lib/libsvn_repos-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_subr-1.0.dylib \
  $2/lib/libsvn_subr-1.0.dylib "$1"
install_name_tool -change \
  /usr/lib/libsvn_wc-1.0.dylib \
  $2/lib/libsvn_wc-1.0.dylib "$1"
echo "Done!"

Now, how long till Xcode supports Mercurial?