Paul Selles

Computers and cats

Renaming File with Team Foundation Server API: Extending Workspace to Rename a Large Group of Files

The Problem

We have TFS check-in policies that will enforce naming conventions for certain files. The policy will allow the developer to programmatically rename any files that do not match the acceptable naming convention. Behind the scene the renaming is done using the WorkSpace.PendRename method [1]. This policy works fine for one or two files but for a large number of files we start having performance issues. Anyone who has experience renaming multiple files on TFS knows that it is a painfully slow ordeal. So how can we speed it up.

The Solution

I have solved this issue through the use of extending methods in the Microsoft.TeamFoundation.VersionControl.Client.Workspace class, and incorporating Task Parallelism [2][3][4]. Since the original Workspace.PendRename returns the number of files that it has renamed as an Int32, we want to make sure that we preserve that functionality.  I have only created a solution for the Workspace.PendRename(string,string) case since this is the only variation of the method that I am currently using; to expand this to all Workspace.PendRename implementations is trivial.

This the extended method:

public static class WorkSpaceExtension
    // Extend PendRename(String, String)
    public static int PendRename(this Workspace workspace,
        string[] oldPaths,
        string[] newPaths)
        // Make sure that the oldPath and new Paths match
        if (oldPaths.Count() != newPaths.Count())
            throw new ArgumentException("Every oldPath must have corresponding newPath");

        // This list will contain all our tasks
        List pendRenameTasks = new List();

        // Loop throuh all newPath and oldPath pairs
        for (int i = 0; i < oldPaths.Count(); i++)
            // Add each new task in out task container
            pendRenameTasks.Add(Task.Factory.StartNew((Object obj) =>
                // We are going to pass the current old path and the
                // current new path into the path as an anonymous type
                var path = (dynamic)obj;
                return workspace.PendRename(path.oldPath, path.newPath);
            }, new { oldPath = oldPaths[i], newPath = newPaths[i] }));

        // Wait for all tasks to complete

        // Sum up the result of all the original PendRename method
        int taskCount=0;
        foreach (Task pendRenameTask in pendRenameTasks)
            taskCount += pendRenameTask.Result;

        // Return the number of file names changed
        return taskCount;


[1] Workspace.PendRename Method. MSDN Library.

[2] Extension Methods (C# Programming Guide). MSDN Library.

[3] WorkSpace Class. MSDN Library.

[4] Extension Methods (C# Programming Guide). MSDN Library.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: