如何获取Visual Studio中相关的所有签到和工作项的列表

时间:2016-04-12 14:26:15

标签: visual-studio-2015 tfs2015

我正在尝试获取所有签到列表以及与其相关的工作项。我知道您可以获取所有提交和更改集的历史记录,一旦您单击特定的更改集,就可以查看工作项。但是,我们正在创建一些统计信息,我想要签到列表以及与之相关的工作项。我不想单击每个变更集并手动获取相关的工作项。这将花费太多时间。如果它们也在变更集旁边,那就太好了。

如果可以通过TFS实现这一目标,我也愿意接受。

我的团队正在使用VS Professional 2015和TFS 2015

提前致谢

1 个答案:

答案 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}