Migrate SVN Repository to Git on BitBucket

By Jimmy Bonney | June 26, 2012

SVN to Git

We have just migrated the version control system of our web application from SVN to GIT. While there are a lot of sources available online to perform this, not all of them consider the special case when one need to migrate branches that might not have been re-integrated to the trunk yet.

I have mixed a few different sources in order to get this right for us. I will not re-write what has been written so many times by others (often in a better and clearer way that what I could do) but will simply list the steps that I followed and links to the different sources.

1. Install Git and Git-SVN

1
sudo apt-get git-svn

2. Create the author files

A great way to collect all authors is given by John Albin. From the folder containing the working copy of your SVN repository, just run the following command:

1
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Be aware, that this will take all authors from the working copy only. If your working copy is trunk for instance, this will take all submitters to trunk and will therefore not provide you with the name of people that might have committed to branches only.

Once authors are collected, simply edit the file so that all entries contain the SVN author name on the left, and the Git author name (and email address on the right).

jbonney = Jimmy Bonney <jbonney@myveryowndomain.com>

3. Clone the SVN repository

From the directory where you have the authors-transform.txt file, clone the SVN repository.

1
git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

The --stdlayout assumes that your SVN repository is configured with Trunk, Branches and Tags. If you are using another setup, you can run a more explicit command.

1
git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt -t tags -b branches -T trunk ~/temp

Once done, the following command should return git messages with your latest commits:

1
2
cd ~/temp
git log

4. Convert svn:ignore to .gitignore

Many sources reference this step. However, it seems that it is now done automatically during step 3.

5. Create a bare Git repository

Create a bare git repository (i.e. one without working copy) and push the temp repository to it.

1
2
3
4
5
6
7
git init --bare ~/new-bare.git
cd ~/new-bare.git
git symbolic-ref HEAD refs/heads/trunk
cd ~/temp
git remote add bare ~/new-bare.git
git config remote.bare.push 'refs/remotes/*:refs/heads/*'
git push bare

6. Rename the trunk to master

1
2
cd ~/new-bare.git
git branch -m trunk master

7. Migrate the SVN tags

Since git-svn matches the tags to branches, a final step is necessary to migrate the tags to the proper Git format.

1
2
3
4
5
6
7
8
cd ~/new-bare.git
git for-each-ref --format='%(refname)' refs/heads/tags |
cut -d / -f 4 |
while read ref
do
    git tag "$ref" "refs/heads/tags/$ref";
    git branch -D "tags/$ref";
done

8. Push the bare repository to Bitbucket

I am assuming here that you have an account on Bitbucket, but the following should work on any Git hosting provider of your choice (Github, etc…)

Time to switch resources, and head to Neogregious for the final steps.

Create a new repository (let’s call it, originally, myapp) on Bitbucket and get the “Clone this repository” information (probably something like $ git clone git@bitbucket.org:yourname/myapp.git or $ git clone https://yourname@bitbucket.org/yourname/myapp.git depending on whether or not SSH keys have been enabled or not).

1
2
3
cd ~/new-bare.git
git remote add origin git@bitbucket.org:yourname/myapp.git
git push -u origin --all

The last command pushes all branches to the new repository on Bitbucket. However, tags are not pushed in this case. To do this, simply run:

1
git push --tags

9. Remove temporary folders

You can clean up the folder used until pushing to Bitbucket.

1
2
rm -rf ~/temp
rm -rf ~/new-bare.git

I hope I haven’t forgotten anything. If this is the case, simply reach out to me, and I’ll edit it.



For the time being, comments are managed by Disqus, a third-party library. I will eventually replace it with another solution, but the timeline is unclear. Considering the amount of data being loaded, if you would like to view comments or post a comment, click on the button below. For more information about why you see this button, take a look at the following article.