Skip to content

Instantly share code, notes, and snippets.

@aheritier
Created February 5, 2014 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aheritier/8824148 to your computer and use it in GitHub Desktop.
Save aheritier/8824148 to your computer and use it in GitHub Desktop.
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/swfcommons-functions.sh
# Initialize our script
swf_init_script $0
swf_init_var
# Get config (use this for environment specific settings)
swf_load_env
svn_repo_url=$1
git_repo_path=$2
git_repo_name=$3
git_repo_desc=$4
git_repo_owner=$5
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 user.name "SWF Team"
git config user.email exo-swf@exoplatform.com
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-lookup-author.sh $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 user.name "SWF Team"
git config user.email exo-swf@exoplatform.com
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 <exo-swf@exoplatform.com>' -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";
done
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";
done
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
fi;
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