Following up on the good work of Jean-Francois Roy, here's my slightly extended version of his script to backup all Subversion repositories to a remote host.

How to use:

  1. Download backup-all-svn.sh
  2. chmod u+x path/to/backup-all-svn.sh
  3. ./backup-all-svn.sh -h target_host (can also set target port and user name)

Some features:

  • Works with plain /bin/sh, so it should work on any Linux / BSD distribution.
  • Works with repository names with spaces and non-ASCII characters.

backup-all-svn.sh

 #!/bin/sh # # $Id: backup-all-svn.sh 387 2008-06-07
20:36:08Z vengmark $ # # NAME # backup-all-svn.sh - Backup all Subversion
repositories # # SYNOPSIS # backup-all-svn.sh [options] # # OPTIONS # -v Verbose
output # -h Target host name (mandatory) # -p Target host port # -u Target host
user name # # EXAMPLE # ./backup-all-svn.sh -v -h example.com -p 1234 -u johndoe
# # DESCRIPTION # Backups all your subversion repositories to a remote machine.
# # The current user must have access to the subversion repositories. # To work
around this, you should `sudo adduser
<username>
  <svn-group
    >` # and `sudo chmod -R g+w /path/to/repos`. # # To avoid having to type
    your password several times, you can setup SSH # keys - See e.g.
    https://help.ubuntu.com/community/SSHHowto # # BUGS # Email bugs to victor
    dot engmark at gmail dot com. Please include the # output of running this
    script in verbose mode (-v). # # COPYRIGHT AND LICENSE # Copyright (C) 2005
    Jean-Francois Roy # Copyright (C) 2008 Victor Engmark # # This program is
    free software: you can redistribute it and/or modify # it under the terms of
    the GNU General Public License as published by # the Free Software
    Foundation, either version 3 of the License, or # (at your option) any later
    version. # # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of #
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General
    Public License for more details. # # You should have received a copy of the
    GNU General Public License # along with this program. If not, see
    <http://www.gnu.org/licenses/>. #
    ################################################################################
    # Init ifs_original="$IFS" # Reset when done PATH="/usr/bin:/bin"
    cmdname=`basename $0` directory=`dirname $0` # Remote host
    target_dir=".svn-backup/`date +%G-%m-%d`" target_port=22
    target_user=`whoami` # Subversion svn_root="/var/lib/svn"
    svn_install_root="/usr/bin" # Error messages from /usr/include/sysexits.h,
    recommended by # http://www.faqs.org/docs/abs/HTML/exitcodes.html EX_OK=0
    EX_USAGE=64 EX_CANT_CREATE=73 # Custom errors EX_NO_SUCH_DIR=91
    EX_NO_SUCH_EXEC=92 usage_error() { echo "Usage: ${cmdname} [-v] -h host [-p
    port] [-u user]" #Code 3 exit $EX_USAGE } # Process parameters until [ $#
    -eq 0 ] do case $1 in -v) verbose=1 shift ;; -h) if [ -z "$2" ] then
    usage_error fi target_host=$2 shift 2 ;; -p) if [ -z "$2" ] then usage_error
    fi target_port=$2 shift 2 ;; -u) if [ -z "$2" ] then usage_error fi
    target_user=$2 shift 2 ;; *) #Unknown parameter usage_error ;; esac done if
    [ -z ${target_host} ] then usage_error fi # Use for mandatory directory
    checks # $1 is the directory path # $2 is the (optional) error message
    check_directory() { if [ ! -d $1 ] then echo "No such directory: '${1}'" >&2
    echo $2 >&2 exit $EX_NO_SUCH_DIR fi } check_directory $svn_root "Please
    change \$svn_root to point to the directory where your Subversion
    repositories are." check_directory $svn_install_root "Please change
    \$svn_install_root to point to the directory where Subversion is installed."
    # Make sure an executable is available # $1 is the path to the executable #
    $2 is the (optional) error message check_executable() { if [ ! -x $1 ] then
    echo "No such executable: '${1}'" >&2 echo $2 >&2 exit $EX_NO_SUCH_EXEC fi }
    svn_install_missing="Please change \$svn_install_root to point to the
    directory where Subversion is installed." check_executable
    ${svn_install_root}/svnlook $svn_software_missing check_executable
    ${svn_install_root}/svnadmin $svn_software_missing # Create the temporary
    folder temp_dir=`mktemp -t -d ${cmdname}.XXXXXXXXXX` || exit $?
    verbose_echo() { if [ $verbose ] then echo "$*" fi } # Announce that we're
    running verbose_echo "Running $cmdname at `date`." # Create target directory
    ssh -p ${target_port} ${target_user}@${target_host} "mkdir -p
    \"${target_dir}\"" || exit $? # Loop over repositories cd "${svn_root}"
    IFS=" " # Make sure paths with spaces don't make any trouble when looping
    for repository in * do # Get the last revision
    revision=`${svn_install_root}/svnlook youngest "${repository}"` verbose_echo
    "Backing up repository \"${repository}\" revision ${revision}." # Make sure
    the repo is OK verbose_echo "Recovering the repository."
    ${svn_install_root}/svnadmin recover --wait "${repository}" > /dev/null #
    Did the recover operation fail? if [ $? -ne 0 ] then echo "Backup failed
    because recovery failed." >&2 break fi # Hotcopy verbose_echo "Hot-copying
    the repository." ${svn_install_root}/svnadmin hotcopy --clean-logs
    "${repository}" "$temp_dir/${repository}" # Did the hotcopy fail? if [ $?
    -ne 0 ] then echo "Backup failed because hotcopy failed." >&2 rm -Rf
    "$temp_dir" break fi # Compress the hotcopy verbose_echo "Compressing the
    repository in a tar.bz2 archive."
    archive="${repository}-r${revision}.tar.bz2" tar -cjpf
    "$temp_dir/${archive}" -C "$temp_dir" "${repository}" # Send it over
    verbose_echo "Copying repository archive to remote host." scp -P
    ${target_port} "$temp_dir/${archive}"
    "${target_user}@${target_host}:\"${target_dir}/${archive}\"" done
    verbose_echo "Cleaning up." rm -Rf $temp_dir IFS="$ifs_original" # End
    verbose_echo "${cmdname} completed at `date`." exit $EX_OK