我正在尝试获取所有签到列表以及与其相关的工作项。我知道您可以获取所有提交和更改集的历史记录,一旦您单击特定的更改集,就可以查看工作项。但是,我们正在创建一些统计信息,我想要签到列表以及与之相关的工作项。我不想单击每个变更集并手动获取相关的工作项。这将花费太多时间。如果它们也在变更集旁边,那就太好了。
如果可以通过TFS实现这一目标,我也愿意接受。
我的团队正在使用VS Professional 2015和TFS 2015
提前致谢
答案 0 :(得分:1)
您可以使用TFS api(.net api和REST api)获取列表。
.net api,请查看此博客:https://blogs.msdn.microsoft.com/buckh/2012/02/01/listing-the-work-items-associated-with-changesets-for-a-path/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace ListWorkItems
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Usage: listworkitems <URL for TFS><server path>");
Environment.Exit(1);
}
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(newUri(args[0]));
VersionControlServer vcs = tpc.GetService < VersionControlServer();
// Get the changeset artifact URIs for each changeset in the history query
List<String> changesetArtifactUris = new List<String>();
foreach (Object obj in vcs.QueryHistory(args[1], // path we care about ($/project/whatever)
VersionSpec.Latest, // version of that path
0, // deletion ID (0 = not deleted)
RecursionType.Full, // entire tree - full recursion
null, // include changesets from all users
new ChangesetVersionSpec(1), // start at the beginning of time
VersionSpec.Latest, // end at latest
25, // only return this many
false, // we don't want the files changed
true)) // do history on the path
{
Changeset c = obj as Changeset;
changesetArtifactUris.Add(c.ArtifactUri.AbsoluteUri);
}
// We'll use the linking service to get information about the associated work items
ILinking linkingService = tpc.GetService<ILinking>();
LinkFilter linkFilter = new LinkFilter();
linkFilter.FilterType = FilterType.ToolType;
linkFilter.FilterValues = new String[1] { ToolNames.WorkItemTracking }; // we only want work itms
// Convert the artifact URIs for the work items into strongly-typed objects holding the properties rather than name/value pairs
Artifact[] artifacts = linkingService.GetReferencingArtifacts(changesetArtifactUris.ToArray(), new LinkFilter[1] { linkFilter });
AssociatedWorkItemInfo[] workItemInfos = AssociatedWorkItemInfo.FromArtifacts(artifacts);
// Here we'll just print the IDs and titles of the work items
foreach (AssociatedWorkItemInfo workItemInfo in workItemInfos)
{
Console.WriteLine("Id: " + workItemInfo.Id + " Title: " + workItemInfo.Title);
}
}
}
internal class AssociatedWorkItemInfo
{
private AssociatedWorkItemInfo()
{
}
public int Id
{
get
{
return m_id;
}
}
public String Title
{
get
{
return m_title;
}
}
public String AssignedTo
{
get
{
return m_assignedTo;
}
}
public String WorkItemType
{
get
{
return m_type;
}
}
public String State
{
get
{
return m_state;
}
}
internal static AssociatedWorkItemInfo[] FromArtifacts(IEnumerable<Artifact> artifacts)
{
if (null == artifacts)
{
return new AssociatedWorkItemInfo[0];
}
List<AssociatedWorkItemInfo> toReturn = new List<AssociatedWorkItemInfo>();
foreach (Artifact artifact in artifacts)
{
if (artifact == null)
{
continue;
}
AssociatedWorkItemInfo awii = new AssociatedWorkItemInfo();
// Convert the name/value pairs into strongly-typed objects containing the work item info
foreach (ExtendedAttribute ea in artifact.ExtendedAttributes)
{
if (String.Equals(ea.Name, "System.Id", StringComparison.OrdinalIgnoreCase))
{
int workItemId;
if (Int32.TryParse(ea.Value, out workItemId))
{
awii.m_id = workItemId;
}
}
else if (String.Equals(ea.Name, "System.Title", StringComparison.OrdinalIgnoreCase))
{
awii.m_title = ea.Value;
}
else if (String.Equals(ea.Name, "System.AssignedTo", StringComparison.OrdinalIgnoreCase))
{
awii.m_assignedTo = ea.Value;
}
else if (String.Equals(ea.Name, "System.State", StringComparison.OrdinalIgnoreCase))
{
awii.m_state = ea.Value;
}
else if (String.Equals(ea.Name, "System.WorkItemType", StringComparison.OrdinalIgnoreCase))
{
awii.m_type = ea.Value;
}
}
Debug.Assert(0 != awii.m_id, "Unable to decode artifact into AssociatedWorkItemInfo object.");
if (0 != awii.m_id)
{
toReturn.Add(awii);
}
}
return toReturn.ToArray();
}
private int m_id;
private String m_title;
private String m_assignedTo;
private String m_type;
private String m_state;
}
}
REST api,检查https://www.visualstudio.com/integrate/api/tfvc/changesets#Getlistofassociatedworkitems
GET / tfvc / changesets / {id} / workitems?api-version = {version}