Friday, October 23, 2009

updating git svn local copies

Post-release in maven, I have a lot of svn modules to update:

for d in `find . -maxdepth 1 -type d`; do cd $d; if [ -d .git/svn/trunk ] ; then echo $d && git svn rebase; fi; cd -; done
view raw gistfile1.sh hosted with ❤ by GitHub

Monday, October 05, 2009

Settig up Git mirrors of SVN

At work, I've been using git-svn for quite a while. I like the workflow options, and better merging capabilities. As a casualty from the recent laptop hard drive failure, all of my git repositories had gone, checked out from our main SVN server. I'm the only one using git where I work, but I love the workflow that it gives me and going back to SVN is a no-no. That had previously been created by doing a

git svn clone -s svn://svn.example.com/module

That took ages (3 days for all of the stuff I need to work on) and was quite slow when doing commits. My backups are mildly corrupt too, so I've started over, and set it up properly this time. Thanks to the guide here.

On the server, I created a directory to hold the git mirrors, and a text file containing the SVN modules that I wanted initially. Then a simple bash script to loop through the file and create a mirror of each SVN module:

for f in `cat svn-modules.txt` ; do svn2git.sh $f ; done

$ cat svn2git.sh
#! /bin/sh
# Simple script to mirror an existing SVN repository as a git repository.
# Full project history will be imported
#
# Usage:
# svn2git.sh name-of-module
# name-of-module - the name of the GIT repository that we wish to create
# svn/module/path - the optional SVN path of the module being mirrored.
# Defaults to the name of the GIT repository being created
if [ -z $1 ] ; then
echo "Usage: $0 module-name [svn/module/path]"
exit 1
fi
module_name=$1
if [ -z $2 ] ; then
svn_path=$module_name
else
svn_path=$2
fi
mkdir $module_name.git
cd $module_name.git
git --bare init
git --bare svn init -s svn://svn.example.com/$svn_path
git --bare svn fetch --all
git --bare update-server-info
cd ..
view raw gistfile1.sh hosted with ❤ by GitHub


Then just make the repositories available:

git-daemon --export-all --base-path=/opt/git --verbose

and create a cron job to refresh the git mirrors periodically.

git --bare svn fetch --all

There are other ways, but that's the quick-n-dirty approach. Then a similar script on the client, which used the same list of modules that I wanted to check out.

$ cat checkout-git-svn.sh
#!/bin/sh
# Simple script to checkout a project from git and tie up SVN commits. Should be a lot faster than git svn clone
# Initial parameter is the name of the git /svn module. Optional second parameter is the SVN path. This allows us to manage more complex SVN modules, which may be nested rather than at the top level
if [ -z $1 ] ; then
echo "Usage: $0 module-name [svn/path]"
exit 1
fi
module_name=$1
if [ -z $2 ] ; then
svn_path=$module_name
else
svn_path=$2
fi
mkdir $module_name
cd $module_name
git init
git remote add origin git://git.example.com/$module_name.git
git config --add remote.origin.fetch '+refs/remotes/*:refs/remotes/*'
git fetch
git svn -s init svn://svn.example.com/$svn_path
git svn fetch
git checkout -b master -t trunk
cd -
view raw gistfile1.sh hosted with ❤ by GitHub


Benefits of this approach:
  • Much faster to set up - it took just over a couple of hours this time.

  • Available to other people to try out - not just me.

  • Provides a migration path off SVN as we eventually migrate off SVN (my long-term aim, muhahaha)