TFS2010:检索与分支关联的所有变更集(完全递归)

这符合我之前关于TFS 2010的问题以及创建更新日志的可能性。

我以前使用标签来识别该程序的一个版本,但由于标签不是固定的时间点,现在我正在使用分支机构。

以下是分支层次结构的外观:

如您所见,有两个不同的应用程序是干线分支: APP_A (应用程序A)和APP_B (应用程序B)。 两者几乎完全相同,但有一些功能上的差异。

以下是创建应用程序的新版本的过程(比如版本1.3):

  • Main trunk被修改(添加了新的功能,错误修复...)
  • 从修改后的Main trunk创建一个新的分支: Main trunk 1.3
  • APP_A分支可能会被修改,所以APP_A独特功能将与V1.3的修改APP_A工作
  • APP_B分支可能会被修改,所以APP_B独特功能将与V1.3的修改APP_B工作
  • Main trunk 1.3被合并到APP_AAPP_B ,所以APP_AAPP_B应用程序都接收到Main trunk的修改
  • 从修改后的APP_A分支中,创建一个新分支: APP_A_1.3
  • 从修改的APP_B分支中,创建一个新分支: APP_B_1.3
  • 我的目标是能够在APP_A_1.3APP_A_1.2之间生成更新日志。

    通过更改日志我的意思是一个WorkItems列表。 每个检入的变更集都与一个或多个WorkItem(例如一个Bug项)关联。 我希望能够获得所有链接到影响APP_A_1.3的变更集的工作项目列表 :这些变更集可能来自Main trunk (上面的第1步), APP_A branch (上面的第3步)或甚至APP_A_1.3分支本身(如果在创建分支后检入修补程序)。

    为了获得这份工作项目列表,我尝试获得所有“链接”到APP_A_1.2变更集列表“链接”=在变更集中签入的代码现在在分支APP_A_1.2 )以及与APP_A_1.3 “链接”的所有变更集列表。

    然后,我将能够知道哪些变更集与APP_A_1.3 “关联”,而不是与APP_A_1.2 “关联”。 从这个变更集的子集中,我将获得所有关联的WorkItem以及我的更改日志。

    这是我的问题:我怎样才能得到与指定分支“链接”的所有变更集的列表? 我正在为C#代码使用TFS 2010 API。

    我的程序(它将检索指定分支的所有变更集)的输入将是分支的名称(比如APP_A_1.2 ),输出将是以下变更集的列表:

  • 更改集应用于APP_A_1.2分支本身
  • APP_A_1.2创建之前应用于APP_A分支的变更集
  • Main trunk 1.2分支已被合并到APP_A之前应用的变更集
  • Main trunk 1.2创建之前应用于Main trunk分支的变更集
  • 我写了下面几段代码来获得所有这些变更集:

    // 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();
    

    即使指定了RecursionType.Full ,上面的代码也返回在APP_A_1.2分支上签入的变更集。 这与Visual Studio中源代码资源管理器视图上的“历史记录”命令相同。

    然后我尝试了下面这段代码:

    // 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();
    

    这返回在APP_A_1.2创建之前在APP_A分支上签入的变更集+在APP_A_1.2分支上APP_A_1.2变更集。 好得多,但不够。 我无法找到一种方法来使用“高于” APP_AMain trunk在我的情况下)的分支进行递归...

    任何人有想法?

    此外,任何更好的想法,以获得两个分支之间的变更日志,欢迎... Thx。


    首先让我先问一个问题。 在你写的帖子的顶部:“我的目标是能够在APP_A_1.3和APP_A_1.2之间生成更新日志。”

    但是当你写什么具体改变时,你正在寻找你列表:应用于APP_A_1.2上的变更集在APP_A_1.2创建之前在APP_A分支上应用的变更集在主要主干1.2分支上应用变更集,然后将其应用于APP_A变更集在主干线1.2创建之前在主干线分支上

    这不是一个有效的列表,因为它会为您提供对存储库开头的APP_A_1.3,APP_A_1.2,1.1等所做的所有更改。

    我现在无法测试我的方法,但这是我将要做的: - QueryHistory将所有更改直接检入分支1.3 - 使用QueryMergesExtended将合并到此分支中。 QueryMergesExtended(http://msdn.microsoft.com/zh-cn/library/ff736485.aspx)在TFS 2010中添加,特别是要比QueryMerges和QueryMergesWithDetails更具性能和健壮性,以支持分支可视化工具 - afaik you不需要在QueryMergesExtended中指定选项FollowRenames,因为您在分支的根上查询合并 - 当您获取源变更列表(来自APP_A)时,您需要检查每个变更集以查看它是否包含合并变更。 如果是这样,您需要在app_a上查询这些变更集的合并。 直到您走完整个分支层次结构为止递归执行此操作。

    在侧面主题上,您可以稍后查看QueryMergeRelationships(http://msdn.microsoft.com/zh-cn/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver.querymergerelationships.aspx),它可以为您介绍分支对象列表在tfs 2010中(这是在Source Control Explorer中选择文件夹并单击转换为分支时发生的情况)。 但是,如果你能以不同的方式发现你的分支(硬编码它们)而不是不需要。

    希望这可以帮助!


    我终于想出了一个简单的解决方案。 我不完全满意它,因为它看起来像一个蛮力算法,但至少它工作。

    我所做的是:

    1)获取应用于我的TFS分支根目录 (即Main Trunk的“父路径”)的每个变更集的列表:

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

    2)对于每个检索到的变更集,我调用TrackMerges来查看变更集是否以某种方式影响我的分支。 TrackMerges能够告诉我指定的变更集是否应用于我指定为函数参数的分支(它将返回这些分支上的目标变更集标识)。 如果目标分支(在我的例子中是APP_A_1.3 )而不是在源分支( APP_A_1.2 )中应用了变更集,那么这意味着它肯定是我的APP_A_1.3分支上的新东西。

    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, 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));
            }
        }
    }
    

    我不认为这是最好的方法,但它工作正常,而且很简单。 此外,我不必硬编码任何东西(分支名称/层次结构),所以它不是太糟糕国际海事组织。 希望它能帮助别人。


    是的,我自己也在处理这个问题。 无论如何,我发现了一个解码它的codeplex项目,当你对标签进行区分时。

    看看这是否有帮助:http://tfslabeldiff.codeplex.com/SourceControl/changeset/view/7075#158224

    我很惊讶这是多么难以找到,但TFS的文档是最好的。 它似乎应该是显而易见的!

    链接地址: http://www.djcxy.com/p/31819.html

    上一篇: TFS2010: Retrieve all changesets associated with a branch (full recursion)

    下一篇: TFS 2010 Branch Visualisation