Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Script used at eXo to convert various SVN projects to Git. You can reuse some of its content but you won' be able to run it with others eXo SWF scripts.
#!/bin/bash -eu
# Load SWF functions
source /home/swfcommons/bin/
# Initialize our script
swf_init_script $0
# Get config (use this for environment specific settings)
echo "==="
echo "If something wasn't removed by a previous job"
echo "==="
rm -rf $SWF_TMP_DIR/$git_repo_name.git
rm -rf $SWF_TMP_DIR/$git_repo_name.svn
echo "==="
echo "Create the target repository"
echo "==="
git init --bare --shared $SWF_TMP_DIR/$git_repo_name.git
cp ${SWF_BASE_DIR}/etc/${SWF_NAME}/cgitrc.repo-default $SWF_TMP_DIR/$git_repo_name.git/cgitrc
echo "name=$git_repo_name" >> $SWF_TMP_DIR/$git_repo_name.git/cgitrc
echo "desc=$git_repo_desc" >> $SWF_TMP_DIR/$git_repo_name.git/cgitrc
echo "owner=$git_repo_owner" >> $SWF_TMP_DIR/$git_repo_name.git/cgitrc
echo "readme=master:README" >> $SWF_TMP_DIR/$git_repo_name.git/cgitrc
cd $SWF_TMP_DIR/$git_repo_name.git;
git symbolic-ref HEAD refs/heads/trunk;
git config http.receivepack true
git config "SWF Team"
git config
git --bare update-server-info
cp $SWF_TMP_DIR/$git_repo_name.git/hooks/post-update.sample $SWF_TMP_DIR/$git_repo_name.git/hooks/post-update
chmod a+x $SWF_TMP_DIR/$git_repo_name.git/hooks/post-update
echo "==="
echo "Clone the original Subversion repository to a temp repository."
echo "==="
git svn clone --stdlayout --quiet --no-metadata --authors-file $authors_file --authors-prog=${SWF_BASE_DIR}/bin/ $svn_repo_url $SWF_TMP_DIR/$git_repo_name.svn;
cd $SWF_TMP_DIR/$git_repo_name.svn;
# Create .gitignore file.
echo "Converting svn:ignore properties into .gitignore." >&2;
git config "SWF Team"
git config
echo "#" > $SWF_TMP_DIR/${git_repo_name}.gitignore;
echo "# Ignores generated by SVN2GIT conversion" >> $SWF_TMP_DIR/${git_repo_name}.gitignore;
echo "#" >> $SWF_TMP_DIR/${git_repo_name}.gitignore;
echo "" >> $SWF_TMP_DIR/${git_repo_name}.gitignore;
git svn show-ignore --id trunk >> $SWF_TMP_DIR/${git_repo_name}.gitignore;
cat ${SWF_BASE_DIR}/etc/${SWF_NAME}/default.gitignore >> $SWF_TMP_DIR/${git_repo_name}.gitignore;
cp $SWF_TMP_DIR/${git_repo_name}.gitignore .gitignore
git add .gitignore;
git commit --author='SWF Team <>' -m 'Convert svn:ignore properties to .gitignore.';
echo "=== .gitignore ==="
cat $SWF_TMP_DIR/${git_repo_name}.gitignore
echo "=================="
echo "==="
echo "Cleanup useless entries"
echo "==="
git filter-branch --msg-filter 'sed -e "/git-svn-id:/d"' -- --all
git filter-branch -f --tree-filter '' --tag-name-filter cat --prune-empty -- --all
echo "==="
echo "Setup .gitignore in all branches"
echo "==="
git filter-branch -f --tree-filter "cp $SWF_TMP_DIR/${git_repo_name}.gitignore .gitignore" --tag-name-filter cat -- --all
echo "==="
echo "Push to final bare repository and remove temp repository."
echo "==="
git remote add bare $SWF_TMP_DIR/${git_repo_name}.git;
git config remote.bare.push 'refs/remotes/*:refs/heads/*';
git push bare;
cd -
rm -rf $SWF_TMP_DIR/$git_repo_name.svn;
cd $SWF_TMP_DIR/$git_repo_name.git;
echo "==="
echo "Rename Subversion's \"trunk\" branch to Git's standard \"master\" branch."
echo "==="
git branch -m trunk master;
echo "==="
echo "Remove bogus branches of the form \"name@REV\"."
echo "==="
git for-each-ref --format='%(refname)' refs/heads | grep '@[0-9][0-9]*' | cut -d / -f 3- | while read ref; do
git branch -D "$ref";
echo "==="
echo "Convert git-svn tag branches to proper tags."
echo "==="
git for-each-ref --format='%(refname)' refs/heads/tags | cut -d / -f 4 | while read ref; do
git tag -a "$ref" -m "Convert "$ref" to proper git tag." "refs/heads/tags/$ref";
git branch -D "tags/$ref";
echo "==="
echo "Call GC to manually cleanup/compress the repo"
echo "==="
nice -n20 git gc --aggressive --prune=now;
cd -
if [ ! -e $git_repo_path ]; then
mkdir -p ${GIT_REPOS_DIR}/$git_repo_path
mv $SWF_TMP_DIR/$git_repo_name.git ${GIT_REPOS_DIR}/$git_repo_path
rm $SWF_TMP_DIR/$git_repo_name.gitignore
rm -f $authors_file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment