Skip to content

Instantly share code, notes, and snippets.

@svagionitis
Last active December 7, 2015 18:29
Show Gist options
  • Save svagionitis/61e432a3188af2b0b744 to your computer and use it in GitHub Desktop.
Save svagionitis/61e432a3188af2b0b744 to your computer and use it in GitHub Desktop.
Convert a subversion repo to git
#!/bin/sh -ex
# Convert a subversion repo to git
# according to this link http://john.albin.net/git/convert-subversion-to-git
if [ $# -eq 0 ]; then
echo "Usage: $0 [svn repo url]"
exit 1
fi
# Checkout an svn repo
# $1 - The svn repo url
# $2 - The directory to checkout
checkout_svn_repo() {
local svn_repo_url="$1"
local dest_svn_dir="$(basename ${svn_repo_url}).svn"
svn checkout ${svn_repo_url} ${dest_svn_dir}
}
# Create an authors file from the svn repo
# $1 - The svn repo url
transform_authors() {
local svn_repo_url="$1"
local svn_checkout_dir="$(basename ${svn_repo_url}).svn"
checkout_svn_repo ${svn_repo_url}
cd ${svn_checkout_dir}
SVN_ROOT=`svn info "${SVN_URL}" | grep '^Repository.Root' | sed -e 's/^Repository.Root: //'`
svn log -q "${SVN_ROOT}" | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@google.com>"}' | sort -u > ../${svn_checkout_dir}-authors-transform.txt
cd -
}
# Clone a svn repo to git
# $1 - The svn repo url
# $2 - The authors transform file
clone_svn_to_git() {
local svn_repo_url="$1"
local authors_transform_file="$2"
local dest_git_dir="$(basename ${svn_repo_url}).git"
if [ -z ${authors_transform_file} ]; then
git svn clone ${svn_repo_url} --stdlayout ${dest_git_dir}
else
git svn clone ${svn_repo_url} -A ${authors_transform_file} --stdlayout ${dest_git_dir}
fi
cd ${dest_git_dir}
ls -la
cd -
}
# Create a bare git repo and push the changes there
# $1 - The svn repo url
create_bare_and_push_to_bare() {
local svn_repo_url="$1"
local git_dir="$(basename ${svn_repo_url}).git"
local git_bare_dir="$(basename ${svn_repo_url})-bare.git"
if [ ! -d ${git_dir} ]; then
echo "Git directory doesn't exist..."
exit 1
fi
# Create bare git repo
if [ ! -d ${git_bare_dir} ]; then
git init --bare ${git_bare_dir}
fi
cd ${git_bare_dir}
git symbolic-ref HEAD refs/heads/trunk
cd -
# Push to bare repo
cd ${git_dir}
git remote add bare "../${git_bare_dir}"
git config remote.bare.push "refs/remotes/*:refs/heads/*"
git push bare
cd -
cd ${git_bare_dir}
# Rename trunk to master
git branch -m trunk master
# Cleanup branches and tags
git for-each-ref --format='%(refname)' refs/heads/tags | cut -d / -f 4 |
while read ref
do
git tag "$ref" "refs/heads/tags/$ref";
git branch -D "tags/$ref";
done
cd -
}
authors_transform="$(basename ${1}).svn-authors-transform.txt"
# If the file of authors doesn't exist
# create it
if [ ! -f ${authors_transform} ]; then
transform_authors ${1}
fi
clone_svn_to_git ${1} ${authors_transform}
create_bare_and_push_to_bare ${1}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment