SVN was a good enough version control system (VCS) and sometimes even a synonym for VCS in everyday talks. However, technologies change and the way of developing computer software as well, in my opinion, SVN became some kind of “disturbing” or “breaking” thing in development process. It’s slow, centralized and linear. I mean it’s really slow. And when Git was introduced, usually nobody realized how it’s different to SVN and why we need it. Today it’s de-facto standard for VCS. It has a bit different logic, but you can get used to it relatively quickly without any problems.
But back to the topic. So you want to get rid of SVN repository and start using Git without loosing your commits history and other stuff. Actually save all data and work with Git instead of SVN? There’s already enough articles on the internet about that, even in the official book. But I will describe how I did it myself with some additional commands. Everything is done with the help of built in Git commands.
- So first, you’ll need an SVN repo to convert. Define a repo path. It may look like this
svn://example.com/svn/repo_example/
- In case repository requires authorization for accessing it, prepare name and password of SVN user
- You will probably want to map SVN usernames to Git users, you can do that by creating a special text file in format:
svn_username = Name Surname
. Each user on the new line.This command will help you to to find all users that were commiting to SVN repo and create authors file:
svn log --xml | grep -P "^<author" | sort -u | \ perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt
All you have to do is open it and add appropriate Git usernames on the right hand side.
Ok. Now you’re ready to start the process. Import of SVN repo to the Git is done by git svn clone command. This will init Git repo and import SVN data (you can do that by using separate git commands).
git svn clone --username=SVN_USERNAME --authors-file=/path/to/authors.txt -s --no-metadata svn://example.com/svn/repo_example/
This will create a git repo with the same name in the current folder. It may take a while to complete, especially on bigger repositories.
Once it finished, you’ll have a ready Git repo with your data. But you’re not done yet.
Git doesn’t track empty directories, so you’ll need to fix that. Run:
find . -type d -empty -exec touch {}/.gitignore \;
This will make it track even those empty dirs by creating special empty file .gitignore in them.
Commit changes.
Now, your SVN tags are remote branches in your newly created Git repo. Fix that by running:
git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done
It will convert them to real Git tags.
SVN branches are remote branches as well, fix that too:
git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done
Now they’re normal branches.
You may want to fix some branches names, for example trunk to develop, do that using git command:
git branch -m old_branch_name new_branch_name
Now you can cleanup some SVN stuff in your Git repository you no longer need:
git branch -rd git-svn git config --remove-section svn-remote.svn git config --remove-section svn rm -rf .git/svn
Now you’re all set. If you want to push it to some remote repo, do that by adding an origin and push all data:
git remote add origin [email protected]:repo_name.git git push origin --all git push origin --tags
Now you can come back to work using Git repository.