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
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
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:
- cherry-pick changes from
working, applying them to
- backout the development code (using
git rebase -i) then merge changes back into
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.
As a professional software developer the vast majority of my experience has been working on C#.NET WinForm applications. I started using .NET shortly before the 1.0 framework was released. I can't remember if I ever did .NET development under Windows 2000; I generally use Windows XP. If you're wondering why I don't use Vista I have to assume that you've never tried Vista yourself. It's not good. I'm waiting for Windows 7 and hoping for the best.
The tools that I use for C#.NET are pretty standard:
- Microsoft Visual Studio 2008 (with ReSharper)
- SQL Server Management Studio
- .NET Memory Profiler to chase down memory leaks
- AQtime to help locate performance problems
- Outlook and Skype to stay connected to coworkers
- Team Foundation Server (TFS) for tracking work items and for version control
- cygwin to make the command line in Windows behave somewhat normally
The one thing that is sorta strange about how I do my C#.NET work is that I do everything on a Mac Pro with XP running in VMWare Fusion. I've had a similar setup at home for a couple of years but I've only had this setup at work since January.
There are definitely a few quirks that I had to get used to, working in Windows running in a VM on OS X. But the benefits of this setup far outweigh any inconvenience. The ability to take snapshots of the entire VM is awesome! If a program screws with my registry and Windows starts acting funky I just roll back to the last snapshot!
The other huge benefit to working in VMWare is memory. Unless you're using 64-bit Windows (which can be problematic for many reasons) you are limited to 2 GB of memory. Windows sucks at managing virtual memory so I always try to keep my open applications below that 2 GB limit. Since my Mac has 12 GB of memory, if I need to do something else, I can just boot up a second VM.
Most of the software that I've written for OS X has been personal projects. Nothing fancy, just various tools to scratch some itch. Since getting my iPhone I've been doing more work in Objective-C and Cocoa.
Because I've done so much work with managed and interpreted languages, it feels a little weird to work in unmanaged C/ObjC. But it is kinda cool too. Objective-C is a fairly simple language and Cocoa is a very nice framework. There are some things that I don't like about Obj-C (not having namespaces and gimpy string manipulation come immediately to mind) but I really appreciate being able to actually use Cocoa controls for UI work. It is almost unthinkable to do GUI development for Windows without buying a set of third-party controls.
My must-have software for writing Mac/iPhone applications:
- XCode and Interface Builder
- MacPorts to install all of the software that is missing from the base OS X install
- Mail.app, Syrinx, Adium and Colloquy to keep in touch with other developers
And finally, a few additional pieces of software that are invaluable to me. These are helpful regardless of what type of software I am writing.
- OmniFocus to help me Get Things Done
- git for source control (don't tell anyone but I keep my TFS repositories checked into git too)
- Terminal.app for a whole bunch of things
- PathFinder because Finder doesn't always cut it
- GeekTool to keep an eye on logs
- iTunes to help keep me in The Zone!