Friday, November 24, 2006

(Not) getting latest on check out - a bug?

Did you know that TFS will not automatically get latest version on check in? And what do you think about it?

In all probability, you know about that particular feature and roll with it (if you use TFS that is). But the question that appears to be still actively discussed is whether it is such a big deal, that “get latest version” is not done automatically on check out. When I started using TFS, at first impulse I thought it to be somewhat problematic (coming from VSS background). But after I worked with TFS for a year and being now somewhat older (and may be even wiser) I do not feel that way anymore, and even consider it an advantage of TFS Version Control over Visual SourceSafe. But as it happens, there is an opposite point of view; out of disagreement with it I was moved to write that post.

So let us start with short preamble. If you used Visual SourceSafe for version control, you used it with exclusive check out only (yes, I know that it allows to check out files concurrently, but never ever heard about success story of using VSS in that manner – while hearing lots of stories to the contrary). When you perform check out using VSS, it conveniently retrieves latest version for you and makes it writable.

Enter TFS Version Control. By default, check out is performed concurrently. When check out is performed, the local file is made writable (no version is retrieved from server).

My conclusion at that point would be “Wow, Team Foundation Server is not the same as Visual SourceSafe and uses different source control model, so we need to learn something about it and may be even adjust our practices!” Should have been no brainer, that one, don’t you think? But strangely enough, people tend to overlook that point from very beginning and try to use TFS VC as next version of VSS.
At that stage the typical issues that arise are


  • TFS won’t get latest version for me before check out

  • TFS will perform concurrent check out by default

  • TFS by default will not place any lock on checked out file

Can we work around these issues to make TFS exactly like SourceSafe? Unfortunately no. Is TFS any worse for that? Absolutely not. And I am going to prove that!

I am going to take real life example. Before I got my hands dirty with TFS, I participated in development of largish application as part of team of around 30 developers, using VS 2005 and VSS for source control. Let’s have a look at typical check out and what can (and did happen) after.

  1. The file I checked out was not modified on server. Then essentially I have latest version on my workstation, and simply making it writable would suffice. As nothing has changed, I shall be able to compile my project without problems.
  2. The file I checked out was modified by someone else and checked in, so my version is outdated. Get latest retrieves newer version but luckily the changes are such that when I perform build it compiles.
  3. The file I checked out was modified by someone else and checked in, so my version is outdated. Get latest retrieves newer version but now the changes are such that my project does not compile (for example, the method signature in that file was changed, and that very method is used throughout other project files).

As one may see, only third case creates a problem. Now, I bet that when you checked out that file you were not going to integrate the changes made in that file on server into your project. My guess would be that you are implementing some feature, and implementing it requires file modification so you checked that out. And now you cannot compile your project.
So instead of doing coding you are integrating changes. If the project is large, you probably will not perform “Get latest version” on whole project recursively (as in VSS it will take eons of time, and you are in the middle of development!). What you do is to try and handle the files one by one – let’s perform get latest for the files that break my build! Surely that will help! Ok, you do that. And it turns out that latest version of that other file breaks your build in some other place. That’s called chain reaction! At that point you have two choices – either perform “Get latest version” file after file until the project compiles, or start that recursive “Get latest version” beast and go pour some coffee (I assume that beating the crap out of guy who broke your build is not a valid alternative :).
Here we go as far as VSS is concerned – out of three cases, two work nicely and one is a major pain. I worked over VPN oftentimes (with full recursive “Get latest version” on the project taking lots of time), so I was full of apprehension every time I checked out “popular” file.
I can understand why dev’t guys at Microsoft wanted to help out the users in that problematic case. TFS solution is elegant, easy to understand and supports concurrent development at that! But it appears it is never a good idea to take away freedom of choice (even if it means preventing people from shooting themselves in the foot). Anyway, here goes TFS solution:

  1. The file I checked out was not modified on server. Then essentially I have latest version on my workstation, and TFS makes it writable. My project compiles as it did before check out, and there will be no problem to check in, as I am the only one who changed the file
  2. The file I checked out was modified by someone else and checked in, so my version is outdated (but the changes are such that they do not affect other files). Local file is made writable, my project compiles as it did before check out and all is well until check in. On check there will occur a conflict for me to resolve (more on that later).
  3. The file I checked out was modified by someone else and checked in, so my version is outdated (the changes are such that they do affect other files). Local file is made writable, my project compiles as it did before check out and all is well until check in. On check there will occur a conflict for me to resolve (more on that later).

In TFS, two cases created a problem for me instead of one in VSS! What’s happening here? We have paid some serious money for that souped up VSS and it cannot even check in files, huh?
In fact, several things happened, not all of them obvious.
First, what you got is a boost in immediate productivity – developer is allowed to develop (supposing one does check out in order to add new changes) without interruption, integration is delayed to development completed stage.

Second, there is overhead for conflict resolution on check in. That part here is tricky, and I am afraid that here it will be my personal opinion vs. yours. But as it is my blog, I am not afraid, so I can state plainly that overhead depends on quality of your code, quality of your development tasks and your engineering people.
If the code is modular, and each engineer performs well-defined task in all probability the conflict will be resolved automatically – that is new version of file will have changes non-overlapping with changes in version made by other developer (talking about agile shops, there developers may more often perform code breaking tasks; but in agile settings effective communication is the key, so assuming that it is relatively easy to handle merge conflicts effectively and in real time).

But in real world we have code breaking changes, and code does overlap! Does TFS do better job then by highlighting those conflicts after the fact (as compared with VSS that by breaking your build signals you before the fact)? In my opinion, TFS VC approach is indeed better and here is why. You check in your changes, the conflict cannot be resolved automatically, and you have that three-way merge window to stare at. At that point, you either qualified to perform merge, or not qualified to do so. How can you be not qualified to do that? For example, if code you have written does different thing from the same lines of code in server version of file. But wait a minute, that’s a sign of a different problem! You have been doing your job in parallel with someone else, and at that point in TFS there surfaces the problem while VSS would be hiding it!

I am well aware that my reasoning is not perfect, but overall I believe that adoption of TFS will lead to significant productivity gain over VSS, even though that may require some changes in work habits. But would you like to do concurrent development? If so, how well would your VSS-centered model fare? Your new practices should answer those questions as well, may be even before you start thinking how that get latest stuff will affect your development.

To conclude, while that get latest thing may seem a deficiency, and surely the user must have a choice (as one apparently will in TFS v2), I do not view it as a showstopper, and strongly believe that client may be made aware of TFS advantages over VSS using that very feature (or an absence of it – depending how you look at it). It seems that Microsoft somewhat underestimated the impact VSS had on the development practices over the years; but as VSS addicts have more hands on experience with TFS I do hope that VSS-only work patterns will fade away.

And to add up to this argument, some links from MS development team on that very subject:
Buck Hodges blog post (read the comments as well)
Adam Singer blog post (excellent read, but be prepared - it is longer than that one)

I tried to be as concise as possible (unless Thanksgiving dinner somewhat got in the way :), but please drop me a line to know what you think and where I might have been wrong.

2 comments:

Anonymous said...

We can debate the merits of allowing developers to edit stale code until the cows come home. The point is that lot of time and blog entries could have been saved had the TFS team provided their customers with the option of forcing a get-latest on check-out as opposed to hard-coding the tool to work THEIR WAY.

eugenez said...

We sure do debate about it :) And I am thinking due to the wide resonance that get latest thing gathered the option of forcing get latest will be the one new feature in Orcas you can be certain of.