Tarin Gamberini

A software engineer and a passionate java programmer

How to migrate from svn to git

Migrating from subversion to git mainly consists in creating a temporary local git repository from the remote svn repository and then pushing such temporary git repository to a new remote git one.

It is warmly suggested to perform the migration on a case-sensitive file system, otherwise the migration process might end up in a not correctly transformed git repository, as reported from the following discussions.

A case-preserving file system is not sufficient, since giving two
files differencing only the case of their names (such as foo\bar.txt
and Foo\Bar.txt), trying to retrieve either file by name would always
return the same file. (For example looking up foo\bar.txt or
Foo\Bat.txt would always return the same file, for example
foo\bar.txt). As a result, git-svn will merge the history of one file
into the other during the conversion to Git.

Microsoft Windows hasn’t a case sensitive file system:

For info, FAT and its variations are not case-sensitive. NTFS is
case-preserving but not necessarily case-sensitive depending on
whether you interact with it through the Win32 or the POSIX
subsystem: see KB-100625 and Case preservation.

OS X file system hasn’t a case sensitive file system:

OS X partitions are by default case-preserving but not case-sensitive.
You either need to create a new partition and make it case-sensitive or
re-think your naming strategy.

Preparatory work

Some preparatory work is needed before starting with the migration. It consists in creating a temporary local git repository from the remote Subversion repository. Therefore you have to know about:

  • Mapping authors
  • Cloning SVN repository
  • Ignoring what SVN ignores

I have yet described these steps in the post The best of Git using svn, so I invite you reading it and than continuing with this post.

Cleaning up the temporary local git repository

At this point you should have created your temporary local git repository and you should be in that directory:

$ cd temporary_local_git_project
temporary_local_git_project

Such git repository doesn’t “mirror” Subversion branches and tags. In fact the git svn clone command has imported svn branches as remote branches and svn tags as remote branches prefixed with tags/. In order to transform them in actual git tags and branches you have to run:

$ cp -rf .git/refs/remotes/origin/tags/* .git/refs/tags/
$ rm -rf .git/refs/remotes/origin/tags
$ cp -rf .git/refs/remotes/origin/* .git/refs/heads/
$ rm -rf .git/refs/remotes/origin

At this point checkout if tags and branches that you expect should exist are correctly listed running git branch and git tag.

You should find the trunk branch but you can safely delete it because it has been imported into the master yet:

$ git branch -d trunk

Likewise you can delete:

  • svn branches correctly reintegrated into svn trunk but “resurrected” by the cloning process
  • branches with a peg revision: branches which name ends with an “at” followed by an integer number (for example: trunk@1234). Peg revision is a Subversion feature which hasn’t a corresponding one in git; therefore you can delete them if you don’t need them anymore

Creating a remote git repository

Now you have to create a new remote git repository, for example on github, and suppose it is located at URL https://github.com/your-user-name/your-git-project. Now add the remote repository calling it locally origin:

$ git remote add origin https://github.com/your-user-name/your-git-project

Pushing to the remote git repository

Finally you have to push all branches and tags from the temporary local git repository to the remote one:

$ git push origin --all
$ git push origin --tags

As a last thing check if the remote git repository has been correctly created. Change to another directory and clone the remote git repository:

$ git clone https://github.com/your-user-name/your-git-project

verify if your branches and tags are correctly listed:

$ cd your-git-project
$ git branch
$ git tag

and if your precious history has been migrated too:

$ git log

Reference

Post a comment

A comment is submitted by an ordinary e-mail. Your e-mail address will not be published or broadcast.

This blog is moderated, therefore some comments might not be published. Comments are usually approved by the moderator in one/three days.