Using P4Merge with Team Foundation Server
I’ve found that the best way to deal with merging is to avoid it completely! Unfortunately that is rarely realistic. So, assuming you don’t want to take any radical measures to completely avoid merging in TFS, you should at least use the best tools available. My favorite merge tool is the freely available (and cross-platform) P4Merge.
Getting TFS to use P4Merge isn’t difficult but neither is it intuitive. For a merge operation P4Merge expects four files to exist:
- the original, base file
- file with conflicting change #1
- file with conflicting change #2
- final, merged file
Unfortunately TFS doesn’t create the merged file (#4) until after the merge tool is invoked. A simple batch script will solve the problem though. Save this as p4merge.bat.
@ECHO OFF COPY /Y NUL ""%4"" START /WAIT /D "C:\Program Files\Perforce\" p4merge.exe ""%1"" ""%2"" ""%3"" ""%4""
This script will create the merge file and invoke p4merge.exe.
Now you can configure TFS to use P4Merge by running this command from a Visual Studio command prompt: tf diff /configure
That will bring up a dialog:
If an entry already exists for the Merge operation you can add it. Otherwise just modify the existing entry to point to the batch file we created:
Note that you must set the command to be your batch file, not the executable.
And that’s it! Next time TFS launches a merge tool, it will use P4Merge.
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:
- cherry-pick changes from
working, applying them tomaster - backout the development code (using
git rebase -i) then merge changes back intomaster
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.
Thoughts on Doing Contract Work as a Software Developer
As I was recently looking for new employment I spent quite a bit of time deciding wether I might enjoy doing contract work full-time. I enjoy working on different projects and learning new things but there is one major roadblock to becoming a full-time contract developer. My personality doesn’t let me write software that is anything less than my best.
WARNING: Gross generalizations and simplifications below. I’m not trying to offend anyone, just describe my experiences.
Most of the contract work I’ve done has been for people who are not technically savvy. They come to me with a very vague idea of the software they want. They expect me to tell them how much it will cost before we’ve discussed specific requirements. When the requirements are incomplete or incorrect they expect that I’ll just fix it without additional cost to them.
Not all of my contract experience has been negative. In fact, most of it has worked out quite well. Usually both my client and myself are pleased with the software and the cost of building it. But I’ve had enough negative experiences to be careful when considering a new job.
Part of the problem is that it is nearly impossible for anyone to completely define the scope of a project. There is always some miscommunication or misunderstanding, there is always some unforseen problem.
“You want me to setup a blog for your company? No problem, I can get WordPress setup for you in an hour.”
“Wait, I didn’t realize that by ‘blog’ you meant store front application that can accept payments, handle accounts payable, accounts receivable and inventory tracking. That will take slightly more than an hour.”
That kind of situation actually isn’t bothersome to me. As a contractor it is part of my job to understand what you want before making a bid. If a potential client obviously doesn’t know what they want, I can either decline to bid on that job or I can adjust my bid to account for a large amount of unknown. I don’t love it, but that type of risk is manageable.
The part of contract work that I dislike is being forced to compromise quality. When I’m working on a fixed cost contract, it is in my best interest to deliver exactly what is specified, as quickly as possible. As long as my client is reasonably happy with the deliverable, I am going to get paid $20k regardless of whether it took two days, two weeks or two months to create. I don’t get additional money for clean code. I don’t get extra for having good test coverage.
When I complete a project more quickly than I had anticipated there is no problem. I can spend time verifying that the code is tight and that everything is working as expected. But if I am running behind schedule, it becomes more difficult to care about testing the code or fixing “little” bugs.
There may be a bug in the code where order totals aren’t calculated correctly, but what are the odds that my client will notice the bug before he signs off on the project? If he does find the problem and I correct it, will he think to test for that same bug in every release?
This is the dilemma that makes contract work difficult for me. If I see a bug in my code, I’m going to fix it. If I’m writing a tricky or important calculation (like calculating totals), I’m going to write a test. I need to have confidence that my code is doing what I expect. I’ve never shipped any software that didn’t have a list of known bugs but I have also never shipped any software in which I didn’t have a high level of confidence that it was working correctly.
For me, doing the bare minimum isn’t an option for two reasons:
- Quality is extremely important to me. I can’t just hack something together that meets the contract requirements. When I write software, I want to deliver my personal best.
- Most of the time, the fast/crappy way of implementing something simply doesn’t occur to me.
I understand a company’s need to understand cost before approving custom softare. But if you want me to do contract work, pay me on an hourly basis. I’ll give you a projected timeline for project completion.
With an hourly rate, you only pay me for the time I actually spend working. With an hourly rate I know that I won’t lose money just because I insist on high-quality code. We’ll both be happier in the long run.
The Rest of My Development Environment
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
- Instruments
- 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
- vim
- screen
- Photoshop
- iTunes to help keep me in The Zone!
Web Development Environment
During 2008 I spent most of my time doing web development. There was some Java, PHP and Python, but most of my time was spent working in Ruby on Rails. Rails is a lot of fun and (I know this sounds cheesy, but…) it helped me to enjoy doing web development again.
When I’m working in Java I always prefer to use JetBrains’ excellent IntelliJ IDEA. However, this past year I didn’t have a license for IntelliJ. I tried every free IDE I could find and wound up choosing Eclipse. I’ve used Eclipse periodically over the last several years. I don’t really like it but I dislike it less than the other free alternatives.
My work was completely server-side and didn’t involve developing a database component. Most of my development was done on OS X but I was deploying to Ubuntu so I did work there also. I used maven to build, test and deploy. I’m not a unit-test fanatic but, in this case unit testing was invaluable.
My setup for both PHP and Python is the same. When I’m working on Mac I use either TextMate or vim. I haven’t done a great deal of Python work but over the past several years I’ve tried to find a PHP IDE that I like… I’m still looking.
I started out doing my Ruby work using TextMate and Terminal.app. I didn’t have any major complaints. There are some nice plugins and various tricks that are handy. But personally, I prefer an IDE. I’ve heard some people say that IDEs make us lazy. Ok, I’m lazy. But I’m also far more productive when I have a good IDE. When JetBrains started issung beta releases of RubyMine, TextMate was history!
RubyMine’s GUI for easily stepping through code in the debugger is great. The inline code analysis is nice for quickly catching typos and the code completion can be useful too. But for me, the best part about having RubyMine is the navigation and documentation.
When I’m working with other developers (or even with frameworks that I didn’t write), I don’t always know exactly what a method does. Being able to instantly bring up documentation is awesome! If I need more information, I hate wasting time trying to hunt down a method buried in code that I am not familiar with. With one key-stroke RubyMine takes me to the code I’m looking for.
I am definitely a fan of JetBrains’ production. IntelliJ is awesome, RubyMine is awesome, and VisualStudio is just broken without ReSharper. There is certainly a learning curve to these tools but once you’ve memorized the key strokes, the code you need is always right in front of you. And the best part part is that the key bindings are the same across each of JetBrain’s products!
One last application that deserves to be mentioned is Navicat. Navicat is by far the best application that I’ve found for working with MySQL or PostgreSQL. Unfortunately, that’s not saying much. I have spent a lot of time using SQL Server and Microsoft’s related tools and, as far as I can tell, there is nothing for MySQL that is even in the same league.
Don’t misunderstand me. Navicat is a great tool. Allowing me to save connections to different servers with many different login credentials is a lifesaver, especially the ability to tunnel the connections over ssh. Being able to do basic server management via a GUI is nice too. But when I need to design a database, I always turn back to SQL Server Management Studio.







