Buck Hodges

Visual Studio Online, Team Foundation Server, MSDN

March, 2006

Posts
  • Buck Hodges

    Team Foundation Version Control client API example (RTM version)

    • 24 Comments

    [Update 3/10/2012] If you are using TFS 2010 or newer, there is an updated version control client API example.

    [Update 6/13/06] While the documentation is not what it needs to be, you can find reference-style documentation on a significant amount of the API in the VS SDK (current release is April): http://blogs.msdn.com/buckh/archive/2005/12/09/502179.aspx.

    I've updated this sample a few times before.  This is a really simple example that uses the version control API.  It shows how to create a workspace, pend changes, check in those changes, and hook up some important event listeners.  This sample doesn't do anything useful, but it should get you going.

    You have to supply a Team Project as an argument.  Note that it deletes everything under the specified Team Project, so don't use this on a Team Project or server you care about.

    The only real difference in this version is that it uses the TeamFoundationServer constructor (in beta 3, you were forced to use the factory class).

    You'll need to reference the following dlls to compile this example.

    System.dll
    Microsoft.TeamFoundation.VersionControl.Client.dll
    Microsoft.TeamFoundation.Client.dll

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using Microsoft.TeamFoundation.Client;
    using Microsoft.TeamFoundation.VersionControl.Client;

    namespace BasicSccExample
    {
        class Example
        {
            static void Main(string[] args)
            {
                // Verify that we have the arguments we require.
                if (args.Length < 2)
                {
                    String appName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
                    Console.Error.WriteLine("Usage: {0} tfsServerName tfsTeamProjectPath", appName);
                    Console.Error.WriteLine("Example: {0} http://tfsserver:8080 $/MyProject", appName);
                    Environment.Exit(1);
                }

                // Get a reference to our Team Foundation Server.
                String tfsName = args[0];
                TeamFoundationServer tfs = new TeamFoundationServer(tfsName);

                // Get a reference to Version Control.
                VersionControlServer versionControl = (VersionControlServer) tfs.GetService(typeof(VersionControlServer));

                // Listen for the Source Control events.
                versionControl.NonFatalError += Example.OnNonFatalError;
                versionControl.Getting += Example.OnGetting;
                versionControl.BeforeCheckinPendingChange += Example.OnBeforeCheckinPendingChange;
                versionControl.NewPendingChange += Example.OnNewPendingChange;

                // Create a workspace.
                Workspace workspace = versionControl.CreateWorkspace("BasicSccExample", versionControl.AuthenticatedUser);

                try
                {
                    // Create a mapping using the Team Project supplied on the command line.
                    workspace.Map(args[1], @"c:\temp\BasicSccExample");

                    // Get the files from the repository.
                    workspace.Get();

                    // Create a file.
                    String topDir = Path.Combine(workspace.Folders[0].LocalItem, "sub");
                    Directory.CreateDirectory(topDir);
                    String fileName = Path.Combine(topDir, "basic.cs");
                    using (StreamWriter sw = new StreamWriter(fileName))
                    {
                        sw.WriteLine("revision 1 of basic.cs");
                    }

                    // Now add everything.
                    workspace.PendAdd(topDir, true);

                    // Show our pending changes.
                    PendingChange[] pendingChanges = workspace.GetPendingChanges();
                    Console.WriteLine("Your current pending changes:");
                    foreach (PendingChange pendingChange in pendingChanges)
                    {
                        Console.WriteLine("  path: " + pendingChange.LocalItem +
                                          ", change: " + PendingChange.GetLocalizedStringForChangeType(pendingChange.ChangeType));
                    }

                    // Checkin the items we added.
                    int changesetNumber = workspace.CheckIn(pendingChanges, "Sample changes");
                    Console.WriteLine("Checked in changeset " + changesetNumber);

                    // Checkout and modify the file.
                    workspace.PendEdit(fileName);
                    using (StreamWriter sw = new StreamWriter(fileName))
                    {
                        sw.WriteLine("revision 2 of basic.cs");
                    }

                    // Get the pending change and check in the new revision.
                    pendingChanges = workspace.GetPendingChanges();
                    changesetNumber = workspace.CheckIn(pendingChanges, "Modified basic.cs");
                    Console.WriteLine("Checked in changeset " + changesetNumber);
                }
                finally
                {
                    // Delete all of the items under the test project.
                    workspace.PendDelete(args[1], RecursionType.Full);
                    PendingChange[] pendingChanges = workspace.GetPendingChanges();
                    if (pendingChanges.Length > 0)
                    {
                        workspace.CheckIn(pendingChanges, "Clean up!");
                    }

                    // Delete the workspace.
                    workspace.Delete();
                }
            }

            internal static void OnNonFatalError(Object sender, ExceptionEventArgs e)
            {
                if (e.Exception != null)
                {
                    Console.Error.WriteLine("Non-fatal exception: " + e.Exception.Message);
                }
                else
                {
                    Console.Error.WriteLine("Non-fatal failure: " + e.Failure.Message);
                }
            }

            internal static void OnGetting(Object sender, GettingEventArgs e)
            {
                Console.WriteLine("Getting: " + e.TargetLocalItem + ", status: " + e.Status);
            }

            internal static void OnBeforeCheckinPendingChange(Object sender, ProcessingChangeEventArgs e)
            {
                Console.WriteLine("Checking in " + e.PendingChange.LocalItem);
            }

            internal static void OnNewPendingChange(Object sender, PendingChangeEventArgs e)
            {
                Console.WriteLine("Pending " + PendingChange.GetLocalizedStringForChangeType(e.PendingChange.ChangeType) +
                                  " on " + e.PendingChange.LocalItem);
            }
        }
    }

  • Buck Hodges

    How to change the computer name and update the owner name for a workspace

    • 11 Comments

    As part of the information about a workspace, the version control server records the name of the computer that hosts a workspace and the user that owns the workspace.  If you need to change your computer name or your user name, how do you tell the server to update the workspace information?

    The command line, tf.exe, provides two options, /updateComputerName and /updateUserName, on the workspaces command to address this issue.  Note that in version 1 you must use the command line for this.  Also, you may notice that the documentation on MSDN shows that these options do not accept values, but that's a documetation error that will be corrected in the near future.

    To update the computer name for workspace, you'll need to run the following command.

    tf workspaces /updateComputerName:OldComputerName /s:http://Tfs_server:8080

    OldComputerName should be replaced with the name your computer had previously (more precisely, it should be what the server currently has recorded).  Tfs_server should be replaced with the name of your server.

    When you execute that command, tf.exe removes the cached workspace entries that use the old computer name, calls the server to tell it the current computer name, and gets the current list of workspaces owned by you on the current computer.

    Similarly, you'll need to run the following command if your user name changes (for example, from corpdomain\eharris to corpdomain\esmith).

    tf workspaces /updateUserName:OldUserName /s:http://Tfs_server:8080

    OldUserName should be replaced with your user name prior to changing it.

    As with updating the computer name, tf.exe uses the old user name to clear out the workspace entries where the owner is the old user name, tells the server to update your user name, and gets the current list of workspaces owned by your current user name.

    The server actually stores the Windows SID (security identifier) for your account, so the update call to the server simply tells the server to update its cache with the current user name for that SID.  That also means that if you get a new user ID rather than just changing the name, you won't be able to update the workspace ownership this way.  In that case, you'll have to create a new workspace.

    You can find the complete command line reference documentation at http://msdn2.microsoft.com/en-us/library/cc31bk2e(vs.80).aspx.

    To use /updateComputerName and /updateUserName, you must use the RC or newer release of TFS.

  • Buck Hodges

    Annotate (also known as blame) is now a power toy

    • 9 Comments

    [UPDATE 8/9/2007]  I fixed the broken link to power tools page. 

    [UPDATE 9/8/2006]  TFPT is now available in its own small download: http://go.microsoft.com/?linkid=5422499!  You no longer need to download the VS SDK.  You can find more information about the September '06 release here.

    One of the features that we had to cut for version 1 was annotate, which is also known as blame in Subversion.  We had hoped to provide a power toy that at least provided the basics, and the Visual Studio 2005 SDK – March 2006 CTP for v2 contains an updated tfpt.exe with support for annotate.

    Written by Justin, a developer working primarily on the version control server, annotate downloads every version of a particular file and annotates the output with attributes showing the changeset, date, and user who last changed each line in the file.  The current implementation does not show deleted lines.

    Most of the time, you will likely run tfpt annotate filename to bring up the viewer, but you can also specify /noprompt to get console output.  The optional version provides the ability to see changes up to the specified version.  Here is the help text.

    C:\Program Files\Visual Studio 2005 SDK\2006.03\VisualStudioTeamSystemIntegration\Utilities\Team Foundation Power Toys>tfpt annotate /?
    tfpt annotate - Display line-by-line change information for a file

    Displays the given version of a file along with information
    on who modified the line last.

    Usage: tfpt annotate [/noprompt] filespec[;versionspec]

     filespec               Server or local path of file to view history of.
     /noprompt              Prints interleaved output to console instead of GUI.

    The annotate viewer is shown in a screenshot below.  By default, the content viewer displays only the changeset number.  You can use the View menu to display the user name and date, as I have.

    When this screenshot was captured, I had selected the line that prints the output.  As a result, the changeset information on the left hand side shows some of the changeset information, including the comment.  If I had associated or resolved a work item when checking in, that work item would be displayed in the Work Items list.

    Finally, the Edit menu gives you the ability to search and go to a particular line number.

    This annotate implementation provides the basics, and it will likely whet your appetite for more.  While this power toy is not likely to get more features, we are certainly interested in your feedback for what you would like to see in the shipping product.

    Enjoy!

  • Buck Hodges

    How to get the login dialog when using the Team Foundation Server API

    • 9 Comments

    Someone asked how to get the login dialog if the user fails to authenticate.  The code to do that is shown below.  I copied the call to the constructor from the basic API example, and I've added code to create and pass a UICredentialsProvider object to the TeamFoundationServer constructor.

    Also, I'm now calling EnsureAuthenticated().  The purpose of that call is to make sure that the user is able to authenticate with the server.  If not, the TeamFoundationServer object will use the UICredentialsProvider to display a login dialog.  If the user authenticates successfully after entering a user name and password, the program will continue execution.  If the user clicks the Cancel button in the login dialog, perhaps after failing to enter a valid user name and password, the EnsureAuthenticated() method will throw TeamFoundationServerUnauthorizedException.

    If you look at the TeamFoundationServer class, you will notice that there are two authentication methods to call: Authenticate() and EnsureAuthenticated().  The difference is that Authenticate() will always call the server, and EnsureAuthenticated() will only call the server if the user has not already authenticated, resulting in no performance penalty for calling it multiple times.

    Only Authenticate() and EnsureAuthenticated() will display the login dialog.  Any other method calls that fail due to the user not authenticating will result in TeamFoundationServerUnauthorizedException being thrown.

        // Get a reference to our Team Foundation Server. 
        TeamFoundationServer tfs = new TeamFoundationServer(tfsName, new UICredentialsProvider());

        // Authenticate with the server if we haven't already (in this example, we haven't).
        // If authentication fails, the user will see the login dialog, as a result of
        // UICredentialsProvider() being specified above.

        tfs.EnsureAuthenticated();

    [Update 3/20/06]  Fixed typo.  Thanks, Tim.

  • Buck Hodges

    How to check in changes on behalf of other users

    • 5 Comments

    Recently someone asked how to check in changes for another user.  There are at least two good scenarios where this is needed.  One is for check-in systems such as the Gauntlet system we used internally during the development of TFS.  Rather than check in directly, developers would shelve their changes and put them in the Gauntlet queue.  Gauntlet would unshelve one shelveset's worth of changes, build the code with those changes, run a small set of tests, and then check in the changes on behalf of the user who created the shelveset.

    Another important scenario is for converting an existing system over to Team Foundation Server.  For version control, you would like the history in TFS to reflect who actually made the changes, rather than the account used for the conversion.

    We provide the capability to support these scenarios through a permission and parameters to the CheckIn() method, which supports the /author option on the checkin command in tf.exe.  In order to be able to check in changes on behalf of another user, the user performing the check in must either be an administrator or must have the CheckinOther permission.

    The MSDN documentation describes the CheckinOther permission and how to set it from within VS as well as from the command line.  From the command line, you would execute something like the following.  This example sets the permission for $/Project and all directories and files that inherit permission settings from $/Project.

    tf perm $/Project /allow:CheckinOther /user:domain\SomeOne

    From the command line, you can check in changes for someone else by using the /author option to the the checkin command (documentation).  For example, the following command checks in all changes in your current workspace on behalf of OtherUser (/author:domain\OtherUser) without prompting (/i).  You will need to specify domain if it is different than the domain of your user name (there's no harm in always specifying it).

    tf checkin /i /author:domain\OtherUser

    One important thing to note here is that the changes are pending in your workspace and are being checked in from your workspace.  You are simply specifying what user name you want to see in the brief history format.  Both your user name and OtherUser are recorded in the changeset data, so that you can always determine who checked in the changes.

    All of the above discussion also applies to the CheckIn() method on the Workspace class in the version control API.  I have copied the method signature and its documentation below.  The overload below is the one that takes all of the parameters.  The simplest CheckIn() overload requires only two parameters, an array of PendingChange objects and a comment, and it is used in the basic version control API example.

        //********************************************************************************************
        /// <summary>
        /// Check in a set of pending changes.  Checkins are atomic - either they all succeed or
        /// they all fail.  If there are any conflicts that need to be resolved before the check in, the check
        /// in operation will throw an exception.
        /// If any part of the operations leading up to the final check in commit fail (uploading
        /// files, etc) then the operation is aborted and an exception is thrown.  If updating client
        /// or work item state fails after the commit operation, a non-fatal error is reported with the 
        /// actual checkin having been successfully committed.
        /// </summary>
        /// <param name="changes">List of changes to check in.</param>
        /// <param name="author">if non-null, this identity will be listed in history for the committed
        ///   changeset (note that the user running this operation must have the CheckinOther
        ///   permission)</param>
        /// <param name="comment">Comment to go along with the checkin.</param>
        /// <param name="checkinNote">Any applicable checkin notes data.</param>
        /// <param name="workItemChanges">List of work item changes to occur with this checkin</param>
        /// <param name="policyOverride">if non-null, policy failures are being overridden</param>
        /// <param name="checkinOptions">Per-checkin options that affect event generation and
        /// checkin author validation</param>
        /// <returns>changeset number created by checking in</returns>
        //********************************************************************************************
        public int CheckIn(PendingChange[] changes, String author, String comment, CheckinNote checkinNote,
                           WorkItemCheckinInfo[] workItemChanges, PolicyOverrideInfo policyOverride,
                           CheckinOptions checkinOptions)

        [System.FlagsAttribute()]
        public enum CheckinOptions
        {
            None = 1,
            ValidateCheckinOwner = 2,
            SuppressEvent = 4,
        }

    The author, checkinNote, workItemChanges, and policyOverride parameters can all be null if you don't have values to specify (okay, the comment can be null too, but you wouldn't do that, right?).

    The CheckinOptions values allow you to control what happens with the author parameter (ValidateCheckinOwner) and server-side event generation (SuppressEvent).  For overloads of CheckIn() that don't specify the checkinOptions parameter explicitly, the value CheckinOptions.ValidateCheckinOwner is used.

    For a Gauntlet-type scenario, calling the Checkin() method with the author being the owner of the shelveset is exactly what you need.  You can call an overload that doesn't explicitly specify the checkin options and use the default value.

    The real purpose of the checkinOptions parameter is to support version control converters.  For that scenario, you may need to check in changes on behalf of users that don't exist as Windows users, either because they have been deleted or because the old version control system had its own user security system (e.g., Visual SourceSafe).  So, most converters will not want to have the server validate the checkin owner (author).

    Also for the conversion scenario, you will likely want to suppress checkin events on the server.  The reason is that you are likely creating hundreds or thousands of changesets, and checkin event generation will simply add overhead to a process that you'd like to have run as quickly as possible.  To do this, you will want to specify CheckinOptions.SuppressEvent for the checkinOptions parameter.

    Putting this all together, the call to CheckIn() in a version control converter might look like the following.  You may also want to specify the old system's checkin date and other metadata in the checkin comment.

    PendingChange[] pendingChanges = workspace.GetPendingChanges();

    String oldSystemUser = /* get user name from other VC system */;

    workspace.CheckIn(pendingChanges, oldSystemUser, "converted changeset", null, null, null, CheckinOptions.SuppressEvent);

    For those of you wondering why CheckinOptions.None and other None enum values have the value of 1 rather than zero, it was a side effect of wsdl.exe.  In SOAP, the enumeration values are marshalled as names, such as None, rather than integers.  As a result, the values of the enumerations in the client may not match the values of the enumerations used by the server, since they are specified in the web service's WSDL.

  • Buck Hodges

    How to create shadow folders in TFS

    • 10 Comments

    One of the features from VSS that TFS does not support "out of the box" is shadow folders.  Last year, one of our interns, Philip, wrote short guide to setting up shadow folder for TFS by using Scheduled Tasks in Windows (he also wrote tfpt.exe).

    I've attached the MS Word document to this post.  You can read the introduction below.  Another use for this is to prime the version control caching proxy at a remote location to minimize the amount of time users have to wait to get files from the version control repository.

    Shadow Folders with Team Foundation Version Control

    Microsoft Team Foundation Version Control does not support the concept of shadow folders. In Visual SourceSafe 6.0, shadow folders are a copy of the repository, constantly updated with the latest version of each checked-in item.

    Shadow folders are useful for several situations, including:

    • Source code index servers
    • Centralized build servers

    Shadow folders can be emulated with Team Foundation Version Control by using the Scheduled Tasks service on Windows Server 2003 or later.

  • Buck Hodges

    Configuring different diff/merge tools for Team Foundation Version Control

    • 6 Comments

    Many of you probably know that you can specify your own diff/merge tool.  One thing that's not mentioned on that documentation page is that you can specify * for the Extension field to change the default diff or merge tool.

    James Manning recently put together a nice post on configuring different diff and merge tools, making it easier to properly configure the tool of your choice.  This is most useful for merge, where for v1 a number of other available tools offer a better experience than diffmerge.exe in the more complex cases.

    Diff/Merge configuration in Team Foundation - Common command and argument values

    One of the extensibility points we have in Team Foundation V1 is that you can configure any other diff and merge tools you want.  The purpose of this article is to start collecting the most common ones we know or heard about in a central place so people don't have to figure these out on their own.

  • Buck Hodges

    Licensing differences between TFS Workgroup Edition and TFS Standard Edition

    • 5 Comments

    Recently Ajay Sudan, Product Manager for VSTS, answered a question regarding some confusion over the differences between TFS Workgroup Edition and TFS Standard Edition.  Here is how he summed it up.

    TFS Workgroup Edition is not licensed on a Server/CAL model. This means CALs are not required when using the Workgroup Edition. For this reason, the Workgroup Edition does not include any CALs. TFS Workgroup Edition can be used by 5 unique users using any client (MSSCCI, 3rd party client, VS Pro, Team Edition, Project, Excel, etc.).

    Once you grow beyond 5 users, you’ll need to upgrade to TFS Standard Edition, which is licensed on a server/CAL model. This means that you must make sure all users have the necessary CALs in place.

    The full details are available in the Microsoft Visual Studio 2005 Team System Licensing White Paper.

  • Buck Hodges

    How to validate check-in policies, evaluate check-in notes, and check for conflicts

    • 5 Comments

    In the version control API, the CheckIn() method does not evaluate check-in policies and validate check-in notes.  It provides with the ability to supply both an override comment and check-in notes, as applicable, but the evaluation and validation must have been performed prior to calling CheckIn().  The reason for this is that in a real-world application, you will evaluate check-in policies and validate check-in notes at points in time that make sense for whatever you are writing.  For example, the Visual Studio environment will evaluate check-in policies when certain events are triggered.  Also, applications that are converting from a different version control system to TFS will want to bypass these checks.

    The EvaluateCheckin() method evaluates policies and validate check-in notes.  It also checks for conflicts.  Here is the method signature along with its documentation.

        //********************************************************************************************
        /// <summary>
        /// Evaluate the changes to see if they are ready for checking in.
        /// </summary>
        /// <param name="options">Selects what to check (notes, policies, conflicts).</param>
        /// <param name="allChanges">All pending changes for the workspace (needed by checkin policies).
        /// </param>
        /// <param name="changes">List of changes to evaluate.</param>
        /// <param name="comment">Comment to go along with the checkin.</param>
        /// <param name="checkinNote">Any applicable checkin notes data.</param>
        /// <param name="workItemChanges">List of work item changes to occur with this checkin (supplied to checkin policies).</param>
        /// <returns>the results of what was checked</returns>
        //********************************************************************************************
        public CheckinEvaluationResult EvaluateCheckin(CheckinEvaluationOptions options,
                                                        PendingChange[] allChanges,
                                                        PendingChange[] changes,
                                                        String comment,
                                                        CheckinNote checkinNote,
                                                        WorkItemCheckinInfo[] workItemChanges)

    The options parameter controls what is evaluated and is a simple flag enum.

        //********************************************************************************************
        /// <summary>
        /// Used in pre-checkin evaluation, this enumeration is used to specify which aspects of a
        /// checkin should be evaluated.
        /// </summary>
        //********************************************************************************************
        [Flags]
        public enum CheckinEvaluationOptions
        {
            Notes = 0,
            Policies = 1,
            Conflicts = 2,
            All = -1,
        }

    The result of the function is a CheckinEvaluationResult, which has the following properties.

        //********************************************************************************************
        /// <summary>
        /// These are the checkin conflicts returned by the server.
        /// </summary>
        //********************************************************************************************
        public CheckinConflict[] Conflicts

        //********************************************************************************************
        /// <summary>
        /// These are the checkin note problems (missing required notes, invalid checkin notes, etc.).
        /// </summary>
        //********************************************************************************************
        public CheckinNoteFailure[] NoteFailures

        //********************************************************************************************
        /// <summary>
        /// These are the checkin policy failures.
        /// </summary>
        //********************************************************************************************
        public PolicyFailure[] PolicyFailures

        //********************************************************************************************
        /// <summary>
        /// If evaluating policies throws an exception, this is the exception that occurred.  It is null
        /// otherwise.
        /// </summary>
        //********************************************************************************************
        public Exception PolicyEvaluationException

    The properties will be set according to the options you specify and according to what fails.  So if you don't request policy evaluation, for example, or there are no policy failures, the PolicyFailures property will be an empty array.

  • Buck Hodges

    Slides from a TFS version control presentation

    • 6 Comments
    Yesterday, Ed Hintz and I gave a "brown bag" presentation in Redmond for some internal groups that will begin using TFS.  I've created a public version of the slides and attached it to this post.  The presentation goes over a few concepts (the intended audience is already quite familiar with source control), shows some common operations with the command line, gives an overview of how to write tools that use version control, both using the client API as well as VS add-ins, and introduces the command available in tfpt.exe.
  • Buck Hodges

    DIY: Running TFS using a named instance in SQL

    • 1 Comments

    The question about using a named instance with TFS has come up several times, and it came up again today on an internal mailing list.  As to why we don't support it in V1, Brian Harry states that it was the time to get it into setup and the additional testing that led to the decision to postpone it to a future version.

    However, for those of you who want to try it, there is a "do it yourself" approach.  Bill Essary posted the outline of how to do it in the following forum post.  I've copied the answer below, and added some links to the TFS admin utilities and SQL docs.  Keep in mind this is not a supported and tested setup.

    TFS only supports operation on the default SQL instance in V1.  If you are determined to try move TFS to a non-default instance, you might have better luck experimenting with a SQL native client alias.  This allows you to map a non-standard port for a server name in a connection string without actually introducing the port number into the connection string itself.

    Here is how you create an alias:

    1) Open SQL Server Configuration Manager on the TFS application tier machine

    2) Expand the SQL Native Client Configuration node

    3) Right click on Aliases and select New Alias...

    4) Enter an alias name and a SQL port number for that alias

    Use tfsreg and renamedt to replace the SQL Server name with the name of the alias.  Alternately, reinstall the TFS AT using the alias instead of the real SQL Server name.

    If you have questions, be sure to post them in the Visual Studio Team Foundation Forum.

  • Buck Hodges

    Using Outlook with RPC over HTTP is great

    • 2 Comments

    Not too long ago, I finally got around to configuring Outlook to use RPC over HTTP on my laptop and my desktop at home so that I can get to my work email more conveniently.  I love this feature and wish I had done it a lot sooner.  Outlook Web Access is great for places where you don't have your own computer, but it's not the same as the full Outlook.

    If you use Outlook, give it a try.  If you work at Microsoft, you can find the instructions on the lower left of the Outlook Web Access front page.

  • Buck Hodges

    TFS standby application tier and database clustering

    • 4 Comments

    Keith Hill had seen mention of a standby application tier in the slides I posted and asked for more information.  I sent email to Bill Essary, and he replied with the following links covering server availability.

    Ensuring Team Foundation Server Availability

    You can control when you take the servers offline for maintenance. However, you must also consider how you want to handle unexpected failures. By applying one of three basic strategies, you can make sure that the servers are available to the clients during maintenance or failures. The strategy you select is determined by the amount of down-time the users can tolerate and the topology of the system.

    Activating a Fail-Over Application-Tier Server

    After you set up the primary data-tier and application-tier servers, you can add a warm standby computer for the application-tier server of Team Foundation.

  • Buck Hodges

    Manually modifying TFS databases is a bad idea

    • 1 Comments

    Over the last several months, I've seen folks post SQL hacks to modify TFS databases, usually to try to work around some limitation such as not being able to delete work item types.  Marcel de Vries, a Microsoft MVP who has been using TFS for quite a while, recently wrote a post on his experience in trying to do this.  As he mentions, there are many relationships and dependencies that are not obvious, and sometimes you won't find the problems until much later.

    Don’t change a TFS database by hand; How I got myself in real trouble

  • Buck Hodges

    Registry settings to make VS start up faster

    • 2 Comments

    A while back, I wrote a post on how to get better performance from the tf.exe command line.  Today, Tim Noonan, our resident hippie dev from version control land, posted about a couple of registry settings that can help improve the performance of VS with TFS.  The first helps with startup and the second helps with opening solutions.

    A couple helpful Team Foundation registry settings

    Here's a couple of registry options that never made it into the UI anywhere that some of you may find useful.
  • Buck Hodges

    TF14107: The changes could not be checked in due to an incompatible change in another workspace

    • 3 Comments

    When a rename is checked in, the server paths for other workspaces’ pending adds and branches are updated according to the rename being checked in.  If the server cannot update one or more server paths in the pending adds or branches in other workspaces because it would cause two pending changes to reside at the same server path (the server allows only one pending change per target server path), the checkin fails with the error message, "TF14107: The changes could not be checked in due to an incompatible change in another workspace."

    This error is correctly triggered when someone else has an add or branch to a file by the same name.  Unfortunately, it's also triggered by having another person unshelve your changes where you have renamed a file and added a new one with the original name (we ran into this internally).

    The scenario that triggered the error message recently, and thus prevented the user from checking in, is the following.

    1. User A pended a rename of RangeType.cs to RangeName.cs
    2. User A pended an add of a new file called RangeType.cs (the same path as the original file on the server)
    3. User A shelved the changes
    4. User B unshelved the changes to build them as a verification step prior to User A checking in
    5. User A attempted to check in and received the TF14107 error

    In the scenario described above, the server incorrectly sees the pending add of RangeType.cs in the User B's workspace as needing to be renamed to RangeName.cs as a result of checking in User A's changes.  In this case, RangeType.cs is a pending add that has nothing to do with the rename, except that RangeType.cs was the original name of RangeName.cs.  The problem is a bug in the code that detects the condition for TF14107.

    The work around is to undo the changes in the other workspace and then check in the rename.  To find the other change that is causing the problem, you will need to use the status command in tf.exe.  For example, running tf status /user:* $/Project/RangeType.cs $/Project/RangeName.cs would show all of the pending changes for all users on those files.  If you want to see the workspace(s) with the other changs, you can add the /format:detailed option.  In an emergency, you (or someone with UndoOther permission, such as the admin), could undo the change with tf undo /workspace:OtherUserWorkspace;OtherUser $/Project/RangeName.cs.

    [Update 6/3/06]  I added info to the last paragraph regarding workspace info and undo.
    [Update 3/15/06]  I removed a typo at the beginning.

  • Buck Hodges

    Want an easy way to search MSDN blogs?

    • 1 Comments

    While there are other ways to accomplish it, the MSDN Enhanced Search provides an easy way to search MSDN blogs.  Give it a try: Search MSDN Blogs.

  • Buck Hodges

    All about the caching proxy for version control

    • 1 Comments

    Rob Caron posted the following the other day, and I've copied it below.  If you want to learn more about how we cache versions of files to speed up downloads, including get, view, diff, and more, you'll want to take a look at this.

    Team Foundation Server Proxy Screencasts

    We just posted a series of six screencasts by Swamy Subramanian, a developer on Team System, that go into great detail about the inner workings and configuration of Team Foundation Server Proxy. 

    • Overview
    • Installation
    • Configuration
    • Cache Management
    • Request Processing
    • Dogfooding Experience

    TeamFoundationServerProxyScreencasts.zip

  • Buck Hodges

    How to detect whether Team Explorer is installed

    • 2 Comments

    On an internal list, the question of how to detect whether Team Explorer is installed came up.  I didn't know the answer, and I figure there are others that would like to know this.

    To detect Team Explorer, look for the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Team Explorer with a DWORD entry called UseInterface having a value of 1.

    From the command line, you can use the reg command to query the registry.

    D:\>reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Team Explorer" /v UseInterface

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0InstalledProducts\Team Explorer
        UseInterface    REG_DWORD    0x1

  • Buck Hodges

    Update on the TFS source control provider for applications other than VS 2005 (MSSCCI provider)

    • 0 Comments

    Brian Harry has posted an update on the status of the TFS source control provider.  It's currently scheduled for release the week of April 3rd.

    Here is the list of applications tested.  There are more applications that support the MSSCCI provider model than we have resources to test, so he also requests your help in reporting issues with other applications.

  • Visual Studio .NET 2003
  • Visual C++ 6 SP6
  • Visual Visual Basic 6 SP6
  • Visual FoxPro 9 SP1
  • Microsoft Access 2003 SP2   
  • SQL Server Management Studio 2005
  •  

    Check out his post for more information.

  • Buck Hodges

    Team Foundation Server - version 1.0!

    • 1 Comments
    Rob Caron posted about Rick LaPlante's public announcement at SD West that TFS ships tomorrow!
  • Buck Hodges

    How to move your Team Foundation Server

    • 1 Comments

    There is now draft documentation available that describes how to move a TFS server.

    Moving Your Team Foundation Server Deployment
  • Buck Hodges

    More posts from Tim

    • 0 Comments

    Tim Noonan is on a blog-posting roll.  Not long ago, he did quite a bit of work to get better performance in Visual Studio when dealing with large numbers of pending changes, among other things.  Much of the performance improvements came from better use of the ListView: inserting initial items and setting checked states.

    He's also posted a preview of new review command features that will be available in the next release of tfpt (Team Foundation Power Toys).  The current release is available in the VS March CTP SDK.

  • Page 1 of 1 (23 items)