以编程方式访问TFS注释以确定所有者

时间:2016-05-06 12:54:11

标签: visual-studio tfs

我正在开发一个项目团队,我们的应用程序在TFS中。我正在尝试确定每个团队成员负责的代码行数。在TFS中,我知道Visual Studio界面中的Annotate功能,它允许您查看最后修改每行代码的人,因此我知道TFS具有此信息。

我编写了一个小型控制台应用程序来访问我的TFS项目及其所有文件,但我现在需要以编程方式访问注释,以便我可以看到每行的所有者是谁。这是我现有的代码:

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

public class Program
{
    static void Main(string[] args)
    {
        var credentials = new NetworkCredential(username, password, domain);
        var server = new TfsTeamProjectCollection(new Uri(serverUrl), credentials);
        var version = server.GetService(typeof(VersionControlServer)) as VersionControlServer;
        var items = version.GetItems(projectPath, RecursionType.Full);
        var fileItems = items.Items.Where(x => x.ItemType == ItemType.File);            
        foreach (var fileItem in fileItems)
        {
            var serverItem = fileItem.ServerItem;
            //TODO: retrieve and parse annotations
        }
    }
}

一旦我有了TFS项目,我似乎无法弄清楚如何检索注释。 This链接通过调用TFPT解释了如何执行此操作,但在实现它之后(tfpt annotate /noprompt <filename>),您只提供最后一个变更集和每行代码,而不是所有者。

我还发现了Microsoft.TeamFoundation.VersionControl.Server名称空间,其Annotation类。我在我的机器上安装了TFS以访问该DLL,但似乎对此问题没有任何帮助。

如何以编程方式访问TFS注释以确定文件代码行的所有者?

1 个答案:

答案 0 :(得分:1)

当项目的更改类型为分支时,您可能必须查询分支。 举个简单的例子,有一个场景

$/Project
  /Main`
   /a.txt
  /Develop
   /a.txt (branched from main)

当您查询$ / project / Develop / a.txt的历史记录时,您还可以使用以下代码获取$ / project / Main / a.txt的历史记录

void GetAllHistory(string serverItem)
    {                    
        var changesets=vcs.QueryHistory(serverItem,
            Microsoft.TeamFoundation.VersionControl.Client.VersionSpec.Latest,
            0,
             Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None,
             null,
             new Microsoft.TeamFoundation.VersionControl.Client.ChangesetVersionSpec(1),
              Microsoft.TeamFoundation.VersionControl.Client.VersionSpec.Latest,
              int.MaxValue,
              true,
              false);

        foreach (var obj in changesets)
        {
            Microsoft.TeamFoundation.VersionControl.Client.Changeset cs = obj as Microsoft.TeamFoundation.VersionControl.Client.Changeset;
            if (cs == null)
            {
                return;
            }
            foreach (var change in cs.Changes)
            {
                if (change.Item.ServerItem != serverItem)
                {
                    return;
                }

                Console.WriteLine(string.Format("ChangeSetID:{0}\tFile:{1}\tChangeType:{2}", cs.ChangesetId,change.Item.ServerItem, change.ChangeType));
                if ((change.ChangeType & Microsoft.TeamFoundation.VersionControl.Client.ChangeType.Branch) == Microsoft.TeamFoundation.VersionControl.Client.ChangeType.Branch)
                {
                    var items=vcs.GetBranchHistory(new Microsoft.TeamFoundation.VersionControl.Client.ItemSpec[]{new Microsoft.TeamFoundation.VersionControl.Client.ItemSpec(serverItem, Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None)},
                        Microsoft.TeamFoundation.VersionControl.Client.VersionSpec.Latest);

                    GetAllHistory(items[0][0].Relative.BranchToItem.ServerItem);
                }
            }

        }
    }