TFS 2010 – An Introduction to Gated Check-in

In TFS 2008 we made quite a few improvements to build, such as scheduled builds and continuous integration. The continuous integration feature is nice for detecting failures in the build as soon as possible to ensure minimal downtime and reduce the chance of generating a bad nightly build. However, it’s not a perfect solution since even when the build fails it is possible for others to submit unrelated changes and keep the build broken. As a first measure to aid this scenario, Buck Hodges wrote a check-in policy that would determine which, if any, build definitions would be affected by the changes being checked in – if the last build for the definition failed, the policy would not allow the user to check-in without overriding it. But there are quite a few issues with this approach, the main one being that it requires the users to install the policy and only override it when honestly submitting fixes for the build break. At this point you may be asking yourself “what if there were a way to stop people from submitting broken source code into the repository on the server?” This is exactly what gated check-in offers, and I intend to explore the features around gated check-in in the following paragraphs.

Setting Up Gated Check-in

Gated check-in is merely an extension of the check-in trigger for a build definition, so it should be easy to setup for those familiar continuous integration. In TFS 2008, we provided ‘Manual’, ‘Continuous Integration’, ‘Rolling builds’, and ‘Schedule’ (along with the option to force builds on that schedule even if no changes occurred since the last build). When viewing the build definition properties in TFS 2010, you will see the same options (with the addition of ‘Gated Check-in’):


When this trigger is selected for a build definition, any check-in that is made to a file that is mapped in the associated workspace will trigger a verification build. If the build succeeds, the changes will be submitted to the repository. If the build fails, the changes are not allowed to be submitted and must be fixed and resubmitted.

Submitting a Gated Check-in

When a user attempts to submit changes to a version control path that is mapped by a build definition with the ‘Gated Check-in’ trigger, they will be presented with the following dialog:


The first thing to point out here is that the check-in been automatically converted to a shelveset. In this particular scenario, the shelveset has been named ‘Gated_2009-06-29_02.49.00.9801’. The check-in notes, associated work items, etc., are all replicated into the shelveset and will be included in the changeset upon a successful build. The second piece of the dialog to pay attention to is the build definition selection. If there were only a single build definition that was considered affected by the changes, the combo box would be disabled and you would not be provided any options. If, however, there is more than one build definition that maps the changes being submitted, the user you will be presented with the list of build definitions as shown in the following image:


It’s important to note here that the actual definition selected to perform the check-in does not matter here, as both have been determined to map at least some subset of changes included in the check-in. However, it’s possible that ‘Gated Definition 1’ only maps a single file in the check-in, while ‘Gated Definition 2’ could map all the files or a larger subset. Currently we do not provide any indication as to what percentage of the changes are mapped by any given build definition. Once you have selected a build definition, you have the ability to specify some extra options. For example, it is entirely possible that you are a build administrator and wish to submit a fix directly rather than waiting for the verification build. However, this option will only be enabled for a selected build definition if you have the appropriate permission, ‘Override Check-in Validation by Build’. If you have the appropriate permission, we have provided the ability to bypass build verification as shown in the following image (although it’s disabled in this particular shot since no build definition is currently selected):


The other option available in the ‘Show Options’ section of the dialog is ‘Preserve my pending changes locally’. This allows the user to decide whether or not the changes being submitted should be left in the workspace or undone once the ‘Build Changes’ button is clicked (if the changes are left in the workspace, there is an entry point that we will explore later in the article to reconcile the submitted changes with those in your workspace). Once you are satisfied with the options on this dialog and ‘Build Changes’ is clicked, you will be redirected to the build explorer where the build just queued will be highlighted for easy discovery as shown here:


Now I know there is only one build in this particular queue so it wouldn’t be very difficult to locate the build, but imagine there is a team of 50-60 people all submitting changes to the same build definition, or even multiple definitions all sharing the same build controller. 🙂 Anyway, moving along to the successful gated check-in, you can see from the following build report that the submitted changeset is associated with the gated build, just like changesets would be associated with a non-gated build by comparing the labels and analyzing the differences.


Now that the build has completed successfully, you may have some further actions to perform if you chose not to preserve pending changes in your workspace. The entry point for this functionality is in build explorer, which is available via the context menu of the build detail entry in the ‘Completed Builds’ tab or the queued build entry in the ‘Queued Builds’ tab. If you only have a single workspace on the current machine then a workspace will be automatically selected for you. If, however, you have more than one workspace on the machine, you will be prompted to select the workspace which you would like to reconcile changes with. We currently do not support storing the source workspace from which the shelveset originated, so we cannot automatically determine the workspace used to create the shelveset. However, this feature is on a backlog and we are looking at including this functionality in a future version. The second entry point is from the gated check-in notification window in the build notification system tray application, which is included with the product in TFS 2010.

This has been a very targeted and simple walk-through of the new gated check-in functionality available in TFS 2010. I will be covering more advanced scenarios surrounding permissions, integration with the build notification system tray application, and more in future postings. Stay tuned!

Comments (19)

  1. pciml says:


    I configured the gated check-in, and all steps that you showed, but the check-ined items stay as pending (when I try refreshing – no change), if I try action "Get latest version" I must resolve conflicts for each check-ined item. When I resolve all conflicts, check-ined items continualy stay in check-in dialog, after one more check-in VS shows messagebox – "no changes for check-in".

  2. Good to hear that you’re using the feature! With respect to the experience, did you uncheck ‘Preserve my local changes’ under the ‘Advanced Options’ of the gated check-in prompt? If not, then the changes will remain in your workspace. Under this scenario you can go to Build Explorer and view the Completed tab. Find your build, right click, and choose ‘Reconcile Workspace’ from the context menu.


  3. roberjo says:

    I have set up gated check-in as well as single signout/exclusive checkout.  Now when my users try to run a gated check-in, the option to "Preserve my pending changes locally" cannot be checked (greyed out/disabled and unchecked).  Any ideas why this happens?  I need to be able to preserve local changes so my users do not have to go hunt down their shelveset and wrestle with unshelving changes.

  4. This behavior is expected in the exclusive checkout scenario. If we allowed users to retain the changes in the workspace then the build machine would not be able to unshelve and verify them since the user will still have the changes exclusively checked out. Typically you have a couple of controls for the source control process:

    1. Enable exclusive checkout

    2. Enable gated check-in.

    Although these two options are not required to be exclusive, your experience will be degraded considerably when attempting to use them together.


  5. Mohamed Radwan says:

    I just wandering how can make multiple build definition as you mentions "more than one build definition that maps the changes being submitted," , I create more than one build definition under the build in the team project but still the drop down box doesn’t show up so what's I need to do?

  6. The drop-down will only show multiple definitions if:

     1. At least one of the files being checked in is mapped in the workspace for each build definition

     2. Each build definition is marked with the 'Gated Check-in' trigger

     3. Each build definition is enabled


  7. Rune says:

    …and what if the check-in breaks the build? Will the user be notified, or do they have to check the build manager manually?

  8. Dan Wygant says:

    I have a differing experience. I have a widget in the taskbar that shows TFS status.

    After a complete, another messagebox pops  up asking me to reconcile… or ignore.

    The message is confusing at best.

    So I usually go to do a manual reconcile.

    The entire process after either a successful or failed build is confusing and so I wonder if I could ask you to update this great reference. Please add something about how to manage the reconciliation afterwards.

    On top of all that, after a few attempts – with successful builds – to add projects, everyone else in the team sees empty projects. Can you explain that?

    They're all having issues with those projects, even though the builds did succeed, and I did manually reconcile.

  9. Yaworm says:

    Our TFS administrators have a build set up for Continuous Integration.  I've been begging them to switch it to Gated Check-in, but they insist that doing so would require them to set up some kind of specialized database and they don't have time to do that.  I haven't been able to find any discussions on-line that support their claim.  Are they lying to me?

  10. Tanmoy says:


    I have set up gated check in into our server and did not have to use any special database or anything special for it.

  11. @Yaworm

    If you are using TFS 2010 then it is built into the product. It's a simple configuration option when editing the build definition.


  12. Arun Sangal says:

    OK. Here's what I need. Can you assist, thanks.

    1. Our BD(Build definition) is: CID_Build, it's trigger is set to Gated checkins.

    2. Developers committed changed, got the window about shelveset, so s/he launched the build (gated way)

       due to trigger set in BD.

    3. Now, lets say, "due to" TFS application/services/build server issue related to memory/disk space if a build

       fails (i.e. build didn't fail due to a bad source code by the developer), then, IS there any auto way to run that

       same build again i.e. if someone resolves the disk space/network/memory issue on TFS App/Build

       server/etc, then that developers changes should be checked in (and for this we need a fresh build which

       failed earlier).

    – Is there any setting in Team Explorer that does this?

    – Is there any configuration file/setting I can do to make this happen.

    – We dont want the developer to come next day and tell us that the his/her changes didn't go to TFS repository

     because the build failed to a NON-Developer issue.

    Any insights will be appreciated.


    Arun Sangal

  13. Keith says:

    Gated checkin in TFS 2010 doesn't seem to work when you add new files. I converted an old VS 2008 sln to VS 2010 format and an number of new vcxproj files were added for my C++ projects.  The gated build failed saying it couldn't apply a label to foo.vcxproj because it hasn't been checked in.  Now, isn't that a bit of a chicken & egg problem?  I can't check it in until the gated build passes and the gated build won't pass until I check it in.  Great idea but doesn't seem fully baked yet.

  14. Simon says:

    Having now used tfs 2010 for 2 months I can honestly say it is the worst code repository system on the planet.

    Why, or why or why, would anyone want to have their changes shelved on the build machine when a build fails. In what use case could this possibly meet. It is purely there because tfs is an upgrade from source safe which doesnt allow multiple people working on the same file.

    I love microsoft products, and ive built my career around them. I wish they would get with it on source control too.

    TFS 2012 is a bit better but not much, when you compare with mercurial or git.

  15. Shaun says:

    Keith:  We encountered the same problem. IT is because you are using the old tfsbuild.proj for your builds instead of the 2010 workflow way.  No worries, all you have to do is add the <SkipLabel>true</SkipLabel> into each tfsbuild.proj file that you have gated enabled on and this will fix your issue when doing a gated checkin with added files.

  16. Russell Horwood says:

    If a CS crosses the domain of multiple gated check-ins then the user get's offered a choice which one to use. This obviously allows users to check-in code that doesn't compile and tests that fail. Anyway know of a way to correct this behaviour?

  17. karthik says:

    I have ten gated build definition. If i checkin one solution, all ten build definition are being listed in Gated Check In Screen. How can i make it visible correctly mapped build definition among all 10.

  18. Jason says:

    Shaun: I have two build servers, set up exactly the same. On 1, the gated check-in works fine when adding new files. On 2, the gated check-in fails (can't apply label to new file). The only difference in build definition is the build controller. Each build uses the same .proj file in the build definition. Why is one failing while the other succeeds? Thank you.