Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7579369
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T17:39:43+00:00 2026-05-30T17:39:43+00:00

This follows my previous question about TFS 2010 and the possibility to create a

  • 0

This follows my previous question about TFS 2010 and the possibility to create a changelog.

I was previously using labels to identify a version of the program, but as labels are not fixed points in time, now I’m using branches.

Here’s how the branch hierarchy looks like:

branch hierarchy

As you can see, there are two different applications that are branches of the trunk: APP_A (application A) and APP_B (application B). Both are almost identical, but there are some functional differences.

Here is the process to create a new version of the application (say version 1.3):

  1. The Main trunk is modified (new functionalities are added, bug fixes…)
  2. From the modified Main trunk, a new branch is created: Main trunk 1.3
  3. APP_A branch might be modified, so unique functionalities of APP_A will work with modification of v1.3
  4. APP_B branch might be modified, so unique functionalities of APP_B will work with modification of v1.3
  5. Main trunk 1.3 is merged to APP_A and APP_B, so both APP_A and APP_B applications receive the modifications of the Main trunk
  6. From the modified APP_A branch, a new branch is created: APP_A_1.3
  7. From the modified APP_B branch, a new branch is created: APP_B_1.3

My goal is to be able to produce a changelog between APP_A_1.3 and APP_A_1.2.

By changelog I mean a list of WorkItems. Each changeset that is checked-in is associated with one or more WorkItem (for instance a Bug item). I would like to be able to get the list of all workitems that were linked to a changeset that has impacted APP_A_1.3: those changesets might come from the Main trunk (step 1 above), the APP_A branch (step 3 above) or even the APP_A_1.3 branch itself (if hotfixes are checked-in after the branch has been created).

To get this list of workitems, I tried to get the list of all changesets that are “linked” to APP_A_1.2 (“linked” = the code that was checked-in in the changeset is now on the branch APP_A_1.2) and the list of all changesets that are “linked” to APP_A_1.3.

Then, I’ll be able to know which changesets are “linked” to APP_A_1.3 and not “linked” to APP_A_1.2. From this subset of changesets, I’ll get all associated WorkItems and thus my changelog.

Here’s my problem: how could I get the list of ALL changesets that are “linked” with a specified branch? I’m using the TFS 2010 API for C# code.

The input of my program (that would retrieve all changesets for a specified branch) would be the name of the branch (say APP_A_1.2), and the output would be the list of following changesets:

  • changesets applied on APP_A_1.2 branch itself
  • changesets applied on APP_A branch before APP_A_1.2 was created
  • changesets applied on Main trunk 1.2 branch before it has been merged to APP_A
  • changesets applied on Main trunk branch before Main trunk 1.2 was created

I’ve wrote the following pieces of code to get all those changesets:

// Gets the list of all changesets ID from APP_A_1.2 branch
var branch1ChangeSets = myVersionControlServer.QueryHistory(
    "$/PATH/APP_A_1.2/",
    VersionSpec.Latest,
    0,
    RecursionType.Full,
    null,
    null,
    null,
    int.MaxValue,
    false,
    false).OfType<Changeset>().Select(z => z.ChangesetId).ToList();

Even if RecursionType.Full is specified, the above code only returns changesets that were checked-in on the APP_A_1.2 branch itself. This is identical to the “History” command on Source Code Explorer view in Visual Studio.

Then I tried the following piece of code:

// Gets the list of all changesets ID from APP_A_1.2 branch
var branch1MergedChangeSets = myVersionControlServer.QueryMerges(
    null,
    null,
    "$/PATH/APP_A_1.2/",
    VersionSpec.Latest,
    null,
    null,
    RecursionType.Full).Select(z => z.SourceVersion).ToList();

This returns changesets that were checked-in on APP_A_1.2 branch + those that were cheked-in on APP_A branch before APP_A_1.2 was created. Much better, but not sufficient. I can’t find a way to make the recursion work with branches that are “above” APP_A (Main trunk in my case)…

Anyone has an idea?

Also, any better ideas to get the changelog between two branches are welcome…
Thx.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T17:39:44+00:00Added an answer on May 30, 2026 at 5:39 pm

    I finally came up with a simple solution. I’m not totally happy with it as it actually looks like a brute-force algorithm, but at least it works.

    What I do is:

    1) Get the list of every changeset that is applied on the very root of my TFS branches (i.e. the “parent path” of Main Trunk):

    var allChangesets = vcs.QueryHistory(
        "MySourcePath",
        VersionSpec.Latest,
        0,
        RecursionType.Full,
        null,
        firstPossibleChangeset,
        VersionSpec.Latest,
        int.MaxValue,
        true,
        false).OfType<Changeset>().ToList();
    

    2) For each retrieved changeset, I call TrackMerges to see if the changeset impacts in some way my branches. TrackMerges is able to tell me if a specified changeset is applied on the branches I specify as parameter of the function (it’ll return the target changeset ID on these branches). If a changeset is applied on the destination branch (in my case APP_A_1.3) and not in the source branch (APP_A_1.2), then it means it’s definitely something new on my APP_A_1.3 branch.

    List<int> newChangesets = new List<int>();
    foreach (var z in allChangesets.Where(y => y.ChangesetId > firstPossibleChangesetId))
    {
        var zz = vcs.TrackMerges(
            new int[] { z.ChangesetId },
            new ItemIdentifier("THE TRUNK PATH"),   // The root of all branches
            new ItemIdentifier[] { new ItemIdentifier(fromBranchPath), new ItemIdentifier(toBranchPath) },
            null);
    
        var targetInFromBranch = zz.Where(t => t.TargetItem.Item == fromBranchPath).FirstOrDefault();
        var targetInToBranch = zz.Where(t => t.TargetItem.Item == toBranchPath).FirstOrDefault();
    
        if (targetInToBranch != null && targetInFromBranch == null)
        {
            // Then the changeset is only applied on the ToBranch
            newChangesets.Add(z.ChangesetId);
        }
    }
    

    3) Now it’s very simple to get my changelog (the list of workitems) from the list of “new changesets”:

    // Now, gets associated work items!
    Dictionary<int, WorkItem> dico = new Dictionary<int, WorkItem>();
    foreach (int changesetId in newChangesets)
    {
        foreach (WorkItem zz in vcs.GetChangeset(changesetId).WorkItems)
        {
            this.AddWorkItemToDicRecursive(wis, dico, zz);
        }
    }
    
    private void AddWorkItemToDicRecursive(WorkItemStore wis, Dictionary<int, WorkItem> dico, WorkItem workItem)
    {
        if (!dico.ContainsKey(workItem.Id))
        {
            dico.Add(workItem.Id, workItem);
    
            foreach (WorkItemLink associatedItem in workItem.WorkItemLinks)
            {
                this.AddWorkItemToDicRecursive(wis, dico, wis.GetWorkItem(associatedItem.TargetId));
            }
        }
    }
    

    I don’t think it’s the best possible approach, but it works fine and remains simple. Also, I didn’t have to hardcode anything (branch names/hierarchy) so it’s not too bad IMO. Hope it’ll help someone.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This follows my previous questions on using lxml and Python. I have a question,
This follows on from my previous question about Moose structured types. I apologise for
This is a follow up to my previous question about using XMLHttpRequest() to post
This is a follow up question to a previous question I asked about calculating
This is a follow on from my previous question although this is about something
This question follows on from a previous question, that has raised a further issue.
This problem follows on from a previous question . When I run the following
This question follows on from a previous question. However stackoverflow presents me from commenting
This is a follow-up to my previous question about developing Perl applications . Let’s
This is a follow up to a previous question that I had before about

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.