SVN to TFVC with History

That’s it we’ve made the switch to TFS! Now I’ve got to migrate over our SVN repos. These projects have been ongoing for a while and I don’t have the luxury of leaving behind our commit history. So I did some searching around on the web and found a FREE way to get this done. This is what worked for me.

The path we will be taking is to convert our SVN repo to a Git repo and then finally check in to TFS.
Required Tools:

  1. Tortoise SVN – If you are on Windows and using SVN you probably already have this. This tool is required because it also comes with svnserve which we will use to host the current SVN repository from a svn:// address.
  2. Git – The Git command line tools. Don’t forget to add the Git bin directory to your Environment Variables path variable so you can just type git in a command prompt without having to give the full path.
  3. Git-TF – Required to check in our Git repo to TFVC. Add this one to your Environment Variables as well.

Got everything installed? Great! We are ready to go:

  1. Open a command prompt and type the following:
    svnserve -d -R --root \\path\to\svn
    NOTE: This window will then look like it’s hung, don’t worry it’s hosting our repository now. Leave the window open and open another command prompt for the rest.
  2. We create the directory that will hold our Git repo and change our working directory to it:
    md git\repo\path
    cd git\repo\path
  3. We initialize an empty Git repo:
    git svn init svn://localhost/path/to/your/svn/project/folder --no-metadata
  4. Fetch all data from SVN into our Git repo (this command can take awhile depending on the size of your repo):
    git svn fetch -A authormap.txt
    Note: authormap.txt is a text file we create for the purpose of mapping authors. See documentation for the -A switch
  5. If step 4 fails or you need to stop it for any reason, re-enter the command and Git will resume where it left off.
  6. Now we configure Git-TF so it can connect to our TFS instance:
    git-tf configure "" "$/Your Project Name/Main" --username=MyAlternateUsername --password=MyAlternatePassword
    The reason why I user Main after the project name is because you can’t just dump your code into the root of a non-empty folder so you have to specify a folder name. I’ve also included the –username and –password switches so I can save my credentials to the repo so I don’t have to retype them in constantly. Just beware they are stored in plain text.
  7. Lastly run the last bit and your source will start getting checked in:
    git-tf checkin --deep --metadata --no-lock --keep-author
    Note: You may run into one more step after this if all the users in your Git repo cannot be mapped to TFS. If this does happen git-tf will generate a file that you need to alter to map the unmapped users and then you can enter the checkin command again.
  8. Done!

git-tf: item ‘some/file/path’ exists in commit xxxxxxx more than once with different casing. TFS does not support having the same item with different cases in the same path.

If you don’t need to check in this file you can purge it from history with the following Git command

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch some/file/path" --prune-empty --tag-name-filter cat -- --all

run the git-tf checkin command again to continue where you left off.


Leave a Reply

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