nwinkler
nwinkler

Reputation: 54427

How to SVN relocate multiple directories

I would like to relocate multiple checked out SVN directories on my local machine, since our SVN server moved and now has a different IP address. Instead of doing this through a tool like SmartSVN or TortoiseSVN, I would like to use a script to do the directories in one sweep.

Each directory contains a different working copy - so either a different project or sometimes also a different branch or tag, therefore I can't just do the relocate in the root directory.

Upvotes: 1

Views: 1776

Answers (2)

nwinkler
nwinkler

Reputation: 54427

I found a partial solution on a web page that has disappeared, and also an improved version in the comments, but I wanted to clean it up a bit and provide it here for other people as well

The IP addresses are fictional and need to be adjusted to local settings.

The script iterates over all directories that are managed by SVN and use the old location, then calls the svn switch command with the relocate option for each one.

#!/bin/bash

OLD_REPO=http://127.0.0.1/svn/
NEW_REPO=http://192.168.0.17/svn/

for dir in `ls -1 */.svn/entries | xargs grep -H -l $OLD_REPO | grep -E -o ^[^\/]+`; do
    echo Switching sandbox $dir from $OLD_REPO to $NEW_REPO;
    
    OLD_ROOT=`svn info $dir | grep ^Repository\ Root | cut -f 3 -d ' '`
    NEW_ROOT=`echo $OLD_ROOT | sed "s|$OLD_REPO|$NEW_REPO|"`
    svn switch --relocate $OLD_ROOT $NEW_ROOT $dir;
done

If you also want to change the user while relocating, it's easy to add something like --username $USERNAME parameter to the command, and defining the $USERNAME at the top of the script.

Upvotes: 2

Jean-Francois T.
Jean-Francois T.

Reputation: 12920

The solution of @nwinkler was not working on my machine as my version of grep does not support the option -o (grep 2.4.2 in Msys).

I came up with this other solution which has also the following improvements:

  • Support of directory names with spaces
  • Support of several old repository URLs (e.g. server name and IP address)

Code is much longer and not as elegant, but it does the trick.

The script shall be run from your directories containing your local repositories.

#!/bin/bash

#Change separator to support directories with space
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

#URL of new 
NEW_REPO=http://newserver:8080/svn/

#List of potential old repositories
OLD_REPOS[0]=http://oldserver:8080/svn/
OLD_REPOS[1]=http://oldserver.domain.com:8080/svn/
OLD_REPOS[2]=http://127.0.0.1:8080/svn/


for dir in `ls -d1 *`; do
    #Check directory and skip if needed
    if ! [ -d "$dir/.svn" ]; then
        continue;
    fi  
    #Relocate
    OLD_ROOT=`svn info $dir | grep ^Repository\ Root | cut -f 3 -d ' '`
    if [ "`echo $OLD_ROOT | grep $NEW_REPO`" == "$OLD_ROOT" ]; then
        echo "Skipped repository '$dir' (already relocated)";
    else
        for OLD_REPO in ${OLD_REPOS[*]}; do
            NEW_ROOT=`echo $OLD_ROOT | sed "s|$OLD_REPO|$NEW_REPO|"`;
            if [ "$OLD_ROOT" != "$NEW_ROOT" ]; then
                echo "Switching repository '$dir' from $OLD_REPO to $NEW_REPO";
                svn switch --relocate $OLD_ROOT $NEW_ROOT $dir;
                echo "=> done";
                continue 2;
            fi
        done
        echo "Repository '$dir' does not match any old repository identified";
    fi
done

#Restore separator
IFS=$SAVEIFS

#--END--#

The approach is slightly different:

  • Loop over all the files and directories
  • Skip if it is not a SVN repository
  • If the local repository matches a URL of old repository, it is relocated

Upvotes: 1

Related Questions