Migrating From Svn to Git
Suppose you have a SVN repository and you would like to move to GIT - there might be many arguments around this. Well - here are some steps that I have tried to synthesise after many attempts and reading in internet. I am sure there are many approaches, but this one works for me straight forward.
The whole procedure consists of several steps:
- Extracting users from SVN and creating a mapping file SVN_USER <-> GIT_USER
- Cloning SVN repository into GIT repository
- Migrating branches
- Migrating tags
- Creating new GIT detached repository and pushing all changes to it
Here are some assumptions:
You will work in one directory, where you will create
`Suppose you have a SVN repository and you would like to move to GIT - there might be many arguments around this. Well - here are some steps that I have tried to synthesise after many attempts and reading in internet. I am sure there are many approaches, but this one works for me straight forward.
The whole procedure consists of several steps:
- Extracting users from SVN and creating a mapping file SVN_USER <-> GIT_USER
- Cloning SVN repository into GIT repository
- Migrating branches
- Migrating tags
- Creating new GIT detached repository and pushing all changes to it
Here are some assumptions:
You will work in one directory, where you will create
YOUR_SVN_REPOSITORY_URL
- is the URL that you use to checkout from SVN.
Lets start
Extracting users from SVN and creating a mapping file SVN_USER <-> GIT_USER
GIT needs to know how to map users from SVN to it’s format. Usually users in SVN are just usernames, where in GIT they are in format
John Smith <john.smith@mail.something>;
So at the end we should produce a mapping file that looks like:
jsmith = John Smith <john.smith@mail.something>;
ltorvalds = Linus <linus@linux.org>;
So execute the following command in your checkout svn repository, in order to create a file with the mapping svn-git-users-mapping.txt
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > svn-git-users-mapping.txt
Edit the produced file with correct User names and emails on the right side.
Cloning SVN repository into GIT repository
The following code executed in terminal will first create a directory, and clone svn into git repository in this directory, using svn-git-users-mapping.txt
file for transforming users.
mkdir YOUR_GIT_REPO_DIR
git svn clone YOUR_SVN_REPOSITORY_URL -A svn-git-users-mapping.txt --stdlayout YOUR_GIT_REPO_DIR
This script uses the standard SVN layout (trunk, branches, tags) - if you have a different structure - you can explicitly specify it, using parameters (-T trunk -b branches -t tags)
Migrating branches
Now is time to migrate branches - enter the created directory (YOUR_GIT_REPO_DIR) and execute the following script (this is a bash script, so if you use another shell, maybe you have to adjust it):
for branch in `git branch -r | grep -v -e 'tags\/\(.*\)' | sed 's/ \(.*\)/\1/g'`
do
remote_branch="remotes/$branch"
echo "About to checkout branch $remote_branch into $branch"
echo "============================================="
git checkout -b "$branch" "$remote_branch"
done
Similar process is used for the next point too:
Migrating tags
for branch in `git branch -r | grep -e '\(tags\/\)\(.*\)' | sed 's/\(tags\/\)\(.*\)/\2/g'`
do
remote_branch="remotes/tags/$branch"
new_tag="tag_$branch"
echo "About to checkout tag $remote_branch into $new_tag"
echo "============================================="
git checkout -b "$new_tag" "$remote_branch"
git checkout master
git tag $branch "$new_tag"
git branch -D "$new_tag"
done
Now that we have fully migrated repository, if we want a detached one from SVN (currently the created repo is connected to svn and can be used that way, with commends git svn rebase --all
- to fetch and rebase all changes from SVN, and git svn dcommit --interactive
- to push changes from git local commits to remote SVN repo).
Next step:
Creating new GIT detached repository and pushing all changes to it
git init --bare NEW_GIT_REPO
cd NEW_GIT_REPO
git symbolic-ref HEAD refs/heads/trunk
cd YOUR_GIT_REPO_DIR
git remote add NEW_GIT_REPO ../NEW_GIT_REPO
git config remote.NEW_GIT_REPO.push 'refs/remotes/*:refs/heads/*'
git push NEW_GIT_REPO
Now you are ready to use the newly created GIT repository, having all your history, branches and tags.
In next article I will try to share my experience of using SVN as central repository, and GIT as local versioning and client.
Here are some links that I used, while researching the best way to do the migration:
~Enjoy