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:
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With