Create a gist now

Instantly share code, notes, and snippets.

@ztj /migrate.sh
Last active Dec 11, 2015

Shell script targeting bash for the purpose of creating a git repository from a subversion repository of standard layout.
#!/bin/sh
set -u
set -e
SVNURL="https://pearson.jira.com/svn/ZIS"
USERSFILE="users.txt"
GITREPO="git-tmp"
STARTINGPATH="`pwd`"
GITREPOPWD="`pwd`/$GITREPO"
USERSPWD="`pwd`/$USERSFILE"
if [[ ! -e "$USERSPWD" || ! -s "$USERSPWD" ]]; then
echo "Populating $USERSFILE with usernames."
echo
echo "YOU MUST FILL IN THE NAMES AND EMAIL ADDRESSES BEFORE RUNNING THIS SCRIPT AGAIN."
echo "YOUR RESULTING GIT REPOSITORY WILL BE FULL OF LIES IF YOU DO NOT UPDATE THE FILE!"
echo
svn log -q $SVNURL | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { gsub(/^ /, "", $2); print $2 "= User Name <user.name@domain.com>" }' | sort | uniq > "$USERSPWD"
exit 1
fi
if [ ! -d "$GITREPOPWD" ]; then
echo "Cloning subversion repository $SVNURL"
git svn clone --stdlayout --no-metadata --no-minimize-url --prefix=svn/ -A $USERSPWD $SVNURL $GITREPO
else
echo "Continuing clone of subversion repository $SVNURL"
cd "$GITREPOPWD"
git svn fetch
fi
# Now move into the git repo for various tasks
cd $GITREPOPWD
# Now we will make annotated tags in the git repo based on the tags in the svn repo
git for-each-ref --format='%(refname)' refs/remotes/svn/tags/* | while read r; do
tag=${r#refs/remotes/svn/tags/}
sha1=$(git rev-parse "$r")
commiterName="$(git show -s --pretty='format:%an' "$r")"
commiterEmail="$(git show -s --pretty='format:%ae' "$r")"
commitDate="$(git show -s --pretty='format:%ad' "$r")"
# Print the commit subject and body separated by a newline
git show -s --pretty='format:%s%n%n%b' "$r" | \
env GIT_COMMITTER_EMAIL="$commiterEmail" GIT_COMMITTER_DATE="$commitDate" GIT_COMMITTER_NAME="$commiterName" \
git tag -a -F - "$tag" "$sha1"
echo "Tag: ${tag} sha1: ${sha1} using '${commiterName}', '${commiterEmail}' on '${commitDate}'"
# Remove the svn/tags/* ref
git update-ref -d "$r"
done
# Remove the tags in the git repo that had been created but then removed in the svn repo over time.
for tag in $(git tag -l); do
set -e
echo "Check if the tag '"${tag}"' still exists in Subversion"
set +e
svn ls ${SVNURL}/tags/${tag} > /dev/null 2>&1
if [ "$?" -ne 0 ]; then
echo "Tag '"${tag}"' doesn't exist anymore, will remove it from git repository."
set -e
git tag -d ${tag}
fi
done
# Create local branches out of svn branches, will use anything left in remotes after tag process is done
git for-each-ref --format='%(refname)' refs/remotes/svn/ | while read branch_ref; do
branch=${branch_ref#refs/remotes/svn/}
if [[ "$branch" != "trunk" ]]; then
echo "Creating branch: $branch"
git branch -t "$branch" "$branch_ref"
git update-ref -d "$branch_ref"
fi
done
git tag -m "The state of the trunk at the time of migration from subversion." migrated-trunk
cd $STARTINGPATH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment