Tag Archives: source control

TFS API: How to Get a Specific Version Programmatically

Within the Visual Studio Source Control Explorer, there are a number of options available for getting files out of TFS. Often times, developers just want to get the latest code to work with. But in some scenarios, developers need to get source files based on alternate criteria, such as by a specific date or label.  TFS provides a handful of options for selecting source files easily within the “Get Specific Version” dialog.

TFS: Get Specific Version Options

This works really well within Visual Studio, but how can you do this programmatically?  As it turns out, the Workspace.Get() method has an overloaded method that takes a VersionSpec argument.  Notice that VersionSpec is actually a base class. and that there are several inherited classes that can be used to specify the changeset type, including:

  • ChangesetVersionSpec
  • DateVersionSpec
  • LabelVersionSpec
  • LatestVersionSpec (equivalent to VersionSpec.Latest)
  • WorkspaceVersionSpec

For example, if you wanted to perform a GET on a specific changeset, you would simply pass an instance of ChangesetVersionSpec:

'connect to source control and get reference to existing workspace
Dim server As TfsTeamProjectCollection = _
   TfsTeamProjectCollectionFactory.GetTeamProjectCollection("http://myTfsServer:8080")
Dim vcs As VersionControlServer = _
   server.GetService(Of VersionControlServer)()
Dim ws As Workspace = vcs.GetWorkspace("MyExistingWorkspace", My.User.Name)

'Perform a GET on Changeset 100
Dim version As New ChangesetVersionSpec(100)
ws.Get(version, GetOptions.GetAll)

Performing a GET based on a pre-defined label works in much the same way (just replace the ChangesetVersionSpec object with a LabelVersionSpec object):

'connect to source control and get reference to existing workspace
' (same as above)...

'Perform a GET on items defined by label "My Label"
Dim version As New LabelVersionSpec("My Label")
ws.Get(version, GetOptions.GetAll)

Updated 2/28/2012: Revised code sample for TFS 2010 API.

Check In Code Frequently for Roll-back’s Sake

One of the best practices around source-control is the idea of checking in code frequently. “Frequently” is, of course, a relative term. Some take this to mean checking in code within a matter of hours; others, days. Some suggest check-ins should occur every time a new feature is added. Then the question becomes: What constitutes a feature? Is a method of a class a “feature”? Is a class a “feature”? Is a feature based on a user story? A Use Case? A bulleted item in a requirements document?

For me, I’m prescribe to the practice of checking in per feature. And, by feature, I mean a Use Case (or a single flow of a Use Case), or a backlog requirement. Of course, some features take more time to implement than others. But this is ok. Sometimes, I’ll check in within a couple hours. Other times, I might check in after a couple days. Rarely, however, do I leave files checked out for more than 2-3 days (if that gives you an idea how “large” I spec these features).

key-undo

One of the many benefits of checking in frequently is that you allow the ability to rollback in-progress code changes that are not panning out. For some of you, this may be a completely foreign idea.  “Delete my code?! Are you loco??  This code was spawned from the magnificence that is my brain.  It is precious.”

If that was your reaction,… well, if that was really your reaction, then you should probably stop reading.  Wait, don’t stop reading.  I need the subscribers…  For those of you that had a bit more subtle reaction, consider this anecdote:

This morning, I was coding up a new feature for an active development project. All previous code had been checked in before starting this new feature, so I was starting from a stable build. Starting out, I was trying to figure out the best way to implement this new feature. In some cases, some up-front design and modeling would have been useful – but, in this case, where I was working with a few unfamiliar .NET classes, it made more sense to just try out a few different approaches programmatically and get a feel for which worked best.

In the span of about 90 minutes, I had implemented – and subsequently rolled back – five code changes before finding an approach that finally worked.

Some of the reasons for rolling back the first several changes included:

  • The implementation was not going to work
  • The implementation would have created more maintenance overhead than I wanted
  • The scope of the implementation became much better than what I wanted to bite off

Also while making these development changes, I noticed Visual Studio modifying a number of auto-generated files that I don’t normally touch (including project, .settings and .resx files). It would have been very difficult, if not impossible, to go through these files manually and find all the changes that were made.  But because I was rolling back all of the files via TFS, there was significantly less risk of introducing unstable code (or accidentally leaving leftover code) in a later build.  It was also considerably faster than manually traversing the code for delinquent code.

If you’re not accustomed to rolling back code in your development cycle, it’s feels kind of like this:

  • The first time you intentionally rollback (read: DELETE) your code changes, it’s kind of scary!
  • The second time, it’s a little scary, a little exciting, maybe even a little deviant-like.
  • Subsequent times, it’s empowering. And you wonder why you weren’t doing it sooner.

Control key So if you are (or know someone who is) in the camp where code check-ins are almost an afterthought, consider this example and think about the value that frequent check-ins can add to the development cycle.

Removing Local Source Control Files with TFS

One of the things in TFS that has been of little value to me is the “Latest” column, found in the Source Control explorer.  The intent behind this feature is a good one:  Be able to easily tell if you have the most recent version of a source file, or if somebody has checked in a new version since you’ve last pulled down code.  But somewhere between idea and implementation, something got lost.

View of Files in TFS

View of Files in the TFS Source Control Explorer

There’s an annoying little side effect to this feature.  If the developer decides to make changes to files outside of TFS – for example, deleting local files that are no longer worked on – TFS will not recognize that the developer no longer has the latest version.  This becomes very irritating when trying to re-download the files using GET LATEST.  Because TFS thinks you already have the files on your local machine, it will, by default, skip downloading the files.

Fortunately, Martin Woodward posted a solution on his blog a while back on how to correctly clean up your local files while, at the same time, keeping TFS in sync.  I consider this to be a bit of a hack, because it seems very unintuitive.  However, I haven’t seen any new features in TFS 2010 to lead me to believe that a more intuitive approach is being added.  So, either Microsoft isn’t getting much feedback on this, or they consider Martin’s approach to be the preferred approach…

Meanwhile, I’ve since found myself doing this somewhat frequently after finishing projects, in order to keep my local directories from piling up with old files that I no longer need.

When to Check-In Source Code Changes

For the last couple of months, I’ve been leading an adoption effort at work to migrate developers away from our current version control system over to Microsoft’s Team Foundation Server.  During this time, I’ve been approached with a number of questions regarding best practices around source control usage, causing me to brush up on my own level of knowledge on the subject.

Recently, I was asked the following question:  When should I check in source code that I’m working on? At first, this seemed like a trivial question. But, since I didn’t have a good immediate response at the time, I figured it can’t be all that trivial.

So, upon further reflection – and consultation with several fellow developers – I’ve compiled the following list to be good situations in which committing changes to source control is a good idea.

You should check in files…

  • When the project is first created
  • When a new feature has been written (such as implementing a class, a method or a “slice” of functionality – from the GUI down through data access layer)
  • Before refactoring or re-designing a component (so that there is something to compare with, or roll back to)
  • When a bug has been fixed.

In what other situations would it make sense to check in files to source control?