Home > Programming, Tools, Version Control > Back up your Subversion and Mercurial repositories

Back up your Subversion and Mercurial repositories

This morning I cooked up two scripts to back up my VCS repositories. I have two Subversion repositories locally, one for my main research project and another for my homepage. I have three hg repositories at the moment, one for local shell scripts (like the ones I was writing), one for my configuration files and another for an extended book project I’m working on.

The svn-oriented script takes either command-line arguments or reads repository paths from a file (~/.svnbk), each one on a single line. It makes (not “takes”) an svnadmin dump to stdout, which is compressed with the best available compression program, in the specified directory.

#!/bin/sh

# svnbk.sh: A tool for backing up my SVN repositories
#
# Copyright (C) 2010 Joel James Adamson
#
# 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, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

# Usage:
#  svnbk.sh [repositories] bkupdir
#
# If `repositories' is empty then svnbk.sh will look in ~/.svnbk for a
# list of repositories to back up; repositories will be dumped to
# compressed files in the directory `bkupdir'

# If available, use xz compression; otherwise use bzip2; if
# unavailable use gzip
XZ=$(which xz)
BZ2=$(which bzip2)
GZIP=$(which gzip)

if [ -x $XZ ]; then
    ZIP="$XZ"
    EXT=".xz"
elif [ -x $BZ2 ]; then
    ZIP="$BZ2"
    EXT=".bz2"
elif [ -x $GZIP ]; then
    ZIP="$GZIP"
    EXT=".gz"
else
    printf "Compression unavailable; dumping to uncompressed dump files\n";
    ZIP="none"
    EXT=""
fi

# Command-line variables
declare -a argv
argv=("$@")
# number of command-line args
argc="${#argv[@]}"
LAST=$(($argc - 1))
BKDIR=${argv[$LAST]}
# now to get a list of repositories from the command-line, we copy
# argv, then destroy the last element:
declare -a REPOS
REPOS=(${argv[@]})
unset REPOS[$LAST]
if [[ -z $REPOS ]]; then
    while read repo ; do
	FILE="$BKDIR/svn_$(basename $repo).dump$EXT"
	svnadmin dump $repo | $ZIP - > $FILE
    done  $FILE
    done
fi

The Mercurial backup requires you to initialize remote repositories, which is easy if you’re backing up to a mounted CIFS or NFS partition. Unfortunately, hg init does not create the directories on the CIFS partition I’m using, so I used the following:

joel@cifshost > mkdir hgbak
joel@cifshost > cd hgbak
joel@cifshost > mkdir bin
joel@cifshost > cd bin
joel@cifshost > hg init

After that the hg push should work just fine. The config file for this one has the local repository followed by the remote repository on each line. It does not use any compression:

#!/bin/sh
#
# Copyright (C) 2010 Joel J. Adamson
#
# 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, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

# hgbk.sh: A tool for backing up my hg repositories
#
# Usage:
#  hgbk.sh [repositories] bkupdir
#
# Read ~/.hgbk for a list of repositories to back up; the syntax of
# the file specifies
#
# [local repository] [remote (backup) repository]

# now to get a list of repositories from the command-line, we copy
# argv, then destroy the last element:
while read -a repo ; do
    cd ${repo[0]}		# full pathname!
    hg push ${repo[1]}
done < $HOME/.hgbk

Pretty easy, but saves a lot of time. The only non-automated part is the initial remote repository. I then activate them with the following script, placed in ~/.cron.daily/:

#!/bin/sh

ERRLOG=$(mktemp)
/home/joel/bin/svnbk.sh /home/joel/bioark 2>| $ERRLOG
SVNRC=$?
/home/joel/bin/hgbk.sh >> $ERRLOG
HGRC=$?
if [ $SVNRC -ne 0 ] || [ $HGRC -ne 0 ]; then
    mail joel < $ERRLOG
fi

rm $ERRLOG

You can download these from my homepage. I welcome comments and improvements.

  1. June 29, 2010 at 09:40

    You could also use a backup hg repository on an ssh-available host where you’ve set up password-less logins through ssh.

    Like

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: