Monday, 30 September 2013

TFS 2010 to SVN Migration

Brief introduction

Migration between TFS to SVN can be quite challenging as there are no tools* that I could find that actually work smoothly with Team Foundation Server 2010 and SVN. This brief how-to assumes that you know your way around Linux/SVN and TFS. 

* I have only found one tool for this tfs2SVN however it is heavily outdated and it hasn't been much use with Team Foundation Server.

Instead I have split this migration process into two.
  1. Migration from TFS to GIT - using GIT-TF
  2. Migration from GIT to SVN - using SubGit

Requirements for migration

  1. Linux box (Ubuntu) for SVN hosting (this is vanilla install purely for SVN hosting)
    1. SVN installed on Linux box
    2. GIT installed on Linux box
    3. GIT-TF (download ZIP file and chmod +x on git-tf file)
    4. SubGit (see Debian/Ubuntu section in Download for repository - otherwise ZIP is fine)
  2. Windows Server - Team Foundation Server 2010

Business requirements

  1. History of all file changes as well as who has made them need to be migrated.
  2. Some configuration (that only relates directly to TFS such as builds - we have migrated to Jenkins instead but that's not part of this how-to).
  3. Some cleaning and re-organizing repositories might be required to align it more with SVN standards.

Migration procedure

Migration from TFS to GIT

  1. Download & Unzip GIT-TF somewhere in your home directory (any directory will do). 
    1. In this example "/home/luke/gittf/git-tf-2.0.2.20130214"
    2. Make sure you "chmod +x on git-tf"
  2. Create a folder where you will keep your Git repository
    1. In this example I have ran following "mkdir /disk2/git/dnd" to create folder
  3. Run git-tf
    1. Run "/home/luke/gittf/git-tf-2.0.2.20130214/git-tf clone --deep http://tfs-server:8080/tfs/DnDCollection $/"
    2. Replace URL with your TFS URL. Also you can specify single project by changing "$/".
    3. This will prompt you for your username and password you need to connect to TFS.
  4. This step will take quite a while. This particular collection took over 48 hours.
  5. Test if all check ins are there by running "git log".
  6. Run "git status" to see if any files have been changed in the process. This should show you no pending changes to be commited. My git repository showed some files with extra character (hidden character) so I ran "git reset --hard" to discard all changes and get repository as its checked in.
Few notes;
  • Your developers can still use TFS as normal (it will be however slower). Simply once your clone is done you can run git-tf pull to get it up to date.
  • Make sure you run --deep otherwise only last checkin will be pulled from TFS.
  • More documentation here GIT-TF Documentation

Migration from GIT to SVN

To clean SVN repository
  1. Use aptitude to install SubGit
    1. Follow steps on SubGit to download and install SubGit on Ubuntu/Debian
  2. Create empty SVN repository (only if you don't already have one)
    1. In this example my SVN repository will sit in /disk2/svn/dnd to create it I ran
    2. "svnadmin create /disk2/svn/dnd
  3. Setup SubGit
    1. Go inside DND SVN repository by entering "cd /disk2/svn/dnd"
    2. Run "subgit configure"
      1. It will prompt you that new configuration file has been created and you will be required to modify it.
    3. Change settings to associate your repository with Git repository
      1. Open /disk2/svn/dnd/conf/subgit.conf by running "vim /disk2/svn/dnd/conf/subgit.conf"
      2. Find "[git "default"]" section.
      3. Change repository = .git to point to your location. In this case "repository = /disk2/git/dnd/.git"
    4. If your repository is customized you can modify trunk, branches, shelves and tags. I have left this with default settings. See SubGit Documentation for more information.
    5. If you are using existing SVN installation and you just want to migrate your TFS as a subproject then modify translationRoot. Eg. if your SVN already has folder called Clients\[Projects] then setup your translationRoot folder to be "translationRoot = /Clients/
  4. Run migration
    1. Run "subgit install" - it will pop up with progress bar.
    2. This takes a lot less than TFS to GIT. In this particular example it took about 2 hours.
  5. Test your SVN repository to make sure that all Logs are there and you can successfully checkout/commit etc.
  6. SubGit create tags folder with every single check-in in TFS showing as separate tag - I have simply removed it. I appears to be a biproduct of double migration. 
Addition to existing SVN repository
  1. Use aptitude to install SubGit
    1. Follow steps on SubGit to download and install SubGit on Ubuntu/Debian
  2. You will be required to have Bare GIT repository - to create one all you need is
    1. Move .git folder out of your git repository eg. mv /disk2/git/dnd/.git /disk2/git/dnd.git
    2. Then you need to mark it bare with "git config --bool core.bare true"
    3. See http://stackoverflow.com/questions/2199897/how-to-convert-a-git-repository-from-normal-to-bare for more info on this.
  3. Configure your dnd.git to be connected to SVN
    1. Run " subgit configure --svn-url http://svn.yoururl.com/yourfolder dnd.git"
      1. Your folder is any path that you want your git to be migrated to. Make sure it doesnt exist yet.
      2. Modify /disk2/git/dnd.git/subgit/passwd with your username and password for SVN. (if you require authentication for your repository)
  4. Go to physical location of your SVN repository and add a hook to enable all information to be migrated (such as authors of each check-in)
    1. In this example my SVN is under /disk2/svn/dnd
    2. Go inside /disk2/svn/dnd/hooks with "cd /disk2/svn/dnd/hooks"
    3. Create new file with "touch pre-revprop-change"
    4. Open it for editing "vi pre-revprop-change"
    5. All it needs to do is to return true - ie. exit with 0
      1. Follow http://subgit.com/book-remote/index.html#N2038E (section 5.8) for exact content of the file.
    6. Make sure you run "chmod +x pre-revprop-change" otherwise it will not be executed!
  5. Run "subgit install /disk2/git/dnd.git"
  6. Wait for the process to complete. 
  7. Test your SVN repository to make sure that all Logs are there and you can successfully checkout/commit etc.
  8. SubGit create tags folder with every single check-in in TFS showing as separate tag - I have simply removed it. I appears to be a biproduct of double migration. 

Disclaimer

Please follow this procedure at your own risk. I strongly recommend doing a test run on empty TFS collection with empty SVN repository. I'm not responsible for any loss of data or damages caused by tools or procedures in this How-To.

Sunday, 8 September 2013

ASP.MVC failed after deployment - works fine on my local!

I have been working on a site for a while that has been working fine on our local dev machines as well as our CI (DevTest). However, when I have deployed it to production it exploded with 

Server Error in '/' Application.
Could not load file or assembly 'System.Web.Mvc' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Solution

This will make sure all DLLs that are required at run-time are included with the assets, therefore you will NOT need to install MVC3/4 on production server.
  1. Open your Solution (*.sln file)
  2. In each of the projects that use "MVC" open "Reference" 
  3. Right click System.Web.Mvc and select Properties
  4. Change "Copy Local" to True
  5. Save solution and rebuild.
  6. Check Bin folder for System.Web.Mvc.dll
Note: Dependable on what other parts of MVC you use you might also need following DLLs 
  • Microsoft.Web.Infrastrucutre.dll
  • System.Web.Helpers.dll
  • System.Web.Razor.dll
  • System.Web.Webpages.dll
  • System.Web.WebPages.Deployment.dll
  • System.Web.WebPages.Razor.dll