ken*_*n2k 11 c# tfs branch workitem tfs2010
我正在寻找一种方法来自动生成我的应用程序的两个版本之间的更改日志(实际上是一个工作项列表).我有两个版本的应用程序,v1和v2,每个版本都由TFS 2010(LABEL1和LABEL2)中的标签标识,我在构建应用程序的设置之前手动创建了该标签.我有一个分支系统,这意味着我有一个主干,大多数错误是固定的,并且一个分支,其中补丁主要使用来自主干的合并(但在分支上也有一些修复只与主干无关) .我的应用程序的两个版本(v1和v2)是分支的版本.
我希望TFS 2010能够返回这两个标签之间已修复的错误列表(即,类型= Bug的工作项列表已关闭并验证).
我尝试使用TFS 2010的Web UI或使用Visual Studio实现此目的,但我没有找到任何方法.
然后我尝试使用以下命令行向tf.exe询问历史记录:
tf history /server:http://server_url/collection_name "$/project_path" /version:LLABEL1~LLABEL2 /recursive /noprompt /format:brief
Run Code Online (Sandbox Code Playgroud)
其中LABEL1是与应用程序的v1的源代码关联的标签,LABEL2是与应用程序的v2的源代码关联的标签.它实际上以两种方式失败: - 命令行只返回变更集列表,而不是关联的已关闭工作项列表 - 变更集列表仅包含我在分支本身上应用的变更集,而不是我也应用的变更集和主干然后合并到分支.设置与否"/ slotmode"参数不会改变任何内容.
在那里,我尝试编写一段C#代码来检索工作项列表(而不是变更集列表):
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://server_url/collection_name"));
VersionControlServer controlServer = tfs.GetService<VersionControlServer>();
VersionControlServer vcs = tfs.GetService<VersionControlServer>();
VersionSpec sFrom = VersionSpec.ParseSingleSpec("LLABEL1", null);
VersionSpec sTo = VersionSpec.ParseSingleSpec("LLABEL2", null);
var changesets = vcs.QueryHistory(
"$/project_path",
sTo,
0,
RecursionType.Full,
null,
sFrom,
sTo,
int.MaxValue,
true,
false); // Slotmode to false
Dictionary<int, WorkItem> dico = new Dictionary<int, WorkItem>();
foreach (Changeset set in changesets)
{
foreach (WorkItem zz in set.WorkItems)
{
if (!dico.ContainsKey(zz.Id))
{
dico.Add(zz.Id, zz);
}
}
}
foreach (KeyValuePair<int, WorkItem> pair in dico.OrderBy(z => z.Key))
{
Console.WriteLine(string.Format("ID: {0}, Title: {1}", pair.Key, pair.Value.Title));
}
Run Code Online (Sandbox Code Playgroud)
这实际上有效,我得到了我的两个标签之间的工作项列表,这实际上就是我想要的.但是只考虑与在分支本身上提交的变更集相关联的工作项:在主干上求解然后合并到分支的"Bug"类型的工作项不会出现.Slotmode不会改变任何东西.
然后我终于尝试用由changeset定义的VersionSpecs替换由标签定义的VersionSpecs:
VersionSpec sFrom = VersionSpec.ParseSingleSpec("C5083", null);
VersionSpec sTo = VersionSpec.ParseSingleSpec("C5276", null);
Run Code Online (Sandbox Code Playgroud)
我的代码终于有效了.
所以我的问题是:我怎么能用标签获得相同的结果,标签是我用来识别版本的TFS对象?如果不可能,我该如何识别TFS 2010中的版本?谢谢.
顺便说一句,我在stackoverflow上发现了一些问题,但没有一个给我带标签的答案.例如: 问题示例
一般来说,在任何 SCM 中定义时间点的绝对方法显然是 checkin-id。
在 TFS 中使用标签来抽象这一点并不是此处和此处讨论的最佳选择。更好的方法是使用构建,尤其是在现代 CI 环境中。
为了检索给定构建中包含的最大变更集,您必须执行以下操作:
using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
namespace GetChangesetsFromBuild
{
class Program
{
static void Main()
{
TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://TFSServer:8080/Name"));
IBuildServer bs = (IBuildServer)tpc.GetService(typeof(IBuildServer));
IBuildDetail build = bs.GetAllBuildDetails(new Uri("vstfs:///..."));
List<IChangesetSummary> associatedChangesets = InformationNodeConverters.GetAssociatedChangesets(build);
int idMax = associatedChangesets[0].ChangesetId;
}
}
}
Run Code Online (Sandbox Code Playgroud)
上述操作的一个困难是检索您感兴趣的构建的 BuildUri。为了获取此信息,您可以执行以下操作:
IBuildDetail[] builds = bs.QueryBuilds("TeamPorjectName", "yourBuildDefinitionName")
Run Code Online (Sandbox Code Playgroud)
然后检索对您重要的 Uri。
如果您最终坚持使用标签,这也是一个很好的工具:此外Uri
,每个标签build[]
还有一个LabelName
.