Using Local workspaces – Promote Excluded changes with TFS 2012 API

Since the introduction of Local workspaces in TFS 2012 I use them where I can. I really like the concept of local workspaces as it gives me much more flexibility when working with my files. (read more about Server and Local Workspaces in my previous post(s))

Local workspaces are also great when you want to quickly build up some history within a branch. For example when you want to build a demo, or if you are migrating sources from another system. Local workspace allow you to add, delete and modify files without notifying the server, so this makes life easy.

Let’s take this example.

We have some source code from 3 versions and want to store this with history in TFS.

    • Version 1.0
      • Version 1.0.txt [Add]
      • Version 1.1.txt [Add]
    • Version 2.0
      • Version 1.0.txt [modified]
      • Version 1.1.txt [Delete]
      • Version 2.0 [Add]
      • Version 2.1 [Add]

  • Version 3.0
    • Version 1.0.txt [modified]
    • Version 2.0 [unchanged]
    • Version 2.1 [unchanged]
    • Version 3.0 [Add]

With Local workspaces building up this tree is a piece of cake. In pseudo script you can do

  1. Create a local workspace with mappingimage
  2. Create MAIN folder in this workspace
  3. Copy contents of Version 1.0 into MAIN
  4. Include all changes in Source Controlimage
  5. Check In
  6. Remove all files from MAIN folder
  7. Go to step 2 use Version 2,3,etc.

The local workspace “knows” which files are modified so this works great.

You can imagine that if you have a lot of these actions, it is nice to automate this. You can use TFS API for this and use the VersionControlServer object to make use of the TFS Version Control API.

You can find MSDN reference here and great examples of connecting to the Object model here.

In code we would translate the above code like:

private void PendChangesAndCheckIn(string pathToWorkspace)
{
    //Get Version Control Server object
    VersionControlServer vs = collection.GetService(typeof 
(VersionControlServer)) as VersionControlServer;
    Workspace ws = vs.TryGetWorkspace(pathToWorkspace);

    //Do Delete and Copy Actions to local path

    //Pend changes
    ws.PendAdd(pathToWorkspace, true);
    var pendingchanges = ws.GetPendingChanges();
    ws.CheckIn(pendingchanges, "This is a comment");
}

ws.PendAdd, moves the excluded changes to the pending changes and the pending changes are checked in.

However, when we remove the files from MAIN and copy Version 2, the following happens.

image

Version 1.0 is marked as modified and the local workspace detects 2 adds and 1 delete. When running the same code as above the delete file stays in Excluded Changes.and my ws.GetPendingChanges() method only “sees” the adds and edits. (as  you can see in the watch window in the picture below)

image

So, how do we get this deleted file in our included changes as well?

The workspace also has a method GetPendingChangesWithCandidates, which actually gets all the “Excluded” changes. Now we know this,it is a matter of promoting these candidates.

You can do this with the following code

private void PendChangesAndCheckIn(string pathToWorkspace)
{
    //Get Version Control Server object
    VersionControlServer vs = collection.GetService(typeof
(VersionControlServer)) as VersionControlServer;
    Workspace ws = vs.TryGetWorkspace(pathToWorkspace);

    //Do Delete and Copy Actions to local path

    //Create a item spec from the server Path
    PendingChange[] candidateChanges = null;
    string serverPath = ws.GetServerItemForLocalItem(pathToWorkspace);
    List<ItemSpec> its = new List<ItemSpec>();
    its.Add(new ItemSpec(serverPath, RecursionType.Full));

    //get all candidate changes and promote them to included changes
    ws.GetPendingChangesWithCandidates(its.ToArray(), true, 
out candidateChanges);
foreach (var change in candidateChanges)
    {
        if (change.IsAdd)
        {
            ws.PendAdd(change.LocalItem);
        }
        else if (change.IsDelete)
        {
            ws.PendDelete(change.LocalItem);
        }
    }

    //Check In all pending changes
    ws.CheckIn(ws.GetPendingChanges(), "This is a comment");
}

It is al little bit different because we have to have a ItemSpec array. This is the serverpath of an item. E.G. $/TestProject/MAIN. I use the ws.GetServerItemForLocalItem to translate the workspace local path to the server equivalent.

We loop through all candidates and check whether we have to add them (PendAdd) or Delete them (PendDelete). Edits are always included by default.

After the loop we can just checkin all our changes.

Hope this helps!

2 Responses to “Using Local workspaces – Promote Excluded changes with TFS 2012 API”

  1. How do you get the excluded .dll and other files that were excluded due to the file extension?

%d bloggers like this: