Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TFS2010 - Track Merges

Tags:

tfs-sdk

Given a changeset c and given that c contains merge operations, I would like to get a list of all changesets that have been merged and resulted in c.

For example:

  • Changeset 1 contains some edits for some files.
  • Changeset 2 contains some edits for some other files.
  • Changeset 3 is a merge of changesets 1+2 to a parent branch.

Now I would like to get changesets 1+2 from asking changeset 3 which changeset merges it contained.

I want to do this using the TFS API. I came across the versionControlServer.TrackMerges method, however I do not understand what the ItemIdentifiers that the method expects should be. Unfortunately, I cannot find an example of how to use this method. Also I'm not sure if that is really the correct one.

like image 376
Christian Avatar asked Mar 01 '12 10:03

Christian


2 Answers

Okay, it took me really long, but I think I found out how to do this. This is the Code that will find all the "parent" changesets:

/// <summary>
/// Gets the changesets which have resulted in the given changeset due
/// to a merge operation.
/// </summary>
/// <param name="changeset">The changeset.</param>
/// <param name="versionControlServer">The version control server.</param>
/// <returns>
/// A list of all changesets that have resulted into the given changeset.
/// </returns>
public static List<Changeset> GetMergedChangesets(Changeset changeset, VersionControlServer versionControlServer)
{
    // remember the already covered changeset id's
    Dictionary<int, bool> alreadyCoveredChangesets = new Dictionary<int, bool>();

    // initialize list of parent changesets
    List<Changeset> parentChangesets = new List<Changeset>();

    // go through each change inside the changeset
    foreach(Change change in changeset.Changes)
    {
        // query for the items' history
        var queryResults = versionControlServer.QueryMergesExtended(
                                new ItemSpec(change.Item.ServerItem, RecursionType.Full),
                                new ChangesetVersionSpec(changeset.ChangesetId),
                                null,
                                null);

        // go through each changeset in the history
        foreach (var result in queryResults)
        {
            // only if the target-change is the given changeset, we have a hit
            if (result.TargetChangeset.ChangesetId == changeset.ChangesetId)
            {
                // if that hit has already been processed elsewhere, then just skip it
                if (!alreadyCoveredChangesets.ContainsKey(result.SourceChangeset.ChangesetId))
                {
                    // otherwise add it
                    alreadyCoveredChangesets.Add(result.SourceChangeset.ChangesetId, true);
                    parentChangesets.Add(versionControlServer.GetChangeset(result.SourceChangeset.ChangesetId));
                }
            }
        }
    }

    return parentChangesets;
}

Edit:

I just realized that there is a small "bug" in the above code, I used to write "VersionSpec.Latest" in the query, however: "new ChangesetVersionSpec(changeset.ChangesetId)" would be better, because then the changesets would also be tracked once the source branch has been deleted.

like image 120
Christian Avatar answered Oct 02 '22 10:10

Christian


I think this page by a Ben Clark-Robinson answers the original question how to use the TrackMerges() API:

Here's a verified example:

using tfvcc = Microsoft.TeamFoundation.VersionControl.Client;

var sourcePath = "$/projectName/branchObjectName1"; 
var targetPath = "$/projectName/branchObjectName2";

versionCtl.TrackMerges(
    sourceChangesetIds: new[] { 1000 },
    sourceItem: new tfvcc.ItemIdentifier(sourcePath),
    targetItems: new[] { new tfvcc.ItemIdentifier(targetPath) },
    pathFilter: null)
like image 24
user3167162 Avatar answered Oct 02 '22 10:10

user3167162