Migrate an SVN repository to TFS

It’s no secret that I’m a big fan of Microsoft’s Team Foundation Server (TFS.) It is a complete tool for managing an application throughout its lifecycle. However I was bought up (and learnt most of my programming skills) on open-source software. It’s important to me that I don’t forget my roots!

While TFS is a fantastic tool for commercial application lifecycle management, SVN (Subversion) also has its place in corporates. It’s free and has lower training overhead: perfect for companies that don’t need anything other than source control (or use other tools.)

Over the last few years, a new kid has burst onto the scene: Git. The popularity of Git has exploded thanks to hosting services such as Github and Bitbucket and its wide adoption in IDEs. It is fast becoming the defacto standard for source control. It supports remote/offline working, better collaboration (pull requests, flexible branching) and is cross-platform.

In this article I’m going to teach you how to migrate an SVN repository (including all its history) into TFS using a Git repository.


You will need:

  • Access to TFS 2013 or above, or Visual Studio Online
  • Visual Studio 2013 or above
  • Git installed on your client machine (the Git command-line tools for Visual Studio work nicely)
  • An SVN repository to migrate!

My theory is that Git includes native SVN support. It acts as a bi-directional “bridge” between an SVN repository and a Git repository. TFS 2013+ supports storing code in Git repositories (instead of the previous TFVC format) therefore we can use Git-SVN to import our revisions from SVN and push them as changesets into your Git repository in TFS!

TFS and Visual Studio 2013 were the first server and client versions to support Git. Git is our central point for this operation. It is therefore essential you have TFS and VS 2013 or later.

Once you have the above pre-requisites installed, the process is relatively simple. It can take anywhere from a minute to hours depending on the size of your SVN repository and the number of revisions. The whole process took a couple of minutes on my 44-revision sample repository.

Note: I’m using Visual Studio and TFS 2015, so the screenshots may look slightly different in 2013 and Visual Studio Online.

[adrotate group=”4″]


Step 1 – Create a TFS project with a Git back-end

TFS On-Premises

Open Visual Studio and select the “Team Explorer” tab. Connect to your TFS server and click the drop-down menu selector. (It will say something like “Home”, with an arrow on the far right.)

Point to “Projects and My Teams” and click “New Team Project”.

Follow the wizard through selecting the options relevant to you. Ensure you select the “Git” option on the “specify source control settings” page. The default option is pre-selected as “Team Foundation Version Control,” which won’t work.

Once you have completed the wizard, hit Finish to create your new project and repository.


Visual Studio Online

If you are using Visual Studio Online (the cloud-hosted version of TFS) it will look slightly different – the wizard is only a single page.

Click the “New” link under “Projects & Teams” and complete the form. Make sure to select “Git” as your version control system:

When the wizard has finished, click the “Navigate to Project” button. Click the “Open in Visual Studio” link.

[adrotate group=”4″]

Step 2 – Check out your new project

Still within Team Explorer, select the “Clone this repository” link.

Provide a location in which to store your check-out. Make sure you know where this path is, as you will need it for step 3. Copy and paste it into Notepad if you need to.


Step 3 – Import the revisions from Subversion

The third step is to use Git-SVN to import the revisions from Subversion. There is no UI for this in Visual Studio, so we’ll use the command-line. Don’t worry, it’s straight-forward!

Note: you only need remote access to the SVN repository. You don’t have to check it out to your machine.

Open a command prompt window and change into the directory you noted in step 2.

cd \TFS\Andys Git Project

Next, we need to “initialise” the link between Git and SVN:

git svn init <url to your SVN repository>

This sets up the mapping and configuration so subsequent Git-SVN commands know where to find your SVN repository.

Finally – begin the import:

git svn fetch

You should see all your files being transferred across. Git-SVN is effectively replaying your SVN history revision-by-revision. This may take a while depending on how many revisions you have, the size of the changes and the number of files.

At this point, you can now inspect the files that have been migrated in your Git working copy. It’s a good idea to open your solution in Visual Studio and check it builds. Nothing has been committed to TFS yet, so this is an ideal time to make sure everything works.

Note: you can repeat the above command at any time (on the same Git checkout) to pull in newer changesets from SVN. This is perfect to test it out, then you can “switch over” at any point by everyone checking out from (and pushing back into) TFS instead of SVN.

[adrotate group=”4″]

Step 4 – Push to TFS

Now the exciting bit – it’s time to finally get your SVN code (and history) checked in to TFS. This is a standard git operation (push) so it can be performed from the command-line (“git push.”) Alternatively you can use the “Sync” option in Visual Studio.

Note: you will get actual usernames in your history – I’ve removed them from my screenshots for confidentiality.

In your TFS web access (http://your-server:8080/tfs) you can browse your source code, see a full history of your commits, and even see differences in any commit we just imported!



The comments shown below have been left on this article.

Why not join in the discussion?

  • Reply

    Joe says

    27th February 2017 at 9:18 pm

    Andy, can this be placed into TFVC instead of TFS/Git…?

    • Reply

      Andy Heathershaw says

      18th March 2017 at 7:06 pm

      Unfortunately not, the Git-to-SVN tool is part of the Git library.

  • Reply

    Ed says

    30th June 2017 at 3:54 pm

    Great Tutorial, thanks. Did get a little confused with
    cd \TFS\Andys Git Project
    Which looked a little UNIX like, but further up you have C: prepended.

    Thanks so mush

  • Reply

    Teresa says

    31st July 2017 at 8:55 pm

    Very good information, I did get the SVN migrated to my local folder, however not in the TFS. When I bring up the url from VS2015 and trying to push it to TFS , yet the “PUSH” link is disabled and said there are no outgoing commits. I do not understand how to get the migrated code to commit to TFS. Please help. I am so close to get it. I am a .net developer and this is first time to use SVN and Eclipse. My purpose is to have the SVN moved to TFS and then check out the project from Eclipse.

  • Reply

    Magnus says

    9th August 2017 at 3:01 pm

    When running git svn fetch I get this error:

    0 [main] perl 35652 child_info_fork::abort: unable to map C:\Program Files
    \Git\usr\bin\msys-svn_subr-1-0.dll, Win32 error 1114
    open2: fork failed: Resource temporarily unavailable at /mingw64/share/perl5/sit
    e_perl/Git.pm line 412.

    Anyone knows a solution?

  • Reply

    Ahmed Abdo says

    10th December 2017 at 12:25 pm

    Very helpful Andy,
    you save may day
    Thank you

  • Reply

    Rick says

    16th March 2018 at 2:42 pm

    We are having the same problem as Teresa. We get through all the steps up to the last Push step, but there is no active push link and trying the push from the command line doesn’t work. We are not familiar with git at all so we don’t know the right commands for the git command line. We are just trying to move a rather large SVN repository to TFS 2015.


  • Reply

    Anthony Dimas says

    12th April 2018 at 9:47 pm

    Im getting an error when I run the following command, any assistance would be awesome.

    git svn fetch-
    Authentication realm: VisualSVN Server
    Password for ‘Domain\UserID’: ReadKey.c: loadable library and perl binaries are mismatched (got handshake key 0xde00080, needed 0xe080080)

    • Reply

      Andy Heathershaw says

      12th April 2018 at 10:20 pm

      Looks like git is finding a library/Perl binary different to that which it was compiled against. Do you have Perl installed separately, as well as Perl? What platform/Git version are you on?

  • Reply

    Anthony says

    12th April 2018 at 11:36 pm

    I was able to resolve that issue, but now I have run into a different issue after the git svn fetch completed it returned this error:

    fatal: refs/remotes/origin/trunk: not a valid SHA1
    update-ref HEAD refs/remotes/origin/trunk: command returned error: 128

  • Reply

    Vidya Nikam says

    18th May 2018 at 2:11 pm

    Well, Git does not support empty directory if you have any in SVN repository …
    Do you know the way , how to migrate SVN to TFVC repo instead of Git ?

    Thanks ,
    Vidya .

    • Reply

      Andy Heathershaw says

      18th May 2018 at 6:38 pm

      I don’t unfortunately Vidya, unless there are any tools that integrate with the TFVC web services. My approach used the git-svn extension which is native to the Git library.

  • Reply

    swabha says

    24th September 2018 at 3:53 pm

    Well, we are getting an error with git svn fetch
    Can’t create session: Unable to connect to a repository at URL ‘http://s0df09f.ba.ad.ssa.gov/!/%23IMGateway/view/head/trunk’: The XML response contains invalid XML: Malformed XML: no element found at /mingw64/share/perl5/site_perl/Git/SVN.pm line 148.
    Anyone have this issue, Please need your thoughts and solutions

    • Reply

      Andy Heathershaw says

      24th September 2018 at 7:03 pm

      Are you sure that’s the URL to your SVN repository itself and not a web interface that shows you the repository contents (like viewSVN?) If you put that URL into something like TortoiseSVN does it show you the repo’s contents?

Leave a Comment

Your email address will not be published. Required fields are marked with *.

Enter your email address (won't be used for anything naughty!)
This must be an external URL such as http://example.com.

This site uses Akismet to reduce spam. Learn how your comment data is processed.