zobie's blog I create software, I like music, and I'm mildly(?) OCD.


Using git to avoid problems with TFS

For the past few months I've been using Team Foundation Server (TFS) at work. I'm certainly not a TFS expert; I probably don't even quality as a power-user. But I've used TFS enough to have found a handful of things that I like about it. Revision control is not among those things.

As a software version control system, I dislike TFS intensely.

In the short time I've been using TFS I've had several problems with code that was merged incorrectly. I've seen problems where TFS silently allowed older versions of code to overwrite newer versions. I could probably fill an entire blog post airing grievances with TFS but I thought it would be more interesting to describe how I use git on top of TFS to solve some of these problems.

First, to use git to track a TFS repository it is really important that all your source code be on a Fat32 partition. TFS locks files and NTFS respects that lock. Fat32 will track the lock but doesn't enforce it. This allows git to modify files (change to different versions of files) without necessarily having those files checked out in TFS.

Using TFS I checked out all my code into s:\src. I then created a new git repository in that same directory and added everything into the git repository.

For working I maintain at least two branches. My master branch always matches TFS. When I need the latest code from TFS I switch to the git master branch, pull from TFS then commit all changes into git. My working branch contains my current code changes. I also have one branch dev that contains a single commit consisting of all my debug code that should never be checked in to TFS.

When I'm ready to start coding I get the latest code from TFS and commit those changes into git's master branch. I create a new git branch, working. I cherry pick my development code from dev into working. Then I do all my coding on that branch. When I need to get code from TFS I can swtich to master, update from TFS, check that code in to git then either merge or rebase the changes back into working.

Once all of my changes in working are complete I need to merge the changes back into master so that I can commit them to TFS. I can't do a straight merge becuase my cherry-picked dev code would be included. So I have two ways of doing this:

  1. cherry-pick changes from working, applying them to master
  2. backout the development code (using git rebase -i) then merge changes back into master

After going through one of these two options I end up back on master with all of my code changes. I then commit the changes to TFS. Once that is done I delete working and recreate it from master next time I need it.

Working like this has been great for me. If there are conflicts when merging my code changes, git takes care of it. This way I can almost always avoid having to let TFS merge anything.

This is my general way of working but you can easily see how to apply these same principles when you want to work on multiple different changes using multiple different branches in git.

One thing to note: When you're working like this git's history isn't great. This isn't like git-svn where you get a seperate git revision for every svn revision. For me, using git with TFS isn't about being able to track my changes over time. I just want to make sure that my changes aren't lost and I don't want to clobber anyone else's changes.

Comments (10) Trackbacks (1)
  1. I haven’t tried that.

    Catherine Sea

  2. Neat idea. I’ve been wanting to use git on top of TFS but haven’t gotten around to it. Thanks for the tip on getting around the locks.

  3. Interesting. I am doing the same thing with Mercurial right now. I like Mercurial for this task because there is good windows support in TortoiseHg, and Mercurial Queues works out well for the task of keeping local customizations etc. I know there is patch queue management for git as well, so that might be effective for you to avoid having to do manual cherry picks or rebases.

    Now how do you handle checkins where another developer has chosen to lock a file?

    • In my organization we try not to lock files unless necessary (i.e. for major changes). When that happens I just try to avoid those files until they’ve been unlocked.

  4. Wouldn’t it be easier to install svn bridge to give you an svn front end to TFS and then use git-svn?

    • I thought about taking this approach several months ago but found several people (just via googling) who had bad experiences using TFS via svn. I don’t remember the exact problems that I read about and I never tried it myself. Have you been able to successfully use the svn bridge like you’ve described?

  5. this is awesome, but i heard windows 7 doesn’t support Fat32.. Any work around that you know of?

    • Windows 7 and Windows Server 2008 R2 both support Fat32 just fine. I’ve been successfully using the method described in this article with both of those OS’s.

  6. Alternatively, you can also have your git and TFS paths in a separate folder, and use WinMerge to avoid locking issues. I use this method successfully with SourceSafe.

  7. Have you seen this?

    Someone is working on a git-tfs similar to git-svn. Would love to hear how it’s working from someone that could actually use it now.

Trackbacks are disabled.