Jordan Foreman
Jordan Foreman

Reputation: 3888

Dynamic Workspace.Merge TFS changesets

I'm writing a TFS plugin to automate merging of changesets related to a work item whenever said work item is changed from state "Resolved" to state "Closed". The following code is what I have so far:

C#

private void Action_ResolvedToClosed()
{
    //Linq query for getting changesets associated with the current work item
    var changeSets = WorkItem.Links
        .OfType<ExternalLink>()
        .Select(link =>
            VersionControlServer.ArtifactProvider.GetChangeset(new Uri(link.LinkedArtifactUri))).ToList();

    if (!changeSets.Any())
    {
        LOG_NOCHANGESETS(WorkItem.Id);
        return;
    }

    Workspace workspace = VersionControlServer.GetWorkspace(<My Workspace>);

    var source = URI_LOCAL; // $/<Project Name>/<Working Branch>
    var destination = URI_DEV; // $/<Project Name>/<Development Branch>

    // Merge applicable changesets
    foreach (var versionSpec in changeSets.Select(changeset => new ChangesetVersionSpec(changeset.ChangesetId)))
    {
        workspace.Merge(source, destination, versionSpec, versionSpec);
        workspace.CheckIn(workspace.GetPendingChanges(), "**Automated Merge**");
        LOG_SUCCESS(versionSpec.ChangesetId, WorkItem.Id);
    }
}

Is there a way to dynamically generate the workspace variable? Odds are I won't be the one actually making changes - the goal is to automate this process for our devs.

UPDATE: I'm pretty sure what I'm looking for in this second part is GetStatus, so it can be ignored. The paragraph above is my real question.

Secondary: I feel like automating merges can't be this simple. What happens if merge conflicts arise? Does Workspace.Merge fail gracefully? Are there any other glaring issues that someone with a bit more experience with the TFS API can point out?

Upvotes: 0

Views: 1535

Answers (1)

Edward Thomson
Edward Thomson

Reputation: 78873

First, it sounds like you want to query the user's workspace cache to get the appropriate Workspace and "realize" it. If

WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
Workspace workspace = workspaceInfo.GetWorkspace(new TfsTeamProjectCollection(workspaceInfo.ServerUri);

However, as you point out, you may prefer to create a temporary workspace. This will ensure that you do not conflict with any changes the user is trying to make in their own workspace. For example:

TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("http://server:8080/tfs/DefaultCollection"));
VersionControlServer vcs = tpc.GetService<VersionControlServer>();
Workspace workspace = vcs.CreateWorkspace("MERGE-TEMP");
workspace.Map("$/Merge-Source", @"C:\Temp\Merge\Source");
workspace.Map("$/Merge-Target", @"C:\Temp\Merge\Target");

Second, if you run into merge conflicts, they will be set in the workspace. You can query the NumConflicts method of the returned GetStatus. (Though you will not be able to Checkin untli you have resolved the conflicts.

Upvotes: 1

Related Questions