UPDATE: there is git-tfs now, no need to bother with this post

I'm on a mission to ease the pain dealing with some of the quirks of TFS. I've kind of reversed my previous strategy, which boiled down to synchronizing my TFS working copy to an offline working copy managed by git. It didn't feel right, and turned out to be quite unworkable. I'm trying another way now, which is to manage my TFS working copy also with git.

Initializing git:

git init
git add *.csproj *.cs [+ other file types]
git commit -m "initial commit"

This created the master branch with a bunch of files in it. I also added a .gitignore file with all patterns, files and folders I don't want to manage in git (*.suo, *.resharper, *.user, bin, obj etc). Then I created a working branch in which I will be able to do intermediate checkins of unfinished work.

git branch working
git checkout working

Now when changing stuff inside this working copy, I still have to make sure everything is properly checked out from TFS, that doesn't change. But I don't really care anymore since I now use git for checking the status of my work (git diff and git status are your friends). There are 2 operations that need attention: updating my working copy with the changes from other team members, and committing my own changes to the TFS repository.

tfs2git

To update my working copy from TFS, first I make sure everything is committed in my git working branch (git commit -a -m "some meaningful comment"). Then I take the following steps:

git checkout master
tf get . /recursive
git commit -a -m "synchronize from TFS"
git checkout working
git merge master

Now this deserves some more explanation. First, I make sure to commit my work into my local git repository (working branch), so everything is nice and clean. Then I switch back to my master branch, which reverts all my own changes w.r.t. the situation as it is currently on the TFS server. So I'm left with a bunch of checked out but unchanged files. Then, I can easily do a 'tf get' to get the latest version (without merge problems). After committing these changes to the git master branch, I switch back to the working branch and leverage the powerful git merge function to merge the TFS changes with my own.

git2tfs

After resolving possible conflicts, when I'm ready to check in my changes to TFS, I first merge my changes into master:

git checkout master
git merge working

Now I'm on my git master branch and can check in into TFS.