Finally you decided that git is more suitable than svn for your work. But, what happens when you have projects that where using svn for a while? All of that information represented in thousand of svn revisions is something that normally you don’t want to lose. For these cases I wrote this step by step guide to successfully migrate all the history stored in svn on a git repository, included all branches and tags no matter svn repository size. The only drawback is, more revisions you have more time you need to wait to get migration finished.
To start the migration process, you need some info about how is data organized in your svn.
If you are lucky your project follows this directories layout
This can be simply informed to git-svn with -s or –stdlayout. If is not your case you have to inform to git-svn where is every one of these tree directories.
-T trunkSubdirecty or --trunk=trunkSubdirecty
-t tagsSubdirecty or --tags=tagsSubdirecty
-b brenchesSubdirecty or --branches=brenchesSubdirecty
For example you can have a layout like this
If you are migrating projectname1 the arguments must look like this
-T trunk/projectname1 -t tags/projectname1 -b branches/projectname1
The other thing you need to know is the revision number where start the history of what you want to migrate. First candidate is first revision number where your project exists. You can ask svn by running this line.
svn log -r 1:HEAD --limit 1 svnrepourl/a/path/trunkSubdirectory
If you want to truncate some of the old history simply choose a newer revision number.
Standar
git svn clone --username=yourSvnUsername --stdlayout -r aRevisionNumber svnurl/a/path/projectname gitreponame
Custom layout
git svn clone --username=yourSvnUsername -T trunk/projectname -t tags/projectname -b branches/projectname -r aRevisionNumber svnurl/a/path/projectname gitreponame
cd gitreponame
git svn fetch
This step could last long time even days depending the amount of revisions, data transfer ratios and from my experience, if you use windows takes more time than linux or osx. Git-svn will perform one request per revision to svn and will create a git commit if it considered convenient. If something goes wrong during data fetching, you simply run again “git svn fetch” and work will resume from last svn revision successfully processed. That’s the reason why you must use “git clone -r n” and then “git svn fetch”. When you run “git svn fetch” and finish with nothing to log it minds you finished the hardest part, now you have all data in your local git repository. But to finish your work you need to put all this information in github, bitbucket, your intranet git repositories container or where you consider useful.
Run this line
git svn rebase
This has the same effect of
git reset --hard origin/trunk
but have the advantage of confirming you that origin/trunk is already updated with the last svn revision
Regarding branches in git, are references to commit-objects inside git database you can simply copy those references that git-svn made.
cp .git/refs/remotes/origin/* .git/refs/heads/
If you run
git branch
You will see all branches that exists in svn including trunk
Tags in git are different than branches, tag references point to tag-objects inside git database. The references that git-svn created are references that point to commit-objects instead of tag-objects, then they are branches instead of tags. Well, lets create a tag for every references that git-svn have created inside .git/refs/remotes/origin/tags. Just run this line, if you are using windows you have to run it inside git bash console
git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done
If you run
git tag
You will see the same list of tags that exists in svn
Create an empty repository in your repositories container, for example github. Then in your local repository add remote and push.
git remotes add newrepo git@github.com:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo
At this point you can forget that your project once was using svn.
24 Feb 2016