Glen Skinner
Glen Skinner

Reputation: 81

TFS 2010 API: Get old name/location of renamed/moved item

I'm writing an application that pulls changesets from TFS and exports a csv file that describes the latest changes for use in a script to push those changes into ClearCase. The "latest" doesn't necessarily mean the latest, however. If a file was added and then edited, I only need to know that the file was added, and get the latest version so that my script knows how to properly handle it. Most of this is fairly straight-forward. I'm getting hung up on files that have been renamed or moved, as I do not want to show that item as being deleted, and another item added. To uphold the integrity of ClearCase, I need to have in the CSV file that the item is moved or renamed, along with the old location and the new location.

So, the issue I'm having is tracing a renamed (or moved) file back to the previous name or location so that I can correlate it to the new location/name. Where in the API can I get this information?

Upvotes: 4

Views: 1347

Answers (2)

vossad01
vossad01

Reputation: 11958

You will need to use VersionControlServer.QueryHistory in a manner similar to the following method. Pay particular attention to SlotMode which must be false in order for renames to be followed.

private static void PrintNames(VersionControlServer vcs, Change change)
{
    //The key here is to be sure Slot Mode is enabled.
    IEnumerable<Changeset> queryHistory =
        vcs.QueryHistory(
            new QueryHistoryParameters(change.Item.ServerItem, RecursionType.None)
                {
                    IncludeChanges = true,
                    SlotMode = false,
                    VersionEnd = new ChangesetVersionSpec(change.Item.ChangesetId)
                });

    string name = string.Empty;

    var changes = queryHistory.SelectMany(changeset => changeset.Changes);

    foreach (var chng in changes)
    {
        if (name != chng.Item.ServerItem)
        {
            name = chng.Item.ServerItem;
            Console.WriteLine(name);
        }
    }
}

EDIT: Moved the other solution up. What follows worked when I was testing against a pure Rename change but broke when I tired against a Rename and Edit change.

This is probably the most efficient way to get the previous name. While it works (TFS2013 API against as TFS2012 install), it look like a bug to me.

private static string GetPreviousServerItem(VersionControlServer vcs, Item item)
{
    Change[] changes = vcs.GetChangesForChangeset(
        item.ChangesetId,
        includeDownloadInfo: false,
        pageSize: int.MaxValue,
        lastItem: new ItemSpec(item.ServerItem, RecursionType.None));

    string previousServerItem = changes.Single().Item.ServerItem;

    //Yep, this passes
    Trace.Assert(item.ServerItem != previousServerItem);

    return previousServerItem;
}

it would be used like:

if (change.ChangeType.HasFlag(ChangeType.Rename))
{
    string oldServerPath = GetPreviousServerItem(vcs, change.Item);
    // ...
}

Upvotes: 1

Jonno
Jonno

Reputation: 1976

Here is your answer: http://social.msdn.microsoft.com/Forums/en/tfsgeneral/thread/f9c7e7b4-b05f-4d3e-b8ea-cfbd316ef737 Using QueryHistory you can find out that an item was renamed, then using its previous changeset (previous to the one that says it was renamed) you can find its previous name.

Upvotes: 2

Related Questions