Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I migrate an SVN repository with history to a new Git repository?

People also ask

Which migration is actually recommended for migration from SVN to Git?

When moving to Git from another version control system like Subversion (SVN), we generally recommend that you perform a "tip migration", which migrates just the latest version of the repository contents, without including history.

What is SVN migration?

SVN is a popular tool for code hosting. It is used to manage different versions of files like source code, documentation and more. It keeps history and project data. Subversion is an open-source tool and comes under the Apache License.


Create a users file (i.e. users.txt) for mapping SVN users to Git:

user1 = First Last Name <[email protected]>
user2 = First Last Name <[email protected]>
...

You can use this one-liner to build a template from your existing SVN repository:

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

SVN will stop if it finds a missing SVN user, not in the file. But after that, you can update the file and pick up where you left off.

Now pull the SVN data from the repository:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

This command will create a new Git repository in dest_dir-tmp and start pulling the SVN repository. Note that the "--stdlayout" flag implies you have the common "trunk/, branches/, tags/" SVN layout. If your layout differs, become familiar with --tags, --branches, --trunk options (in general git svn help).

All common protocols are allowed: svn://, http://, https://. The URL should target the base repository, something like http://svn.mycompany.com/myrepo/repository. The URL string must not include /trunk, /tag or /branches.

Note that after executing this command it very often looks like the operation is "hanging/frozen", and it's quite normal that it can be stuck for a long time after initializing the new repository. Eventually, you will then see log messages which indicate that it's migrating.

Also note that if you omit the --no-metadata flag, Git will append information about the corresponding SVN revision to the commit message (i.e. git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

If a user name is not found, update your users.txt file then:

cd dest_dir-tmp
git svn fetch

You might have to repeat that last command several times, if you have a large project until all of the Subversion commits have been fetched:

git svn fetch

When completed, Git will checkout the SVN trunk into a new branch. Any other branches are set up as remotes. You can view the other SVN branches with:

git branch -r

If you want to keep other remote branches in your repository, you want to create a local branch for each one manually. (Skip trunk/master.) If you don't do this, the branches won't get cloned in the final step.

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same names

Tags are imported as branches. You have to create a local branch, make a tag and delete the branch to have them as tags in Git. To do it with tag "v1":

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

Clone your GIT-SVN repository into a clean Git repository:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

The local branches that you created earlier from remote branches will only have been copied as remote branches into the newly cloned repository. (Skip trunk/master.) For each branch you want to keep:

git checkout -b local_branch origin/remote_branch

Finally, remove the remote from your clean Git repository that points to the now-deleted temporary repository:

git remote rm origin

Magic:

$ git svn clone http://svn/repo/here/trunk

Git and SVN operate very differently. You need to learn Git, and if you want to track changes from SVN upstream, you need to learn git-svn. The git-svn main page has a good examples section:

$ git svn --help

Cleanly Migrate Your Subversion Repository To a Git Repository. First you have to create a file that maps your Subversion commit author names to Git commiters, say ~/authors.txt:

jmaddox = Jon Maddox <[email protected]>
bigpappa = Brian Biggs <[email protected]>

Then you can download the Subversion data into a Git repository:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

If you’re on a Mac, you can get git-svn from MacPorts by installing git-core +svn.

If your subversion repository is on the same machine as your desired git repository, then you can use this syntax for the init step, otherwise all the same:

git svn init file:///home/user/repoName --no-metadata

I used the svn2git script and works like a charm.