Change svn:externals quickly

If you’ve worked with external repository definitions and branches before, you probably know the problem: If you create a new branch off an existing one or merge one branch into another, subversion is not smart enough to update svn:externals definitions which point to the same repository, but rather keep them pointing to the old (wrong) branch. (I read they fixed that with SVN 1.5 by supporting relative URLs, but still, a couple of people might not be able to upgrade and I want to keep rather explicit with external naming anyways.)

Anyways, today at work I was so sick of the problem that I decided should hack something together. Here is the result:

#!/bin/bash
export LANG=C
if [ $# -ne 2 ]
then
    echo "Usage:" $(basename $0) "<old> <new>"
    exit 1
fi

old=$1
new=$2
repo_root=`svn info | grep "Repository Root" | cut -f3 -d" "`;

if [ -n "$(svn info $repo_root/$new 2>&1 | grep "Not a valid URL")" ]
then
    echo "$repo_root/$new is not a valid URL"
    exit 1
fi

for ext in  $(svn st | grep -e "^X" | cut -c 8- | xargs -L1 dirname | uniq)
do
    externals=$(svn propget svn:externals $ext)
    if [[ "$externals" == *$repo_root/$old* ]]
    then
        externals=${externals//$repo_root\/$old/$repo_root\/$new}
        svn propset svn:externals "$externals" $ext
    fi
done

Save this into a file, make it executable and you’re good to go! The script is smart enough to check if the target URL (based on the repositories’s root and the given <new> path) actually exists and also only changes those external definitions which actually match the repository root.

Fun!